From afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1c Mon Sep 17 00:00:00 2001 From: jtg Date: Thu, 19 Aug 1999 00:55:39 +0000 Subject: [PATCH] Initial revision --- Make-config | 1265 ++++++ Makefile.X11 | 521 +++ include/GL/Makefile.am | 30 + include/GL/amesa.h | 75 + include/GL/foomesa.h | 89 + include/GL/fxmesa.h | 120 + include/GL/ggimesa.h | 67 + include/GL/gl.h | 2235 ++++++++++ include/GL/gl_mangle.h | 531 +++ include/GL/glu.h | 444 ++ include/GL/glu_mangle.h | 86 + include/GL/glut.h | 751 ++++ include/GL/glut_h.dja | 352 ++ include/GL/glutf90.h | 81 + include/GL/glx.h | 261 ++ include/GL/glx_mangle.h | 72 + include/GL/mglmesa.h | 80 + include/GL/osmesa.h | 256 ++ include/GL/svgamesa.h | 106 + include/GL/wmesa.h | 155 + include/GL/xmesa.h | 357 ++ include/GL/xmesa_x.h | 92 + include/GL/xmesa_xf86.h | 189 + progs/beos/Makefile | 42 + progs/beos/demo.cpp | 153 + progs/beos/sample.cpp | 212 + progs/demos/Makefile.BeOS-R4 | 96 + progs/demos/Makefile.X11 | 60 + progs/demos/Makefile.cygnus | 76 + progs/demos/bounce.c | 240 ++ progs/demos/clearspd.c | 221 + progs/demos/descrip.mms | 63 + progs/demos/drawpix.c | 307 ++ progs/demos/gamma.c | 176 + progs/demos/gears.c | 356 ++ progs/demos/glinfo.c | 50 + progs/demos/glutfx.c | 207 + progs/demos/isosurf.c | 821 ++++ progs/demos/isosurf.dat | 7179 +++++++++++++++++++++++++++++++ progs/demos/morph3d.c | 892 ++++ progs/demos/multiarb.c | 307 ++ progs/demos/osdemo.c | 169 + progs/demos/paltex.c | 186 + progs/demos/pointblast.c | 506 +++ progs/demos/reflect.c | 435 ++ progs/demos/renormal.c | 123 + progs/demos/spectex.c | 277 ++ progs/demos/stex3d.c | 578 +++ progs/demos/tessdemo.c | 439 ++ progs/demos/texcyl.c | 261 ++ progs/demos/texobj.c | 289 ++ progs/demos/trispd.c | 277 ++ progs/demos/winpos.c | 128 + progs/images/girl.rgb | Bin 0 -> 89287 bytes progs/images/reflect.rgb | Bin 0 -> 39632 bytes progs/images/tile.rgb | Bin 0 -> 206534 bytes progs/redbook/Imakefile | 222 + progs/redbook/Makefile.BeOS-R4 | 70 + progs/redbook/Makefile.X11 | 64 + progs/redbook/Makefile.win | 81 + progs/redbook/README | 41 + progs/redbook/aaindex.c | 153 + progs/redbook/aapoly.c | 172 + progs/redbook/aargb.c | 149 + progs/redbook/accanti.c | 168 + progs/redbook/accpersp.c | 240 ++ progs/redbook/alpha.c | 143 + progs/redbook/alpha3D.c | 175 + progs/redbook/anti.c | 111 + progs/redbook/bezcurve.c | 114 + progs/redbook/bezmesh.c | 148 + progs/redbook/checker.c | 125 + progs/redbook/clip.c | 108 + progs/redbook/colormat.c | 153 + progs/redbook/cube.c | 97 + progs/redbook/depthcue.c | 102 + progs/redbook/dof.c | 238 + progs/redbook/double.c | 119 + progs/redbook/drawf.c | 103 + progs/redbook/feedback.c | 171 + progs/redbook/fog.c | 186 + progs/redbook/fogindex.c | 138 + progs/redbook/font.c | 167 + progs/redbook/hello.c | 95 + progs/redbook/image.c | 159 + progs/redbook/jitter.h | 222 + progs/redbook/light.c | 113 + progs/redbook/lines.c | 138 + progs/redbook/list.c | 125 + progs/redbook/material.c | 293 ++ progs/redbook/mipmap.c | 165 + progs/redbook/model.c | 126 + progs/redbook/movelight.c | 148 + progs/redbook/nurbs.c | 176 + progs/redbook/pickdepth.c | 203 + progs/redbook/picksquare.c | 197 + progs/redbook/plane.c | 157 + progs/redbook/planet.c | 123 + progs/redbook/polyoff.c | 237 + progs/redbook/polys.c | 124 + progs/redbook/quadric.c | 189 + progs/redbook/robot.c | 132 + progs/redbook/sccolorlight.c | 127 + progs/redbook/scene.c | 127 + progs/redbook/scenebamb.c | 126 + progs/redbook/sceneflat.c | 126 + progs/redbook/select.c | 222 + progs/redbook/smooth.c | 106 + progs/redbook/stencil.c | 162 + progs/redbook/stroke.c | 181 + progs/redbook/surface.c | 217 + progs/redbook/teaambient.c | 148 + progs/redbook/teapots.c | 206 + progs/redbook/tess.c | 241 ++ progs/redbook/tesswind.c | 290 ++ progs/redbook/texbind.c | 172 + progs/redbook/texgen.c | 207 + progs/redbook/texprox.c | 120 + progs/redbook/texsub.c | 187 + progs/redbook/texturesurf.c | 141 + progs/redbook/torus.c | 152 + progs/redbook/trim.c | 187 + progs/redbook/unproject.c | 126 + progs/redbook/varray.c | 195 + progs/redbook/wrap.c | 180 + progs/samples/Imakefile | 102 + progs/samples/Makefile.BeOS-R4 | 64 + progs/samples/Makefile.DJ | 36 + progs/samples/Makefile.X11 | 61 + progs/samples/Makefile.dja | 26 + progs/samples/README | 520 +++ progs/samples/accum.c | 157 + progs/samples/bitmap1.c | 250 ++ progs/samples/bitmap2.c | 787 ++++ progs/samples/blendeq.c | 295 ++ progs/samples/blendxor.c | 174 + progs/samples/copy.c | 193 + progs/samples/cursor.c | 150 + progs/samples/depth.c | 209 + progs/samples/eval.c | 472 ++ progs/samples/fog.c | 311 ++ progs/samples/font.c | 273 ++ progs/samples/line.c | 219 + progs/samples/loadppm.c | 72 + progs/samples/logo.c | 1630 +++++++ progs/samples/nurb.c | 355 ++ progs/samples/oglinfo.c | 218 + progs/samples/olympic.c | 375 ++ progs/samples/overlay.c | 378 ++ progs/samples/point.c | 234 + progs/samples/prim.c | 546 +++ progs/samples/quad.c | 455 ++ progs/samples/rgbtoppm.c | 273 ++ progs/samples/select.c | 456 ++ progs/samples/shape.c | 345 ++ progs/samples/sphere.c | 1034 +++++ progs/samples/star.c | 331 ++ progs/samples/stencil.c | 143 + progs/samples/stretch.c | 375 ++ progs/samples/texture.c | 474 ++ progs/samples/tkmap.c | 71 + progs/samples/tri.c | 403 ++ progs/samples/wave.c | 602 +++ progs/util/README | 22 + progs/util/dumpstate.c | 1959 +++++++++ progs/util/errcheck.c | 27 + progs/util/glstate.c | 504 +++ progs/util/glstate.h | 53 + progs/util/glutskel.c | 145 + progs/util/idproj.c | 26 + progs/util/imagesgi.cpp | 369 ++ progs/util/imagesgi.h | 55 + progs/util/mwmborder.c | 91 + progs/util/readtex.c | 353 ++ progs/util/sampleMakefile | 49 + progs/util/showbuffer.c | 192 + progs/util/showbuffer.h | 36 + progs/util/winpos.c | 42 + progs/xdemos/Makefile.X11 | 58 + progs/xdemos/descrip.mms | 79 + progs/xdemos/glxdemo.c | 136 + progs/xdemos/glxpixmap.c | 160 + progs/xdemos/offset.c | 323 ++ progs/xdemos/shape.c | 305 ++ progs/xdemos/vgears.c | 282 ++ progs/xdemos/vindex.c | 66 + progs/xdemos/vtest.c | 83 + progs/xdemos/xdemo.c | 347 ++ progs/xdemos/xfont.c | 148 + src/glu/mesa/Makefile.BeOS | 73 + src/glu/mesa/Makefile.BeOS-R4 | 85 + src/glu/mesa/Makefile.X11 | 57 + src/glu/mesa/MesaGLU.def | 54 + src/glu/mesa/README1 | 195 + src/glu/mesa/README2 | 43 + src/glu/mesa/all.h | 69 + src/glu/mesa/descrip.mms | 62 + src/glu/mesa/glu.c | 335 ++ src/glu/mesa/gluP.h | 83 + src/glu/mesa/mipmap.c | 790 ++++ src/glu/mesa/mms_depend | 13 + src/glu/mesa/nurbs.c | 715 +++ src/glu/mesa/nurbs.h | 252 ++ src/glu/mesa/nurbscrv.c | 500 +++ src/glu/mesa/nurbssrf.c | 1422 ++++++ src/glu/mesa/nurbsutl.c | 1403 ++++++ src/glu/mesa/polytest.c | 1049 +++++ src/glu/mesa/project.c | 318 ++ src/glu/mesa/quadric.c | 858 ++++ src/glu/mesa/tess.c | 369 ++ src/glu/mesa/tess.h | 121 + src/glu/mesa/tesselat.c | 456 ++ src/glw/GLwDrawA.c | 686 +++ src/glw/GLwDrawA.h | 195 + src/glw/GLwDrawAP.h | 130 + src/glw/GLwMDrawA.c | 41 + src/glw/GLwMDrawA.h | 41 + src/glw/GLwMDrawAP.h | 41 + src/glw/Makefile | 59 + src/glw/README | 56 + src/glw/boilerplate.c | 451 ++ src/glw/depend | 6 + src/mesa/Makefile.X11 | 243 ++ src/mesa/drivers/allegro/amesa.c | 395 ++ src/mesa/drivers/allegro/direct.h | 189 + src/mesa/drivers/allegro/generic.h | 233 + src/mesa/drivers/beos/GLView.cpp | 1233 ++++++ src/mesa/drivers/d3d/D3DCAPS.CPP | 251 ++ src/mesa/drivers/d3d/D3DHAL.H | 69 + src/mesa/drivers/d3d/D3DInit.cpp | 891 ++++ src/mesa/drivers/d3d/D3DMESA.H | 85 + src/mesa/drivers/d3d/D3DRaster.cpp | 214 + src/mesa/drivers/d3d/D3DShared.h | 154 + src/mesa/drivers/d3d/D3DTEXT.CPP | 577 +++ src/mesa/drivers/d3d/D3DTextureMgr.cpp | 948 ++++ src/mesa/drivers/d3d/D3DTextureMgr.h | 63 + src/mesa/drivers/d3d/D3DUTILS.CPP | 639 +++ src/mesa/drivers/d3d/D3Dvbrender.c | 2150 +++++++++ src/mesa/drivers/d3d/DDrawPROCS.c | 400 ++ src/mesa/drivers/d3d/DEBUG.C | 144 + src/mesa/drivers/d3d/DEBUG.H | 91 + src/mesa/drivers/d3d/DbgEnv.bat | 25 + src/mesa/drivers/d3d/MAKEFILE | 102 + src/mesa/drivers/d3d/NULLProcs.h | 49 + src/mesa/drivers/d3d/NullProcs.c | 130 + src/mesa/drivers/d3d/OPENGL32.DEF | 443 ++ src/mesa/drivers/d3d/WGL.C | 1262 ++++++ src/mesa/drivers/d3d/d3dText.h | 53 + src/mesa/drivers/dos/DEPEND.DOS | 119 + src/mesa/drivers/dos/dosmesa.c | 1513 +++++++ src/mesa/drivers/ggi/ggimesa.conf.in | 13 + src/mesa/drivers/glide/fxapi.c | 1411 ++++++ src/mesa/drivers/glide/fxdd.c | 632 +++ src/mesa/drivers/glide/fxddspan.c | 817 ++++ src/mesa/drivers/glide/fxddtex.c | 1299 ++++++ src/mesa/drivers/glide/fxdrv.h | 576 +++ src/mesa/drivers/glide/fxglidew.c | 247 ++ src/mesa/drivers/glide/fxglidew.h | 358 ++ src/mesa/drivers/glide/fxopengl.def | 467 ++ src/mesa/drivers/glide/fxsetup.c | 1552 +++++++ src/mesa/drivers/glide/fxtexman.c | 579 +++ src/mesa/drivers/glide/fxwgl.c | 806 ++++ src/mesa/drivers/osmesa/osmesa.c | 1594 +++++++ src/mesa/drivers/svga/svgamesa.c | 540 +++ src/mesa/drivers/windows/colors.h | 499 +++ src/mesa/drivers/windows/mesa_extend.c | 211 + src/mesa/drivers/windows/mesa_extend.h | 43 + src/mesa/drivers/windows/stereo.h | 47 + src/mesa/drivers/windows/wgl.c | 518 +++ src/mesa/drivers/windows/wing32.def | 12 + src/mesa/drivers/windows/wmesa.c | 3021 +++++++++++++ src/mesa/drivers/windows/wmesaBackup.c | 2879 +++++++++++++ src/mesa/drivers/windows/wmesaOld.c | 2737 ++++++++++++ src/mesa/drivers/windows/wmesa_stereo.c | 1872 ++++++++ src/mesa/drivers/windows/wmesadef.h | 154 + src/mesa/drivers/x11/fakeglx.c | 1516 +++++++ src/mesa/drivers/x11/glxapi.c | 405 ++ src/mesa/drivers/x11/realglx.c | 239 + src/mesa/drivers/x11/realglx.h | 111 + src/mesa/drivers/x11/xfonts.c | 398 ++ src/mesa/drivers/x11/xmesaP.h | 499 +++ src/mesa/main/Imakefile | 127 + src/mesa/main/KNOWN_BUGS | 20 + src/mesa/main/Makefile.DJ | 95 + src/mesa/main/Makefile.X11 | 243 ++ src/mesa/main/accum.c | 495 +++ src/mesa/main/accum.h | 51 + src/mesa/main/attrib.c | 863 ++++ src/mesa/main/attrib.h | 47 + src/mesa/main/blend.c | 812 ++++ src/mesa/main/blend.h | 68 + src/mesa/main/clip.c | 460 ++ src/mesa/main/clip.h | 105 + src/mesa/main/colortab.c | 312 ++ src/mesa/main/colortab.h | 55 + src/mesa/main/config.h | 222 + src/mesa/main/context.c | 2388 ++++++++++ src/mesa/main/context.h | 167 + src/mesa/main/dd.h | 635 +++ src/mesa/main/depth.c | 879 ++++ src/mesa/main/depth.h | 98 + src/mesa/main/descrip.mms | 156 + src/mesa/main/dlist.c | 3501 +++++++++++++++ src/mesa/main/dlist.h | 79 + src/mesa/main/drawpix.c | 946 ++++ src/mesa/main/drawpix.h | 54 + src/mesa/main/enable.c | 699 +++ src/mesa/main/enable.h | 51 + src/mesa/main/enums.c | 893 ++++ src/mesa/main/enums.h | 34 + src/mesa/main/eval.c | 2725 ++++++++++++ src/mesa/main/eval.h | 95 + src/mesa/main/extensions.c | 196 + src/mesa/main/extensions.h | 56 + src/mesa/main/feedback.c | 395 ++ src/mesa/main/feedback.h | 74 + src/mesa/main/fog.c | 327 ++ src/mesa/main/fog.h | 51 + src/mesa/main/get.c | 3692 ++++++++++++++++ src/mesa/main/get.h | 48 + src/mesa/main/hash.c | 295 ++ src/mesa/main/hash.h | 59 + src/mesa/main/image.c | 2417 +++++++++++ src/mesa/main/image.h | 109 + src/mesa/main/light.c | 1183 +++++ src/mesa/main/light.h | 103 + src/mesa/main/lines.c | 1146 +++++ src/mesa/main/lines.h | 45 + src/mesa/main/macros.h | 546 +++ src/mesa/main/matrix.c | 1438 +++++++ src/mesa/main/matrix.h | 115 + src/mesa/main/mesa.conf | 74 + src/mesa/main/pixel.c | 774 ++++ src/mesa/main/pixel.h | 111 + src/mesa/main/points.c | 1344 ++++++ src/mesa/main/points.h | 45 + src/mesa/main/polygon.c | 177 + src/mesa/main/polygon.h | 53 + src/mesa/main/rastpos.c | 227 + src/mesa/main/rastpos.h | 48 + src/mesa/main/simple_list.h | 99 + src/mesa/main/stencil.c | 1107 +++++ src/mesa/main/stencil.h | 88 + src/mesa/main/teximage.c | 2344 ++++++++++ src/mesa/main/teximage.h | 186 + src/mesa/main/texobj.c | 571 +++ src/mesa/main/texobj.h | 85 + src/mesa/main/texstate.c | 1146 +++++ src/mesa/main/texstate.h | 112 + src/mesa/main/varray.c | 1259 ++++++ src/mesa/main/varray.h | 113 + src/mesa/x86/3dnow.c | 168 + src/mesa/x86/3dnow.h | 95 + src/mesa/x86/assyntax.h | 1629 +++++++ src/mesa/x86/common_x86.c | 77 + src/mesa/x86/mmx.h | 77 + src/mesa/x86/mmx_blend.S | 363 ++ src/mesa/x86/x86.c | 107 + src/mesa/x86/x86.h | 37 + 359 files changed, 145077 insertions(+) create mode 100644 Make-config create mode 100644 Makefile.X11 create mode 100644 include/GL/Makefile.am create mode 100644 include/GL/amesa.h create mode 100644 include/GL/foomesa.h create mode 100644 include/GL/fxmesa.h create mode 100644 include/GL/ggimesa.h create mode 100644 include/GL/gl.h create mode 100644 include/GL/gl_mangle.h create mode 100644 include/GL/glu.h create mode 100644 include/GL/glu_mangle.h create mode 100644 include/GL/glut.h create mode 100644 include/GL/glut_h.dja create mode 100644 include/GL/glutf90.h create mode 100644 include/GL/glx.h create mode 100644 include/GL/glx_mangle.h create mode 100644 include/GL/mglmesa.h create mode 100644 include/GL/osmesa.h create mode 100644 include/GL/svgamesa.h create mode 100644 include/GL/wmesa.h create mode 100644 include/GL/xmesa.h create mode 100644 include/GL/xmesa_x.h create mode 100644 include/GL/xmesa_xf86.h create mode 100644 progs/beos/Makefile create mode 100644 progs/beos/demo.cpp create mode 100644 progs/beos/sample.cpp create mode 100644 progs/demos/Makefile.BeOS-R4 create mode 100644 progs/demos/Makefile.X11 create mode 100644 progs/demos/Makefile.cygnus create mode 100644 progs/demos/bounce.c create mode 100644 progs/demos/clearspd.c create mode 100644 progs/demos/descrip.mms create mode 100644 progs/demos/drawpix.c create mode 100644 progs/demos/gamma.c create mode 100644 progs/demos/gears.c create mode 100644 progs/demos/glinfo.c create mode 100644 progs/demos/glutfx.c create mode 100644 progs/demos/isosurf.c create mode 100644 progs/demos/isosurf.dat create mode 100644 progs/demos/morph3d.c create mode 100644 progs/demos/multiarb.c create mode 100644 progs/demos/osdemo.c create mode 100644 progs/demos/paltex.c create mode 100644 progs/demos/pointblast.c create mode 100644 progs/demos/reflect.c create mode 100644 progs/demos/renormal.c create mode 100644 progs/demos/spectex.c create mode 100644 progs/demos/stex3d.c create mode 100644 progs/demos/tessdemo.c create mode 100644 progs/demos/texcyl.c create mode 100644 progs/demos/texobj.c create mode 100644 progs/demos/trispd.c create mode 100644 progs/demos/winpos.c create mode 100644 progs/images/girl.rgb create mode 100644 progs/images/reflect.rgb create mode 100644 progs/images/tile.rgb create mode 100644 progs/redbook/Imakefile create mode 100644 progs/redbook/Makefile.BeOS-R4 create mode 100644 progs/redbook/Makefile.X11 create mode 100644 progs/redbook/Makefile.win create mode 100644 progs/redbook/README create mode 100644 progs/redbook/aaindex.c create mode 100644 progs/redbook/aapoly.c create mode 100644 progs/redbook/aargb.c create mode 100644 progs/redbook/accanti.c create mode 100644 progs/redbook/accpersp.c create mode 100644 progs/redbook/alpha.c create mode 100644 progs/redbook/alpha3D.c create mode 100644 progs/redbook/anti.c create mode 100644 progs/redbook/bezcurve.c create mode 100644 progs/redbook/bezmesh.c create mode 100644 progs/redbook/checker.c create mode 100644 progs/redbook/clip.c create mode 100644 progs/redbook/colormat.c create mode 100644 progs/redbook/cube.c create mode 100644 progs/redbook/depthcue.c create mode 100644 progs/redbook/dof.c create mode 100644 progs/redbook/double.c create mode 100644 progs/redbook/drawf.c create mode 100644 progs/redbook/feedback.c create mode 100644 progs/redbook/fog.c create mode 100644 progs/redbook/fogindex.c create mode 100644 progs/redbook/font.c create mode 100644 progs/redbook/hello.c create mode 100644 progs/redbook/image.c create mode 100644 progs/redbook/jitter.h create mode 100644 progs/redbook/light.c create mode 100644 progs/redbook/lines.c create mode 100644 progs/redbook/list.c create mode 100644 progs/redbook/material.c create mode 100644 progs/redbook/mipmap.c create mode 100644 progs/redbook/model.c create mode 100644 progs/redbook/movelight.c create mode 100644 progs/redbook/nurbs.c create mode 100644 progs/redbook/pickdepth.c create mode 100644 progs/redbook/picksquare.c create mode 100644 progs/redbook/plane.c create mode 100644 progs/redbook/planet.c create mode 100644 progs/redbook/polyoff.c create mode 100644 progs/redbook/polys.c create mode 100644 progs/redbook/quadric.c create mode 100644 progs/redbook/robot.c create mode 100644 progs/redbook/sccolorlight.c create mode 100644 progs/redbook/scene.c create mode 100644 progs/redbook/scenebamb.c create mode 100644 progs/redbook/sceneflat.c create mode 100644 progs/redbook/select.c create mode 100644 progs/redbook/smooth.c create mode 100644 progs/redbook/stencil.c create mode 100644 progs/redbook/stroke.c create mode 100644 progs/redbook/surface.c create mode 100644 progs/redbook/teaambient.c create mode 100644 progs/redbook/teapots.c create mode 100644 progs/redbook/tess.c create mode 100644 progs/redbook/tesswind.c create mode 100644 progs/redbook/texbind.c create mode 100644 progs/redbook/texgen.c create mode 100644 progs/redbook/texprox.c create mode 100644 progs/redbook/texsub.c create mode 100644 progs/redbook/texturesurf.c create mode 100644 progs/redbook/torus.c create mode 100644 progs/redbook/trim.c create mode 100644 progs/redbook/unproject.c create mode 100644 progs/redbook/varray.c create mode 100644 progs/redbook/wrap.c create mode 100644 progs/samples/Imakefile create mode 100644 progs/samples/Makefile.BeOS-R4 create mode 100644 progs/samples/Makefile.DJ create mode 100644 progs/samples/Makefile.X11 create mode 100644 progs/samples/Makefile.dja create mode 100644 progs/samples/README create mode 100644 progs/samples/accum.c create mode 100644 progs/samples/bitmap1.c create mode 100644 progs/samples/bitmap2.c create mode 100644 progs/samples/blendeq.c create mode 100644 progs/samples/blendxor.c create mode 100644 progs/samples/copy.c create mode 100644 progs/samples/cursor.c create mode 100644 progs/samples/depth.c create mode 100644 progs/samples/eval.c create mode 100644 progs/samples/fog.c create mode 100644 progs/samples/font.c create mode 100644 progs/samples/line.c create mode 100644 progs/samples/loadppm.c create mode 100644 progs/samples/logo.c create mode 100644 progs/samples/nurb.c create mode 100644 progs/samples/oglinfo.c create mode 100644 progs/samples/olympic.c create mode 100644 progs/samples/overlay.c create mode 100644 progs/samples/point.c create mode 100644 progs/samples/prim.c create mode 100644 progs/samples/quad.c create mode 100644 progs/samples/rgbtoppm.c create mode 100644 progs/samples/select.c create mode 100644 progs/samples/shape.c create mode 100644 progs/samples/sphere.c create mode 100644 progs/samples/star.c create mode 100644 progs/samples/stencil.c create mode 100644 progs/samples/stretch.c create mode 100644 progs/samples/texture.c create mode 100644 progs/samples/tkmap.c create mode 100644 progs/samples/tri.c create mode 100644 progs/samples/wave.c create mode 100644 progs/util/README create mode 100644 progs/util/dumpstate.c create mode 100644 progs/util/errcheck.c create mode 100644 progs/util/glstate.c create mode 100644 progs/util/glstate.h create mode 100644 progs/util/glutskel.c create mode 100644 progs/util/idproj.c create mode 100644 progs/util/imagesgi.cpp create mode 100644 progs/util/imagesgi.h create mode 100644 progs/util/mwmborder.c create mode 100644 progs/util/readtex.c create mode 100644 progs/util/sampleMakefile create mode 100644 progs/util/showbuffer.c create mode 100644 progs/util/showbuffer.h create mode 100644 progs/util/winpos.c create mode 100644 progs/xdemos/Makefile.X11 create mode 100644 progs/xdemos/descrip.mms create mode 100644 progs/xdemos/glxdemo.c create mode 100644 progs/xdemos/glxpixmap.c create mode 100644 progs/xdemos/offset.c create mode 100644 progs/xdemos/shape.c create mode 100644 progs/xdemos/vgears.c create mode 100644 progs/xdemos/vindex.c create mode 100644 progs/xdemos/vtest.c create mode 100644 progs/xdemos/xdemo.c create mode 100644 progs/xdemos/xfont.c create mode 100644 src/glu/mesa/Makefile.BeOS create mode 100644 src/glu/mesa/Makefile.BeOS-R4 create mode 100644 src/glu/mesa/Makefile.X11 create mode 100644 src/glu/mesa/MesaGLU.def create mode 100644 src/glu/mesa/README1 create mode 100644 src/glu/mesa/README2 create mode 100644 src/glu/mesa/all.h create mode 100644 src/glu/mesa/descrip.mms create mode 100644 src/glu/mesa/glu.c create mode 100644 src/glu/mesa/gluP.h create mode 100644 src/glu/mesa/mipmap.c create mode 100644 src/glu/mesa/mms_depend create mode 100644 src/glu/mesa/nurbs.c create mode 100644 src/glu/mesa/nurbs.h create mode 100644 src/glu/mesa/nurbscrv.c create mode 100644 src/glu/mesa/nurbssrf.c create mode 100644 src/glu/mesa/nurbsutl.c create mode 100644 src/glu/mesa/polytest.c create mode 100644 src/glu/mesa/project.c create mode 100644 src/glu/mesa/quadric.c create mode 100644 src/glu/mesa/tess.c create mode 100644 src/glu/mesa/tess.h create mode 100644 src/glu/mesa/tesselat.c create mode 100644 src/glw/GLwDrawA.c create mode 100644 src/glw/GLwDrawA.h create mode 100644 src/glw/GLwDrawAP.h create mode 100644 src/glw/GLwMDrawA.c create mode 100644 src/glw/GLwMDrawA.h create mode 100644 src/glw/GLwMDrawAP.h create mode 100644 src/glw/Makefile create mode 100644 src/glw/README create mode 100644 src/glw/boilerplate.c create mode 100644 src/glw/depend create mode 100644 src/mesa/Makefile.X11 create mode 100644 src/mesa/drivers/allegro/amesa.c create mode 100644 src/mesa/drivers/allegro/direct.h create mode 100644 src/mesa/drivers/allegro/generic.h create mode 100644 src/mesa/drivers/beos/GLView.cpp create mode 100644 src/mesa/drivers/d3d/D3DCAPS.CPP create mode 100644 src/mesa/drivers/d3d/D3DHAL.H create mode 100644 src/mesa/drivers/d3d/D3DInit.cpp create mode 100644 src/mesa/drivers/d3d/D3DMESA.H create mode 100644 src/mesa/drivers/d3d/D3DRaster.cpp create mode 100644 src/mesa/drivers/d3d/D3DShared.h create mode 100644 src/mesa/drivers/d3d/D3DTEXT.CPP create mode 100644 src/mesa/drivers/d3d/D3DTextureMgr.cpp create mode 100644 src/mesa/drivers/d3d/D3DTextureMgr.h create mode 100644 src/mesa/drivers/d3d/D3DUTILS.CPP create mode 100644 src/mesa/drivers/d3d/D3Dvbrender.c create mode 100644 src/mesa/drivers/d3d/DDrawPROCS.c create mode 100644 src/mesa/drivers/d3d/DEBUG.C create mode 100644 src/mesa/drivers/d3d/DEBUG.H create mode 100644 src/mesa/drivers/d3d/DbgEnv.bat create mode 100644 src/mesa/drivers/d3d/MAKEFILE create mode 100644 src/mesa/drivers/d3d/NULLProcs.h create mode 100644 src/mesa/drivers/d3d/NullProcs.c create mode 100644 src/mesa/drivers/d3d/OPENGL32.DEF create mode 100644 src/mesa/drivers/d3d/WGL.C create mode 100644 src/mesa/drivers/d3d/d3dText.h create mode 100644 src/mesa/drivers/dos/DEPEND.DOS create mode 100644 src/mesa/drivers/dos/dosmesa.c create mode 100644 src/mesa/drivers/ggi/ggimesa.conf.in create mode 100644 src/mesa/drivers/glide/fxapi.c create mode 100644 src/mesa/drivers/glide/fxdd.c create mode 100644 src/mesa/drivers/glide/fxddspan.c create mode 100644 src/mesa/drivers/glide/fxddtex.c create mode 100644 src/mesa/drivers/glide/fxdrv.h create mode 100644 src/mesa/drivers/glide/fxglidew.c create mode 100644 src/mesa/drivers/glide/fxglidew.h create mode 100644 src/mesa/drivers/glide/fxopengl.def create mode 100644 src/mesa/drivers/glide/fxsetup.c create mode 100644 src/mesa/drivers/glide/fxtexman.c create mode 100644 src/mesa/drivers/glide/fxwgl.c create mode 100644 src/mesa/drivers/osmesa/osmesa.c create mode 100644 src/mesa/drivers/svga/svgamesa.c create mode 100644 src/mesa/drivers/windows/colors.h create mode 100644 src/mesa/drivers/windows/mesa_extend.c create mode 100644 src/mesa/drivers/windows/mesa_extend.h create mode 100644 src/mesa/drivers/windows/stereo.h create mode 100644 src/mesa/drivers/windows/wgl.c create mode 100644 src/mesa/drivers/windows/wing32.def create mode 100644 src/mesa/drivers/windows/wmesa.c create mode 100644 src/mesa/drivers/windows/wmesaBackup.c create mode 100644 src/mesa/drivers/windows/wmesaOld.c create mode 100644 src/mesa/drivers/windows/wmesa_stereo.c create mode 100644 src/mesa/drivers/windows/wmesadef.h create mode 100644 src/mesa/drivers/x11/fakeglx.c create mode 100644 src/mesa/drivers/x11/glxapi.c create mode 100644 src/mesa/drivers/x11/realglx.c create mode 100644 src/mesa/drivers/x11/realglx.h create mode 100644 src/mesa/drivers/x11/xfonts.c create mode 100644 src/mesa/drivers/x11/xmesaP.h create mode 100644 src/mesa/main/Imakefile create mode 100644 src/mesa/main/KNOWN_BUGS create mode 100644 src/mesa/main/Makefile.DJ create mode 100644 src/mesa/main/Makefile.X11 create mode 100644 src/mesa/main/accum.c create mode 100644 src/mesa/main/accum.h create mode 100644 src/mesa/main/attrib.c create mode 100644 src/mesa/main/attrib.h create mode 100644 src/mesa/main/blend.c create mode 100644 src/mesa/main/blend.h create mode 100644 src/mesa/main/clip.c create mode 100644 src/mesa/main/clip.h create mode 100644 src/mesa/main/colortab.c create mode 100644 src/mesa/main/colortab.h create mode 100644 src/mesa/main/config.h create mode 100644 src/mesa/main/context.c create mode 100644 src/mesa/main/context.h create mode 100644 src/mesa/main/dd.h create mode 100644 src/mesa/main/depth.c create mode 100644 src/mesa/main/depth.h create mode 100644 src/mesa/main/descrip.mms create mode 100644 src/mesa/main/dlist.c create mode 100644 src/mesa/main/dlist.h create mode 100644 src/mesa/main/drawpix.c create mode 100644 src/mesa/main/drawpix.h create mode 100644 src/mesa/main/enable.c create mode 100644 src/mesa/main/enable.h create mode 100644 src/mesa/main/enums.c create mode 100644 src/mesa/main/enums.h create mode 100644 src/mesa/main/eval.c create mode 100644 src/mesa/main/eval.h create mode 100644 src/mesa/main/extensions.c create mode 100644 src/mesa/main/extensions.h create mode 100644 src/mesa/main/feedback.c create mode 100644 src/mesa/main/feedback.h create mode 100644 src/mesa/main/fog.c create mode 100644 src/mesa/main/fog.h create mode 100644 src/mesa/main/get.c create mode 100644 src/mesa/main/get.h create mode 100644 src/mesa/main/hash.c create mode 100644 src/mesa/main/hash.h create mode 100644 src/mesa/main/image.c create mode 100644 src/mesa/main/image.h create mode 100644 src/mesa/main/light.c create mode 100644 src/mesa/main/light.h create mode 100644 src/mesa/main/lines.c create mode 100644 src/mesa/main/lines.h create mode 100644 src/mesa/main/macros.h create mode 100644 src/mesa/main/matrix.c create mode 100644 src/mesa/main/matrix.h create mode 100644 src/mesa/main/mesa.conf create mode 100644 src/mesa/main/pixel.c create mode 100644 src/mesa/main/pixel.h create mode 100644 src/mesa/main/points.c create mode 100644 src/mesa/main/points.h create mode 100644 src/mesa/main/polygon.c create mode 100644 src/mesa/main/polygon.h create mode 100644 src/mesa/main/rastpos.c create mode 100644 src/mesa/main/rastpos.h create mode 100644 src/mesa/main/simple_list.h create mode 100644 src/mesa/main/stencil.c create mode 100644 src/mesa/main/stencil.h create mode 100644 src/mesa/main/teximage.c create mode 100644 src/mesa/main/teximage.h create mode 100644 src/mesa/main/texobj.c create mode 100644 src/mesa/main/texobj.h create mode 100644 src/mesa/main/texstate.c create mode 100644 src/mesa/main/texstate.h create mode 100644 src/mesa/main/varray.c create mode 100644 src/mesa/main/varray.h create mode 100644 src/mesa/x86/3dnow.c create mode 100644 src/mesa/x86/3dnow.h create mode 100644 src/mesa/x86/assyntax.h create mode 100644 src/mesa/x86/common_x86.c create mode 100644 src/mesa/x86/mmx.h create mode 100644 src/mesa/x86/mmx_blend.S create mode 100644 src/mesa/x86/x86.c create mode 100644 src/mesa/x86/x86.h diff --git a/Make-config b/Make-config new file mode 100644 index 0000000..b03e723 --- /dev/null +++ b/Make-config @@ -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 index 0000000..21f27e2 --- /dev/null +++ b/Makefile.X11 @@ -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 index 0000000..61af039 --- /dev/null +++ b/include/GL/Makefile.am @@ -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 index 0000000..b4a1867 --- /dev/null +++ b/include/GL/amesa.h @@ -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 index 0000000..8874629 --- /dev/null +++ b/include/GL/foomesa.h @@ -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 index 0000000..68f15eb --- /dev/null +++ b/include/GL/fxmesa.h @@ -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 + + +#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 index 0000000..b7f9379 --- /dev/null +++ b/include/GL/ggimesa.h @@ -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 + +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 index 0000000..58b51d5 --- /dev/null +++ b/include/GL/gl.h @@ -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 /* 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 index 0000000..8ab25a9 --- /dev/null +++ b/include/GL/gl_mangle.h @@ -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 index 0000000..b1321c0 --- /dev/null +++ b/include/GL/glu.h @@ -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 index 0000000..ed3944c --- /dev/null +++ b/include/GL/glu_mangle.h @@ -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 index 0000000..1b7fc43 --- /dev/null +++ b/include/GL/glut.h @@ -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 +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + 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 */ +# 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 +**/ +#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 index 0000000..d5713f0 --- /dev/null +++ b/include/GL/glut_h.dja @@ -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 +#include + +#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 index 0000000..46f1979 --- /dev/null +++ b/include/GL/glutf90.h @@ -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 + +/* 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 index 0000000..4b27880 --- /dev/null +++ b/include/GL/glx.h @@ -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 +#include +#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 index 0000000..e246801 --- /dev/null +++ b/include/GL/glx_mangle.h @@ -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 index 0000000..76deb33 --- /dev/null +++ b/include/GL/mglmesa.h @@ -0,0 +1,80 @@ +/**************************************************************************** +* +* Mesa bindings for SciTech MGL +* +* Copyright (C) 1996 SciTech Software. +* All rights reserved. +* +* Filename: $Workfile: mglmesa.h $ +* Version: $Revision: 1.1 $ +* +* Language: ANSI C +* Environment: Any +* +* Description: Header file for the Mesa/OpenGL interface bindings for the +* SciTech MGL graphics library. Uses the MGL internal +* device context structures to get direct access to the +* high performance MGL rasterization functions for maximum +* performance. Utilizes the VESA VBE/AF Accelerator Functions +* via the MGL's accelerated device driver functions, as well +* as basic DirectDraw accelerated functions provided by the +* MGL. +* +* 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. +* +* $Date: 1999/08/19 00:55:40 $ $Author: jtg $ +* +****************************************************************************/ + +#ifndef __MGLMESA_H +#define __MGLMESA_H + +#include "mgraph.h" + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +#ifndef __WINDOWS__ +#define GLAPIENTRY +#endif + +#ifdef __WINDOWS__ +bool GLAPIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version); +#endif +void GLAPIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual); +bool GLAPIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *visual); +bool GLAPIENTRY MGLMesaCreateContext(MGLDC *dc,bool forceMemDC); +void GLAPIENTRY MGLMesaDestroyContext(MGLDC *dc); +void GLAPIENTRY MGLMesaMakeCurrent(MGLDC *dc); +void GLAPIENTRY MGLMesaSwapBuffers(MGLDC *dc,bool waitVRT); + +/* Palette manipulation support. The reason we provide palette manipulation + * routines is so that when rendering in double buffered modes with a + * software backbuffer, the palette for the backbuffer is kept consistent + * with the hardware front buffer. + */ + +void GLAPIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue); +void GLAPIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex); +void GLAPIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif /* __cplusplus */ + +#endif /* __MGLMESA_H */ diff --git a/include/GL/osmesa.h b/include/GL/osmesa.h new file mode 100644 index 0000000..11423a8 --- /dev/null +++ b/include/GL/osmesa.h @@ -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 index 0000000..9625a5b --- /dev/null +++ b/include/GL/svgamesa.h @@ -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 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 index 0000000..94b6197 --- /dev/null +++ b/include/GL/wmesa.h @@ -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 index 0000000..b25a2ac --- /dev/null +++ b/include/GL/xmesa.h @@ -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 +#include +#include "xmesa_x.h" +#endif +#include "GL/gl.h" + +#ifdef AMIWIN +#include +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 index 0000000..c9bb17a --- /dev/null +++ b/include/GL/xmesa_x.h @@ -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 + * + * $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 index 0000000..5c1af7a --- /dev/null +++ b/include/GL/xmesa_xf86.h @@ -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 + * + * $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 index 0000000..0d9c27b --- /dev/null +++ b/progs/beos/Makefile @@ -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 index 0000000..c25eb93 --- /dev/null +++ b/progs/beos/demo.cpp @@ -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 +#include +#include +#include + + +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 index 0000000..2310b33 --- /dev/null +++ b/progs/beos/sample.cpp @@ -0,0 +1,212 @@ +// sample BGLView app from the Be Book + + +#include +#include +#include +#include + + +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 index 0000000..c0d990e --- /dev/null +++ b/progs/demos/Makefile.BeOS-R4 @@ -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 index 0000000..9d475a6 --- /dev/null +++ b/progs/demos/Makefile.X11 @@ -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 index 0000000..69012b1 --- /dev/null +++ b/progs/demos/Makefile.cygnus @@ -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 index 0000000..876ce58 --- /dev/null +++ b/progs/demos/bounce.c @@ -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 +#include +#include +#include + +#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 index 0000000..b2edf32 --- /dev/null +++ b/progs/demos/clearspd.c @@ -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 +#include +#include +#include +#include + + +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 +#include +#include +#include + +#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 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 index 0000000..a3b0bd8 --- /dev/null +++ b/progs/demos/gamma.c @@ -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 +#include +#include +#include + +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 index 0000000..8d99a8d --- /dev/null +++ b/progs/demos/gears.c @@ -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 +#include +#include +#include + +#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 index 0000000..a61e365 --- /dev/null +++ b/progs/demos/glinfo.c @@ -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 +#include + + +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 index 0000000..278d726 --- /dev/null +++ b/progs/demos/glutfx.c @@ -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 +#include +#include +#include + + +#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 index 0000000..393197f --- /dev/null +++ b/progs/demos/isosurf.c @@ -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 +#include +#include +#include +#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 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 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 +#include +#ifndef _WIN32 +#include +#endif +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 index 0000000..f69cd22 --- /dev/null +++ b/progs/demos/osdemo.c @@ -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 +#include +#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=0; y--) { + for (x=0; x +#include +#include +#include + + +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 index 0000000..a36046f --- /dev/null +++ b/progs/demos/pointblast.c @@ -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 +#include +#include +#include /* for cos(), sin(), and sqrt() */ +#include + +/* Some 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 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 +#include +#include +#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 index 0000000..bd099dc --- /dev/null +++ b/progs/demos/renormal.c @@ -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 +#include +#include +#include + + +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 index 0000000..412f442 --- /dev/null +++ b/progs/demos/spectex.c @@ -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 +#include +#include +#include + + +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 index 0000000..7c478c7 --- /dev/null +++ b/progs/demos/stex3d.c @@ -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 +#include +#include +#include +#include +#include +/* 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\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 index 0000000..497b105 --- /dev/null +++ b/progs/demos/tessdemo.c @@ -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 +#include +#include +#include + +#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;i2) + { + 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 +#include +#include +#include + +#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 index 0000000..673923c --- /dev/null +++ b/progs/demos/texobj.c @@ -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 +#include +#include +#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 +#include +#include +#include +#include + + +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 +#include +#include +#include +#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 index 0000000000000000000000000000000000000000..8901e45e19bb87bc0f04047a488bf4ae1c41d556 GIT binary patch literal 89287 zcmeFadwg5zdEfcM2Oy=H@ul{}iF2hBH*KAJ+6GCJG)!|jVU)l^a>A2A2JVqU77b0Uj1wtu`MGFPz&ktciai2U+zzauj9+5edr{r}JP|1|^eY8mqt zv&MYoWn#sjyOm@_mr+*e{g_g-5GG=PTm}%FTU*Y*fKVi(Xyk59y z%y2qMKOgsuxtTTQ&ASJ_qrc8=JQ=5^-r^u5OPzS@|-^+(3sJ8#V2dBm9ezhlgU17rT)3&#BYDPw-) z1IGO3cN+7L_}p*t-ap~Jf3{)F|ME-5{I8trUwnr#|MEW@^S||s`8Qnuf9D$ij@N$g zF=KxJUmNou(4YU5Gv@#JE@S@lmyG!%=Ip<|&zS$lJpcFSOvL=5iM(ajM52y~#8ymX zFk&L-woK%aA2pFj|A~pb^_NWK?O$Oc@Aw-g@=n)8-t`|%k@qf|$TwXukw5)T6Zz&(naH30MHBgR|G`AQh1b9BYfa?apEr^3 z{3a9mt`|(?&;O8#{DnIv@;#x6eDBwp$oI8P!MDc)N*wVBAD5a;~3wi;4W~_n3$`W+FfL zNfYsT@8`LPCkiH#`fU^W1?YY9Wd`&3_(fyh&D?$!JblkUN8V43`MSC>-+;`#_nVOS zKSbXDjxpbiUi{h1#=PG(=39r5cVzlI_Ko?jUoqy-|9~-nk?()cze3&*jrmJ28uJ72 z{x5$s^8OEy_m3L$Bk<|Rz8iV}56C+__{lEve$$vl#h8m9GUjKHBk!k-867s}=eh0^ zzmL3s!kF|mWB%%xF_*aRFMgjfbx6yf5}7!khMW%{rvYM@Bhj~ z9{XhzdD|n%`+;4S#{x3{qh;x18w;=Do zi@YQ2f99u<_kU|5@2{H3w<6EqwqqjS@m}P8&qTia$B_5GWg>r(^TxTx_kPYq{?d0N z@0{}ozurXtGWs$6mB>5a`4Q;*QNHuz(Ce-s@Bhg}elmx=^ZlQO=EO&lcj!%CK;DbU z`w{XEJ)_@?ynh0DKSkEjgI`D@=g{=zrx{1cJ9GQ)zl*%@8uQf)*!C2*9X@>n^Znkx zY0Nh8oi-~A5c{U0Ll$Y%UmZ2Qk)+rJ-q|3l<` z$C%*)w*4<4@Ba~b|NF+c4P!=TjJW_$ej54yz+b|)BPTx_Mc)4<@{UaWJanbdgC~C) z+m1c_tN$H&|M$o{dNTg&$a@EQ|25vF$&PZU2BVALHIz zzhulyi^lA1Bku>u`xlXS=4bEskoSLwy#Frp&b@v1Zy@hn=inaleg}Df9eL;4uYJat zlaCm4hxxtB9Q~~^W8V0y#{4?xy+4X=e;>A;`~T8EN8XXye{kKHe|Qz!{xjHiX!~dA z>~AwKzr#KM^Hpqn2HPITwm*iv|6Sz0Wz4_lyubgm*!FKn-l69Yx%dCf_y6c^$UD6K zZz*g$GG?w}+rI{R{|L67=Yef(dmMTHBDOt?y#E*E{U)~k$B}nr{asVoc4YD0zhxp{ zwT5l~0Ji;6|`;d3O|3l}I_fKNmk@X+Bg>8Qy@(#T}5yiG+_kR-k z{;3~D-l6XU=)uJ?oEVtJ*k>R+ zhB-3Gt=VBT8J}ak$asnIaR%~akRvy0+-m5G^|Q!@u?XSq5@ux(uE3@a*{& zp0TM!@cny!_3U+hRRGSpJbM4(_w-%lk=&sFy5>&Td5xiC z&7a=?)Y-F+^}5cd``7(EoO{iqXl^ldAEHU`=`-k@oiojw=C94rxix?KjOftZX}Ci7|V<*L-(QQ=NUSu-q*SG{w(7H z*U))2bga)FGJfssZ^@G6Pw(mTU4~xMxkZy+(`R*^1BPVgp^WOB;-BtYpA)^JP4}pI z6TP};y{2nu9v;%Cxqc|e`o7-NXIp1O-xsZ#Yt4t~d&r-M^CS8+G|w%DzOQqM4$Ya~ zdyXNwldMSYBs&Xd$3>ohl`+H6b@VyCCwb9%bYAhe!4O~dw_X<=I=8-~>nxrfi$;B4 z=h0_%t!0L2keui}olmdn`oej-}?nmd>J&3l4_b2(%^>q(=U301XmF(+SL*LVV>sX(E zc)$9*=Az8dyy`r<*N5{Yd3dN#x?YPR9)FynInbQxSl`=Y=<|BkJU#r}!`CEJpJzO@ zgPPAzF~kFX_M!ahdY@+Kv-+-HKVY=Zj&*(=>odAfokO3KjDO~A?DH)7*WdbFo1yE7 zPF-K$kxc6Khxht$9(DZ|Lvtj$M5pHD;T-FpbzRAo=2S!Tr#aS~v>5u1=2q|Nb$!2n zcC7R2^OB84hU6*Fm_0iVc^+r{BI9Ys6eD2#b%x&4_~opjVzuK6K`&aLxJGem>rQh!e}bZ)(-@9K43M>OfZUt;LHGmL;CdPU!pj5OmX z&;Is#4j4bh_yFT)7{9>Kd33DL={rBn_%23FV=+F&&s&FzafdN5G#}@nYG34mv+znb79H5;CUBZPQBn?h&wzV`kp_^PdYu34ua>N+dR6N^1L9O&lIMg z%NNpqFq6*vxwPwfZahBBL-2_&Jm)bj!_oM>t8>JQ!;V|#eJ>R_8S`g{qEK|hg;sZ_ zbfpyL^FiPTffslK!F(#^1dCqE8}$Z~&@*x&F>)aYoDt}8o#2xriG-imU96gYO0 zqHy;-V{oVfJM}X(5HAhInd5jlD1G|V$G4rs`J=9LR6FU4!6zrjVzJX%+1lOOXl#@> zc-Uw}%e6+S&)8DA6m5JKzTT+7&|9w^oMeL_yS1^gx7XgU9CpHNrL`A|$?Hwnn+?3( zUcpNQg@RLEn9agr$E(5HY&I*n#H5~Rf+vE;5oCwIl)PgkqgOHOsEAeM%3 zw9Ip

6>0tnZI{qZeT71^o_q^R6HDN|` zro%w&ok*vUGS}T`c61s*OWq9e6L;3pCz2|pMKVhJZ$8Be5A({ocf z80RIOpygdojpu#W9Ulu)VsbJeg57vFXP@HE#f7Bj4#sO@w3|ZK+|*l=Mtb`W$YPq1 zL&m&V8`FX7M&s3By>obU_{!nF(`{PCJ$d8!GHnQ#ZiDxuI3d+PL@OdbNnwM#F)^TDer< z;%KV}PvL6x0*dWbkW(bV^J4J@jvQ~r_cK8N?=sWP%`h7OjO(WJg|JjAOk{k2V!F_n zb3JA@m6`DUXTx;v+RfKr-)UrgFY^?Z1~$jzQ8(rl{YVhWnQylAKv;BW*?T6;Pv*mX z3Vj_2s$3(DIT-bvWa&Z@MqXG(F-P2yzzy7yk(hgZ#B-&y{&dk=In>VtR6Ob8hOg?~Nx@F;|zyfJhAeNGfvC#GuI0R1Mk# zDQ*nzp5sNyG2C4UZ{EcAzT$M}Po%cT$ME&2d(!Q6tTAq2j8R&r;cTF=Q=U%HE%@%{GSB06d z6)WZhWwA93Bjw1fmB4pFrff{qnmz~9f{AhBOENVcmnt){ z0%~)C2ZvDZL};Q~8z2 zF`xUwz{-hp-ynqQc6U3w8;u4$t%CeseEE2 zoSe)C36U#SmM^8}uK7^2z}*bQD`+Kt6u;t@bbk>qk}~g<5}t#Z3rOd?P~L2PuiM3a z7LNyymb=~8I=f<8xzTjW3t?Dx!W*!Q1N2T$1vm%$obv4(H=1y67x9!1y6f#SzH_g0 z=haH3o+a=JtM;*RaM0>D0}0W*SBPO}6-WgIjBv1s!R0x$zEcMFU4(P-p+PHN6)f4z zTw#KEs8|{(RItcn@aIC*TS|*hag5Qj>-!vtY4{jSY}AYT<#c8|Q}AL##E%nsuTZMb zm2PimGBb{}EEjdJ29-u*x{zjmh!4eWX`qcP73eZmOqLt*%=;lJYCXA3RU8$~PNuM} z{$S8Zc~78Ra8B+~_H)E>w=n7)pnLjTzdA~7 zo&Ei8_vk2gQao}x<*mjRM%BTND!AofwY&i@OXWgohM%%i`n7Vi3{!7x+`1v-EbAQ3 zR1WU;4mz(C%Izjr)eG>S39o+Gy3wwevrJn7^IDT>%F2Oe%TBh;0Ung#BWvd6C>0UC z8~N8P$}OzOy$#1Rg~D?f)mULQBq}OoFDceV2XU}IJcx2o@h-$Y{y3Y17QQTXRN@#VRxoF?dNBFDFvYklNog@Os3WFC}MEN;BU0@MxrxB z2vQeSZakCCP7~V%$mhJ5a=dD4lvE`NlO4CD_%_PH>c|Bci>Xz>5R4$o1ht8ACwO@} z5M@>+yz!}YZYmwRelj6m@&j=}ek@1^KG7bQbs&CCR6!tugBbJRTG4yw8E?<*$J>e5 zWAReh>h3w+I{C}d@$u2gey6j$)!Z5=7YniSHNxAOjWabZ&2Zp^*UH%48jxs;zO5tE;ijv#*u(-((^yc&_v8fG^v5V?k-?|Y-^(Z{@NnuQB}mDT-PJ%;N9 zy`yN#_;i$$At7GA(I^B#W+KcxF2e3EKQ$Z=YSUg}G?+j%7LW==%e|`k!|!q`CA<-r z0^R>W(;&0Bz>UO$Rc;7<^vGcFp2>j`qOy@|#Jb*vGp!9g4jgx71cnCVNphpi7{bwl z=wxmR+r?{142Co_2|?L0*Gs07=qwotxw_R=YfGxgtv=;?Z;2bFr_$NSWZlSfu4=M) zpA#YF!L3`}{r#ik=+X6)qy3XkyF*^OyS3HEeU`Td$z96j8K=CCVJ`3sZ*ia2b5>rK z4T!~CLD1}+bn5NdR=wUtEW-lI>&>>B+3a2r&Ssp2=dFmX zeHWU^VTmPmZn{t_%;cY%o|#G8>5In$_o-Ui^XA;(Dfv(=o;M&ntQ6BjWv$tJ9J*vc z1|HILP4sB`;_mcx7ESe?pn{*{CpkKpT*R4Itn z=ZLE+H(!?dJ&7KzcJZqCMj|2(_MFbr7TKwFqc!4794oPHX~rq7DmJ=7{<6_pCwz=@ z-korr@3qU7%3hb8rBlX&WDC3NVc3SR>o`^qq<~o?9=a+MjJ~3C4xA+*QueHDbg4gM zmd1Ym0!ORyc&41=!(p^g=X;)aNdc}7vd*Q_D2d@YZwa0vs5r-qR9o^s54T-tNAv*RgP9td_)MC8G8m9-EyA^11~u; zKAsAOUEhasQobbog!-fn&CoiVqd-s!Q_fR75{H%j=nR|oHm2JddaD$9FiyrW+ue(H zE5Hf_NGIea#ZI)lKwKN^?CkEXH(?-|Cpij_;-P*^jT_}=v(hSXW7unNw%K;N?fs3; z;l1vQuO4g`!fd&HaM0C^UpL!y3E&6>>tHw7%GpW?!a%a&WZxoNTZ}&rS^dn; zP8OLJFVr}e1je5#%vr!_M#@a)nTirnEo3jj!9_1SksghDFDhB_eC2QUS8PnDGt()) z@5HZThn`9UT;aV7t()2McH`No*Tni_w(A9dCLf@e={RYs;J`JsBS<|3K#_SW#S|+t zc`t5M9u(jbn))f!ay*Xl#9j(sa`2<%pHZF`QllwnbUW!`en*sllD%MQ&!VQ0zye9* zWA5P49*j$H25I=*Wa@*HQ=@3&NOEc_mCE8yf+RQK;#o!5fLnprVtx=ed259h>*jV_xDLXqusJa1-s74yg=Wpz=U1Epxw^CgL}OSZv`R|H#y~{ z^)?ai1|s#c(quQNuD82~cY3!U{N|m5S33s>yKNpi#~knNH8)%9XsHrL*9&F|j_^Za zEL+4mFA)3^BY8%XCoA`uG((tXBTnAPi~XN?kdua1!c-W}0Qn9e8dr&iQFI^F${8*C zG4DE@g&97X0NkC(6Yd5BoQS!}P2|H*e4$Z#>Hh7;cFAen$X_E~DsenFmwtA7!u2NP zxkwtGQbs=jyhxlEb4g#UPanc@En1V?=j>W42lS&L9=s8wo3dzxlUl$6JE>9vy>*h% zG;#x`0w?*zYs9={q9ib!>!Tv-BC0)iEf;QnZe?mRH8qt@rl+RT{?w$CT1t$LC6S)N zcr^+9q#ykHg6pHT^KtJjuF{2sQac46a#>`1GQs%rGyE{yQrzntFPxmb;hYdJS?+=h z>bdK5oZZsK)-EYd6)CrQO-Q;!s1)5O72rWM{;7ofV(*xmz<&4OaDTV@Vyjv1Jh<08 zI6OJtXmxLeV8-cTN4SC zy=g(dPU(5_ssa$hjKU@2xB{FGNi{$&f>AFGVuVYTf5ff&{DM)9rz9TE(5Hvv5(zR?o8kBbN<QNFi1(g5@tYKzHj+g2db0pBt2$;JtgD z!_&idxpmOaw(cBM%Ae{T9(J0WyX|IscMs>92pXR%+t43ZM5+fvV`8Py-M1oRQi1b4 zQ(aJTX5O843M$DIi$d&UC9uF!sjs4WInq%Q8uy%6^U+NYbdT64HuNc&;iW-%=StO` zYT!*b0(bfg0Jt~Ss?~b>*+L$?ckY^p&8^(<9#c-LIT~=y+pQcG<6m(`iZj%Nao(8k zXSp0`fS(O=Iieas2H(f$!hMtyY~70z8KH=Y*vPUND2xGohuk+SIro7W4TqF)BmtrP3qF&!rH31S0A`z&f0$uw5gMZo^vzkpn}^vRs-VJ&1>W zXsP06clWv^F3$1%$)VF*IPJaR^vc5PdvMa}mO9502F*&n(?KHk4>}v=7mumJRBqlm?CrI>ue^Bk)!l=QY+%bjC?vXQz}fC>Ki04UbzIulPTYBHRh%Z^JQFX1D%??2K0cJiqjqZ z9#Juf!NDYOI?*zy5~VnYi*x+-Tz(SEl1;MOh5gO@9(cPa>NG$@m% zV2!NHL?fk)7E*ACGbCA>t9M%dMd70b8aAxZp9fo-a)_ za+#gmnLZ028nL2xzMpu?FX4!WuIpq{0nMA2LOsb-vK82vd-_VQ7|j*a4iZ@*AN5kc zml#Mcz{`P=%7rJNL@_hmQVjTGBryhPNV#+KB7PNSdE?J)&ZhHobCY3daw<1Iw=%Ba zd;!-WtIjibK(&F$7PDnBqq9uzF{_H_FkRH%9HOA5z$2+RK8&6$^iEHsy@dz8(}CXl z8@-dBJS9cQcin*_PU6v{f!1*I?>gweilMDX8gS=ld{4d{4SDj5ZqjFVQB zsT?8)5j^;;WK1D;!YdY-_5IRGjU@C@(U2kTZ zQ_Rf-PmNC3@_{$uh6pL zV+xmoRPxeTE(tb2axs|OoDH8@*_^u)PEO@l@&u)8#Iwpx?8Ql$&>RxEet<1-B?@I$ z*o%pQcro!ve1jOI-UWEKd^_#+_`QF>cfSWq9Uuj#d&4T_Uc0^5-UTZY77q}3<90c) z7TQKJgt)ElZmYFP_Sh~{Eo<*}_wSq@bZ?%X9v|O1p}Z0d5{<~C;9Qg?66Z)g&(!kK zhtZ;-p~0b=Bp=Zq<{3>T0wV77W(rlTDHgR>Z>-hV)>c>7RvUG3)+sFz3K12PheWg0 zOonL%8=%NE;Di1s`M3Cr_wngMVS4&m3|!u)V3waNY~J2!6v{h0*RS8MwF*jCt==89plc;!m*N-h*{9e*&W!7j}0<;#Ez zPNIwvMN2^jffk3XAFRUVvA`P}8+F|Eq))XhNp`X_HL~>8DKJKd58@S4823uG!cjnZ)4HRH;+#aP7Zq~Z}fT(daw3Q@7@t}@AfRKouj4w zBOr#oPIPYxyr|vYCG7b;`RGQOd|Y-X0A#^mg7LSyo3IOLw#nmR=Wb`c)jB*qxP9l% zJH3Owb$F@zB&mAI3NxvAi~-gW*hY)5lb?#xU(x3(reqTiluNZn4USSz-)?NL?ZAo6 z&DG7d#vq(r#ME9QS80F|<$;Kp2PG$gpW;LcNQWHv6F~gobV1zoNiun?mYRi$>FL%^ zqjdZAFEko+6JDSxL08F8;*Y>jQWK#Xnl>REe}bx5d`l+W9igRVDwogZ(z)DhZn8L6 zTbWy1yHYFWoa{2rg>Y6yv{4+=K$39C2g_BS;&L+O){x`!iLvac1}K)=Kw5r%lWcj%n#!%{f;#oqk~ zy$4_V(gQu6N`vpxbcEgQcDjJO#Izlhw$*OHQ>Rh8Q4TrXP#ms0?q0Us>}*vkS=68E zW`RVcbNEWHT|c;Yc={V}{>Hsqb@@*MNAQKmR4`LCgGW^3p6>$h({r*xzwWMKgIo`Z5Ia0IIXCBQu1ro74=L9~ek?tzqN!F87gaJrvcVQL(=9U2=@q$qGN*MJ zZQUnd#zfvEb?hCUoSxo~^;RD|xPSNb?x~D2rBSldqb`U;b-%OU-rqxQovj6s0yQ6% z!+t?q(!Lv%=PE67mJs{w2B8~vPv1DW*EzTYcYpKEyJa=|cyun5lpJ7E66E1-V$drF zZ}C8LEtVixfhdx3iNO-?;?N_iE|tj`Yt>S{z8b~;Zf~z{?riR0j=}0F1VzIl3QVk& z3A3YwZKJdjP;|2z%voq-h_6UY{L##Gns69%weAkb-9o+GxLIo4hP(G)Z$kF4Y_`SI zio?>7VGEN-`yN*02rd;c14(&hj(M<-E74rNI6Hf#HdmX&9A~MNI{rXF=YgNPobr-M z^3WQ-7OjP$(peR*Uq)a&|I+vvwHn-}#Ak?7M_Ta0%G~DW=QfqY$SFK(U4EQ7wp~-8 z^HN&DfC?v}h#y=l=Ts@KiWqpi-D6UeUh(97Z}C3-gsmmTNU`n`c_|in-`QK1f2BQ) zSgG6~SOP5@+T(JfCR-@%wJQY16i}P%yL$(B?i}3db?)5xjk~}3=D}s9;gT?5hLf!` zr4+O>!KiqLBO3Y`cQ?$OyQ$P%CPR8dW}2QT%r$P`ZhT>_?%ZBFy8n6u)ZX^m4TyPt zD@VdIY!h^4P_~!jF{p`Itx&3f8S=A!G`C2Eo6GWi1r}a$ax~KrCZu8jfEEShVGRwv zj8jd~E+pg2eZ6cMrfvu~b$Q&UwFq>cymM-0W$IcnTv^%t#OF4rGBg=EfU{pFYQTki zHaJj|iPX_H5s8E6vOgsfkltDHPX;hw8PO8oV9@!3DoP zQpQJRB}20cFg&WKJF==GONw13?*!|c&iK=K-koN?Fn{~@>nL50*12<5a^HpYzGc{a zHCMN(E**(BdR(OfnZiHjfl!Hh=sle*!lf_=av)qu;Z6_?q?QO(F{*^Ki zrVX(n>?N-XxI>_GOk~3^j5=X}@hA`JU@%Xj-DQQba*aY}oxMuCg|4;Rz<9Ui7iD@; z@3>b8)CyK0)F~G>@7)DA0vHglzH~x;G`lYBNu>t5f}jv~(RPErkvt_5u*^ujzl?k; zZsZTmJuDRFqo`vYSd|R3sz{a)h(;mMAB|{OgLMM+q=3;Z07h0V10K0wemV$7^LdOJ zcBLP~6997MsQ1wn(T|sU_GYtGXn_@oncFp-mp6fTvCkScvb4PN45U*_cHL;0jGZ`fwq~*hMHy}I1*70Gi-X}^hsU;UCoy)Dluxw6@Qlb%@OE$po z09);!XkZfF(VTcWc{vB}>LZ!z8`k7t1@uZZaW$38hEria7$c0SP6pt0qXanvh|Sx% z)WZwM5SX*Z#lFF$(xn2cLjoDk-s~P8^K)`)GYhF7%mOK2Lf@ozG{JX@{7pN2_j(6Y ziIpTi<)^&|gD{gs7%C?fv4SlMmE|fOdY%0y;b^b3`O4{?yZF0yr$XB_05fKe*jo|S zqwbQFkk)C(qe|Y-b5%|y$F*HbNV)!`na3*^WIL<1ItmvBYF$CM{7beG6^B9b!e2~f zRr(6A_dVb!u7@Zu2uIT%=h*wQh!dlEUXDJ!LYO8TZ4{oJ-}%Dk?M5MA%4BMDLel`I z2^Zq9$_n+oJM5@h__!oq{!ZGWBbl`u5J&9d^OFm0E(sv(1k1FJ@H3j=k&bC6Q5vOf z&+%@kY=R}ar%WatmLt?h@PY|~)0{sV&Rwgm#h#`?r_+chs=x_$HZ&5}nHG(G;T z_^MU|sb$eBq`ETfT%Hx-&RL<8c~v9`UD+wYKNWnY4{}efnjXo~)Va~p6PCAByPXtn zpW&nkPE$mxsmo)DpkK&v;va(|I1SJ~GLoF0%+Wx-GPyEI44d@FGNZ!mmd<#@712%j z`Y1%$01F~yR2_m*>@ESNJ3QdlW{=?|Y{X;6PD*g|K$zX?1QOe5|O+E196g?CMP%N@^l4VOn6B(!&){fxnPPPMS7gLc?3cfnPSvvp5>M6 zP7g>{|7?*Be-6zl@4nB-qZUO1~@sQi<27 zn5vS=d3CUeFn-h?SD`Hy*e5+TklVr!5YPsx(a|g^HWugBdwp)Gho@342b_r^)@K#LjZckjNYWD?M)3!8DX8@n5{2m!nb|4~}0 zl(HY@ZUj;hsqTy5Ii5mXB_%U6v-|5!BIHWvUazaJ0=M2E(+=E0ZzX|OWiWwo*`fp1 z#0j2y1glq-&RK+ZP~Lk6yZdP(+G?$7%O;oWS8 z84Xu2WvFbxSt46-I%$cRJFJc`3L7*^ld5FGi8Rz^>Nr|oaNdjuzwDt=ROKzDyW{u$se;#`0N!rgQ>ox?EOnD*(^+?CDED^E}IgH0Yy zu%IPLg#ul6Qgp2ZqnF7i;Wb@FYD4G~3I%i)(D1kJ)AyBOT@uB#@o-YXE}f%60vgo( zAVdcL7vu9^rc=4+ms5ixHX34MLvM>;mzoK6i-(<)-m9?t;52sP^r|r2{=ODHx&9g* zCi=x%Z-Cu)Y==>kSZfcr3)e|(S}pbV!FGjmG*3s%FVGsmilip+ZKv9K^B#e5!3|q- z?)}w-FgzH*YA0L*4i{hPIf;i(*G}f2vPrTNZ%CMixUpeIP_H$%YfhtBkJae5o{1Jp z6O)r;(aE*3)Z_$<1yE;o_<4R*xSxzSKk%JwW_lV>f!ILCd(*Xg@A)M0nRLBbFXUc+ z{iaW56ZfY3h>F4}>Ma7eOYnUdzo#H!7{?-^6sI4WAWlfHC^H`)N(tygx2M7w2yT%c zr_$upPd^cTdijabrzc0BmSQI_P8{srY25&i?Dr!zCiBB z9Z!Vm(7(8}i4#sRgJVp{pknqub+U|S)VW4HSHGGx1~`PH0Y2MM^AVFTZohbVfbl+X zPGY^qL$UT;cmB24obCb!+v!y3O=y(2w&);RL9ykR_c|?%c(gs=$_iRkM;z3tai00b z_klI+wY%MR>p>4^+-lP6r%Dxzv(bMT*;yk4+aSsqso|*x#mBiu?m4VnvwCST0uS?9W zhKu8tQul-TDN>`UXs%3OLoN^F7de2s$;uN?Ou}-CxJ1=-HDJDDsfO~W6pe#p-sQ2& zL|=bp@W_RoRl!YVBIZYR1szqJAUx3v`o9K@Crf;oFN3stmQ z>z2_U=iU(-cum{8r)ajm`63cQKSQ&i3>e545kskMg_v*}J1(AcKoF)50T~8S)^Bi= zF?)f#kc0+}YQ0`&mO@c7uv1oQ6Rkf|MQc#+SMlYZNqoY=p;qH94;AE>oel$Rz zClDM2U(8jI2%YwE=Gii6;bx;i#;esYQd7Z$klD|4`$qtl^3Y;0N~b!Fa%QR0`j9u3 z4?_$$+MG@kd=Y~w>m3-a2BRz+ly{CLS1!<<0zin}W@#!xHHlpXo1LQgl6*vpEXd{s z&k_}keh`-wPT{nHgQbi8Ao83I!{F?r%8^8pHBfTQWWDzGD95n2m}nY6<7(^p^t5;S z>dDDztoQLZj!xjC40C&Lzk7Ik#7YVpQ#M#6L2y+lW33gVU9*aeyWXXBNbE(Aqwx-` zl~I7X<x7*?DaffAWAzTGffGj`{8X;m-;b% z1v*WgOl3NgwNZDB+yfVFrPH6lRA*?wFR`ADGg;tI^4o7{c~m@BMnx7XYDCpp&@NQX zi8uS~m9R^xRWP5VeD35{SmuE}mUt(pLuYQDCFI!!GAK?=yD$DYg$0sU_ZvnpSH>=T z3chVfZ{t7A^);be1m>4%>Ln9IEXbXR!648=#xS{r1?6_hXl0_Tj%)sGj%B?)DLo%A z!uC~&NkD1+Kr#5~`CfxC41RBb*)})Yhp%+^DZ*WEZrP0h=yyTw>C@*UPWSV0ybpJ^ zH~0yxu)}cauy777jcXQ4mEB5F4Y;l5rR#*xio)35!A%F5Dyy!j%H2q7YXAji;x=qo?BG~j zgeYm0vgmkVovB0fg;-@>9iSzPreHrvP=={mh2ion=-g7)ppd6b#BtH}%69{^L1A(uf{NJcEajA{$} z3R0OAOg}RpuF8d!gWO=;8y};UAEi&mQo-U5ss=q-X{D*md|8M-Bg3LM$p*m8ESDy62Z&}p=tPDx75)86jhMzp=Kh1$~; zYo`pY#7;YfkEmy6rqpB^T(hjmjWsxYfPhBJE8%ez?Wfz2(5$Rt-dPLqBYhB}pUgAe4vVxw<56)V)9FBt*uF>aBQ;8rGn%A)5v24jB>vHl7 zti3t+<$`&NDjSvUG#!d*pZy=EU4Pgj^lDDT6OxNs48T^jzf9RXkT~hx;*gi03J1~R zXl`9)1Y9%N7RsCyd+ou6DD4tSRS-ytvA|AB-NdOyFX;uBW69!(#D@EmIb28GM=e)U!S z^}Tbwir6biglK!0g&FnzBmSglw8e|SU(WvOURzl-n*eNVG}S{YbPdcq2&=5x$O194 zk}BIS&;Z=#m?)a-5fR{!EskkxMFsW3&^{`auoi{~8yA8>0O`oFfcHFAuU>Z=B81bNcE7Rk2D`T?`1JM+gzfl#?vYNG3VvvX-f$ z>YY}?$dzPy2Z#pfh{aTd#5%HrRHoswwxAwL3jlB*oT3x$QR=zNVWR))dudC9<@!fr6N5r^;#htOD$sZ zQe!M*$rdl+TElC7c8aHr94p47!TfaIq2l@xC;+CV#Wv+r5n>0PiHUUFV@4G?!)a@2 z<8KwNWtphWYb=Rcpt7bThGK7#jXKd#8jmX{3a?zj^wNM>tU0;LB*An@932~7RQmHo zls5h1Xe_1Gn+mRjAg0E|+~w5eXlfBRI|Ol#tnDy+e5i($WY-;(e8}}B+x>J$Du8bG zmq}4jen_MRB;rGl3EWhZL^-Pt%hB7KbnULos z4;l>TRmHV?3M>af9BUWFz#oTk#B9;UXdEm>5hmzGLVNt3!8d+qi1 zCf2qYSkYB*E?O0$(6cn7Mdt1Ga($~A(!qprv3->21A(z!bg@MGtAaIqC8a#J$OGHozFg1rN%1Ri;in)Q{dFd^Ul0-=X zp>dKzRw99QS6{*lmZ6$XTEkhkksP6T2&t&yL*2!eiRIebK%A$}1+7Bg-f1(HSbPO= zkOHXYasE^2YYjcMHkkhJXm9D>DQf$Gqs2GSUD{=0T{_m#+9J)w%di|)D;3(?8)%o- z$!@GI6+pTu{UiXo#zM8qdWV2%Z@s>`$wCb4vf$)ZRaRw{gY0?YB_MJ_&FGf{7`3SN z(;u4wOX-$a3pWfi^uo*yRCpKe5*Dx3xAoX)+^nyX1ar8?%4l^(!QKh&DzL;#WwCld z%FL?B3;@amn|IjWCA%h&c_VsT$V?P~7{ZB}XP*VEwrNhkmZL6(dllyW4Bel4BSa3Yeo!EQw*)D6i$ zV)3>5Ar0aRoaiQ2#vAL+pPoAC^J(vp^q1u~i@jqihS4s2MRc#K?MCW-!XGTP*;m1d ze0F22(JTzuy?aEMj4wLO9GBP2jdiDeLq!Q|cbPeUOP#Lc`~Vvo>Gfan>sJokoj1xD>6;mu$Cq7@k9!**`Cq zU7^!0A57C^Bg8o>pmtb3Y#Ar)P59nKCZ7jPl3%lt68?)eacdiqPd-Y!RDYq1C_|%F zb(IX-kXAjOGG(++k@_g4$`Mh?`R1JBd^qP6E8$#j4qf*hn&AAbhyCs+1Qlg|vS=V0 zfjSsdW2*Tl5JedaL0ZFt!L^5voH07@gZPV1`_RY#!47CKj=^WsWBzl)S1S~R}le#KsGBq1ilYyL#3_Y^DBhtsUk zh=UL=b5d9a`DiR{?^%iv_4UdIt0C1{Y_yNJZ*!w5d zTxD5_0C$Mrlx3|@w-PX2Ki{~vw!OBwy1ltZFF7$7uSa=9dr0&fs~i}wp#@nO@a2HD z0zrn#qHRRA9l9`6^D%(pkVg6J$Hb~gHGkR}RgSF)Q7w&{=ive2MC7=GT6+6G{QNPA zCHI-BDF@X)pW7(T7T2!K(jbi?2mP>3S9D(i&!!ZOC|_`b>r!f^y{sNcT~3Uv&BLw& z1)ZY09A5+FPy@htz(PrCB!5huZ90|pw)A1ZBSQw@QWa1pOj?4C4>7s(SyoO}4o*+$ z+&MiN?A0EeKDdkZzI!ZoFTSBZ59g>1bBVX8E5q!Q*bxgtY+DbY=9W^U^=74+Jx~2u zX(hPSJd1S7YfS-MDm<62>BF(BHb(O=TYJQtcf@~qIA)V2k?C;s5{k4 zqh4ptM_pAW#@cp$dvj-d2k%^8qsyF)nFz*&PU4b*vgDvyYEu}<)&iP%^7)B$Cfzs9 zxCHbNqM&BOgSlz;v&+Z?LL%4f4{pZhy1Xb1hzNTKKO^eS_TK1!OfQI3?$46yvESj+ zl<+J;mGCh4!fZHOo12{zpNo@J9O(eDE{sBiHj2}1pyycdsN!sDP63yy8!PnS5D%p7t-sh1qbYK3Hod6OhV-rhL!ZoTq?oQF>oD+ z8P;#rXbP{@6oxI->pZTIS=9-^wd|)+cfzX$;7ki)(bctx)7BoCj`)vue+=bj>6}1H zu~)zRFnO9HsfWXcPxaPU(_m)`x|mUSRNemSK#8=ow`L2=TQpPB-Yiw2 zKBh{A6KrG&&hg{yGqO%gts-+J#>l9mJLr{#Csbi!QGe!fR`6d<4}x?0<@6;^sUIx< zuvip}-x_+VQElMOZERkzU%$S&LvX&0`U7RNNL`IWrGnPkET!2<29^(?{xf7?gV|MD z>R8`L42}Vk|L9kS9rt6(i{m(TKSSuAPit8f4D5@CE-y{D%OW23O&LXQB(dUoA6s8P z`?O93i=cWaIhCJc@5J24@ZqdNVEq9>`YifCOPwzimO z&lsBg=0{jrhA65`1$M~1l}7yWaVL3Q7_=l!@@6MW{!igLE9nJG!F+-^K14r8BCaiP z&nXOHI^AGh5zU%A`wI0a%2d6(76F6rr}tPE_JBNX`-nXS0J|}xB^b+%y<7!e!!=A#=ONT%0#%kT z4Y?Ccpcsz-8l>35r3B}9WRA?6) zadh;?(K)pqPXO85+bmC6tFSB(P1jDFFTiWK zIx2%mkqFmKkROI~v>6Q$y|0GTa`UXyCRXwfzp&`Q4-eROt5!jX}SUXoQU+{2*u zLa?en6u+1pj#^}kIkQv>WK)*Te8@5hQsYU6f01CAvx(C6zS4?CZ?m1HiQL$2wc#*#De|n})StGI3q5x~T&fo7 z{?tm|dVRCbTE!j0_U(H8=3159JBCfa#QLT+V!2U2uay$)SAvqqLbhrM!wfac(NR(~ zibU}^TbDBx)`as+qpKPLo?<7sQI8iF@CB49Ig)-no5yn6>J-NF%Va9;)m%QTB51d@ zAsQ~B*n!$-=-KpvWu)<8jiP0JjtHJ@ohOTV;`IPFuZ?OSI6OT|deQYDPdB%;TU9L3 znaeEKX9JX|TVr2y>po=e`##6M%j-_w`NI}0kx5-l#JL! zXar8`ZESyBL6&5-g4W>yj-M(u`z!Q{_nqFg`*-gi-$fdzSs$_AYLC~qvG98@-`el) zwM*(NJi;=N+zFl2;u-4I^cgi-D07`T*WwtGblf|EMHco104Hp64P28&7`aKPA*6SM zwv|nr3R{XTtrqF(FOrj^9bk~lv0(uUw&vDoF9JZ{#<3#{s}4Zx=H_))1k{X%SOyF}t4WcTtL$C`8izC}-5@c-C@GBg*a-=^28++q9o~hR zWFUjq4sbhp1qnj8|CmfHEp`e(LGLi@meka^NUgfr{1gs9H|gX`1b0`Q;_4N$Io1dx z3nX#`0-u6Ppmi@dEyml_c2dzO4qxWp*CXu-m)T8_o)t355nsWaB^H7%#@wq|e(iEa z;RJu<+G-I9N0Rv8S^GL zQTKVd0T5X^0|G#W(Olhvc|-9uPTwY?n%wA+^#Xmu-^!mX{O4sG%BWFJ>oqXztW$*D zlR0N{3zTklb}pwp?+VK}ir{$KwkRNZXY=y}n_vchG}}72 zCmgX#Rx$#FcvM;l{@tuoUa87U(0*1|c+hWRFAGV-c?4lq z|E)yE^KEmbH%w5cK$Jym(htY4=9u1;&;LMyHpx6#a>@h`Rvgel>mjhRP^`cD3%B|d zW5N1MX@$Y4XzB*j(fkrEhKPbXl;{}GP0p&yb|rUZt#&1}4+sN>ALS>5XK|gvghvSn zs^t91V4NKUXau0%hv6ndP|D2JSdz4Q(f1VrdMFjK|2eEB`-h4mEzUEKqI%N8sTLy!C)-WMBE9 z9>^#WsP^j}eUMqf06^NXvKW+tnvt11Ce0qab|pERx>%S!K1`qfb?BkH zT&BQ94)|5Z!T$8_jFksTixNf|SQrkS5D4JG>!MUY@nBd{<|pGUj)t{b4J(eb=)6{& zoeSp(3a|&csY(9E9B9u0ZEozTVQC;(WVLginjIBiwn<}O!^>JCOEk#ZcyK#eEH0r0 z+P#77!d9RB!T0<)zitv2Wc36Bg!cR~u}aDLp4Zn(p*J|KqZk9hWk2$03Hhk*9y zd-eNlAOZg|2)(<<_wRz~KL8yP#v5(#ZqbtpvWpb}h? z0!-r?e!p6Z)nXvKc!2F~n9s&9jm_(;n*<2kYd3)a2m*2YLI9$Q2G~xGeY9o-?F-|* zsuWNG0Z{QUfUVf+rlM|(rEoy|>N}qZ;vNgTAcJ3z|E(bIJ>>ziDBVY1Esd7!hcpsC z!U^tx{XU2TN%K@5$gu!Bmb*r3P@G+Y?-XZqHLw7uSf2$2ATWT@mqF-B`c{}bwx6I+ z18+c;woXu>q8)1pU^fB0NM-GqxTYnwfcrKV#BYrfw=B39F+l9ihTy7FEE><44R~p} z&ZZ$-Xr=C(=tpk;_^5MuNZfZyc^zYLde1psy?;tVpg((H{cKIJEG$9s2xU| zu4!xj=+Vod{(ysfo!xe8t5TTJ9ViRn*Y>k14JR;!^TgCHVFV?H-fCJ3BWq1gmU1A;2H@YsVO{ z{b)@jR2Pj<=AXw%KAEpRfoL zkXr@~s;ymFTPv;=$q*|PkYmYlgg~@<0;mX8?3~Cq z;0|0O1BhjZFBVJqs({qvDQ$as=FNs!vuw0X*vbx_7Q-$(6KA9GH#~Rm~KnU;9e_PkXUio z0ODYTAm~RAvS)%a>5z-_*=YP#7C%kSQLtB_n5WNX?h1xLF=7p=D2D21F3!!Zu(1$Z zMxj8Hmu*_$VIpt}KD|~80TCwXFglKNU_)?ucPP{UN+D{I(|)M1NW7?;UzrZbgqs9v zgqOa$u@2GRrKg5KRP zffy)%jGcZ2IU!8gr%7W^YZC+wQZ2-pQ29MsI69&RyrOb1|E*cSi`WToDd&NBo_}0tsvgGcT4{hhFpTu?*4QVEFu`gY_Jj^dYpb(ZpWqzOmR_3VPig8 zT`5u2h2J;p7=j&Vdzn}P9bPKpMNuBFlLck-Aew2#w5=%h^v z!)Sifr@#xVCqsrY#Gp8uKAu_5WI z>f8Kgw)Z#t+huPL_WsaM{p<)uLa}tj(ON&FLj+^V8Dz|HHBz<9G2r-uLkxy;LE$P) zK|7T!-OgmY15GAqlrCU3waR9HrS9oJW*_Y9{W(s$MQ#w953XZZ)yvZtviV+7AE`{gbE%*~9qWLxVQ*sB)wfq~uE-jlzd9jJ zK&2h^&9Bd2UCT*Sjh0MBN0T@i(YW`I6($nll+(#8=>Ya~W`hLShUg6{c^GcYWE4yj zH>WmYVi!o+r1w`zh7Vfj{0Br6CGkYakS@i{y=uF(DnAhc@L1`6=NL1vS7&aRzG75! zKnOUBr6$qBX;y`()Gt?U$|$hx5D`O)wW@Ub%le{83Ee6Qi1)N>=Eh5?b&=&p-HoHY@(8Y66KbBGs9QPk@vk z(+rkl>O2L|F2MoXCVlsBVSCkcj5GC2=B{FP7-)!J(r@AUwez-0c^&y*Qh@)A+-HI# zO2E0?!y0%?0$34ZBmi#W8{$FF=_aEQO;ynFJ0w!)!)ODvKpXE6jz8Gz3eB2^p(!-9 z5#oVzibq5QDBGdXoyjV@yQQEUdbQ!fviM)}2P$UvRFy~3!3W*JU!D9_Z8THqR#dWu z*g$DmGAT)^mUCD=Zk0$2lL}l_tQfhE8gPzxa1&Ir)gk+TObvj>0|L%Uft>U-IB&^6 zV55uNL|$HqNg~k10^@^x-6WZG62HW*0fAfks|wU`bK;f-UBr>B1dyc0*PsEdT&>W&Gi@5MD$sQ6#Ce+ei)bEf4X$pNH1?CVWlPX!2Eo%B+wbQ98V5E5)XwT)?RqjFO~Op2QP>F!~K5$SF}$IPWDfoZ`aO$#geB7 z0jq)n$eN%hg`@}IKzk>35npc8L?V04^grf^VI^!c+p77f-P_#kVJA9=jh^Dl$H$va zd#txfOmQL1W{a|4S&G0MZAP(_R^pJxZf>E(C=OIN6I!GYq9m+>!s;VQe2uUWeLxxX z6BpC>=6}&SEY-G{7rWEj>y-wzQ|F)7p6-yvf8Z{#xljN@Qm9}xZEPV1M=(7E~=a=}9AYcOo&Tu|IAm4Q{Mcr(T(``ey8C(=a1fq(+4irAv~jUSi^LPn_r zr0Q-RbaTJ@?mKD?$^<#oMt~U|gcW2itV!x&S5AkC5r>c?c0GXe@cL@uK2Q==+9I0V z>}=yyK0d~nz3mfj5v?`$wD$dL1Ewz6Lc&IG8RuL z;D<$^3W6X*`|1|rfT4wzI+$-UhO$+r4jF?XzgAwU@M9%(7B|v!)cneQq;SlF3TuQO z$pL{7$n?s$7>?I8&u;HQ@&=-{RQ)4+n5dD{mmsRMBgzQ8GKhoK3qC)A3_-f z8NvONlfHBEoni|(msVvU<3az$yCeX8w71K~E{R!bEoI0t7`Um72z^I`YY_$x%rIK; z_9N^Byb6??LU+W(CBLPqO)5?#73}XO68Aip^@MJg5`8Sh%~Geiz3FUkV@MnmTR28} z^!ScHx$SILDc)~mPeL12<+8K+Tv1#9R^&zyagJN3)HcS&LIKkd&M-1aD)@qsAnqn+ zG2xF22|ArVBlSJ9p`(gGMQXMpo7b|;QIQsK3>DPICf{)>$v;$E#GjnI-p?lS zUqU_4h%%i)7U#^%Kf8b;Fe4OYy#5YPf{Fv@^2@99OY{bk;`?jd3lwT8d+N%u_%nq^s+y2gBaW&OD5wyEPdaT{a_EumKcUQ}-&{6V1F!*og8aC< zKP>Scc^6c2MYZ@yMEPm|nA9^1d2U{w^n}NBVVM-vowWO%ZN>~^M=;;=(dJ{S5H{OA z=XkBxM>e#emP0ukm=iR{OwSU2LO_JKNLQAq8;%j}V-k(_(h@gBO>rN)7l+0^hOMn) zzS-#)Y1grGH=VMm7MQBFtu!ZY!F{AJ6k~;)T6_5(*gF`0czINsg(!?&hV56D5F0C) z4~U8TD~n}RM%Z#HU$iO}^ak>yzKO%3j1=}J5eDqdU<@ZyafdB@4p9apE=Wc}8Ng)T zBDd$@Nb`u17%n}T$;{;`OP{-gGzHWxov?wee`YkAK7w1m90?V~g{qLCj?a}UQV_C< zyg)uM(2Hhxa?)2T*UnYzk_lf}7f=T_=&JHjRp{oebG`oN4XWV@3mT4`lhxA~j%`~( zXT(mwMq;R?_Bmr0sZ(I$sK?eSZXvBIV^=9aYoiRp{lQUbclc5kNZ59AYF;4DP`Wzu zaFKA2)SS4U6bh1X9MAlj?{UJ3Jc6R#K77Uy-DbOYJTA-f8RS5`p#wd%m8Gn1ANSB3 zge4IaL;^jU7{k&k$w}&w#vqOj#$6Dm4hTPqQ>^MGlEbmY=h6#+TlDsLY}tVB)V={=x#lzs@y8~HRXwJlV`$|jSrm|e_Y!VLtYu_GiW z?pHR;&Ssk|MUc+RR6xEGH?>Z3)t+u)Q&=?${j>9uVaO~CDpN?ToiH;w`nNKRGBMIf zXzz!(LYb6BAZZz+C|{(5Nq<8Ro)mjQBaTj=K`DxY9V@}~*)QW@08Ay@RO8Wz3ZlRP^S{n500}w@BsOKl_ zXUyJNLRa1#lZ`8_dL<|ph%-@(kSD~@Dx)3vA_L`w$HblZS?wg7_4-P9pJiPLQ_xRk zO0b9+z?O*xd$K4c2-pX5m*f;a28PM#{1iXh70|loe>} zvJ%v(y?S+Wa-dkWP;W{>6wy^ma!AdBy8EyfNk2ozr~|4Y0rD#z4H>{!Z4cu(l?v24U+H*k%Rvd9FPyH4W&;UR&3Aq{y1%@xG{qfRSa-R@GK zgnjU+O+L!zCxHFK*0w|hmU*YwgE$^hp{5`Moi}7B2}`3O;-jn-7R09}5R{=b1B)Dw zWppJ3DC5|1{dsO2;7%gVKIzaS7G?W1j|F1&w%Ai?hD|J?>?9wHs?p+!|70*nG2nDz z5$R77G6;z_tdN4FTB*Vx0+C1pEQtFQDle|&SC%j<88zQp)c$IZty{z)i9E>LRBdui zRSM~%g`Y$$RWy=?qry~^6r?5Sx+igcfyuC?MufLiE6P|n>N1w@=4t&K z$%N;~gmnl(<5HLh>M((BdDOqe%q0eV%0-a#04cmUJ$m*{zp*#m-(x--?1vvekthvA z7)y4ewAu|omAMcFB&&K+mV4Jr@?MIP>Fi`|Sy2_K^cpz59jpM9!DG@Dk>!AaiJbtY zJnDT7HSp$KHp9d^?I=*s;HUiMwFP>O6pYf;S9*C11e&n_WTrUDXzYo(n{;Ids|(rc zr^W1iyY^Y$QYeyTRf19|3akU=f1nCkH1<62L7q(V;yh?yX~E!gs!UyJ-FI3$DorIp zLDE9~CTFJ)S z8z*a|7Wc#nB;1XRVB_TxAqMAYeemsR6or5ms&4HhPzYKAZX_9ONLO^)V4o0#=!K{L zHV>h@m6d9H`><2W%`@u0-RYBzKnPI9hVgjV+LYdCHfvVN(B3?zFXhoT?u18$Qufng ziD9v#jT|K{3Z2CXP-hjGRKilkhI%)2VwCWsf;>t>yA(XswhBSec~&AKX$!cN-1)## zl_CRZBckPT$oBFMpL5fTe#q2&Hi<7St%O+j3`pOsP{4+5!0-(z4G7SR7{Zkb-6?7m zrekbs>TZ$!?Ia}-s%bSKk?iIt{<+J*Bqc0~ybx5-QV03iQW!cStSH7*&SaQVn%l?$ zCxteYJn|dO1922Kx8yo$Ac<`CkP-x9&>)IBWS8Fh6|sS%KEejRps?7u)6o?8O2|}tMl*%wH7kxPp z?UwwB-0rjIM>~!ETB#iBta$*61d}~RBqABCCqM$>-6Cb`8|@*T#8W8>xlS%=g;sB~ z8WxJwvJ#qBih}mSUXNLaEo(|^A1HT4BJ)^ zL28ZyR;8anHtmJ2RxDqI|MO1Bz;}%M6>?Si`>irNOoA0MPYu%rbWxCs!X%&+U4}vG zE-6!}K}C+fOM9s7{S7z8(1KuoX3{0}sO_)QsXqfIqENt5y$Lc6_=E5}zA>GM+DMtnOALibT_D}XA|dwj4}}c@_=`^bgT&9 zWBL}AC|DJZFg^kK*7Yv_#M}d-3GDtVHWwkZSo zXOI*AAmPz(*nn;q(9Xk{FEF^9P@dF)M!PZHj#8* zw%FPR?U;$%iX{;D?@JqY~98RX@Azc-8 zUSLjTf&7)P%Zm!vCz9L;l^`9onPh>H_eo|Uge=^9_c&FCx_MjOBydG_VUaMnsk%V{ zD@*PFL~85NXEf&>#4_qGe;<5fAL2CNCtwHgvWn9Rlqcox)1^S)d3lpMCPGT8WoM6L zu&SAut$=J3e`cvgaHbwi5>jGpPXl;G#4yoU6S|ebD^g4{b8C_@Kd>LGuQji!>Si+7 zEx;KSSw$wLX0-lECp)}!%k__hz z!hQYn&6~Fn#p$W2;dyt!AeR@A2L3^*R?!;1P0ehnQN?<~$PdMs)k{fCme7?3#&*a; zoIo;tEJ(6bjj{~Hbv6%v7g+%oG$MAOfWDAoCap4leaJzRS3p9(+O#Uw!a|YoVjsJZ zsRE1@cuww#ZAGODM48u+WBQs}Ef#O!IbZ`o4Oxm>r%R>P1-TBQg&4cf9#PMlWBLby zB^z|irKto3}o-A(y{ZH)?01*80FM%L}uZ8Q2$k+vI;|>l37A5 zAk628EXpw`V;C&umkNXc*h>X1M$?W9*0Oy6e%Yi5gmBj;N#w#s+L6IIWPn!PR@M6? z32NmZ6h`_Bc%|c+Bc+rHTj}oJ(b$1`=7|6dkC9s>?)@P)i(W9pK&~!+8l6nCeDD`o zD$4snG#0?=Nq_J34BD2!c12mob~3ybrm&Nk*?pLtFHNGkHvFki&1 z2D^AAvH@8Lfx)1*HWLnR2J6b54jAz7r-@3~@G2ReRSFL2D5y*Aawj`ML^?L&T9O_DkVFl7&CsyttNw!TKXyJeSQaQMZEU zNHXG4E?o@rbJl;3EQzP<4DwnERR#Yg)&TVfs!qUYq-X)7P?m=kD_~_kM6lpo+FUBm zO1F=I{))3gTlmDtsbWDDq*KJafznOq*tw&kno<071oFrfV*{ae#ECo(-Llkrh+)VI zEd0SIPpEK%KB#X!yM9bGDc0ShXRT3T7ihP(w?_e_IwCs%FKZ=+0~j7%QDWfr)d`jX z-gmgOEJ?{ALza^{2cPcoTeChuwS1ND(!!cCr3Sgz(ziXb$zcJ|N2#2C>X%e%8-UX9IHj zL~67&WRoT-=B|<#^E2vYD0X@kYN$y^iX6y7vG%+MI(Pybkd_q2nXnG*ZaR-bq2(>0 zrYVt5-&0ckfxGuOA6XJ({8yH*WhCB1TjztK=&{6?DZ!g&gfgp1aR^oNit@mRWC=4g z8Jije^ZxuSt3);CoW+$gGwFOrmN4*%nIn@4e{QLjX5O}pZo!NH$U!impMnNRa;RX!e&T+TF&T*lv-BEcuKi|M{m>fO0doPh_zIkQ>zw z^s*Hxk%aVw@6Oj&lcGBd(rf#3nmtVv#KDpZ&uNfZTNJJ%_VNPXixo&yc=>FR@2o$R4k>c z_dBe77afI)LP{@3Ml$39#O@8Nj+c-$K9tx2A3}{g)wrf?ZS{1|Iof`9uGwN|WGGK5 zG4O)YZX@PCrnS5cMRd)y#4SPpP#ry>>y0*OGSSP>2)#pbWm2)!)gh6q?J(4FIiv*w z!hzxlkoVNT=uZA)~r368vL71RXYo8w}-|_&1OcFz90F^sxI9GTta^>}}_CRnL zi6p2euFMs(0h`!plF$;NTmgBsmi|R{j1a*x!yz&hHQ=hyxz$=zj!KgNF%ysroM!=) z+9e+`Z5t%vps=c2x3xH^nKm~QEncOB#9s~Ld#qor?di8Vt)JJ0y>{1}D7lr%vCWTSdmzN&eX^T10G zfNKGRdBJMY7@lw#Pkv}&AnY;iGNaF+07y^mva56M+cqO;t0H%|>n@B~TjF#Ua+!AWyNQ(|ts< zBwk2ZfnsQwjZgeWxZ)3F$WPSPpub9$Hq*T6vuU3UF)eB@&-%Un!9Ekeaa*AfBppkm zqoHQ7fc;6vNhgwNcHIhnTCHW4g8A7`SEW4|qC!PvVHv?dA8}p!oKC3El^a3L5V*1e zdb|*igQRIj0lC#A?7^(vOx#=ZUAz(XOU4pU`6v-TFsidnq^G%0hL@JZHXT&{VW;>B z=9CqjVYMcuq~W_8Dv%aU912zrPM_ByQ^2ki6w2S9FNRVZOi{@dsBa?)DoKtj0G=KH zGoD)6DK@a6Xdpf5j!8M6AX!fZokI<=sfQ#fC~=zQf02xk5AS|0h(S5GoyF8J8!iY{ zA-A|RH$9V^kprk_G=u&F7*B=CF)iTWLQ}ci5X7Kk*TSt7TixL`eWa6O^fL%3&It?u418Bet zyF6?-I4al5xGU|!up1TzF9(fs4f(OfBk)!TK@X!JahX`;q=V*MacPsc5~tYTY#xLR zNK7X&)iSrulRdLZF+{@l{^suSfqQ zHo+9EI?_SJuLQO1Sg_0~WgPdjpcG{Ndw6-v9oE+uD2vP9^M6L7Rlw;>Wf>R1QQ3TMQRC3;q!3o>R3C9a6*)RS=5M;6QEr-R zl6$5w4e3uyBgG0A&e`hlg8GB!%0ANx*Cxb79^&AD$z@%dCY_7V#QDUY$p@&UaJjbI z?e4P8e(m6(8$Woo)2R{sS7J^2WNhN8@F%tx9^?cDIhLHAo`bf=^Ow6}X>di;j1|s< zR36BxzN1|`#ueiu=wsv!vE3+kW+R<0>Mge^ZlaSOabF_jsJ2)q!#pc5LmrB7a+<+M z%uNyrq8OAFX#$16kjX5t-F|I)I>R0?&b_0|4GAtuYFf7_2gvC#c!{4CeRl;94TIc_)|+scUj@3XlWTv5|9TN(y2J zpP&wPpaue#43gn*GqVM~kIaXjDL)t|9vM$PFjvE2vY7`J+8|W!4iNIjWt)L#9n<#5@MjjMO+(jEb$NG56D&0FF^x6lgH=-7Gat}OW%%rXk1K_ zl;RA-qw=q>nvKV2=P!42<+C=GO$qp2-5P6pAoqc!mIiF=Xh}fWff7g~pj_R^;kPHe zY!yClQhc(d$^!)vS(8O!DRZG=DWcGl_A&C1OcGbs7hV<*$$>IMAv3KGss%=&dB_Z6 z4oc*Ih)&^Pk_)9mw%N;PYn`WHJKI_2!z-?4OyOv7^86RDaO^}RBgnid?E~3L8)Wk# zJYJCO0iR9ElF2Tn=7=h@Y6u7jAo44I=dotef(gh)aDoW15wpaUh%nZfkOXXMSdj6_ z0(($R`$LjZ3)yPx&OF6Qiz$*^f%i9nM-ZRxGPc=7=SO@W`}@Q>J$iLs4SI^H*(dB~^O5#Pt#`k7dCdRFw!$#gImSnSRH55li zHKA1Yqp%|@By%Vd^?%;!+hinAsgY+52GFojG7SnEToz+byuGUREE`owR1-)ICs_CH zs_(}$RW-@8zg)B>z7)`EW19dbYE?1!-E47wXRlNGh3j_0G>^j;WX{0ba|~1xx8J%f4jugK+s0^fLqF zR8zh2c1!>*T@%Hw%-}aGlc5QpWdk^Rel8nUmvSF_#PJ2E2vaul2vi|MU`o%rt4tzG z{07xd2`RY(R-#cx=R?^1wT4~{(9sONk@1Ktc<`LpoY%E~fk;$}w2sw3 zWYY@JIj{!?S-6bVhC9fd95|nEjQ%#?gmZnaDmVp=D6(apL+PluTWfOfi#~mpZgW@; zxPpD@++>*mXI+QH&!~3qhUOjeCAyGogDwUd7eJIA^WOwM=vpnc+RZ8hh@lCJN6_8A zP67Z}B?%SsdJFwCCXtUxjkP1nVd@T28-+qpDg(K(iSUE zOO-+*zm>J4jEoE%>SVM<@;!u6c#ijc2|-MPaAWd znXFQy{8q|S-H^P`EG3?t4`Ll?!!y5UqHO}Jj&@h-O&gpi1kpZYU+J^h>D~o}sXLWr zFv>gWaj$iijC^%*&c?lSjD1F^FeroC0~vwF(J~l#NCkCOR;SW*drJB6bzOuTP|VpZ zdCm47IjLH0zdz^=Pr}-1Ewq)FT!%lJ=*Nt=sc|jojASbK#J1}ulUxRw5YD3VffpI* zEq9#u3X;86r3#*@Sloh*;AE2w^K`xt1|ZPrlpaDIAyozl1qe+p9+H&flrXp%X?gBu zA;Y|v$S;FHj=Wave6m&Xe5^^Bk0%&Slf)VQOXxV~E|&!!a5XKy7j&2lOEHw+7lg9W z@T1alUdGMmEkui%eOp6Pz&lKOo!0(fz&FA$d;AZ?e%l`pZ|r87w0ctoc8KckqB(|S~@u4pkh3If!Fbti0MVm1>5%`m%_N$WFfI0ZKobwEmD5GX;88Dep{EuAnrhVN|F!r~6J zcY$ypnkmf9u~mzbQXe{!!2ANaHboRbBNK91^$GxJ9s;gD{DP8a2;NPiOEOPL#z+n( zx&99Tk(;Run${-mhw$gqbMp{TAw8d&0@)%<%ikEnAwocul_bRib#u1Q007gTQt<&v z!y0Jvg7Oo#hd()LlpEa&UODj^Shse7Rfh*hQ!9ZWVuUm^obL$rP=I)@A56Vxtx;0_RE-k{!<8L=mK!$~ZF$jYaUCpewz=Ko`@(W5d)TB0UijyiA1amuO>(3L z;=5{k4L66Jyh)V2;~m zcnXf>sH;?lQ5#eXAPH1HWdy_By`7!i{vJ`komyj$2?sFw^=qacf2Y}4t5CqD<{od_ zN_py#RcUep?p5lqNi)cKR675VPXI`(43P93=n+W%1JW;$GOEE&YIS53J=z~lpP*DHYWwM?7ZxZAN07ROpn?w} zqEZ+r8Z9Y*j=xE?Xp+XI4@OIhO#e{!tazP9m^9G!L0IrpPVi-F4kXR<7j{R%lj6$c zGpasPO^Oqa<(1C#V-%XA@KX$iZK!39Rz4&rBfq)%N5HnDBTA)6TT^`Il1QXA7vB^n z)40PZ{vk;(&7+EA9`2Xm`-Cn=N;}xvgJBQWsrd-^PtTvdIDPWur2pg_`jC!TBk_u& zWN^GfYxC;GrH#Nq+9T{WHH#pCijB3Yd?25nKrcc5Wd%{-q?;3#JjFx8gC`Rh9(Bnp zp*q6-{>lCsnFNG9WQ{szr?ooo^@Jc>C?~2r7BvINszY=gc@Nyg-}F zS4-sDiuq3~MMlw=9;`H(9!)nfg(f72j^k7kP))E2$2UtY7+tnUL3Y2BVV^XdCjyh~ z6|3K5=$QnFpMVc(*&y&6)QS~45PTgU!pu@7nm(fJie95u549A9N)#HSua%?USCP*& zDCc5sdL}1XPi$^3Urf(2jGmQ?g&fndR_c_PXmP=<{EmvwkO`a!I)V_M>V)D`q$?Ru z4>ck&KZJR-sR5|T1#4VAgF0vC(lblMa0DKehKhyA?^L$WAiJpmh<+(0>Uk{tKvvQN zcd&Ev{1pZOpUO2(UYwo}apc)aus*yv2ff#{B*5R-vCCC9CNl-h-S$&(_IqHx_!rjrU!3AaSOQ0@Q|LIIQ-+py1uO>DTji#$c*yJTt=evvL-_p+7MQnTG$rE%cPg$4ZdCg|+YdqAoACVwd{XZQ*A z0SrOXKx}FXozfN#z1kiXv}52c@wtevrF%>X>7>TVcPV5yjf%#sK>BQLb++0%=y(cV~*m4=+;f}$&E#!--K7IgkTYzjY(=^moj%`^KvjU+1W!7 zWunc*zW8x5EKg(R6w(zta1bmrI0A-q*|=7~@E5<6!p*m9m~m8* zw>O*HtJ_Zd05(R%Y*H%BJOlM3GUS9hQEJZhh1RhdCXZ~Y!R)NZhyz504FFRqhw}G_ zSYe8h<$dlVv9b`XKJCaNO>#@|kK>Xj=fNyoV^b~>>H`9A2BJ50`*x}TxR6q@~)SSKqAb7r&S4Kc-ZW&QrCZ(u&HUGmSCOf?X{4RjtsC zEClNyaa|G*nVvo?R z&Ya>al4t~_4e2}(c5Ho-W^|fHocn#2fKe{aj>hu+aFH@W)s9!F3S41|fp*c*jEwb0 zu`qRk(cgG#J(xw0a8L} zk;{=iAIR=jV1*$Cx#r;Ua0v2g6L|eH8fboo0E19k6G){q+bNgX9?213H`=`)AB1aTu_P5oxr^H*HX(tU%@| zN<50nAY~Ogd2-JyAXD|^zU)71O6K_q&)2GL&`)1L>u{TPLADt%!p!MCVAIf}M-I)U z5CeEe0vv8`vWzB)?^nwA?>iNS zR`45?I8*I3-d-!S*a$`vj$%-xde!Gp92RG_xF!(c*H0q%>htq6OBwm{EAGz{RRIJ2 z5jo(!L)U8~Qa!H>JR!@fPZT&nWZ^7n@|YQARB%zocTOeOo7hzw@vYVn`*!vAJ1s>g z2Twog#d-X6M{5{q{1_0s8>qGujc6qp9K@I0SppY=WNPg$u{-5GiMS80&-+r>h;aqm zW9|mHB~+*KMBY9g=|r=~p%Mj3m3B^e%d+3ydtB9((UTDkffhdq7eKKLF-xQKYmGXF(}4`3l}f}*xkrkf9W`THLDShVZQ9v*h&*;I3h#Ki}RVD^Z;QubZQ zVVPm2Eg|cfV-{<5)JI5>IJJLtij-xsJNZ6+=&B4>qK1hz#1kS5jz}E_J9v-Q2db(g zLAclVF@S0*FJG7gK850F0}<}!sPmIOAl{myaSuf`9DK-N36C~Pfmvc10f(XG)D&KX z!#<-(UNg*Gm3>$05qkMHcKJJc#+Wprsm5<#zPZ+9d-WJfxx?}54T6{;4TuAeoxl#o zIGh>eFxn%d8lAdVQfRLv3kOH7c6tekV7vvanQYK%jx8q>uPPcEgD7amG#ziV;W>BI ztB4DQww_3{i@@%n&@jQ{BC|+Z3^!L@Ur(JuhljD_fqKJwhym?0V60*Lc(X6Yr!W+X zz|)hhNn3920Uo=Lq(n3-sPHZdzKtlt6@nnSMZqf_Z%IDD=Cr#LrAZ{wn*tH(6eVfb z#q1n=dXmRQN>eaSYE8Z~^a7k|e~$Shc}AP7p0B0Gpv7{m@&)Yz44qIDVHp9yK)V%; zI}Cupmz6}s!=qtX*?76_NCC;CAHw?Nm2mZqp)unpg9>yF1i%1@vXn?2MFy&gPd>$* zb{#K7g0yE^9pQBdq)u?1*8p-|nfKlP^KVYiW0#GKOGcN{9)OR2bv1U`QZG5mpSH2{ zIPsbX=adS+il1)EtV1j?#T;>u4i|Iubrw(nUtle_>{3?=a1+cg*zIA#hvr$L?UfUi z%$J`oU-PC=FT#z=OWK|X+1o=Jhgmf(Nw$R|9e&MN`_c9>BdTZzpcRO*m9gW8Z8eCY z^pE?S&3M})vdghhLrroRb6^~ci3=w2FyyDj65yFi*u2n0f%(EG)DnvrB+f0gO^LJ~ z1eW3-Wa|p~I`LK82=X0hDuZb0S^d-;CA@`L_~?FRi6+oWi~39kRmLh0BemXIsZ>@9 zajZNV%m~%Wkn_@5aVF>=sMjm;6TxLRrd424f5*=4B_GCEasPT00fA6&SZ5dfgFdC& zE;6VU)zVCAeBv6#m#433?>nQS-?>@?d$Fq;oC|A@UDjSA`!9*V;geIVi`n*?#JVK> zV4z+OmC}h=L__1O80C0ywW&hNg-wu2JipQDpTF!Wx=V01AhN&+9HkA(dVTnAG>pt5 zUr~1bA`oe?x(MY}#xpV4;oRP}bs z1=1gb!_jE4ssN0on!!?!0{wR(krS+} zl}amKsWT>8vz{0@g|m&%jj6>JF+!tsZcEp*I6Fm6%({~390oY};lx*>7%VxiX)w)D zO;cHt^ErYE%tlL(=@2KU!prI;p={Jc97I~f2-!h|B0d3L2P3Kqf% zrEi(s;k;bEx)@V7J$h>71|Ux{S>qGym~v#iHL!`f z*16sh0kX3r1^`m;uV{%_6;lLH`U8DN`U{ST^sCq&?LGPa;a4V4EKHe@vhfY>~=@C6J5rqe!L z!hR-7!V)<8F3Xk0oU^#vx*x091h3TseKYJ)z=T>QG%(^>fCRk`9=?pd&&99AKqcak z%F}70WJ{9W@4Qd#`-%}Wy%AZ_`cIpB*i|GlwGgm?o)e%M?=%5$s#@vyv7)h~X^)br zboGGg3RleFQ5dwP$QZvQul?%Q>FNo{T^Tqh>)q~N6>nL>0|%5{@C;m{XIhmn%@Sig z8*M6_hUY8-QbG*V#a+Xe$L*Wq1Thy-geLGJT}U2@^V>)!Jt{0lwEQ8nWgx)7D;6=A zF__V;edkzwL5`-dLVWC(~H9{^-dPBvGQiWo93Ik9P)R4Z1Pu6KVJvlc=DI$h4 zeNRFpTK567eOq~^?c_s5GMKl%I?5OvkV~+L&e=4L)ZY5k)NRf0Cn!rGAgcR3{?YR`XNGr22v}%o`K3Oc# zdw%9zw$Zy-RM!mD0Lhn{#zs>$Nv+uHwet&hd~DJ@$IOfqV%?a^2YVf-M(vZT6GtT- z1}4-*dCT7E)o{2&*sRZr=K*;Rj1LQkB}lDWC=BK`4#7-@lTkZ@&QZRBgi|8O%563~ z0gx3!ca>x=l@#+}uqR<|1}k+ij}JA4?U*ra40vYhH~cJyRy0h(I@}`W{?AfwbUPMV zS?^iei2`F_Jsq5Mt5x;|m5OY4*2X%RMvQ`fHHtWvuNTN<$$3pb1m%3u?wYzi+PPqb^t?C@&i@$TaBGP1kZKP0RTKld@7sXA9N;-jb{#h;y>W{(%ufy~kcz~o0! z_cF2=IlJvIl!}!?g>}6F)kx&6l=3xdi+q3^l$pxp<0Uoinu&*B>wN^49R;R-qsbt>VTq$qU|~4UR3&oyHGTF0<~=TbE~q zsf|~!YDd}5!1B%wa&Xwh1!_#;vyp%v9UrqJcqu9Qja9$IKBh~Zac7E2DOPz* z&T*5h1e#WxSJ}6wx-qe78aIP9qjS6F%l71sq9Id2H_iUR6x9TSv=8~U^X%^^(ksdl ziaZe_;*DrxGB4Ozdb7fGA(>iqU684a;@pn=n1b&hU8KH=z$7#CmzZ(}lQNtJO-sgc zg?xmPQIwGsa^tEQoR*19q8;!k3zi}E7vM>S?gAdl)Af0h@J_ho&rMCL*NM1^#K=!L zHQ81eO)4Z<*TO~&9qRR^EaDn~$4j{~TdcofR{9W2Dq4hY1I(PO&!lDnzLEaVPh3;NHQe=MwNxtI{6hZDW0Pz{g$#4P zkwd3?)S$^kCecu5qL6=^5)<4}VJjMSA(*zO7=Mr2nIls@y_BKgNYMW{@l$aDFo=gG zHh3$U63&{iMI?qeQ&?BcUQyWM6wQiP`|<~us~TFoj`hUcYpGW%MDTqWM@T)0bFzKV z-J?5PV*{*1Ln(tXI@cmf2c1~Q6cTp#&nPN9*&Uvpc6X7$kdo%#Kt}u(4IouC)PZ=J zM!y2nhsFeMQoUAP5eSS*^9^|hO1g1o*@fgB*JTM4g>rftF!V@&+X&tcIfa%5qGs8L zHl4Zciyigwuvb#{7&nj!FB11UEKSVRI>ln8vH+uM0*#_pCTB5`MzX>%uaU1tuD}Bk zC`Bh$WuPtpGbr^xhCh&3QrCeP)2Y-$4C2ZrHu9qi>Q$p<5X58}*pW&c9vMuS>|tu^ zHY^FE@pB?6z?nofX+-|9kJ*PgHM7LrfpjWdV)6v4T%0X9>$0YS>EDTODZk?Mr_Nx5 zxN)b3YfDj&B);;*qP{P%C%D{E_vo?mi6?t)iplo->H~|)XH16Z+=&S&lzT&F2v#v# z7uJlv$M6KS{Zzsj4agpPM#7a!bnY}Q|4(+{ca3N39#k;TSU&06{J- zC;>88 zV@MJ?Yh*vg!s+>`yXi%mw(dLmfwKR~3RLQ4wplPcWK(k|v4%AQ6|to?hm4C!wTKx{ zP2$ud2p~WO3N^7XMuY~IB&3m|>4a8KmL{fCGjqJ8!dH6&Ot{GZ|7*>3)^m=#9dM6p z3Cl?^tL~C2Zta&6-25N5+riLfBH)@VRKD&7@hqp$!*ftgK_ODPeo zP~?QtFdwjm6|i03XFo0aQ#NsIyDGHa>J4yiP_Poe8Yg9WA5uS24#0zT#kWarWExTd zCGGU`r?ab!g{%|{8O)^l+P#2jrG|Qybw(;edPPt0ksyQTqZBZ*Pi{{1O;PiRFM!YU zgE>`YLcE1S?0!{fy}9`SZe7H&Swlp}mF!_1h01fA4F0)IDW}#uXrHT``f)=ik*)cV z5s+BSQ^fYNg;aXh-k{@>p$D5<2oibc)-Z^XhcS;}g#wgvf?$p=!FnWWjfrjj{_~TI zD~jw1N2xr|x!z|l(c5pY6p*4)3!7LD4u&y7#es9shD{mLAfpJgi0UgnyPBxG&_#*W zUr9)Qb@h*N7%M(+wCE_2hG4E8M^oKX-KO*g(KSA=@bx zh1)wsJpzogr7r(Z(fDk zcT-ry5p4e%MmbMp>8J+=3ey!~CAd<_6srw}r5xj0nq(NgqCtEZPO7P1L*T|PH{L3~ z_*RuVWb)&$zak%S`p@)O5F~~_VbEoYE%8~28uEB*L?=$9N9JiMOnF&ZgKQ{wkON;V?jNaTfkHzE!QQ)q=KBU zzb4b8Z)}So06{yIGWBx|?ef&?#Ns~075+m~?a(8;Om+!H0^+Km&?#kW`Q_!#)5jgU zgCO&$Tw0nQ@T1l%f_LCpYf`b-!GOX%qoEIAUZRac6mX?9EBnQyJa<7LinYRM!3rbj zD824LSbv9A=O?ve|`pUh<-Vm;ATgN^6qEwX#+%}Our{L@4S8lZ(4!} zgi?4Dhert{X;PXlg;I!$In}5yN-i;|t-LoNyz#5c{z-q>Gd2GsF@c;JnMxoHPze?P zlz_Vhpx#GxZ*g`**1$`aGJKKSYqtj#bSv^sL6#PQY5kMD7orV0ru1WT6XN%#ZEDx%vBkZa0 zFa;sR0|FMb|^P)fARCD+6Z7>=@KO)pIJtyjie)e_z}m4_(ww(GxM6KR_8MEuB=vt zR)&BTEcqfahZ^+|SVI&{DS(7~D)W}fX=qgwu&`qLwk8s&c>yBfGNzS9%?63f+_Tw#hM7k(egF%8Rm8bo1|r4Cy85Z2lkWb8Dj z1X&Afo}Mup4=t)nDav74-gHhI1F@NX#3-OfzPd} ztL#)N=zTZXnr;oCG2Owu7U9!wM<6k}KY$8E>{~R%I6RBcNvE<%S6MQ+G`uf{l?9rZ zDR38#rYU7|h&FGk5+9Rmy}!4aGfWPZz>=NJ}eo^PSTs`E)espu6WVeO^b2T_snVrVj|kELaZe zbGOC0Ijk{n;wVsOx3s4G9Z6WgRsKuDQHv79$;l)P3}NEF$a$eRNkT{Q z0v%!>-AH`j$4Vkx*j!m92BEQs%t2%s8`S2oN1UCwDtXD=#`91RfioF#Z&E%2#Rg2r zp12SuUj-aRtrpX1r8HCf>LrA)6#&G3uu=yZ1AI;w$;17*}d<98*r2!O(~d3 zcY_=Y8ly-Ax%M1OSy4{Dsa)l6(7TEg-j<#hejMmVR*#^2I5~BPFq1z=zBWskH#5nQ zi4;2a9diH9!sQ%G%-sjE_D9AMKQUoSNFk|hX9|tr%8|hNdpZU8cG;mt4W!ugd|Vs2 z2@q;U3ZdVLfr;qJ0$f_fK{S z)JIOj$S<&T9vGJ0t6mCP55K?}l?(>EPzlmGy@0AV79NA9W$gJI!2&T|ZQA7vW+jao z5`uHWjofUOgl}$omUe{9*ho}G0X2m-aQm{%yyo!poh_f|O)y2MSj#Qw_9LDU{X}FG zC02nLu$aGY$P`dQD*Mx+FEAYebyq-9Y)+&e{IO4UEY|^ZOchWe`t)5z8&bHVN}tnR ziiQQYHEDimTn_qPVxFK7BKpo!#sK4Lb2F?`de8WLkY_>v)yfK2E-bW)Jflnua0qj8& zqP~rLpDfeOiBkzmIbD*7Fb${Rqhx*5Y&OQWk`2k*V44Y}ls_;AXeHxJx0y=n-HztP zh#<_@rP-2?NBU_G5zHQC3f!}_Hpl_lg74d<4E|?Kx=Xof9f$#g1J4LwuULt+#uJBB8GpiwWknMxffZ;B-!;qOD$w-G4f(C)H` z*`>NM!$2WQ4HUQi?;n3%Hkh?VX%XeWk!8z-b)pNU#?Ees9mwQb zoMDUI0_-E%19Nzp4O|kYL9t?-z=6Jq$gJZQa7_SG(i@nRs{0&&daupEiG5OO{F*@# zA)TkthG|Ri_9M>6iuSDBhLb=7*dGE2intKKRU$;BAbEq01y3@~W`UR}iA}y_hS7P4 z2xI))^s3AsSefq+WoTeT@K{NyBSbYqiTep}ie4G=gJnc(jhzzQiZH$BZB=nI#{f|G zlQ9JCaCn%qrlXX~#JuuaSsj*fBJZ{Rl3Ze**)6O!W^T04GE34J_@U`Bix*J&&z)kE z4`}rACQXzA8zNlVT74n1Xm$c*AtU373viI&cQTU(1lboTNxj*PO-aCcRq-C3jMzCL zo8I_859-)DB0QcTSE)2=JB(e~V`tFOk<)E3e}#d4RZ?ax*%YWBm4;wAa)gS>a#qUH znUMfQLeV}1<%K=Qu{F+4x>z!~9&c@50VBwjKc!f=sc=2Qm^d$<(AsXwALKW2MGEe) zhe4olI6m=6#sT^+ONu0$4J0!QPNt!WE1Cv=Q+;DXm_$?3qfk*gF7el4 zeOp7_MU5@GH6UB)LpoCG#KLj1-av+;c5EOA_49;c1qw~&>@!IG&*HIhx1LmO!W0XD zsCklb#C&N|r+{pws+ZB#oSOn`xWh0JL-JyKt2^CTjaZ3OTOl>#Xm4FCN23kf)|dvM z{%U(5?u#ha05RzYo&}xPKFTqh>4-MZpm9W6=H;$@kkRbp2ub39k+P+zFi@>cSt>3$ zE+bcXZ(6j7yC5=!dsc#D_Yps#!-7*{%&NbE^Npm$LebfBMs~tl_sky~ILYY%R}{AX z(je4>qTWE13>MnG0=CK@F7O^mBbKdA5s3SIJIETBo;ICc1nw2Qf%& zB|300#`r5lEQ1rcZIZ`~O^m}~N*H2=gB`V7D(&+Fr3Iws07jv__u*s%%?QG6ELYrn z%|ZrT);=NeQL8A*7L^X^9r{c76p=ZmY9>RsWE917^71Vb%FEFsNTqRt;ur7)(Ss1| zO>>~2jyf2G^F2Dc;UYWKk-!5xZmN*7MyF|}8WdDU%AEzte-kOKN8Fl#n&<-2249(< z05gRHcw-y+&rl#Pz;!`Xh1apENg|_>VjkMZu*9)(8GuFU)v-P~K%PaJlX@Dcbzi4QY140Dn>Vk^DQl_qYCCpKj_qLX=8VNE6obM&!v zA+(?l3}B7-vv7kDl}?MZG8>Ng6tql7KvEfEsi`R33MGG`O94NvYRg+$PCxMp%L%qB zU{~`gO`E;js&-SpP2N@!Gd832(Lr4wiAPGgUX7O}S%JJ3@qJ zM1xB$uoO1A_7{}heg<(Df&mM}&&Bm#TU zE2Ox0Fh`X`N|%x6W7_(^5@U^_CQ($_GM|kkE_ex7%bcHH&&9%+$I4JN6~Zq^piVUz z`~@5}U`EsIw9T_4@N`P{Wj`2~5Y$2UhYa@4^&5|e`_$t+4x48%Eq08OyoM&N=}uq* zVqYaWR-9LH$r#0v99x#_f*M2`y_M4K6n7x#!2)~-=Z->ETtV#}0AP0)QiKa(0ZPSi zXO2s)O?YIv=H^ui$B9|nubFpIgTgyeC+}_q1y89V-LrxMVWz@1l=29QhwiKxh6Cnu zakLmf{MQ^XJAfpsyt(;8I73pe;NDphN!r8y52W${`pZK13YY> zT`0}8MkUA1k?NJ`8sleu>Q=OtM5eofln|hkTumg|uH@CSoB*Fp2HCjB4on?1j~&Sq zJ&ImXzm8aKRPb1jsKM-76?%P6e2=D0#N9s>i_M_r)vB71$=y&AiXcmJ=-(eofPDZP z@SNj`hu(~CE*4B@k^DLk-QA2;P97znNLumfJq|}^n-wp^T0T^aU6PTOnF}TAP9M{cIb$%xUX9F z>^=f83Il#0z`iY?WksFw#X1_J-qCOle?4TMJuCJ+%s3PG0%*<750q6acCcq+b&^?s%+ zjuUoyn5 zt|S7EOlAE{R!ZuaW6{7DD&vwIzhbUPB&==O6@@GUnO_m?jnJismy{i!i0EJb0!Q%y zYMMu3N$-Svk6Geva@WNg#V3_aMi=DlKG69~JjW7$V>iYY5C)hulIEl*n8AP~Q18-w zR<62asBX#$m^E$R#Dj*-@d;3`%SM0Q6axrDa?*2}A(Eb&8r_r|n(F#*3C!;HzXI);6zc%%S@wBK24ozZ|n*c(TNd&VxX2J2pi6f5HGXQ95sV(oH zpFQ6@dNHJzJlBV!q-WFs4-i_St2;&C1e}-x(?&l;mDFShlOIKL8Q>fTG@XwCjNr0q>^cM?_ML=@bH+%F7!e?>UiPF0h1IPRlBuYCIp@sdm=$9j zp(F4Cla}C`TTr%bo$NN^Zi{$@`~V@@F1uohfTIiq%$qIC!6BN zyJ|bpehu>|DMtWGSHM&*X@LLE=&gH*W#nKIm7%}UQOmvo0#UQ7p}C828->f%Bxj}w zf$c1@@IvX+4qL&zg-rB5&x|8MB!meSBga+x0o_2ur=C_e2=Y^XTXFi?IIp|u?0h<# z;*UY3ht%H)B0Zgo3B=hyG0fneO|fz^oyrxL(le<^d=P_^*tKE5sY9}hn97h^#&T6Z zu3lEc=_?*eVk#F_cWc!DLJJt`%#lU83l1GD00gy%Z7eWopL zU0&=BD~+yAWy5(i$-@yEZ=2y}ULr{d1*?sSN5L0zh9HQSMD|L)Y``2O&Hv#StWKE@ zWWy8g#QMb06;~NP>{wO2;!xG-C9T9FZ#zsl`kkN3L-AH2 zNZj>PGh;c~sBx5Y|1&f!vyj^O_+vjiJFBH=MElHj7lsTR?NH|Dk=_EBD9enHP+bkv z5NDSBOuE9lxY_wBpZlt_=YPSBC4H_sEzlyR!5_zM;S9Qj;&cc69uJ$AT_@#6xst=t zp*RjLYF(R>e!L@2%GIF2*VYf*TXZL8a>!q+!^Hm3Ge*prw(9fYuyN9D@1vgpkYe_C z=OBA(ge(a!=ryK@m`b+SD3BoVlH^qk015gnH(1Vc7|gGm<}x5g@wemz8U@yo7O~{4 z?)_0@-0%`{Q-s#Is&JWX&k!`~R!iARW?7{bklVcx@Df3sq7b9PKyixLm!kp-S_4!h zC9>$TA`C5hj1e=ZP;_$VDP4(o`nhl88q+ zd)x>+19^sdgX-cn(+8`j_A!%5ZFW$3sCgFP33VM2!79fFY}sQ<6nxz(`qCdHT;ENdr$sVjMjs@9b$3^#ruV8?4}c?sxbo0y^* z6Yo5S6vN6Dhd}h08Q32ISOMf#LX3|pf#@Yi*X@5gH=coOl4l#!C~DHEgk$I)LSz_KOq(}zDjphbe1%!XE`StNJ zX>_JljiX4MfU}3>_+{#fSQH+RmEkfEEavU{Fb|;Vp#KaS5ROzAGzW|SdkH!3&drI> zvB^`_UZp~+sZt@&15F{%QvX{N@PbMeWtie04G}fgKn&6DCVySCA(g}?m`F~WkR^#! z)wA%;L>r)TJCvD>M~3fksBnLzd!^d+$W*K{Ak>uf+++3WxbG)R_KY(inlD4-%nQ=CI+ zZmM2PC*{c;fTHZ1_{|$v#i%#^^FEW_*eqW?E~N|Tx`1tSQOeug#K_NrcCh5eP@)3S zbj~APSggfGz>VX!g%wE?0R-B{Ep{N`$PcuEn3&_UKqCHB07pvEo7C97=EE!@da9-3^_L1d6Z*G=C;m_$cC6yT0kNX!sA` zfnUvJI%7(4o6nv(j~}g;4v#BY32d(;^L#~O$Fz=+En{>v9Tm0A#}$?g{v#Ztp^$R9 z1qX*HgV?By+kmToFG6Nsi=><9&sH~j&LZC&t8=+&IKf#3vktB%6Ft9YXZ)XIzrwP6Ylh{D~wS z`w!KBz=vcesZI|pD5#+LBj-WDpZo_O;8*;PA0m5Sfq7tqsMU|d6MLUN`~9=y!)C32 zT*?Fz@hy-Pu^J3w!71zjF@I#%|0O)S010gWW1k-a@8jiXR6wnUGIHO1V=1^bddf z?dGK{iwx6H;{*Ci&gVnf?JME(QrG{~! zyGt@lyn}Z+x~3k-8jFC;!%A!`1!mY zFcf{y^X^Icz-(D@8GMx_t|dwlM{#^;YLAtSqzUwUg-7)(Q#S$c=##qK`TFInSI?gH z`^W#J?ZrDSd?Q@}yolpXa77jlk>sfS;TT+Vy?CV~soFJ`xim|HN_hGhmMuH=o8RSEq1&g9b77v{dKj|0BsQ zq%^ogJPLjE(J00vMsvbLfTe=DPzG_>4OIKrn`WWoQOWod`Zx5vUdj5h#Z>4b8KFind$U;_e*&c$>+Rv16lM;8}I!#;+@ z2`)!QDH#-kz~6iI=FRV4y?O%*57`IH#@1TlUH@z(0wRUR*`eGdMc;vDjBLGy^0n7k z(?sbh;K2)oPceNSc-g6Ad%Z5YDzhEw_(8gqlOW(t4?qdSZ-axmH3VNW$NW<+jT0{t3lFh$e!4 zD7yg8N@h#`7H2Qwf?VX>03&&mj>!1Gchqvdfe!iwglFT%Z$SMyB zKa)ayGrHq3BpBYao&7p`DhWxoQZeYo4FDSyi2$GiH@jTK&;=M+FlhorVo5LXMteqp zvIB~wj!^Jb1h1Roz1*|LyOYeqk$A>A7(ZtflEjml49Wt%-M9?nxWx?*JJ1(eipGYb<2h0{ACjiDVFaQe_dP8+9Fd z+g~dXHgE(Ik_IFVLy$GPagw?<-CLe?yq z@9Oy>uISPE1AT|IbUY+;v^7E44l4-7qNQ$khMsvooRk4nnhT)5#+f(U4_?0B zC$pi0&Gwp{E~_mfnaMFy8)0~J}LOHs-`@s8Lx=tyu( zLTt2>7S;riq0K`>f=J*LI#H)eej7q?Br$#JMoZmW3P@>GE03$o^SPenh%PYFqna;D zFHC?~wie^v2Ev?gE-9Qwl$NDih-{HRJd_q04FF+V>&iJ|ezk)DYISg92;|2wO8Tqd zZX|zW2(Pi1Q()0HQU5Z57#h!sBT=5%&3&``*pjsZ@GL%1r{ZV=jae$+*%gbborG~^ zz0t$j92)}$=pkz&(indV9Zr6D&jNr&Go`Htvmt)`@!<8rUgLXGS`#EAZZdgWQ`#`P zE--V3SNRu6AOjXUHZE#)&20P!Ig+$>(5R~0CYXjmBWX+;NeJ04(MK93Mvs>UoY6rf zcITtYq?6s@sZ^o8O@-ierCtx%C|6soE!VRoVXp%Dtr%Gwy~hXOF$AQEmtsHns-=cnomS>+!(C;$y6ik^-JevGRt#XDF{`Xt~HY##hK zDHzxT02YbEzz~4wuWDTA;*ScJlU8+LEm_>LYQ1?BY1}^e@o0Z@YueA}i~L`fn3bH+ zh!e4+BK-$oN&4bc*q&y&6z~JxVoqr}8kd}cwz@qEw zu4RtNTe(!7(>&q9mp!>c&{2O-TdY^cD*bVe`ZPT0Q~D^Elm?N^OCvgSYx|1L^-v_= zHhGjZl=+p$jM(x>cq+rbL!2ZfpainSM}CkB1DzJ6xy%^g3nBbftDYrg!moH=b|#3F zX9uQ&{>;#4oC|NTDI{j`|DYZy9n%Ijb#v+nRNB7eXRu0LQ%}5!S$|?doRZ8yU<6IW zt@RAFWQ(j1+n}SsTvE^6bZ3hF5)(F~C9`W=%|@$nwBKqpw$__jpW&Z~pZJ6?o4@6R zK@B@+^;EPpyqt0#;|+@75;><7+trg;ahf8QfAu;rNeRaI4aGF2%vXZvyU*(ZkIEeNX`dmnqL@zCivAh|6I448dRId=;;}nnG5EEyTM#}sF%T7@y|X(D#e`U zY#?E9u*hN!wKzFanC^>TXQQ`q;=86^KFVenYLwM)5?)7b6qXxt$9venLi4&fQ1B3L zTRKNR4+&70XC%YIu*lV|y@PF=%CY@&b!{v;u|PYr=qdo-Gv(mw6+(|QUPNV6c4hIS z6~^2`dWrWUo)UdEDkT7dd=_-QCbh)w4KLtvPV`Pa=mq2)zmiipXa9H!!1Oku19Cq-9j`QojG&csw&-THkB^ z_`214#u?bpw&uIY#M5iXI%L@Z)riS&VIX4dIDGh&I99#;PIe?in0e7<9uTlwD=$*l z9^fi)e`al{kOL3jV!ILEA$x`IhmJ-isyZOVx?a<~;&ZVF9gV00*@C=(1ZjF}N<1j#+lN6A89m@3Vc z>LYP`r~Gv-4TR3O>Y^l_)L)dFx=B3UNnX=}G=W5)%vh;Z!!d6(UT(fVKHA<|_x*3R zZC86PG!(q;PB?c@l@-3#s>P66sTMN2x<@TwE#YoYvZ}&UFACrEOLujOKe!#;uBIqJ zIni{+?2<4fdjxZ04mptmN4#FY7cA}6rz@CyZIy`nF%h26Olcv$e#ynG_seRHA*Q6R z#V!c12z5V%3)!G5TzFh~NLdp`vwm&|jkfUujlj3sxq#8>Lf^nSsnj5Dc)9#lC3qUp zi4=`~u5*n5=eIVZ53oRBn-m{#t5Bm)of&qiNE>4=^N7v?0kf}>5O(eP* z#r+28NM{Xok48vNepk&FtBs?h*50#vv(aolBVsN|oG5g01^K=2IL`Tdx)W_EvW$T8 zxx7V*5nGKPu1{CaMa++}`8e+13hGxykDKvi!jE47sh}a|qalnsswK&}gUX8X;v@G9 zexl&j@9i#67J~YV-O0IxPqvD?!&sPS#)9v;j^IUF_)mM*4{} zp8X_KyJ)iJ&S=c=8M&yP)N%hjkSGZNNOyohP+ZQA_=ypMqXim6cVbf+8JO!d4~J1DK1TN$vBzS&7;<{((EdpS97nizczw-iTi*3 zUNTi!!hZ*A6sI@_lRG&tQw5d;l}w|v?yfrt=>On7Ud_I7PumUl9Y1loux2O24hY8Cu`_Sz&IID<^6t) z8y}r5OxJVWbVNk`?$OBvR$BayIHDhTlhhD0>;&yx=PaqaWG=NvX(E`Mo`3G`a$-)Q zGKUAvkWvSYm3|ZtE7rvQ1q3T{wR!C)INnqEB;mW1p*edOX*;JgnHYtrMuR0$So%oP0W6`zEa(6 zY-f~zW&0u31L;D=PRdHCa*Ok8oJ|je7Il&s=bU>|Ib#nRt>cr|&|vOp|21tw+cl1s z+i5C-aU`&6j_6@wldbO9l0PYL?0%lrjs?o!q6*X#Wx}_L861HW<;^p8dE`FRQiA7? zW8zto1W8A27pd~zDY z_ERH_8EzR5tx2!zPhg0D-e>uqG?h}uk<8`8<&)T8%lLF?VLFN2!ZJDyNK(>wqWOU zk}60tS95}XD#=MaBU7&qO!Tz~js!IKe()NVqsHq7)x5^uHb*#q-#94Ar-h`>TZM?a z9f=4Om3(NXA4w3Hnwuw3)vfbopKuZ>=+1WDkNV@Yx!mY<@I0NgS_8-yK_yzJDQNdn zpM@~`w5eza{d)wv_R|5|e}cKULLSH806Y z34;R;MH2ltiXRRXxoltGaA9dK#f^*El@roUV56Cy8OmprrV0UO00eMzfsr=l@*HLI zGIhIhez51WWT8BeivG1~h6?`>O{GW$hSE{iG9@@7(Fguitu(RlP2tVJYk|lL6aY&5ac+UheC( znsldPGJ3@F{=FVMHW|iDKiFJbt5XSI^6GbXpVv6cD?9VNp5yW&sB7D|r!KrUvn5x` zk=xQ{(uUz{AyE3%Ncn*nd1Nq^9-f-2u(`sh1bjpr2o}&?>Ps+$yf1`K_<`P<=Av`^ z7$Ebvh4~q|RCEfJZwGS&14Bc}%v`xI`d0t|t0EA{jQo8EYk*0deK1=JsKhE9T1w^B80+#)^-mM$%vA zI6yBk$hJbTmb^};GZKA)Aactp`(uDBK_)y=glfx`lse!@v)N9=coLi6-8WdsCOP98 zd81sw5qpv7s=&I)VM{}d;7knmbfr>#xm`J!q;L*xLp|IR&9v>+lX&KRuAlJSkGYLni)`Sz`K+B4U^;!?p zx-w1nX6J|M?`J!YR7mAOqpNsjiS(C=xG$d|kxW3OUJifD%`Pt1>Ilp9gX)d`>1Bve zQAhl>RDWUg+O^sGiyb6NoeClm%C1(ydIN%H8~oBlS3b$R10>!DDI&p#or`jNS(&2~ zQi&9~PK3ozF>Ot!kzM@kQeV~^_@;~`FamX;e=rZChm!Ftnc;MQAu>EwHq<}v2yXGD zJU7tKvMz1NU7G);*{#}Urr=8s;+f8df^%xwgxr~hg;HT@pSpG}Jw8dfnwOE?+jRKs?!4Hg>!4=#$#Pa;8paU*6~Ext zDcylcgjsHK1#voir)cnCeU!!z!^5fJ!f;9^K^rkk>DQ9Jv8_PG#LyaY^uKnV`ji{C$WA;_C4iJ2idIL3f`W70ugQT4#s{6>B@umi-oG|F z`bA-q9-GnPNcTukDRP)wqM!NI>Gbvfv1(y*GT40)IsE!~|2T3ug%Gw{`#T+nle@d# zVfnZv#6va#r8I^u@iBnONE;b0$mcuVW{FQaIY}Iy!@}P1Qm&94=}QfNp1hpQ4h>$q zm`Hxc?DQ*F7|2Vc&6vo?k&Ukr{m91Dt5^T;)vLzSj*ZD6@HS>tU>;!F3Q-CIAO8zh zB&YfdTv&rZXgS~czr|$Wo@S2h!pf8F)zw<{VQFFY!OEkBg;mbkUVp|polORLa#JVA zt&=zJy*+#4wWd$RwT5=91~r@l>IIbacEsksX^{o@ONA(o%hQ_i$(Tu(iK`?)dDXw>y0(R(@VdoH)vf;IhjmOYA8E;et%;;B?zZxK2=mZJxn!VQMg!8|>>z4d>E@{^8-=CHix+ z`N6Md?sf!I8&89cSB=KG=GhG|nBEZk&JCp$Rk7$_n=qU5#3m|TqXYUx&o%-cgIQv_ zg@-}yyB{`JVe9Gw18?^?S065{tb@}=gLb8pHz*G8t#@*RhxfMl=H%_k8=l@3dRqru z5At?snnGgoK`Hhzf;njwn>5j8aRo7wT#yjK_dF#U_3oq<=o<+UZ*kXu!Z6{-rx5QZybAv-f^*YxPRE<>1`o?w^m7Z zf)vU)jgPP zyE0s$5dxQ#KBSFTC=T%BZ7>{o!)q2_Z8SDs@$|Nc5HQ%3UFu-OHZ9PR9*_PF$t9^3 zIYBb7PSUl<2vp#v{7*B zwWf}UsZsG>t90=4+4}bS7!?hL7&-)%7HhGTQ!I8UTJ95iZO}h#a*B* z=UuSM%N4t-aZoaekK?_qt#9I`013Sdi`(*V(dl^r(1`I7*!;~+x6;& z7btvhw^S=kvS&&NQBF^fNk3*v{ljpn)27+9sQA+YGPp!uEq`jeu%BxFgu#(wG-7Xd z=Bq1Aei|;!%ZcIK+k83LcnV2^$j0=m4Wxs1v5k)4CZ6e2BxGtJ!NF$e-}mYywFF0KWjP3XFdKlS%Bz;;TkYGl*vGrUFe z;w0DNDhR?snCX$3>e{{j?rZ6Ep;%p8u6xU+MQ|_lM|STV9v|-zM(@^ZvujIB-r+5t z6|x1oXsuPc(~HTSVRKpRuVmxTx5aZxIEQ;aBoAQR!YkIp-(kMh%vb%FhtsK%LC$#$ zynJa291G2a%Nxz+Q-#jK0QFY%`z?AcafpWc6D%a&)SaT(e#2d&=V_XTmi8ScSfn+e z1Z*o0z4JrT=!9yswe`Jc4@;#iPru)5Y&Y1E(V9Gh@h6Wks`IVA<{zK@@VfO@E=}`5 zo#zMZnTUqv5u?bnL7zfssUS(Y+iPMh<~sEvkR7)|x6P^$!I(~kSY9cEDYz`wobE(B zjT9d(PkL!4#9bXBmscf3_I4-h@cCpNb2`7ftlZMl?y>xtc{+mTYc&Qg#M%M9$(&$8 z?YrEZ&?`}u*ZU{7ta#FLuP$D4LHj4XO`zx>{DLztB?qVS*()jbtm!QKa(=Gd5!`^~ zy^Z+*0u`V`Q%+6q03)Ra1~h@jfuT&XaI6~^MRcz&zhT_(wqc4PMG1gYiTrGInT$qp zVXXl@nDjF-OZ-NoPh+q7?fN>6k?X6~M;wfM@-?LJS~CX+1ZD?;j!Px-($*^F;v{>h z85y_`<<2a-G*;;6$>{)3aHZ=M5E>*P;mm~Z9Owd{or9y*`toGbPe2+XwF5 zhFCgBGU13SPgBHTu>S?8Co9r=W50YFe!w0plN77ota(S#R%6i!&LNfYGSH6Nz!C{AiDsO zFE2%>E#YQ|MFeehRq}=<#h3i+A6OE#^FK1f94^^UrshgEbLkSt<}hWaX9%sMO%%aE zCOg1(3Z4!OX})v>PE`rZ<)FmfNRyPUb2`rOEL6RE5+?s90ZiSH@j$GpjTJ-6)MK5!wxQT&Y**O6DNB`$xB*RHqzJ>$(9ccM3X?cK`m3MiVwz`(7wNw?W z!)r1Fya%vs>yo73#lDur5+D2`x<)S2$KOk0cft80xdZZW#RMo%jLoxwf3XIp>oaNj z?l3@1Jj{=nx*%P0PBj|`hdds$C`y7j-QqgS`Qs;T-m~hTnqa@7Z;F{0%uPt8!2JLT zf`DGogy-L3FE}&#c@4(dxy~Ur!4_E^Sp3ob8g$#e{!sD6SycD1OWUKl!cZwR-df2yVBvHfb3-Kx4l?y=nVk#w4I;PN zWX}ALRClHqzMdEuN~IED`{Kp!Au=@ZcRy#97y!1B7)~W|cAowO`Ifr>&{CTK;}rMssIpeReGSFv#k(IPF)#YU-!~4M2jo zHH4>)?VlsKy>G`=8(8=~6J#A%Pik05H-AdP?ZInK$N}o3=(0qO%llVHD@CT{oZ3Ro?-rKU)p_Nr8)pf2)h@wocjNuID!FB$aAqEFdJ5 zETZ8wl$(i?zL&iNvIn>K>ZRg5TwOYynVMx7i>Zy<)bBNdM8kG8T~zo`&$BVK9B{F; z)K z?vsa(@hyIK9|&2=WdIecx=s^EKpO_42uf1)kpbs*euC1)Ua;+Vx+k7uBu6UI<@Mf3 zX<%ya#h!C)_|UDn+Pe6?gDs@8ORl^ol_|kEO;1O7>&7fnqeV0XUy&}nI1K`!YYP;! z$5)D%iG$g(iN?`^w>Q7WQ&K$>YwLM!VYK}NT}eja@ovdA8@_ZYJ}r_t*=)~q@pP-JrMj*_im@?9stfJ2u!Ysmc-m;4BK2>i2>$&GW!`HQXjORa~72xn*E)~b_^ za~Av}&0uH-FJC}i^ZMo`2EF DQ-(ly2Cq#eM%q?RZ+`r*#~6!PrvYj?aaivuI6@ z8)9!|*F9w;*#0i5&>$SD>>0Kl3DtXBYn)=lScz}94<3%q^Jhj#+a4-KpzJGVz$Z|f z{G0A~3n(2D!lAqi%SwO2`CxN1o$9+^#Pk* zlH?Z?BgJYhNxej#CJc>Mj^WEPZB-XnpbdKM)7I!_YWJYEg=jp^C6asXV)0t5r!bHuq{1(_S``MDem3t;w){0i@~|a9YnBD3z`i z?VMdxqF7>zdfPV`_L-e1RLv_LOs2VqFt_s#@unM>s7dH(H`uW})Z&f87YX3ReT0(ew@ z4fzQPipW?eA{$3kPXb!FyBR54u=KG*UKDG;u?cy40ZUD&nHy78|zQGJ{cc!)Rfn(g$ zjEdJp>f{K)+)&?VvJmIx$=ak0(4{0rSZWZ@ojT2(ureH>fWiF;#T$S%Mi1_>sS4&j za6@!>qbS&ez=4PwI<3=dbdsq@$iVm)hWJUFYp@6`awfbT(c)dnL77oEyh;(P4L1<( zn0M(6kQcLjN`!6^?mNbca*OY9P7gzgQC5ty*DP;+nDRjkTVonQs#V+|i)+<;CreH_ z{A*#;Fisld9izd6*1+o zeAgL{u%!g*d;)4JTq~J8ompf$y6^+D$@ygGizLJeuRuW-Sq6@k{uXL1auOE^H*R|o ze?>Ym-NGT%64juV+C~foyiry`57$-1Cigh2Yoa?_d^n87r@v8Ie@j)w)byh(>6BJh zmaH53)q-MA$YX_}h2|zp`Dh8qsRvbCeHNW2RaYV>4eH{Is+QQ87X0bzJTrZxX+;(Y zqj^rL6_pFKoBt%ObkRu^Q{F!;rrb{g)sM%05&eQ|@695kp&-)73O zBSI)2wOQo=-i}QrgF>${+AqRzN-Lf+Qx9qNNYWDu96dSjELH}Z>_3hIyCkg zE>(N3ez0Rl!Yo^Eezo=Ws!>s&{Yxzn7DoiHtFy{HiG%FMB4Hbp@T=)&hHQE3EJO zra9$(D^#^C9RI`qntQ|N1-hLVh+%_oISw6<@xRA=x|mn?3{PLyA2KC(z>|3A{5>Y44~a@Cw#h5t3xOZr$c1{TdB4FByo_h++61%x&|u%0_YqAk`IHL)s50gz{qn(HP% z@ifwGICDymcPYXl+_P1cXyJu(b>x|~7Y*;zi~g5TC!ErI1er($BHG@sIf{0dCJrGF zYG0M%T6}nyy1ae++HKCdI?(L~nK-=%*qmOFp%a_@sfnt*K(|;Y`)lo~RyHjX)-iC( z;X#|_?+lo=Rq1m2cIx&9tx~64)$Py!*;OP@6mH{XSw!~@H9}ixXqL0h1>lU(3F8{h zs{a(fs-kV`6484f4u*#$*0(tGR6a2ea9|1(Ns51J@0GH3Iff9CymGz=pXb)kM*pKY z?JTaTu7=@IFeB|?od2uPW%`{I%o+B*I_X7v^nUiF(3UE>afJORAK`8$I{*8>@Z%o= Db5Pfc literal 0 HcmV?d00001 diff --git a/progs/images/reflect.rgb b/progs/images/reflect.rgb new file mode 100644 index 0000000000000000000000000000000000000000..45319e96346f71bee28b157ee3cef40e18910f3e GIT binary patch literal 39632 zcmeFZcT`ndwu<$sj?Z0To4p znC`uL@7LY0Ucc_H(bZk``t_@-_r9vpqkC@dwd;;IYV=>-|Mk_M>!iKrT64}d*IaYX zbt%75COm17H*IpAiyx04f1n2no4> zWWYG!|3FBT0$4&wECQ4OenCj$33z~zlmRFP{5J^6LIH~i$>o45z~3RHI0|@*kkSay z0r)FIs~SOF#xGPD4|n2gK-V+a|W z0v;n|0<8(OI%sv!ni>N}5Hf?-3|ez&&7rk`)&g2f7>gy0-O2zkgpjo!;4VToGC&tX zw!k;r7KH3*fNB7&A$yp&{l7uTAq(&wA;%~HjM>Q*FoBS>8qf*=Ub?{iT!2Tefq-d* z+@yf3fWJk^9r*4JWA^~QdE^0r-=11P1>gW7FBqFwDc}u4-Y^bt;E^|s(Hoxif${pJ z0d51}IiLRxAz$d**8u?I@bv=t1AvAv@YFX3kPWBU0OL-8F()bj-3TR#0YLv45736taSi}vl*|O& zL?{L1n^KQZDg|&20CG+%2f%pKF92X{C$a#)A(W8-*hMHa008qoX$=6HSrP#BmG#dE zojL;m{$&RP<`Fs#dUd)E@V_FI1JCEIB9sgB&xN&-``;pz=LzTq{5yosgaBadXZ|fh zXT1TS^B({(&htRyJdFGNe+2wzgkbpS0s&9~ zya1;GU4VCh{}Z8nppg&b$e#rK4eStdz;VDG0KC5lyuAo|d~q7^j|dgQ_zGcsh5rGe zB9M2{5<s@s{R0>8&Lq@RRgpQFs_?0pPMl5M$om!R|qxv0$^;-?f{ruiydGB zp;lwSJ%rk%02u2n3~&YT_XxGa*xJ7%)NvH>9HCBIz#u}mVNKjF1N<#QUGQDkB0}9N z0LZKx=F$T+dqxrJr2t@Fy~_yo@d40Z-wHx^m;m6_od z_kNgvKdj;YM*tXqKghKoc#nub0mh6B0U!eeeIRFm2LSW|1pqw%cnxz$fq?Ko0Aoh6 zfFwXVAPtZK$O2>oV4NuL4}hEyiSqzb>B#SL{{XCq!|(E;EdZPa6aqj`(B(g&0$zjs z(bYdt1uY5S*CDP$`)5@D@t$n|CCKOg|L1;w^#6k%+5Q*^c;a~5a=zs2q5Q4&X?o`$rp0YB(HJ+ByUauNIqr)P5?;WrT{>%5y%vQ-l7;l zB!H9$=qUnyL4E))fE&OOU=7d#^ZOVdsWl8>)Y{}n}za!sQ|M8l9PrfFfA%8=@ zC)*#i$Y)59&-?&Mmy|t;A7doP{X_nw>`9QaC-s_?KPh_>zZWl53EZ#SuUtz#Bly$rWG^umYF>RDeIr{LinY@SP#R0zk^&3GhSy z0r1)e-~u4~^#_ojg#t)92Lposcu$Ut9A6sXBp?$&jz0xJewGS24oCu!dQ8fnY)=A6 zxu5=1ORfu&XFvG*L;gQ_PRihiOvv_!T*=qucck2Y$ddf7`u_ps@5%3f{GNRMqkr-< z^7%jOzz-VaSV-Cb*W^#?!4LV9dQ8rx81Q5LlX55J|6~1=HjvZqr}NjdldJOOS1N5Fq|{a-^=az;P?@j&fDy8v${hr<`~EaJmM zC?IJkG$14}p$KDQR1g1v04te~PR}slxOHlPI*5R-?NA+!%EhojDwV5N8tPjrSvZx7 z(O5QiDXqx{oAPaOXr>{xN*}rDA+qY z`3MWt)dJ1pbb?8j5DFfP$z(7U0v?0GhR5gxMx{~^PN5mn^Vq3JQd~k*xj}KDwq|IN zL8CH+Y`R8B6Yw?q`b>;q@_7W4C*(8f2vIQ%XVDor&G0Ha!QId{=0b9^0oXeo>ZZ{# z7Kh1@nks|>!hosZ$}|c>Ii!-X5QV{GGubo>g-S;li)|F@?xJJ{ACJ#6GJzun8mG}2 z46c#X#6!o&F}k5`kdK3bfsn`GayfL2iXl3e0cT$VUUk3#XavS}RT|4oZG6wmjmRa} z15a7VLmaa^1B`Io!96zCSD#PNPz@DFwG;}DZcq>qXP_1e(^`P@pyy*zuu`?Ci-OZ6 zu}-4Y$vA?*sWKd=;S6+>%C$1K6Ji*(os1=660@K5$S(ZEN!9fo7QD~g({wRw=V+>=! zlxTKz2u9!(3~L7t!Owv%L8a0#82?R>H_V2LQJAQX%EK{qgT|z1HK<90Hb7V>M>L(5 zSu+S4gGm=Eo!!{*iiHsb=vF&UFh~}_C`j?+I97{e7=?}Mp=X3qZV(KI0!t+vHPJGK zxj0l^Y|7y>*dRJCSHvY~Oa_~eVH_r%$tJ`s8mIt_j?UnV2oNfbM&J}KYQ<$R5{igT zcdEBgzzG(uQQRgsb4#qbdJ?WA$XG|iIaHj%;PCi3gC*w+WCBxb6B>=eU@$r6;hE9y zA{L8DqrkkGs0IXH1AJ>xt29p6ZRK!EM$hS3&{F+qx3AbxF7~N*V&DWU0*uMxa77F{ zlgkwvIHz2=W?jK*cNIXpUi2dj_(=FvdF zAhQ2kO*BEOg!l?69QDyFDv{^mkT~2gGxVIk;~*0fYzCd=KEdMhxD1X^D3A)IGMU1P z#}h#B3|Qi9E}hBa0FOYOSU3T~X`lfC&?-uU!rw?1Q6zzA0(wPfOLUW0Na0Tv=0 zq)DZ4e6)74*TrP-f58pUg)LsrvU93luT1lFHWu*-I*rDl(Qp=<#pGfFiAbR2I%VGo z62M&ed}Ct~hs7m;GMg%rN%-7DRimnWMTDse_yqdP(w8`D9Wnz&5Ew!CsOAG1@7HrI zJRd$Ut>{~B)=K#tuyafX4WnVKQ4ZKDkw~I2_3+{|xHwK1IH#m|n@U*>9+%G)OB4#J z7^Czds-3lsoaXIo!Y8N{18$zgp5d5oC?rYzckCPIUymR6jeWRMdiTvvos*5b1||*a zO29yAq!X(s4&kOZ9zs=}r-Ieg$Z z8;lpZ{;2RJ6BZ_$&1EzAT)Do+kcQy|&JaqZ$6btlIZO@{WB6ZUV$!reD*uoSLw0#| z9B&S1UVZj8?;eK13BPetqu(ixibJG=?rqwGB8}gA~2Q! zwh~w`GJ^kRsOp&{TI!7~u)gVBf#(Wg^{0u%2N)1!Be zAgV`a9FL?lP2rtfC_mLSTy<|`e{*T><<6@@4VOkaqy%OQ6b7Wg<57Sn=;tk%6j)O# z*i{TBh*L%poiwXd9Ou_h#9j_oiK6|ZLy!2I#GSe8meFWMHO%U_1|8&~ai;&BW0iH& zHyc{+z5R5szqh-+VF}D2S0PTN!8S@@OyD02!`p#rR2HAqRSX0L+`V~dFKJ*nhhR@3 z@?SmcIcx9cC(`rHjMkS%gf@!}YX!)8x(-Nj&;W(db11JX8yW%LN3iw74h04e2;Zl0=v0oRW@W6-%)#Ek#-`3w zEM$puQxa@4sMNFbksOlNLtJD~-&|ZfwEb{+>ErgBw{PaMN+KA<;nv4+2GbAHsHf8z zVC|ZLc}hbuseByt2zE0n%}$?2VdhtKR)iSDTYDCdK8@5@siV)I<9Vo&{91#8jSw46 zQRsTNM(V12=Z7bjK7ZQZd-rVCOau#*&fu`vX1zi#*aRH7MG&xSw!xgpX&r8rR3>^z zGZk`p1kEq@Xk>9_!N~Qj#mzUZmT3uTd9HE;oDw)|dq`y(mz0gPHTP}LZoJrCdbhXr z#@mNaCm3|K)J7&xDV7S^G%)luFf9nkG?QdVm7`EuXp}-R&@$y>j@HD&>ZmOC#iOF) z7q1rGw5j3tNA+-=ttz_@o(s%nnq$54xP5--`Npg5gXM{h*)juh(~zxhViqlkHw2jQrE`Jl^MfrOUvQ6#C}K5R;p;2DIsp?HfEBP zo=Nmu7CU+#Zf}3sURryfAOp1lrDa&1z4YS!yJL4RKkCAN{J6&E(Z})>!V&D1~39ds+rzr6%3$Prtvmrf8Dh5eygXcWbd#mZi z?#Iu2V>kOOgdEtA;V;j%e(U9j{cF>^yNwA>&gCg$2AhLpVy~D8eVK?WAomGAdPFgo zdj(L!FQwgI&uwpQ_j5>IZaH4Hd7Y(~&ewpxvRfinF90D1+T_@kEnRAR{CW4&%l)S5 z!J>?C4|53>WAF!G?!MptF!S!i+mgKO)mA+LhY4&t!6boi;#DZ-DwrPyPr6B@GbyPN(qcIx6 zV6pTKLg{^PUcQ~|D%ogtP90o%zIw-;W1%8fAvMvkU@{h{($PQCjp8?ItA^iv-kn{# z)jC~tDm^7FHPx2IQB|z&9DMljZhx=1V|(|emsH9EXA?F#DubmD8!ZbgE@_g<1xKM< zg2FJ!EyYn_tSgw_OnIJmy7fX=*3;F={xc^y1Plx)<9U*&72s?E;dOEBy@ypT<8Kxg z2fM2mCQl_N#KxwkWtxi2*S6lRzGaPs7kM#sY5~ z5eiuF2y~UoP!Pc~j+d>aXrz7Q#Ix14yK^t{2D>*+!HNS*C={u#aoGk4)6hGLd-_z< zwaKa3PfG)}kDgUtEi5h0N=na4@d(}8KX~zBwYzoV!BYRNSFi4L^$hoxolMWUaCvZbcJkx9jeA#G9^O2iVQU}|Gg(g8 zm!7wp;NZA{Cx&4loB|(; z0+Nt4UYElDOGE!bl-ANx|MJoPlh5-5U3Z@^FV4@+wwI<|>=+p?n|QtVZhh(ILUUd1 zX;pvn5M>58lsxuDbMtPGy#V%gY@$LzU7Ulk0xKVwlA+OEiPd5|EjyHcjZoV z&+NvhcP|&`w|YA|vcpf;yxz`DV!}c-Gj-sI6lyw!<;l?a2{_!tt%K@iBMQ>vT<(sJ z3`jfT&lKoiU!Hzgz4mPT@$l-~c=9*{3WhLy#mke2wErV+QPHzL{cNe{;lyy~!rIEx z;**8>#fhH5SM@EE`yamSZmrI~9KSo2>v^TMJ1wpJgh~)3W8k>P(OgSQm>%$xGFhNH zVttBX(@5EI%jAO7=?O@qxZqn)u+JnCku;DUvI8ex30W;`Fa1{%a{8P+K2Ox$G#s4TfaSc!p7wo zjSxvKWmx3G#iObSkvWT^we%L!k9Nmp^^jdG~g^ zySgstV)ORuo1DyhDUU9zcmg(@#GOt>Muv&l3NBOR>F1(PHBRYEGvIOQ;D8bo*ahJr zI`t-JZujN8?Z@LACwV8X6)Bw!TpzCKJFdNbS^$_K2ue@w)NaVHT1lD_%xf#VIjqtL~}uf0-PWk&Boqc zgsAF57ZFGm+;`}k&){MFte20@yxrN^-n{$%l2&)R*bA94Sz*k{bBEM-Df$)VeVdc( z_g9}k7+BeOIy*NxJu|=j`q_h9BTG*{9=zKB{Au-O`(#7Sy|VH*L)H%MFHa|lIDA6^ zVg_(oRSu4%t4avGnHXxM;+#MN93qT*pMrC6HkEd4X?gI)&d!G?&95~A(S_m|3ixew zO8SXI>U)HJY3=BTj_!fS6ZZyJmu9D@#;4}yUw_#h>FHlu`MNc<`+RJ*v3Kz1!h?rJ z_ZpI`-BPDhL;?nbO66pR=j30Cz%VlhwpgHo1Kkv%A;7Sb295&Cz}6#d9>00q_hxbC z>E>e>xl@6^6BRKq8Z~a7JiOy*75A>ZHo3SlIy-uQXy)nM^!V80$(gzJ-Mwc+OG~4R zz3U$)yO(NjR9za}cu>{TG1^ccIG!Mufe-zH>aG)uW2JPlON^C>tEEzKGrAP~c+w%H zP!$Yi*IBipd-cHM?Ww`4_W9+GHQq9ux)c)xl6Nj8jM_ifUx8uYS6M?x(sWveh zu&^=o<4D5u&Zdwd4%qu2P|Py3>g_aULXY8>b&YF16@$x{;-kf;q)y-%=N|k9X8()e z(wXYI%K72xg~{u~ljEbqgAX2!P0y|m+#MX>S(@wFp4^(>zIUba%IMf$N8S;Qk(eoF zfCBsL?|QzlI6YSXRMW?%-oefLc}L&W z$HYr$;800$OjH#Qfpm8$aE2wyFY4li{kfqkp)Nq)gKoo{z z7*pzU^0=>8$6{qm+T_#fq?;Ff&jxeA3BY0Ja}PS4{$G8rT&#O?z3qPK#EGm^LxcUd zd-?{3h9|~y#^#5X=ZCr{H%30J+?twu)Z4Y#6n0Jl5lkk7bkG@Wqt@=XTN^XW*B&j8 zF0Q_RY3NDg+sbhn4U>ZgQfbySO}bg?$yZ7B%M;I^&BRm=kNL@X;8AiY)cDxL>3^em z7gn{+Ce)q1HmmR8TV2!DcBAdi-JyYFr)DQ+=jJDd=igkKd9nDoufM6PHK*WexZFa; z$6;Y(9G@D73gx)fEg2O?~- z#5Vrb^jh=Uhmp?XbMJSrO>NCisTmknPo;(#{~`XEGdCJHbw)a09-D6-SLH5Y=;dUm zS(>S&IgMSWOSRQ^11Ec0Zq{BcJX3h7I3mS4z(~qxLx@(akef&MwlrSIDD7N$F*P=B z#U~Y?N?{n1hYUJ|0tzOlH|J;Sw|{#3Xmt1e=k_Oi`@1euBQ9=D^)&mPJ~jOGz4isM zfG4E0m>J2zR5vwWmlPbvf-s$Nh(Tjud`Q^V{o747*UK)XloaIWpLSQWxlG_79CGQr z?ItLkR@<^ve|#Lv!$*gE&tN> zs>7LAQ@a3>0q8^Iyag2o|3w=|d|gDtF> z*?84aU3oSALVj_1o)L|Vc!0Uzz+F8p1bRZc)cDwC1MoH=pg<#pLMiWJ_uY!hj9*aM|vC~(1xvua`(b)@yXT1qn`vj~lh*IJV15dwjj*Lcl=}Bl-5DO-wKn#v3 zGPi4Sy)>ci)BB&keqDO|X=`V9=k=?fK7Kr1GuA6){E5ELiA&4#5PGHYF$Mu)GO3E8 zCx9?I#1ovooG;^;Xqa=btMst17=*D&fGc1CbdxT;iO%7-6W&kwftVFP#JX zEsX^>N#D@#^x*Ej?CSj2^ZOs)z5TfN%h%5b&z}GMZYwr#<+351yL=%yb~t~(yekj; z=`<>jM+U3R2?KKzsRvz1g@^`Az+-Y01Y54D9lBrLbh)^`vu5DYEqA4W2d=701R)&a zT)yCloJBKoho}u$b&RQY7I2O9qq}#$EH+&k|1`0@esHk&d1mFq*MpZoZET(_STD2% z+kE;5|9$g{d)wJ;x(K4<42}!V6Y4R1Aq2*NScibYl?ezAR~RrhGdez5(KAre+H<8T zSH`2!v^;^Fz*JY-Ol=-8edxebGD<%Bs_M>6Y|zkGeu(!KQQ>B=5xz`^IY2M3=% zFU)-Iy|9z-1qZNWjKlfwQ@qbs^-sfjlg?m4NZpgG#4IFkZfuMJX9Yfdj1df(K#)Jb zF#l?z?RKDdj2Bxb1}1w7&BVCW@?uzss~4S4VZ(?qG({B{@)QvF8B69kt2*%@AvutN^vc?+R(_9@_3*(gu;enMYFU}x;ZEq zpk@ja4s4@rfx@Ka(UsAT%Cq`ve@~?-O37q!9rfi*iJ9%AKo3Z(P?*$Uo|X>*3Bu9a zP^z<=`GkEPx_9Hr(~Y$h(|e|!Js`PxqZ*q1^h2#V6&{*b@2@M2v&M5Va| z&Z2t8a5J2v&hfRzfif18qg8UKG%Ag06BT&&?88(OYq3av7I->5UF)S|F+_YO8h+Z)RVPWU%&nK>u>e%F@ameXS$(osNk3Y-0zRN(_NBIABugm_X>0q;b00 zw{ri%_|((aKmGdaZ@+!Ve(i)I?7UbS9QwLbVsA;MvP^%UJ*~35yNu0ZNYo6T+TJtK z-$m-|Vm^1PTwC zl1G-GQmIBZXPk2?n(i%*k4!D>e*5+NUw-@k>-TTpzyIa?-n046XJ6l+(^gZEtMrik zKVz|1J01a(X$CU7$k5!z$$@2N=b|5?3-uH*=v*bl4CoFQGdlAkLsV>;ML@)3AF9aO zS)i9>ld#y_RN_>6E-y?IaoHA@J`LhH5<5@(vsapWh6l%%_rCr5D{%e$Z{NNH6Mp@$ zF*ES_>$~F~E*ORL`*DLBR@?rNqr_<}6@goL2;6P-4Qw5?-bxEcQ$ur=9AnTqs-WZ( zC0=H7g^^)^tF?)(gHtG1rckQxJ{hSJmHU{9_(HB38*-imA(6XE8cM-8QxIks+I9JWc0GUD8mF=^yU6#zK<(|pwO@eSzy13C^UoyXfBp-+{I)VZw)y#-J&!@5u@8y=h2D7UX|WKtJRFl+ zsgIag8*}CMrcoMmD{Dtbuskfjv2C7bT0~}wBa5yLa&s|Ky6E&dgjyx@yBFqPeIYei zk6<4W=u7OR9xk479`eZQ_9vfy{{G8P*e`c~{`T9qpZ33yQvdDy)A2{k&n(pvoWisH zedbt8%j?^Y5ZtE|hJp5WZUM$3k(zr{X<}pP_0Oteu=g-r4yHxc=?&_;jA3v4Bc5 zWFC_K_teW(t(U@aL};}3wl+EgPa6T7XXj{OVQyt*7vgAXX{av~8v7sh^^A9r`>KqL zI9y8uC5P)qY>8TzQ@fAqV2?d{e#J+8KD~SK_4_Zsej4n#>f;A4F->t8q5Mbs`QUNUK&V}BNvddL32g)OOT#3?0QY#q*7&*{Q{im6!Y5FFybB)3?3;=AsZj6(j3C$Vl)%gu8mw+SCgRVMyfah7~XePe-2Cif4v^g799nw+><+uL+@ zc7Ek@pvoZZxV6n`HA5ahH$5>q{djz0bm(6H!zXLc7S{LPKKt_XPv4$()fI+IAf;}3 z7=ZoWy&N2Xp;?dfQ>d9<-fY<-!%v;E+yh`!>S;?t%UH63+ji@lRwtxfGM?H#xKMyAFF zW@ksAzTe#V{Ndt4eB`SYQ3sZd_pI~bpOx@kR zT^ucq?JQK@PMPC3N}N;u%@yiIR}&B0v%U^tw*HlFDXGObwx))A@>`3`Ywu*%Pu%Hf zZEtOBX>af7z0+PN?S`Ka}AI09_H`mVCQS6)EV1Y1r=Ytzdo?LJ#qc`u`YW%PhHxT%MTa3 z9wg=_2bPX>-)tItF!x}v|8f82lERCHr6u`=MFrQX_D&hO!k8-+#Px4Ig;AJs} zhrR8c?GGOhibwA3zJ0Uyq^}}C-!N}(w5{RZVEdL|RjR0FK(u+ued?qAz|7WhTr^-6Y2eehE)7Lk1^YV2l z+&ehfefMtf!~2~*ApK#bdHwzF>!rKd{yLld{EoKXf$oO-E5#Si=471ANKH;jii?kl zjtDyv6zK2g=k4hi5|@3Y@pkj@+T!c=;$~MLh{>=VRFHk;pyyPHM$UDKvvfBz)v5)~ zo^DoN`8)6TcHV96eE6`xxBv0;r@gs1d#_*3+zCA%aK3-n#&Mxl3A@Mm^TH0GCmRB~Lk1M=*kkO!vAZyJ<{~A|o1p28Lylo8C zLbZ>FyQyj1yY20_@80i!`t%Vtr%yk9{&*f!hq#jR< zkBJHo3k~%5_wn|0b#-!duy^(ej!eC9t);zpZgq3?h}zB>{5y`m{vomdi6YQQl}4Fa zMrx(VHrUfm7i{!$ht!hY{SOEG2OmFug2V2Io%gTTmX_8ATW=NQWS`0c_N4;%qM{-~ zf&v4*y*=Groa}7v>}(+K9}=5gT+`kcenF)Q$<->;o028h@%nV{(k-eArap0Zk~QV-d;YA zF7|frK0#5br^~BvjgR)#dzxy@?Kms})F{DCDfBloiO^HvRhAv#7vO7a?qRpE1M2tj z0A};y{r2AbSI<`$rY9B_XZt&ERFsqz6`V>-Ns0^!2=Mmu_Yd@S_x17e^!Idhw0HLm z2v0g$aOu{Bmz!5SpDWduv8CK7DAN(56$*!MYp*m8yBQPf@9gO5c4d3_!~XuqgM-fp zu%@=&y__8%o1UJXf85mAc&+lnnbhOSsfkg3nD;11)6>b`#@WLgRL<2WFgzjSOi5#Z zlP6cg)wyb9GJSRQVY$&0Duc;$78oR4@QVttJ?4HCr1J4#cmLyuT`(5gZ{IwdhG_Z7 z{Re&R9qsLv<(XLeMDp?2sF1K=e;*G!TPF`6Uso45@4&G5w4B15qsx{8Gkw0$#Qv0l z*dFqIWKkA_7aB-d9JRK-lo{sW)Ca5c0G7>%{SP0uw%)vawl*_8(An12dAqygR`sQe zxvA+HnI}?H;^IR6yc}JGnPzk&zlNzI{OIT)85(M+|klpQ+BbS;LNFvl+=@n5wME|K&ZgW*E=9MDlt8; zcB;8^qRlri)6z_!mRs3Np&m|#e#Qx&rEf%>rMFb>lkjNbX6ucr=2=*Id+%SaOixYD zOpXrpb#?Z1HQu;ZcrN{T)``rR&;TEA|8Rd#A7B3?;nBx3&a@5=SG8QU4NNrQ3)EVv zBL-D`a;W{Gv5c+H+Oti(t;_?v7eBn)-5YG7XZNiuMcEl? znW@L){e9g%eS$-Myn}+mViHnv@*4*qmWKFSYs1c|4Xp(t4-85V73cxZq)O~!QeBPx z%{4yBQ(L>hXxPfYSAMp#@MQAAJ*;KAuD+`H{PCpZ}zyMfVAwj{R5z%qU897Cb zV=d8k$B$dqmTHYf`VJ9Lb*V%LP(#8}dpp=g>FL|X#WX!yd%OAO{mZSLt@VZZ*}I+H z-3_o@D=uEh%}h&*i#!@0cqB9|G%7kaF*)OGer3vXs?a`# zL1!fC>mS*mEwzb`;sRz{Tl~mL6&qc>!aGV`k;xX6bDzGF6Hk3@k$GHaDhvtCQ1O z9}oAoH@3E1E4y$mH!VIsE;{j8V&d`CwDioZyz`}X_hzoe#>dO`EwoGl$I;D|0!619 zG>w}GEvy}U9SkKB0b8gEx!y55(U5S&^F+E^Q0Hv@<-Dv@C(}~X(@$odI*sM^<(@4l zzFbw;HQ!wtq>(!Kxhe=_$2eoC>eZqVfxgbq@w0p?ai*avD&l2QlZdVtZ(4Tx1{JJWPmm)Jf%m7y`{0h z(nM=;WX93WFWlWcFs<&~*yB4*cRKF$^>wv3H8*wk^bE9IZyFw%Z)$4njxsYaIpt!a zGgR9cAY=qpuTp8SubGLFAoQx&h2?5fH+w&w_pQOk&c=rFvfAFU{;uAp%k6E~i%Xgs z$MRaHA5}=C2ANeQ!Pf336hrdH!y3Von(LX! zHN|3mM{hHazTx`2eKnUWlRP3lk5vx%c)6PSiYaDr&lKtd<+kQVT9H61;adx|d==yt z?Ajj>b=|5ix^(mQKuOD)s=~JN^OY$o1qHIxHs~=`rL*-nc9)o|t@r||oNwZtbH2Rt zPN`jc_vO=2+wAwdZ&5#Nn-UaEy#-l_aHXS5OQcx z`Yz%d7-{H`BH{~ZQ2h;Mpcv|gN;oDIoD%YKcDR?J?U77f5W|$bIM7SbD3IW1NX!*d z2~)@9u=#MNRAK5NrIT_JsrLEXrWQ|?kp38jL{eYmA_mQnbzGD zisBe7zEV$Xq!sd*Pyq@YgH#O^y8=H5)DA&jIIDZ8bV_4OYiGg;A@bq?g=QfQv&(Mt zF@fqinLwr%@TpqVj2kcrk%UEe(!eS(K(}$47#y_3@hB+B1W`c9oQdioa1Gh<8#oYx zTwpB)pX!Y?IjaY%!=h8EHc+SlPeUafg&ZsS4^%RYlO@^(F77m2+N=w0@Z*d8<;XioHKdZTmn+XbDeGD?%bj?CH18O ziWoAt^-zQlL~5XNw&t)vmyYT{W(3>>K@_$?EVi;fEXVJFVt&(*m>c;_+_^V~MF)9+ zuEH-7##Tz`aC)T(4~cd|DFa4U1CmKm&>o1P*#;ig+;?Dlxk1zCB4v!|etQW)P=%-y zBn?G|at|0EXbr*%HfShZf$0`mvv5lT1|2j47s!Md*UDaTSXkdlwd_lMH6P2S)eI?= z$GS3L8eKpO>W&fg2}x&$(trh7OLPP3w5d>?(4#ZA;1Vvj3P`t8bi5=nj+DQ;Ah8zmg$!i(ypi^K)pe71>L=s4@CDz0=FBBo6Zw%$ID*iT8aG^g#CNK!S?>n=3zb;XN2@iWZyc_d- zkHGDEP*u1N)Ibgtir-N;uJmLeEn6aHcnH~vSC|66vnzDS2Lr*Yev-+B&~ERQcdN-# zIRiAM6YBV>WYPxKCX}**4l$rkn~wUa46vH($TreD#1SB{vMvPBQz`fLJUFa*n+=z``!MV4@01q-Z!&LpeU$>MR)U5y%NLIDOiKr|jf5hcjoL&ZiBGk0w?#|E#D4*N87 zT|zTU4QUh$M4XEO(+worc|?4fwQWpi^Z3x2>KP~4eFTmny|0%!g)W`vK|7oHbSbC+ zg{hAjG-@>vX(#a%`&2 zMraG?33$X`o{^ydnsn3$)e-F~acJA}NYVuh+p@6W;J_mxM?jLd<7%f~Z>&wNKa&K` zzev);?Hls44;Xw7SHlyDU{OJ74}oT(JlYCsr71K9BAldJ$%(!vVNX+2t54pFdpy=# zb|PKIf(#z40ZJmRF5r;rI^Q5SRAQRYeD$20t@6TkA75`zpMc;H*l%w=I@!B3>2mVI z#kWtZVY35s4Rjh4F$2(%O(@vj`_6`d1l8T0x)@qkZ z94$|8m4Av~6wdJ^%l@efC<=#Lo`{{4VC|>U8H6g*x_f2@ zCTG@WI*N1d^oP-CTqwXNbNsP&=0KN*-r$ysNO5@d)ztAKH^rqU5#U#H<@}kjV)c@IvGW0@dcLFo{=6JYIjGr%4pu2Rxz2?H?^jc5b_-Z6ZujRteZs1m|ULBAo&~1uR>Q#H; zTA_b(w7Vd zPdp_3Pc&zlUCiCOtBw(+mR=W^mX}wSS5}@b^>!2~&B||7KYQ3zd37$%CP>P$cr_Tf zP}7-W>6k#HiJ_hd`OlsSHV9Lga}ZT3r>aj>-qf+!_AdTv8;5a?%to1RrnQ&n69f1(q$C6eSR+Pz3~^LJxlQuxWPv)w|xxb)7(HW(n1XP^*cY?SV9oc5!`?e(aMt zdyk`WF5c&778d5A1b=aTbHvBS{bcov{)mAqN6R&?-Ufxi;f5WhQJ0)k$C4x>I%xxw zLo-j81|y1v9aG8@5a@;$j&n2u4T~*V7>8=yzi{{3%)|Q+mip{e7Tz*B>|g|eEH52S zdPQHUJkeYcksjvjojN)1~^Oym$`4!4`ZV2BWh+_rG^fMS5tGeabLo)w*4YY)2eYwlmU=mSa# zwoJ-KhPh-N9FA6)Jc-6Fz0xy2>EzL>nd!N?sj1l~3p0f=whm{9a@?JJt1oyKnZUhT zWo_%J_24w6RYtL&GZeA)QYk(PLM`M#(6(2j6PWW{toX@8mj9KZl&K6OPbFkzCs}pPOihlBj!)0d&2)M>I!Co< z=i0WVHDvb(ilqD_7uExujCfG3CFM$)piqcu6;zO@(1x0;QX|40G&J0lo$o`|=E4aU zQTUcRb3;FER>`}P>RT&)=^-msks(s@h${fAA8B(q_hr6Zs)}Lc6j&9cMAeOtkBy9s zK88C+cZz&G9RiPq1~r_$-8Gl(=57&mbJ?E@_iJQKxGayMemF$h>!oKqS02?`_}{E+ zv2ujFWExCCI`1P;Jjyrr;Oe5iJTKlatd1END~vsz;E@!>ZY+i=4@LW zS8Z?&R4b9lI4X_8EYJ>$MZrwc_#&;&Q4{9nY3Eiv+B4BwMf#93C7nx#Q{ew( zz*h=w!k^q|E55f?Umf4I{4%d~`A#L90WJ@OBFXYs94(6_X8QdU4p)k(TuY0y9wJI&ds^_AN%dcx6!@! zUTdy7*P3&TF)L+EDbvMCGU5@0uMr5l**3sfaWY{>>4Hg7N{QJ|5CAS7nXP2zsZ0XJ zo)|B)TCdg1L^7qurWezJ6^5rFMso#Nm1!BAJ#OF{99_%spJ^Q2+yTTRbEJz;oH#giG9yAzm29C&eYAsIZeWNbob1L-P! z2tLoZ-}LnkjmawEawQ52uA@{$58^6IzDTm#6f{gBN1i%Jgm1y$V6((ZHO0SQuhfX4 zaXaodUAeM-)vZ&ll{>dIRX1H69y!8SBzB?byZp@(o=CGenMNu`mJFF3lFETcP!S=( z1*eg=A}2Yf=vb^ss8g``46Z<^2In4mLDE$sIYQ$4_eJPys?Sy)KHYfxMs7$!KA+)2{yp}8Y>s@v7`!mvp9&%*U25cj zi^4$820AnxOahG@x^8=fOoO})U#OO9EO<2}HDTPaE=qEY#L3suNFMkS>?1Nz!!81? zT5IWdt|)g>|Fc`J)mI$2URmFG^~#Q8O=r)>q!$HAgfy}hZ;lOjnapO&2aLxJ1td^t zTQDg`Ulm~fa_m+PQ_N$t6`&Q6x@Tl4Y*L=V-;mlPK>*%9k-&s%%8JN5VK5Ku8LbQH z7?rMYa(Qa8CgbeA!;^+LB7e|u zvt>EOj)Ww>_;|>gsL9^$Yu)x4H4C zlw^2gnAII%gHvW94GlRPCY`|*a!GPIhXVvC3lM7_@-|copFs*AHEwuGesE8jNFye( zIJh;+DKIs;B|0F&7kOx82}rP;GO|b~Q2H9}W6GLaZcoTA*j{=0_U)q$H(Oh8-M(IT zc;mrtvu}o(u}>i)Lky3FSDG>@Qh0y(Ko>4kO*6RCA-%(ZfR4s0L?TegVzARjr1i|| z=H!W(ASnb3aWavBohY_C=KK4F;1IPV=QZ6^Bdau5I=vxks_m1DqlLd=Cs*MtRyE2f;iSAFrw z_EJEt>w!Og(9-_kX6>De`{#~0(&#EfW(}7e;`8^D`JAX|sIL%GGb{_ENJ6d;qc;NVD9p^ILm@D=)m%OpIrk5EX6FCgcD zPnQV2aMyxzlB@F6` zS61qoVyaq{9ONtZ^71zYNoisZIEY3J22IeISf7kwRDZ++`koFmQUuEJ?lk`YP= z7`~p&m--jrhR<{}P?;jRr?-RQ<_OSrGaB4LWMLx`Q<&bPdoLN&Jx0xwi9G{0_>hDS zZ<^BI?6+sZtbD(M{GqA(&`~BTN-~I(5^J#ks97M?ZQWa5cmL7-4(h{A5865&fMift zd30rcOPQN@AQ6VT?l2MqJzm#o6OBit3uX;tBuR;KPlFx z(wT*JoCMv10z=3GrAWML|F-eM{9wBbGAn8Z=H7*Z>Xmmu#{5<5Hy^3Nw6{Na_~1T} zMa{sy-oIOU9){Q8)&ppU2R(o6oj& z+$TP~;m*DL9qo+({N8Urb!hMLJKg+n{XrZd(gQ!OwyAM69-9Yrs8E{;u7m_+^WLsD zA0I!q3w(~q8jxcil-Z-Zl|$zn)UG9Ao>it#6_U^4pchhT0 zGGsC_^bcnExCtrPcuX=!=j|CBFIVby#u#s_S9G8iNP%gbi;j2by3G~N~)sS&$7 zjb<&IDG+!sI(#tS5~oZFk9F0IOjc+l?py^&pJ|Ic4tRH4TT5$mmwyH5&u;*m-)X>kQ|jCTh!`=4QZA8k_OS z;Lo(Scig+*w*TPqK>!a^s1n>P@ztH=;DFQt@i-tD3=Ti1%{|enlF0)@Exum9&H%I1 z$IHzm7g>|jW4+?MM7|=ej>C4C6*LCh>KPet1$cl-q1oJna|6aFia8=}Zns@$fuE}f zUhi&GYjZQ8iHI?6j~ef{>^ih1L?4b69g1`aMGx%`*TFr^i0($NzqhxqIoDMta?Ms) zy{taIKHi>gO0gq8xm&ikhfg>t1PrlmaXwv4=W>Vi<0+-!&?-&dk#4$Rj})sW#NZbU zes%rjf*Pjs?FAAwok`OB`FOk8 za&;a)8CtW|!^36^G^(w^@xXr;_BDtD>`H@x@7vv~6UuFL*D!y9M!7BBRS%T~d4$Zf zyIZ75JL^*Yt=j;Z-hqnH?b_?L^>yHyH?`lt+i`pI^2yQQ$}&g{49q08ImC*zfu1__W02)TG2=xxONsNzIi@1W~cB{=-=`o-w^!aB}qc z@pF>F7m5n8_z%%A<=tv-)ZDy5y}q;h+U3hY@-)=e0lC=Paj)&%`o)u?RR~==+;spe zw*?3lvAIYhxUdEG5N|+pqrzR?7z({cqYDNGFgZRkDk5*N-R9-gNQ6Shmii)T5SK3C zjGd62DmJdm)j4JH({m;it_(5HHm$yT>Efjel~rde&tJWH7Q8HXbiii*lJ)XMGWuUx%aRej^?EdUN% zabnpzHrs=XY{l>Ff1^YyQpb#mlyX>Xrq$oe%f#iw=Pq72zui0BJFPHD8o9OXWEr#z%8#Eo zcJ#oG?d4amUZ`!VZ-gH?)W^-Dppe`>kygjG=cAOb3+XY|;;-i*8aO>2CZRMiD=yGC zFxJm#a}V@MpS9%hm06X?`$m}6`R337O-f?72{VKGO5Ai3W8Z`2R%Xyu7 zfdeIn4(>ltvU}II4ePg_0xjfrV?$G0Q`5mHNZ*iXlCZ84(MJeKN&_Z^_&YV;7PF7d zRV(!h3o2i^Y0>PB>*gP;y@MU!QnR$Fu?{%Zek1+uW=~(Qh@5DD(+H0Np^K25IeM)0 z(18QRdw1{NwQI+g?c26&T)Sq~^0m88U#h%tyQ!|R_13*9Mx0=%)Jzu)$szsYB2ZX{ z4vcg9`UNFK&!WV z?u4?kLq`rB*tZ8mZQHVK^X5$()~#B(Y*|s!;w9@3l%J~vV7k7kW%YJHv4{qP_3x_U z{f*Ls!SDq{@-M@eL&MjLv6>r#pp;jzg3>5Yp>dfs^fj(QY_0Z|cvsd5^PX*64YXC~2 zdb2Pbs=O?Kcmne5VGf(CK^mD98xT9anc4!xXfr;s4Yu9hQrXmYuc{yeLC$N)F)SID z?Z}b+dv|T!xMBU;l`B^)Uc7M8+&MF*PM$n*Y~h6Yi&yO|#c0>->&^~O6^n2dhiV26 zp@4RiAr7kRF)Y>`x5yC&t@7`x2n;do4HvbrAeIaL(FVTbeJdnK;Hr?lF4tek@nl z1Qr87xNOdfuGp9_RIDTCIsNus$3>`IY=Aso_N{&}lT)kO$YVb&g4jf~ONRLvv zfK*H;I~A^J$!3u_Au%P|JJqYanc7NgThY1*6%!WqN1wic3rkRSc`CEF5E7(zy-42 z9PJa8m*sCsOioA&jxp`LhgBkm06!8#A+Qs0_4=DN(6~8u48)s_OBOFFDq29DcVzaI zNt35doieU)g0j_2li~=x*QCY`7@?WnL29@j9}cv zapT4o4jVOU#JDN*mTuU7xa@54#nO4fCaKoWf+i6QPzu1hA&%)O_MVuTn3$aC?;Yg} z<{wT(9qk?pz)ux>Xwyd9N5xFaA0<)v9 zlH=Be>VAw|k=abKCHweI8JXf2u`-Cf1IWi9~Lr=9^7wY;xFp8?E1eupK*w1(1qD!}S%`Jn` zcC>^{^t&mQP&cTXQGlj-<82e4`?(kTjwqj$!;X#*{~u#{292!aU= zq^+&F3ApYXS1*=BCh2(To~_FlgJn=On>KCNoO!e7E?B%Ax76(=CAnUDue4b6-0|SS zDqTYWol}z$mLQduV;2&E6M}P0r%5tTIU3zf$&aLYa zN|vr#vwGF~O`A7u+rDehp|V{QGyQ^6)f%gY!Q(rFT>*L2lWN6utG5ljSDsA76NAx~ zwy|VKulTT>FqJfRGos+uEt@uNDBiqf)3$9pckbS~d*6X0M^9FqAL3`?37la*VuqW4 zw5|)qeVrkc1vz}ZH5xUS!!-^b8r3awT$I0?ck=Abo9C=5JyZhkR&wajkt6tBN$Ihp z$4^yVTbf{n0xaLc)0l%rTEIU|q-zwecck6nA@Y=|6!8_l-XY0Oi>F^f)Q*E&$CYg< zJC2IyspBV3tX{NkMqKp1s*0)I<9Y-eRGL2iu4a?UwF|?2nat#c`y0*f!o)eD<1WoJ zhPrym9jV!lK)X#Tca51nepH;RF5MZKIdt0Ey;=Q+5AbGilzEdT#bTauZ*nJ9aZp#6 z%M`ZA!1;4$jf?T{?*)*3c*ekNr`7BiBNr*;^yXRPmK0dx%mWH^ugJXsqu}RsO{zFrgJC$UOAP^ zP*VYjW-wj3!1H8F=+I+j$xK?g*Me2uGb2<|wOAEnOB=P;#~Emj5L*d}{bMdX8AmDP zint6BTg8#H=?qEEsJuvjEl=#1JTiR#z;UBjj2t+*hfZ!s&mhtv22TjDDD;q;8BCFY zA-4^HUtV6IUbJ|8kHVwV*XF0&r8F-BxV?wUaAQXCbfFP!6d!Z=oi+LOR;R|uG7$Z^wELK=rHm#d)i zDbVUUJgHVgG`4~Y4nxExvZw>;@kX)Po~^P7vCM9yb6g%MmQV`SOL#&T9Yes9T5Jxx zr`>8b6L3Mfh=U|N&~GTF(G>w&JD(O1C^ZUUTabO{faVHSdZAs-L1{wa799fyu^!oe zl>#L^I*F$fKy(>(3&_3$?nt9>odOw8X%ZM1Fl?Z=!GSi4qD+HVM{CJsqen!1j9G=c z34neIK)7{u3dC+`auZ4@gwi{M#!d9*W|rgvI873w%!CT*T7Zy@B9t0{foPAPh-B9-S~JK}(n3_(mQvU*_P~ta zz-}6U@a)L^13e(tZ(cGM*t7MB=frH_FwI~nJcFS4Uj$1dK=BJPpRgkWyN!MTWRNuD z0(*C1z1P!RhT3(}TQCEK{HyoT-`LLRdVScqN- zcu^YQam7?7MW2A$8D0|zQz@~ikTt|pi7CJrEu#abB!cJ)X$6%plL^FXZ`UrM_$IP$ zb4E**jltU37!ow&>_VbD18~VOD#9G8)csu&RT_e|CIXIvxO{(o&mZ}Y(c{4Ab%N=6UA)EyyIi!+k6oFPn_(+lqH{FBDRF6Rk46uYPJjS5O^^1DQ z?c*OtRle&e+kRvBta(70ZpW+ONq8hS7Tz1R4dRP{+a`Dxm^msy+d!6Yfw|L6xKO~e zp}ef>qb6}fhyK=EFQ#)wADX8T1dMGM*zjlD#aV$;U`vTb+6enb`vV#ac0o)s@#Q#D`0vvld?;DG5)?zOwVrmrLv(GSqQ@ z+tW5e><(Lr*j|KnAO>{J2Fk2mcysJ%4yq+u5wQj|zCJGm{XN5G$~8XH<+2K z*xshdfliVju8$S&AJ}t-|5{J)$h|4i(F1P%_2>JyZ{M_cF)?Ue4J}}01d4_X1^A_e zLNUGTdjLXDTD^Ke2#>F%(Rl_fou-$BGNoZ&B*Tt=cr2G#0I@PMOu1myMS&#u!K*)7 z?>)Wm2b#nt!oKk7m}7Gf za8Y<-3Ho;vXh+_O7YF02`LO+5YGE=#+OVTMytd0TLhlubCJZ1%wNXf5L?Yv&Vl+%6 z-(()J$ODq;YEKWELP=uu>Bi_v+-!0YELarC@Y)F3&I|AVeDn0~Ne)c8$Za+-nMJ5f z^N0;if}=TrZXL*qki=$peQ2<6&#cHfMMW8qz;USAF2L)$7W42#4iNaPNz1bMkvBCW z^{68qFCIS8`M{kn=h1W&a_(s4k&6iBI&9#D6dBasp{_+p@N>C=4Abr*;enHiAdDuE zaAl~3Q#iv1(7O^^8=1WF74CEDv&2gOj*8tkDyJa;ucqx-U8{4M(~E$*VfEQuMc4Av zNlPIgN7B=Tqyv~)n#!Ff;RzC1bkA7>qRkb3Y3>ZAhk{8W5Xbp$cs|@2W_?ZnUVDor z8pndlXBXog4AN@qi05y%2=?ZR&3IvuaA+Q=5Cfvj5ot{RehfZ`2~amNGGNIZg_O#5 zEGb~q!!`_>I@CFz>Z8;J!0{MKF4Jtk!RhOH%w7i~M$d{g3|@2c?BfK?#X(E={KmI` zsP^YoEhlW3%%lSVj}jyBKY{)ZJDV&;w*b;XvI-%9hB_37yC-d;3rje@Z_><+B+yeJ zBZxa?gk|_|bovH1)8kxd|DJtxqt0$VRbBvg6lnwX(v5p>-`bX)dRru5YbN!AxZHZ| z8C!aEsE?;bFC_s&F2EoA;OPk~hcbg_XW zTAH7geZn!|%)`xtmtvzcNF{F5AKZKUclXM-Z@OCq`av-SsR{^0&**TS!XT4La7q(` zhDYY9NeaEO{}Rv4{473CJ|e;hb z-()JOl(OmWAAdH!t$y{_QcLXl3nqeXM$~l46g6lS_yxQXP}*6FZx0Yg+S;Kp@hXY!#@zs0`SrB%u8@w@_^erg3loV z&&mrOzRkYR=G85_k7@Yuv}jj7vCRncq$Dv`MB?`t_#)eD`CLc$b(dF{E|`?Orz9yk zE+RIoPj5X{T>s!;-TO<4YnSYL^K=#b1BQSv70_55wGW>Sr7lot5RmaQ0t6lWh~U+e z zPM_-QB?pgQJu|z1N>1-SE2{QvJmqH+b5mx;0y)WmzoXhGU96j<1P}@!8_X+P?4K)! zmFy=7Ruo5?3sn`y@^aDlnlpNoGu*OiMp3#Z!wG``CS)0f#$b+%|BV)3&y5<=Kc#A8 z$Cj7#7vxW=en7qds{PQ6q@20S=l0xOGs+;8I7(yVVl-?~`UEG_eO$qa9E{3hfnq`7 ztLZYK8FNfTOK9amZM27%sUJfr#NkOgD%=obP0AlSB-}7#0FK={C89q?Mo!#{i6e@@ zQjhpag=H0`)B4TmKcw;z+?tV7xMjjU44`n1|&4g z=w@T%KR)UsBew) zOd6CY;D$)hdkhlV0!qxDWe&h&u+BI!dS~_U@{#LxC@b<^oDvm<=GG(EJtVqs!JM%v zLndMeV{WkZWvnf;y2k#+42T}O==S+DR*|E}{G$(`eh2x#hY#wmoroKDrsm?FM6Gt< z!;JVj$V;@Xah{vKCf#C9rh(54>`&~GOsgQAhv*MT7~Rxuz!VLGDrQJ%B9_`jAo5r# zv-_qkTDIi0U&a6#DO4uG-GS^z&DgBz!W;bJg#}ES_~5{HlV9M}%deh1egb5`(xNp?n# zE96fxuK>A1n-Bv{UFA7^Z~yhh!@JG&XN2c!aE)VA<&HfdZD7{hMd|7JD=uDI9hZsJ zvW9bT!*HQ$L;@Pg5S>PVcHnME`w)O}U!}(^i8mlOHNUX;_IM`4*X~P_GiXWVJp(Z~ zAe>}wRLImD2QE%A$4nnz+6D~HgGb0zKdGMGe|gEyKmMqKc6n*W-~z5`o;B~zD!Fy> z-ONOsbTmQ|)0gQoM(>6V51nLpIFvFp-HO0;!`<3vqX8O>i z$t7EduA9iEvm@Q@*lW0@cpWD~J|xS@hM1W3=T0u&I&c2Gt@Qvup+58A{^LJ7PL1)j zxh_mO+p%Hd{a{6b*B;t%wh8s2 zmKIva)f2@-2Zwjp2-2F)lrOC4;qU24-n75?NkU(dC3mQw4``mah5CtT5b$M+c(cVy zArMjCX*m&uKgZ~MwK{p45U4Tk@RdP5X7x2poD;8+P&61Ehd9cdt~oDe#0g@PMwKqv zdtlw53n+g8AVF<=-BLYi>cqaj;;2Cl+iFX0P6+Y!T{f>RHOY++E(nKU*+UDTt+HnY zF(rNqUbj9uP7Q;mV)gd{b(FZOkjS=hN1RhmO9-v;ix|CWl3h|V*eXKIB}1j3LLZ&l z_38gvV(2k5WgAcA9bZ3lPeaqa#`?Q>hsN8d=FJ$rBvyBxBw|*tNPWSY2xXFp zZ5E?B7~%X$f&dH;sQ`*Gik^HpZOX>v;<(|HZZ$O2-)f*XzHYi5TfA%5v4gYow_e)x z_+ZcNJJ%JCIo4ZbCFGkSEr6_okgwX+ZI+G+AWmmdhh{Gg<>eq^4?wJ-=~-z^j-&b6Z-VrFAPfGw)ggp%Qt`; zsTtB^|GGW9j%=QN>~`$Q%cbk4P0mdkWOgJOS!kH(f^!i=u8~6!r2EL}2U135dn#t` z3#XAej6h%9MaW$mdY_65zR!`a^8tiI9R_Sa$iunG+2MCk;rC57ilM z;UUIwrAf*Yb)Db;?fDD2VmVu3=gu7i(66F>>OW9(aVy& zUVE=yv1e^PSjy+inJzZ6?DzQpL-i8-4?K&DCa{&<;f6HIATNU>(~!Xic1-EuPtr!{ z>`jXc@*<@)nu{|$A|wXA9;L`BkU|R9epN6}uPgCXls6t_r%_xWXeR%Hb_u zvtre}#N5)lrm<_!zPPg@VRyk&54o#5i%Et^E%E*5sa^upp1#NnBD*LY=qey(g^-w@ zZh11am!mP!u>}dfQ@3Vh_vgc@x<+KBCa2*Biym;K4FJ92{@^Aj`-TkY>mF_g@uiFm zVit>RW}9t3=-V0U(XDv>q@t2{l_f1J@1EE&^+B>QrLf?8a!FeDKu$LJ$vjpl8xcc(rvUtR~ z7DrSjSFWN9W)1HXGQ@XSTl3yaQ)V66_Sd|HGwzqQ9LY>Bw4)m%MMXGW@Fg(5ta>q~ z69_C88mm#P*{~ueFuhPO$A6}JzbkQJhgspL(7t$74z>r*i+tp&ZCQ!w)D~rBjn1p z#A%#Ls&~-{MMWC`W)*WGeLz!CeKI9nH;$G9P#Iq>u$!Jhd$epDy-d$nDac|mvQAtgg`@W|s-z|z z)XBS!-D-JWG2`Opw{OpsA2?sOsy1@&i%2uV9zn(=Opl__dnHXGyNVTPNXV2JIBFNY zQEbyesa?wVO+w!jsL~l|oneq5L=V@?VYD&mF#0bMOAk#~;6cefjan#qyU;We0~>ee@8~SglYv;dt z>qG+tBIks$$w|i8EDG1fSH~A}CFYfszKk8O=T@B-EjVH__?Q zI153IOV!gkc1f5UhtHC^!c1t?ZSYWZihys46&c4aKYJL+`KwKzI=_9Tec$+{v-9<{ z#_IWtKD9@v^l&Q#M~g;!$%^rsJRSkU8o<>E{Os{TPLYqp-#I9N;VMJwDuB2v#m9IU z4WS-lo=7%Sg{F&CfxkrJEw{Kj`c6uU;zY1`HuP7(yyFO_F{arEEnl_o#NjiQ7oUIq z{*BtX`Ny}f-@ktQ_@v>=+=@@Fp^~W-k{Wk=4F9i-N9drPSX_RrjUjf|divOz?w(Qh z$^Py!psUCYgxHEB%{(RbK(1}Xh@lCRzyU_MM`WLw z0)vOOaNYLO6GzY7eDVFq_s-5Aot>Y*{lM>D+`hc|<>z`IcOXlD&-}k+-^5|-NOFiE z`7tR0QKBHLht(eJUEmd)?jDlr@Ic>Nu_Msw>=B@sNQ^?WgdyL+gez zQne}`W?lhT3oRb5(A8nh*tEOk$mM5WI)D85`RnKRzh1p~kHNpcyLGYh%Euj^Vh4$V zN)9&auZYQWj$&N0h_B{*^~><`3bsP~b(U{jZgzJQj*o1SHP@mZ*ef_16ibViOB3g% zW;&=euRLK`-_qj@XE!BFNSE>lvz1~#B%y)2cTCxTvhnMW&L6)zzrA|(=a28--v0Oj z%d5U{s{CD?C-OMBU~~;m?m4V#1YN+BFc}KA_Y|MdB=_)m$K0U!w5%RV@J0mk=w4HT z`^3cLSVasDAjdXUoF|`21&};wwXgSx(W!n43SEc3v_`R~)hbp?L&ol@{rtJ}!@GYz z{r&zsJ{?o==dT~%zt>cqI8-W=g1JineW&}y7?#;I#RSL0;zEl&r*C*;HQD{{6SVe*FCT>(|fD&aYoT|9t!XSLgRDRb~4JgYrU#tLysmpX5P#Tc>y-$co8~ z*f`G#;bB1megQLs64G!o6@&_6LJt7lkbQkcXVo0sEeiH%P|H%6L7Z|IZPFL%P& zS$SqI*qOd;t&c;70B>BnuJ(23&mWj{%=NeL-@bnN_VdTfpPkFd|dU$0>9mrm@N zXpn(Z1a%8y=ni`E%qbEHm130IQnC_4`sPMLw6srZbV^3QK3S@$+^p!tNKZ?jamg`} ze7ZN+ta5c_Lp_eol6V9Sh?%8e$uwSW=Jo4+R5pfMEB9ELSMm8ft#jAcFQ4(vonOCo ze*gaK`(HmhPai#+DK~@eC&ozvBX?3q^qi9Hj^N;QrguwC2p^HcyudE=vr3})YV5TrUqU8L6wyE0i^D^dc5yfRhM7hssuVKU;mhv4#58}x z2YtKJ3<8?Kx@VRPhc4jfPuF^w(I!S}@(cIW+Dx%w=5V*L zv^O6=f1-X~^yMq{`?k+tK7IW3rSltH%ZFbd%1T!{tU$0+1YH9+b5nd$V?5v!crJl? znaL5+6aAc_LmdI}QL)KM89}zFy!^3+1tAH1u0_I9aD>imt5G5|(PPKMBm$02i}7Q! zm6AZACBqtK)o*@A{j~4Pm(Sl2LO%WT;lt;TpMHG%^5f@UKi(eOu_y?HUAR6B%p^Sw zQ7eXJxVxZOrc3RXofsXSpAi^jQaZx|!~C5gBgW^C9bYhFq>qtp;ETBuxhy@+J7x~w zMHV}8$mEf^B}Xpy_Yg}QF&6I;2y8vyefa0Y#}EH}{O2#~`z`-``t;A|@137Jf4u+N zQnF>dpA2~nURRR&Ye=5+t(m5 z;J}6!m8bvNCW#g>B%%pxreuokb*n?=hR6}#3#RQ&cWkns`0M?<_kX^A`}+0UzcBd6 z4WJmjjlS-C)BU%nrspMz)dS~G&Obc2;mzwe zZ{Pg+_Rn{JfB5Sy{`cwox6jztuaD2l*7I=4C&-g15qvhtcmki0M74k~kz{A5rZ|N{ zw#1a3F+6|Fpn=`uyQK#V$QZG6`XJX>t3v9QAE6J|_VrhK>tlA?@~2H-@b22tRsDJf zhGsA5R@U_9%`4(NU%&bD&$llhKl||ayHA~8zhKl)n>=(fij)HM2{Gt37grW9DX?2N zSDeg!a#CX=?LrT8z@P!yeG}6AOf49e-J?&>exo)VJ(MSrxULuz;_eY@4&9mStJeqi zyYu=D_0N@O(hB=5Et&5ac8~gO-}C2x5Wk+?Z*6_?&-*_=b$veF8+9jSl3^JUwnK@Q(_c4N3I zr&qt72Zu~mhWeRfH$8m*;`+Ywy~h`BDZ2rr>Lc{*c=)iR9oV|&=YPL@|EcrSx6V(0 zUykHGQu@=ia!;+KXnHU$Io*d?M%jlindhGn}9p}#OX?*|r>(}q!U+nqz z{ll4M7uU>i_w>q03(TE1u6I~m$jV`7k)3>ktn9-FP3`S~76VY)+(Pt^zTMFN^8MR4 zpTB+i_Wj-0neKA1aVg0-0ir_ofr@7I>V%BUoV4ujSs968K1oCS#$JIZ?}UT-hGPUG z>htY?{yYk%_O5fa`=$F(*?Zy8F}b+>N<&3X-J*6P~E z$FKf;{TDpN_mflOWI(S_slorNP%h?6_--L7DVd3J@!^j2{KAphyT1PX*7@x_aZ35| z>))Thnvc9d%=%b6B_Yu7)Tw9J?mT<_$FrvoJKEZsKu`jGrtbEwn>Vjty8__s#S3T8 zU%S=vOl0OZVQXXlGz(vHmkhT^?|wJBL;@defsp#)2B}!KYejcw?jx?>63p6#UKFnyZ&DT&Su#bNcj&V@FDlmX@7?Qc26B zKi<6l>%*rfOAC2+1)wG{Mxug$0F?P4u`V*kt~cb5o-jOpL|i*U{m)+*jQFg7fBvBU zy!H!2eg5$F<%^e3K%J|vyLGGn_Kg~>(FIK1+47So%fJsfaia7@)urnCw#P5ty!q$j z$65Yd0n!$rr*@$b4$vKLA=;>Tzu@44Q3VA#0|PD+hl-!SI{*FeKg{2MKY!AGT7UmxUp{~KxV7ajL2atJcJ1ob%T*O;&z(Da`V>B>^hD{gii_87H{XB$`pvr!_vTwf zh~)@QYHD*k=i>0Z#1P0NW zii&e*Pn|h+?AU31$82r`RSj(KYjS{@$WzWc>d&3>%Cjl+G97a0;7yxW926f zmFzD$cCzd^WE?Kl)ZJ@)^t@qNoJ=P+c*unakilIr_F{0R=mwr5DKsm0WcuX1N!T*9 zU$w;A|NM#d>HPcezy5yz?%iuF{tMKC>TlP=#4caFaOTXZqX+gLK3-ma;^digmuu?p zwmxWTJmDjE*Shev9$7N3unWarjI@?cO^eF0*oXESk)Bk8Qxx^r60FDn{G$F?)%oN5 zKmWk8Uc7upeR=8;Fx)q9-@a9Q1N)`2yzKDN)2Gg#K3RV5N=;p3b4Sh0xxPkEJvheJ zaj7ac83RB(oX(3;s*+Q6mLSL2X>&ew85OojC$0rwKmPsKUw^-ahk5$=>9c1K!T!9B zg}8CMuKF@$d9WEPD=VtbU%7F+srmkvsML@IgFT0@c2(xdguh|zbh|^*qqp3`)>;BL zZoU8Z%C?4||NYN@@L^v+fBgHy`!_G1KYKxEfxQUJ<=fU`>JY4~Ws|(j| z)-|==+&yFd$r2FbO$M}Nl;A!^;O2Hx8EkP}U%iYga1YqCbxq0cjmIAR{O@1vy|2^{ zmH+(x_q#XGpZ@Xk#gm7v_ikQCe}XHQs?L<3y#fM8)rBkQ%GliAx@>9If+cRzz4S<& zaM>at;S{7Yz(JY(1Pxs%S1O&WPkj8=`J?HdpFd%ngtPzj>EqwTguj0Iu$P=vn%f@S-`(4+ z&Q4R$n52+$WdiH}L9#PBCcPw(%T;;@7cQ>;3n%Wce}4b*^~;wJ?_WQE^~b|jFoXc^ zue*7(rsmpZXfxE@tVM5w=C+Q9b@_pous~N;d^XEPFOVp@bZPG*^*~S5n|KN_hc7p} zI!7FP`0eY1lbbu9fBf+N)$3O;pAtR2I$G}Byir|EPzG+^s=IRsJemiOE-%iQ9GGDj zrnz&-G;gB`a0>#=PUl*}W30Y9u2Lk>igjK|O&|WL-;$g&d)>A>&oP-#AGWojhZ9V< z;ZA)$+7vW_>-*sGvwJ&xM@2@<4Q2&;R6Bg6U10Wo0(xkyEzDofmjFSl%bY&1;_~Sp zy}D1$_OQ=tLjx>o%LGM~wisOuYiGQ$#MK^nU$h)xYWiD)E zR(Mjp!&NWf@!e-mi|^qxE5g?|y7!Lj4d-qmjz1*0{Wz^WL1Az6)5p(VyncUioR1lL z6&j9Q?8oL1isS&ZlX>A8A<-ckFRjj)+ZGe#j7Qs~^wmS}v^VU3T>s?htJg37c=qhc z)pOM)g%es|Ki|4=T2X>dt;%+)RC=Dc3(S6n#t~jYtVt zvwq#Y3^!YRuvhGmv5P16>XFnZ-J~)byoXQARrStUGuczZ=4Zr==9q{KKMs+{5~02kWfC{sBH&LqSZ3;)yWT-Q7TTBOvXk z=`5-Y)ieM%(UX~_?jr-cn8}uz-P93VcNR{al3@1}^PMXHv^fT&k3LpS@#xYcC%QYb zv@%F~BZsZ!$?hUHJ3T+~;+YQdm{QKv^OADC!VGm$)i9yyh1p!+kWegQ0?rBrC7V;{GC`}VB# nk#P<+iXy(h^~h-?A@E*ei??@tpY$k$L?hR*sDb|vvi<)9(U2b@ literal 0 HcmV?d00001 diff --git a/progs/images/tile.rgb b/progs/images/tile.rgb new file mode 100644 index 0000000000000000000000000000000000000000..5c1c73b06e408a9bdd3e22a3e61118d1b14e044c GIT binary patch literal 206534 zcmeFacbsHtRX=?0Z3Gn+BdCBR1yKY8CJ+e=%kK1ag`4xO+_`(YtLo-lspI6CO+*ny z34%!4zyccyDxe6WpooHq2!a@)`F(458|Jq!?|<)K@27UQKUGt8Z`GaC&vT#WobwIL zCm4q27-ER#=>Gq{IepmJeEddzz5T#TvxooxM&Kv$PkZbS6FvS3L{It^q9?zI=&3T% z)0#xj*e3erA@kG^MCK7&|NUjiR z4I;BgR2vgD&k%K9NwoYXqP6!DZGM<&`!huSuMznVA&MSJl>RJH@hqazNunK{Xn%$1 zbVPLSG||PE5?%L)L^r;N=%pVbdd1%oz3N|yUh@s2KX?Su8*trk!gap|*ZnqJ_d7d8 zw|YdkPl(=of#|MR6W#lEq7U3b^rs&s`taw7{^GxhKK^i`zkV#yr=CIdX?sqAw1JzI=)3tG`S1A8#Z2?|X^9{t2RQewG;azleG0_Y(6xk0j>%ewLU=Jd>Co zzM7aH6N&lpMPeT96Z2CeVxDjvF+cqpVxIC2Vt(!(Vt(N-iTTBUB<5HClbBzBC^66a zablkH6k?wDE5uy&B4Vx(7X(f0~%q7l~Q? zCNZnuP0Yrlh}n87F}-IK<1P>r*u=zJ#AE|v2A7B#{~j^B?E|G_;zCc=ni7u`VnH@@ejn@@*l+9 zj_-T#PZD$2(}=nEw~6^cg_u8W5c6St-(O_JeC#|ipLiKDpL`QBfA?NuKJypEd=}sL z`7aUkMciP%{DZ`N^@+s%$1f4{-&Yayb;RqNEn-=R*zejQ_PcK+_TjH5_6Keu_J`h2 z?2rBpv5)#!Vt?`*#QxMHh<(Bni2dnbB=#xKCHCh^#QuUw>@RK-`ztxIzjlGx-+VQ( zzx8%vpL;j4FZejIFZvv@*L;=Olix*b`BB7jPa;f-G3zZ_x_XE*FBWjH~u)WZ+;4~fBb92zWqhS-YgS)TZh

SILR&l5TSLlk^3QT!O9?CC^<=MjyoM7uSjgHuFj3ZnCv zzn5M`bp2b2Zn~T3WthLO#CQMhSBYLbNA$WMBYGpQ`^~uSKgM;x-5|Pojp(+R=-vB7 zcicd9_v?t>cMH)6-$(Rke@*m}FA{weYusPqzV$axBKq5B68-&EME}SW{ZpIh3og;W z;=2FsMxuZJ1ET-DmFR!|l;|6u!Xo)E#LOKL^ROQv=6fGQ%=cq1{NS^Q`H^{I9;p-a z6YIo0CMM=_`@}pEbN6RnPt4C^?*9A-iFx{86Z1=7Am*80C+0W4kC}6F_@~62#r0qK7h*1dgP0p1PRvVj?|3=x zF|Wiu=XY_=?@fsLgByr>!|RB7(=Eij1^0}%eVmwg{xdPR;+o%$fAbxWC+6;7Cgy!F zB<6z>F@Ls5%tstzJ~}4m)$2jQ*R^Y(>V7ZaKHK7=ZX2}uMzXF4<+W`9!bo< zKZTh8{B>gf=UQUEp%F`%M{^Oe4?Run_q>AG?|U<`k9aq+Kl~wLf9&sx{c+6S$IKD? zxE~|-iBBf>XD|nT_Jzd$Jm$dDo5cQ7pV((&4*mKK#6IhF#6IU%VxRXxVz2rnu~&bA z*lYir*oB7^TX{6G{8NdQo=vQ}K&)XCYi|+T7!cdW{9Sq#v8!((cH=H$w?0N}@AJgE z|3hr}y~HMuAvS+HvBTdcc5;%~J&V{w%)PU??h6ORUdDav27LERaNm0QpAh>y`0iKZ zyI=ctVqgD##Qx!9iT$Ie5&Kqr_dDi^y~QB*U2DX?2Xpt%ePZvywZH!li2akBiT%(A zi2ZZiKmPKw#QxQP5c|o85&L(zcYOxe{#l&=d7S?*DzRT$BK9j?V!wv#|F28L{_pP* zd-P81<32!h5BVg`J?u*~_i*g%e&9!F?uUMw=6>{)_MZiGC>|dgfW8U;iDVXZ`D z{+a0NuM?fXxeJdbsyvN|e-@E+f=I<2G&YFrjHq!y)V_&m33G52^JwFPL|dOE>V1jG z#T*QOkSKW~QI0t{yqai&d&eH;;Gsiwc8BP~^+cC{pXi2Lh+gsmqL+Vy=yyI(^y>d2 z`u*=AdOg1T4{_apgzJ7QuKOKzqFb-?>R$s=gW!ic{9=bZzuYbKO_3kr-}X? z_l}Q!7ttqh&->(4iT)1vj?Y{}^jVeY^Q%Pvf_ul8aPC)d?$_Q#^k45K`rp4GI{JHJ zn6D7?T@NAVyMLINhhr`KfnOx%hn`2wk5-6zRGpZg>=N_XoS4U-Bj!n%yHEZjVxIb5 zVxIP4VxIAL#QgHV5%X&dF~5oPe+%b77jyRo&n4zXWn!+W5i@^^m=g96)e$iQ=9Byy zVzjptW4@1=8txxW%%{$O6SMMN#H`~pPCbd3?ynN#yqFkYB__iCBaMkE&JZ)g_wT%g zn0?$kPGc=ThwH!i6=JSuiMiQ4+}K7@1sJS65X4~Y4z8;SXwKOp9B zZzbmMaliRT{Coci_nR;LFEL-j{pKr=A?9mOBj&%JL(Ko;-+P2P$ebefAqBAy!yNqH z*AV;tZzJ{xF$aI-FNuBRKN0&A|3&O$zlYezKbqJl{XDTxeipG$y_VRgVGVx9GO@oL z68o!%#Qw(1iG4Qi9l!k^VxRvJVqb`R$BVy2?1^s@Tf+KTeH^jEGl-R+PppP}hl%yG z<`Uc7CANe4xBOaS*WO9&Cg$HZ=5HV8dN?=wL1NP<5?efz*wG7!-QkGc$DZZ%HnHb$ z-51XidmZjuH@=D3m*Tr$@#n<8>eIx&=HH0@1BTc){4lX^!ufCcC1T(9JYwHjCHB@j zvA5&=_u~A!uy)^zYyZF>68opP?|t|~#Qp`o|6^Yu_7k{&d(@M~9o#_{vx$19J0@N3iej(?87@A&aM9m`%3n=3zedd~6j)3`qPy(_Q%%IC+& z9iKb>`}8?}2=}}H>-Tef-t_(B^NwHpPLI=Lj*mP3{40-}{r~*W(x-KVJE}I(~k9{PgiSw$t~ne13fF@#Fv7=N*66@o`sv z#_{vx$19J0@N37Pe|*f9kKgIo>1$UWbNv0&$K&H?^Z(mpYgu&++>Ye(lQ7IDUToc;&GVe(k~6e0=Qm@jD$meeKF)j<4s+f5-o4 z^Z)4mr_bJSF~yzu0MDF{Mnl>Uw`THh12IRoIN~$n~h-*~O#Nzjw!0 zKh67j-|cOBUU6d)Zic;hJnDztEcXK6NwZ+x@e^+tbkihGon9LFy^-T=b^G|g*vgB< zaot`Kra|OwIbLte&6B1*7&yHk56%svG>-=9_|SLL zvtgWuLEjJaZaf)woxYckCh5S(fOO~5qimGrxwo5oTfOaQ(C_v9UYP8R(p|Uf<@qR_ z#7XQ2p&xkB^|vWC%@P;Pu%#KMc4}2On}TVy>;`YG>WWsCbzUw@w$yDZhON|%_J+tC z+p=cJQbkbglGbT1R4csQTr?Wui7MWFy zk~^BNi;^PBJfkoP&4Mrs!u=!R=*}c`qH!v&TtZ=8>Nbx*^Ux zoJ85)8MmJgl4v+`2En!)g{gaV>cTCCQdK);Wp%TyDI6zprn$6*A4Ah?RYj51h9HY( zOEL9@s;J9+BYweEnrVqTukpHBYt))GSx^Pru82lsslt~vp>CSI=&vkWOl zd2>-QSGTx|)zH;ei>piXoFW${$DCk1nnht2g>Q|8JF+zN{mgeFCvYp$y3ru; z$5G%UgDgEruy4sy*E!V>hk@(*UAM?$FZKFa6a=F|>?D)I4~rm3A}@#>?0_ag9FO+= zZkQ$8ev}`MhS_*L9E{^+H}|q244v5B?v8?SaI|sxX3J1S!4xWLRj!sqT~xJB(5#DM zOO>j6-7?m7NvxU%U%j@hG(?UU7r2_K@djTp6-jE<)vDg9335%6bd{G>?nK4x$g0*_ z5f&s%KPf8qW~*to+l_il)t4>alw`T0@+TKsQqh)~7c(Ip&7v@i!tq$RyGU>&j~vI} z#ttUVg7GNz!$H5;Nz)(( zcr_V0ZZR5R>LlI9)-c%WrF*-WTzDOh9pahDoLWc?Q0T0&zlXSV^~XOLy~!2)-|~<+L|KRhQghwwaS7l z=z6ot)myEG#2KaEm~Tq+C1Yi|txAHmWXmdVn6{xcINKCCRpJYgW6IMtVitv26do80 zcifp@PE%}avhJz8h!Z!;ydaAPZWKEX^3Dje!cWsYKNw(H*n0&Mi*d4_d(I%*aiU4) z_v2_T`9|Ob{r)fv;?O^Zos;K=e&%*vzvnvPIM1RXc1iAZ12%|8`Q9Ku7kSwbIY<1; zTWsGj1x>aVPS`co;1o*`O{KxBYPHJCHC0q35yRM8uk(hmGFmf~w!Uif)ta(YRTnL> zqN;PoJEW>yt~6v(lf`SxLWSpK!Q>WrvBXv7wq>df=_Jo7EzC5fX|FWwt}2)falXo^ z%pT2RFpI%-9Q@6_`9YqgvFpZ(pQXD=J`TqF!*MTmdqFlG+)*54lN?Jyl6pHY9bq-_ z!^rWm;pruLKkT{P+#e);%%bt6w;ecrY^nNgnDkF|=lVxkl4gY;rLON5yFrr2zVCFC zFp5s40d{Bc4ez!$EYr|9PSr)zSkmpb)LLtFN-9^9Oj%YHMU%`$ThkTY5SEITA@hQ) zR7LLOLRq)Va+xbxVqLFb7IhX&C#7nI9V3;Ye;25$7IN6L6`;Mfst@@Z#u{Z*vI5i-W39GYVbQMvL({9}f=?uyu;_I38r)VB&90qJHj$rwgZ#o5C$;6Mwi9f=wC&iX1Kn==w-EJ_L%A+v0K*WDO0!c$B;DHkd3No zEo-W1nyS)hYKx1a*4D)qkK$`ZK>n=CBF8Pr4a?9q*Fb%W<1EP%%ZttW^PW9#Yew5Z z;Z~AclC-#OD3&3Kx>B*4lE^ES;v|O^B0-617KK?99vBPvoZHR2r?$|h%EQndrTL{x z?%uAC_SgD-p|uZd_U+%{WS6X?d=3RBh;Hl zC^e<=D%J)+jj**s{#E49oYq zl_gO#D_7rFZmJ4~!dFDB5Dqp^je13IDo6?Vc3r8fHu@KJL69m+#n1(DeqI;&T1~|G zSF5IaRoUVNQx$m$Q-(7)8ji>#DQR|iW1Z*9x?YqyMq);EG>gJ43f~$F;}rF!UYZPp zy>57B?2mVSYei)=lFt`czCNEC$f1GAsF+rE^a6Iy|C=1-J?I7$2 zz2GnkqY3&Gy+oQY{-s zLs~s4Z?(ntve@VdoG!H-P3Fy--dI&6Lzn8ABx{0Z@S1@J9=1hj(`|NIf~lAiH-8e9 zRH-a(D6-Pg1ie(28tM|Nua+sGw;>x%j;pUPaVNNHO}AB3K;FG_s;HLHmWweXW>J_$ z;eoMm_joWKyZ*)KV4OIyhasH$+eMa)vtiuz!e~_ZH|&qX-4wf=B8^6gpZZCFSujfX z$1b*7`^cKHy7WmG1-jgmG%kFvzlf}Q zJP1<9O-7Luz2x#>aO9l5)v7P|)JE;O^@b>{YG^wcT3JxrEej0@({A)u7fi)?VTBiE zvsP=$6-}>q#FJ&6SK?)bTc~QfXd@*TtECsqQne%toY~P!Qq8Vuf~;w1$C({NtBZW) zIlQviu1jW>(^_gp&4Z%eU@A*5F%scAZEYDH zyH-Qs6;)M?I+_y=6kY9(*y#u-E0!wMY_lVndL6qd)6muV7m6BJ6+|A8D3g=Lr54X| z&3Kio+WmGNO^TM;@>UvhS(gEMDl7FyvAD&^Ocyg^7KK?99vBOEhWRiHfCi1+5Id$I zj`r~PGzNYT?X+wsKIKL(Zuk!y>BXtlKVnxRU%!wH*{B|)}ooM`LV z5Xp62l56cHwWZi?bG1=7jkR`J-`cR7df6;XrILU$Y)vQ@511`x8?~lc6lPI)U@Y8| z$I&3@d8w0)CTFlJAaO=|9GyizFdm*i%;I8-06eq1KlWTd8Tx41A(e2EVGIUnRClBN zOqPysLOpdj_D6Wxi`_6DByN9v-7rS}5e^4YHjF%XG78hvS(vB2UiVZQ1+KGud3fnv zmZmnuvS3uLR%c5S(63hKl+UT#3MaOj{dG&L$v^;}T3N#_U(lMOENP;N+NsiN)P=Hk zQn9xzqn)9=+H8w084YQTleN0emD^!MTQ zv=BcF!Yl~)kA%CTX(M`&40n@Z7N*I-^Wz}(Cp+n2uovPbOpn0BoWK-`F$?^?H0=3- zANqXx~t?VacdB2_j0YVrR*y*H_VGP*ejrCbcHdDId|WeG*qqxg<)W zB2=n&OA!I^>&VNsx?#4(vSO^FX#otBVTh($ZK#T+@^V`ijT*lo)K+bI*+L7vQa445 zKgkI^W1(e#Gz-Ek2=|YKyW?T8Gs?s9#4jcV`e>62=g?70{4h)scRE2p&`I+GLpt<^ z!0i?JAk6$I$ivOm7;R{D;+!ZCeJmnwKgFc!c?VgHBl}Jtj2$lw2IDE=qMwW%^z9-C zd#2>#p%WFZKRgP~-ljF`i!B?_3!&Dj8;Z8r?`lR<7iC$~v5PWw!;}oG1`N0?OmTZP zyDpo8D%O;1uF@ve^B(}pzp=wpg=QX zh*Tm%Q5KYlBv1EFXFviv>11mo!)(BWK`%R;9HPRM4&rHg&<7R}vt!5cVh1H!q!xaT zEM*L;QH-R0F8>CacEtcSDF5K)+j%$6M*%nvaTfPeK$em)$cMo6 zdA(>a1d_>h!_}=YEYjV*7|8H^=fFjM7Tvc|=7b~gg}QF;`jfq48;uN%@^CQiP5=mX zVKCgw>V%@y%;gnT#Qa%W=QLFyku*dsMJ^Mf->z+ z*Bi?GGE6x^ZkX*4i)1*AvmydCHryE&x#teTASqHGtfFmD9sIZe4lo<< zxPU$lgK-WX>L~B0Bg`{oBA!3VJWxp87!AHD9ONj!@Gj9ZmD&c<-$jW(De7xx8%#OV ztgmaTvDA{9aurlhjuUy=T5HtwW<#}VDi8GQQnPLe)jG24nkj-+bW+CdNV998J+zm& zDfCHd+j`4x+GQlure>neEp*VgUJy794L(jR1c|X3cNT?N6uvzc?m$D?_i}Kk^C{tH zw2x+7JlO@i6CjH;y)*&^A{~Mb5u^pW6F4S6m>@Ig_I3uvBkRIaRmP;D8)bd34 zQVU=<`sfV!gVAmVNFK=1o_i*X!lBdmaYN6N92g8V?gj<8*9BN~r$I3dPmj|axBR_i zifQU~T{j(gPVQs1NOmWvCxKZy_Ty1HLFEe6x;#ES%=*24gyK`29z~aKwbu+#d1O_p znWk9bYrI%*Euo|;l{H@APN6c|tX4$e`%KM7jxES$qbBnlmIC#ZRMnKtwqdJvW7Pnf zgDWp^oKfeimMEw-W4R+?nE%&Ugo87|W-v-t>6j1EK3^?W%U3<8C5qgdx-cEwoLO52bDGoSmMJc3Jj4e&YfUtz zZMoH`@rsRd6esJ-H7|ya2Ko;IdfydU(dH|HC7m#lpJN@76(eZtHKo2KT_d-3ZeG)| zK)5su!7K#WINuY;c?PzqySW4qhUW+Sph*YC5D2Ewxo#h-0}#as;w0Ni;tZX-Bo5H7 zz=8Sc3+N=okw1u%U}tZ;7eZTOtG6|MEp&_V#M^dGZT9>jKuyW%&;hE$@hFP)GSO;xyBdyzj`z4n^2*aW*y-;}GeW>p1eRo}8X zP2>26ER+jNVYq4fFpI)03J;8h58Umgrw;-zahy}J1A(vTas*6kdU4>y7mK~aq?@4e z3^Xf%8QB06V+brpo*l8}Qfoa0ua= zJnje3paD;=a2zNNWDp_<_ebgVxADg2nkZa|*hpRcNcA}<+++o)=8ZDm7W(9w6+ z4PKRXtAT`|p-a$F()G2P)&kQc$#wn>fLuhoN(e~uy@_a*^2i3 zo?n1bH?7`gz`PDpFY|`uB7>Gwj1m)|QrS^>{;mxj1*Qc>gmRJqd{TW?(e0Wb8qkzM zp-D1SRX00rZnbIJriQ;M9H?))+OWYWwJnW1$!Vrg=0%08R5V$rYFc9@Y*pu#Rk1AE zMuo4VdTWVj;~CJnX|(H8EhjX(HCZcE3y404W>J_$;dm^({GM@`qHECKKkR}Y?R5b? z%0ZS+_8pX*LT@fO3Nut$`&kBwzG!eEO&#p7oB?uhKma{x(g3UEqhq}j0G7$+X2qZm<8efkpN=77li;K zg#-80b^^gki0y^ZwgaqE9QcE5+ENCD3EQ9?#irtP=JcWq1Bfn#-L9Kv`+>JJ8t(1x zCfO9Y6hz3N<2>-dec0-TMdocRhdZd`_Mm76q099xEJ9=GvPQWZLAvj#xbAjCP-KuB zw-tAbG5G^=H`U*~mQURdBvYgG~!Tg}zw zWgYcYQ<7A@DywLB*IMd{1-WkWS3h5dhKEqDSz4#DaPWd=olG=cB{ z_E}Dzb&K6Nz5d3VM)71P3Qjp7K>)3RPXrxx8@aQ;8?N>WtTd1yz|ISZrx?BO3>>?O z1G$^%C_aCyCNBV~-85uvVO|xlk+-&`r8+0`Wl2D5x&>)5y{?s1ds|VeKy^>$nL4^` zK<1CLtcBXLWa$IM!bME38q`Rn> z7TwUr_6yTxf*fMBla75r{(|8A&8i_96`2!dqb03NLT$ZUUvE{b6>F6iB~KLG&R(Uyxp$VH#cRyW>;0C!d;6TTGb@!#C(OTE-rQ5HV-C5 z$*h%RPChS5Wh5lXAzDjDTPVw_j4hK(vmnfZaQ{dEW72m4C+a~`40@{(5KSX6NBdDe zbh^+G13t+qh7c1#pABreq`*EZ$e}leygC~@LttWaZwKA$tyL!*4eS0zh0|43VNVFP z8fvXgTWi!>3g2v)Ed#I1VzQrH5cD36 zM>(3#;3%Ls0Rkv^qG&aYz zXnVbIDq);Lo+-RfGa2>}NeB*h6zv`s(1=Cn57K9OzwZoEu<+viD1GTI<|&J>KvAZq z%FT_5(-hE`)0fehlO@xv@v37rJ_$;ag+D zi@K29gTTOO0$exrTOle|><5mAnG%8UmM3Eu(yv~(6YLg6);j=14@dT$WC&Ce6g8ku z1`#ti9S$-4y}==xe9%S4Bpd8Zbq9c50&*Nox;%ueI5KK~7xN@?lVX@8N73b*1!V!F z7^3&BMcY`mbZCGJwKb_KY+8Z>!kewPIeX0(O3#s&YqnKhU$m9Qno+6hO#=)%9;|Dg zht8|nXo3$RG&Tgi3Z?t1X4aSVx{P@>MUL0%rmdU=T*_P(ms=J}x>~JK=sMO2;C=6$ zMPU|&`^Unk@7YZ=@Pcv_Sd(#rY#G|FlgSPk)7_PLk~sZ5OR@_)k?;4MNde`tz5OiQ z8+iR*1QML<^!JA-th$527!3wU+ZVg=nE-df0~Kz(AD!NxD~_T*@KB)MMPWX2JP0@C zA>@#UKtH*cZ(laSfdkPE*wZ$&zx8^p*;!n~O0n<)t)o{fwy9hFMMV_Ll}=4+s;jG( z44OlwtVoSESFNl<#4%hL}5f99&3(EjKH$2>I9F1~!8R1gikbgD64WTVH{ujI~tX=*%kum~9=DkJdF! z`KYR%oFXt<80Q9O8B?J6)H0$XY4t@&VCpM%+u%jb-fn3d5Vow^<$42>_ls7ivnuOi zRjXM|d9`WVn&jx>2>=DL2m#iY&@2eEAlyF^j_!2aaA&lKLK5~cXfaHc1V&&04Gz!2 zjL?OOD{vNJw!0IB*g8SL>@eCw(X}7>ZXYt2m<@v*A{tZufPEMKKwf`<_QjM}3JDIt zLA-pJkMj{Q;ZqN-C>}zkBM(7Cg+)p)JW8*-rOL@mt<{FALr+E(6br&it!7=TZ)}^Y z&Y5*v)X{)mUR2RuMnigKL!C#Nr~;|h3a?95IBi)F(SWu_dzEW70OF|gk|={%sxByS z*b=}DYFkZBwd}gCs9IAMjGAnz6<+3wvJ4~>8gsKK%%X5S7VdDsi9S4sIRKq|aD4W$ zCmNzeG@bx_kwl}(lmIa;wT>MRAlP8ApQDN0?+t_gc7hB8#i)bV+z_MsG)#eBjSBdy zpb(XXK6X)kKsg+z3pn5i;`$Mc>jpWV4*VE;eGZU+NAV5stX7Q9#&)9)P2>8Cp{!w3 z)Rd-R)dm&}wY3NWgbra#1Ihq`RFmqfC_kx{QcJ4L>%jT}0JVNP)>;j@X;dJmUu#sM z>sqs90o$lD76rGX*S9uu00Yz&rh# z%i+!r98`KK+<*rC$V+nQkYOt}T@GMJ3hnRl7-Agg%;g~B0m}jXd`Q6d(w$e_%vUw5 zb84}sR8KB8Efp?WEA8rnrD1;qrLxw#sn#V4zCz0qUs5^^d%3P+f`~P-x=^c`kTVlD zPY3eS65xGhL*=bTMGVT@~=TNc-ycLFuU^~EoHv)_gMp$UbjX{uzM#E7wK_3C4ec0*1yf*^8 zDeHn3eVAnsB!C(8RIbcVvMk@($)UZ0jz)qc9a#xv$pX0V?m-~=@(!909+aByvlj9o zL2$JD##sr`R&?~7Q7DC+l3})ZnC7+`EwzI_f?zEQXf@Q(iv}-l z0Y+IHmc?t94!u_c4Zf*O(9)7ENmjkp(QM48s;I(-uB9xlRBDF51j{-eN=;Zh;PI;! zg3K&4H%-O*W>J_$;eoN>#PJsPHxSf-pcn{1MH1%&--%(J>xN*w_24{;9JvQWbg$US z{iq8@P`{VB&?56jX^?{&0g_xag@Es6yBA(@0jf*G@$LXAH<+RzOq|Zn40jKPgW|$C z>TQL^>C`>&wmhsekQcb&7T~o{AbWa~7b zEzK*nO@m((P6&!#2qK8}XjR`ii^41l4~&I7ycB+jm}>m}8$os~!la2^bhRhIcKF54*;k!`944f`_YN|MhmYW) z<;6jsID;@Qz_d$)o!zMCk9(&A&{W-5cxP`GOtB0{ILPhEx}fQ;I^_FcroI5N0U1J; zpDc0E@!ZYH(@SI;N_LwZ-kdEmc8M-db5V^%CEL zhnAp9whmzqt)^l5krtPglGrYvkkq!tG5l2RdKQFP5bhrd_X4Ze?E|+x!G?b@9-;*Y zBa@=&gDah)T@79|NJ0QycrJEO-UudiX;SQ8ni3%};E`baP%?uyQ{lk^B`FTDD}q+R zFqn+c!Ujza7F@-dWMvx)2ADN|ob|i-j4T@#(RTmdt&8uj8QMYx+oDbdM(gcno40jK zt<}o1+%eFuhMYG@LI7M~olp(Fr6`(q_ZFzRcD2tjYX zDJ`}dWth;ZYNKUu>n}KoTmz&a?4T+O;24=uC{RvTn0dwr`g<0HSrG0U3Gds<92evV z&xzvxV6Y4H9T0v=k~-leia;1WfJ1c-!bIj~dlw-_*$;!Lxas;)F$5{d-GRS*fr=9} zn~)lyS~Vyf`0rxmLn<6KTnL&aSqy3%MEzp8Irbsp3JFgbBN9t-27StjMBL%c2%K3}8$wRl$kV%H@iV zG+VA3oqD~B^#t25$yx+V9E1qn(lkk{8kWYl%<>$+&sFrL6`1qZrIXCnQ~mo{5N1KR ze&3@Dyq=PM)Hu6pn}3`JkB)d42Tf_6CD|A3*K>+zn4h5P41gVZ1+tz4Qpx zq|;FlrT!=z0NjUEd^aCMoDx(xWZWs#H_(&@Q9F;jy%a`Vdj|t}Ze^kC4PuC70yenc zJ$tJRn-jIsH0H`*sahs%8{~GgV<@IjQStvuZKYnfRsqyroBD{V@ZrT$p{+HQ7WhAc zwW&aUKxkWafcwBIUAEhXq}XO%(MM7jZuIX)nMk-A8il z7jO{DhL{e!#o;8)c5*l-re5D42GRat2$?>#7xthYFokJ2*oNi9LsXSOEDaA&W1^rQ z1*kc4k0{(aaxcBJES9fc;2?!joi|L`TwCf!t!BG!bU40ZSvvIWYY=cXEV~Bg=qi$9 zv1TcT)ofa=WqV`Mu$OEs4W>{Pnv%L!Z*YpDDwP%61WQQdsuH@|&2@=~B$K6VZW^%h z1@%;@2oTgSD>EO@@3}lD} z0kX*H?zzJVT{<`qfinmH#f>B9x_5A>6$!wws`{qR8+Nb041Iej+SkAat-M&NiwhDI z>kW>#L`mkL$tp_=3;ZVRTMh5}hHpUg68o}h!Mzw3T4++wqA-iX@mRPc8@t=+O9R`w6ZS^upjhLF}MnmLli*mWugK~Y#XsEoZ ztTxeV7GW&61eP=!5TFW`suoJF>M{=`EF4m7^z5MhZP<`+1$sl5t<|Omi9fA=?Q^dc z>R{kOt4|P{oz+DJFb^E+*rH-;n-J@;48By%Pr)nLJ zC z+S{##1rav83rK~LFIcePUEUO1i%<^Gwdw*W6Ue>SRherj+|+V>N)=lY0GL`=;YwtQrQ(|M{Sq{H%%T8R`78?e zvC5r(nmb{E8d4azlfA@2GI5``q7SB98V*o69qf)l>WQ;~=T2eZ5DM_&iIqb)05l)i zQcu;(`c9TZZpj(`?!n&B1;Z#EAY&N7p%?0}U|>VOCfMo&>Rlia?)BUn9l)(mkcJ(dbBsi zY{Xkr15%7>^sl%3;UI*0R^Q(pr|>};PhF{}rV7oD`D;#^_O%sB zeldqOcta`8S4t-Yiz#73%z`ir!u=!R=*}*tg6s9rCjci1Hj0xm{MJ!n!W}(NcMry+ zA}e5RlEZ8fqD$EQqZ0ump~-1C0l*{i`fhO^qGj-y>-TrBi?*Y%7sSKSVAzEq4PZ`v zEGCnz7;k%kiwEwy1KS92O=Ae61p|mO-LgV4%V ztI;uQ?URBcauRoSwI=aR9_FM~e(IuCyASm|i^3EEKZ^pQaPKZ~7qHO^{JjKbig`TA z!akthSuvRQtJD31JWNq;1Q?%5M zsZ=Bsg=%#)nQdcj-IhU^t{J+yW+Q_Df2eKE33snGDvNczukmF;tO6Gf>qWS!G)rZn z+-^5Fp+zPuW}T~n5mz&WaDBdN8W!f7q=QPqm#!*RAZr7pYd#CYEC>&bgxB5+_K$;F zD28?5jy$xTktzeA3Y5ht-@ggI4l$_IgTY*KaRM!xIQNkPbVCS@opStfH0OO5LVaDB zsEnd6wn$h*+%-Rmb^v&SSPf)3Vob8FFzEsI*Z1At5L>G4$Q$a>EO!Nhl7Hp;-lmPNkQXhRuL5t<8S4Vr(TQu{QE!7K*T zad31O>~S{hNBo>KuJCrWkm*?>8L;LqZK1>nE74b0|Cen0m+!Q z*g%3q>l$)1+1cG_KZWi+)HUF5w4$cw@&dLhiPhPmHI9smi;q6qgu zgHF-FhLZPGG+?rK*y~TiaClIlQ!#`9egX3bKs=%mx_&N{1U$er0E7+lV(dg-4_m1f zleU~XhtQb-NoT;iBibM+BgA}0(PQyC54z{k>_*z-%*iyq5E64+2$BUm8oCBkv zsggJBQ{>LdMycF^Fzi|l;!aJpCF-@QniDiU_)4kTgvu*?+to!wvTNy; z2oUT8zH=6ZSri@^3opHU1R{{ri(!=LX6Him%+O{A%`<=yaWEIY3dYjV)5wZEIWyXU zT0ok5X%}3fUOMo{=XcJBr}}fjH{$HH+e4FLFdU3rc$Narn&+TWCqqmtfN0ZU4pQnM zcDJT{RFF`|d!XNSgY?Y1TC!fPmNa;?^VYU3TN=8|V6#E~-Uir01{<2MmMtiOpK2}D z8%^Eh%>_7Om5jR3?k)DD6O}pX9h$kxmC>WX#;VQn`c$~dwna_Un`@?0M&r6+D*$z< z+&oqzg@fDT3g~wW5@VvWGK;}12GenHbWbtdhhyl)VGruYZm$mk8f^X1M+P?(s$;_m z^0K5V7>*8{&cE^ev!802{{bIGR9BIYI5IfaU1zc4G~9c(++P37>{C`f9SMV>2}MLn-q{V-W<< zmVr`}f+1}}NF!0}Q>%3jjOnHUqv?ft;A1&nF=PphI$@P7O>ODWn-)|sDU>#}!vP@U5{hPI^;nw4Xt>6?rwD zB6+~b?FK!(G8pck-8q+Lqx-;kkfn@4r-u11^p!kV#+}Q3h-c(Uf4Q9vdJrT-a)72= z(BFZOWwGb?2RjbbXP~+PSJUoh4+Ynq!FUpYLV;JK_$WB@p0-|AL5&t+1~JX6YZ}aQ z4PHjks03x1dUFi`5W{L|XrjrGrGzq{1-w&d4T5G3xoZn`Te7su^MA{%mqbob_;Oj2 zrOKjgS+y0h+*smjO`9))h9@svQ%2IU*ywa5BpwZ$FO;bXFEWVt&7v@i!UJRBj(*q= zaXU{6&^WUo86<@a^?{V#L0_-ubpdRR(YM2z;cwy-k`YKl?g9L&2V33A(df+06}cj- zElsb3#)KoK^XV0rOV#jcCz)b$qR%_OnPiK~jlm+hKro?PG?{-hy+hzd%Q zDinGX634Kmo<(66h2ydCeh3*SgB<&v)CJli!Tla0eh?Bvb1nesc?j@^J2=cw6?^#G zI87jS30V#pZb5P;M$aMZ_J;|24R9dEwrd!`!FuXFHx5Cq?)!1DYEbmH7RpVC4B&VW<)*9%-Byrqbd;K|SD-5}FD!0aqGmwYMlkv2 z_MjuTwrizISvLxO0era$9nGRJi^2nA;p{!h4szb9y*g~>yumIIeDFJgcI6J})BtpV z{^KQs>jrD5FQ7D=KjQx_p0 z=DR+8xA0-8T@}#%0}3RB@9$u=)$Lup-B`qe0559EgoI^dS^1)@l)0)|uPrV@lSu=4 z6bko^u>PXWK8&!8l43Q*=TsHbT+%9>t<-oEGT_yEZHi2)Vp6q@x(e$R7^;|1s)TeC z)(mW`s_@`a%h0bBc&LDj@Mx^mTk{J{84b!=5N1KRe24hK;LNO5vH(Qr2yWKeJQj?p|$+%U)YjD>XrC)ZSp%ZETpd z>In`iXCPZ!@Of{Ru{Hqv2g}haAblMLH7BXQZcg3W`!ox}EC~0Hgrhrg&kurL4xz~u z=5kOiMzILo&IxRS(5K#Vz?eP+_j$J%?@n83hZn*y&!S>DJ_I8u=z}sh83oB?SYYhq z%zO+*jwtP|z?=~+iM?oYn1CUXjBrz!&vfE3L9FsO21x8xnNVhla7RpJIpmbWI-f5tJt>V^i zw|S%=X6gAbXM_#)irU%G!KcuhHZt<+B9N{PFeFfYH6^W3c;J|(0MA(zW>I)xEZhxL zw-B>vKPWSaadeB1AzuKpOYPw zjnKJ{6PPGE(bQRV9Jqm#4}wuQIk(e~N0@AoH%3?5%b^aQ?}HNrHY)5V+@s>cZ8eyv zOC<%QPf@nv8m-EzA;BsI0^oIUs(F|_Kv)bQ45hKSWJz@>+PBnlv*vBdN>yF0=}XX> zDM_lP8y!%LL>p?z8244HE;UPfcd4wk0F+fZc>$;?TTnST_?F7xUdvXYa{zv$6ETaz zEDGNm3vp0@=$WJcjQxHA2-5y=knKafJB!CIV6So5??a6h=Dd&y@EyRFA`JHQ|FHL7 zJ(i_edR_)%L;?IE`T@F-L=Z!2*v;yyj5ua{Z;lUdj@id-zmE-@kr`>qbocZOK?)i` zqTB^p)zwW*byW|C(v2txlB!35peqUjNSO;szy$Q{s;r@YgK$tLU1TP(@a?m|wbuJS z@8UL@K&iP4M_A@Eazw-M>be-`i*Zg=R(`#thk#(YcwhywrpX?lmRf|X$so>du9@Se z3)oMSr{dL@Q1)buZ=OzUsP6l&c+zY*C#DZArXwP>FtvK!o*tt4a~+Hiq-`05#W~Fr zOG3eYs@I{(xOLUgwZkJU5>3%lEzdh@sS=VXuho}ry-N#TK`qtNI&#HuPmXYsf~?UB zMJAsb-{d#jDr~Fp{w#bwV=($q3cx3$Vn)<%uv&2IN1qq-Ft9mbLC1)7PP|q=;ep_1 z%PDJ-uCvpan9@-nDff6dD{d1qs>j7m*dLYoav)yAWQzBJq(x*=%&yK3PYIG3FYaD{ zGGAYgNV6V~pMv{ef=D{*mkMyX?yENIg-*-1Td*ok9tLJc61}j}ZU9$;cwYzLXX<8G z_2|VvFs!;!-`wm#aqIeZ!Rv#FY91s+v*%M{;F-gcF2p{Z zWp*#RO5=3|3_n|s1F%n{;pF9)wr4q})iWfqdSrrz(P^@E_mcUk<{1)OiWaO_O)^^z zD6S54`+Y*!?T$6HwdVBD6fD1jj!CgJy*u`y{1H*DEBLLo50#d!^QKT$ftJE;RR5N7 zXj@%Fy@BJ=73+c|)N9zOgJ;_!Y>V*yNg#D|#jq$}-xPWNDjr7hH4zX|akBu0&nPyT zqweEHL10P@x z6W|0_pQ`eNb?+P`;(W*`x8?~(cSZa_WrvbEaWK*?V zo&0Jz`H25o76xoG91HT=_43NJt-`hnKb(c%7RAMsU|rnOxD>`vm{#ak*;-Fuf$K(~ zHv>Ym=6|yQU~P5}*i z2+sz;99J+>9qBKoYqA?>ak;AYz2^vARnxa|DTunPb`C>1tksC5^rnWDR90%= zUBNs>(&R3}@DgK+2*n4&q|YeqtVHFVQ|hCrGklIJzy_8Zk82bU0>IHJS|Q%kfV~n=+Mm zHSLo;m%NHcvv=uqwj7P4r|``e6}9=1>RiwR?^ij(_!!D46I~z>%W2VT3lesR23H@A zN5I7I(`8X-h(@Eqf}&}<1GG<~-M}SRt)E)3HE6I^n@7ViYElJ1Dl#V>v4+a4W1r+X zYiQQhnJufWS|RE{nGkPmtFW!Y`?D~IaJ!q|MERO68akt5z8n7~kHKt{PHr%W7D$!& z)Q8Q=g$eY)Y>I~IXV{8R?~y8m68vNGNSU~fb4cH5dJ_l3 zm=xh+Ltlc6`UQ@O1h{1oa4Y-dm%0IaM)!IwpV8d;&0X_<;VDpiwtU>iLG9_>id0$E zTivFH*$4dbVbRjK{SY3(eaVf8BV{u!x(B%JtP@LM+&XG&T&-#XK=5u$`-pdgS;{$xDMlFee24%1*Z2-5qf@b#CCn#KwkGZabgU;@@tb;>| zMnLO%j`Cb}6~S+xwH&~$O;DEt-XJte8fY5eG-$h_l~qlB5eoa_`?tfk3gz2jTZQl5kznr^dG_jM!pP@<_aSa zdk9?8!w67*NjM%(@}wxH+5Bo0&99TesKom%Q2>@vLMTAy2?@P9+9fjO!WgK{7)Hk^ zOxNgV*ZHhJjaYRg(QuXm-jBxdyQl2aFPc54O-WsQto!*!~SgG2O2qN24= z{i@!!>xQnYRYFvJUvZj;HNA0URq7?)ucZPK@XZdu%7#@(*@xPj*{x;*g%yEx)O4rU zQk|ZsR+!(?VHj2HclDYf6=sNqw2YA2R$*I(@6W=&{L^7U8t6E>os`VhV!&u=7=t06 z-d(eKMz+mdDI5*44P}FH5^#lz=6vFh3-GP^cr-W)$ViE1;Ub?$L_o{}7S&;#@$DuC zP&Nts2s-BFbCQk*>xA3b)nq_$5LhO1xW@1Pan(0^mZYCZ6^QnYibF)4;k%A}dfbD= zTK76lQ^)mV*=|LXgbsev2I^R`acGg(F6{q7-I5h>;7zY#n3bw3I9-+7lv1}3Ocz*_ zwlAt)L$py$)hj(~*StNH_Q?&B1>j5ygXj3!wg%f8l;_~-H`sRO41b`Bq3|1y-eiQy zv7qj+mU)DfX`UxByXom{os7suoQ+sWpt+djcO|uH7M@P2Bn3PY#cyasU7B*86 z6`NbI1v8)pgY+sGB?bJA3udR(jZyp@lF*gCy9)ljqQe(%H< zP`H{>#XbNU>jMUV&XP}QdNm0bo>jH{qNgJ4L$mB$lSA6kNJ$}A|XclY8h_`7UBj}hAz@cgC>Y?ZXVf55TeCqt{4vifWP|1 zFY*9S5x(pBMabgqaxh(__q)j-6&nVyv*{8RcproTChKT2ef&~xH=Onn%myp|}PAURP8;+ZFTpWMs&^Iixz*D6y(Z-f+F* zrQ*+;lE%NHzy1Un{q?s<98jpsAyqWg|C!wynXo2IV<;`X=2hrp0PC z!tXG{^iu%KNY})guy%`%XPbg(QSwH|Iiu17IvMk#@hDwR(sxVXlyQ#bp-+P`9HpzP z>?TjLho5tW3WsdF36~(#n&_ZKa*cN5x*+d8O>dKAaU7DGLXg&secZ3?UQ6-2?V9Pk zDyAPFrk>L^TTMyb*MFoQ_$t%@;&eT`BR5JqSxpdYPD{3DZC28T>zi^#)?3xO-8pnm zT+8h*Y|GcGl2{>Jf=p|ogId-R+qWa%Y-o;iYT2zH>)gMPFiGn70Q_wg%6;6n3RK~r z{buPIwzB~$V)M7nqI;Ok5fjmx zz`jQsA{tfJZ?fXHeY@3D8rE}-DU;!!DoWE-n!aa1QnH;r!C-xT+_JGdU?QqJp4jG9 zVgF~2jTf6B2`H{C?g%n1eRrl>4smT!M*iVjsA$>kiB%boku27s3yii!*cRdaNqG8t zK^uTsCrxhnIRB1C2{r)2{nhI^N^b^CtQAmg&ys8i>2*cAG$HMa1eEJy8H|W-4<-dj zCh*3W1K2YuFq-Kd5d9bp|)}95*zWF(As2GC7Q3om!O$MoVZmj5?bGxzlP3b)wq^*_TB@kmbFK z@LY9((I{sp)~ShIg615Xsdb|Hc;gh}vvi?;XiFj*S(A+S0s)isouY4Bg;LkJtwLFa z&GniP-5`0piN|>4kldl)xXx$e7i^TY1nnT^ajq6r%D&DVZkScc>j}%197ZX@AZ^^8L(^WGL$l0(k5|=$TOfC z3)V3&fW3XB;Rrf<*CSQXj(xw^?V05(!C;}+xB&fx%R+>aulm;Ea#pwsf(Q$v1WqEBVQm4XL&u(LME~gIUBix__*uE?)29a-as$oU~#p~f&~|)lJB&+zK6IU z|MUwDN^8ezIK6YP0fUm5EPdZT(|B(fo>hLb3%m9gEFxN`-tjqXvQ|T^v2AWx^a;At z?OF|V;il%dhzL@Zdea3?X7oK4at+esj#|6&r;=n_eN$*1w%vN0ds2yaIygE%vP>Aq z^Jm){Y->=S1KyDYG$gb8o0Pl$v>3ozT260nOT*4IV2OOq^#?E|48IjT`!T2h{BzSW zc@U_hLxAv>kb}!& zgAr_*2q8l*QxBUk^P$i98X-cGW@?A7jMl?sk7u3(=;$7F9sV#w#*VGKeyfnRosV{! z+bV3U@UPFpKYI*sH&6l+Za*CUS#q<<$2sn{41HdD{i>97m+ixh%`?uq2mv@7i?k?8 zx5TiINF#~X#4`d4psyYd#-*`{Gf%k0BFvY?96orSuh!Y72xfTEqEYcs(l*3N;NCGKFPjz+`Dc?jj>3rle5EUavv2 zW*4;5i2MhuxC%KIaWHBiJ`dukH)>6Q#Er*Xa%94jzTHNWd6m zgz&!or2#U=Cr+_L1Un~LL{D*K%65KuY_v}r^b@=fpxFz+V#qqtL`g8mJz_@PkEA-` zD2AhdsAh#KC|(CK?7rD;*)3=@4Nc~~;vZPf;ThID%juG7ZQIA5peZ%o_AN(H3a1R= zEh8beRoGVH{aN@byq_%}ZrBfuka&+zdqKAR6#3~Y#v9E#BA>0YQHX*sP79a;rMcm1 z!`Ns&IVXB?hLs^XJ}cI^h{A#=Vm99-_tUWde)DB;sYXMj?~g6sFkR{4;{S?yRX%-$dnu3Uusg-Ik2lP6J7B` zw|OM(%1cMk4%HodX9K-*TZC;9%9C*arvum;i^mrai})g(?M|Pv65mR61KWscwvJKc z<)ir(Qt)tjO<2S#3syJam#*X493Lt9)5)Bj9H04E;PM$y0^#iiWHS=A9`);x7#vR+2hKm11(IK<81;<9Bv*Hq_Yq4@L_yb#=;sRHe* zH4Y7A+O0#43&3)Wk{CQ*jKc=PRcYfD$W5EKhqZkS8>{-Lr0R0{zZe$ zh3fmYdP_&!suJ4%cmEc0ziz8U+OD@n*cRdaN%;F;#mU1}c740KPR~Ho$2TZ7Mrc=8 zOn!=2Z|R?B<9IiD3ggur(*0}=ZJ;EB-`!^Oj4d5gR~BtSoS?;sMpyGRTCd}Ll+&Ll zGX#9uE6|rKrb?4M3-AfCtDc3clU7vjw&U5u=cd&^bdOGZ$My$%FpN){wpXtkjSfCh ze>iht+DoSW-yu9QJEcWV?LixWTB)C%x=mMU5~4-;LtQY<13K;cLBrO2UDK<1PK!1j z!K*WDVH;|@#7H;-bJio1l)282{{~nOQ!!ak51(y|ur0#(C*kRv_3UA>D!Ic6xmnYg z47hYQCzl!;G4UuM$ie^^IEOyVR^w#x^5$b?sU`XwjcbXQnT-P$(u?%2Nc&^>8w-d{ z`lB`=Vi)OK0F21rBxc=qbo9d^ZS_ta->v#I_3M3u0S^(X*fa zHhG9=vpnDml!dVL_z=HJ$5?rQ3eY%YBh;>894%(6m^}ML#(KTHS!0lkbKF76s<^sFCUQ4%5e9TYbnf zo=}RGG*EhVRX?yLtUM6;tp5oQP`y;UntD^|n3cM2whsZ90m~3sL+f7K>e+4whPR{| zE?7V4dl(|1E**3<$(Gy>7=okraS!9E=^dDk)$tFHFbUO8n|4d^s#R`GlWh^UMRk8TTl;{(%_j73BWbOjzgR8&1-E0^>aizjaT0A`D1F{wqVoI~ex4#Ak zW9X);4&i*mwQn~Sb_%LzVe|BC**gy!8f%8OW7NcYUC~U{zc`dEvVYu0qwRqIwt+Xv zw$yaxLsZ`i$tN||ZVr%24OoY6_1yO9LC@{F1pLxN`~6G5Le!$QtLE;`i1ov^2HP5x z=KywT%Jc}}WR8aQeu2g)g7iI0uCHdJaDA8aZ9I4pWdX@S$!0Rn2|Jk%=%$OCyNm!7 z65+634*#K+?F9)0sSW2%+92l)N>i`WOVJC7`cWnRU%mF^*@j7UE zRf*JI(0-S5!}3AfSLhrFL9wisDf+DNNZ@MweqH20*aNOy-y0s*m7>|)>6XpIwhG%S z{BRb&O0v_zlDI3Rd$W5M)limVrlmlR!7b4eOvAU~bp%cW*yNG`p_@%Xwl34uGIaea z8Zs>+F9KHs-}Grt>+iIlDT36GN)=K``jg`oriydY8?zhkw5L z_;btopwgBE)zv-q0xOS9vS{74J+$7MOI~FwsNe90(9P>G^mX?6%YLbm>s9 zmEa6rXID|f>CkJ}c7;DNeM<%81o{}gY@=aWD#Sn8B#+nluu`w=tNT^s-ON$l{?5Tp z!X9c{gl!SNI|+Xp#U~@)5xDFg$)dyc8b1Rbe(qBZFvR? zR|PWuiSUu3p!PQ4Fx3cNJTRWqTbI9CZJo5scofxh1=6>UI)aAo$^2-4Pf{yYL5ojJ zv+#yHhdcSRr)?FsRd|0Ee(}}pGGMY4j3WTuvk1Ksxr!^61otGqb{#@M?Ow|xXqkF)X4Y?9g>mA!P-LBJ}c(V2vEFZ`Ps*&0*)(!1| zW?8UZ&oQc|>h-MseTgj_P)d3Q5>Yhm$JL6c)(`V;m zcfjAMDCbsJXybmEKHC;yTZHdV!hik^c28IV6F%0Vj-}D!<_@q1DJED#^E;B|V9yMu z1m;f8&l)EIu$f|ax_MFRn7x(+ogWFZ(Drxb&1Iq~09*B4;R{9NX4N##JEn->&#cu+hNu&-=r-&F**b=F);J8D zlPaj>mMqmi@|$AEw}-OcZ10LYm(R8p*jC`>H+*VCg~_t~W;w<8kdywlfCmsHXitHz zvUR}zkeB}G;JhD@uuk?m0FBWYw`h`sl*|Lm!5(^mv{>eo~p z*t(B5f~KKqRrH41JOWNYTAfDMh3OWR)rQ;z?m;|xv zXncM#&W9XpVn%PT?pHTApzBfR5hOk6L#q#O@&&ki`iykGMDUa?+0`+KV!%2b4N|n> z0f~##WXgUzTwZ}l?n9{LaT`t`cuX$oCtiN8v|8js+t~Vj{eL4SPSN1#c}EcH;Z1({ zTy(37f$7sbIlAbc9BYud9SiARWnWS}?bvJSU8H)W zjot$4OwI}!Q~(Mj7{^n9d+ZHnpj(4^Oe28?DJ+s@%)Mtl4U6LD4ZK%yeS=B`o$lc7%_nH)%-FXvRCFz%ns8yBLL2x(eb*7tvGn@C5N?LKR%MY@E2qwq9W)ZCXM9Kt|&&YybA&wY*+S z#BXZpbwNAV>duKnQ=z-OLwqa~(g)9LnhYfw@^R79c_NUoZL6@Y!uzxE7hk6tP_TT? z<~g0Ovc)>Yz%V7HA(}%}TIOZKD9-|6q9rsSUWXf&6A=3P!Qyfvi2L!1O@1Bxp#>_op0;&^kF0i|K{2TQ;B>5KgJFKyR`{L+9VU^hB$ ztE-E=3#>g!C+JOWA;Boq5CO{2LemNN^aGX?5c>9o)^mUx+=;;R0U9{#D3_8+@q{YaNvB_G_|H_u8|6TWJ3Uz9D|WBjDah`fVm+Y)R`5Ip;*-=NWk zOF0-J%uY^@(I=HR{c&0>H&M38mQeP%F-5&)IVmd?uw@58TLv!y`luD4Xx z{_)>A;Xu<3h_uB$!)-e4lCozs6qlq>y>7L&7EU**j@Q|2Y6LuJavRCFB)3QUe}RmT zscpk-f+JB>C)G0Em@6c+2p`E7xK={A}S5hC$O1cbuPgK>JDg)n4F)59XTT=PiX zl@YoGV-nEHb+5q3j`)0f%9t&Xd_24pyuAbtLf9?AX#g_ME zPnM;zq=zQQmS9k*6ezZFKU zrrxD(zNCrJ)d~YB7H^W*KBuoH(^|J(ARDY9OjD_9N~5J|exbTdmgu0iRoGVHhqLhY zVpS||Bd$2(XbR~fB}_D&&6m@dWOXh*?9Qor*THmHkQ2nht{5+8=)W;fBLgYsMLHUdCu>}$^A~jHPwC??L1#2i zbW!JDnJc|b%!8&j+KQ>SE!AyV41rAVNYa`eTT{G-FS@;sFG^+uLHKjc=@GLlIUZ>z zuGwkBFt#PQG?G&FO`v^>>r3qt$fS}gXCeLYY+{1sF0s~)%SO@Ye&-Q|UAwJ9$*$d2 zfw?lxOlI6@NYVq%LJEW<%E%9jqQPZ4r%Q)K17cu~2rVB?&o9%&H6Osv=Qlx z%>w&FvOurbCv=xDi5FA;hiGp$ywSBs)DPk=MAUTRrZahNB@ zw%u|CVZVlFLKSG!`Jap(u4-zMp&Ir5n#mZ;u#Wn5rzwegttDBu=p0@adUdCX+WYA@ z+bV3U@ct}(#aO66L#p(Pcfe-Ig(m2vSZ}h$%{`lk5&3`-AXBxwc@#fX_P3Z|3t-_?k_up+d3{^DTcCXAcaT47=s@jFi+Covvk(A>dHygAl%1`zkg;*@!Gm4J5RpZaxS8bW7-L_Fw|K|7E zK-(&m2}#>3d{>2l0n)6bBJpw?%>*4FAg7Fh?Px&qZjgn+*(5605Q}t> zJSA^F7fijbN?en4lz4SM`7K<|s-Slox@5G`rxGsO@=48Yba6u0^=3!*Ov`1H&FWef zs`eod0AwVF-L14(kk#<_=OdhcLOscoh{1v!=_R@x#FN1#fm=*& zSJ80#lz#lV<~2%eJzSVJpZExk48pByvfD+oWOd4TMb|v-sXQ`W088ZQP6S;-%nf6S zK*gHbF`x&Kw@!SVV#;Rg$Pgvn>R3(J8_sMIEjcDqUxySfn!HKaaATo%nA~>sq9*S+ z<=k;wg>4mnI168A^Hr1wqcm9ErYn>hyeXntZ${*30pB|>V}r=hg)T6^3rJjyk|hL= zGWyx$uFHoTlYvzuXj)FZbP%lhSRm**Bk(1veU!irudfWsYv|J2sGiM)YeSW;#`ip z+Z6mRnTeo_%Uy(Nn>EQs-%;wETHUs1p$E}L#Z~K?@u9fiWanL};IV5On2jzDq{5cD zHDyd$wpG|x;rp|2^-a8lA_*sEck(pggP-J|@fbDuYQ{P`xmqP*927S>I;Ua{+j5w$ z$&;Q=%7mblw+QctJc?c{`sV>bya4Z6P?NelnqF<#N>8(!6&Vp_4CyI5i7^`5^Vu8J zQfWfsd&p$#^_NBmw;PUW`Tvx~iY!S!x>pf3cn6)gWF2;}J_wBy&u?}7u3A@WPS=t> zMQXrSB2QAQ)09n zi@OweGls9zXWJrdi}3wPC~;i(S6RGfn#4yuuYjCXAXdx-Xr*a9m?u}wtGXY;F7o`lg77{DC$1@gOmk;b>z z9C8Lr>&2WK(DI5@_9!T~5wkH-bMraL?K~jY(;!QLkVWe${Cte03sx6lyjUS0pAM(} z>1>iO=l2;GsGyY4ZYCtN7vX=q`NKawR8D#a9si`EG!DC-tr_i>(P*H)aL9yf+2-jH z>4@OIyRD{eshvZSsA@syZl#JM20DJ5B^&J{S#Yd|DjQwJH-69g2Q5XeYi6s{v}_<9 zdx|Q-CAe?}g}m#gW*chJeWgV0>t)@F>Y&A2b^W9Px6Ipmm5h zIq8xvsz`RbL8C3={ZWZ$*F@bCYj&pxd~9GD#};r`-GBZ!_Do4brqSt|ic~S14q^{+ z|GZpHR|#3MD<4Q|T|88LSD+y&E*syEn6^~_wy`}6C3ofNH=9>E67T7FJ>SfVNAyNf z3Ri;#bGj*FGEg2KZpc);+8}gg#yTXAI-|u#*_tml6Nvb9;e6SYs8LcM0z^;5K%7kg zA7d6;TW-8pQq zfODK4x>dW`zdX?u<*0|!l^JV|je~<72t=jZI*@$aM4cvIrtE2M)f9yq@#~866Y_Ss zPT3ugwH)AA%RW&_lYsv%S)@TQ!`iJZ1jdPl=$%^^cDkZTCZHD#x_6F=M5U|WOo9Q@CJ{`#k{U%hcds5EK7D+6{Opt0FJ8WV@o@L>_~|GA@bT5_Pk;W&!|TU~H?Lnj zynOxU)5n*OZyp{W-oCy2MO!N4E&1;{_9~zGhU=K zp3A}LVhG6TGthzgDjfpvfE)!j3T+hDrQrnV-$gpSDBoMzkOlkY@N9HF?uP`#kJ4cX zczn2f{&6t87!x(o9}O=1m;G$WJ8C!$&W1aeJMXqN*w)~?bCCbV?(cTL-Tdx%-~R5~ zZ-4i@fAiY~-~D#?cYp2M^>;t=Nhr@Wa z9EAfgB3vw4Z=S+pn=EF7G>Ow-h`?pI41&wSh<}Sq!UF;b4F!RH(d3dh^CeUt9`jLf zGdnx$2eV5+qL=6KI9rS+QGio7NdcRbFK$%!PyNR~zkm4T)0dy}v2^?R`m_J|vp2VI zAKv}^XMBu(@+qHCFF*O@&CRRV?;d~p=EcYF-hJ}&;o~=t4?lnP@}7^m7cW1%`}DJq zU%qW|;t+`M@8=KkI5hr8Q%kDvbZ<>T9zFJ6B7 z@h9)zz53+c$B%D{pTFL@-}w(%Yj3Ntt-|}W@TKmXu2ONrHZi8=#W4;J*|FPRQ*w_j z?r&V{w3_OvgO+Z4dc*FVF%{@z)PtGHM!rhkZ$+px^y=A7wD6nEj_PQ zj7Gg$RjRsm(6$f7s^s}?t!tuaQ4z98|6EVLj*2*&4zhPko^XPPFs!v!`tlwng~_X7HJoT?0I#?ZXVR7nkhF* zQR4LIuw?oxZUYmOp`G`1=lBv3Nz*dgZLy*5AwqG)r{|O3Bw-M(hS5zqz#EToqhwbP zDGA_&as((aAxMX$fP?(ujtLrZ{>jlXa!cM>u;ozp7Yp(}qDhfMvYu~7n1UzsEE`YX zTwiCvAWEbukkRmN9c9-qN)ijJre!dn^$|lC>3HX2=keLowhG%S{BRaNci9Qbj$Ahc zO{gNOGR*F*)lihSfup10+NYMP2oBKYk7|f)MM`u#;wPxM#0n9<1i#Sm+`cqSt_9UlicWw8;!S2e;7rt^s@l5Q2z!aYQ z?V7ByacK!+qup+*qFw#>_FC#*)jm4xAa!>SJPielL!5R~^vK3DR7nw^YLjo6e6vA< z8r^3T8fUZB5>V)TRBRCB6Uc!)a~eIoWgXOKCWzD~yFy{c)SJ-bu$Z!ZoggY0Ulz+z zISWsg!MIp1d32IN^Kvn}9H!S-JX|HyJw(Hk;djc8Sit}*3R=g7o}ljIXKM4P=`HW5=?x6oX)4IIu78ui zWqE{rU~rL_%Cjgd7pC(u^X~w+7w}z@4M?!Lo%2?>{sn!-3M%O&m`9r+T4%7bqTS>l zp|~847U<2w=>-=j0Hy#|1~`Dni2w5pVs#%)8~3kyw9K#P`AZN(3tEnyc;}CvZELWt zL3s|I{)uO4i=UUgp;>Y^yu*}T_2s?=-s63a|jo-N9vcc2hek1DasHqrRVR%^2L zKN{Je<+m8IVn8SfC{UQvtJ&&iv0^XE+O#~~B>SOJ=2eiSlg-bTybY#hbT}8DVUmwX zD;N;vk&JkZR_kGZ2ETNSGCxd47lYl=AF@Wx08tb9L8{FxLEknF2FQ7sa?iM(@i2U{ zEyA`4e{~XA3N}4W_lWB1xPa1{2O6p?4WFKT=F}D9iB6lQ?Q^w}RlVWk>}&bDgp9pj zt14m}BAd4FcRF6Tb#__;%ssri27U3EKx7)^4a5{&D%0uYE+w-Ewt;WsSyW0*vu;9gXrycwYn~-Z#8uAju^}o~<)t4Wj zUf&m=jN~_DA`|5la_Yw~ugL?yzeh;VKj{p5VhB1VzbcKugn7)D$$CAFR>^e9wI}6H z1SN%}gYjTShIo>^E;%a%*r3N5trx{%=aP&Mq{(FqvYgG<4{4OMLIGEu@k8A3MSuK$ z(6+4tGuQ1|D97)=8XkI;kM_WSc$y}*ZFf2qj}FKvs(4?vqWW>sjFF{L;Ncy-#m9}O-F&xeo@g`e?tDXj9Fz<`;cz(MXUj#vc zgFc;{4=2~OeYWm8sN*HQM-p?9#nR%Fd+`AU4; z)(#!fs3FH~Ti`k^61OpcA9q>JiN}5!N+H$+wJx+sjyFU_C!(IO8K{T2#rcPXjFY{J zv!^n>k_=bv9@AahCx=S?sW$s&HD9g9)7R1MD#5G85e8#|5}y!*ct8dRV8u^vmH_K3m@~!%c6mifOPjD*K3S6}DCQ;Vk@;6pNwJ^#69FsmRABYX_X%ve9XmbOgt1 z4v#C2ZvPl`pyv2~ORJk!1C&(FlJxjc7b^n67alFSB2<5(sX~?fFif#k)%Sc;CYPRd zoI@x;Ly_vgFX=r1ZV=eawoy0oS)=(>AL9SMdKJy{1K_;V>zKwMO@?^1=&}*+=ku30 z1NfoGNRLB6DN8`rM1D;BBYa$+Tt(wSK=>bt;}LrPGfcdLa5Bl(@o-i!!$rCu7i_uL z2%M*rQID<~gk2hplO?XOpS~^Tb2{sXXHVNIY^(5BXQA0PHL)v+$BtQ3bYgy6bOhc> z+dnyEW7lp1NiYoEZm^qZGINDZ*zL;ub=Q!6&*{pgu}?D{+cNfktl;916$wR@BWlV) zTN1@qd`#-asMBCa(RSLCqozh~H;Sj4-e~qNpR~c(3%Kj!)p&dZ)nQtS1ebIK`R%f} zxr$3;;*@n=95In1&4VR#zMihjCxU07$kR0z71nf!^V7J00x2b6L>1p(Gm)BZmXq;# z@yQJ$;a4jty!d~YZ>|?SQz4hKA?dWm<^?zC7d#Q$Dr~Fp{w#d1xlIy?L|2zI&vjH& zKWaIeO$L}_v{dK7dM-kKa=NEo*8{L)__AlvYZJ8Xw$09oZKzft%IE6?S#y0+@kmQ0 zh!~Hc-#Gw9<#n7Avu2-kYS!hM2Y1S;snx2?7}l42w@;USs5y&lh8`9$FE^%H99{F{ zG)BM2J}ukC7h_;R+4>eBJBHt=n2_%A-DN0S#;aTW^2y_PdjCgovvNqK1+NSidJwIP z)m6NVczs+ixP;v-hsle(9P(BMT!J;kcv4J?&EMa7v2%}jV_Su76}~?UuSvErnhI(1 zg4^z1nlkHZV^@DN`XF!Gt{M?z8*ShIfIw5r&01Da*It(1bqj(VIFS2y?8S~V| zYP#g7F{Fg?9MIP4-6E#{2uTOY7SUw9UWVyCL24dfT4i}Y|08FR;7DjHyXz*8Opc{ScJaDGh%XmQjQ(1s;G)C*98w2Ap*ay zcIY>3r=!$#`>@>jX zWN`&nH%yZ`R8jb#>rFbJUz2vmdx932MeMR zf*Kk|q~zcnX0Vi&`lvYsQ=W|#g4tp+n8F_lH;DV_&skVZh<+OHWIKQSY+HnF5xzeO zPhXmZ+_gQF7jnr+)6L#!VA?H9A)3hI7Uh6IQ*GBr1Fp%XZqN4`8fmABuYdR>)5X&5 z05W&M`)hTQ^^j#$yo*&1oq1nWNWGC?{ z48}03qi8s}CHaOQU}B6W6Cx2-rQu?ftOE9SQNW!kd3_f|1@YnwItY5|Z56gvcz+iD zk1q)gMy??%qSbBju8_2zQ&UbFbzsfJ&6D!w_^l>%5CLkYpy2F2x^Vg67o6VS2d=9K zC88OWX75a>=ysD3m#R{C9OCfoo&bWDtX19f$jeZzHdZ5iMf$Gym*@xmrpgvP`UZI` z@(qTgq;e#n)sa^Wr?Ko+?mp^2qQS>ZH_>DhPl4LiGH&IoE}itKq?gKZ7UbMW*} zfSZ+2n;Q8=9hD$d(=}_3?}(PBVSw{2xvC#&Y!8sB{^+@``_AE!q44+|oDvFVRMl47 z6?BYtUR88OrFZD>OR7h(k={6N$a=Y*ZZr>lvuA5~g*3M<%Z`sguvXW3t2}kXKZ}`% zhFs@Ka9V;4oy1v5ddNt4o7zh~iB zitFh98SQURmG%|u1jx8)IZor$H0*=6+R_B9o}#EontRgptya@;eM3V0de8#5@glri~PtZ8bZWhE~E@EJdNMpmzqR2`6gAY`I>n+hi z5xqx&4lrA7$TyfTW?<@;`7$4+OP(`Yk;xSL3Kr6F%z`hN5*)RYe`f;NR-rV6Y^y*O zK8LET5EDt%msF+^9YcaLyN6`r38HV?lNJ^TTnmb$^3iU|?5Mqyu4+h?+CkIrsWqdF zj5KW31sEku!e0FY7JG`XIaR_gIsmCGL)4nxo{JgPGUT%k5#BW&L$zzmyd#v+S1gpF z%Hg5TOT*9dhGks5z9M)7kwu!mS>l062@XtWq{$`|z9zq2(-{ngn>lRWVVp%*@U&(b z$Siga{n1&e_yZa=1l7AD6A&p>xL9q_(_$x@+^xzG^9X7+;U7g%-k9hhwpG|x;fJ&E zOYekeQ((%f?>I_b@+GCwK47G()=WtjFPMzBgt~&hkK`A6Y*}-fXBts;tcLlRs?HhlZA3%d|!X-5TJ+hYSxUYKv5o;kH@9qyE9+E4oI>-;uF zMu8@^K(jGoGccVmuYg{Wcf%2X0a|epj7aWa|CXb{U~yL_pN$J#boW?H!}}G9Nkw{1 zlI(0;M$D%3NkC>AZ=I_(^CX<5t7(~jz~~BVT^`@vWuxIJV)#_VDSB6w8`~;utML9T zy!_I3Yoc7nLmGa=(7Vp>nSUu%h1!pPzpW_ZiBTy}x9C7t6D-lx+K$pQCFld)lNMWP zPir@QN%xpXiSV31{0Sfp77#LP-@2xodv)1WpF8yDW%jUc&pMW`H!jr=wT>n3q4^kp zljg%Q0R!YR74tY+Wyx;*FM?q(I_@o})A3C-2zWTq!d^u|0*!r{P1isbQM}$R_%;uh z^MZ9;GR{#ih397xL)dseT`Ylhgh`)ZklAHQf6jY^xaGIYqzLCPX6Lgd#OgTV1@Y?H zwglS}yh7k=Ld)|2rq*Wij`-9f+-B%-9Q}((=jm~*(QkzLxTx5V_(4+=J$_m z65?n|+U0C>-5-XqH7J~HbP-sYLE9oY7`DVSsb=*+5EES@bwP&LbK(h)St z*47ovI`PdmRv)dweaW($*zGESm_$^4&GxX%9s*23We+o*dDHY0&k_5p;9Dq2B-bQFz)7SGLeqCJOC4+>;Gip|Z8QGi%V}TYU znx@H3k&pl~3uysp2If2tgWdE$0mVz+^2-%_h$Np4`p947y9MByJRZ$p(BP9Rf&kJ$ z28bZMS?;9Y;h45XUk2!*aSE@wnx9 zWq=VM{#f4#ukdh`5`7`=i>4#jBt-{RZfde%n$4rIE$r#XN=+d`TWT=9brsflHjJBQ zr%|$;Sah43X}C{X@L%53*G7YAN(jwl!c^!cWc$Wg6s8PFCX`G(1MAiJ8q*L4h=`mH znA1s&JFb|~3BV7C%bo+N_b9+P5fBM={cagtM%Tm@5F$P)r?-Tv<@0osO~|dzU^&H% zn7Eup89oSJ5ZfwjtMJ2F_;pva*c#N1&ns0$kgDALJw{E|NnHlMERhLJ2w2msxvoLW z-5l8t`)E;UKxq;+58lk4*|ZeJP!GV65lC-T?PfT)i4kVZ)RwL1HNjULQ|b1bhWrN= z(a^Xoc`P|PT}OESM{4-n6%nqq&Np`h?9r0}(xV)+baE3gatbHAv)_doQ`S+If#{3o zk7*ikzY6B`;79-`Flo>#P1#s)NQ8w`5Dn7B$3II6QfADwoF-~8tzXXL$q|oF z$Q_EODP69!;DQA;i7#v1+N-+Awe>w5Lc9o+ren!E0bgcK zYkGz(`{xd5{!v4+EUi)z9rsw3d+pZo;UV#LD4D#=RW5@EBn3OSgiWpp_Ri)?as7;c#44k4NW zx;(w)CA5M}8<8qI2LrWJd}k5cR-v>DZmU2QerakIl-ey@Gb?+B@}YLwR}UJZCe>7# z)pQ%Q7<~S!;q`SLs=r^-nYtGFEg;EUx8fg~HXzoH**nnH=K{9tI(d*a5t0*kDN{bu zepCfjpot`@x*fNS*4BKNe7qi!k+$(<24BY@WTrW5<9N`Ir|03rL%5lbXOrO!#PW1` zwTuWT7)JR^s57NAh|Dum%Tn%HL7okYt2q7m)6bUidK1kq0!$FdHTV;;qxR{Yr&r;}cZSDqP39AOIRG?VnYLBfR^f-U@VQ|tc3l${&2Fows_dT*8mDbR zsJq9aBUim6AY{5BDAmTXsi}U)XCqOqN;-Kha?_}5{f^%_Ki4eZ6AZg9enb;(n5z1G zuPzF`gTc5{rgB#uzp9B`ziKoj^bqX>yF;FZp?$25zd}`%j>3Rp(sD*~UEIAaZkM~k zf1Tfq2@=S!H?#&wk%seY4s)?8(7X1vAPZ^ny~2Vz@~q=onYFe&v+1{WsnvAaHb1W^gQ3LJbc(?m;a~HqoqbKR86wpoNHKV;MA(4J zNRttPn85&s82Y53SO61X&xTtrDY!?GTQdgOon)(EfhIPeY}j639tYWK4xMkDFmsw+ zkS04#?v@1-TBuFL2rfyv!5{bX4!9W}9Kjdsk)ZsvO| znOT{&^fJ?Ia)c2xOE;%$>6syPAyEqmiQonAC`c3pK>`F!K#yfs4Wa+w=Z5quB&a(k=Voc4ubNvm*HHM|6l_Ab} z{N)>{tAt$cS4g|VJTK?Tn_`KNhp{SYm&x5rLIR7|`4$sgn1|QyjccBQ{%Q`1*@t}5lY=i9D!f?Uczmxo=4iLT+bP4h{MzM02kkb3|I z)?0Ml@LPe3mG@yV=Shh%ycOwY2KseA?uYxb%qI^>^!Sz2ASFwjbO`QPgohKJvRZNc z=gUWye1MU8$d#Z+PN4^=o+;rp}j>!FPa z4yPO9(;n<^)Au_4!GKRi?e~nnDKuT%bfyDRQya~`r*!o5b4SJJ&}?W*yVnw$=Wtvb zEx+B`x?9etlNb}+ESTP}7_82g z%MA;L3T?k9X9DlUyu^upAHTRiDt{JFQAA5}pTHf$nXd0hMu1{j2`5CgE)BGd{XBkT2;cl>(#7F}GTdRSCtb$cUz5 z_yZ7_=9%wWqHMUMu5ks}Qg9o78{+-I>G#i7Qx*)*>8R%&*EN*Dl%Jy$yu#Yu4CUN`cJ)F-9aFuyNiI zN}lp#8DrJr)jD~E>=YE!FZl=|>#J_hhawz` z@b)BpA+*%f?s;1`;mPQd<^Wdec6`IX8rizpvVB)3J=+-$bk@r(q|dJOW5z^HP_0eT zR7i?%J3usGYxK@r-8Lc)UsPljU#VWxNZ68a2KAf{Dh<~+HQngwlI5umS;R2@)F&(X zCYVLL^&NvG?l7zvDwM#Qo6Pd@BjOlmP+ZYjMEQPKg^06|zI!B^buypEi`f*+B~Qb$ z0HRUx1MX+!1I?#P))$qr6a)uyka@8xHpLoEc$J|QCo3o&MT8G^9?r^1LU!USw-K?aZ%Pw~$gKk3bSS7{!b zNc|8%UA{<+Zd>hGO>p{NTY&58IjY1hssS#%)v9*@#Cp*7MWxmD_)A|V#ZDJ$HTB8J zz78-&KYqkB0OuZ$&pmgd6(gd}7V$+IueX%}q8hbsf;l4CaCu*_#GX!8;dGSJVK9t( z_>-R|OrKWS6#Gv}zzTz?JX&yznj+;0f-!QyHE{iy;JRhOUoIC3yuM&uj-q$T5Qi#M z`51>PR8{y~6bz?-Gw?LwWYBSRVzkbBLXCL%4yHM+dui*wqL3>zRK&X0Z@WWZ=LwNL zS*UrQ4bM!vei5ptr|A0{mM%K&rY4y#p^B(KBw*r%q*%J#>jC3H7e$&@-*k{bwUkD) zVg2u?yRTSLSzyFN%K<+h1neYx zwtM!=LlF)|_~9gc37)vtgdC$GZzb2k(pAl5<;&KdRZHX7s zb4ddn`{d@|1W9ts{RW^0KrswJWttSrMUW7kJB#qVO-LT4N1hM~4{x$q#A6&m(@8pm zMK)h&VSzOQn_OH;!0+hbkPZ@cmi%#pjYOHwc6Sx2KwtVRn7+eT1pkfDNb>$g~Gq&1Wv>l6b_v(*d!ovjhefN+94_}j^HBZ7K4VF<-;PMXJyzd))to+8`ca^GKWR&3zNF)7O_X6cM=HO6Q>Lg+2#GcHi` zH5qhSTHb$B`5-v&^w$eWX32kDfsctmNy`UrMX(B1;dadm8=D*vT;Ny3_~#l z%Q3{R-8d4TT21rxjBH+CIeCBlm%BWe;eD6~aWY*l_lWNh_@!wUMB6yVFZw`0b%9?Z zpXGNS!=juElcnFMDXP``vQ z$LZ`5Ld`VY-Br1c;po{V{QE-@4n=r(682xJ#GL5uj&;;{5*(Y@2DR7eTbeC3b^d$i zo%z0Vj!^re$`RFx;pJ0dTy(T9{vXM?*1!))J;z7fhpTkx_AEtnZC^8Naur!hv#%zA zw_dkwQ#rr%aojly9~3eu(0yyQ$+s9B#=O9@>HjsE21UkDDcY>K`LIlg=Tr7`cgtmQ zk5K!*m_;vQAg|eCmE5n$mtHeXdJ%_lwpiy&#C^2l`(gu~5-S`XcLslhr8GwEA{kFI zg1GJ;mSk?_(QLjTlL z#HQnz@a#SKt(N0@I7iQEj%Cl$ET_|PxiFr`0bXa>00y5wQ&i_ zEkR+c-MLgmkW7wteQgori}h4$N~m1b=TEKZ>&aqrImYfB%x*cs`Tg#rpRQM%Wwyo0 zkmo5pd$e~|PNNXcLj-w*?hWKh4KAz1*VVn!X5O0N~RHT z4=YxWOqDQ}MvpIeP?$#{HK+H8%jg!x1|X(G6%JMS;Vk@Vi&>F`hE+GOP0?~E{t&)B zM0*c6X!FOKFV_@^^;S!CWJPVkWL1?~O{}`^9%?044QEWB6t;MEz1iyfNHG*kBUr12 zY>#Qx6>}uL;{)rU5g(4PG=kyVFfX~639TPLHIv`Wm=!IMpvK9Ibe#L71@R~NBGzEZ7|CvzKnIZV0U4Oh@l9mQ z#|1Kw6(0n+$l3m*$Cxc0$wPSN7D&Udh|pq5eW=2r3O}5MKXdxxiPCP%qBl?*-3jFS zuGQ8>T|4ivYL*F>JH;i<0s^a0U2qt=>O&DFED0$tD?8BNmJ7ZW^@gcB=N$vYpW%P_ zcR!ST40y2mB)QW+A85!t_@#j>YqoI>ti!Ry`myvRkH5}0vk`k~w5_{nvi=Bi{W?R3 z5u-RNSv3Q{-{X>op~N5xP#J`#gf#2`5si0R*pdlk;B0TC)g+mqo<}7sjkn4x%hCLjZ_1>sk ztI5Rd)@X(47aSsZhu3m<06D-kgc_C!dhbhJZMC&lmFC`6RFdaZp((kpA~T_KPuW!K z&;M>s^wov|)C`Y=)9t#hAZhict4Ii@E_G6g9J&5M0|d?2>&hPOmOV|mILg* zH8?W`TVpH7mq0$n=>v*Gcl}{cv~bY*3|@Is`lPTsP{~XPWDVh%#e&_2apt&=D+%qp z%d<{PB-Yy3_*k&nQ%R?;*Hz6|o;M`5g*sfXn?g;JYfa%v8h;y1vm%H}hDcF3+uo%C z&BWVm#RX2cELt)+UG6uSdXjuOpH(t&KmiLfu?n~W*nEhkuIOdcATPiz1*?DW;chj< zVU#WD7?vdTLVv}94ZbG4ozCI;(TGpdV9cJQoCa@~5Ko6H&{!X;P%WgMzGNeZ%ubhJ z1h}4mZe9+=TevZ8UFqSW>-G#m?=W|T)9nqK@9XCvX>8-U;0|EG)?}$(Yl2xKJgX@W zdsg3+da^lY0&6%5Bc`F#)H^!Nj^htbZ1=;aqW-wW8oaI5kDK-9lJgJi<8Ld%eNu^! z2+u8-_vyoK{t9l)Dkgq9FV~wSh*!l?^gn33 zMXjN;S!=K-@clO0jX_V+b=yX#-FEHaWv}Zwo^1Ir%6z6wmWTDN;fc=Rx@BUAu%u?o zn*gs=2+e8^BLv@SL)L-wwQEgLcsp)#+I`#Wok*J8Qd;i|o+5Tc!bt^@6fH0LX3V27 zn@?C2;0Yo|al0XJoe2|f^dj3oY}RF75^Yitwg_~I+dr!al7zM|W+?)XbUvMxuYs14 zF*lv=KZ{3kGzpW{dbt_{q(SC1PZ#ax zz~`SEVndPzbm2rVlBUwBH>5_d*SUs8rfRm|@^Hj?mK0qc3%2F(tSKf|3bFqC^(IuC z)8a4o$S#P{3Kw@NVTwhv&7&zw@4Q@A`|9lep@=f3t%$rIDj+iMp-n#ji}~VyIo&Op z$&&Ga6DR`{UlA~w|HAS+zTFt>ZEh{Yo+x1i3^b`iQl4OwLd#qXw#IOxnthalh0X3;p zYZyTPw8dXw{s|a`a;n4Gdd}LJP8oeFB8zo#|8rs;5}ee_`Im6|#$>3h<1sfRJ|VMmUzoYG```i7)R@bETFVluJbY{W;&i$d$e*rU*(JOVvYf5 z5uwSbR&1EySY3mg$zSc``wZ?qbPaO0vIXB0*aP^A_|K@aO~9<#!2iqFiw&-#Nr`bZ zseIIjDjcft!&&&1Edwit1kkc|-C#(hkshQ;0-lCTybi8udZO3R`mWM;Z+z7)D6PfMQ5a{j=`E4I~)9a7qx|o9auO*rlxyf~9LpD1Xw$@;C-F7up9eV4S&ym(5 zZt)EJT}`pa->vZh1(SrF#997P#LA2x|tq@f12bkW)pT4%hhr{BeE1VYf<2&PFFlth-kA_fhTpD%x)_?Djw9$ z9qzkvh?V-~p$3N{^VPG)}Y) zNF&w#Dr&ujW4dFJGhI7IAKMZ&OI2{xN$0J46-&o%TGDY+Xg%2B$j7~|>zJ?zPGs@K z&<3C|Edh=AlRN)yxw1wg~ypFJ|(P^e?8EqDx)s)9oyU5W)6{_IXLlvqj{P}4Qy1f>*YxKB{Kll;gRiYN(zTssc$5+FP^UJgiE(QdL z?uddFvtR=~=2a}q)<6=D1*Ivr8j45W98ZnY`cUzu6P2C>0*5GB#{>=m(}&^lwnJ%2 zCoReCwym~gO5Rg@{+Bzf(MkO2a*S7Qa(R)hQ-pg+kf0O?LH@A6zkmEGw0gp^fX&Q; z^d}fiL$ZRZMqsv`2k>a7b9(WT9d?9cbaoRi=Odzd<28@UBD*DU2$(($4>}a~ar03H z7+>*qscvG=R);Das__3i3q7-;V~v&xgQ)sy&mb(<5>;kKb;vS)=K}eI<#Y{}XewAr z$b1fZr~U;zv$i^RCEryXqxrl4uI<<5mZXV|hN3FXf$BKkncQffw!Drj*0JHKwGSFJ z9fNkiuh4k3E0)ufJo(E_I;pJDiyUezeKmhc^T5d+hZFwJa&`Y|_feLw--_|TQYP4` z3EzdUG$%6dqhbL(qe!R2UcQ_FB%?WC=@w3RfGo?q#dNs~pwB?vAk}nyJz?OwTW+=? z9t!?0@^Cr`c2R$RsKTKN-=Brgn`%?lyN2mw<77L~w$5CrW6X?v$@Og4wM@oC_}eUA z^)Lqvx9tr#zR6>t3d+r?-R??Uk%SLaOKcu<_0pO`?MIEig6kS1omjIC-(YW7Wm11A zDx%Rv2j04H6}A1m)_>}bzn(_Zh}U^qV&lxibeY~&4Fr^o<)R?;3bZBTAqWBV4%kQe zPOQrPFPSMJ*$BdyJ17E#21V0rY^T#(u3pTe#urnRvOD&Alld57Yr@`+Z^q)9-yvP& z8k#+jSG~L~$6KJ^oP|Rb4psQ!Ec{Aog3c@32vTk0*1JfSIx>rBt%>H_mTf}h?3QwT zjMYs?rJ*`!ByFA9Cd-O$(-`*qmp(&SvyUbg`Kw4bEpY1+Tl!@eyqSW)TRztmvEh2U zeNq$Ki)~xMh>9f%nMmi!41XJf0x16odH|T!Fkd5CT2&0z7_}d=R?w?Uz8<$Dylyn! zV2|(E;N9gZ+luux*>ATGONOxNme0##!TJr?9Rb%Q$2|bh2YwvP7RaL*)RH4N8qZgs z{{2-Lt{6zo;yGcB&(g{VaHzte3O}5MuUSNxzRP{bZW)~}m@*BBU(0t`&MCTRx7&nk zwXfU{y)&YMdKOv@88D60f?I4G5WSsRqXT4sUyo6)az&V~M!(V5JkxB#6*!g#*N$vh zfNdmO?2MLuwL9|a&4y{2wWr$luK*dR%Yyq(HbZTZ^1cV+2S|+VT!`s;g?MAOd@OFt zJO1A$OMzX2YCG$e@D=4`_yQ*T+I`0FyMmkRmvoRhpK1!I?*cxs@RY!K{xTu z;94b+!KF9gS4tujaG8w8rr$lTy>2Xio9^g&tAKT4=H|=&QS`r(cLKX|ho2fn2lk(N zy8LW;@!}1$*%Z+IYBAvUlF(qFaT&)*!t*&~ z{B<&mS2=sO`Fb5rP-m>xt9`i4p|>uQ`^{qi$tH{m84XuQ<$qAjn9ByYJTuXvdTz3G zHC<$^Gb&YJfTVB3g((P$FRh5*cmNJXI27UCN%%ryPmOTZa=0+@7B^*ZWQwj1*c+Id zbu0`l`%)3KQ@3{ta!k1jG=jA7NcXPXF5@Ic()wN5?6=up>%98i9`U`JUH@Ie8Hu4j z)B9H@ehRbW(vb@Tl&)uhXnx|8mVCoIKMW@YpvjDIIjF@9i|}@Ci3ws)eH-AI ze#HB{FE{&Ym-hH3ii$igSDQy1LE#k3+;$zN+f~Wg=O>E|NRBw0oDt5*O5!fwKBhP% z(sjXa5^VVuOB@oxd_*)6-fAKtaE~6UaHzr$XW=W45Ot-lVfvI+m(*xo)h&gn6ae5p zo@$Y-2f$*8FtqmI)KPqh_FcWv@#eRxCg|s$c?xT$uIPqo^|2VqE;MA$z2Nvtr*4i< z8%7tQtlm=DN=vS!w@C1}o`>U@dFmo6iX6i<*^5M_pj4ubK!Uf% z8d`?%0hZf+5iYlP5z&dO@{^aaI@ms^JH|$=u9K7y#UQSdMK|Fr42osA9;YAerpcOz z4ZQJ~8(9Gzytog?Q{1QonWi&@-|S-!RX9}PZ_WagJqhERtC1S2d7jg{X#4hs;X#Y( zwa{4@YO`rAhG_mA8{-3MTRLHJcKgBsO=vPsQ_(ebc!ouy-EtMvbtsc@jl$ytAie)Y*M>LA|cjc^D%?hHjin}#E1O&^~D^?I& zn(Q%Zsa3R@kCXiVjyZ0&BEoJl=ZPS9^Q%J@4psR6EPM$f>1G%m!gALKt_1PE3Bb?LjK1R1iodU$O}%*{o@gwq{Yz6HoQmGLdeU@UFyBp) zb%w)ILxh~{>Wc8=-+kX?vE8{2lJ?-Zp?oN`T2I30+mONNt4aYrpOzs}yTN9~tsi|} z!o$GkfCU{R)+O;;#heF%zgtaN%WRupCd8CZM`*ccldyb9$*7){_t9ut<;#J1jnW0) z2a*=iMKQa&8eS44F`WYFd zFfmXsIkyZ@RaX~TQ*?m6s-n^H!MNJc?N3Nuw|eHpQrnB6A(&nbA(L#XT7Tw&`6HrQ zlQCSYAIKd`<5Qt10zHM}*Z+<_w9J0B61V%UCW5AB;}a?PE-O%ar&~O8lRGj<$*Dey z|C8b+SQ)HB^NLuEVLFW@U96gd^3jV&39>1gCv!^ubd*D*0*li{eVPg?LzwqaOQZ12mWc%4k* zZXKp&&3Nf%3W{Uw0mon0U8&iRkamW|LP){Ax{&T_Q&{o0AQ} zbqQ(T1?j%QoPcX2;wf-~INvVe?HIHf#%!$Bd=a#^ij`E78*i^*t}LojA6>a(JekpN%kpMHur6+CTnaNN zOdE8oY^@is!F40h3xUvV`9m0>Tte4J#&l4O;|&he_(idrCza}HozBw9^%U7sB@9fm z$#{et0%P_fhEqU;9>KH0Fvk^)R7d)Y#g^>GGEBZ-RUfKQE$k0fpbB5ql=g>;eM1j? zQs)R`W2mA`G=V@YyF;%nh`1emZaylHfPvqq&!SFm>Auf?qHQ>1v`;O|$0b*9UYf8q zXs{KFM?=>eVhuYgGA9kOhQg=ggycDMVl;O5!W2ZOH+c@SxSUe!bwioKmsX?x+F--CHskGl7EEu2|7WVmy_v3#nwomxn`3Y zqpInAOka+FI^I>Oyqm>{zS7_i?dhiH6LmTplI= zil-plW%GOdp(RQsUizR}xi5hp2p340{s>zU;yprz5Q6`NI8p|#vjWn0mfa`8Bz^UI z&8KEWR#uQ~*U|NSF-gm4wWBQ|`S&G;i4?YF5X6;b?x*h^YH+AQbq=1s@*65UgC27n83Ucw@0h1Ukw!orxVHRUab&^kUUh81t!+@30^T4rN-Ag?;52Bv zp_SDQt9oo8(uh`5ZueC5OjW!}+d5(8=a_?b!){oDQWLBjz7F3lCm~9_7aY;;C(B*3 zqooefu@?D)^pk9}PIvn`8@p)B-?=3u2w(N%itNyI1?rM)Ew&c4)<85u8t`2drQ;;y zx#1SY>D9Ha)zmdjsS~2&d9vLeHZ=dttTijVUq=BX;2AxD zmA=_T*@xPj*{x~-g>Av;XlVAJqu2visWHE$!_e#4@0txFe4{5j{|4;+s>ok|l(I9( zQL9dI2j$shx!Yp|Vh@2!dJ;p*uL#GJd6AaoB46&O@$xPmPb<9N8UTGnUc_3 zpj{$UE=r)<%z$)Eqil9gAmF+l-Z>=>*qMK91%ASEzW&3x8HZZ!Koi@mWAdN*qS3 zVi}VF5eDq3qa^3gy97SjJQ|_rSXPfoHXU!%qvT;fACnsdm5CTG1T3Gucc{Uk2Gu!u z`W)Mi&+rFHx9jTl#vGNB%7Xf&*JW>QX}(MTH0~g|Z&s&XX*g{%fLfw^4Yf&7)b}eN z=uMr?TlFNgI+r(>Dr#2E8(dfd3Rgp{S*Ji_J;314S@Owkw;|%fGwa|mm8aJH8*DpE zhCk56Q20%zpX8*;v7jDp)vW-I(4psR6 zEZl!3b$z>g270f3r2Vyw5Bk*Z`jybnAW&`+K;4im6F%jzYn)mg5XBt;_?oQnZkLVo zi>WU0tsi+5Eq~-bCFIOGC^{G|Av(W zAzCcv%Gm_|_v>H&vIwvgVY^=5MC{#e$BR|=0=`+fWBwX0)}X*g5Df5GBj#Fg5)L&u z)Sx;CPrtGT9og%58;0j7n0`EvdUoIFv_<7a`+eoqQ=kSAr|Vih$*<^S4WZSrJCYT4 z*+}b-XGk?k>(rZ8Z|Gb&rZZYurl;1$R*i58GOdXY>X>J2-_AV4S8e;!v^qc1xPB2~ zssO5VTVhREyT#|>t|VHNywO>~sI-Jm#=vMc&DQhmvo&za zq`>kpqQRI@GajgL-{o$FYXxZ(x>eVt% zYBm2GdHT)zQy{LS!fnYzj1~nG*TtgPl)z^e%k(BH_z0Abi^Y;q(z2+;uvvBsA3VvJ z#m*9X>?x9^8IJ1YDEm*@Mn`cPFWa;MPIbM(4#(-;T?5^Mm3`~AmDl->-O*ejsg4%2)B>UBf9G$HM)6qf619ZZRC zhpYsW3B2*`81_sCjAro&L_fiZO;7~dzVyEO6u<>cR&g-hV-Vs)k>FD;r&DArm6q*L zg+mp-KMP--o(%+(M4<3g7gg*!eOd$i%vHo2M>oL}L%jcS&4xJEX$}VRs0!FMGzm%> zE@^`}MdTSkjRo_Z55VyW(r^SFgS)9BsOO$H=nstQlc2ND^KU>u;j(DK$X7gbxDFlp z$qc^T-EB$H4bo3{$qbJik~{PpcSSgR$u^oc8SMQvGpBjHnr?TCS6F*cEzRe^jM+;w zKO(ofq8g|7tg=U=IsJGT?Ed&o7({n;%$qIW5G>iKHkL0c^b@zQF@syc$$#&&lJQbn zeIX82I8@>Lv+&1Xs9;)qrf(0fT^|M|7a#4!x>EUY=&o74+Jz(Q3pNp*OZWU5I9bPU zHP|-$CXIq-_xq-gFx*hR4jDm;+-y70$@G!SM$RWb?yPep{aO?)b7TmeVb^JPxhPe9 zr_;0RGyF%(Z}8`oxS#Xg3wCDcFc2n<(nk()PACxh(u?3I`+`Np>Y=!Q4579zt7t}k zZ8V<8`DP2SW{$?ASfLANdA-adCbF*z7IG!&ad)eu#n0w^fIdos)qb4^E542u-f4ID z0^&Z5<3D`wP=iAas&nx4Rht!nsa&619ZQzoI;^Fxd~so3YNtflqh{sG}P5)78ecU*q}Q^N4u0JNWh3cx?N znC0_1YH)5oC^qmr%pq8&AzSKd+c*H68h+yX=x6o6Z8In~D&-LzwU)ld<37WkCEQY8P zwIvG1Y(UJY^P$)z8%4LZ50t!A1ljE&hCMO*9jgOv##bf2E8eMT53jJ^nRcH{Ys)%! z1yycnmS@_6Y!kv8f15ySEs1y7aM$4^&rqk{f$ICi{avzoU<%95fXULF+(kx62|(6a z^6?fVYkos3O)f+hUq?UxBh=umvE$h&!C|-Nyf68}garGh+5Sbzf}-+P<2t>E+`*#& zg9(fQ2s8E%L_!>@aHzufXW{?;T)k1cqYF>>8v@PlAN-DB_cB#7`i70oN3mR`?=%@P z(O011us|`@h67!;`r-#fFUqPsFn{!84-gr1q>d&+twjAjw6!kmzK(B_DK~p@tBQ5| z)T%oSbXy-d?K6=8E?ZECinaSXdJ(Q)-LoE;qVS$w4uX9BGvue61ZyDsRJn$JA&$zb1Jx#L1AJUzJ--L{Z5D5iWP>EZb)Uw=d?aWf~OO$A9vY8x;JR zNx?jKcAYQp=JPEak09Dt1pHsVcPPT42=7k9)1TG=5x0Yz+m7*ERb-sfC^uw}zJd>e zGcXjOeGPx8qtfmS35$TG(L3iUIMWrr0j4gRrhg)tGUm+q2qiI0^0>2%3Xj(0v5xFY0HAiTYVY(}Kkn>~$2 z{LzbQae*OjGF`=!Y#MFuw>)-Hx?RV79{}|oif|~xyOZ#_VUC8*+2!EedjA-R@kQHm zn@!#CVHEWyp##)jG%SQiMz6BSDFbK&P%E{oOQ-F~Z9=pNe`pGZaZ0D%JoPPY&^O$M zYjAdFl6K3S0`U5>8pKy_prOmu0Yc#_eeFS zXjeBWL2$1>rGE}*$x-@0M#*Lg=|0>-8>q3*5T+ig-z z3;OdkM8TK827S3M+_|bmD5aT@jv1$~hF_P=t3U;a7cS)ak(;c1%D5 zGCFU~R(#*X4%g`PaaD838#w3CX4pN^?2IpBD6NFe5x0eXw3;~yG}dkF%C}Eix@ojM zg+%t#)AsWpF?RyCVUWkwal~3fwglBTRGaTft>N%=$o`Wx{can+T5T%sa7u30A|V4V z3zy_lLn9_01q4|X00ZaH=lN!qu0Fc|3A)q@{f)@A!pnrSfQ9rbdn~ij4F1LnV$*E4 z+b?e~m^(pQ!cz_6Z$5_Z7a-K2MFBxD1tJdCujIB=B}W~qaHzt&v+&Db_t+J8olB3g zk%M)?UtM@4vzv0;7PX#dA6ZYTV~Mgav@UYnblNvl%NShCeVvPx?zm3tq>2*q8LYNR zWN-96%^E6oL(~PKBN>9)Iwzu0bgN#2EK^Z^E<$#a8bYmxG(-u0yGf#Soj)L?$cR)- zm%q3#L&UC3i{>%1jqIPN2_-3Pw2o$8=2$YCx z-xhIp7ft|O2CN#=APN97MYDp%2L5T%9B-;XN8+o;W27Ox7GA%1D8iu#?@q$gSN#j6 zAp;?H4ORDgx_;ViKmVP|^lXDt@+{chZpY{$)$=t6pk+rqZaE&zSAl?&+nz~g9HvlF zCti+?L`%5p0o1m$&`O^qi3*SF&tg6{}>!qXJC^)XZvr3o4(LLWLK22^btj-!yl^qPuxYKd5RK=PSbfSQ%s)zI2<&!{yuqsvUl0G82W3$3|bb6`0=7~Z0y zJ7E2w?_r1lx^&u8MN4#gUARgIrQz4@x)X{tl7Hy#tVQ!k`DfeEltd%1_Ggr&4B*LkukGT=?1 zV2Q)pqxxQud;;};2`rq*UD$kJ_16!(9kVBHR5(e?SFegOQH$vj#MftU7`z{9aHv6b z4q%sBYRhQViA7YcYitcf`ZhD~YYjh5TpqOUIXnCygNZ{&vUbDsjU=KJ_^LR1@G|+zPLvYQQ z9s!&z(6GK(Au@^~eTV7YKAc9|$AUj6HhnhL}}$smtc|De{aohT=D{j<*j4H~OOL}vbb^H`Vs_Stu9)+Vx{2zUmhxw~# zyJtT+6yZ>W?@z+hpKAJ#8Ws)*-M)}4Yryu5fS-ZmIi{)dYFA{HAh>Fqc8R{b<=EZ6 z({XhKt}@Eh3*kduM(wSGVQLV(c&b0Ax2}Fz>0ETHcofBT1k$(8dV-4X$@uW(SX63t zK}{|U!<{@0i{He_#guOZ_WuXo=v!_^M4jvk;@E*q5~#Zf@1w9_?fihgdzNSGEopNx z3Rmn5@qKW^h&Dyjgs&RH$7brWp5(U^z?=}IFjX1eR56;sNL_fV} zyHUJ;wtx0>wsD6l9IEjBS@>Kz77RrfT6+JKH5+;*vetW+VK{xeKX(Byff$3NM{0Yk zsjH_n%Yx;&wq7?BcVM2Jh-}$_Qqn4rh@z@Ls@Gadb6E8K3*8qrS8j8*#4T!a zT?SDse)#^s{riF>biE^Kcblp*#8&M{_(E=RwQB3vJ)?!<&uBD>hG>$n==j#DWS)aM z^M`?bQHPb>k;KM_Uc1%vtcj$xyGO16^7cF2p0EPuyw!n@W%26%5v~RyCOATiM}p;G z&x{x3<<76K{EGnCOnJ1}y{z<2^E5gNzCxsz(~v)I5G{d1o>p1yQ{ol#GTY75d&W@Z z{!Mm2nefc;k8aA^H$7Jf#c8e zPs=Gu5v#bwfJ*DIO2_dsT-|{vAVDRZVvOUhcqqc52=7k9pDEG_puM_4D3*{9c*r(zLk#Wx7f>dPFb}b3*L=|z`Iqi;jwm9r_=2#wyn9QBN=L=rS=Ec%wi?J z5x~kk*|4!Yh!u29vxqGf__z1~I7n_JRE3DeCnx%v#TlTzaX>3D&x%E~T(O4Z=JT+k zt%gq)u9r~6vV65)7A(=q7wHrW&;++mJfLaU_#U}Nrhjp+!soV41bnp@kHRh?=K{@Dm3aIQhGc znr$~#f!swI*$16R_tbWj6O2PxBkCgmI`LSNUx>liiz*{-K|>suN727#W;&ZdhDnjE zPG{FQvtq)rCT#R!|6+5055OLcUL4KGBbfEkeX#<1Pq&dR*T|moH5)tTQH)s^({YAG zJRo;*kuKO$N9#SLr6VzIYdbaVP@A){{p#pJ3QFEJegW4{OGy~OG;D;PQfcjd)D=jW0HDAOa~1sLFKTJ0!(*rx@lC~T|8 z!EMG*tv=2cQNF${x2bf*M5J}QiJ@0&OSsn>nC!#yM zkZWSiF+HVaIEpZE+qYgz>H4D3bV3vkttoU*dujR6zV{`CH=xVx3n62X~PUgrxHqUN&UC} zz;p+l7OqoMYYOVM+O#ihnhMR~8{%P{5Z`~^P$f{w;Ey}nlQ#VZM^73|XV{}R1(6Pf zOrv+bkKJhqdkBRU|*!= zc2%vs(-^xQ5v19D77;g^^9?C6PRy@vrqP0~f>2WIbUYEr`3_Y$RN?!x@Xx=r91H%7 z4^Y7JdrqgXwfGpA$D&5wo6nMJsYZvW<3ZD8TfMg4OMOjtx4G`6X%oxLE*1o}JFp zgg(0rSNrWIKMH>VZUdGpS?uJ$kCSA#&q33${sX9A{^3iS>W|+$)ZkEq>KqUQ!iS(~ z!-`S;Zr?J7Z_l=OqUf$|i#|dnrB%gClN8!kZME$W5dQ%ot~K4?ZwW4gRjyH%s`ds5 zWNow6?i*)v&r{F3{cBey1Hw78+5`_Z$RBOU#@V0>X(aaD^F?!Z`Q)bGfr9~t#KDis zHA}cXnmbToBebf#!k1CT>Kc?7cAu!C^(~iNkH|tn&|RD}e`T=BXCsTE%@*uTp3asV z0vR`DbhqBTD2Wk@@;ihbaWP$_1Pdj1+Y~|*0V?Hko|Yd!@HBupKUCpRh40V8Kl=&{ zH=;vf%YU;W8*UlT z^H)ox8wAh+F#8AjY}_lJlTSU4-AF)SXsh zK8Ciw(FRtG#2e(L(-j#e5gcT>Ld(^TD>A;?>oBikX(xZcZu_4&)9;XKL#G^1(PyU@ z=ctsboBk{-*Sk1h^5uqgc-vCdJTOi(pnnd~P5uZB{9mN@h#fOn3hF_9Xn;^L*Ko zjwM%;#N)Ou+xn^JiH<+;tU*8UFQB$6mm0>Mnn+Nn;2NhGM(s048(R2)pz8_G`?lV` zf_iTmlHgtS9Y<*}iBfe}luxZIJl3j2s1W#KzBjGDsW$}4I;$NE+Ub*#60^HxCq0@M zi}~ypcy|`>%5t7Bw+Jn^Z;xJ;iy_7Jrd1*(0x5 znSrA(@lP)TW~=z4*X-!BSLHf=jERKciHM_WxRfk*uQ%Hmw_CZWhN+crsOq&DwUX7o z2+LPA5pg&sogKiyyj;K7gazzyKs75m6u|dMI3XTr#b5~u$GafKUmvPKA9<)k)lGj1 zK%;%3wKV=KaiO=!dQcU=D;rwZRGf~<49IZLM776 z6=xPN;9X=yibmmby-3Jc=hDMIElY~KS+raO=PQ=wEZ=TQ?*A;);+rVn(P~3MXuNZc%Jl zsezLLuM`m5KpZIM&~o|mlX4R!FYlw6=O9GhM8fpjE*p7Llr9N;7)76cx-6qvo{$_j zosjoHvyg$}h;vee;&^>3L)**?PsL?Y7v`8XeKJTK4c(t3S1GzsV|e z9!r9c_dtv}#;}&w+k5(hS5f}>I%X;HvH;*mLSh&Oga^G?k{lF{XvS$HvX{FRCWv%} zUT;M7F25vME%*bXy>P;p$dm8 ze18@`w>q<*^x`Qg!#7;HmqU%(Nim>Y~ zTS2kcA|v9sR#$Hv))ul{O{8r1yzO&2mw$X>%YiV5`JHekdgzciI&K`=Lt-n0fchRSkFxv6R&h`8Fp_^K}C%J~{u*ha} zEeTSm0}H<)O7%v=(lw1ZIl|+dVU^)KUY?48y@`i#bWv~CWD~Nh*8H)kiC{3>R?U1e z!>h%o2@iii?y_OGp;)dX-Lt z>3lK4T*Lh!y=i5^62$&S)g^$%JnZ8qMu8Xmj0j@jtuRJ5cgG5;3v zQd|VnEZ96`8$4>BmaO%>dF{*JsYjwvMPBlRtdP{m%DkHRbGgnGG#eb;ZTL| z&%#%F54#(_X-R6;BvJIxy|z$;_t1HZ=CFtLLGUkJuhaATN>gsweN%E}(TA`^v=GTz zs;gGhu9jx2dQ%<_R0V(OMU}TA38MeLtlA;~v=5YptMLqRm*Q@AZ!Nw{ z*03a@#T?E5&oM84@_%MC)Zm+tb#%Jlq)`%-_XRqqatq;dl5I(qUd*eUpp35w--jZO zU#>>i0dc%w?^#fjy*pj(cWk8>`Td5dh$@WqlAXj14efRK32LbLc1Lz2JenftRZ^ zM)ViWu7@+!vVbg!j|+1|t@h~l zLX+jQ0YX=1tPM5}Hf|t5l}_hW^e_|k+Wa#4Sas^~Ga7`j%kqy&-Q_xE^<36+;9pJa zLLpNE3b<&J3Be5OsP-fcBd?QxvwK}2@m|cf%UxK$L2eXhU^Un;XS*^X2<6qQdx91B zJ9Ms$SSO@X=XBTzTZ>iI5yv#){IUgkqeMRhXr9P|xSE4M#w@fc;$XCxqhh+};VOZE zW4B{z5ys=qXuQ~eR7fXRB7A=m{-PYtmstQtF0xAi15_yH#M{;2U z?*_ur9-V2X;SKescqIQd$~~(MEJM{{$rw$`tF;8p5QqsPC#BhF$u$ML5TT-;=0M;e zJEGeMTLZqsci3}CAPl4iLUIxrlW*3WO;$d>951#%i-P$C9snenFpJaq7E)P8I0}~O z<*PdeNadan#L?of5bp8!t8{6+qREt1LJ-7BFlKXy186#1j2Xz1PMwwDj%n3FkZlmR zW~?#ts;+uoPv1M#;826=9Q@1QES3ulIq>SrXaouVW{&-MlGBTpS;)B@ zPj4o0jD8M4uh?W0*cE`2pe7*=!n!k=gTA}TCO6f4JD;#$zMWi6?`ETjl=NvfiJ)&! zj;{YYnB2_BTNq8px1-xpKH(ibSp-*;+t2>$<3IfP^+%ul(d*Yg|Mca{k6t{!`Rw(p zS3i66>dnu8`tkqQE*YgD48%axvb91F;*~s4)uPyTcXqQ)*?tKA`s0C;-o>SQ3h^T_ zWF83&<2*YIpgFxL#QB~O31f8dah%E12mWnGAr+GayCRcfD^ c517SP+7&7DC9}>cn{`(8*Qun?&2PSX1G^^UyZ`_I literal 0 HcmV?d00001 diff --git a/progs/redbook/Imakefile b/progs/redbook/Imakefile new file mode 100644 index 0000000..23a6b16 --- /dev/null +++ b/progs/redbook/Imakefile @@ -0,0 +1,222 @@ +LOCAL_LIBRARIES = $(XLIB) $(TOP)\lib\Mesaaux.a $(TOP)\lib\Mesaglu.a $(TOP)\lib\MesaGL.a + +INCLUDES = -I$(TOP)\include + +SRCS = accanti.c \ + accnot.c \ + accpersp.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 \ + simple.c \ + smooth.c \ + sphere.c \ + stencil.c \ + stroke.c \ + surface.c \ + tea.c \ + teaambient.c \ + teapots.c \ + texgen.c \ + texturesurf.c \ + trim.c \ + xfont.c + +PROGRAMS = ProgramTargetName(accanti) \ + ProgramTargetName(accnot) \ + ProgramTargetName(accpersp) \ + ProgramTargetName(accum) \ + ProgramTargetName(aim) \ + ProgramTargetName(alpha) \ + ProgramTargetName(alpha3D) \ + ProgramTargetName(anti) \ + ProgramTargetName(antiindex) \ + ProgramTargetName(antipindex) \ + ProgramTargetName(antipoint) \ + ProgramTargetName(antipoly) \ + ProgramTargetName(bezcurve) \ + ProgramTargetName(bezmesh) \ + ProgramTargetName(bezsurf) \ + ProgramTargetName(checker) \ + ProgramTargetName(checker2) \ + ProgramTargetName(chess) \ + ProgramTargetName(clip) \ + ProgramTargetName(colormat) \ + ProgramTargetName(cone) \ + ProgramTargetName(cube) \ + ProgramTargetName(curve) \ + ProgramTargetName(depthcue) \ + ProgramTargetName(disk) \ + ProgramTargetName(dof) \ + ProgramTargetName(dofnot) \ + ProgramTargetName(double) \ + ProgramTargetName(drawf) \ + ProgramTargetName(feedback) \ + ProgramTargetName(fog) \ + ProgramTargetName(fogindex) \ + ProgramTargetName(font) \ + ProgramTargetName(light) \ + ProgramTargetName(linelist) \ + ProgramTargetName(lines) \ + ProgramTargetName(list) \ + ProgramTargetName(list2) \ + ProgramTargetName(maplight) \ + ProgramTargetName(material) \ + ProgramTargetName(mipmap) \ + ProgramTargetName(model) \ + ProgramTargetName(movelight) \ + ProgramTargetName(nurbs) \ + ProgramTargetName(pickdepth) \ + ProgramTargetName(pickline) \ + ProgramTargetName(picksquare) \ + ProgramTargetName(plane) \ + ProgramTargetName(planet) \ + ProgramTargetName(planetup) \ + ProgramTargetName(polys) \ + ProgramTargetName(robot) \ + ProgramTargetName(sccolorlight) \ + ProgramTargetName(scene) \ + ProgramTargetName(scenebamb) \ + ProgramTargetName(sceneflat) \ + ProgramTargetName(select) \ + ProgramTargetName(simple) \ + ProgramTargetName(smooth) \ + ProgramTargetName(sphere) \ + ProgramTargetName(stencil) \ + ProgramTargetName(stroke) \ + ProgramTargetName(surface) \ + ProgramTargetName(tea) \ + ProgramTargetName(teaambient) \ + ProgramTargetName(teapots) \ + ProgramTargetName(texgen) \ + ProgramTargetName(texturesurf) \ + ProgramTargetName(trim) \ + ProgramTargetName(xfont) + +AllTarget($(PROGRAMS)) + +NormalProgramTarget(accanti,accanti.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(accnot,accnot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(accpersp,accpersp.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(accum,accum.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(aim,aim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(alpha,alpha.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(alpha3D,alpha3D.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(anti,anti.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(antiindex,antiindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(antipindex,antipindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(antipoint,antipoint.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(antipoly,antipoly.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(bezcurve,bezcurve.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(bezmesh,bezmesh.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(bezsurf,bezsurf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(checker,checker.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(checker2,checker2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(chess,chess.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(clip,clip.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(colormat,colormat.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(cone,cone.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(cube,cube.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(curve,curve.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(depthcue,depthcue.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(disk,disk.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(dof,dof.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(dofnot,dofnot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(double,double.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(drawf,drawf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(feedback,feedback.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(fog,fog.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(fogindex,fogindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(font,font.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(light,light.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(linelist,linelist.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(lines,lines.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(list,list.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(list2,list2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(maplight,maplight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(material,material.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(mipmap,mipmap.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(model,model.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(movelight,movelight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(nurbs,nurbs.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(pickdepth,pickdepth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(pickline,pickline.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(picksquare,picksquare.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(plane,plane.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(planet,planet.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(planetup,planetup.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(polys,polys.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(robot,robot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(sccolorlight,sccolorlight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(scene,scene.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(scenebamb,scenebamb.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(sceneflat,sceneflat.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(select,select.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(simple,simple.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(smooth,smooth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(sphere,sphere.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(stencil,stencil.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(stroke,stroke.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(surface,surface.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(tea,tea.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(teaambient,teaambient.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(teapots,teapots.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(texgen,texgen.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(texturesurf,texturesurf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(trim,trim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(xfont,xfont.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) + +DependTarget() + + \ No newline at end of file diff --git a/progs/redbook/Makefile.BeOS-R4 b/progs/redbook/Makefile.BeOS-R4 new file mode 100644 index 0000000..f99e8ed --- /dev/null +++ b/progs/redbook/Makefile.BeOS-R4 @@ -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 index 0000000..129918c --- /dev/null +++ b/progs/redbook/Makefile.X11 @@ -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 index 0000000..79c4f67 --- /dev/null +++ b/progs/redbook/Makefile.win @@ -0,0 +1,81 @@ +# Makefile for Win32 + +TOP = .. + +!include "$(TOP)/names.win" + +!include + +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 index 0000000..4c8d5a7 --- /dev/null +++ b/progs/redbook/README @@ -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 index 0000000..7dbc7b4 --- /dev/null +++ b/progs/redbook/aaindex.c @@ -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 +#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 index 0000000..757f0f4 --- /dev/null +++ b/progs/redbook/aapoly.c @@ -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 +#include +#include +#include + +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 index 0000000..f519841 --- /dev/null +++ b/progs/redbook/aargb.c @@ -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 +#include +#include + +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 index 0000000..d45cf9e --- /dev/null +++ b/progs/redbook/accanti.c @@ -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 +#include +#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 index 0000000..46e369a --- /dev/null +++ b/progs/redbook/accpersp.c @@ -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 +#include +#include +#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 index 0000000..6eeb45b --- /dev/null +++ b/progs/redbook/alpha.c @@ -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 +#include + +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 index 0000000..413836e --- /dev/null +++ b/progs/redbook/alpha3D.c @@ -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 +#include +#include + +#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 index 0000000..12aa5f8 --- /dev/null +++ b/progs/redbook/anti.c @@ -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 +#include +#include + +/* 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 index 0000000..5dee440 --- /dev/null +++ b/progs/redbook/bezcurve.c @@ -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 +#include + +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 index 0000000..eb7f0f7 --- /dev/null +++ b/progs/redbook/bezmesh.c @@ -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 +#include + +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 index 0000000..34853b0 --- /dev/null +++ b/progs/redbook/checker.c @@ -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 + +/* 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 index 0000000..90816f2 --- /dev/null +++ b/progs/redbook/clip.c @@ -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 +#include + +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 index 0000000..9db4491 --- /dev/null +++ b/progs/redbook/colormat.c @@ -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 +#include + +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 index 0000000..5ecc628 --- /dev/null +++ b/progs/redbook/cube.c @@ -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 +#include + +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 index 0000000..41af19c --- /dev/null +++ b/progs/redbook/depthcue.c @@ -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 +#include + +/* 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 index 0000000..166ca9e --- /dev/null +++ b/progs/redbook/dof.c @@ -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 +#include +#include +#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 index 0000000..65dfd4b --- /dev/null +++ b/progs/redbook/double.c @@ -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 +#include + +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 index 0000000..5bcccb6 --- /dev/null +++ b/progs/redbook/drawf.c @@ -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 +#include + +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 index 0000000..4981854 --- /dev/null +++ b/progs/redbook/feedback.c @@ -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 +#include +#include + +/* 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 index 0000000..5f8a4e4 --- /dev/null +++ b/progs/redbook/fog.c @@ -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 +#include +#include + +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 index 0000000..b409c95 --- /dev/null +++ b/progs/redbook/fogindex.c @@ -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 +#include + +/* 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 index 0000000..2d92e9b --- /dev/null +++ b/progs/redbook/font.c @@ -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 +#include +#include + +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 index 0000000..516c9ec --- /dev/null +++ b/progs/redbook/hello.c @@ -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 + +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 index 0000000..8e62f5a --- /dev/null +++ b/progs/redbook/image.c @@ -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 +#include +#include + +/* 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 index 0000000..1ec08c8 --- /dev/null +++ b/progs/redbook/jitter.h @@ -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 index 0000000..0eed85e --- /dev/null +++ b/progs/redbook/light.c @@ -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 +#include + +/* 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 index 0000000..b34d4c4 --- /dev/null +++ b/progs/redbook/lines.c @@ -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 +#include + +#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 index 0000000..3b4f44b --- /dev/null +++ b/progs/redbook/list.c @@ -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 +#include + +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 index 0000000..f8d6a91 --- /dev/null +++ b/progs/redbook/material.c @@ -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 +#include + +/* 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 index 0000000..96ef394 --- /dev/null +++ b/progs/redbook/mipmap.c @@ -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 +#include + +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 index 0000000..8411ef3 --- /dev/null +++ b/progs/redbook/model.c @@ -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 +#include + +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 index 0000000..a108cad --- /dev/null +++ b/progs/redbook/movelight.c @@ -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 +#include + +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 index 0000000..513868e --- /dev/null +++ b/progs/redbook/nurbs.c @@ -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 +#include + +#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 index 0000000..c6d50a9 --- /dev/null +++ b/progs/redbook/pickdepth.c @@ -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 +#include +#include + +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 index 0000000..0a12aa0 --- /dev/null +++ b/progs/redbook/picksquare.c @@ -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 +#include +#include + +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 index 0000000..2b0cca0 --- /dev/null +++ b/progs/redbook/plane.c @@ -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 +#include + +/* 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 index 0000000..e13672d --- /dev/null +++ b/progs/redbook/planet.c @@ -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 +#include + +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 index 0000000..42887c9 --- /dev/null +++ b/progs/redbook/polyoff.c @@ -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 +#include +#include + +#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 index 0000000..2983bc5 --- /dev/null +++ b/progs/redbook/polys.c @@ -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 +#include + +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 index 0000000..4e46c85 --- /dev/null +++ b/progs/redbook/quadric.c @@ -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 +#include +#include + +/* 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 index 0000000..94e20ac --- /dev/null +++ b/progs/redbook/robot.c @@ -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 +#include + +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 index 0000000..191f266 --- /dev/null +++ b/progs/redbook/sccolorlight.c @@ -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 +#include + +/* 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 index 0000000..428e8bd --- /dev/null +++ b/progs/redbook/scene.c @@ -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 +#include + +/* 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 index 0000000..a3449b5 --- /dev/null +++ b/progs/redbook/scenebamb.c @@ -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 +#include + +/* 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 index 0000000..5ab2037 --- /dev/null +++ b/progs/redbook/sceneflat.c @@ -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 +#include + +/* 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 index 0000000..4f413e7 --- /dev/null +++ b/progs/redbook/select.c @@ -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 +#include +#include + +/* 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 index 0000000..9d22fc9 --- /dev/null +++ b/progs/redbook/smooth.c @@ -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 +#include + +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 index 0000000..958cf85 --- /dev/null +++ b/progs/redbook/stencil.c @@ -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 +#include + +#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 index 0000000..d8c75c8 --- /dev/null +++ b/progs/redbook/stroke.c @@ -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 +#include +#include + +#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 index 0000000..fb2691e --- /dev/null +++ b/progs/redbook/surface.c @@ -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 + +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 index 0000000..62c091c --- /dev/null +++ b/progs/redbook/teaambient.c @@ -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 +#include + +/* 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 index 0000000..2431cae --- /dev/null +++ b/progs/redbook/teapots.c @@ -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 +#include + +/* + * 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 index 0000000..cef35db --- /dev/null +++ b/progs/redbook/tess.c @@ -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 +#include +#include + +#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 index 0000000..455966a --- /dev/null +++ b/progs/redbook/tesswind.c @@ -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 +#include +#include + +#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 index 0000000..92c226f --- /dev/null +++ b/progs/redbook/texbind.c @@ -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 +#include +#include + +#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 index 0000000..7c1802a --- /dev/null +++ b/progs/redbook/texgen.c @@ -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 +#include +#include + +#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 index 0000000..6f1e853 --- /dev/null +++ b/progs/redbook/texprox.c @@ -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 +#include +#include + +#ifdef GL_VERSION_1_1 + +/* Microsoft OpenGL 1.1's 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 index 0000000..5dc36ec --- /dev/null +++ b/progs/redbook/texsub.c @@ -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 +#include +#include + +#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 index 0000000..89cdbcc --- /dev/null +++ b/progs/redbook/texturesurf.c @@ -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 +#include +#include + +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 index 0000000..7ae4d41 --- /dev/null +++ b/progs/redbook/torus.c @@ -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 +#include +#include +#include + +/* Some 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 index 0000000..26f4748 --- /dev/null +++ b/progs/redbook/trim.c @@ -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 +#include +#include + + +#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 index 0000000..134c361 --- /dev/null +++ b/progs/redbook/unproject.c @@ -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 +#include +#include + +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 index 0000000..b22e723 --- /dev/null +++ b/progs/redbook/varray.c @@ -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 +#include +#include + +#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 index 0000000..c67e04a --- /dev/null +++ b/progs/redbook/wrap.c @@ -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 +#include +#include + +/* 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 index 0000000..4574932 --- /dev/null +++ b/progs/samples/Imakefile @@ -0,0 +1,102 @@ +LOCAL_LIBRARIES = $(XLIB) $(TOP)\lib\glut.a $(TOP)\lib\Mesaglu.a $(TOP)\lib\MesaGL.a + +INCLUDES = -I$(TOP)\include + +SRCS = accum.c \ + bitmap1.c \ + bitmap2.c \ + blendeq.c \ + blendxor.c \ + copy.c \ + cursor.c \ + depth.c \ + eval.c \ + fog.c \ + font.c \ + line.c \ + logo.c \ + nurb.c \ + oglinfo.c \ + olympic.c \ + overlay.c \ + point.c \ + prim.c \ + quad.c \ + select.c \ + shape.c \ + speed.c \ + sphere.c \ + star.c \ + stencil.c \ + stretch.c \ + texture.c \ + tri.c \ + wave.c + +PROGRAMS = ProgramTargetName(accum) \ + ProgramTargetName(bitmap1) \ + ProgramTargetName(bitmap2) \ + ProgramTargetName(blendeq) \ + ProgramTargetName(blendxor) \ + ProgramTargetName(copy) \ + ProgramTargetName(cursor) \ + ProgramTargetName(depth) \ + ProgramTargetName(eval) \ + ProgramTargetName(fog) \ + ProgramTargetName(font) \ + ProgramTargetName(line) \ + ProgramTargetName(logo) \ + ProgramTargetName(nurb) \ + ProgramTargetName(oglinfo) \ + ProgramTargetName(olympic) \ + ProgramTargetName(overlay) \ + ProgramTargetName(point) \ + ProgramTargetName(prim) \ + ProgramTargetName(quad) \ + ProgramTargetName(select) \ + ProgramTargetName(shape) \ + ProgramTargetName(speed) \ + ProgramTargetName(sphere) \ + ProgramTargetName(star) \ + ProgramTargetName(stencil) \ + ProgramTargetName(stretch) \ + ProgramTargetName(texture) \ + ProgramTargetName(tri) \ + ProgramTargetName(wave) + +AllTarget($(PROGRAMS)) + +NormalProgramTarget(accum,accum.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(bitmap1,bitmap1.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(bitmap2,bitmap2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(blendeq,blendeq.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(blendxor,blendxor.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(copy,copy.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(cursor,cursor.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(depth,depth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(eval,eval.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(fog,fog.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(font,font.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(line,line.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(logo,logo.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(nurb,nurb.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(oglinfo,oglinfo.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(olympic,olympic.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(overlay,overlay.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(point,point.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(prim,prim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(quad,quad.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(select,select.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(shape,shape.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(speed,speed.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(sphere,sphere.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(star,star.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(stencil,stencil.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(stretch,stretch.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(texture,texture.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(tri,tri.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) +NormalProgramTarget(wave,wave.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter) + +DependTarget() + + diff --git a/progs/samples/Makefile.BeOS-R4 b/progs/samples/Makefile.BeOS-R4 new file mode 100644 index 0000000..2e1e804 --- /dev/null +++ b/progs/samples/Makefile.BeOS-R4 @@ -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 index 0000000..5c43b7d --- /dev/null +++ b/progs/samples/Makefile.DJ @@ -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 index 0000000..e2393e8 --- /dev/null +++ b/progs/samples/Makefile.X11 @@ -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 index 0000000..f2d5382 --- /dev/null +++ b/progs/samples/Makefile.dja @@ -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 index 0000000..8531588 --- /dev/null +++ b/progs/samples/README @@ -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 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 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 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 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 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 Number of grids. + -size Size of grid. + -wave Height of wave (floating point number). + -frames 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 index 0000000..24dfc07 --- /dev/null +++ b/progs/samples/accum.c @@ -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 +#include +#include +#include + + +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 index 0000000..517d584 --- /dev/null +++ b/progs/samples/bitmap1.c @@ -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 +#include +#include +#include + + +#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 index 0000000..5faac84 --- /dev/null +++ b/progs/samples/bitmap2.c @@ -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 +#include +#include +#include + + +#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 index 0000000..7be5207 --- /dev/null +++ b/progs/samples/blendeq.c @@ -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 +#include +#include +#include + + +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 index 0000000..a46920d --- /dev/null +++ b/progs/samples/blendxor.c @@ -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 +#include +#ifndef _WIN32 +#include +#endif +#include +#include + + +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 index 0000000..391c637 --- /dev/null +++ b/progs/samples/copy.c @@ -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 +#include +#include +#include + + +#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 index 0000000..de8fc58 --- /dev/null +++ b/progs/samples/cursor.c @@ -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 +#include +#include +#include + + +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 index 0000000..afe2ec1 --- /dev/null +++ b/progs/samples/depth.c @@ -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 +#include +#include +#include + + +#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 index 0000000..3ad9c54 --- /dev/null +++ b/progs/samples/eval.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..96534dd --- /dev/null +++ b/progs/samples/fog.c @@ -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 +#include +#include +#include + +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 index 0000000..a0091a6 --- /dev/null +++ b/progs/samples/font.c @@ -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 +#include +#include +#include + + +#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 index 0000000..59e1d62 --- /dev/null +++ b/progs/samples/line.c @@ -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 +#include +#include +#include + + +#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 index 0000000..bf7c8dd --- /dev/null +++ b/progs/samples/loadppm.c @@ -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 index 0000000..8f7de45 --- /dev/null +++ b/progs/samples/logo.c @@ -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 +#include +#include +#include + + +#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 index 0000000..f90c6ee --- /dev/null +++ b/progs/samples/nurb.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..4fe51ef --- /dev/null +++ b/progs/samples/oglinfo.c @@ -0,0 +1,218 @@ +/* oglinfo.c */ + +/* This demo modified by BrianP to accomodate Mesa and test + * the GLX 1.1 functions. + */ + + + +#include +#include +#include +#include +#include + +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 ]\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 index 0000000..db72002 --- /dev/null +++ b/progs/samples/olympic.c @@ -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 +#include +#include +#include +#include + +#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 index 0000000..41bbc26 --- /dev/null +++ b/progs/samples/overlay.c @@ -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 +#include +#include +#include +#include +#include + + +#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 index 0000000..4cb6ad7 --- /dev/null +++ b/progs/samples/point.c @@ -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 +#include +#include +#include + + +#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 index 0000000..388e015 --- /dev/null +++ b/progs/samples/prim.c @@ -0,0 +1,546 @@ +#include +#include +#include +#include + + +#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 index 0000000..8dec28b --- /dev/null +++ b/progs/samples/quad.c @@ -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 +#include +#include +#include + + +#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 index 0000000..0bc7348 --- /dev/null +++ b/progs/samples/rgbtoppm.c @@ -0,0 +1,273 @@ + +/* texture.c - by David Blythe, SGI */ + +/* texload is a simplistic routine for reading an SGI .rgb image file. */ + +#include +#include +#include + +#include + +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; yysize; 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; yysize; 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 \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 index 0000000..5a73a45 --- /dev/null +++ b/progs/samples/select.c @@ -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 +#include +#include +#include +#include +#include + + +#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 index 0000000..d342ee5 --- /dev/null +++ b/progs/samples/shape.c @@ -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 +#include +#include +#include + + +#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 index 0000000..154e85c --- /dev/null +++ b/progs/samples/sphere.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..180585e --- /dev/null +++ b/progs/samples/star.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..e00bbb6 --- /dev/null +++ b/progs/samples/stencil.c @@ -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 +#include +#include +#include +#include + + +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 index 0000000..3f610e7 --- /dev/null +++ b/progs/samples/stretch.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..7ee41ee --- /dev/null +++ b/progs/samples/texture.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..3ded79c --- /dev/null +++ b/progs/samples/tkmap.c @@ -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 index 0000000..7003251 --- /dev/null +++ b/progs/samples/tri.c @@ -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 +#include +#include +#include + + +#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 index 0000000..187c590 --- /dev/null +++ b/progs/samples/wave.c @@ -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 +#include +#include +#include +#include + +#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 index 0000000..ca89d34 --- /dev/null +++ b/progs/util/README @@ -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 index 0000000..4c039a4 --- /dev/null +++ b/progs/util/dumpstate.c @@ -0,0 +1,1959 @@ + +/* + * + * From: Stephane Rehel + * Date: Mon, 31 May 1999 18:40:54 -0400 + * To: Paul Brian + * 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 +#include + +/***************************************************************************/ + +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 + +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 index 0000000..fe9c297 --- /dev/null +++ b/progs/util/errcheck.c @@ -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 +#include +#incldue + + + +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 index 0000000..4c5db13 --- /dev/null +++ b/progs/util/glstate.c @@ -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 +#include +#include +#include +#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 + +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 index 0000000..1aa4d21 --- /dev/null +++ b/progs/util/glstate.h @@ -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 + + +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 index 0000000..8c283f8 --- /dev/null +++ b/progs/util/glutskel.c @@ -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 +#include +#include +#include + + +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 index 0000000..d5ee340 --- /dev/null +++ b/progs/util/idproj.c @@ -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 index 0000000..f5128aa --- /dev/null +++ b/progs/util/imagesgi.cpp @@ -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 +#include +#include +#include +#include + +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; irowStart[i]); + for(i=0; irowSize[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; iheader.ysize; i++) + { + switch(raw->header.zsize) + { + case 1: + ImageSgiRawGetRow(raw, raw->chan0, i, 0); + for(j=0; jheader.xsize; j++) + *(ptr++) = raw->chan0[j]; + break; + case 2: + ImageSgiRawGetRow(raw, raw->chan0, i, 0); + ImageSgiRawGetRow(raw, raw->chan1, i, 1); + for(j=0; jheader.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; jheader.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; jheader.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 index 0000000..e5ecece --- /dev/null +++ b/progs/util/imagesgi.h @@ -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 index 0000000..b61ffb5 --- /dev/null +++ b/progs/util/mwmborder.c @@ -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 +#include + +#define HAVE_MOTIF +#ifdef HAVE_MOTIF + +#include + +#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 index 0000000..7799416 --- /dev/null +++ b/progs/util/readtex.c @@ -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 +#include +#include +#include +#include + + +#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 index 0000000..ebb57ff --- /dev/null +++ b/progs/util/sampleMakefile @@ -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 index 0000000..17f84dc --- /dev/null +++ b/progs/util/showbuffer.c @@ -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 +#include +#include +#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 index 0000000..63533d8 --- /dev/null +++ b/progs/util/showbuffer.h @@ -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 + + + +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 index 0000000..5ad98fd --- /dev/null +++ b/progs/util/winpos.c @@ -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 index 0000000..ab5dce4 --- /dev/null +++ b/progs/xdemos/Makefile.X11 @@ -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 index 0000000..aa56c1c --- /dev/null +++ b/progs/xdemos/descrip.mms @@ -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 index 0000000..c49cd85 --- /dev/null +++ b/progs/xdemos/glxdemo.c @@ -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 +#include +#include +#include + + + +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 index 0000000..e4a62c7 --- /dev/null +++ b/progs/xdemos/glxpixmap.c @@ -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 +#include +#include +#include + + + +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 index 0000000..158e52a --- /dev/null +++ b/progs/xdemos/offset.c @@ -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 +#include +#include +#include +#include +#include + +/*#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 index 0000000..94b9b1f --- /dev/null +++ b/progs/xdemos/shape.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#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;iMaxSides) Sides = MaxSides; + make_shape_mask(dpy, win, Width, Height, Sides); + break; + case XK_Down: + Sides--; + if (Sidesvisual); + 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 index 0000000..13d030a --- /dev/null +++ b/progs/xdemos/vgears.c @@ -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 +#include +#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;iheight) { + 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 index 0000000..f9e3192 --- /dev/null +++ b/progs/xdemos/vindex.c @@ -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 +#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 index 0000000..f0900b6 --- /dev/null +++ b/progs/xdemos/vtest.c @@ -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 +#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 index 0000000..13facba --- /dev/null +++ b/progs/xdemos/xdemo.c @@ -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 +#include +#include +#include +#include +#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 index 0000000..31bfb4b --- /dev/null +++ b/progs/xdemos/xfont.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..d1e489c --- /dev/null +++ b/src/glu/mesa/Makefile.BeOS @@ -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 index 0000000..d664534 --- /dev/null +++ b/src/glu/mesa/Makefile.BeOS-R4 @@ -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 index 0000000..c155aea --- /dev/null +++ b/src/glu/mesa/Makefile.X11 @@ -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 index 0000000..8b1c444 --- /dev/null +++ b/src/glu/mesa/MesaGLU.def @@ -0,0 +1,54 @@ +LIBRARY MESAGLU +DESCRIPTION 'GLU for Windows Mesa' +EXETYPE WINDOWS +CODE MOVEABLE DISCARDABLE +DATA MOVEABLE SINGLE +HEAPSIZE 256000 + +STACKSIZE 4096 + +EXPORTS + gluLookAt + gluOrtho2D + gluPerspective + gluPickMatrix + gluProject + gluUnProject + gluErrorString + gluScaleImage + gluBuild1DMipmaps + gluBuild2DMipmaps + gluNewQuadric + gluDeleteQuadric + gluQuadricDrawStyle + gluQuadricOrientation + gluQuadricNormals + gluQuadricTexture + gluQuadricCallback + gluCylinder + gluSphere + gluDisk + gluPartialDisk + gluNewNurbsRenderer + gluDeleteNurbsRenderer + gluLoadSamplingMatrices + gluNurbsProperty + gluGetNurbsProperty + gluBeginCurve + gluEndCurve + gluNurbsCurve + gluBeginSurface + gluEndSurface + gluNurbsSurface + gluBeginTrim + gluEndTrim + gluPwlCurve + gluNurbsCallback + gluNewTess + gluTessCallback + gluDeleteTess + gluBeginPolygon + gluEndPolygon + gluNextContour + gluTessVertex + gluGetString diff --git a/src/glu/mesa/README1 b/src/glu/mesa/README1 new file mode 100644 index 0000000..7596857 --- /dev/null +++ b/src/glu/mesa/README1 @@ -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 (GLUenum); + ^^^^^^^ +void (GLboolean); +void (void *); +void (void); +void (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: + (GLU_TRAINGLES) + (...) /* 3 vertices of first triangle */ + (...) + (...) + () + (GLU_TRAINGLES) + (...) /* 3 vertices of second triangle */ + (...) + (...) + () + 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 index 0000000..3c99591 --- /dev/null +++ b/src/glu/mesa/README2 @@ -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 index 0000000..3712ca8 --- /dev/null +++ b/src/glu/mesa/all.h @@ -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 +#include +#include +#include +#include +#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 index 0000000..b660f69 --- /dev/null +++ b/src/glu/mesa/descrip.mms @@ -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 index 0000000..2cceb8b --- /dev/null +++ b/src/glu/mesa/glu.c @@ -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 +#include +#include +#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 index 0000000..1d036ee --- /dev/null +++ b/src/glu/mesa/gluP.h @@ -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 index 0000000..24af0ba --- /dev/null +++ b/src/glu/mesa/mipmap.c @@ -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 +#include +#include +#include +#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 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= heightin) i1 = heightin-1; +/* i1 = (i+1) * sy - EPSILON;*/ + alpha = i*sy - i0; + for (j=0;j= 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= heightin) i1 = heightin-1; +/* i1 = (i+1) * sy - EPSILON; */ + for (j=0;j= 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;k0) { + 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>=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 */ + 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;imaxsize) { + 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 index 0000000..372e3ff --- /dev/null +++ b/src/glu/mesa/mms_depend @@ -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 index 0000000..65bc6f8 --- /dev/null +++ b/src/glu/mesa/nurbs.c @@ -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 +#include +#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 index 0000000..fc2b4f7 --- /dev/null +++ b/src/glu/mesa/nurbs.h @@ -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 index 0000000..022818b --- /dev/null +++ b/src/glu/mesa/nurbscrv.c @@ -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 +#include +#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])open_at_begin=GL_TRUE; + } + else + geom_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + color_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + normal_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + texture_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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; + icurve.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 index 0000000..57eb956 --- /dev/null +++ b/src/glu/mesa/nurbssrf.c @@ -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 + * + * 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 +#include +#include +#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;is_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;iunified_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])open_at_begin=GL_TRUE; + } + else + geom_s_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + geom_t_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + color_s_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + color_t_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + normal_s_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + normal_t_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + texture_s_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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])open_at_begin=GL_TRUE; + } + else + texture_t_knot->open_at_begin=GL_FALSE; + if(fabs(knot[t_max]-knot[nknots-1])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(leftt_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; jgeom_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; jgeom_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;is_bezier_cnt;i++) + for(j=0;jt_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;is_bezier_cnt;i++) + for(j=0;jt_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;is_bezier_cnt;i++) + for(j=0;jt_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;is_bezier_cnt;i++) + for(j=0;jt_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 index 0000000..f0f166c --- /dev/null +++ b/src/glu/mesa/nurbsutl.c @@ -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 +#include +#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 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_minunified_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_minknot)[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_minunified_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_minunified_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_minunified_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;inknots;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;inknots;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;inknots;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;inknots;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;jEPSILON) + 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;jnew_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;jEPSILON) + 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= 2) + { + bincoeff = order-1; + s = 1.0-t; + + for(k=0; k constant curve */ + { + for(k=0; k */ + 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 */ + 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 */ + 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;jtmp_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;jtmp_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;jtmp_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;jtmp_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;iauto_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; isurface.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; iparametric_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; isampling_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;iculling==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;iculling==GL_FALSE) + return GL_FALSE; + set_sampling_and_culling(nobj); + + if(dim==3) + { + for(i=0;iculling==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 +#include +#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; + inext , 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;ivertex_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)y - b->y)y - d->y)y - b->y)y - c->y)y - a->y)y - d->y)y - a->y) 0.0) + { + if((fabs(a->x - c->x)x - b->x)x - d->x)x - b->x)x - c->x)x - a->x)x - d->x)x - a->x) 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;icontours; + 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) && (ynext; + } + 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; inext , i++) + { + for(j=0; jnext , 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; + inext) + { + for(v2=hole->vertices , vertex2_cnt=hole->vertex_cnt , j=0; + jnext) + { + /* does edge (v1,v2) intersect any edge of contour */ + for(tmp_vertex=contour->vertices , tmp_vertex_cnt=contour->vertex_cnt , + k=0; + knext , 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; + knext , 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; + knext , 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 index 0000000..32142c9 --- /dev/null +++ b/src/glu/mesa/project.c @@ -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 +#include +#include +#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 index 0000000..4698e79 --- /dev/null +++ b/src/glu/mesa/quadric.c @@ -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 +#include +#include +#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;iDrawStyle==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;iDrawStyle==GLU_FILL) { + GLfloat ds = 1.0 / slices; + GLfloat dt = 1.0 / stacks; + GLfloat t = 0.0; + z = 0.0; + r = baseRadius; + for (j=0;jNormals==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;iTextureFlag) { + /* 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;iDrawStyle==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;iNormals!=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; lOrientation==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; sNormals!=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; loopDrawStyle==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; loopDrawStyle==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; sliceDrawStyle==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; loopOrientation==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 index 0000000..c773fba --- /dev/null +++ b/src/glu/mesa/tess.c @@ -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 +#include +#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 index 0000000..53d673c --- /dev/null +++ b/src/glu/mesa/tess.h @@ -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 index 0000000..1e424c1 --- /dev/null +++ b/src/glu/mesa/tesselat.c @@ -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 +#include +#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 index 0000000..670ddb1 --- /dev/null +++ b/src/glw/GLwDrawA.c @@ -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 +#include +#include +#include +#ifdef __GLX_MOTIF +#include +#include "GLwMDrawAP.h" +#else +#include "GLwDrawAP.h" +#endif +#include +#include + +#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 + "osfHelp:PrimitiveHelp() \n" +#endif + ": glwInput() \n\ + : glwInput() \n\ + : glwInput() \n\ + : glwInput() \n\ + : 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)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; iglwDrawingArea.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; icore.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; icore.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 index 0000000..a62852c --- /dev/null +++ b/src/glw/GLwDrawA.h @@ -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 +#include + +/**************************************************************** + * + * 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 index 0000000..f121701 --- /dev/null +++ b/src/glw/GLwDrawAP.h @@ -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 index 0000000..bdefe92 --- /dev/null +++ b/src/glw/GLwMDrawA.c @@ -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 index 0000000..2e24589 --- /dev/null +++ b/src/glw/GLwMDrawA.h @@ -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 index 0000000..a0a689b --- /dev/null +++ b/src/glw/GLwMDrawAP.h @@ -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 index 0000000..af55a1b --- /dev/null +++ b/src/glw/Makefile @@ -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 index 0000000..545f8b2 --- /dev/null +++ b/src/glw/README @@ -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 ' where 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 index 0000000..c53a3fa --- /dev/null +++ b/src/glw/boilerplate.c @@ -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 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 + + + 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 + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Now some good stuff */ +#include +#include +#include +#include + + +/* 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 index 0000000..e0c23de --- /dev/null +++ b/src/glw/depend @@ -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 index 0000000..e6419b5 --- /dev/null +++ b/src/mesa/Makefile.X11 @@ -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 index 0000000..6e0f21d --- /dev/null +++ b/src/mesa/drivers/allegro/amesa.c @@ -0,0 +1,395 @@ +/* + * 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. + */ + +#include +#include +#include +#include "context.h" +#include "matrix.h" +#include "types.h" +#include "GL/amesa.h" + + +struct amesa_visual + { + GLvisual *GLVisual; /* inherit from GLvisual */ + GLboolean DBFlag; /* double buffered? */ + GLuint Depth; /* bits per pixel ( >= 15 ) */ + }; + + +struct amesa_buffer + { + GLframebuffer *GLBuffer; /* inherit from GLframebuffer */ + GLuint Width, Height; + BITMAP *Screen; + BITMAP *Background; + BITMAP *Active; + }; + + +struct amesa_context + { + GLcontext *GLContext; /* inherit from GLcontext */ + AMesaVisual Visual; + AMesaBuffer Buffer; + GLuint ClearColor; + GLuint CurrentColor; + }; + + +static void setup_dd_pointers(GLcontext *ctx); + + +/**********************************************************************/ +/***** drawing functions *****/ +/**********************************************************************/ + +#define FLIP(context, y) (context->Buffer->Height - (y) - 1) + +#include "allegro/generic.h" +#include "allegro/direct.h" + + +/**********************************************************************/ +/***** 15-bit accelerated drawing funcs *****/ +/**********************************************************************/ + +IMPLEMENT_WRITE_RGBA_SPAN(15, unsigned short) +IMPLEMENT_WRITE_RGB_SPAN(15, unsigned short) +IMPLEMENT_WRITE_MONO_RGBA_SPAN(15, unsigned short) +IMPLEMENT_READ_RGBA_SPAN(15, unsigned short) +IMPLEMENT_WRITE_RGBA_PIXELS(15, unsigned short) +IMPLEMENT_WRITE_MONO_RGBA_PIXELS(15, unsigned short) +IMPLEMENT_READ_RGBA_PIXELS(15, unsigned short) + + +/**********************************************************************/ +/***** 16-bit accelerated drawing funcs *****/ +/**********************************************************************/ + +IMPLEMENT_WRITE_RGBA_SPAN(16, unsigned short) +IMPLEMENT_WRITE_RGB_SPAN(16, unsigned short) +IMPLEMENT_WRITE_MONO_RGBA_SPAN(16, unsigned short) +IMPLEMENT_READ_RGBA_SPAN(16, unsigned short) +IMPLEMENT_WRITE_RGBA_PIXELS(16, unsigned short) +IMPLEMENT_WRITE_MONO_RGBA_PIXELS(16, unsigned short) +IMPLEMENT_READ_RGBA_PIXELS(16, unsigned short) + + +/**********************************************************************/ +/***** 32-bit accelerated drawing funcs *****/ +/**********************************************************************/ + +IMPLEMENT_WRITE_RGBA_SPAN(32, unsigned long) +IMPLEMENT_WRITE_RGB_SPAN(32, unsigned long) +IMPLEMENT_WRITE_MONO_RGBA_SPAN(32, unsigned long) +IMPLEMENT_READ_RGBA_SPAN(32, unsigned long) +IMPLEMENT_WRITE_RGBA_PIXELS(32, unsigned long) +IMPLEMENT_WRITE_MONO_RGBA_PIXELS(32, unsigned long) +IMPLEMENT_READ_RGBA_PIXELS(32, unsigned long) + + +/**********************************************************************/ +/***** Miscellaneous device driver funcs *****/ +/**********************************************************************/ + +static GLboolean set_buffer(GLcontext *ctx, GLenum mode) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + GLboolean ok = GL_TRUE; + + if (mode == GL_FRONT_LEFT) + context->Buffer->Active = context->Buffer->Screen; + + else if (mode == GL_BACK_LEFT) + { + if (context->Buffer->Background) + context->Buffer->Active = context->Buffer->Background; + else + ok = GL_FALSE; + } + + else + ok = GL_FALSE; + + return ok; + } + + +static void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + + *width = context->Buffer->Width; + *height = context->Buffer->Height; + } + + +/**********************************************************************/ +/**********************************************************************/ + +static void setup_dd_pointers(GLcontext *ctx) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + + /* Initialize all the pointers in the driver struct. Do this whenever */ + /* a new context is made current or we change buffers via set_buffer! */ + + ctx->Driver.UpdateState = setup_dd_pointers; + ctx->Driver.SetBuffer = set_buffer; + ctx->Driver.GetBufferSize = get_buffer_size; + + ctx->Driver.Color = set_color_generic; + ctx->Driver.ClearColor = clear_color_generic; + ctx->Driver.Clear = clear_generic; + ctx->Driver.WriteRGBASpan = write_rgba_span_generic; + ctx->Driver.WriteRGBSpan = write_rgb_span_generic; + ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_generic; + ctx->Driver.WriteRGBAPixels = write_rgba_pixels_generic; + ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_generic; + ctx->Driver.ReadRGBASpan = read_rgba_span_generic; + ctx->Driver.ReadRGBAPixels = read_rgba_pixels_generic; + + if (context->Buffer->Active != screen) + { + switch (context->Visual->Depth) + { + case 15: + ctx->Driver.WriteRGBASpan = write_rgba_span_15; + ctx->Driver.WriteRGBSpan = write_rgb_span_15; + ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_15; + ctx->Driver.WriteRGBAPixels = write_rgba_pixels_15; + ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_15; + ctx->Driver.ReadRGBASpan = read_rgba_span_15; + ctx->Driver.ReadRGBAPixels = read_rgba_pixels_15; + break; + + case 16: + ctx->Driver.WriteRGBASpan = write_rgba_span_16; + ctx->Driver.WriteRGBSpan = write_rgb_span_16; + ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_16; + ctx->Driver.WriteRGBAPixels = write_rgba_pixels_16; + ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_16; + ctx->Driver.ReadRGBASpan = read_rgba_span_16; + ctx->Driver.ReadRGBAPixels = read_rgba_pixels_16; + break; + + case 32: + ctx->Driver.WriteRGBASpan = write_rgba_span_32; + ctx->Driver.WriteRGBSpan = write_rgb_span_32; + ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_32; + ctx->Driver.WriteRGBAPixels = write_rgba_pixels_32; + ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_32; + ctx->Driver.ReadRGBASpan = read_rgba_span_32; + ctx->Driver.ReadRGBAPixels = read_rgba_pixels_32; + break; + } + } + } + + +/**********************************************************************/ +/***** AMesa Public API Functions *****/ +/**********************************************************************/ + + +AMesaVisual AMesaCreateVisual(GLboolean dbFlag, GLint depth, + GLint depthSize, GLint stencilSize, GLint accumSize) + { + AMesaVisual visual; + GLbyte redBits, greenBits, blueBits; + + visual = (AMesaVisual)calloc(1, sizeof(struct amesa_visual)); + if (!visual) + return NULL; + + switch (depth) + { + case 15: + redBits = 5; + greenBits = 5; + blueBits = 5; + break; + + case 16: + redBits = 5; + greenBits = 6; + blueBits = 5; + break; + + case 24: case 32: + redBits = 8; + greenBits = 8; + blueBits = 8; + break; + + default: + free(visual); + return NULL; + } + + visual->DBFlag = dbFlag; + visual->Depth = depth; + visual->GLVisual = gl_create_visual(GL_TRUE, /* rgb mode */ + GL_TRUE, /* software alpha */ + dbFlag, /* db_flag */ + GL_FALSE, /* stereo */ + depthSize, /* depth bits */ + stencilSize,/* stencil bits */ + accumSize, /* accum bits */ + 0, /* index bits */ + redBits, greenBits, blueBits, 0); + if (!visual->GLVisual) + { + free(visual); + return NULL; + } + + return visual; + } + + +void AMesaDestroyVisual(AMesaVisual visual) + { + gl_destroy_visual(visual->GLVisual); + free(visual); + } + + +AMesaBuffer AMesaCreateBuffer(AMesaVisual visual, + GLint width, GLint height) + { + AMesaBuffer buffer; + + buffer = (AMesaBuffer)calloc(1, sizeof(struct amesa_buffer)); + if (!buffer) + return NULL; + + buffer->Screen = NULL; + buffer->Background = NULL; + buffer->Active = NULL; + buffer->Width = width; + buffer->Height = height; + + if (visual->DBFlag) + { + buffer->Background = create_bitmap_ex(visual->Depth, width, height); + if (!buffer->Background) + { + free(buffer); + return NULL; + } + } + + buffer->GLBuffer = gl_create_framebuffer(visual->GLVisual); + if (!buffer->GLBuffer) + { + if (buffer->Background) destroy_bitmap(buffer->Background); + free(buffer); + return NULL; + } + + return buffer; + } + + +void AMesaDestroyBuffer(AMesaBuffer buffer) + { + if (buffer->Screen) destroy_bitmap(buffer->Screen); + if (buffer->Background) destroy_bitmap(buffer->Background); + gl_destroy_framebuffer(buffer->GLBuffer); + free(buffer); + } + + +AMesaContext AMesaCreateContext(AMesaVisual visual, + AMesaContext share) + { + AMesaContext context; + GLboolean direct = GL_FALSE; + + context = (AMesaContext)calloc(1, sizeof(struct amesa_context)); + if (!context) + return NULL; + + context->Visual = visual; + context->Buffer = NULL; + context->ClearColor = 0; + context->CurrentColor = 0; + context->GLContext = gl_create_context(visual->GLVisual, + share ? share->GLContext : NULL, + (void*)context, + direct); + if (!context->GLContext) + { + free(context); + return NULL; + } + + return context; + } + + +void AMesaDestroyContext(AMesaContext context) + { + gl_destroy_context(context->GLContext); + free(context); + } + + +GLboolean AMesaMakeCurrent(AMesaContext context, AMesaBuffer buffer) + { + if (context && buffer) + { + set_color_depth(context->Visual->Depth); + if (set_gfx_mode(GFX_AUTODETECT, buffer->Width, buffer->Height, 0, 0) != 0) + return GL_FALSE; + + context->Buffer = buffer; + buffer->Screen = screen; + buffer->Active = buffer->Background ? buffer->Background : screen; + + setup_dd_pointers(context->GLContext); + gl_make_current(context->GLContext, buffer->GLBuffer); + gl_Viewport(context->GLContext, 0, 0, buffer->Width, buffer->Height); + } + else + { + destroy_bitmap(context->Buffer->Screen); + context->Buffer->Screen = NULL; + context->Buffer->Active = NULL; + context->Buffer = NULL; + gl_make_current(NULL, NULL); + } + + return GL_TRUE; + } + + +void AMesaSwapBuffers(AMesaBuffer buffer) + { + if (buffer->Background) + { + blit(buffer->Background, buffer->Screen, + 0, 0, 0, 0, + buffer->Width, buffer->Height); + } + } diff --git a/src/mesa/drivers/allegro/direct.h b/src/mesa/drivers/allegro/direct.h new file mode 100644 index 0000000..3998fc1 --- /dev/null +++ b/src/mesa/drivers/allegro/direct.h @@ -0,0 +1,189 @@ +/* + * 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. + */ + + +#define DESTINATION(BMP, X, Y, TYPE) \ + ({ \ + BITMAP *_bmp = BMP; \ + \ + (TYPE*)(_bmp->line[_bmp->h - (Y) - 1]) + (X); \ + }) + + +#define IMPLEMENT_WRITE_RGBA_SPAN(DEPTH, TYPE) \ +static void write_rgba_span_##DEPTH (const GLcontext *ctx, \ + GLuint n, GLint x, GLint y, \ + const GLubyte rgba[][4], \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + TYPE *d = DESTINATION(context->Buffer->Active, x, y, TYPE); \ + \ + if (mask) \ + { \ + while (n--) \ + { \ + if (mask[0]) d[0] = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]); \ + d++; rgba++; mask++; \ + } \ + } \ + else \ + { \ + while (n--) \ + { \ + d[0] = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]); \ + d++; rgba++; \ + } \ + } \ + } + + +#define IMPLEMENT_WRITE_RGB_SPAN(DEPTH, TYPE) \ +static void write_rgb_span_##DEPTH (const GLcontext *ctx, \ + GLuint n, GLint x, GLint y, \ + const GLubyte rgb[][3], \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + TYPE *d = DESTINATION(context->Buffer->Active, x, y, TYPE); \ + \ + if (mask) \ + { \ + while (n--) \ + { \ + if (mask[0]) d[0] = makecol##DEPTH(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]); \ + d++; rgb++; mask++; \ + } \ + } \ + else \ + { \ + while (n--) \ + { \ + d[0] = makecol##DEPTH(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]); \ + d++; rgb++; \ + } \ + } \ + } + + +#define IMPLEMENT_WRITE_MONO_RGBA_SPAN(DEPTH, TYPE) \ +static void write_mono_rgba_span_##DEPTH (const GLcontext *ctx, \ + GLuint n, GLint x, GLint y, \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + TYPE color = context->CurrentColor; \ + TYPE *d = DESTINATION(context->Buffer->Active, x, y, TYPE); \ + \ + while (n--) \ + { \ + if (mask[0]) d[0] = color; \ + d++; mask++; \ + } \ + } + + +#define IMPLEMENT_READ_RGBA_SPAN(DEPTH, TYPE) \ +static void read_rgba_span_##DEPTH (const GLcontext *ctx, \ + GLuint n, GLint x, GLint y, \ + GLubyte rgba[][4]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + BITMAP *bmp = context->Buffer->Active; \ + TYPE *d = DESTINATION(bmp, x, y, TYPE); \ + \ + while (n--) \ + { \ + rgba[0][RCOMP] = getr##DEPTH(d[0]); \ + rgba[0][GCOMP] = getg##DEPTH(d[0]); \ + rgba[0][BCOMP] = getb##DEPTH(d[0]); \ + rgba[0][ACOMP] = 255; \ + \ + d++; rgba++; \ + } \ + } + + +#define IMPLEMENT_WRITE_RGBA_PIXELS(DEPTH, TYPE) \ +static void write_rgba_pixels_##DEPTH (const GLcontext *ctx, \ + GLuint n, \ + const GLint x[], \ + const GLint y[], \ + const GLubyte rgba[][4], \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + BITMAP *bmp = context->Buffer->Active; \ + \ + while (n--) \ + { \ + if (mask[0]) *DESTINATION(bmp, x[0], y[0], TYPE) = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]); \ + rgba++; x++; y++; mask++; \ + } \ + } + + + +#define IMPLEMENT_WRITE_MONO_RGBA_PIXELS(DEPTH, TYPE) \ +static void write_mono_rgba_pixels_##DEPTH (const GLcontext *ctx, \ + GLuint n, \ + const GLint x[], \ + const GLint y[], \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + TYPE color = context->CurrentColor; \ + BITMAP *bmp = context->Buffer->Active; \ + \ + while (n--) \ + { \ + if (mask[0]) *DESTINATION(bmp, x[0], y[0], TYPE) = color; \ + x++; y++; mask++; \ + } \ + } + + +#define IMPLEMENT_READ_RGBA_PIXELS(DEPTH, TYPE) \ +static void read_rgba_pixels_##DEPTH (const GLcontext *ctx, \ + GLuint n, \ + const GLint x[], \ + const GLint y[], \ + GLubyte rgba[][4], \ + const GLubyte mask[]) \ + { \ + AMesaContext context = (AMesaContext)(ctx->DriverCtx); \ + BITMAP *bmp = context->Buffer->Active; \ + \ + while (n--) \ + { \ + if (mask[0]) \ + { \ + int color = *DESTINATION(bmp, x[0], y[0], TYPE); \ + \ + rgba[0][RCOMP] = getr##DEPTH(color); \ + rgba[0][GCOMP] = getg##DEPTH(color); \ + rgba[0][BCOMP] = getb##DEPTH(color); \ + rgba[0][ACOMP] = 255; \ + } \ + \ + x++; y++; rgba++; mask++; \ + } \ + } + diff --git a/src/mesa/drivers/allegro/generic.h b/src/mesa/drivers/allegro/generic.h new file mode 100644 index 0000000..898a055 --- /dev/null +++ b/src/mesa/drivers/allegro/generic.h @@ -0,0 +1,233 @@ +/* + * 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. + */ + +static void clear_color_generic(GLcontext *ctx, + GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + + context->ClearColor = makecol(red, green, blue); + } + + +static void set_color_generic(GLcontext *ctx, + GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + + context->CurrentColor = makecol(red, green, blue); + } + + +static GLbitfield clear_generic(GLcontext *ctx, + GLbitfield mask, GLboolean all, + GLint x, GLint y, + GLint width, GLint height) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + + if (mask & GL_COLOR_BUFFER_BIT) + { + if (all) + clear_to_color(context->Buffer->Active, context->ClearColor); + else + rect(context->Buffer->Active, + x, y, x+width-1, y+height-1, + context->ClearColor); + } + + return mask & (~GL_COLOR_BUFFER_BIT); + } + + +static void write_rgba_span_generic(const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + + y = FLIP(context, y); + + if (mask) + { + while (n--) + { + if (mask[0]) putpixel(bmp, x, y, makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP])); + x++; mask++; rgba++; + } + } + else + { + while (n--) + { + putpixel(bmp, x, y, makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP])); + x++; rgba++; + } + } + } + + +static void write_rgb_span_generic(const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + + y = FLIP(context, y); + + if (mask) + { + while(n--) + { + if (mask[0]) putpixel(bmp, x, y, makecol(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP])); + x++; mask++; rgb++; + } + } + else + { + while (n--) + { + putpixel(bmp, x, y, makecol(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP])); + x++; rgb++; + } + } + } + + +static void write_mono_rgba_span_generic(const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + int color = context->CurrentColor; + + y = FLIP(context, y); + + if (mask) + { + while(n--) + { + if (mask[0]) putpixel(bmp, x, y, color); + x++; mask++; + } + } + else + { + while(n--) + { + putpixel(bmp, x, y, color); + x++; + } + } + } + + +static void read_rgba_span_generic(const GLcontext *ctx, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + + y = FLIP(context, y); + + while (n--) + { + int color = getpixel(bmp, x, y); + + rgba[0][RCOMP] = getr(color); + rgba[0][GCOMP] = getg(color); + rgba[0][BCOMP] = getb(color); + rgba[0][ACOMP] = 255; + + x++; rgba++; + } + } + + +static void write_rgba_pixels_generic(const GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + + while (n--) + { + if (mask[0]) putpixel(bmp, x[0], FLIP(context, y[0]), makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP])); + x++; y++; mask++; + } + } + + +static void write_mono_rgba_pixels_generic(const GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + int color = context->CurrentColor; + + while (n--) + { + if (mask[0]) putpixel(bmp, x[0], FLIP(context, y[0]), color); + x++; y++; mask++; + } + } + + +static void read_rgba_pixels_generic(const GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + GLubyte rgba[][4], + const GLubyte mask[]) + { + AMesaContext context = (AMesaContext)(ctx->DriverCtx); + BITMAP *bmp = context->Buffer->Active; + + while (n--) + { + if (mask[0]) + { + int color = getpixel(bmp, x[0], FLIP(context, y[0])); + + rgba[0][RCOMP] = getr(color); + rgba[0][GCOMP] = getg(color); + rgba[0][BCOMP] = getb(color); + rgba[0][ACOMP] = 255; + } + + x++; y++; mask++; rgba++; + } + } + diff --git a/src/mesa/drivers/beos/GLView.cpp b/src/mesa/drivers/beos/GLView.cpp new file mode 100644 index 0000000..4332f97 --- /dev/null +++ b/src/mesa/drivers/beos/GLView.cpp @@ -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 +#include +#include +#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 index 0000000..53595f0 --- /dev/null +++ b/src/mesa/drivers/d3d/D3DCAPS.CPP @@ -0,0 +1,251 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver Build 5 */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DHAL.h" +/*===========================================================================*/ +/* Macros. */ +/*===========================================================================*/ +#define SRCBLEND_MAP(gl,d3d,fall) if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwSrcBlendCaps & d3d ) \ + { \ + sprintf( buffer, "SRC Blend: %s -> %s", # gl, # d3d ); \ + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \ + pShared->dwSrcBlendCaps[index] = d3d; \ + } \ + else \ + { \ + sprintf( buffer, "SRC Blend: %s -> %s", # gl, # fall ); \ + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \ + pShared->dwSrcBlendCaps[index] = fall; \ + } +#define DSTBLEND_MAP(gl,d3d,fall) if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwDestBlendCaps & d3d ) \ + { \ + sprintf( buffer, "DST Blend: %s -> %s", # gl, # d3d ); \ + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \ + pShared->dwDestBlendCaps[index] = d3d; \ + } \ + else \ + { \ + sprintf( buffer, "DST Blend: %s -> %s", # gl, # fall ); \ + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \ + pShared->dwDestBlendCaps[index] = fall; \ + } + +/*===========================================================================*/ +/* I use this function to handle the fact that the D3D texture blending and */ +/* OpenGL texture blending functions don't map one to one. Also there is the*/ +/* problem with cards not supporting all the D3D functions. So I use the CAPS*/ +/* of the card to make a table of functions that will have defaults for the */ +/* unsupported functions. */ +/* So first I fill the table with the fallback function then I check to see */ +/* if the card supports the requested function. If it does I replace the */ +/* default thats already in the array. Now order does matter as I used an */ +/* enum type in D3DShared.h so that the mapping would be a little easier. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void AlphaBlendTableHAL( PMESAD3DHAL pHAL ) +{ + PMESAD3DSHARED pShared = &pHAL->shared; + int index; + char buffer[128]; + + DPF(( DBG_FUNC, "AlphaBlendTableHAL();" )); + + /* Make the fallback for the Source blend. */ + for( index = 0; index < 14; index++ ) + { + switch( index ) + { + case s_zero: + SRCBLEND_MAP( GL_ZERO, D3DBLEND_ZERO, D3DBLEND_ONE ); + break; + case s_one: + SRCBLEND_MAP( GL_ONE, D3DBLEND_ONE, D3DBLEND_ONE ); + break; + case s_dst_color: + SRCBLEND_MAP( GL_DST_COLOR, D3DBLEND_DESTCOLOR, D3DBLEND_ONE ); + break; + case s_one_minus_dst_color: + SRCBLEND_MAP( GL_ONE_MINUS_DST_COLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE ); + break; + case s_src_alpha: + SRCBLEND_MAP( GL_SRC_ALPHA, D3DBLEND_SRCALPHA, D3DBLEND_ONE ); + break; + case s_one_minus_src_alpha: + SRCBLEND_MAP( GL_ONE_MINUS_SRC_ALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_ONE ); + break; + case s_dst_alpha: + SRCBLEND_MAP( GL_DST_ALPHA, D3DBLEND_DESTALPHA, D3DBLEND_ONE ); + break; + case s_one_minus_dst_alpha: + SRCBLEND_MAP( GL_ONE_MINUS_DST_ALPHA, D3DBLEND_INVDESTALPHA, D3DBLEND_ONE ); + break; + case s_src_alpha_saturate: + SRCBLEND_MAP( GL_SRC_ALPHA_SATURATE, D3DBLEND_SRCALPHASAT, D3DBLEND_ONE ); + break; + case s_constant_color: + SRCBLEND_MAP( GL_CONSTANT_COLOR, D3DBLEND_SRCCOLOR, D3DBLEND_ONE ); + break; + case s_one_minus_constant_color: + SRCBLEND_MAP( GL_ONE_MINUS_CONSTANT_COLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE ); + break; + case s_constant_alpha: + SRCBLEND_MAP( GL_CONSTANT_ALPHA, D3DBLEND_BOTHSRCALPHA, D3DBLEND_ONE ); + break; + case s_one_minus_constant_alpha: + SRCBLEND_MAP( GL_ONE_MINUS_CONSTANT_ALPHA, D3DBLEND_BOTHINVSRCALPHA, D3DBLEND_ONE ); + break; + } + } + + /* Make the fallback for the Destination blend. */ + for( index = 0; index < 14; index++ ) + { + switch( index ) + { + case d_zero: + DSTBLEND_MAP( GL_ZERO, D3DBLEND_ZERO, D3DBLEND_ONE ); + break; + case d_one: + DSTBLEND_MAP( GL_ONE, D3DBLEND_ONE, D3DBLEND_ONE ); + break; + case d_src_color: + DSTBLEND_MAP( GL_SRC_COLOR, D3DBLEND_SRCCOLOR, D3DBLEND_ONE ); + break; + case d_one_minus_src_color: + DSTBLEND_MAP( GL_ONE_MINUS_SRC_COLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE ); + break; + case d_src_alpha: + DSTBLEND_MAP( GL_SRC_ALPHA, D3DBLEND_SRCALPHA, D3DBLEND_ONE ); + break; + case d_one_minus_src_alpha: + DSTBLEND_MAP( GL_ONE_MINUS_SRC_ALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_ONE ); + break; + case d_dst_alpha: + DSTBLEND_MAP( GL_DST_ALPHA, D3DBLEND_DESTALPHA, D3DBLEND_ONE ); + break; + case d_one_minus_dst_alpha: + DSTBLEND_MAP( GL_ONE_MINUS_DST_ALPHA, D3DBLEND_INVDESTALPHA, D3DBLEND_ONE ); + break; + case d_constant_color: + DSTBLEND_MAP( GL_CONSTANT_COLOR, D3DBLEND_DESTCOLOR, D3DBLEND_ONE ); + break; + case d_one_minus_constant_color: + DSTBLEND_MAP( GL_ONE_MINUS_CONSTANT_COLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE ); + break; + case d_constant_alpha: + DSTBLEND_MAP( GL_CONSTANT_ALPHAR, D3DBLEND_BOTHSRCALPHA, D3DBLEND_ONE ); + break; + case d_one_minus_constant_alpha: + DSTBLEND_MAP( GL_ONE_MINUS_CONSTANT_ALPHA, D3DBLEND_BOTHINVSRCALPHA, D3DBLEND_ONE ); + break; + } + } + + /* Make the fallbacks for the texture functions. */ + for( index = 0; index < 4; index++ ) + { + switch( index ) + { + case d3dtblend_decal: + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_DECAL" )); + pShared->dwTexFunc[index] = D3DTBLEND_DECAL; + } + else + { + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_MODULATE" )); + pShared->dwTexFunc[index] = D3DTBLEND_MODULATE; + } + else + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_ADD" )); + pShared->dwTexFunc[index] = D3DTBLEND_ADD; + } + } + break; + case d3dtblend_decalalpha: + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECALALPHA ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPHA -> D3DTBLEND_DECALALPHA" )); + pShared->dwTexFunc[index] = D3DTBLEND_DECALALPHA; + } + else + { + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPA -> D3DTBLEND_DECAL" )); + pShared->dwTexFunc[index] = D3DTBLEND_DECAL; + } + else + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPHA -> D3DTBLEND_ADD" )); + pShared->dwTexFunc[index] = D3DTBLEND_ADD; + } + } + break; + case d3dtblend_modulate: + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_MODULATE" )); + pShared->dwTexFunc[index] = D3DTBLEND_MODULATE; + } + else + { + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATEALPHA ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_MODULATEALPHA" )); + pShared->dwTexFunc[index] = D3DTBLEND_MODULATEALPHA; + } + else if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_DECAL" )); + pShared->dwTexFunc[index] = D3DTBLEND_DECAL; + } + else + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_ADD" )); + pShared->dwTexFunc[index] = D3DTBLEND_ADD; + } + } + break; + case d3dtblend_modulatealpha: + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATEALPHA ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_MODULATEALPHA" )); + pShared->dwTexFunc[index] = D3DTBLEND_MODULATEALPHA; + } + else + { + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_MODULATE" )); + pShared->dwTexFunc[index] = D3DTBLEND_MODULATE; + } + else if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL ) + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_DECALE" )); + pShared->dwTexFunc[index] = D3DTBLEND_DECAL; + } + else + { + DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_ADD" )); + pShared->dwTexFunc[index] = D3DTBLEND_ADD; + } + } + break; + } + } +} + + \ 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 index 0000000..12f4b4e --- /dev/null +++ b/src/mesa/drivers/d3d/D3DHAL.H @@ -0,0 +1,69 @@ +/*===========================================================================*/ +/* */ +/* 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_HAL_INC +#define _D3D_HAL_INC + +/*===========================================================================*/ +/* Includes. */ +/*===========================================================================*/ +#include +#include +#include +#include +#include +#include "D3DShared.h" +#include "D3DTextureMgr.h" +#include "Debug.h" +/*===========================================================================*/ +/* Defines. */ +/*===========================================================================*/ +#define DX_RESTORE(ps) if ( (ps) && (ps)->IsLost() ) (ps)->Restore(); +/*===========================================================================*/ +/* Type defines. */ +/*===========================================================================*/ +typedef struct _d3d_hal_struct +{ + MESAD3DSHARED shared; + + GUID guid; + LPDIRECTDRAW lpDD; + LPDIRECTDRAW4 lpDD4; + LPDIRECT3D3 lpD3D3; + LPDIRECT3DDEVICE3 lpD3DDevice; + D3DDEVICEDESC D3DHWDevDesc; + LPDIRECTDRAWSURFACE4 lpDDSPrimary, + lpDDSRender, + lpDDSZbuffer; + LPDIRECT3DVIEWPORT3 lpViewport; + LPDIRECTDRAWCLIPPER lpClipper; + DDPIXELFORMAT ddpf, + ddpfZBuffer; + PTM_OBJECT pTMList; + +} MESAD3DHAL, *PMESAD3DHAL; +/*===========================================================================*/ +/* External function prototypes. */ +/*===========================================================================*/ +extern BOOL InitTMgrHAL( PMESAD3DHAL pHAL ); +extern void TermTMgrHAL( PMESAD3DHAL pHAL ); +extern void AlphaBlendTableHAL( PMESAD3DHAL pHAL ); + +extern void Solve8BitChannelPixelFormat( DDPIXELFORMAT *pddpf, PPIXELINFO pPixel ); +extern char *ErrorStringD3D( HRESULT hr ); +extern void FatalShutDown( PMESAD3DHAL pHAL ); +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +extern char *errorMsg; + +#endif + + \ 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 index 0000000..ba78916 --- /dev/null +++ b/src/mesa/drivers/d3d/D3DInit.cpp @@ -0,0 +1,891 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver Build 5 */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DHAL.h" +/*===========================================================================*/ +/* Local function prototypes. */ +/*===========================================================================*/ +static void DestroyAllSurfaces( PMESAD3DHAL pHAL ); +static void DestroyDevice( PMESAD3DHAL pHAL ); +static void DestroyInterfaces( PMESAD3DHAL pHAL ); + +HRESULT WINAPI EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid ); +HRESULT CALLBACK EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid ); +HRESULT CALLBACK EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc, void *pVoid ); +/*===========================================================================*/ +/* Globals. */ +/*===========================================================================*/ +//char *errorMsg; +/*===========================================================================*/ +/* This function is responable for allocating the actual MESAD3DHAL struct. */ +/* Each Mesa context will have its own MESAD3DHAL struct so its like a mini */ +/* context to some extent. All one time allocations/operations get done here.*/ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +extern "C" PMESAD3DSHARED InitHAL( HWND hwnd ) +{ + PMESAD3DHAL pHAL; + ULONG rc; + + DPF(( DBG_FUNC, "InitHAL();" )); + DPF(( DBG_CNTX_INFO, "hwnd: %d", hwnd )); + + /* Allocate the structure and zero it out. */ + pHAL = (PMESAD3DHAL)ALLOC( sizeof(MESAD3DHAL) ); + if ( pHAL == NULL ) + { + RIP( pHAL, "InitHAL->", "Memory Allocation" ); + return (PMESAD3DSHARED)NULL; + } + memset( pHAL, 0, sizeof(MESAD3DHAL) ); + + /* Get the texture manager going. */ + rc = InitTMgrHAL( pHAL ); + if ( rc == FALSE ) + { + RIP( pHAL, "InitTMgrHAL->", "Failed" ); + return (PMESAD3DSHARED)NULL; + } + + /* Fill in the window parameters if we can. */ + pHAL->shared.hwnd = hwnd; + + /* Parse the user's enviroment variables to generate a debug mask. */ + ReadDBGEnv(); + + return (PMESAD3DSHARED)pHAL; +} +/*===========================================================================*/ +/* This function will unload all the resources that the MESAD3DHAL struct */ +/* has bound to it. The actual structure itself will be freed. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void TermHAL( PMESAD3DSHARED pShared ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + + DPF(( DBG_FUNC, "TermHAL();" )); + + /* Check for an empty wrapper structure. */ + if ( pHAL == NULL ) + return; + + /* Kill this texture manager. */ + TermTMgrHAL( pHAL ); + + /* Kill any DDraw stuff if exists. */ + DestroyDevice( pHAL ); + DestroyAllSurfaces( pHAL ); + DestroyInterfaces( pHAL ); + + FREE( pHAL ); +} +/*===========================================================================*/ +/* This function is used to init and resize the rendering surface as the two*/ +/* are almost the same. First the device and all the surfaces are destoryed */ +/* if they already exist. Next we create a OffScreen rendering surface and */ +/* save some pixelformat info to do color convertions. Next we start to take */ +/* care of getting the most out of the hardware. I use bHardware to determine*/ +/* the state of the device we found in the device enumeration. The enum proc*/ +/* will try for hardware first. I next use a bForceSW to make the enum proc */ +/* choose a software device. So I will try some combinations with HW first */ +/* until I feel I have to set the bForceSW and call this function again. If */ +/* this function is called with no width or height then use the internals. */ +/* NOTE: The worst case is that all will be in SW (RGBDevice) and really */ +/* I should forget the whole thing and fall back to a DDraw span type*/ +/* rendering but what is the point. This way I always know I have a */ +/* D3DDevice and that makes things easier. I do impliment the span */ +/* rendering function for stuff that I haven't done support for such */ +/* as points and lines. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE */ +/*===========================================================================*/ +extern "C" BOOL CreateHAL( PMESAD3DSHARED pShared ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + DDSURFACEDESC2 ddsd2; + D3DDEVICEDESC D3DSWDevDesc; + DDSCAPS2 ddscaps; + DWORD dwCoopFlags, + dwWidth, + dwHeight; + ULONG rc; + + DPF(( DBG_FUNC, "CreateHAL();" )); + +#define InitDDSD2(f) memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); \ + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); \ + ddsd2.dwFlags = f; + + if ( pHAL == NULL ) + return FALSE; + + /* Use the internal rectangle struct. */ + dwWidth = pShared->rectW.right - pShared->rectW.left; + dwHeight = pShared->rectW.bottom - pShared->rectW.top; + + DPF(( DBG_CNTX_INFO, "Width: %d Height: %d", dwWidth, dwHeight )); + + /* The dimensions might still be the same so just leave. */ + if ( (dwWidth == pShared->dwWidth) && (dwHeight == pShared->dwHeight) ) + { + DPF(( DBG_CNTX_WARN, "Context size hasn't changed" )); + return TRUE; + } + + /* If one of the dimensions are zero then leave. WM_SIZE should get us back here. */ + if ( (dwWidth == 0) || (dwHeight == 0) ) + return TRUE; + + /* Save the renders dimensions. */ + pShared->dwWidth = dwWidth; + pShared->dwHeight = dwHeight; + + DPF(( DBG_CNTX_INFO, "Creating Context:\n cx:%d cy:%d", pShared->dwWidth, pShared->dwHeight )); + + /*=================================*/ + /* Create all required interfaces. */ + /*=================================*/ + + /* Kill any DDraw stuff if exists. */ + DestroyDevice( pHAL ); + DestroyAllSurfaces( pHAL ); + DestroyInterfaces( pHAL ); + + /* Create a instance of DDraw using the Primary display driver. */ + rc = DirectDrawCreate( NULL, &pHAL->lpDD, NULL ); + if( FAILED(rc) ) + { + RIP( pHAL, "DirectDrawCreate->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Get the DDraw4 interface. */ + rc = pHAL->lpDD->QueryInterface( IID_IDirectDraw4, (void **)&pHAL->lpDD4 ); + if( FAILED(rc) ) + { + RIP( pHAL, "QueryInterface (IID_IDirectDraw4) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Get the Direct3D3 interface. */ + rc = pHAL->lpDD4->QueryInterface( IID_IDirect3D3, (void **)&pHAL->lpD3D3 ); + if( FAILED(rc) ) + { + RIP( pHAL, "QueryInterface (IID_IDirect3D3) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Set the Cooperative level. NOTE: we need to know if we are FS at this point.*/ + dwCoopFlags = (pShared->bWindow == TRUE) ? DDSCL_NORMAL : (DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + rc = pHAL->lpDD4->SetCooperativeLevel( pShared->hwnd, dwCoopFlags ); + if ( FAILED(rc) ) + { + RIP( pHAL, "SetCooperativeLevel->", ErrorStringD3D(rc) ); + return FALSE; + } + + /*==================================================================*/ + /* Get the best device we can and note whether its hardware or not. */ + /*==================================================================*/ + pShared->bForceSW = FALSE; + pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL ); + pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice ); + DPF(( DBG_CNTX_INFO, "bHardware: %s", (pShared->bHardware) ? "TRUE" : "FALSE" )); + DPF(( DBG_CNTX_INFO, "bWindowed: %s", (pShared->bWindow) ? "TRUE" : "FALSE" )); + + /*========================================================================*/ + /* HARDWARE was found. */ + /*========================================================================*/ + if ( pShared->bHardware == TRUE ) + { + /*===================================*/ + /* HARDWARE -> Z-BUFFER. */ + /*===================================*/ + + /* Get a Z-Buffer pixelformat. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); + rc = pHAL->lpD3D3->EnumZBufferFormats( pHAL->guid, EnumZBufferHook, (VOID*)&ddsd2.ddpfPixelFormat ); + if ( FAILED(rc) ) + { + RIP( pHAL, "EnumZBufferFormatsl->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Setup our request structure for the Z-buffer surface. */ + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY; + ddsd2.dwWidth = dwWidth; + ddsd2.dwHeight = dwHeight; + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSZbuffer, NULL ); + if ( !FAILED(rc) ) + { + DPF(( DBG_CNTX_INFO, "HW ZBuffer" )); + + /*===================================*/ + /* HARDWARE -> Z-BUFFER -> FLIPABLE */ + /*===================================*/ + if ( pShared->bWindow == FALSE ) + { + InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT ); + ddsd2.dwBackBufferCount = 1; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL ); + if ( FAILED(rc) ) + { + /* Make sure we try the next fall back. */ + DPF(( DBG_CNTX_WARN, "HW Flip/Complex not available" )); + pHAL->lpDDSPrimary = NULL; + } + else + { + /* Get the back buffer that was created. */ + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender ); + if ( FAILED(rc) ) + { + DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> HW Flip/Complex" )); + + /* Make sure we try the next fall back. */ + pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } + else + { + /* I have had problems when a complex surface comes back */ + /* with the back buffer being created in SW. Not sure why */ + /* or how this is possable but I'm checking for it here. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); + DX_RESTORE( pHAL->lpDDSRender ); + rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 ); + if ( FAILED(rc) ) + { + RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* If the surface is in VID then we are happy with are Flipable. */ + if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM ) + { + pShared->bFlipable = TRUE; + DPF(( DBG_CNTX_INFO, "HW Flip/Complex!" )); + } + else + { + /* Kill this setup. */ + pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } + } + } + } + + /*===================================*/ + /* HARDWARE -> Z-BUFFER -> BLT */ + /*===================================*/ + if ( pHAL->lpDDSPrimary == NULL ) + { + pShared->bFlipable = FALSE; + + /* Create the Primary (front buffer). */ + InitDDSD2( DDSD_CAPS ); + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL ); + if ( FAILED(rc) ) + { + /* This is an error as we should be able to do this at minimum. */ + RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Create the Render (back buffer). */ + InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ); + ddsd2.dwWidth = dwWidth; + ddsd2.dwHeight = dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL ); + if ( FAILED(rc) ) + { + DPF(( DBG_CNTX_WARN, "Failed HW Offscreen surface" )); + + /* Make sure we try the next fall back. */ + pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } + else + { + /* Might as well check here too see if this surface is in */ + /* hardware. If nothing else just to be consistant. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); + DX_RESTORE( pHAL->lpDDSRender ); + rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 ); + if ( FAILED(rc) ) + { + RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* If the surface is in VID then we are happy. */ + if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM ) + { + /* Create a clipper object so that DDraw will be able to blt windows that */ + /* have been clipped by the screen or other windows. */ + pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL ); + pHAL->lpClipper->SetHWnd( 0, pShared->hwnd ); + pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper ); + pHAL->lpClipper->Release(); + DPF(( DBG_CNTX_INFO, "HW RENDER surface" )); + } + else + { + /* Kill this setup. */ + pHAL->lpDDSRender->Release(); + pHAL->lpDDSRender = NULL; + pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } + } + } + + /*===================================*/ + /* Create D3DDEVICE -> HARDWARE. */ + /*===================================*/ + if ( pHAL->lpDDSZbuffer && pHAL->lpDDSPrimary && pHAL->lpDDSRender ) + { + DX_RESTORE( pHAL->lpDDSRender ); + DX_RESTORE( pHAL->lpDDSZbuffer ); + + rc = pHAL->lpDDSRender->AddAttachedSurface( pHAL->lpDDSZbuffer ); + if ( FAILED(rc) ) + { + RIP( pHAL, "AddAttachedSurface (ZBUFFER) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DHALDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL ); + if ( rc != D3D_OK ) + { + DPF(( DBG_CNTX_WARN, "Failed HW Device" )); + pHAL->lpD3DDevice = NULL; + } + else + { + DPF(( DBG_CNTX_INFO, "HW Device" )); + } + } + } + } + + /*========================================================================*/ + /* SOFTWARE fallback. */ + /*========================================================================*/ + if ( pHAL->lpD3DDevice == NULL ) + { + DPF(( DBG_CNTX_INFO, "SW fallback :(" )); + + /* Make sure we have no surfaces allocated. Just incase. */ + DestroyAllSurfaces( pHAL ); + + /* Get a software device. */ + pShared->bFlipable = FALSE; + pShared->bForceSW = TRUE; + pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL ); + pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice ); + + /*===================================*/ + /* SOFTWARE -> Z-BUFFER. */ + /*===================================*/ + + /*===================================*/ + /* SOFTWARE -> Z-BUFFER -> FLIPABLE */ + /*===================================*/ + if ( pShared->bWindow == FALSE ) + { + InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT ); + ddsd2.dwBackBufferCount = 1; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); + ddsd2.ddpfPixelFormat.dwFlags = (DDPF_RGB | DDPF_ALPHAPIXELS); + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL ); + if ( FAILED(rc) ) + { + DPF(( DBG_CNTX_WARN, "Failed SW Flip/Complex" )); + + /* Make sure we try the next fall back. */ + pHAL->lpDDSPrimary = NULL; + } + else + { + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender ); + if ( FAILED(rc) ) + { + /* Make sure we try the next fall back. */ + DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> SW Flip/Complex" )); + pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } + else + { + DPF(( DBG_CNTX_INFO, "SW Flip/Complex" )); + pShared->bFlipable = TRUE; + } + } + } + + /*===================================*/ + /* SOFTWARE -> Z-BUFFER -> BLT */ + /*===================================*/ + if ( pHAL->lpDDSPrimary == NULL ) + { + /* Create the Primary (front buffer). */ + InitDDSD2( DDSD_CAPS ); + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL ); + if ( FAILED(rc) ) + { + /* This is an error as we should be able to do this at minimum. */ + RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Create the Render (back buffer). */ + InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ); + ddsd2.dwWidth = dwWidth; + ddsd2.dwHeight = dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); + ddsd2.ddpfPixelFormat.dwFlags = (DDPF_RGB | DDPF_ALPHAPIXELS); + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL ); + if ( FAILED(rc) ) + { + /* That was our last hope. */ + RIP( pHAL, "CreateSurface (RENDER) ->", ErrorStringD3D(rc) ); + return FALSE; + } + else + { + DPF(( DBG_CNTX_INFO, "SW RENDER surface" )); + + /* Create a clipper object so that DDraw will be able to blt windows that */ + /* have been clipped by the screen or other windows. */ + pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL ); + pHAL->lpClipper->SetHWnd( 0, pShared->hwnd ); + pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper ); + pHAL->lpClipper->Release(); + } + } + + /*===================================*/ + /* Create D3DDEVICE -> SOFTWARE. */ + /*===================================*/ + if ( pHAL->lpDDSPrimary && pHAL->lpDDSRender ) + { + DX_RESTORE( pHAL->lpDDSRender ); + rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DRGBDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL ); + if ( rc != D3D_OK ) + { + /* That was our last hope. */ + RIP( pHAL, "CreateDevice (IID_IDirect3DRGBDevice) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + DPF(( DBG_CNTX_INFO, "SW Device" )); + } + } + + /*==============================================================================*/ + /* Get a copy of the render pixelformat so that wgl.c can call GetPixelInfoD3D. */ + /*==============================================================================*/ + memset( &pHAL->ddpf, 0, sizeof(DDPIXELFORMAT) ); + pHAL->ddpf.dwSize = sizeof( DDPIXELFORMAT ); + rc = pHAL->lpDDSRender->GetPixelFormat( &pHAL->ddpf ); + if ( FAILED(rc) ) + { + RIP( pHAL, "GetPixelFormat ->", ErrorStringD3D(rc) ); + return FALSE; + } + DebugPixelFormat( "Using OFFSCREEN", &pHAL->ddpf ); + DebugPixelFormat( "Using ZBUFFER", &ddsd2.ddpfPixelFormat ); + + /* Get a copy of what the D3DDevice supports for later use. */ + memset( &D3DSWDevDesc, 0, sizeof(D3DDEVICEDESC) ); + memset( &pHAL->D3DHWDevDesc, 0, sizeof(D3DDEVICEDESC) ); + D3DSWDevDesc.dwSize = sizeof( D3DDEVICEDESC ); + pHAL->D3DHWDevDesc.dwSize = sizeof( D3DDEVICEDESC ); + rc = pHAL->lpD3DDevice->GetCaps( &pHAL->D3DHWDevDesc, &D3DSWDevDesc ); + if ( FAILED(rc) ) + { + RIP( pHAL, "GetCaps ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Get a copy of the pixel convertion stuff for direct buffer access. */ + Solve8BitChannelPixelFormat( &pHAL->ddpf, &pShared->pixel ); + AlphaBlendTableHAL( pHAL ); + + /* We must prime the Begin/End scene for SwapBuffers to work. */ + rc = pHAL->lpD3DDevice->BeginScene(); + if ( FAILED(rc) ) + { + RIP( pHAL, "BeginScene ->", ErrorStringD3D(rc) ); + return FALSE; + } + +#undef InitDDSD2 + + return TRUE; +} +/*===========================================================================*/ +/* This function will make sure a viewport is created and set for the device*/ +/* in the supplied structure. If a rect is supplied then it will be used for*/ +/* the viewport otherwise the current setting in the strucute will be used. */ +/* Note that the rect is relative to the window. So left/top must be 0,0 to */ +/* use the whole window else there is scissoring going down. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +extern "C" BOOL SetViewportHAL( PMESAD3DSHARED pShared, RECT *pRect, float minZ, float maxZ ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + D3DVIEWPORT2 vdData; + ULONG rc; + POINT pt; + + DPF(( DBG_FUNC, "SetViewportHAL();" )); + + /* Make sure we have enough info. */ + if ( !pHAL || !pHAL->lpDDSPrimary || !pHAL->lpD3DDevice ) + { + DPF(( DBG_CNTX_WARN, "SetViewport() -> NULL Pointer" )); + return FALSE; + } + + /* TODO: this is just a temp fix to stop redundant changes. */ + if ( pRect && + (pShared->rectV.left == pRect->left) && + (pShared->rectV.right == pRect->right) && + (pShared->rectV.top == pRect->top) && + (pShared->rectV.bottom == pRect->bottom) ) + { + DPF(( DBG_CNTX_WARN, "Redundant viewport" )); + return TRUE; + } + + DPF(( DBG_CNTX_INFO, "Current Viewport:" )); + DPF(( DBG_CNTX_INFO, "x: %d y: %d", pShared->rectV.left, pShared->rectV.top )); + DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pShared->rectV.right-pShared->rectV.left), (pShared->rectV.bottom-pShared->rectV.top) )); + DPF(( DBG_CNTX_INFO, "New Viewport:" )); + DPF(( DBG_CNTX_INFO, "x: %d y: %d", pRect->left, pRect->top )); + DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pRect->right-pRect->left), (pRect->bottom-pRect->top) )); + + /* Update the current viewport rect if one is supplied. */ + if ( pRect ) + memcpy( &pShared->rectV, pRect, sizeof(RECT) ); + + /* Build the request structure. */ + memset( &vdData, 0, sizeof(D3DVIEWPORT2) ); + vdData.dwSize = sizeof(D3DVIEWPORT2); + vdData.dwX = pShared->rectV.left; + vdData.dwY = pShared->rectV.top; + vdData.dwWidth = (pShared->rectV.right - pShared->rectV.left); + vdData.dwHeight = (pShared->rectV.bottom - pShared->rectV.top); + + if ( !vdData.dwWidth || !vdData.dwHeight ) + { + GetClientRect( pShared->hwnd, &pShared->rectW ); + pt.x = pt.y = 0; + ClientToScreen( pShared->hwnd, &pt ); + OffsetRect( &pShared->rectW, pt.x, pt.y); + vdData.dwX = pShared->rectW.left; + vdData.dwY = pShared->rectW.top; + vdData.dwWidth = (pShared->rectW.right - pShared->rectW.left); + vdData.dwHeight = (pShared->rectW.bottom - pShared->rectW.top); + memcpy( &pShared->rectV, &pShared->rectW, sizeof(RECT) ); + } + + // The dvClipX, dvClipY, dvClipWidth, dvClipHeight, dvMinZ, + // and dvMaxZ members define the non-normalized post-perspective + // 3-D view volume which is visible to the viewer. In most cases, + // dvClipX is set to -1.0 and dvClipY is set to the inverse of + // the viewport's aspect ratio on the target surface, which can be + // calculated by dividing the dwHeight member by dwWidth. Similarly, + // the dvClipWidth member is typically 2.0 and dvClipHeight is set + // to twice the aspect ratio set in dwClipY. The dvMinZ and dvMaxZ + // are usually set to 0.0 and 1.0. + vdData.dvClipX = -1.0f; + vdData.dvClipWidth = 2.0f; + vdData.dvClipY = 1.0f; + vdData.dvClipHeight = 2.0f; + vdData.dvMaxZ = maxZ; + vdData.dvMinZ = minZ; + + DPF(( DBG_CNTX_INFO, "zMin: %f zMax: %f", minZ, maxZ )); + + /* I'm going to destroy the viewport everytime as when we size we will */ + /* have a new D3DDevice. As this area doesn't need to be fast... */ + if ( pHAL->lpViewport ) + { + DPF(( DBG_CNTX_INFO, "DeleteViewport" )); + + pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport ); + rc = pHAL->lpViewport->Release(); + pHAL->lpViewport = NULL; + } + + rc = pHAL->lpD3D3->CreateViewport( &pHAL->lpViewport, NULL ); + if ( rc != D3D_OK ) + { + DPF(( DBG_CNTX_ERROR, "CreateViewport Failed" )); + return FALSE; + } + + /* Update the device with the new viewport. */ + pHAL->lpD3DDevice->AddViewport( pHAL->lpViewport ); + pHAL->lpViewport->SetViewport2( &vdData ); + pHAL->lpD3DDevice->SetCurrentViewport( pHAL->lpViewport ); + + return TRUE; +} +/*===========================================================================*/ +/* */ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +HRESULT WINAPI EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid ) +{ + DDSURFACEDESC2 *pddsd2 = (DDSURFACEDESC2 *)pVoid; + + DPF(( DBG_FUNC, "EnumSurfacesHook();" )); + + if ( (lpDDSDesc->ddpfPixelFormat.dwFlags == pddsd2->ddpfPixelFormat.dwFlags) && (lpDDSDesc->ddsCaps.dwCaps == pddsd2->ddsCaps.dwCaps) ) + { + /* Save the pixelformat now so that we know we have one. */ + memcpy( pddsd2, lpDDSDesc, sizeof(DDSURFACEDESC2) ); + + return D3DENUMRET_CANCEL; + } + + return D3DENUMRET_OK; +} +/*===========================================================================*/ +/* This is the callback proc to get a Z-Buffer. Thats it. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +HRESULT CALLBACK EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid ) +{ + DDPIXELFORMAT *pddpfChoice = (DDPIXELFORMAT *)pVoid; + + DPF(( DBG_FUNC, "EnumZBufferHook();" )); + + /* If this is ANY type of depth-buffer, stop. */ + if( pddpf->dwFlags == DDPF_ZBUFFER ) + { + /* Save the pixelformat now so that we know we have one. */ + memcpy( pddpfChoice, pddpf, sizeof(DDPIXELFORMAT) ); + + /* I feel if the hardware supports this low then lets use it. Could get ugly. */ + if( pddpf->dwZBufferBitDepth >= 8 ) + { + return D3DENUMRET_CANCEL; + } + } + + return D3DENUMRET_OK; +} +/*===========================================================================*/ +/* This function handles the callback for the D3DDevice enumeration. Good */ +/* god who's idea was this? The D3D wrapper has two variable related to what*/ +/* kind of device we want and have. First we have a Bool that is set if we */ +/* have allocated a HW device. We always look for the HW device first. The */ +/* other variable is used to force SW. If we have run into a case that we */ +/* want to fallback to SW then we set this. We will fallback if we cannot */ +/* texture in video memory (among others). */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +HRESULT CALLBACK EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc, void *pVoid ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pVoid; + LPD3DDEVICEDESC pChoice = lpD3DHWDesc; + + DPF(( DBG_FUNC, "EnumDeviceHook();" )); + + /* Determine if which device description is valid. */ + if ( pChoice->dcmColorModel == 0 ) + pChoice = lpD3DHELDesc; + + /* Make sure we always have a GUID. */ + memcpy( &pHAL->guid, lpGuid, sizeof(GUID) ); + + /* This controls whether we will except HW or not. */ + if ( pHAL->shared.bForceSW == TRUE ) + { + return (pChoice == lpD3DHELDesc) ? D3DENUMRET_CANCEL : D3DENUMRET_OK; + } + + /* Always try for hardware. */ + if ( pChoice == lpD3DHWDesc ) + { + return D3DENUMRET_CANCEL; + } + + return D3DENUMRET_OK; +} +/*===========================================================================*/ +/* This function will destroy any and all surfaces that this context has */ +/* allocated. If there is a clipper object then it will also be destoryed as*/ +/* it is part of the Primary Surface. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void DestroyAllSurfaces( PMESAD3DHAL pHAL ) +{ + LONG refCount; + + DPF(( DBG_FUNC, "DestroyAllSurfaces();" )); + + DX_RESTORE( pHAL->lpDDSPrimary ); + DX_RESTORE( pHAL->lpDDSRender ); + DX_RESTORE( pHAL->lpDDSZbuffer); + + if ( pHAL->lpDDSRender ) + { + pHAL->lpDDSRender->Unlock( NULL ); + + /* If this isn't a Flipable surface then we must clean up the render. */ + if ( pHAL->shared.bFlipable == FALSE) + { + if ( pHAL->lpDDSZbuffer ) + { + DPF(( DBG_CNTX_INFO, "Remove attached surfaces from RENDER" )); + pHAL->lpDDSRender->DeleteAttachedSurface( 0, NULL ); + } + + DPF(( DBG_CNTX_INFO, "Release RENDER" )); + refCount = pHAL->lpDDSRender->Release(); + pHAL->lpDDSRender = NULL; + } + } + + if ( pHAL->lpDDSZbuffer ) + { + DPF(( DBG_CNTX_INFO, "Release ZBuffer" )); + pHAL->lpDDSZbuffer->Unlock( NULL ); + refCount = pHAL->lpDDSZbuffer->Release(); + pHAL->lpDDSZbuffer = NULL; + } + + if ( pHAL->lpClipper ) + { + DPF(( DBG_CNTX_INFO, "Release Clipper" )); + refCount = pHAL->lpClipper->Release(); + pHAL->lpClipper = NULL; + } + + if ( pHAL->lpDDSPrimary ) + { + pHAL->lpDDSPrimary->Unlock( NULL ); + + DPF(( DBG_CNTX_INFO, "Release PRIMARY" )); + refCount = pHAL->lpDDSPrimary->Release(); + pHAL->lpDDSPrimary = NULL; + } +} +/*===========================================================================*/ +/* This function will destroy the current D3DDevice and any resources that */ +/* belong to it. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void DestroyDevice( PMESAD3DHAL pHAL ) +{ + LONG refCount; + + DPF(( DBG_FUNC, "DestroyDevice();" )); + + /* Kill the D3D stuff if exists. */ + if ( pHAL->lpViewport ) + { + DPF(( DBG_CNTX_INFO, "Delete Viewport" )); + pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport ); + + DPF(( DBG_CNTX_INFO, "Release Viewport" )); + refCount = pHAL->lpViewport->Release(); + pHAL->lpViewport = NULL; + } + + if ( pHAL->lpD3DDevice != NULL ) + { + DPF(( DBG_CNTX_INFO, "Release D3DDevice" )); + refCount = pHAL->lpD3DDevice->EndScene(); + refCount = pHAL->lpD3DDevice->Release(); + pHAL->lpD3DDevice = NULL; + } +} +/*===========================================================================*/ +/* This function will destroy the current D3DDevice and any resources that */ +/* belong to it. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void DestroyInterfaces( PMESAD3DHAL pHAL ) +{ + LONG refCount; + + DPF(( DBG_FUNC, "DestroyInterfaces();" )); + + if ( pHAL->lpD3D3 != NULL ) + { + DPF(( DBG_CNTX_INFO, "Release Direct3D3" )); + refCount = pHAL->lpD3D3->Release(); + pHAL->lpD3D3 = NULL; + } + + if ( pHAL->lpDD4 != NULL ) + { + DPF(( DBG_CNTX_INFO, "Release DDraw4" )); + refCount = pHAL->lpDD4->Release(); + pHAL->lpDD4 = NULL; + } + + if ( pHAL->lpDD != NULL ) + { + DPF(( DBG_CNTX_INFO, "Release DDraw" )); + refCount = pHAL->lpDD->Release(); + pHAL->lpDD = NULL; + } +} +/*===========================================================================*/ +/* This function will first send (not post) a message to the client window */ +/* that this context is using. The client will respond by unbinding itself */ +/* and binding the 'default' context. This allows the API to be supported */ +/* until the window can be destroyed. Finally we post the quit message to */ +/* the client in hopes to end the application. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void FatalShutDown( PMESAD3DHAL pHAL ) +{ + /* Whip this baby in too try and support the API until we die... */ + if ( pHAL ) + SendMessage( pHAL->shared.hwnd, UM_FATALSHUTDOWN, 0L, 0L ); + + /* Close the client application down. */ + PostQuitMessage( 0 ); +} + diff --git a/src/mesa/drivers/d3d/D3DMESA.H b/src/mesa/drivers/d3d/D3DMESA.H new file mode 100644 index 0000000..907f69f --- /dev/null +++ b/src/mesa/drivers/d3d/D3DMESA.H @@ -0,0 +1,85 @@ +/*===========================================================================*/ +/* */ +/* 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_H +#define D3D_MESA_H +/*===========================================================================*/ +/* Includes. */ +/*===========================================================================*/ +#include +#include +#include +#include "matrix.h" +#include "context.h" +#include "types.h" +#include "vb.h" +#include "D3DShared.h" +#include "Debug.h" +#include "NULLProcs.h" +/*===========================================================================*/ +/* Macros. */ +/*===========================================================================*/ +#define FLIP(h,y) (h-y) +/*===========================================================================*/ +/* Magic numbers. */ +/*===========================================================================*/ +/*===========================================================================*/ +/* Type defines. */ +/*===========================================================================*/ +struct __extensions__ +{ + PROC proc; + char *name; +}; + +typedef GLbitfield (*ClearPROC)( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); +typedef void (*WSpanRGBPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ); +typedef void (*WSpanRGBAPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ); +typedef void (*WSpanRGBAMonoPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ); +typedef void (*WPixelsRGBAPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] ); +typedef void (*WPixelsRGBAMonoPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] ); +typedef void (*RSpanRGBAPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ); +typedef void (*RPixelsRGBAPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ); + +typedef struct D3D_mesa_context +{ + PMESAD3DSHARED pShared; + + GLcontext *gl_ctx; /* The core GL/Mesa context */ + GLvisual *gl_visual; /* Describes the buffers */ + GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ + + HDC hdc; + WNDPROC hOldProc; + + UCHAR rClear, /* Current clear colors. */ + gClear, + bClear, + aClear, + rCurrent, /* Current rendering colors. */ + gCurrent, + bCurrent, + aCurrent; + + struct D3D_mesa_context *next; + +} D3DMESACONTEXT, *PD3DMESACONTEXT; +/*===========================================================================*/ +/* Extern function prototypes. */ +/*===========================================================================*/ +extern void gl_Viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ); +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +extern D3DTLVERTEX D3DTLVertices[(VB_MAX*6)]; + +#endif + + \ 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 index 0000000..b87b3ab --- /dev/null +++ b/src/mesa/drivers/d3d/D3DRaster.cpp @@ -0,0 +1,214 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DHAL.h" +/*===========================================================================*/ +/* This function clears the context bound to the supplied shared context. */ +/* The function takes the D3D flags D3DCLEAR_TARGET, D3DCLEAR_STENCIL and */ +/* D3DCLEAR_ZBUFFER. Set bAll to TRUE for a full clear else supply the coord*/ +/* of the rect to be cleared relative to the window. The color is always a */ +/* 32bit value (RGBA). Fill in the z-value and stencil if needed. */ +/* */ +/* TODO: this can be redone to be called by Mesa directly. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void ClearHAL( PMESAD3DSHARED pShared, DWORD dwFlags, BOOL bAll, int x, int y, int cx, int cy, DWORD dwColor, float zv, DWORD dwStencil ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + D3DRECT d3dRect; + +#ifdef D3D_DEBUG + HRESULT rc; + + DPF(( DBG_FUNC, "CleaHAL();" )); + + /* Make sure we have enough info. */ + if ( (pHAL == NULL) || (pHAL->lpViewport == NULL) ) + return; +#endif + + if ( bAll ) + { + /* I assume my viewport is valid. */ + d3dRect.lX1 = pShared->rectV.left; + d3dRect.lY1 = pShared->rectV.top; + d3dRect.lX2 = pShared->rectV.right; + d3dRect.lY2 = pShared->rectV.bottom; + } + else + { + d3dRect.lX1 = pShared->rectV.left + x; + d3dRect.lY1 = pShared->rectV.top + y; + d3dRect.lX2 = d3dRect.lX1 + cx; + d3dRect.lY2 = d3dRect.lY1 + cy; + } + +#ifdef D3D_DEBUG + rc = pHAL->lpViewport->Clear2( 1, &d3dRect, dwFlags, dwColor, zv, dwStencil ); + if ( FAILED(rc) ) + { + RIP( pHAL, "Clear2 ->", ErrorStringD3D(rc) ); + } +#else + pHAL->lpViewport->Clear2( 1, &d3dRect, dwFlags, dwColor, zv, dwStencil ); +#endif +} +/*===========================================================================*/ +/* Well this is the guts of it all. Here we rasterize the primitives that */ +/* are in their final form. OpenGL has done all the lighting, transfomations*/ +/* and clipping at this point. */ +/* */ +/* TODO: I'm not sure if I want to bother to check for errors on this call. */ +/* The overhead kills me... */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void DrawPrimitiveHAL( PMESAD3DSHARED pShared, D3DPRIMITIVETYPE dptPrimitiveType, D3DTLVERTEX *pVertices, DWORD dwCount ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + +#ifdef D3D_DEBUG + HRESULT rc; + + DPF(( DBG_FUNC, "DrawPrimitveHAL();" )); + + /* Make sure we have enough info. */ + if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) ) + return; + + DPF(( DBG_PRIM_INFO, "DP( %d )", dwCount )); + + rc = pHAL->lpD3DDevice->DrawPrimitive( dptPrimitiveType, + D3DFVF_TLVERTEX, + (LPVOID)pVertices, + dwCount, + (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) ); + if ( FAILED(rc) ) + { + RIP( pHAL, "DrawPrimitive ->", ErrorStringD3D(rc) ); + } +#else + pHAL->lpD3DDevice->DrawPrimitive( dptPrimitiveType, + D3DFVF_TLVERTEX, + (LPVOID)pVertices, + dwCount, + (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) ); +#endif +} +/*===========================================================================*/ +/* This call will handle the swapping of the buffers. Now I didn't bother */ +/* to support single buffered so this will be used for glFlush() as its all */ +/* the same. So first we do an EndScene as we are always considered to be in*/ +/* a BeginScene because when we leave we do a BeginScene. Now note that when*/ +/* the context is created in the first place we do a BeginScene also just to */ +/* get things going. The call will use either Flip/blt based on the type of */ +/* surface was created for rendering. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void SwapBuffersHAL( PMESAD3DSHARED pShared ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + +#ifdef D3D_DEBUG + HRESULT rc; + + DPF(( DBG_FUNC, "SwapBuffersHAL();" )); + DPF(( DBG_ALL_PROFILE, "=================SWAP===================" )); + + /* Make sure we have enough info. */ + if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) ) + return; + + /* Make sure we have enough info. */ + if ( pHAL->lpDDSPrimary != NULL ) + { + rc = pHAL->lpD3DDevice->EndScene(); + if ( FAILED(rc) ) + { + RIP( pHAL, "EndScene ->", ErrorStringD3D(rc) ); + } + + if ( pShared->bFlipable ) + { + DPF(( DBG_CNTX_PROFILE, "Swap->FLIP" )); + rc = pHAL->lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); + } + else + { + DPF(( DBG_CNTX_PROFILE, "Swap->Blt" )); + rc = pHAL->lpDDSPrimary->Blt( &pShared->rectW, pHAL->lpDDSRender, NULL, DDBLT_WAIT, NULL ); + } + if ( FAILED(rc) ) + { + RIP( pHAL, "Blt (RENDER/PRIMARY) ->", ErrorStringD3D(rc) ); + } + + rc = pHAL->lpD3DDevice->BeginScene(); + if ( FAILED(rc) ) + { + RIP( pHAL, "BeginScene ->", ErrorStringD3D(rc) ); + } + } +#else + pHAL->lpD3DDevice->EndScene(); + + if ( pShared->bFlipable ) + pHAL->lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); + else + pHAL->lpDDSPrimary->Blt( &pShared->rectW, pHAL->lpDDSRender, NULL, DDBLT_WAIT, NULL ); + + pHAL->lpD3DDevice->BeginScene(); + +#endif +} +/*===========================================================================*/ +/* This function is a very thin wrapper for the D3D call 'SetRenderState'. */ +/* Using this function requires all the types to be defined by including the */ +/* D3D header file. */ +/* */ +/* TODO: would be much better to get ride of all these calls per VBRender. */ +/* I feel I should get this call into SetRenderStates() the RenderVB. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void SetStateHAL( PMESAD3DSHARED pShared, DWORD dwType, DWORD dwState ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + +#ifdef D3D_DEBUG + HRESULT rc; + + DPF(( DBG_FUNC, "SetStateHAL();" )); + + /* Make sure we have enough info. */ + if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) ) + return; + + rc = pHAL->lpD3DDevice->SetRenderState( (D3DRENDERSTATETYPE)dwType, dwState ); + if ( FAILED(rc) ) + { + RIP( pHAL, "SetRenderState ->", ErrorStringD3D(rc) ); + } + +#else + pHAL->lpD3DDevice->SetRenderState( (D3DRENDERSTATETYPE)dwType, dwState ); +#endif +} + + + + + + + + + \ 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 index 0000000..cc629e2 --- /dev/null +++ b/src/mesa/drivers/d3d/D3DShared.h @@ -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 +#include +/*===========================================================================*/ +/* 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 index 0000000..7321eeb --- /dev/null +++ b/src/mesa/drivers/d3d/D3DTEXT.CPP @@ -0,0 +1,577 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "d3dText.h" + +/*============================================================================= + + 1 + ------ + | | + 6 | | 2 + | 7 | + ------ + | | + 5 | | 3 + | | + ------ + 4 + + TL_0 TR_0 +TLL TL_1 TR_1 TRR + +MLL_0 ML_0 MR_0 MRR_0 +MLL_1 ML_1 MR_1 MRR_1 + +BLL BL_0 BR_0 BRR + BL_1 BR_1 + +=============================================================================*/ + +#define TLL 0 +#define TRR 1 +#define TL_0 2 +#define TL_1 3 +#define TR_0 4 +#define TR_1 5 + +#define MLL_0 6 +#define MLL_1 7 +#define MRR_0 8 +#define MRR_1 9 + +#define ML_0 10 +#define ML_1 11 +#define MR_0 12 +#define MR_1 13 + +#define BL_0 14 +#define BL_1 15 +#define BR_0 16 +#define BR_1 17 +#define BLL 18 +#define BRR 19 + +#define BIT1 0x00000001 +#define BIT2 0x00000002 +#define BIT3 0x00000004 +#define BIT4 0x00000008 +#define BIT5 0x00000010 +#define BIT6 0x00000020 +#define BIT7 0x00000040 + +#define TOP BIT4 +#define MIDDLE BIT7 +#define BOTTOM BIT1 +#define TLEFT BIT5 +#define BLEFT BIT6 +#define LEFT (TLEFT|BLEFT) +#define TRIGHT BIT3 +#define BRIGHT BIT2 +#define RIGHT (TRIGHT|BRIGHT) +#define ALL 0xFFFFFFFF + +/*===========================================================================*/ +/* This is the static array that will map the ASCII value of the character */ +/* being draw to the bit mask that will be scan converted to the LED display.*/ +/*===========================================================================*/ +DWORD textBitMasks[] = +{ + 0xFFFFFFFF, // 000 + 0xFFFFFFFF, // 001 + 0xFFFFFFFF, // 002 + 0xFFFFFFFF, // 003 + 0xFFFFFFFF, // 004 + 0xFFFFFFFF, // 005 + 0xFFFFFFFF, // 006 + 0xFFFFFFFF, // 007 + 0xFFFFFFFF, // 008 + 0xFFFFFFFF, // 009 + 0xFFFFFFFF, // 010 + 0xFFFFFFFF, // 011 + 0xFFFFFFFF, // 012 + 0xFFFFFFFF, // 013 + 0xFFFFFFFF, // 014 + 0xFFFFFFFF, // 015 + 0xFFFFFFFF, // 016 + 0xFFFFFFFF, // 017 + 0xFFFFFFFF, // 018 + 0xFFFFFFFF, // 019 + 0xFFFFFFFF, // 020 + 0xFFFFFFFF, // 021 + 0xFFFFFFFF, // 022 + 0xFFFFFFFF, // 023 + 0xFFFFFFFF, // 024 + 0xFFFFFFFF, // 025 + 0xFFFFFFFF, // 026 + 0xFFFFFFFF, // 027 + 0xFFFFFFFF, // 028 + 0xFFFFFFFF, // 029 + 0xFFFFFFFF, // 030 + 0XFFFFFFFF, // 031 + 0x00000000, // 032 'SPC' + 0xFFFFFFFF, // 033 + 0xFFFFFFFF, // 034 + 0xFFFFFFFF, // 035 + 0xFFFFFFFF, // 036 + 0xFFFFFFFF, // 037 + 0xFFFFFFFF, // 038 + 0xFFFFFFFF, // 039 + 0xFFFFFFFF, // 040 + 0xFFFFFFFF, // 041 + 0xFFFFFFFF, // 042 + 0xFFFFFFFF, // 043 + 0xFFFFFFFF, // 044 + 0xFFFFFFFF, // 045 + 0xFFFFFFFF, // 046 + 0xFFFFFFFF, // 047 + (ALL &~ MIDDLE), // 048 '0' + (RIGHT), // 049 '1' + (ALL &~ TLEFT &~ BRIGHT), // 050 '2' + (ALL &~ LEFT), // 051 '3' + (TLEFT | MIDDLE | RIGHT), // 052 '4' + (ALL &~ TRIGHT &~ BLEFT), // 053 '5' + (ALL &~ TRIGHT), // 054 '6' + (TOP | RIGHT), // 055 '7' + (ALL), // 056 '8' + (ALL &~ BOTTOM &~ BLEFT), // 057 '9' + 0xFFFFFFFF, // 058 + 0xFFFFFFFF, // 059 + 0xFFFFFFFF, // 060 + 0XFFFFFFFF, // 061 + 0xFFFFFFFF, // 062 + 0xFFFFFFFF, // 063 + 0xFFFFFFFF, // 064 + (ALL &~ BOTTOM), // 065 'A' + (ALL), // 066 'B' + (TOP | LEFT | BOTTOM), // 067 'C' + (ALL &~ MIDDLE), // 068 'D' + (ALL &~ RIGHT), // 069 'E' + (LEFT | TOP | MIDDLE), // 070 'F' + 0x00000000, // 071 'G' + (ALL &~ TOP &~ BOTTOM), // 072 'H' + (RIGHT), // 073 'I' + (RIGHT | BOTTOM), // 074 'J' + 0x00000000, // 075 'K' + (LEFT | BOTTOM), // 076 'L' + 0x00000000, // 088 'M' + 0x00000000, // 089 'N' + (ALL &~ MIDDLE), // 090 'O' + (ALL &~ BRIGHT &~ BOTTOM),// 091 'P' + 0x00000000, // 092 'Q' + 0x00000000, // 093 'R' + (ALL &~ TRIGHT &~ BLEFT), // 094 'S' + 0X00000000, // 095 'T' + (LEFT | RIGHT | BOTTOM), // 096 'U' + 0x00000000, // 097 'V' + 0x00000000, // 098 'W' + 0x00000000, // 099 'X' + 0x00000000, // 1000 'Z' + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 100 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 104 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 108 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 112 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 116 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 120 + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF // 124 +}; + +#define CT 1.0f +#define CX 7.0f +#define CY 13.0f +#define CM ((CY-(CT*3.0f))/2.0f) + +float lCoords[][2] = +{ + /* Top outsides. */ + { 0, (CY-CT) }, + { CX, (CY-CT) }, + + /* Top Line. */ + { CT, CY }, + { CT, (CY-CT) }, + { (CX-CT), CY }, + { (CX-CT), (CY-CT) }, + + /* Middle outsides. */ + { 0.0f, (CT+CM+CT) }, + { 0.0f, (CT+CM) }, + { CX, (CT+CM+CT) }, + { CX, (CT+CM) }, + + /* Middle Line. */ + { CT, (CT+CM+CT) }, + { CT, (CT+CM) }, + { (CX-CT), (CT+CM+CT) }, + { (CX-CT), (CT+CM) }, + + /* Bottom line. */ + { CT, CT }, + { CT, 0.0f }, + { (CX-CT), CT }, + { (CX-CT), 0.0f }, + + /* Bottom outsides. */ + { 0.0f, CT}, + { CX, CT } +}; + +static int ConvertCharacter( char *c, int cIndex, PD3DFONTMETRICS pfntMetrics ); + +D3DTLVERTEX TextVertices[MAX_VERTICES]; +/*===========================================================================*/ +/* When we attach I will zero out the whole D3D vertex buffer I'm using for */ +/* the text. This way I don't need to set all the redundant values. I also */ +/* set all the oow values to 1 as I will be doing direct rendering. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +extern "C" BOOL InitD3DText( void ) +{ + int index; + + /* Set the D3D Vertex Buffer up once so we don't do redundant changes. */ + memset( &TextVertices[0], 0, sizeof(TextVertices) ); + for( index = 0; index < MAX_VERTICES; index++ ) + TextVertices[index].rhw = D3DVAL( 1.0 ); + + return TRUE; +} +/*===========================================================================*/ +/* This function takes a single character and draw it using the supplied */ +/* fontmetrics structure. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void d3dTextDrawString( char *pszString, int x, int y, PD3DFONTMETRICS pfntMetrics ) +{ + int cIndex, + nIndex, + index; + float cWidth = CX, + cHeight = CY; + + /* Find the max width/height of a character and add the spacing so */ + /* that we can use this value to calculate the x,y of the character.*/ + cWidth = (cWidth * pfntMetrics->fntXScale) + pfntMetrics->fntXSpacing; + cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing; + + /* Walk the string. This must be NULL terminated. */ + for( cIndex = 0, nIndex = 0; *pszString; pszString++, cIndex = nIndex, x++ ) + { + /* Convert the character and get the index into the text vertex buffer. */ + nIndex = ConvertCharacter( &pszString[0], cIndex, pfntMetrics ); + if ( (nIndex - cIndex) > 2 ) + { + /* Modify the text vertex buffer based on the fntMetrics structure. */ + for( index = cIndex; index < nIndex; index++ ) + { + /* Scale the character. */ + TextVertices[index].sx *= pfntMetrics->fntXScale; + TextVertices[index].sy *= pfntMetrics->fntYScale; + + /* Move the character. */ + TextVertices[index].sx += (cWidth*x); + TextVertices[index].sy += (cHeight*y); + + /* Set the color. */ + TextVertices[index].color = pfntMetrics->dwColor; + } + } + } + + if ( nIndex < 3 ) + return; + + /* Set the states that slim things down. */ + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE , FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); + + /* Blast them baby... */ + pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, + D3DFVF_TLVERTEX, + (LPVOID)&TextVertices[0], + nIndex, + (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) ); +} +/*===========================================================================*/ +/* This function takes a single character and draw it directly to the screen*/ +/* unsing the supplied fntMetrics structure. The character will be drawn at */ +/* the supplied x,y. The x,y position is relative to the top left and uses */ +/* the spacing in the fntMetrics structure. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void d3dTextDrawCharacter( char *c, int x, int y, PD3DFONTMETRICS pfntMetrics ) +{ + int cIndex = 0, + index; + float cWidth = CX, + cHeight = CY; + + /* Convert the character and get the index into the text vertex buffer. */ + cIndex = ConvertCharacter( c, 0, pfntMetrics ); + if ( cIndex < 3 ) + return; + + /* Find the max width/height of a character and add the spacing so */ + /* that we can use this value to calculate the x,y of the character.*/ + cWidth = (cWidth * pfntMetrics->fntXScale) + pfntMetrics->fntXSpacing; + cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing; + + /* Modify the text vertex buffer based on the fntMetrics structure. */ + for( index = 0; index < cIndex; index++ ) + { + /* Scale the character. */ + TextVertices[index].sx *= pfntMetrics->fntXScale; + TextVertices[index].sy *= pfntMetrics->fntYScale; + + /* Move the character. */ + TextVertices[index].sx += (cWidth*x); + TextVertices[index].sy += (cHeight*y); + + /* Set the color. */ + TextVertices[index].color = pfntMetrics->dwColor; + } + + + /* Set the states that slim things down. */ + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE , FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); + pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); + + /* Blast them baby... */ + pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, + D3DFVF_TLVERTEX, + (LPVOID)&TextVertices[0], + cIndex, + (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) ); +} +/*===========================================================================*/ +/* This function takes a single character and draw it using the supplied */ +/* fontmetrics structure. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static int ConvertCharacter( char *c, int cIndex, PD3DFONTMETRICS pfntMetrics ) +{ + DWORD asciiChar = (int)(*c); + + /* Handle the TOP line. */ + if ( textBitMasks[asciiChar] & BIT1 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[TL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TL_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] ); + } + + /* Handle the TOP/BOTTOM RIGHT lines. */ + // if ( textBitMasks[index] & (BIT2|BIT3) ) + if ( 1 == 0 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TRR][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BRR][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BRR][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BR_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] ); + } + else + { + if ( textBitMasks[asciiChar] & BIT2 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TRR][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MRR_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MRR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MRR_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MRR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TR_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TR_1][1] ); + } + if ( textBitMasks[asciiChar] & BIT3 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MRR_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MRR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BRR][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BRR][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BRR][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BR_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MR_1][1] ); + } + } + + /* Handle the TOP/BOTTOM LEFT lines. */ + // if ( textBitMasks[asciiChar] & (BIT5|BIT6) ) + if ( 1 == 0 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TL_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BLL][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BLL][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] ); + } + else + { + if ( textBitMasks[asciiChar] & BIT5 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[MLL_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MLL_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[ML_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BLL][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[BLL][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MLL_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MLL_1][1] ); + } + if ( textBitMasks[asciiChar] & BIT6 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TLL][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TL_1][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TL_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[ML_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[ML_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MLL_0][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[MLL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] ); + TextVertices[cIndex++].sy = D3DVAL( lCoords[TLL][1] ); + } + } + + /* Handle the MIDDLE line. */ + if ( textBitMasks[asciiChar] & BIT7 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] ); + } + + /* Handle the BOTTOM line. */ + if ( textBitMasks[asciiChar] & BIT4 ) + { + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BR_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BR_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_1][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_1][1] ); + TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] ); + TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] ); + } + + return cIndex; +} + +#undef CM +#undef CY +#undef CX +#undef CT + +#undef TLL +#undef TRR +#undef TL_0 +#undef TL_1 +#undef TR_0 +#undef TR_1 + +#undef MLL_0 +#undef MLL_1 +#undef MRR_0 +#undef MRR_1 + +#undef ML_0 +#undef ML_1 +#undef MR_0 +#undef MR_1 + +#undef BL_0 +#undef BL_1 +#undef BR_0 +#undef BR_1 +#undef BLL +#undef BRR + +#undef BIT1 +#undef BIT2 +#undef BIT3 +#undef BIT4 +#undef BIT5 +#undef BIT6 +#undef BIT7 + +#undef TOP +#undef MIDDLE +#undef BOTTOM +#undef TLEFT +#undef BLEFT +#undef LEFT +#undef TRIGHT +#undef BRIGHT +#undef RIGHT +#undef ALL + \ 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 index 0000000..9375e51 --- /dev/null +++ b/src/mesa/drivers/d3d/D3DTextureMgr.cpp @@ -0,0 +1,948 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DHAL.h" +/*===========================================================================*/ +/* Local function prototypes. */ +/*===========================================================================*/ +static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels ); +static BOOL LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj ); +static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ); +static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ); +HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext ); +/*===========================================================================*/ +/* This function will simply set the top of stack to NULL. I only used it */ +/* just incase I want to add something later. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +BOOL InitTMgrHAL( PMESAD3DHAL pHAL ) +{ + DPF(( DBG_FUNC, "InitTMgrHAL();" )); + + /* Be clean my friend. */ + pHAL->pTMList = NULL; + + return TRUE; +} +/*===========================================================================*/ +/* This function will walk the Texture Managers linked list and destroy all */ +/* surfaces (SYSTEM/VIDEO). The texture objects themselves also will be */ +/* freed. */ +/* NOTE: this is per/context. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void TermTMgrHAL( PMESAD3DHAL pHAL ) +{ + DPF(( DBG_FUNC, "TermTMgrHAL();" )); + + if ( pHAL && pHAL->pTMList ) + { + /* Destroy the surface and remove the TMO from the stack. */ + while( DestroyTextureObject(pHAL,NULL) ); + + /* Be clean my friend. */ + pHAL->pTMList = NULL; + } +} +/*===========================================================================*/ +/* This function is a HACK as I don't know how I can disable a texture with-*/ +/* out booting it out. Is there know state change? */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void DisableTMgrHAL( PMESAD3DSHARED pShared ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + + DPF(( DBG_FUNC, "DisableTMgrHAL();" )); + + /* Check too see that we have a valid context. */ + if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL) ) + { + DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" )); + return; + } + + // TODO: This is a hack to shut off textures. + pHAL->lpD3DDevice->SetTexture( 0, NULL ); +} +/*===========================================================================*/ +/* This function is the only entry into the TextureManager that Mesa/wgl */ +/* will see. It uses a dwAction to specify what we are doing. I did this as*/ +/* depending on the cards resources the action taken can change. */ +/* When this function is called we will always search the Texture Managers */ +/* linked list (per context remember) and try and find a structure that has */ +/* the same dwName. If we have a match we pull it out of the list and put it*/ +/* at the top of the list (TOL). If we don't find one then we create a struc*/ +/* and put it a TOL. This TOL idea makes for some caching as we will always */ +/* destroy Texture Surfaces from the bottom up... */ +/* All texture objects at this point will create a texture surface in System*/ +/* memory (SMEM). Then we will copy the Mesa texture into the surface using */ +/* the 'pixel' struc to get the translation info. So now this means that all*/ +/* textures that Mesa gives me I will have a Surface with a copy. If Mesa */ +/* changes the texture the I update the surface in (SMEM). */ +/* Now we have a texture struc and a Texture Surface in SMEM. At this point*/ +/* we create another surface on the card (VMEM). Finally we blt from the */ +/* SMEM to the VMEM and set the texture as current. Why do I need two? First*/ +/* this solves square textures. If the cards CAPS is square textures only */ +/* then I change the dimensions of the VMEM surface and the blt solves it for*/ +/* me. Second it saves me from filling D3D textures over and over if the */ +/* card needs to be creating and destroying surfaces because of low memory. */ +/* The surface in SMEM is expected to work always. When a surface has to be*/ +/* created in VMEM then we put it in a loop that tries to create the surface.*/ +/* If we create the surface ok then we brake from the loop. If we fail then */ +/* we will call 'FreeTextureMemory' that will return TRUE/FALSE as to whether*/ +/* memory was freed. If memory was freed then we can try again. If no memory*/ +/* was freed then it just can't fit. */ +/* 'FreeTextureMemory' will find the end of the list and start freeing VMEM */ +/* (never SMEM) surfaces that are not locked. */ +/* BIND - when we bind and there is a texture struct with a texture surface */ +/* in VMEM then we just make it current. If we have a struct and a surface */ +/* in SMEM but no VMEM surface then we create the surface in VMEM and blt */ +/* from the SMEM surface. If we have nothing its just like a creation... */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +extern "C" BOOL CreateTMgrHAL( PMESAD3DSHARED pShared, DWORD dwName, int level, DWORD dwRequestFlags, + RECT *rectDirty, DWORD dwWidth, DWORD dwHeight, DWORD dwAction, void *pPixels ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + PTM_OBJECT pTMObj, + pTemp; + DDSURFACEDESC2 ddsd2; + HRESULT rc; + + + DPF(( DBG_FUNC, "CreateTMgrHAL();" )); + + DPF(( DBG_TXT_INFO, "Texture:" )); + DPF(( DBG_TXT_INFO, "cx: %d cy: %d", dwWidth, dwHeight )); + DPF(( DBG_TXT_INFO, "Rect:" )); + if ( rectDirty ) + { + DPF(( DBG_TXT_INFO, "x0: %d y0: %d", rectDirty->left, rectDirty->top )); + DPF(( DBG_TXT_INFO, "x1: %d y1: %d", rectDirty->right, rectDirty->bottom )); + } + + /* Check too see that we have a valid context. */ + if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL) ) + { + DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" )); + return FALSE; + } + + /*=================================================*/ + /* See if we can find this texture object by name. */ + /*=================================================*/ + for( pTMObj = pHAL->pTMList; pTMObj && (pTMObj->dwName != dwName); pTMObj = pTMObj->next ); + + /*=========================================================*/ + /* Allocate a new object if we didn't get a matching name. */ + /*=========================================================*/ + if ( pTMObj == NULL ) + { + pTMObj = (PTM_OBJECT)ALLOC( sizeof(TM_OBJECT) ); + if ( pTMObj == NULL ) + return FALSE; + memset( pTMObj, 0, sizeof(TM_OBJECT) ); + + /* Put the object at the beginning of the list. */ + pTMObj->next = pHAL->pTMList; + if ( pTMObj->next ) + { + pTemp = pTMObj->next; + pTemp->prev = pTMObj; + } + pHAL->pTMList = pTMObj; + } + else + { + /*===============================================================*/ + /* Make some caching happen by pulling this object to the front. */ + /*===============================================================*/ + if ( pHAL->pTMList != pTMObj ) + { + /* Pull the object out of the list. */ + if ( pTMObj->prev ) + { + pTemp = pTMObj->prev; + pTemp->next = pTMObj->next; + } + if ( pTMObj->next ) + { + pTemp = pTMObj->next; + pTemp->prev = pTMObj->prev; + } + + pTMObj->prev = NULL; + pTMObj->next = NULL; + + /* Put the object at the front of the list. */ + pTMObj->next = pHAL->pTMList; + if ( pTMObj->next ) + { + pTemp = pTMObj->next; + pTemp->prev = pTMObj; + } + pHAL->pTMList = pTMObj; + } + } + + /*========================================================*/ + /* If we are doing BIND and the texture is in VID memory. */ + /*========================================================*/ + if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_Video ) + { + DPF(( DBG_TXT_PROFILE, "Cache HIT (%d)", dwName )); + + /* Make this the current texture. */ + rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; + } + + /*=================================================================*/ + /* If we are doing BIND and the texture is at least in SYS memory. */ + /*=================================================================*/ + if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_System ) + { + DPF(( DBG_TXT_PROFILE, "Cache MISS (%d)", dwName )); + + /* Create the texture on the card. */ + rc = LoadTextureInVideo( pHAL, pTMObj ); + if ( rc == FALSE ) + return FALSE; + + /* Make this the current texture. */ + rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; + } + + /*=========================================================*/ + /* If we are doing UPDATE then try in VID first for speed. */ + /*=========================================================*/ + if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_Video && + !(pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) ) + { + DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" )); + + /* Update the texture on the card. */ + UpdateTexture( pTMObj, TRUE, rectDirty, (UCHAR *)pPixels ); + + /* We updated the texture in VID so kill the SYS so we know its dirty. */ + if ( pTMObj->lpDDS_System ) + { + DPF(( DBG_TXT_INFO, "Release texture (SYS)" )); + DX_RESTORE( pTMObj->lpDDS_System ); + pTMObj->lpDDS_System->Release(); + pTMObj->lpDDS_System = NULL; + } + + /* Make this the current texture. */ + rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; + } + + /*===========================================================*/ + /* If we are doing UPDATE then try in SYS still gives speed. */ + /*===========================================================*/ + if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_System ) + { + DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" )); + + /* Update the texture in SYS. */ + UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels ); + + /* We updated the SYS texture only so now blt to the VID. */ + rc = LoadTextureInVideo( pHAL, pTMObj ); + if ( rc == FALSE ) + return FALSE; + + /* Make this the current texture. */ + rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; + } + + /* At this point we have a valid Texture Manager Object with updated */ + /* links. We now need to create or update a texture surface that is */ + /* in system memory. Every texture has a copy in system so we can use*/ + /* blt to solve problems with textures allocated on the card (square */ + /* only textures, pixelformats...). */ + + // TODO: make support for update also. Dirty rectangle basicly... + + /* Kill the interface if we have one no matter what. */ + if ( pTMObj->lpD3DTexture2 ) + { + DPF(( DBG_TXT_INFO, "Release Texture2" )); + pTMObj->lpD3DTexture2->Release(); + pTMObj->lpD3DTexture2 = NULL; + } + + /* Kill the system surface. TODO: should try to get the SubIMage going again */ + if ( pTMObj->lpDDS_System ) + { + DPF(( DBG_TXT_INFO, "Release texture (SYS)" )); + DX_RESTORE( pTMObj->lpDDS_System ); + pTMObj->lpDDS_System->Release(); + pTMObj->lpDDS_System = NULL; + } + + /* Kill the Video surface. TODO: need some reuse system... */ + if ( pTMObj->lpDDS_Video ) + { + DPF(( DBG_TXT_INFO, "Release texture (VID)" )); + DX_RESTORE( pTMObj->lpDDS_Video ); + pTMObj->lpDDS_Video->Release(); + pTMObj->lpDDS_Video = NULL; + } + + /*================================================================*/ + /* Translate the the Mesa/OpenGL pixel channels to the D3D flags. */ + /*================================================================*/ + switch( dwRequestFlags ) + { + case GL_ALPHA: + dwRequestFlags = DDPF_ALPHA; + DPF(( DBG_TXT_WARN, "GL_ALPHA not supported!)" )); + return FALSE; + + case GL_INTENSITY: + case GL_LUMINANCE: + DPF(( DBG_TXT_WARN, "GL_INTENSITY/GL_LUMINANCE not supported!)" )); + dwRequestFlags = DDPF_LUMINANCE; + return FALSE; + + case GL_LUMINANCE_ALPHA: + DPF(( DBG_TXT_WARN, "GL_LUMINANCE_ALPHA not supported!)" )); + dwRequestFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS; + return FALSE; + + case GL_RGB: + DPF(( DBG_TXT_INFO, "Texture -> GL_RGB" )); + dwRequestFlags = DDPF_RGB; + break; + + case GL_RGBA: + DPF(( DBG_TXT_INFO, "Texture -> GL_RGBA" )); + dwRequestFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + break; + } + + /*==============================*/ + /* Populate the texture object. */ + /*==============================*/ + pTMObj->dwName = dwName; + pTMObj->lpD3DDevice = pHAL->lpD3DDevice; + pTMObj->dwFlags = dwRequestFlags; + if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) + { + DPF(( DBG_TXT_INFO, "Convert to Square..." )); + pTMObj->dwSHeight = dwHeight; + pTMObj->dwSWidth = dwWidth; + + /* Shrink non-square textures. */ + pTMObj->dwVHeight = (dwHeight > dwWidth) ? dwWidth : dwHeight; + pTMObj->dwVWidth = (dwHeight > dwWidth) ? dwWidth : dwHeight; + } + else + { + pTMObj->dwSHeight = dwHeight; + pTMObj->dwSWidth = dwWidth; + pTMObj->dwVHeight = dwHeight; + pTMObj->dwVWidth = dwWidth; + } + + /*========================*/ + /* Create SYSTEM surface. */ + /*========================*/ + + /* Request a surface in system memory. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); + ddsd2.dwWidth = pTMObj->dwSWidth; + ddsd2.dwHeight = pTMObj->dwSHeight; + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; + ddsd2.ddsCaps.dwCaps2 = 0L; + memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) ); + ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); + ddsd2.ddpfPixelFormat.dwFlags = dwRequestFlags; + rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat ); + if ( FAILED(rc) ) + { + RIP( pHAL, "EnumerTextureFormats (SYSTEM)->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Create the surface using the enumerated pixelformat. */ + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_System, NULL ); + if ( FAILED(rc) ) + { + RIP( pHAL, "CreateSurface (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Solve the pixel mapping info using the surface pixelformat. */ + Solve8BitChannelPixelFormat( &ddsd2.ddpfPixelFormat, &pTMObj->pixel ); + + /*===================================================================*/ + /* Fill the texture using the PixelInfo structure to do the mapping. */ + /*===================================================================*/ + UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels ); + + /*=======================*/ + /* Create VIDEO surface. */ + /*=======================*/ + rc = LoadTextureInVideo( pHAL, pTMObj ); + if ( rc == FALSE ) + return FALSE; + + /* Make this the current texture. */ + rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; +} +/*===========================================================================*/ +/* This function will handle the creation and destruction of the texture */ +/* surfaces on the card. Using the dw'V'Width/Height dimensions the call */ +/* try and create the texture on the card and keep using FreeTextureMemory */ +/* until the surace can be created. Once the surface is created we get the */ +/* interface that we will use to make it the current texture. I didn't put */ +/* the code to make the texture current in this function as BIND needs to */ +/* use the same code and this function doesn't always get called when we do a*/ +/* bind. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj ) +{ + DDSURFACEDESC2 ddsd2; + HRESULT rc; + + DPF(( DBG_FUNC, "LoadTextureInVideo();" )); + + /* Kill the interface if we have one no matter what. */ + if ( pTMObj->lpD3DTexture2 ) + { + DPF(( DBG_TXT_INFO, "Release Texture2" )); + pTMObj->lpD3DTexture2->Release(); + pTMObj->lpD3DTexture2 = NULL; + } + + /* Kill the Video surface. TODO: need some reuse system... */ + if ( pTMObj->lpDDS_Video ) + { + DPF(( DBG_TXT_INFO, "Release texture (VID)" )); + DX_RESTORE( pTMObj->lpDDS_Video ); + pTMObj->lpDDS_Video->Release(); + pTMObj->lpDDS_Video = NULL; + } + + /* Request a surface in Video memory. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); + ddsd2.dwWidth = pTMObj->dwVWidth; + ddsd2.dwHeight = pTMObj->dwVHeight; + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; + ddsd2.ddsCaps.dwCaps2 = 0L; + memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) ); + ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); + ddsd2.ddpfPixelFormat.dwFlags = pTMObj->dwFlags; + rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat ); + if ( FAILED(rc) ) + { + RIP( pHAL, "EnumerTextureFormats ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Make sure we lock so we don't nuke this texture trying to free memory for it. */ + pTMObj->bLock = TRUE; + + /* Start a loop that will free all textures until we have created the texture */ + /* surface or we can't free up more memory. */ + do + { + /* Try to create the texture surface. */ + rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_Video, NULL ); + if ( !FAILED(rc) ) + break; + + DPF(( DBG_TXT_INFO, "Free Texture Memory" )); + + /* DestroyTexture will return TRUE if a surface was freed. */ + } while( FreeTextureMemory(pHAL,NULL) ); + + /* Make sure we unlock or we won't be able to nuke the TMO later. */ + pTMObj->bLock = FALSE; + + /* Did we create a valid texture surface? */ + if ( FAILED(rc) ) + { + DPF(( DBG_TXT_WARN, "Failed to load texture" )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + DX_RESTORE( pTMObj->lpDDS_System ); + DX_RESTORE( pTMObj->lpDDS_Video ); + + DPF(( DBG_TXT_INFO, "Texture Blt SYSTEM -> VID" )); + + /* Now blt the texture in system memory to the card. */ + rc = pTMObj->lpDDS_Video->Blt( NULL, pTMObj->lpDDS_System, NULL, DDBLT_WAIT, NULL ); + if ( FAILED(rc) ) + { + RIP( pHAL, "Blt (TEXTURE) ->", ErrorStringD3D(rc) ); + return FALSE; + } + + /* Get the Texture interface that is used to render with. */ + pTMObj->lpDDS_Video->QueryInterface( IID_IDirect3DTexture2, (void **)&pTMObj->lpD3DTexture2 ); + if ( pTMObj->lpD3DTexture2 == NULL ) + { + DPF(( DBG_TXT_WARN, "Failed QueryTextureInterface" )); + pHAL->lpD3DDevice->SetTexture( 0, NULL ); + return FALSE; + } + + return TRUE; +} +/*===========================================================================*/ +/* If this function gets a texture object struc then we will try and free */ +/* it. If we get a NULL then we will search from the bottom up and free one */ +/* VMEM surface. I can only free when the surface isn't locked and of course*/ +/* there must be a VMEM surface. We never free SMEM surfaces as that isn't */ +/* the point. */ +/* TODO: should have a pointer to the bottom of the stack really. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ) +{ + PTM_OBJECT pCurrent; + BOOL bFreed = FALSE; + + DPF(( DBG_FUNC, "FreeTextureMemory();" )); + DPF(( DBG_TXT_WARN, "FREE TEXTURE!" )); + + /* Just to be safe. */ + if ( !pHAL || !pHAL->pTMList ) + { + DPF(( DBG_TXT_WARN, "FreeTextureMemory() -> NULL pHAL/pHAL->pTMList" )); + return FALSE; + } + + /* Free the last texture in the list. */ + if ( pTMObject == NULL ) + { + DPF(( DBG_TXT_INFO, "Free Last texture in cache" )); + + /* Find the last texture object. */ + for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next ); + + /* Now backup until we find a texture on the card. */ + while( pCurrent && (pCurrent->lpDDS_Video == NULL) && (pCurrent->bLock == FALSE) ) + pCurrent = pCurrent->prev; + + /* Didn't find anything. */ + if ( pCurrent == NULL ) + { + DPF(( DBG_TXT_INFO, "No texture memory freed" )); + return FALSE; + } + } + else + { + /* See if we can find this texture object. */ + for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next ); + + /* Didn't find anything. */ + if ( pCurrent == NULL ) + { + DPF(( DBG_TXT_INFO, "Requested texture to be freed NOT FOUND" )); + return FALSE; + } + } + + /* Can't free this baby. */ + if ( pCurrent->bLock == TRUE ) + { + DPF(( DBG_TXT_WARN, "Requested texture LOCKED" )); + return FALSE; + } + + /* Free the texture memory. */ + if ( pCurrent->lpD3DTexture2 ) + { + DPF(( DBG_TXT_INFO, "Release Texture2" )); + pCurrent->lpD3DTexture2->Release(); + pCurrent->lpD3DTexture2 = NULL; + bFreed = TRUE; + } + if ( pCurrent->lpDDS_Video ) + { + DPF(( DBG_TXT_INFO, "Release texture (VID):" )); + DPF(( DBG_TXT_INFO, "dwName: %d", pCurrent->dwName )); + DPF(( DBG_TXT_INFO, "cx: %d, cy: %d", pCurrent->dwVWidth, pCurrent->dwVHeight )); + pCurrent->lpDDS_Video->Release(); + pCurrent->lpDDS_Video = NULL; + bFreed = TRUE; + } + + return bFreed; +} +/*===========================================================================*/ +/* This function searches the linked list of texture objects in the supplied*/ +/* D3Dwrapper structure. If it finds a match it will free it and pull it out*/ +/* of the linked list. The function works on the bases of a matching pointer*/ +/* to the object (not matching content). */ +/* If the function gets passed a NULL then we want to free the last texture */ +/* object in the list. Used in a loop to destory all. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ) +{ + PTM_OBJECT pCurrent; + + DPF(( DBG_FUNC, "DestoryTextureObject();" )); + + /* Just to be safe. */ + if ( !pHAL || !pHAL->pTMList ) + { + DPF(( DBG_TXT_WARN, "DestroyTextureObject() -> NULL pHAL/pHAL->pTMList" )); + return FALSE; + } + + /* Free the last texture in the list. */ + if ( pTMObject == NULL ) + { + /* Find the last texture object. */ + for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next ); + } + else + { + /* See if we can find this texture object. */ + for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next ); + + /* Didn't find anything. */ + if ( pCurrent == NULL ) + { + DPF(( DBG_TXT_WARN, "No textures to be freed" )); + return FALSE; + } + } + + /* Can't free this baby. */ + if ( pCurrent->bLock == TRUE ) + { + DPF(( DBG_TXT_WARN, "Requested texture to be freed LOCKED" )); + return FALSE; + } + + /* Free the texture memory. */ + if ( pCurrent->lpD3DTexture2 ) + { + DPF(( DBG_TXT_INFO, "Release Texture2" )); + pCurrent->lpD3DTexture2->Release(); + pCurrent->lpD3DTexture2 = NULL; + } + if ( pCurrent->lpDDS_Video ) + { + DPF(( DBG_TXT_INFO, "Release texture (VID):" )); + pCurrent->lpDDS_Video->Release(); + pCurrent->lpDDS_Video = NULL; + } + if ( pCurrent->lpDDS_System ) + { + DPF(( DBG_TXT_INFO, "Release texture (SYS):" )); + pCurrent->lpDDS_System->Release(); + pCurrent->lpDDS_System = NULL; + } + + /* Pull this texture out of the list. */ + if ( pCurrent == pHAL->pTMList ) + pHAL->pTMList = NULL; + if ( pCurrent->prev ) + (pCurrent->prev)->next = pCurrent->next; + if ( pCurrent->next ) + (pCurrent->next)->prev = pCurrent->prev; + FREE( pCurrent ); + + return TRUE; +} +/*===========================================================================*/ +/* This function is the callback function that gets called when we are doing*/ +/* an enumeration of the texture formats supported by this device. The choice*/ +/* is made by checking to see if we have a match with the supplied D3D pixel-*/ +/* format. So the enumeration has to pass a desired D3D PF as the user var. */ +/*===========================================================================*/ +/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL. */ +/*===========================================================================*/ +static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels ) +{ + LPDIRECTDRAWSURFACE4 lpDDS; + DDSURFACEDESC2 ddsd2; + DWORD srcPitch, + dwHeight, + dwWidth, + dwCol, + dwColor; + UCHAR *pSrc, + *pSrcRow, + *pDest, + *pDestRow; + int rc; + + // TODO: Do I need to pass the h/w when its in the object! + DPF(( DBG_FUNC, "UpdateTexture();" )); + + /* Get the surface pointer we are looking for. */ + lpDDS = (bVideo) ? pTMObj->lpDDS_Video : pTMObj->lpDDS_System; + + /*===================================================================*/ + /* Fill the texture using the PixelInfo structure to do the mapping. */ + /*===================================================================*/ + + /* Get the surface pointer. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + rc = lpDDS->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL ); + if ( FAILED(rc) ) + { + RIP( NULL, "Lock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); + return; + } + + /* For now we are only updating the system surface so use its dimensions. */ + dwWidth = (bVideo) ? pTMObj->dwVWidth : pTMObj->dwSWidth; + dwHeight = (bVideo) ? pTMObj->dwVHeight : pTMObj->dwSHeight; + + /* If we are updating the whole surface then the pDest/pSrc will */ + /* always be the same. */ + if ( pRect == NULL ) + { + pDest = (UCHAR *)ddsd2.lpSurface; + pSrc = pixels; + } + + /* Fill the texture surface based on the pixelformat flags. */ + if ( pTMObj->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS) ) + { + srcPitch = dwWidth * 4; + if ( pRect ) + { + pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); + pSrc = pixels + (pRect->top * dwWidth * 4) + (pRect->left * 4); + dwHeight = (pRect->bottom - pRect->top); + dwWidth = (pRect->right - pRect->left); + } + + for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) + { + for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) + { + dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); + dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift ); + dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift ); + if ( pTMObj->pixel.aScale == -1.0 ) + dwColor |= ( (*(pSrc+3) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); + else + dwColor |= ( ((DWORD)(*(pSrc+3) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); + memcpy( pDest, &dwColor, pTMObj->pixel.cb ); + pDest += pTMObj->pixel.cb; + pSrc += 4; + } + } + } + else if ( pTMObj->dwFlags == DDPF_RGB ) + { + srcPitch = dwWidth * 3; + if ( pRect ) + { + pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); + pSrc = pixels + (pRect->top * dwWidth * 3) + (pRect->left * 3); + dwHeight = (pRect->bottom - pRect->top); + dwWidth = (pRect->right - pRect->left); + } + + for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) + { + for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) + { + dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); + dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift ); + dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift ); + memcpy( pDest, &dwColor, pTMObj->pixel.cb ); + pDest += pTMObj->pixel.cb; + pSrc += 3; + } + } + } + else if ( pTMObj->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS) ) + { + srcPitch = dwWidth * 2; + if ( pRect ) + { + pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); + pSrc = pixels + (pRect->top * dwWidth * 2) + (pRect->left * 2); + dwHeight = (pRect->bottom - pRect->top); + dwWidth = (pRect->right - pRect->left); + } + + for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) + { + for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) + { + dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); + if ( pTMObj->pixel.aScale == -1.0 ) + dwColor |= ( (*(pSrc+1) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); + else + dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); + memcpy( pDest, &dwColor, pTMObj->pixel.cb ); + pDest += pTMObj->pixel.cb; + pSrc += 2; + } + } + } + else if ( pTMObj->dwFlags == DDPF_LUMINANCE ) + { + srcPitch = dwWidth; + if ( pRect ) + { + pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); + pSrc = pixels + (pRect->top * dwWidth) + (pRect->left); + dwHeight = (pRect->bottom - pRect->top); + dwWidth = (pRect->right - pRect->left); + } + + for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) + { + for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) + { + dwColor = ( ((DWORD)(*pSrc * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); + memcpy( pDest, &dwColor, pTMObj->pixel.cb ); + pDest += pTMObj->pixel.cb; + pSrc++; + } + } + } + else if ( pTMObj->dwFlags == DDPF_ALPHAPIXELS ) + { + srcPitch = dwWidth; + if ( pRect ) + { + pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); + pSrc = pixels + (pRect->top * dwWidth) + (pRect->left); + dwHeight = (pRect->bottom - pRect->top); + dwWidth = (pRect->right - pRect->left); + } + + for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) + { + for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) + { + if ( pTMObj->pixel.aScale == -1.0 ) + dwColor = ( (*pSrc & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); + else + dwColor = ( ((DWORD)(*pSrc * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); + memcpy( pDest, &dwColor, pTMObj->pixel.cb ); + pDest += pTMObj->pixel.cb; + pSrc++; + } + } + } + + /* Unlock the surface. */ + rc = lpDDS->Unlock( NULL ); + if ( FAILED(rc) ) + { + RIP( NULL, "Unlock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); + } +} +/*===========================================================================*/ +/* This function is the callback function that gets called when we are doing*/ +/* an enumeration of the texture formats supported by this device. The choice*/ +/* is made by checking to see if we have a match with the supplied D3D pixel-*/ +/* format. So the enumeration has to pass a desired D3D PF as the user var. */ +/*===========================================================================*/ +/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL. */ +/*===========================================================================*/ +HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext ) +{ + LPDDPIXELFORMAT lpDDPixFmtRequest = (LPDDPIXELFORMAT)lpContext; + PIXELINFO pixel; + + DPF(( DBG_FUNC, "EnumPFHook();" )); + + if ( lpDDPixFmt->dwFlags == lpDDPixFmtRequest->dwFlags ) + { + /* Are we looking for an alpha channel? */ + if ( lpDDPixFmtRequest->dwFlags & DDPF_ALPHAPIXELS ) + { + /* Try for something that has more then 1bits of Alpha. */ + Solve8BitChannelPixelFormat( lpDDPixFmt, &pixel ); + if ( pixel.aScale == -1.0 ) + { + /* Save this format no matter what as its a match of sorts. */ + memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) ); + return D3DENUMRET_OK; + } + } + + /* Save this format as its a good match. */ + memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) ); + + /* We are happy at this point so lets leave. */ + return D3DENUMRET_CANCEL; + } + + return D3DENUMRET_OK; +} + + + \ 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 index 0000000..6b3ac78 --- /dev/null +++ b/src/mesa/drivers/d3d/D3DTextureMgr.h @@ -0,0 +1,63 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#ifndef _TEXTURE_MGR_INC +#define _TEXTURE_MGR_INC + +/*===========================================================================*/ +/* Includes. */ +/*===========================================================================*/ +#include +#include +#include +#include +#include +#include "GL/gl.h" +/*========================================================================*/ +/* Defines. */ +/*========================================================================*/ +/*========================================================================*/ +/* Type defines. */ +/*========================================================================*/ +typedef struct _local_texture_object +{ + DWORD dwName, + dwPriority, + dwFlags, + dwSWidth, + dwSHeight, + dwVWidth, + dwVHeight; + BOOL bLock, + bDirty; /* I only update VID on SubImage calls so the system */ + /* texture can get invalid. */ + + LPDIRECT3DDEVICE3 lpD3DDevice; /* If the device changes we must get new handles... */ + LPDIRECTDRAWSURFACE4 lpDDS_System, + lpDDS_Video; + LPDIRECT3DTEXTURE2 lpD3DTexture2; + + PIXELINFO pixel; + + struct _local_texture_object *next; + struct _local_texture_object *prev; + +} TM_OBJECT, *PTM_OBJECT; +/*========================================================================*/ +/* Function prototypes. */ +/*========================================================================*/ +void APIENTRY InitTMD3D( void *pVoid ); +void APIENTRY TermTMD3D( void *pVoid ); +/*========================================================================*/ +/* Global variables declaration. */ +/*========================================================================*/ + +#endif + \ 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 index 0000000..381e09f --- /dev/null +++ b/src/mesa/drivers/d3d/D3DUTILS.CPP @@ -0,0 +1,639 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DHAL.h" +/*===========================================================================*/ +/* Local only functions. */ +/*===========================================================================*/ +static int CountTrailingZeros( DWORD dwMask ); +/*===========================================================================*/ +/* This function is used to get the pointer to the surface and the pitch for*/ +/* the scanline rendering functions. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" DDSURFACEDESC2 *LockHAL( PMESAD3DSHARED pShared, BOOL bBack ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + static DDSURFACEDESC2 ddsd2; + HRESULT rc; + + DPF(( DBG_FUNC, "LockHAL();" )); + + /* Set the request structure up first. */ + memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); + ddsd2.dwSize = sizeof(DDSURFACEDESC2); + + /* Make sure we have enough info. */ + if ( pHAL ) + { + rc = pHAL->lpDDSRender->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL ); + if ( FAILED(rc) ) + { + RIP( pHAL, "Lock (RENDER) ->", ErrorStringD3D(rc) ); + } + } + + return &ddsd2; +} +/*===========================================================================*/ +/* This is just a simple wrapper. I probably don't need to do any error */ +/* checking as the Lock must have worked inorder to get here... */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void UnlockHAL( PMESAD3DSHARED pShared, BOOL bBack ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + HRESULT rc; + + DPF(( DBG_FUNC, "UnlockHAL();" )); + + /* Make sure we have enough info. */ + if ( pHAL ) + { + rc = pHAL->lpDDSRender->Unlock( NULL ); + if ( FAILED(rc) ) + { + RIP( pHAL, "Unlock (RENDER) ->", ErrorStringD3D(rc) ); + } + } +} +/*===========================================================================*/ +/* This function will track the main/Primary window that will be used as the*/ +/* target for the Blt in SwapBuffers. As a side effect the call will check */ +/* to see if the primary surface is the same size and position as the screen.*/ +/* If they are the same size we will call it fullscreen... */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +extern "C" void UpdateScreenPosHAL( PMESAD3DSHARED pShared ) +{ + PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; + POINT pt; + DWORD dwWidth, dwHeight; + + DPF(( DBG_FUNC, "UpdateScreenPosHAL();" )); + + /* Make sure we have enough info. */ + if ( pHAL != NULL ) + { + /* Update the windows screen position. */ + GetClientRect( pShared->hwnd, &pShared->rectW ); + pt.x = pt.y = 0; + ClientToScreen( pShared->hwnd, &pt ); + OffsetRect( &pShared->rectW, pt.x, pt.y); + + /* Compare the primary to the screen. */ + dwWidth = GetSystemMetrics( SM_CXSCREEN ); + dwHeight = GetSystemMetrics( SM_CYSCREEN ); + if ( (pShared->rectW.left > 0) || (pShared->rectW.top > 0) || + (pShared->rectW.right > dwWidth) || (pShared->rectW.bottom > dwHeight) ) + pShared->bWindow = TRUE; + else + pShared->bWindow = FALSE; + } +} +/*===========================================================================*/ +/* This function will fill in the pixel info structure defined in D3Dshared.*/ +/* Basicly it will take a DirectDraw pixelformat structure and make scaling */ +/* values that will convert from 8bit channels to whatever the supplied ddpf */ +/* uses. Also we will generate shift values that will be used to get move */ +/* each component of the pixel into place. */ +/* I have now added a special case for a 1bit alpha channel. If I find a 1b*/ +/* alpha then I will set the scale to -1.0 which should be unique. Later I */ +/* can check the alpha scale value too see if its -1.0 and thus handle it. I*/ +/* was finding that the case was not working tom my advantage so this is my */ +/* HACK for the day. As a TODO I should work on this... */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void Solve8BitChannelPixelFormat( DDPIXELFORMAT *pddpf, PPIXELINFO pPixel ) +{ + DPF(( DBG_FUNC, "Solve8BitChannelPixelFromat();" )); + + memset( pPixel, 0, sizeof(PPIXELINFO) ); + + /* Check too see if the color space is valid in the PF. */ + if ( pddpf->dwFlags & DDPF_RGB ) + { + /* Solve the red stuff. */ + pPixel->dwRMask = pddpf->dwRBitMask; + pPixel->rShift = CountTrailingZeros( pPixel->dwRMask ); + pPixel->rScale = (float)0.00392156 * (float)(pPixel->dwRMask >> pPixel->rShift); + + /* Solve the green thingy's. */ + pPixel->dwGMask = pddpf->dwGBitMask; + pPixel->gShift = CountTrailingZeros( pPixel->dwGMask ); + pPixel->gScale = (float)0.00392156 * (float)(pPixel->dwGMask >> pPixel->gShift); + + /* Solve the blues. */ + pPixel->dwBMask = pddpf->dwBBitMask; + pPixel->bShift = CountTrailingZeros( pddpf->dwBBitMask ); + pPixel->bScale = (float)0.00392156 * (float)(pddpf->dwBBitMask >> pPixel->bShift); + } + + /* Do the alpha channel if there is one. */ + if ( pddpf->dwFlags & DDPF_ALPHAPIXELS ) + { + pPixel->dwAMask = pddpf->dwRGBAlphaBitMask; + pPixel->aShift = CountTrailingZeros( pPixel->dwAMask ); + + /* Special case a 1bit alpha. */ + if ( (pPixel->dwAMask >> pPixel->aShift) == 1 ) + pPixel->aScale = -1.0; + else + pPixel->aScale = (float)0.00392156 * (float)(pPixel->dwAMask >> pPixel->aShift); + } + + /* Get the size of the pixel in bytes. Should work as dwRGBBitCount is in a union. */ + pPixel->cb = pddpf->dwRGBBitCount / 8; +} +/*===========================================================================*/ +/* See RETURN :) */ +/*===========================================================================*/ +/* RETURN: number of contiguous zeros starting from the right. */ +/*===========================================================================*/ +static int CountTrailingZeros( DWORD dwMask ) +{ + DWORD Mask; + + if ( dwMask == 0 ) + return 32; + + /* Can't take credit for this one! */ + Mask = dwMask & -(int)dwMask; + return ((Mask & 0xFFFF0000)!=0) << 4 + | ((Mask & 0xFF00FF00)!=0) << 3 + | ((Mask & 0xF0F0F0F0)!=0) << 2 + | ((Mask & 0xCCCCCCCC)!=0) << 1 + | ((Mask & 0xAAAAAAAA)!=0); +} +/*===========================================================================*/ +/* This function will convert the DDraw error code to its macro string. The*/ +/* returned pointer is static so you need not worry about memory managemnet */ +/* but the error message gets written over from call to call... */ +/*===========================================================================*/ +/* RETURN: pointer to the single static buffer that hold the error message. */ +/*===========================================================================*/ +char *ErrorStringD3D( HRESULT hr ) +{ + static char errorString[128]; + + switch( hr ) + { + case DDERR_ALREADYINITIALIZED: + strcpy( errorString, "DDERR_ALREADYINITIALIZED" ); + break; + + case DDERR_CANNOTATTACHSURFACE: + strcpy( errorString, "DDERR_CANNOTATTACHSURFACE" ); + break; + + case DDERR_CANNOTDETACHSURFACE: + strcpy( errorString, "DDERR_CANNOTDETACHSURFACE" ); + break; + + case DDERR_CURRENTLYNOTAVAIL: + strcpy( errorString, "DDERR_CURRENTLYNOTAVAIL" ); + break; + + case DDERR_EXCEPTION: + strcpy( errorString, "DDERR_EXCEPTION" ); + break; + + case DDERR_GENERIC: + strcpy( errorString, "DDERR_GENERIC" ); + break; + + case DDERR_HEIGHTALIGN: + strcpy( errorString, "DDERR_HEIGHTALIGN" ); + break; + + case DDERR_INCOMPATIBLEPRIMARY: + strcpy( errorString, "DDERR_INCOMPATIBLEPRIMARY" ); + break; + + case DDERR_INVALIDCAPS: + strcpy( errorString, "DDERR_INVALIDCAPS" ); + break; + + case DDERR_INVALIDCLIPLIST: + strcpy( errorString, "DDERR_INVALIDCLIPLIST" ); + break; + + case DDERR_INVALIDMODE: + strcpy( errorString, "DDERR_INVALIDMODE" ); + break; + + case DDERR_INVALIDOBJECT: + strcpy( errorString, "DDERR_INVALIDOBJECT" ); + break; + + case DDERR_INVALIDPARAMS: + strcpy( errorString, "DDERR_INVALIDPARAMS" ); + break; + + case DDERR_INVALIDPIXELFORMAT: + strcpy( errorString, "DDERR_INVALIDPIXELFORMAT" ); + break; + + case DDERR_INVALIDRECT: + strcpy( errorString, "DDERR_INVALIDRECT" ); + break; + + case DDERR_LOCKEDSURFACES: + strcpy( errorString, "DDERR_LOCKEDSURFACES" ); + break; + + case DDERR_NO3D: + strcpy( errorString, "DDERR_NO3D" ); + break; + + case DDERR_NOALPHAHW: + strcpy( errorString, "DDERR_NOALPHAHW" ); + break; + + case DDERR_NOCLIPLIST: + strcpy( errorString, "DDERR_NOCLIPLIST" ); + break; + + case DDERR_NOCOLORCONVHW: + strcpy( errorString, "DDERR_NOCOLORCONVHW" ); + break; + + case DDERR_NOCOOPERATIVELEVELSET: + strcpy( errorString, "DDERR_NOCOOPERATIVELEVELSET" ); + break; + + case DDERR_NOCOLORKEY: + strcpy( errorString, "DDERR_NOCOLORKEY" ); + break; + + case DDERR_NOCOLORKEYHW: + strcpy( errorString, "DDERR_NOCOLORKEYHW" ); + break; + + case DDERR_NODIRECTDRAWSUPPORT: + strcpy( errorString, "DDERR_NODIRECTDRAWSUPPORT" ); + break; + + case DDERR_NOEXCLUSIVEMODE: + strcpy( errorString, "DDERR_NOEXCLUSIVEMODE" ); + break; + + case DDERR_NOFLIPHW: + strcpy( errorString, "DDERR_NOFLIPHW" ); + break; + + case DDERR_NOGDI: + strcpy( errorString, "DDERR_NOGDI" ); + break; + + case DDERR_NOMIRRORHW: + strcpy( errorString, "DDERR_NOMIRRORHW" ); + break; + + case DDERR_NOTFOUND: + strcpy( errorString, "DDERR_NOTFOUND" ); + break; + + case DDERR_NOOVERLAYHW: + strcpy( errorString, "DDERR_NOOVERLAYHW" ); + break; + + case DDERR_OVERLAPPINGRECTS: + strcpy( errorString, "DDERR_OVERLAPPINGRECTS" ); + break; + + case DDERR_NORASTEROPHW: + strcpy( errorString, "DDERR_NORASTEROPHW" ); + break; + + case DDERR_NOROTATIONHW: + strcpy( errorString, "DDERR_NOROTATIONHW" ); + break; + + case DDERR_NOSTRETCHHW: + strcpy( errorString, "DDERR_NOSTRETCHHW" ); + break; + + case DDERR_NOT4BITCOLOR: + strcpy( errorString, "DDERR_NOT4BITCOLOR" ); + break; + + case DDERR_NOT4BITCOLORINDEX: + strcpy( errorString, "DDERR_NOT4BITCOLORINDEX" ); + break; + + case DDERR_NOT8BITCOLOR: + strcpy( errorString, "DDERR_NOT8BITCOLOR" ); + break; + + case DDERR_NOTEXTUREHW: + strcpy( errorString, "DDERR_NOTEXTUREHW" ); + break; + + case DDERR_NOVSYNCHW: + strcpy( errorString, "DDERR_NOVSYNCHW" ); + break; + + case DDERR_NOZBUFFERHW: + strcpy( errorString, "DDERR_NOZBUFFERHW" ); + break; + + case DDERR_NOZOVERLAYHW: + strcpy( errorString, "DDERR_NOZOVERLAYHW" ); + break; + + case DDERR_OUTOFCAPS: + strcpy( errorString, "DDERR_OUTOFCAPS" ); + break; + + case DDERR_OUTOFMEMORY: + strcpy( errorString, "DDERR_OUTOFMEMORY" ); + break; + + case DDERR_OUTOFVIDEOMEMORY: + strcpy( errorString, "DDERR_OUTOFVIDEOMEMORY" ); + break; + + case DDERR_OVERLAYCANTCLIP: + strcpy( errorString, "DDERR_OVERLAYCANTCLIP" ); + break; + + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: + strcpy( errorString, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE" ); + break; + + case DDERR_PALETTEBUSY: + strcpy( errorString, "DDERR_PALETTEBUSY" ); + break; + + case DDERR_COLORKEYNOTSET: + strcpy( errorString, "DDERR_COLORKEYNOTSET" ); + break; + + case DDERR_SURFACEALREADYATTACHED: + strcpy( errorString, "DDERR_SURFACEALREADYATTACHED" ); + break; + + case DDERR_SURFACEALREADYDEPENDENT: + strcpy( errorString, "DDERR_SURFACEALREADYDEPENDENT" ); + break; + + case DDERR_SURFACEBUSY: + strcpy( errorString, "DDERR_SURFACEBUSY" ); + break; + + case DDERR_CANTLOCKSURFACE: + strcpy( errorString, "DDERR_CANTLOCKSURFACE" ); + break; + + case DDERR_SURFACEISOBSCURED: + strcpy( errorString, "DDERR_SURFACEISOBSCURED" ); + break; + + case DDERR_SURFACELOST: + strcpy( errorString, "DDERR_SURFACELOST" ); + break; + + case DDERR_SURFACENOTATTACHED: + strcpy( errorString, "DDERR_SURFACENOTATTACHED" ); + break; + + case DDERR_TOOBIGHEIGHT: + strcpy( errorString, "DDERR_TOOBIGHEIGHT" ); + break; + + case DDERR_TOOBIGSIZE: + strcpy( errorString, "DDERR_TOOBIGSIZE" ); + break; + + case DDERR_TOOBIGWIDTH: + strcpy( errorString, "DDERR_TOOBIGWIDTH" ); + break; + + case DDERR_UNSUPPORTED: + strcpy( errorString, "DDERR_UNSUPPORTED" ); + break; + + case DDERR_UNSUPPORTEDFORMAT: + strcpy( errorString, "DDERR_UNSUPPORTEDFORMAT" ); + break; + + case DDERR_UNSUPPORTEDMASK: + strcpy( errorString, "DDERR_UNSUPPORTEDMASK" ); + break; + + case DDERR_INVALIDSTREAM: + strcpy( errorString, "DDERR_INVALIDSTREAM" ); + break; + + case DDERR_VERTICALBLANKINPROGRESS: + strcpy( errorString, "DDERR_VERTICALBLANKINPROGRESS" ); + break; + + case DDERR_WASSTILLDRAWING: + strcpy( errorString, "DDERR_WASSTILLDRAWING" ); + break; + + case DDERR_XALIGN: + strcpy( errorString, "DDERR_XALIGN" ); + break; + + case DDERR_INVALIDDIRECTDRAWGUID: + strcpy( errorString, "DDERR_INVALIDDIRECTDRAWGUID" ); + break; + + case DDERR_DIRECTDRAWALREADYCREATED: + strcpy( errorString, "DDERR_DIRECTDRAWALREADYCREATED" ); + break; + + case DDERR_NODIRECTDRAWHW: + strcpy( errorString, "DDERR_NODIRECTDRAWHW" ); + break; + + case DDERR_PRIMARYSURFACEALREADYEXISTS: + strcpy( errorString, "DDERR_PRIMARYSURFACEALREADYEXISTS" ); + break; + + case DDERR_NOEMULATION: + strcpy( errorString, "DDERR_NOEMULATION" ); + break; + + case DDERR_REGIONTOOSMALL: + strcpy( errorString, "DDERR_REGIONTOOSMALL" ); + break; + + case DDERR_CLIPPERISUSINGHWND: + strcpy( errorString, "DDERR_CLIPPERISUSINGHWND" ); + break; + + case DDERR_NOCLIPPERATTACHED: + strcpy( errorString, "DDERR_NOCLIPPERATTACHED" ); + break; + + case DDERR_NOHWND: + strcpy( errorString, "DDERR_NOHWND" ); + break; + + case DDERR_HWNDSUBCLASSED: + strcpy( errorString, "DDERR_HWNDSUBCLASSED" ); + break; + + case DDERR_HWNDALREADYSET: + strcpy( errorString, "DDERR_HWNDALREADYSET" ); + break; + + case DDERR_NOPALETTEATTACHED: + strcpy( errorString, "DDERR_NOPALETTEATTACHED" ); + break; + + case DDERR_NOPALETTEHW: + strcpy( errorString, "DDERR_NOPALETTEHW" ); + break; + + case DDERR_BLTFASTCANTCLIP: + strcpy( errorString, "DDERR_BLTFASTCANTCLIP" ); + break; + + case DDERR_NOBLTHW: + strcpy( errorString, "DDERR_NOBLTHW" ); + break; + + case DDERR_NODDROPSHW: + strcpy( errorString, "DDERR_NODDROPSHW" ); + break; + + case DDERR_OVERLAYNOTVISIBLE: + strcpy( errorString, "DDERR_OVERLAYNOTVISIBLE" ); + break; + + case DDERR_NOOVERLAYDEST: + strcpy( errorString, "DDERR_NOOVERLAYDEST" ); + break; + + case DDERR_INVALIDPOSITION: + strcpy( errorString, "DDERR_INVALIDPOSITION" ); + break; + + case DDERR_NOTAOVERLAYSURFACE: + strcpy( errorString, "DDERR_NOTAOVERLAYSURFACE" ); + break; + + case DDERR_EXCLUSIVEMODEALREADYSET: + strcpy( errorString, "DDERR_EXCLUSIVEMODEALREADYSET" ); + break; + + case DDERR_NOTFLIPPABLE: + strcpy( errorString, "DDERR_NOTFLIPPABLE" ); + break; + + case DDERR_CANTDUPLICATE: + strcpy( errorString, "DDERR_CANTDUPLICATE" ); + break; + + case DDERR_NOTLOCKED: + strcpy( errorString, "DDERR_NOTLOCKED" ); + break; + + case DDERR_CANTCREATEDC: + strcpy( errorString, "DDERR_CANTCREATEDC" ); + break; + + case DDERR_NODC: + strcpy( errorString, "DDERR_NODC" ); + break; + + case DDERR_WRONGMODE: + strcpy( errorString, "DDERR_WRONGMODE" ); + break; + + case DDERR_IMPLICITLYCREATED: + strcpy( errorString, "DDERR_IMPLICITLYCREATED" ); + break; + + case DDERR_NOTPALETTIZED: + strcpy( errorString, "DDERR_NOTPALETTIZED" ); + break; + + case DDERR_UNSUPPORTEDMODE: + strcpy( errorString, "DDERR_UNSUPPORTEDMODE" ); + break; + + case DDERR_NOMIPMAPHW: + strcpy( errorString, "DDERR_NOMIPMAPHW" ); + break; + + case DDERR_INVALIDSURFACETYPE: + strcpy( errorString, "DDERR_INVALIDSURFACETYPE" ); + break; + + case DDERR_NOOPTIMIZEHW: + strcpy( errorString, "DDERR_NOOPTIMIZEHW" ); + break; + + case DDERR_NOTLOADED: + strcpy( errorString, "DDERR_NOTLOADED" ); + break; + + case DDERR_NOFOCUSWINDOW: + strcpy( errorString, "DDERR_NOFOCUSWINDOW" ); + break; + + case DDERR_DCALREADYCREATED: + strcpy( errorString, "DDERR_DCALREADYCREATED" ); + break; + + case DDERR_NONONLOCALVIDMEM: + strcpy( errorString, "DDERR_NONONLOCALVIDMEM" ); + break; + + case DDERR_CANTPAGELOCK: + strcpy( errorString, "DDERR_CANTPAGELOCK" ); + break; + + case DDERR_CANTPAGEUNLOCK: + strcpy( errorString, "DDERR_CANTPAGEUNLOCK" ); + break; + + case DDERR_NOTPAGELOCKED: + strcpy( errorString, "DDERR_NOTPAGELOCKED" ); + break; + + case DDERR_MOREDATA: + strcpy( errorString, "DDERR_MOREDATA" ); + break; + + case DDERR_EXPIRED: + strcpy( errorString, "DDERR_EXPIRED" ); + break; + + case DDERR_VIDEONOTACTIVE: + strcpy( errorString, "DDERR_VIDEONOTACTIVE" ); + break; + + case DDERR_DEVICEDOESNTOWNSURFACE: + strcpy( errorString, "DDERR_DEVICEDOESNTOWNSURFACE" ); + break; + + case DDERR_NOTINITIALIZED: + strcpy( errorString, "DDERR_NOTINITIALIZED" ); + break; + + default: + strcpy( errorString, "" ); + break; + } + + return &errorString[0]; +} + \ 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 index 0000000..57c1306 --- /dev/null +++ b/src/mesa/drivers/d3d/D3Dvbrender.c @@ -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 +#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; + } + } +} + diff --git a/src/mesa/drivers/d3d/DDrawPROCS.c b/src/mesa/drivers/d3d/DDrawPROCS.c new file mode 100644 index 0000000..33a1e47 --- /dev/null +++ b/src/mesa/drivers/d3d/DDrawPROCS.c @@ -0,0 +1,400 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DMesa.h" +/*===========================================================================*/ +/* This call will clear the render surface using the pixel info built from */ +/* the surface at creation time. The call uses Lock/Unlock to access the */ +/* surface. The call also special cases a full clear or a dirty rectangle. */ +/* Finally the call returns the new clear mask that reflects that the color */ +/* buffer was cleared. */ +/*===========================================================================*/ +/* RETURN: the original mask with the bits cleared that represents the buffer*/ +/* or buffers we just cleared. */ +/*===========================================================================*/ +GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer, + *pScanLine; + int index, + index2; + DWORD dwColor; + + if ( mask & GL_COLOR_BUFFER_BIT ) + { + /* Lock the surface to get the surface pointer. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Solve the color once only. */ + dwColor = ( ((DWORD)((float)pContext->rClear * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)pContext->gClear * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)pContext->bClear * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + + if ( all ) + { + for( index = 0, pScanLine = (UCHAR *)pddsd2->lpSurface; index < pContext->pShared->dwHeight; index++, pScanLine += pddsd2->lPitch ) + for( pBuffer = pScanLine, index2 = 0; index2 < pContext->pShared->dwWidth; index2++, pBuffer += pContext->pShared->pixel.cb ) + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + else + { + pScanLine = ((UCHAR *)pddsd2->lpSurface) + + ( (FLIP( pContext->pShared->dwHeight, (y+height)) * pddsd2->lPitch) + (x * pContext->pShared->pixel.cb) ); + + for( index = 0; index < height; index++, pScanLine += pddsd2->lPitch ) + { + for( index2 = 0, pBuffer = pScanLine; index2 < width; index2++, pBuffer += pContext->pShared->pixel.cb ) + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + + UnlockHAL( pContext->pShared, TRUE ); + } + + return (mask & ~GL_COLOR_BUFFER_BIT); +} +/*===========================================================================*/ +/* This proc (as all others) has been written for the general case. I use */ +/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */ +/* Screen render surface uses. The alpha is ignored as Mesa does it in SW. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD dwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Find the start of the span. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb); + + if ( mask ) + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + { + if ( mask[index] ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgb[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgb[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgb[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + } + else + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgb[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgb[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgb[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc (as all others) has been written for the general case. I use */ +/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */ +/* Screen render surface uses. The alpha is ignored as Mesa does it in SW. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD dwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Find the start of the span. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb); + + if ( mask ) + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + { + if ( mask[index] ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + } + else + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc (as all others) has been written for the general case. I use */ +/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */ +/* Screen render surface uses. The color is solved once from the current */ +/* color components. The alpha is ignored as Mesa is doing it in SW. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD dwColor; + + /* Lock the surface to get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Solve the color once only. (no alpha) */ + dwColor = ( ((DWORD)((float)pContext->rCurrent * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)pContext->gCurrent * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)pContext->bCurrent * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + + /* Find the start of the span. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb); + + if ( mask ) + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + if ( mask[index] ) + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + else + { + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc (as all others) has been written for the general case. I use */ +/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */ +/* Screen render surface uses. The alpha is ignored as Mesa does it in SW. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD dwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + if ( mask ) + { + for( index = 0; index < n; index++ ) + { + if ( mask[index] ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + + /* Find the pixel. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + } + else + { + for( index = 0; index < n; index++ ) + { + /* Pack the color components. */ + dwColor = ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + + /* Find the pixel. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc (as all others) has been written for the general case. I use */ +/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */ +/* Screen render surface uses. The color is solved once from the current */ +/* color components. The alpha is ignored as Mesa is doing it in SW. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD dwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Solve the color once only. I don't uses the alpha. */ + dwColor = ( ((DWORD)((float)pContext->rCurrent * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift ); + dwColor |= ( ((DWORD)((float)pContext->gCurrent * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift ); + dwColor |= ( ((DWORD)((float)pContext->bCurrent * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift ); + + if ( mask ) + { + /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */ + for( index = 0; index < n; index++ ) + { + if ( mask[index] ) + { + /* Find the pixel. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + } + else + { + /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */ + for( index = 0; index < n; index++ ) + { + /* Find the pixel. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb); + memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb ); + } + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc isn't written for speed rather its to handle the general case. */ +/* I grab each pixel from the surface and unpack the info using the PIXELINFO*/ +/* structure that was generated from the OffScreen surface pixelformat. The */ +/* function will not fill in the alpha value as Mesa I have Mesa allocate its*/ +/* own alpha channel when the context was created. I did this as I didn't */ +/* feel that it was worth the effort to try and get HW to work (bus bound). */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + UCHAR *pBuffer; + int index; + DWORD *pdwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + /* Find the start of the span. Invert y for Windows. */ + pBuffer = (UCHAR *)pddsd2->lpSurface + + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + + (x*pContext->pShared->pixel.cb); + + /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */ + for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb ) + { + pdwColor = (DWORD *)pBuffer; + rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale); + rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale); + rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale); + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} +/*===========================================================================*/ +/* This proc isn't written for speed rather its to handle the general case. */ +/* I grab each pixel from the surface and unpack the info using the PIXELINFO*/ +/* structure that was generated from the OffScreen surface pixelformat. The */ +/* function will not fill in the alpha value as Mesa I have Mesa allocate its*/ +/* own alpha channel when the context was created. I did this as I didn't */ +/* feel that it was worth the effort to try and get HW to work (bus bound). */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DDSURFACEDESC2 *pddsd2; + int index; + DWORD *pdwColor; + + /* Get the surface pointer and the pitch. */ + pddsd2 = LockHAL( pContext->pShared, TRUE ); + + if ( mask ) + { + /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */ + for( index = 0; index < n; index++ ) + { + if ( mask[index] ) + { + /* Find the start of the pixel. Invert y for Windows. */ + pdwColor = (DWORD *)((UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb)); + rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale); + rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale); + rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale); + } + } + } + else + { + /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */ + for( index = 0; index < n; index++ ) + { + /* Find the start of the pixel. Invert y for Windows. */ + pdwColor = (DWORD *)((UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb)); + rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale); + rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale); + rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale); + } + } + + /* Giver back. */ + UnlockHAL( pContext->pShared, TRUE ); +} + \ 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 index 0000000..26c2c25 --- /dev/null +++ b/src/mesa/drivers/d3d/DEBUG.C @@ -0,0 +1,144 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "Debug.h" +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +DWORD g_DBGMask = DBG_ALL_ERROR; +/*===========================================================================*/ +/* This is your basic DPF function with printf like support. The function */ +/* also works with a global debug mask variable. I have written support that*/ +/* allows for the user's enviroment variable space to be read and set the */ +/* masks. This is done when the dll starts and is only in the debug version.*/ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void _cdecl DebugPrint( int mask, char *pszFormat, ... ) +{ + char buffer[512]; + va_list args; + + /* A mask of 0 will always pass. Easy to remeber. */ + if ( (mask == 0) || (mask & g_DBGMask) ) + { + va_start( args, pszFormat ); + + if ( mask & DBG_ALL_ERROR ) + OutputDebugString( "MesaD3D: (ERROR)" ); + else + OutputDebugString( "MesaD3D: " ); + + vsprintf( buffer, pszFormat, args ); + strcat( buffer, "\n" ); + OutputDebugString( buffer ); + + va_end( args ); + } +} +/*===========================================================================*/ +/* This call reads the users enviroment variables and sets any debug mask */ +/* that they have set to TRUE. Now the value must be "TRUE". */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void ReadDBGEnv( void ) +{ + g_DBGMask = DBG_ALL_ERROR; + +#define IS_VAR_SET(v) if ( getenv( # v ) && !strcmp(getenv( # v ),"TRUE") ) g_DBGMask |= v; + + IS_VAR_SET( DBG_FUNC ); + IS_VAR_SET( DBG_STATES ); + + IS_VAR_SET( DBG_CNTX_INFO ); + IS_VAR_SET( DBG_CNTX_WARN ); + IS_VAR_SET( DBG_CNTX_PROFILE ); + IS_VAR_SET( DBG_CNTX_ERROR ); + IS_VAR_SET( DBG_CNTX_ALL ); + + IS_VAR_SET( DBG_PRIM_INFO ); + IS_VAR_SET( DBG_PRIM_WARN ); + IS_VAR_SET( DBG_PRIM_PROFILE ); + IS_VAR_SET( DBG_PRIM_ERROR ); + IS_VAR_SET( DBG_PRIM_ALL ); + + IS_VAR_SET( DBG_TXT_INFO ); + IS_VAR_SET( DBG_TXT_WARN ); + IS_VAR_SET( DBG_TXT_PROFILE ); + IS_VAR_SET( DBG_TXT_ERROR ); + IS_VAR_SET( DBG_TXT_ALL ); + + IS_VAR_SET( DBG_ALL_INFO ); + IS_VAR_SET( DBG_ALL_WARN ); + IS_VAR_SET( DBG_ALL_PROFILE ); + IS_VAR_SET( DBG_ALL_ERROR ); + IS_VAR_SET( DBG_ALL ); + +#undef IS_VAR_SET +} +/*===========================================================================*/ +/* This function will take a pointer to a DDSURFACEDESC2 structure & display*/ +/* the parsed information using a DPF call. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void DebugPixelFormat( char *pszSurfaceName, DDPIXELFORMAT *pddpf ) +{ + char buffer[256]; + + /* Parse the flag type and write the string equivalent. */ + if ( pddpf->dwFlags & DDPF_ALPHA ) + strcat( buffer, "DDPF_ALPHA " ); + if ( pddpf->dwFlags & DDPF_ALPHAPIXELS ) + strcat( buffer, "DDPF_ALPHAPIXELS " ); + if ( pddpf->dwFlags & DDPF_ALPHAPREMULT ) + strcat( buffer, "DDPF_ALPHAPREMULT " ); + if ( pddpf->dwFlags & DDPF_BUMPLUMINANCE ) + strcat( buffer, "DDPF_BUMPLUMINANCE " ); + if ( pddpf->dwFlags & DDPF_BUMPDUDV ) + strcat( buffer, "DDPF_BUMPDUDV " ); + if ( pddpf->dwFlags & DDPF_COMPRESSED ) + strcat( buffer, "DDPF_COMPRESSED " ); + if ( pddpf->dwFlags & DDPF_FOURCC ) + strcat( buffer, "DDPF_FOURCC " ); + if ( pddpf->dwFlags & DDPF_LUMINANCE ) + strcat( buffer, "DDPF_LUMINANCE " ); + if ( pddpf->dwFlags & DDPF_PALETTEINDEXED1 ) + strcat( buffer, "DDPF_PALETTEINDEXED1 " ); + if ( pddpf->dwFlags & DDPF_PALETTEINDEXED2 ) + strcat( buffer, "DDPF_PALETTEINDEXED2 " ); + if ( pddpf->dwFlags & DDPF_PALETTEINDEXED4 ) + strcat( buffer, "DDPF_PALETTEINDEXED4 " ); + if ( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) + strcat( buffer, "DDPF_PALETTEINDEXED8 " ); + if ( pddpf->dwFlags & DDPF_PALETTEINDEXEDTO8 ) + strcat( buffer, "DDPF_PALETTEINDEXEDTO8 " ); + if ( pddpf->dwFlags & DDPF_RGB ) + strcat( buffer, "DDPF_RGB " ); + if ( pddpf->dwFlags & DDPF_RGBTOYUV ) + strcat( buffer, "DDPF_RGBTOYUV " ); + if ( pddpf->dwFlags & DDPF_STENCILBUFFER ) + strcat( buffer, "DDPF_STENCILBUFFER " ); + if ( pddpf->dwFlags & DDPF_YUV ) + strcat( buffer, "DDPF_YUV " ); + if ( pddpf->dwFlags & DDPF_ZBUFFER ) + strcat( buffer, "DDPF_ZBUFFER " ); + if ( pddpf->dwFlags & DDPF_ZPIXELS ) + strcat( buffer, "DDPF_ZPIXELS " ); + + DPF(( (DBG_TXT_INFO|DBG_CNTX_INFO),"%s", buffer )); +} + + + + + + \ 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 index 0000000..e63d6c5 --- /dev/null +++ b/src/mesa/drivers/d3d/DEBUG.H @@ -0,0 +1,91 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#ifndef _DEBUG_H +#define _DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ +/* Includes. */ +/*===========================================================================*/ +#include +#include +#include +#include +#include "D3DShared.h" +/*===========================================================================*/ +/* Magic numbers. */ +/*===========================================================================*/ +/*===========================================================================*/ +/* Macros defines. */ +/*===========================================================================*/ +#define DBG_FUNC 0x00000001 +#define DBG_STATES 0x00000002 + +#define DBG_CNTX_INFO 0x00000010 +#define DBG_CNTX_WARN 0x00000020 +#define DBG_CNTX_PROFILE 0x00000040 +#define DBG_CNTX_ERROR 0x00000080 +#define DBG_CNTX_ALL 0x000000F0 + +#define DBG_PRIM_INFO 0x00000100 +#define DBG_PRIM_WARN 0x00000200 +#define DBG_PRIM_PROFILE 0x00000400 +#define DBG_PRIM_ERROR 0x00000800 +#define DBG_PRIM_ALL 0x00000F00 + +#define DBG_TXT_INFO 0x00001000 +#define DBG_TXT_WARN 0x00002000 +#define DBG_TXT_PROFILE 0x00004000 +#define DBG_TXT_ERROR 0x00008000 +#define DBG_TXT_ALL 0x0000F000 + +#define DBG_ALL_INFO 0x11111110 +#define DBG_ALL_WARN 0x22222220 +#define DBG_ALL_PROFILE 0x44444440 +#define DBG_ALL_ERROR 0x88888880 +#define DBG_ALL 0xFFFFFFFF + +#ifdef D3D_DEBUG +# define DPF(arg) DebugPrint arg +# define RIP(pH,msg,err) OutputDebugString(msg); \ + OutputDebugString(err); \ + OutputDebugString("\n"); \ + FatalShutDown(pH) +#else +# define DPF(arg) +# define RIP(pH,msg,err) FatalShutDown(pH) +#endif +/*===========================================================================*/ +/* Type defines. */ +/*===========================================================================*/ +/*===========================================================================*/ +/* Function prototypes. */ +/*===========================================================================*/ +extern void ReadDBGEnv( void ); +extern void _cdecl DebugPrint( int mask, char *pszFormat, ... ); +extern void DebugPixelFormat( char *pszSurfaceName, DDPIXELFORMAT *pddpf ); +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +extern DWORD g_DBGMask; + +#ifdef __cplusplus +} +#endif + +#endif + + + + \ 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 index 0000000..40858e6 --- /dev/null +++ b/src/mesa/drivers/d3d/DbgEnv.bat @@ -0,0 +1,25 @@ +SET DBG_FUNC=FALSE + +SET DBG_CNTX_INFO=TRUE +SET DBG_CNTX_WARN=TRUE +SET DBG_CNTX_PROFILE=FALSE +SET DBG_CNTX_ERROR=TRUE +SET DBG_CNTX_ALL=TRUE + +SET DBG_PRIM_INFO=FALSE +SET DBG_PRIM_WARN=FALSE +SET DBG_PRIM_PROFILE=FALSE +SET DBG_PRIM_ERROR=TRUE +SET DBG_PRIM_ALL=FALSE + +SET DBG_TXT_INFO=FALSE +SET DBG_TXT_WARN=TRUE +SET DBG_TXT_PROFILE=FALSE +SET DBG_TXT_ERROR=TRUE +SET DBG_TXT_ALL=FALSE + +SET DBG_ALL_INFO=FALSE +SET DBG_ALL_WARN=TRUE +SET DBG_ALL_PROFILE=FALSE +SET DBG_ALL_ERROR=TRUE +SET DBG_ALL=FALSE diff --git a/src/mesa/drivers/d3d/MAKEFILE b/src/mesa/drivers/d3d/MAKEFILE new file mode 100644 index 0000000..59734cf --- /dev/null +++ b/src/mesa/drivers/d3d/MAKEFILE @@ -0,0 +1,102 @@ +############################################################################## +# +# Mesa-3.0 Makefile for DirectX 6 Driver +# +# By Leigh McRae +# +# http://www.altsoftware.com/ +# +# Copyright (c) 1999-1998 alt.software inc. All Rights Reserved +############################################################################## +NAME= +TARGET= WGL Driver (D3DHAL) + +D3D_DIR=$(MAKEDIR)\D3D +TARGET_DIR=e:\WinNT\System32 +TEMP_DIR=c:\Temp + +SPACE=- +LINKER=link.exe + +INCLUDE=$(SDKROOT)\include;$(INCLUDE) +LIB=$(SDKROOT)\lib;$(LIB) +############################################################################## +CFLAGS = /c /nologo /W1 /G5 /I..\ /I..\..\Include \ + /D "_WIN32" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "MESAD3D" +CPPFLAGS= /c /nologo /W1 /G5 /I..\ /I..\..\Include \ + /D "_WIN32" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "MESAD3D" + +!IF "$(DEBUG)" == "1" + +CFLAGS = /MTd /Od /Z7 /Yd /D "_DEBUG" /D "D3D_DEBUG" $(CFLAGS) +CPPFLAGS = /MTd /Od /Z7 /Yd /D "_DEBUG" /D "D3D_DEBUG" $(CPPFLAGS) +BUILD_TYPE=debug + +!ELSE + +CFLAGS = /MT /Ox /D "NDEBUG" $(CFLAGS) +CPPFLAGS = /MT /Ox /D "NDEBUG" $(CPPFLAGS) +BUILD_TYPE=release + +!ENDIF +############################################################################## +SRCS_WGL = wgl.c D3Dvbrender.c DDrawPROCS.c NULLProcs.c Debug.c +SRCS_HAL = D3DInit.cpp D3DRaster.cpp D3DTextureMgr.cpp D3DUtils.cpp D3DCaps.cpp +OBJS_WGL = $(SRCS_WGL:.c=.obj) +OBJS_HAL = $(SRCS_HAL:.cpp=.obj) + +WINLIBS = kernel32.lib user32.lib gdi32.lib oldnames.lib +DXLIBS = +LIBS = $(WINLIBS) $(DXLIBS) +############################################################################### +# Primary Targets # +############################################################################### + +default: header WGL HAL footer + +all: default + +WGL : $(OBJS_WGL) + +HAL : $(OBJS_HAL) + +install : forceit + @echo $(SPACE) + @echo ======================================== + @echo Install files created. + @echo ======================================== + + +############################################################################### +# Secondary Targets # +############################################################################### + +clean: + @echo ======================================== + @echo Cleaning $(TARGET) + @del *.obj + @del *.dep + @del *.exp + @del *.ncb + @del *.plg + @del *.lib + @echo ======================================== + +header: + @echo ============================================================ + @echo Building $(TARGET) ($(BUILD_TYPE) version) + @echo ============================================================ + @echo $(SPACE) + +footer: + @echo $(SPACE) + @echo ============================================================ + @echo DONE building $(TARGET) ($(BUILD_TYPE) version) + @echo ============================================================ + +forceit: + + + + + \ 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 index 0000000..f0bbd21 --- /dev/null +++ b/src/mesa/drivers/d3d/NULLProcs.h @@ -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 index 0000000..e8f1854 --- /dev/null +++ b/src/mesa/drivers/d3d/NullProcs.c @@ -0,0 +1,130 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 DirectX 6 Driver */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "NULLProcs.h" +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLSetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +GLboolean NULLSetBuffer( GLcontext *ctx, GLenum mode ) +{ + return TRUE; +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) +{ + *width = 1; + *height = 1; +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +GLbitfield NULLClearBuffers( GLcontext *ctx, GLbitfield m, GLboolean a, GLint x, GLint y, GLint w, GLint h ) +{ + return m; +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLWrSpRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][3], const GLubyte m[] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLWrSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][4], const GLubyte m[] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLWrSpRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte m[] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLWrPiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte r[][4], const GLubyte m[] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLWrPiRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte m[] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLReSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte r[][4] ) +{ + +} +/*===========================================================================*/ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +void NULLRePiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte r[][4], const GLubyte m[] ) +{ + +} + + + + + + + + + + + \ 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 index 0000000..19762bb --- /dev/null +++ b/src/mesa/drivers/d3d/OPENGL32.DEF @@ -0,0 +1,443 @@ +;=========================================================================== +; +; Mesa-3.0 DirectX 6 Driver +; +; By Leigh McRae +; +; http://www.altsoftware.com/ +; +; Copyright (c) 1999-1998 alt.software inc. All Rights Reserved +;=========================================================================== +NAME OpenGL32.DLL +DESCRIPTION "Mesa-3.0 DX6 Driver Version 0.5" + +EXPORTS + DllMain + glAccum + glAlphaFunc + glAreTexturesResident + glAreTexturesResidentEXT + glArrayElement + glArrayElementEXT + glBegin + glBindTexture + glBindTextureEXT + glBitmap + glBlendColorEXT + glBlendEquationEXT + glBlendFunc + glCallList + glCallLists + glClear + glClearAccum + glClearColor + glClearDepth + glClearIndex + glClearStencil + glClipPlane + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glColorMask + glColorMaterial + glColorPointer + glColorPointerEXT + glColorSubTableEXT + glColorTableEXT + glCopyPixels + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glCopyTexSubImage3DEXT + glCullFace + glDeleteLists + glDeleteTextures + glDeleteTexturesEXT + glDepthFunc + glDepthMask + glDepthRange + glDisable + glDisableClientState + glDrawArrays + glDrawArraysEXT + glDrawBuffer + glDrawElements + glDrawPixels + glEdgeFlag + glEdgeFlagPointer + glEdgeFlagPointerEXT + glEdgeFlagv + glEnable + glEnableClientState + glEnd + glEndList + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalMesh2 + glEvalPoint1 + glEvalPoint2 + glFeedbackBuffer + glFinish + glFlush + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glFrustum + glGenLists + glGenTextures + glGenTexturesEXT + glGetBooleanv + glGetClipPlane + glGetColorTableEXT + glGetColorTableParameterfvEXT + glGetColorTableParameterivEXT + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPointerv + glGetPointervEXT + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glGetTexParameterfv + glGetTexParameteriv + glHint + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexMask + glIndexPointer + glIndexPointerEXT + glIndexs + glIndexsv + glIndexub + glIndexubv + glInitNames + glInterleavedArrays + glIsEnabled + glIsList + glIsTexture + glIsTextureEXT + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glListBase + glLoadIdentity + glLoadMatrixd + glLoadMatrixf + glLoadName + glLogicOp + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glMatrixMode + glMultMatrixd + glMultMatrixf + glNewList + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glNormalPointer + glNormalPointerEXT + glOrtho + glPassThrough + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glPixelStoref + glPixelStorei + glPixelTransferf + glPixelTransferi + glPixelZoom + glPointParameterfEXT + glPointParameterfvEXT + glPointSize + glPolygonMode + glPolygonOffset + glPolygonOffsetEXT + glPolygonStipple + glPopAttrib + glPopClientAttrib + glPopMatrix + glPopName + glPrioritizeTextures + glPrioritizeTexturesEXT + glPushAttrib + glPushClientAttrib + glPushMatrix + glPushName + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glReadBuffer + glReadPixels + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glRenderMode + glResizeBuffersMESA + glRotated + glRotatef + glScaled + glScalef + glScissor + glSelectBuffer + glShadeModel + glStencilFunc + glStencilMask + glStencilOp + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glTexCoordPointer + glTexCoordPointerEXT + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glTexImage1D + glTexImage2D + glTexImage3DEXT + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexSubImage1D + glTexSubImage2D + glTexSubImage3DEXT + glTranslated + glTranslatef + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glVertexPointer + glVertexPointerEXT + glViewport + glWindowPos2dMESA + glWindowPos2dvMESA + glWindowPos2fMESA + glWindowPos2fvMESA + glWindowPos2iMESA + glWindowPos2ivMESA + glWindowPos2sMESA + glWindowPos2svMESA + glWindowPos3dMESA + glWindowPos3dvMESA + glWindowPos3fMESA + glWindowPos3fvMESA + glWindowPos3iMESA + glWindowPos3ivMESA + glWindowPos3sMESA + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA +; WMesaCreateContext +; WMesaDestroyContext +; WMesaMakeCurrent +; WMesaPaletteChange +; WMesaSwapBuffers +; OSMesaCreateContext +; OSMesaDestroyContext +; OSMesaMakeCurrent +; OSMesaGetCurrentContext +; OSMesaPixelStore +; OSMesaGetIntegerv +; OSMesaGetDepthBuffer + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext +; wglDescribeLayerPlane + wglGetCurrentContext + wglGetCurrentDC +; wglGetLayerPaletteEntries + wglGetProcAddress + wglMakeCurrent +; wglRealizeLayerPalette +; wglSetLayerPaletteEntries + wglShareLists + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + wglChoosePixelFormat + wglDescribePixelFormat + wglGetPixelFormat + wglSetPixelFormat + wglSwapBuffers + + + + \ 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 index 0000000..2d1a6a0 --- /dev/null +++ b/src/mesa/drivers/d3d/WGL.C @@ -0,0 +1,1262 @@ +/*===========================================================================*/ +/* */ +/* Mesa-3.0 Makefile for DirectX 6 */ +/* */ +/* By Leigh McRae */ +/* */ +/* http://www.altsoftware.com/ */ +/* */ +/* Copyright (c) 1998-1997 alt.software inc. All Rights Reserved */ +/*===========================================================================*/ +#include "D3DMesa.h" +/*===========================================================================*/ +/* Window managment. */ +/*===========================================================================*/ +static BOOL InitOpenGL( HINSTANCE hInst ); +static BOOL TermOpenGL( HINSTANCE hInst ); +static BOOL ResizeContext( GLcontext *ctx ); +static BOOL MakeCurrent( D3DMESACONTEXT *pContext ); +static void DestroyContext( D3DMESACONTEXT *pContext ); +static BOOL UnBindWindow( D3DMESACONTEXT *pContext ); +LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ); +/*===========================================================================*/ +/* Mesa hooks. */ +/*===========================================================================*/ +static void SetupDDPointers( GLcontext *ctx ); +static void SetupSWDDPointers( GLcontext *ctx ); +static void SetupHWDDPointers( GLcontext *ctx ); +static void SetupNULLDDPointers( GLcontext *ctx ); +static const char *RendererString( void ); + +/* State Management hooks. */ +static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); +static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ); +static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ); + +/* Window Management hooks. */ +static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ); +static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ); +static void Flush( GLcontext *ctx ); + +/* Span rendering hooks. */ +void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ); +void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ); +void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] ); +void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] ); +void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] ); +void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] ); +void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] ); +GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); + +/* Primitve rendering hooks. */ +GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone ); +void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv ); +void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ); +GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ); + +/* Texture Management hooks. */ +static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ); +static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ); +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 ); +/*===========================================================================*/ +/* Global variables. */ +/*===========================================================================*/ +D3DMESACONTEXT *pD3DCurrent, + *pD3DDefault; /* Thin support context. */ + +struct __extensions__ ext[] = { + + { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, + { (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" }, +}; + +int qt_ext = sizeof(ext) / sizeof(ext[0]); +float g_DepthScale, + g_MaxDepth; +/*===========================================================================*/ +/* When a process loads this DLL we will setup the linked list for context */ +/* management and create a default context that will support the API until */ +/* the user creates and binds thier own. This THIN default context is useful*/ +/* to have around. */ +/* When the process terminates we will clean up all resources here. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved ) +{ + switch( reason ) + { + case DLL_PROCESS_ATTACH: + return InitOpenGL( hInst ); + + case DLL_PROCESS_DETACH: + return TermOpenGL( hInst ); + } + + return TRUE; +} +/*===========================================================================*/ +/* The first thing we do when this dll is hit is connect to the dll that has*/ +/* handles all the DirectX 6 rendering. I decided to use another dll as DX6 */ +/* is all C++ and Mesa-3.0 is C (thats a good thing). This way I can write */ +/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage. */ +/* I feel this is easy and better then using static wrappers as it is likely */ +/* faster and it allows me to just develope the one without compiling the */ +/* other. */ +/* NOTE that at this point we don't have much other than a very thin context*/ +/* that will support the API calls only to the point of not causing the app */ +/* to crash from the API table being empty. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL InitOpenGL( HINSTANCE hInst ) +{ + /* Allocate and clear the default context. */ + pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); + if ( pD3DDefault == NULL ) + return FALSE; + memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) ); + + /* Clear the D3D vertex buffer so that values not used will be zero. This */ + /* save me from some redundant work. */ + memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) ); + + /* Update the link. We uses a circular list so that it is easy to */ + /* add and search. This context will also be used for head and tail.*/ + pD3DDefault->next = pD3DDefault; + + /*========================================================================*/ + /* Do all core Mesa stuff. */ + /*========================================================================*/ + pD3DDefault->gl_visual = gl_create_visual( TRUE, + GL_FALSE, /* software alpha */ + FALSE, /* 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 ( pD3DDefault->gl_visual == NULL) + { + FREE( pD3DDefault ); + return FALSE; + } + + /* Allocate a new Mesa context */ + pD3DDefault->gl_ctx = gl_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE ); + if ( pD3DDefault->gl_ctx == NULL ) + { + gl_destroy_visual( pD3DDefault->gl_visual ); + FREE( pD3DDefault ); + return FALSE; + } + + /* Allocate a new Mesa frame buffer */ + pD3DDefault->gl_buffer = gl_create_framebuffer( pD3DDefault->gl_visual ); + if ( pD3DDefault->gl_buffer == NULL ) + { + gl_destroy_visual( pD3DDefault->gl_visual ); + gl_destroy_context( pD3DDefault->gl_ctx ); + FREE( pD3DDefault ); + return FALSE; + } + SetupDDPointers( pD3DDefault->gl_ctx ); + gl_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer ); + + return TRUE; +} +/*===========================================================================*/ +/* This function will create a new D3D context but will not create the D3D */ +/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/ +/* done here is the internal Mesa stuff and some Win32 handles. */ +/*===========================================================================*/ +/* RETURN: casted pointer to the context, NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglCreateContext( HDC hdc ) +{ + D3DMESACONTEXT *pNewContext; + DWORD dwCoopFlags = DDSCL_NORMAL; + RECT rectClient; + POINT pt; + + /* ALLOC and clear the new context. */ + pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) ); + if ( pNewContext == NULL ) + { + SetLastError( 0 ); + return (HGLRC)NULL; + } + memset( pNewContext, 0, sizeof(D3DMESACONTEXT) ); + + /*========================================================================*/ + /* Do all core Mesa stuff. */ + /*========================================================================*/ + + /* TODO: support more then one visual. */ + pNewContext->gl_visual = gl_create_visual( TRUE, + GL_TRUE, /* software alpha */ + TRUE, /* 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 ( pNewContext->gl_visual == NULL) + { + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /* Allocate a new Mesa context */ + pNewContext->gl_ctx = gl_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE ); + if ( pNewContext->gl_ctx == NULL ) + { + gl_destroy_visual( pNewContext->gl_visual ); + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /* Allocate a new Mesa frame buffer */ + pNewContext->gl_buffer = gl_create_framebuffer( pNewContext->gl_visual ); + if ( pNewContext->gl_buffer == NULL ) + { + gl_destroy_visual( pNewContext->gl_visual ); + gl_destroy_context( pNewContext->gl_ctx ); + FREE( pNewContext ); + SetLastError( 0 ); + return (HGLRC)NULL; + } + + /*========================================================================*/ + /* Do all the driver stuff. */ + /*========================================================================*/ + pNewContext->hdc = hdc; + pNewContext->next = pD3DDefault->next; + pD3DDefault->next = pNewContext; /* Add to circular list. */ + + /* Create the HAL for the new context. */ + pNewContext->pShared = InitHAL( WindowFromDC(hdc) ); + + return (HGLRC)pNewContext; +} +/*===========================================================================*/ +/* This is a wrapper function that is supported by MakeCurrent. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglMakeCurrent( HDC hdc, HGLRC hglrc ) +{ + return MakeCurrent((D3DMESACONTEXT *)hglrc); +} +/*===========================================================================*/ +/* MakeCurrent will unbind whatever context is current (if any) & then bind */ +/* the supplied context. A context that is bound has it's window proc hooked*/ +/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent. */ +/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/ +/* the viewport (Mesa-.30 and DX6). */ +/* */ +/* TODO: this function can't fail. */ +/*===========================================================================*/ +/* RETURN: TRUE */ +/*===========================================================================*/ +static BOOL MakeCurrent( D3DMESACONTEXT *pContext ) +{ + D3DMESACONTEXT *pNext; + + /*====================================================================*/ + /* This is a special case that is a request to have no context bound. */ + /*====================================================================*/ + if ( pContext == NULL ) + { + /* Walk the whole list. We start and end at the Default context. */ + for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next ) + UnBindWindow( pNext ); + + return TRUE; + } + + /*=================================================*/ + /* Make for a fast redundant use of this function. */ + /*=================================================*/ + if ( pD3DCurrent == pContext ) + return TRUE; + + /*=============================*/ + /* Unbind the current context. */ + /*=============================*/ + UnBindWindow( pD3DCurrent ); + + /*=====================================*/ + /* Let Mesa-3.0 we have a new context. */ + /*=====================================*/ + SetupDDPointers( pContext->gl_ctx ); + gl_make_current( pContext->gl_ctx, pContext->gl_buffer ); + + /* We are done so set the internal current context. */ + if ( pContext != pD3DDefault ) + { + ResizeContext( pContext->gl_ctx ); + pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC ); + SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc ); + } + pD3DCurrent = pContext; + + return TRUE; +} +/*===========================================================================*/ +/* This function will only return the current window size. I have re-done */ +/* this function so that it doesn't check the current size and react to it as*/ +/* I should be able to have all the react code in the WM_SIZE message. The */ +/* old version would check the current window size and create/resize the HAL */ +/* surfaces if they have changed. I needed to delay the creation if the */ +/* surfaces because sometimes I wouldn't have a window size so this is where */ +/* I delayed it. If you are reading this then all went ok! */ +/* The default context will return a zero sized window and I'm not sure if */ +/* this is ok at this point (TODO). */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* Fall through for the default because that is one of the uses for it. */ + if ( pContext == pD3DDefault ) + { + *width = 0; + *height = 0; + } + else + { + *width = pContext->pShared->dwWidth; + *height = pContext->pShared->dwHeight; + } +} +/*===========================================================================*/ +/* */ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static BOOL ResizeContext( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx, + *pCurrentTemp; + RECT rectClient; + POINT pt; + DWORD dwWidth, + dwHeight; + static BOOL bDDrawLock = FALSE; + + /* Make sure we have some values. */ + if ( (pContext->hdc == NULL ) || + (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) || + (pContext == pD3DDefault) ) + return FALSE; + + /* Having problems with DDraw sending resize messages before I was done. */ + if( bDDrawLock == TRUE ) + return FALSE; + + // TODO: don't think I need this anymore. + pCurrentTemp = pD3DCurrent; + pD3DCurrent = pD3DDefault; + bDDrawLock = TRUE; + + /* Get the current window dimentions. */ + UpdateScreenPosHAL( pContext->pShared ); + dwWidth = pContext->pShared->rectW.right - pContext->pShared->rectW.left; + dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top; + + /* Is the size of the OffScreen Render different? */ + if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) ) + { + /* Create all the D3D surfaces and device. */ + CreateHAL( pContext->pShared ); + + /* I did this so that software rendering would still work as */ + /* I don't need to scale the z values twice. */ + g_DepthScale = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); + g_MaxDepth = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF); + gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far ); + + /* Make sure we have a viewport. */ + gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight ); + + /* Update Mesa as we might have changed from SW <-> HW. */ + SetupDDPointers( pContext->gl_ctx ); + gl_make_current( pContext->gl_ctx, pContext->gl_buffer ); + + /* If we are in HW we need to load the current texture if there is one already. */ + // if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) && + // (pContext->pShared->bHardware == TRUE) ) + // { + // CreateTMgrHAL( pContext->pShared, + // ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name, + // 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 ); + // } + } + + // TODO: don't think I need this anymore. + pD3DCurrent = pCurrentTemp; + bDDrawLock = FALSE; + + return TRUE; +} + +/*===========================================================================* +/* This function will Blt the render buffer to the PRIMARY surface. I repeat*/ +/* this code for the other SwapBuffer like functions and the flush (didn't */ +/* want the function calling overhead). Thsi could have been a macro... */ +/* */ +/* TODO: there are some problems with viewport/scissoring. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSwapBuffers( HDC hdc ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return FALSE; + + SwapBuffersHAL( pD3DCurrent->pShared ); + + return TRUE; +} +/*===========================================================================*/ +/* Same as wglSwapBuffers. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY SwapBuffers( HDC hdc ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return FALSE; + + SwapBuffersHAL( pD3DCurrent->pShared ); + + return TRUE; +} +/*===========================================================================*/ +/* This should be ok as none of the SwapBuffers will cause a redundant Blt */ +/* as none of my Swap functions will call flush. This should also allow */ +/* sinlge buffered applications to work (not really worried though). Some */ +/* applications may flush then swap but then this is there fault IMHO. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void Flush( GLcontext *ctx ) +{ + /* Fall through for the default because that is one of the uses for it. */ + if ( pD3DCurrent == pD3DDefault ) + return; + + SwapBuffersHAL( pD3DCurrent->pShared ); +} +/*===========================================================================*/ +/* For now this function will ignore the supplied PF. If I'm going to allow */ +/* the user to choice the mode and device at startup I'm going to have to do */ +/* something different. */ +/* */ +/* TODO: use the linked list of modes to build a pixel format to be returned */ +/* to the caller. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return 1; +} +/*===========================================================================*/ +/* See wglChoosePixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return wglChoosePixelFormat(hdc,ppfd); +} +/*===========================================================================*/ +/* This function (for now) returns a static PF everytime. This is just to */ +/* allow things to continue. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) +{ + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; + + /* Return the address of this static PF if one was requested. */ + if ( ppfd != NULL ) + memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) ); + + return 1; +} +/*===========================================================================*/ +/* See wglDescribePixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd ) +{ + return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd); +} +/*===========================================================================*/ +/* This function will always return 1 for now. Just to allow for support. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY wglGetPixelFormat( HDC hdc ) +{ + return 1; +} +/*===========================================================================*/ +/* See wglGetPixelFormat. */ +/*===========================================================================*/ +/* RETURN: 1. */ +/*===========================================================================*/ +int APIENTRY GetPixelFormat( HDC hdc ) +{ + return wglGetPixelFormat(hdc); +} +/*===========================================================================*/ +/* This will aways work for now. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return TRUE; +} +/*===========================================================================*/ +/* See wglSetPixelFormat. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd ) +{ + return wglSetPixelFormat(hdc,iPixelFormat,ppfd); +} +/*===========================================================================*/ +/* This is a wrapper function that is supported by my own internal function.*/ +/* that takes my own D3D Mesa context structure. This so I can reuse the */ +/* function (no need for speed). */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +BOOL APIENTRY wglDeleteContext( HGLRC hglrc ) +{ + DestroyContext( (D3DMESACONTEXT *)hglrc ); + + return TRUE; +} +/*===========================================================================*/ +/* Simple getter function that uses a cast. */ +/*===========================================================================*/ +/* RETURN: casted pointer to the context, NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglGetCurrentContext( VOID ) +{ + return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: NULL. */ +/*===========================================================================*/ +HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane ) +{ + SetLastError( 0 ); + return (HGLRC)NULL; +} +/*===========================================================================*/ +/* Simple getter function. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +HDC APIENTRY wglGetCurrentDC( VOID ) +{ + return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL; +} +/*===========================================================================*/ +/* Simply call that searches the supported extensions for a match & returns */ +/* the pointer to the function that lends support. */ +/*===========================================================================*/ +/* RETURN: pointer to API call, NULL. */ +/*===========================================================================*/ +PROC APIENTRY wglGetProcAddress( LPCSTR lpszProc ) +{ + int index; + + for( index = 0; index < qt_ext; index++ ) + if( !strcmp(lpszProc,ext[index].name) ) + return ext[index].proc; + + SetLastError( 0 ); + return NULL; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglShareLists( HGLRC hglrc1, HGLRC hglrc2 ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf ) +{ + SetLastError( 0 ); + return FALSE ; +} +/*===========================================================================*/ +/* No support. */ +/*===========================================================================*/ +/* RETURN: FALSE. */ +/*===========================================================================*/ +BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, UINT fuPlanes ) +{ + SetLastError( 0 ); + return FALSE; +} +/*===========================================================================*/ +/* This function will be hooked into the window that has been bound. Right */ +/* now it is used to track the window size and position. Also the we clean */ +/* up the currrent context when the window is close/destroyed. */ +/* */ +/* TODO: there might be something wrong here as some games (Heretic II) don't*/ +/* track the window quit right. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +LONG APIENTRY wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam ) +{ + WNDPROC hOldProc; + GLint width, + height; + + switch( message ) + { +// case WM_PAINT: +// break; +// case WM_ACTIVATE: +// break; +// case WM_SHOWWINDOW: +// break; + + case UM_FATALSHUTDOWN: + /* Support the API until we die... */ + MakeCurrent( pD3DDefault ); + break; + + case WM_MOVE: + case WM_DISPLAYCHANGE: + case WM_SIZE: + ResizeContext( pD3DCurrent->gl_ctx ); + break; + + case WM_CLOSE: + case WM_DESTROY: + /* Support the API until we die... */ + hOldProc = pD3DCurrent->hOldProc; + DestroyContext( pD3DCurrent ); + return (hOldProc)(hwnd,message,wParam,lParam); + } + + return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam); +} + +/**********************************************************************/ +/***** Miscellaneous device driver funcs *****/ +/**********************************************************************/ + +/*===========================================================================*/ +/* Not reacting to this as I'm only supporting drawing to the back buffer */ +/* right now. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer ) +{ + if (buffer == GL_BACK_LEFT) + return GL_TRUE; + else + return GL_FALSE; +} +/*===========================================================================*/ +/* This proc will be called by Mesa when the viewport has been set. So if */ +/* we have a context and it isn't the default then we should let D3D know of */ +/* the change. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + RECT rect; + + /* Make sure we can set a viewport. */ + if ( pContext->pShared && (pContext != pD3DDefault) ) + { + // TODO: might be needed. + UpdateScreenPosHAL( pContext->pShared ); + rect.left = x; + rect.right = x + w; + rect.top = y; + rect.bottom = y + h; + + // TODO: shared struct should make this call smaller + SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F ); + } +} +/*===========================================================================*/ +/* This function could be better I guess but I decided just to grab the four*/ +/* components and store then seperately. Makes it easier to use IMHO. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + pContext->aClear = a; + pContext->bClear = b; + pContext->gClear = g; + pContext->rClear = r; +} +/*===========================================================================*/ +/* This function could be better I guess but I decided just to grab the four*/ +/* components and store then seperately. Makes it easier to use IMHO. */ +/* (is there an echo in here?) */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + pContext->aCurrent = a; + pContext->bCurrent = b; + pContext->gCurrent = g; + pContext->rCurrent = r; +} +/*===========================================================================*/ +/* */ +/* */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static const char *RendererString( void ) +{ + static char pszRender[64]; + + strcpy( pszRender, "altD3D " ); + + if ( pD3DCurrent->pShared->bHardware ) + strcat( pszRender, "(HW)"); + else + strcat( pszRender, "(SW)"); + + return (const char *)pszRender; +} +/*===========================================================================*/ +/* This function will choose which set of pointers Mesa will use based on */ +/* whether we hard using hardware or software. I have added another set of */ +/* pointers that will do nothing but stop the API from crashing. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void SetupDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + // TODO: write a generic NULL support for the span render. + if ( pContext->pShared && pContext->pShared->bHardware ) + { + ctx->Driver.UpdateState = SetupHWDDPointers; + } + else if ( pContext == pD3DDefault ) + { + ctx->Driver.UpdateState = SetupNULLDDPointers; + } + else + { + ctx->Driver.UpdateState = SetupSWDDPointers; + } +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. This version of */ +/* hooks will do nothing but support the API when we don't have a valid */ +/* context bound. This is mostly for applications that don't behave right */ +/* and also to help exit as clean as possable when we have a FatalError. */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupNULLDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* 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 = SetupNULLDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = NULLSetColor; + ctx->Driver.ClearColor = NULLClearColor; + ctx->Driver.Clear = NULLClearBuffers; + ctx->Driver.SetBuffer = NULLSetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = NULLGetBufferSize; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = NULL; + ctx->Driver.RenderVB = NULL; + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = NULLWrSpRGBA; + ctx->Driver.WriteRGBSpan = NULLWrSpRGB; + ctx->Driver.WriteMonoRGBASpan = NULLWrSpRGBAMono; + ctx->Driver.WriteRGBAPixels = NULLWrPiRGBA; + ctx->Driver.WriteMonoRGBAPixels = NULLWrPiRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = NULLReSpRGBA; + ctx->Driver.ReadRGBAPixels = NULLRePiRGBA; + + /* Misc. hooks. */ + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. There are two of */ +/* these functions. One if we have hardware support and one is there is only*/ +/* software. These functions will be called by Mesa and by the wgl.c when we*/ +/* have resized (or created) the buffers. The thing is that if a window gets*/ +/* resized we may loose hardware support or gain it... */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupSWDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* 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 = SetupSWDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = SetColor; + ctx->Driver.ClearColor = ClearColor; + ctx->Driver.Clear = ClearBuffers; + ctx->Driver.SetBuffer = SetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = GetBufferSize; + ctx->Driver.Viewport = SetViewport; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = NULL; + ctx->Driver.RenderVB = NULL; + + /* Texture management hooks. */ + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = WSpanRGBA; + ctx->Driver.WriteRGBSpan = WSpanRGB; + ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; + ctx->Driver.WriteRGBAPixels = WPixelsRGBA; + ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = RSpanRGBA; + ctx->Driver.ReadRGBAPixels = RPixelsRGBA; + + /* Misc. hooks. */ + ctx->Driver.Flush = Flush; + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will populate all the Mesa driver hooks. There are two of */ +/* these functions. One if we have hardware support and one is there is only*/ +/* software. These functions will be called by Mesa and by the wgl.c when we*/ +/* have resized (or created) the buffers. The thing is that if a window gets*/ +/* resized we may loose hardware support or gain it... */ +/*===========================================================================*/ +/* RETURN: pointer to the specific function. */ +/*===========================================================================*/ +static void SetupHWDDPointers( GLcontext *ctx ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* 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 = SetupHWDDPointers; + + /* State management hooks. */ + ctx->Driver.Color = SetColor; + ctx->Driver.ClearColor = ClearColor; + ctx->Driver.Clear = ClearBuffersD3D; + ctx->Driver.SetBuffer = SetBuffer; + + /* Window management hooks. */ + ctx->Driver.GetBufferSize = GetBufferSize; + ctx->Driver.Viewport = SetViewport; + + /* Primitive rendering hooks. */ + ctx->Driver.TriangleFunc = RenderOneTriangle; + ctx->Driver.LineFunc = RenderOneLine; + ctx->Driver.RenderVB = RenderVertexBuffer; + + /* Pixel/span writing functions: */ + ctx->Driver.WriteRGBASpan = WSpanRGBA; + ctx->Driver.WriteRGBSpan = WSpanRGB; + ctx->Driver.WriteMonoRGBASpan = WSpanRGBAMono; + ctx->Driver.WriteRGBAPixels = WPixelsRGBA; + ctx->Driver.WriteMonoRGBAPixels = WPixelsRGBAMono; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadRGBASpan = RSpanRGBA; + ctx->Driver.ReadRGBAPixels = RPixelsRGBA; + + /* Texture management hooks. */ + // ctx->Driver.BindTexture = TextureBind; + ctx->Driver.TexImage = TextureLoad; + ctx->Driver.TexSubImage = TextureSubImage; + + /* Misc. hooks. */ + ctx->Driver.Flush = Flush; + ctx->Driver.RendererString = RendererString; +} +/*===========================================================================*/ +/* This function will release all resources used by the DLL. Every context */ +/* will be clobbered by releaseing all driver desources and then freeing the */ +/* context memory. Most all the work is done in DestroyContext. */ +/*===========================================================================*/ +/* RETURN: TRUE. */ +/*===========================================================================*/ +static BOOL TermOpenGL( HINSTANCE hInst ) +{ + D3DMESACONTEXT *pTmp, + *pNext; + + /* Just incase we are still getting paint msg. */ + MakeCurrent( pD3DDefault ); + + /* Walk the list until we get back to the default context. */ + for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext ) + { + pNext = pTmp->next; + DestroyContext( pTmp ); + } + DestroyContext( pD3DDefault ); + + return TRUE; +} +/*===========================================================================*/ +/* This function is an internal function that will clean up all the Mesa */ +/* context bound to this D3D context. Also any D3D stuff that this context */ +/* uses will be unloaded. */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static void DestroyContext( D3DMESACONTEXT *pContext ) +{ + D3DMESACONTEXT *pTmp; + + /* Walk the list until we find the context before this one. */ + for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next ) + if ( pTmp == pTmp->next ) + break; + + /* If we never found it it must already be deleted. */ + if ( pTmp->next != pContext ) + return; + + /* Make sure we are not using this context. */ + if ( pContext == pD3DCurrent ) + MakeCurrent( pD3DDefault ); + + /* Free the Mesa stuff. */ + if ( pContext->gl_visual ) + { + gl_destroy_visual( pContext->gl_visual ); + pContext->gl_visual = NULL; + } + if ( pContext->gl_buffer ) + { + gl_destroy_framebuffer( pContext->gl_buffer ); + pContext->gl_buffer = NULL; + } + if ( pContext->gl_ctx ) + { + gl_destroy_context( pContext->gl_ctx ); + pContext->gl_ctx = NULL; + } + + /* Now dump the D3D. */ + if ( pContext->pShared ) + TermHAL( pContext->pShared ); + + /* Update the previous context's link. */ + pTmp->next = pContext->next; + + /* Gonzo. */ + FREE( pContext ); +} +/*===========================================================================*/ +/* This function will pull the supplied context away from Win32. Basicly it*/ +/* will remove the hook from the window Proc. */ +/* */ +/* TODO: might want to serialize this stuff... */ +/*===========================================================================*/ +/* RETURN: TRUE, FALSE. */ +/*===========================================================================*/ +static BOOL UnBindWindow( D3DMESACONTEXT *pContext ) +{ + if ( pContext == NULL ) + return FALSE; + + if ( pContext == pD3DDefault ) + return TRUE; + + /* Make sure we always have a context bound. */ + if ( pContext == pD3DCurrent ) + pD3DCurrent = pD3DDefault; + + SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc ); + pContext->hOldProc = NULL; + + return TRUE; +} +/*===========================================================================*/ +/* There are two cases that allow for a faster clear when we know that the */ +/* whole buffer is cleared and that there is no clipping. */ +/*===========================================================================*/ +/* RETURN: the original mask with the bits cleared that represents the buffer* +/* or buffers we just cleared. */ +/*===========================================================================*/ +GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + DWORD dwFlags = 0; + + if ( mask & GL_COLOR_BUFFER_BIT ) + { + dwFlags |= D3DCLEAR_TARGET; + mask &= ~GL_COLOR_BUFFER_BIT; + } + if ( mask & GL_DEPTH_BUFFER_BIT ) + { + dwFlags |= D3DCLEAR_ZBUFFER; + mask &= ~GL_DEPTH_BUFFER_BIT; + } + if ( dwFlags == 0 ) + return mask; + + ClearHAL( pContext->pShared, + dwFlags, + all, + x, y, + width, height, + ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)), + ctx->Depth.Clear, + 0 ); + + return mask; +} + + + +/*===========================================================================*/ +/* TEXTURE MANAGER: ok here is how I did textures. Mesa-3.0 will keep track*/ +/* of all the textures for us. So this means that at anytime we can go to */ +/* the Mesa context and get the current texture. With this in mind this is */ +/* what I did. I really don't care about what textures get or are loaded */ +/* until I actually have to draw a tri that is textured. At this point I */ +/* must have the texture so I demand the texture by destorying all other */ +/* texture surfaces if need be and load the current one. This allows for the*/ +/* best preformance on low memory cards as time is not wasted loading and */ +/* unload textures. */ +/*===========================================================================*/ + + + + + +/*===========================================================================*/ +/* TextureLoad will try and create a D3D surface from the supplied texture */ +/* object if its level 0 (first). The surface will be fully filled with the */ +/* texture. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* TODO: only doing first LOD. */ + if ( (ctx->DriverCtx == NULL) || (level != 0) ) + return; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + level, + tObj->Image[level]->Format, + (RECT *)NULL, + tObj->Image[level]->Width, + tObj->Image[level]->Height, + TM_ACTION_LOAD, + (void *)tObj->Image[level]->Data ); +} +/*===========================================================================*/ +/* TextureBind make sure that the texture is on the card. Thats it. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + + /* TODO: only doing first LOD. */ + if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) ) + return; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + 0, + tObj->Image[0]->Format, + (RECT *)NULL, + tObj->Image[0]->Width, + tObj->Image[0]->Height, + TM_ACTION_BIND, + (void *)tObj->Image[0]->Data ); +} +/*===========================================================================*/ +/* TextureSubImage will make sure that the texture being updated is updated */ +/* if its on the card. */ +/*===========================================================================*/ +/* RETURN: */ +/*===========================================================================*/ +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 ) +{ + D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx; + RECT rect; + + /* TODO: only doing first LOD. */ + if ( (ctx->DriverCtx == NULL) || (level > 0) ) + return; + + /* Create a dirty rectangle structure. */ + rect.left = xoffset; + rect.right = xoffset + width; + rect.top = yoffset; + rect.bottom = yoffset + height; + + CreateTMgrHAL( pContext->pShared, + tObj->Name, + 0, + tObj->Image[0]->Format, + &rect, + tObj->Image[0]->Width, + tObj->Image[0]->Height, + TM_ACTION_UPDATE, + (void *)tObj->Image[0]->Data ); +} + diff --git a/src/mesa/drivers/d3d/d3dText.h b/src/mesa/drivers/d3d/d3dText.h new file mode 100644 index 0000000..9ff0650 --- /dev/null +++ b/src/mesa/drivers/d3d/d3dText.h @@ -0,0 +1,53 @@ +#ifndef D3D_TEXT_H +#define D3D_TEXT_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/*===========================================================================*/ +/* Includes. */ +/*===========================================================================*/ +#include +#include +#include +/*===========================================================================*/ +/* 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 index 0000000..60a0fdc --- /dev/null +++ b/src/mesa/drivers/dos/DEPEND.DOS @@ -0,0 +1,119 @@ +# DO NOT DELETE + +accum.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +accum.obj: dlist.h macros.h +alpha.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +alpha.obj: dlist.h macros.h +alphabuf.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +alphabuf.obj: context.h macros.h +api1.obj: api.h bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +api1.obj: eval.h image.h macros.h matrix.h teximage.h +api2.obj: api.h bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +api2.obj: eval.h image.h macros.h matrix.h teximage.h +attrib.obj: attrib.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +attrib.obj: draw.h dlist.h macros.h +bitmap.obj: bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +bitmap.obj: feedback.h image.h macros.h pb.h +blend.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h blend.h +blend.obj: context.h dlist.h macros.h pb.h span.h +bresenhm.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +clip.obj: clip.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +clip.obj: dlist.h macros.h matrix.h vb.h xform.h +context.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h +context.obj: draw.h eval.h light.h lines.h dlist.h macros.h pb.h points.h +context.obj: pointers.h triangle.h teximage.h texobj.h texture.h vb.h vertex.h +copypix.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +copypix.obj: copypix.h depth.h feedback.h dlist.h macros.h pixel.h span.h +copypix.obj: stencil.h +depth.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h +depth.obj: dlist.h macros.h +dlist.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alpha.h +dlist.obj: attrib.h bitmap.h blend.h clip.h context.h copypix.h depth.h draw.h +dlist.obj: drawpix.h enable.h eval.h feedback.h fog.h image.h light.h lines.h +dlist.obj: dlist.h logic.h macros.h masking.h matrix.h misc.h pixel.h points.h +dlist.obj: polygon.h scissor.h stencil.h texobj.h teximage.h texture.h vb.h +dlist.obj: vertex.h winpos.h +draw.obj: clip.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +draw.obj: draw.h feedback.h fog.h light.h lines.h dlist.h macros.h matrix.h +draw.obj: pb.h points.h texture.h vb.h xform.h +drawpix.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +drawpix.obj: drawpix.h feedback.h dlist.h macros.h pixel.h span.h stencil.h +enable.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h +enable.obj: draw.h enable.h light.h dlist.h macros.h stencil.h +eval.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h draw.h +eval.obj: eval.h dlist.h macros.h +feedback.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +feedback.obj: feedback.h dlist.h macros.h +fog.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h fog.h +fog.obj: dlist.h macros.h +get.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h get.h +get.obj: dlist.h macros.h +hash.obj: hash.h +interp.obj: interp.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h +image.obj: image.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h +image.obj: pixel.h +light.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h light.h +light.obj: dlist.h macros.h matrix.h vb.h xform.h +lines.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +lines.obj: context.h feedback.h interp.h lines.h dlist.h macros.h pb.h vb.h +logic.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h +logic.obj: logic.h macros.h pb.h +masking.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +masking.obj: context.h macros.h masking.h pb.h +matrix.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h +matrix.obj: context.h depth.h dlist.h macros.h matrix.h stencil.h +misc.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h +misc.obj: context.h depth.h macros.h masking.h misc.h stencil.h +pb.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h +pb.obj: blend.h depth.h fog.h logic.h macros.h masking.h pb.h scissor.h +pb.obj: stencil.h texture.h +pixel.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h +pixel.obj: macros.h pixel.h image.h span.h stencil.h +points.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +points.obj: feedback.h dlist.h macros.h pb.h span.h vb.h +pointers.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alpha.h +pointers.obj: attrib.h bitmap.h blend.h clip.h context.h copypix.h depth.h +pointers.obj: draw.h drawpix.h enable.h eval.h feedback.h fog.h get.h light.h +pointers.obj: lines.h dlist.h logic.h macros.h masking.h matrix.h misc.h +pointers.obj: pixel.h points.h polygon.h readpix.h scissor.h stencil.h +pointers.obj: teximage.h texobj.h texture.h varray.h vb.h vertex.h winpos.h +polygon.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +polygon.obj: macros.h polygon.h +readpix.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +readpix.obj: context.h depth.h feedback.h dlist.h macros.h image.h readpix.h +readpix.obj: span.h stencil.h +scissor.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +scissor.obj: macros.h dlist.h scissor.h +span.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h +span.obj: blend.h depth.h fog.h logic.h macros.h masking.h scissor.h span.h +span.obj: stencil.h texture.h +stencil.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h +stencil.obj: macros.h pb.h stencil.h +teximage.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +teximage.obj: image.h macros.h pixel.h span.h teximage.h +texobj.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h +texobj.obj: teximage.h texobj.h +texture.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h +texture.obj: macros.h pb.h teximage.h texture.h +triangle.obj: depth.h types.h ..\include\GL\gl.h config.h fixed.h dd.h +triangle.obj: feedback.h macros.h span.h triangle.h vb.h tritemp.h +varray.obj: draw.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h +varray.obj: enable.h dlist.h macros.h varray.h vb.h xform.h +vb.obj: types.h ..\include\GL\gl.h config.h fixed.h dd.h vb.h +vertex.obj: draw.h types.h ..\include\GL\gl.h config.h fixed.h dd.h light.h +vertex.obj: dlist.h macros.h vb.h vertex.h +winpos.obj: ..\include\GL\gl.h draw.h types.h config.h fixed.h dd.h dlist.h +winpos.obj: macros.h winpos.h +xform.obj: types.h ..\include\GL\gl.h config.h fixed.h dd.h xform.h +glx.obj: ..\include\GL\gl.h ..\include\GL\glx.h ..\include\GL\xmesa.h context.h +glx.obj: types.h config.h fixed.h dd.h macros.h xmesaP.h +osmesa.obj: ..\include\GL\osmesa.h ..\include\GL\gl.h context.h types.h +osmesa.obj: config.h fixed.h dd.h depth.h macros.h matrix.h vb.h tritemp.h +xfonts.obj: ..\include\GL\gl.h ..\include\GL\xmesa.h macros.h xmesaP.h types.h +xfonts.obj: config.h fixed.h dd.h context.h +xmesa1.obj: ..\include\GL\xmesa.h ..\include\GL\gl.h xmesaP.h types.h config.h +xmesa1.obj: fixed.h dd.h context.h macros.h matrix.h +xmesa2.obj: ..\include\GL\xmesa.h ..\include\GL\gl.h macros.h types.h config.h +xmesa2.obj: fixed.h dd.h xmesaP.h +xmesa3.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h +xmesa3.obj: interp.h macros.h vb.h xmesaP.h ..\include\GL\xmesa.h tritemp.h diff --git a/src/mesa/drivers/dos/dosmesa.c b/src/mesa/drivers/dos/dosmesa.c new file mode 100644 index 0000000..2f39732 --- /dev/null +++ b/src/mesa/drivers/dos/dosmesa.c @@ -0,0 +1,1513 @@ +/* $Id: dosmesa.c,v 1.1 1999/08/19 00:55:41 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: 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 + * + * + * Revision 1.5 1997/06/19 22:00:00 Brian Paul + * Removed all ColorShift stuff + * + * Revision 1.4 1997/06/03 19:00:00 Brian Paul + * Replaced VB->Unclipped[] with VB->ClipMask[] + * + * Revision 1.3 1997/05/28 07:00:00 Phil Frisbie, Jr. + * Now pass red/green/blue/alpha bits to gl_create_visual() + * Fixed DJGPP mode 13 support. + * + * Revision 1.2 1996/12/08 16:13:45 Charlie + * Added VESA support via Scitechs SVGA kit. + * + * Revision 1.1 1996/12/08 16:09:52 Charlie + * Initial revision + * + */ + + +/* + * DOS VGA/VESA/MGL/Mesa interface. + * + */ + +/* + * + * TODO: (cw) + * Improve the colour matcher for rgb non vesa modes, its pretty bad and incorrect + * Keyboard interrupt. + * Comments and tidy up. + * Add support for VESA without SVGAKIT. + * DirectX Support. + * Better GLIDE Support. + * Clear up the #ifdef madness. + */ + +#ifdef DOSVGA + +#if defined(DOSVGA) && !defined(GLIDE) && defined(DJGPP) && !defined(UNIVBE) && !defined(MGL) + +/* Should help cut down on the crazy #if`s */ +#define MODE13 1 + +#else +#undef MODE13 +#endif + +#include +#include +#include +#include +#include + +#ifdef DJGPP +#include +#endif + +#ifdef MGL +#include +#endif + +#include "GL/DOSmesa.h" +#include "context.h" +#include "matrix.h" +#include "types.h" + +#ifdef GLIDE + +static void glideshutdown( void ); +#include "vb.h" +#include "glide.h" + +/* the glide modes available, set one */ + +//#define GLIDE_MODE GR_RESOLUTION_ +#define GLIDE_MODE GR_RESOLUTION_800x600 +//#define GLIDE_MODE GR_RESOLUTION_640x480 + +static GrVertex gr_vtx,gr_vtx1,gr_vtx2; + +#endif + +#ifdef UNIVBE +/* You get this file from Scitechs VESA development kit */ +#include "svga.h" + +/* + Set these to the VESA mode you require, the first is for 256 colour modes, + the other is High colour modes, they must both be the same XRes and YRes. + */ + +#define VESA_256COLOUR_MODE 0x11c +#define VESA_HICOLOUR_MODE 0x11f + +#endif + +struct DOSmesa_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 DOSMesaContext DOSMesa = NULL; /* the current context */ + +#ifdef UNIVBE +SV_devCtx *DC=NULL; +int useLinear = TRUE; +SV_modeInfo *mi=NULL; +unsigned long modeNumber = 0; + +int activePage = 0; +int visualPage = 1; + +#endif + +#if defined(MODE13) + +/* DOSVGA With no UniVBE support */ + +unsigned char *video_buffer; + +#define VID_BUF(x,y) *(video_buffer+x+(y*320)) + +#if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__) + +void setupcopy(void); +void copyscr(void); + +/* Watcom C specfic, screen copy and clear */ + +#pragma aux setupcopy = \ + ".386P"\ + "push ebp" \ + "mov esi,video_buffer" \ + "mov edi,0xa0000" \ + "mov ecx,2000" \ + "xor ebp,ebp"; + +#pragma aux copyscr = \ + ".386P" \ + "lop1: mov eax,[esi]"\ + "mov ebx,[esi+4]"\ + "mov edx,[esi+8]"\ + "mov [edi],eax"\ + "mov eax,[esi+12]"\ + "mov dword ptr [esi],ebp"\ + "mov dword ptr [esi+4],ebp"\ + "mov dword ptr [esi+8],ebp"\ + "mov dword ptr [esi+12],ebp"\ + "mov [edi+4],ebx"\ + "mov [edi+8],edx"\ + "mov [edi+12],eax"\ + "mov eax,[esi+16]"\ + "mov ebx,[esi+4+16]"\ + "mov edx,[esi+8+16]"\ + "mov [edi+16],eax"\ + "mov eax,[esi+12+16]"\ + "mov dword ptr [esi+16],ebp"\ + "mov dword ptr [esi+4+16],ebp"\ + "mov dword ptr [esi+8+16],ebp"\ + "mov dword ptr [esi+12+16],ebp"\ + "mov [edi+4+16],ebx"\ + "mov [edi+8+16],edx"\ + "mov [edi+12+16],eax"\ + "add esi,32"\ + "add edi,32"\ + "dec ecx"\ + "jnz lop1"\ + "pop ebp"\ + modify exact [edi esi eax ebx ecx] ; + +#endif // WATCOM + +#endif // MODE13 + +/* + * Convert Mesa window Y coordinate to VGA screen Y coordinate: + */ +#define FLIP(Y) (DOSMesa->height-(Y)-1) + +unsigned short vga_cindex = 32768 ; + +static points_func choose_points_function( void ); +static line_func choose_line_function( void ); +static triangle_func choose_polygon_function( void ); +static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv ); + +static points_func choose_points_function( void ) +{ + return NULL; +} + +static line_func choose_line_function( void ) +{ + return NULL; +} + +static triangle_func choose_triangle_function( void ) +{ + #if defined(MODE13) + return NULL; + #endif + + #if defined(GLIDE) + return fast_tri; + #endif + + return NULL; +} + + +#if defined(MODE13) + +void setgfxmode(void); +void settextmode(void); + +#ifndef DJGPP +#pragma aux setgfxmode = \ + "mov ax,13h" \ + "int 10h" \ + modify [eax]; + +#pragma aux settextmode = \ + "mov ax,3h" \ + "int 10h" \ + modify [eax]; +#else +void setgfxmode(void) +{ + union REGS in_regs,out_regs; + + in_regs.x.ax = 0x13; + int386(0x10,&in_regs,&out_regs); +} + +void settextmode(void) +{ + union REGS in_regs,out_regs; + + in_regs.x.ax = 0x3; + int386(0x10,&in_regs,&out_regs); +} + +#endif + +int set_video_mode(unsigned short x,unsigned short y,char mode) +{ + setgfxmode(); + return 1; /* likelyhood of this failing is very small */ +} + +void restore_video_mode(void) +{ + settextmode(); +} + +int vga_getcolors(void) +{ + return vga_cindex; +} + +int vga_getxdim(void) +{ + return 320; +} + +int vga_getydim(void) +{ + return 200; +} + +static unsigned short num_rgb_alloc = 1; /* start from 1, zero is black */ + +/* an unlikely colour */ +static unsigned char last_r=1,last_g=255,last_b=99; + +extern void set_onecolor(int index,int R,int G,int B); + +static unsigned char rgbtable[64][64][64]; + +void vga_setrgbcolor(int r,int g,int b) +{ + +/* + * make this into a translation table + */ + + DOSMesa->red = r; + DOSMesa->green = g ; + DOSMesa->blue = b ; + + r/=4; g/=4; b/=4; + + if( (r == last_r) && (g == last_g) && (b == last_b) ) return; + + last_r = r ; + last_g = g ; + last_b = b ; + + if(r+g+b == 0 ) { + DOSMesa->index = 0 ; + return ; + } + + if( rgbtable[r][g][b] == 0 ) { + /* not allocated yet */ + if(num_rgb_alloc<256) { + DOSMesa->index = num_rgb_alloc; + set_onecolor(num_rgb_alloc,r,g,b); + rgbtable[r][g][b] = num_rgb_alloc; + num_rgb_alloc++; + return; + + } else { + /* need to search for a close colour */ + { + unsigned short pass ; + + for(pass=0;pass<64;pass++) { + if(r-pass>0) { + if( rgbtable[r-pass][g][b] !=0 ) { + rgbtable[r][g][b] = rgbtable[r-pass][g][b]; + DOSMesa->index = rgbtable[r-pass][g][b]; + return; + } + } + if(r+pass<64) { + if( rgbtable[r+pass][g][b] !=0 ) { + rgbtable[r][g][b] = rgbtable[r+pass][g][b]; + DOSMesa->index = rgbtable[r+pass][g][b]; + return; + } + } + } + } + rgbtable[r][g][b] = rand()%255; + } + } + DOSMesa->index = rgbtable[r][g][b]; +} + +#if defined(DJGPP) +static int dos_seg; +#endif + +void vga_clear(void) +{ + +/* Check if we`re using watcom and DOS */ +#if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__) + setupcopy(); + copyscr(); +#else + +#if defined (DJGPP) + + + asm (" + pusha + pushw %es + + movw _dos_seg, %es + + movl _video_buffer, %esi + movl $0xa0000, %edi + + movl $64000, %ecx + + rep ; movsb + + popw %es + popa + "); + +#else + + /* copy the RAM buffer to the Video memory */ + memcpy((unsigned char *)0xa0000,video_buffer, vga_getxdim()*vga_getydim() ); + +#endif //DJGPP + + /* clear the RAM buffer */ + memset(video_buffer,0, vga_getxdim()*vga_getydim() ); + +#endif //WATCOMC + +} + +#ifndef DEBUG +#define vga_drawpixel(x,y) { VID_BUF(x,y) = DOSMesa->index; } +#else +void vga_drawpixel(x,y) +{ + VID_BUF(x,y) = DOSMesa->index; +} +#endif + +int vga_getpixel(int x,int y) +{ + return 1; +} + +void vga_flip(void) +{ + +} + +void vga_setcolor(int index) +{ + /* does something, what i`ve no idea */ + DOSMesa->index = index; + +} + +#endif + +#if defined(UNIVBE) + +/* UniVBE VESA support */ + +void set_video_mode(unsigned short x,unsigned short y,char mode) +{ + if( setup_vesa_mode(x,y,mode) == FALSE ) { + fprintf(stderr,"VESA: Set mode failed\n"); + exit(1); + } +} + +/* + This is problematic as we don`t know what resolution the user program + wants when we reach here. This is why the 256 colour and HiColour modes + should be the same resolution, perhaps i`ll make this an environment + variable + */ + + +void check_mi(void) +{ + if(mi!=0) return; + + if(DC==NULL) { + DC = SV_init( TRUE ); + } + + if(modeNumber == 0 ) { + modeNumber = VESA_HICOLOUR_MODE; + } + + SV_getModeInfo(modeNumber,mi); + + return; +} + +int setup_vesa_mode(short height,short width,short depth) +{ + if(DC==NULL) { + DC = SV_init( TRUE ); + /* how many bits per pixel */ + if( depth == 0) + modeNumber = VESA_256COLOUR_MODE; + else + modeNumber = VESA_HICOLOUR_MODE; + } + + /* Check if correct VESA Version is available */ + if( !DC || DC->VBEVersion < 0x0102) { + fprintf(stderr,"Require a VESA VBE version 1.2 or higher\n"); + return FALSE; + } + + /* Check for LFB Supprt */ + if(DC->VBEVersion < 0x0200 ) { + useLinear = FALSE; + } else { + useLinear = TRUE ; + } + + /* Get desired mode info */ + if(!SV_getModeInfo( modeNumber, mi)) + return FALSE; + + /* Set VESA mode */ + if(!SV_setMode(modeNumber | svMultiBuffer, FALSE, TRUE, mi->NumberOfPages) ) + return FALSE; + + return TRUE; +} + +void restore_video_mode(void) +{ + SV_restoreMode(); +} + +void vga_clear(void) +{ + SV_clear(0); +} + +void vga_flip(void) +{ + activePage = 1-activePage; + visualPage = 1-activePage; + + SV_setActivePage(activePage); + + /* + Change false to true if you`re getting flickering + even in double buffer mode, ( sets wait for Vertical retrace ) + */ + SV_setVisualPage(visualPage,false); +} + +int vga_getcolors(void) +{ + check_mi(); + switch ( mi->BitsPerPixel ) { + case 8: + return 256; + case 15: + case 16: + return 32768; + default: + return 64000; + } +} + +int vga_getxdim(void) +{ + check_mi(); + return mi->XResolution; +} + +int vga_getydim(void) +{ + check_mi(); + return mi->YResolution; +} + +unsigned long current_color = 255; + +void vga_setrgbcolor(int r,int g,int b) +{ + DOSMesa->red = r; + DOSMesa->green = g ; + DOSMesa->blue = b ; + current_color = SV_rgbColor(r,g,b); +} + +void vga_setcolor(int index) +{ + DOSMesa->index = index; + current_color = index; +} + +void vga_drawpixel(x,y) +{ + SV_putPixel(x,y,current_color); +} + +/* TODO: */ +int vga_getpixel(x,y) +{ +/* return (int)SV_getPixel(x,y); */ + fprintf(stderr,"vga_getpixel: Not implemented yet\n"); + return 1; +} + +/* End of UNIVBE section */ +#endif + +/* Scitechs MegaGraphicsLibrary http://www.scitechsoft.com/ */ + +#if defined(MGL) + +/* MGL support */ +struct MI { + unsigned short BitsPerPixel; + unsigned long XResolution; + unsigned long YResolution; +}; + +struct MI*mi; + +static MGLDC*DC; +static int activePage = 0; +static int visualPage = 1; +static int modeNumber = 0; + +void set_video_mode(unsigned short xres,unsigned short yres,char mode) +{ + int i,driver = grDETECT,dmode = grDETECT; + event_t evt; + + /* Start the MGL with only the SVGA 16m driver active */ + MGL_registerDriver(MGL_SVGA16NAME,SVGA16_driver); + if (!MGL_init(&driver,&dmode,"..\\..\\")) + MGL_fatalError(MGL_errorMsg(MGL_result())); + if ((DC = MGL_createDisplayDC(false)) == NULL) + MGL_fatalError(MGL_errorMsg(MGL_result())); + MGL_makeCurrentDC(DC); +} + +/* + This is problematic as we don`t know what resolution the user program + wants when we reach here. This is why the 256 colour and HiColour modes + should be the same resolution, perhaps i`ll make this an environment + variable + */ + +#define MGL_HICOLOUR_MODE 0 + + +void check_mi(void) +{ + if(mi!=0) return; + + if(DC==NULL) { +// DC = SV_init( TRUE ); + } + + if(modeNumber == 0 ) { + modeNumber = MGL_HICOLOUR_MODE; + } + +// SV_getModeInfo(modeNumber,mi); + + return; +} + +void restore_video_mode(void) +{ + MGL_exit(); +} + +void vga_clear(void) +{ + MGL_clearDevice(); +} + +void vga_flip(void) +{ + activePage = 1-activePage; + visualPage = 1-activePage; + +// SV_setActivePage(activePage); + + /* + Change false to true if you`re getting flickering + even in double buffer mode, ( sets wait for Vertical retrace ) + */ +// SV_setVisualPage(visualPage,false); +} + +int vga_getcolors(void) +{ + check_mi(); + switch ( mi->BitsPerPixel ) { + case 8: + return 256; + case 15: + case 16: + return 32768; + default: + return 64000; + } +} + +int vga_getxdim(void) +{ + check_mi(); + return mi->XResolution; +} + +int vga_getydim(void) +{ + check_mi(); + return mi->YResolution; +} + +unsigned long current_color = 255; + +void vga_setrgbcolor(int r,int g,int b) +{ + DOSMesa->red = r; + DOSMesa->green = g ; + DOSMesa->blue = b ; + current_color = MGL_rgbColor(DC,r,g,b); +} + +void vga_setcolor(int index) +{ + DOSMesa->index = index; + current_color = index; +} + +void vga_drawpixel(x,y) +{ + MGL_pixelCoord(x,y); +} + +/* TODO: */ +int vga_getpixel(x,y) +{ +/* return (int)SV_getPixel(x,y); */ + fprintf(stderr,"vga_getpixel: Not implemented yet\n"); + return 1; +} + +/* End of UNIVBE section */ +#endif + +#ifdef GLIDE + +/* GLIDE support */ + +static GrHwConfiguration hwconfig; + +void set_video_mode(unsigned short x,unsigned short y,char mode) +{ + grGlideInit(); + if( grSstQueryHardware( &hwconfig ) ) { + grSstSelect( 0 ) ; + if( !grSstOpen( GLIDE_MODE, + GR_REFRESH_60Hz, + GR_COLORFORMAT_ABGR, + GR_ORIGIN_UPPER_LEFT, + GR_SMOOTHING_ENABLE, + 2 ) ) { + fprintf(stderr,"Detected 3DFX board, but couldn`t initialize!"); + exit(1); + } + + grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST); + + grDisableAllEffects(); + atexit( glideshutdown ); + +// guColorCombineFunction( GR_COLORCOMBINE_ITRGB ); +// grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_ZERO); + } +} + +void restore_video_mode(void) +{ +} + +static void glideshutdown( void ) +{ + grGlideShutdown() ; +} + +void vga_clear(void) +{ + grBufferSwap(0); + grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST); +} + +void vga_flip(void) +{ +} + +int vga_getcolors(void) +{ + return 32768; +} + +int vga_getxdim(void) +{ +#if GLIDE_MODE == GR_RESOLUTION_800x600 + return 800; +#else + return 640; +#endif +} + +int vga_getydim(void) +{ +#if GLIDE_MODE == GR_RESOLUTION_800x600 + return 600; +#else + return 480; +#endif +} + +unsigned long current_color = 255; + +void vga_setrgbcolor(int r,int g,int b) +{ + DOSMesa->red = r; + DOSMesa->green = g ; + DOSMesa->blue = b ; +} + +void vga_setcolor(int index) +{ + DOSMesa->index = index; +} + +void vga_drawpixel(x,y) +{ + + gr_vtx.x = x; + gr_vtx.y = y; + gr_vtx.z = 0; + gr_vtx.r = DOSMesa->red; + gr_vtx.g = DOSMesa->green; + gr_vtx.b = DOSMesa->blue; + + grDrawPoint( &gr_vtx ); +} + +static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv ) +{ + struct vertex_buffer *VB = ctx->VB; + + gr_vtx.z = 0; + gr_vtx1.z = 0; + gr_vtx2.z = 0; + + if (VB->MonoColor) { + gr_vtx.r = DOSMesa->red; + gr_vtx.g = DOSMesa->green; + gr_vtx.b = DOSMesa->blue; + gr_vtx1.r = DOSMesa->red; + gr_vtx1.g = DOSMesa->green; + gr_vtx1.b = DOSMesa->blue; + gr_vtx2.r = DOSMesa->red; + gr_vtx2.g = DOSMesa->green; + gr_vtx2.b = DOSMesa->blue; + } else { + if(ctx->Light.ShadeModel == GL_SMOOTH ) { + gr_vtx.r = FixedToInt( VB->Color[v0][0] ); + gr_vtx.g = FixedToInt( VB->Color[v0][1] ); + gr_vtx.b = FixedToInt( VB->Color[v0][2] ); + + gr_vtx1.r = FixedToInt( VB->Color[v1][0] ); + gr_vtx1.g = FixedToInt( VB->Color[v1][1] ); + gr_vtx1.b = FixedToInt( VB->Color[v1][2] ); + + gr_vtx2.r = FixedToInt( VB->Color[v2][0] ); + gr_vtx2.g = FixedToInt( VB->Color[v2][1] ); + gr_vtx2.b = FixedToInt( VB->Color[v2][2] ); + } else { + gr_vtx.r = VB->Color[pv][0]; + gr_vtx.g = VB->Color[pv][1]; + gr_vtx.b = VB->Color[pv][2]; + + gr_vtx1.r = VB->Color[pv][0]; + gr_vtx1.g = VB->Color[pv][1]; + gr_vtx1.b = VB->Color[pv][2]; + + gr_vtx2.r = VB->Color[pv][0]; + gr_vtx2.g = VB->Color[pv][1]; + gr_vtx2.b = VB->Color[pv][2]; + } + } + + gr_vtx.x = (VB->Win[v0][0] ); + gr_vtx.y = FLIP( (VB->Win[v0][1] ) ); + gr_vtx1.x = (VB->Win[v1][0] ); + gr_vtx1.y = FLIP( (VB->Win[v1][1] ) ); + gr_vtx2.x = (VB->Win[v2][0] ); + gr_vtx2.y = FLIP( (VB->Win[v2][1] ) ); + + if(gr_vtx.x <0 || gr_vtx.x > 639 ) + return; + if(gr_vtx1.x <0 || gr_vtx1.x > 639 ) + return; + if(gr_vtx2.x <0 || gr_vtx2.x > 639 ) + return; + + if(gr_vtx.y <0 || gr_vtx.y > 479 ) + return; + if(gr_vtx1.y <0 || gr_vtx1.y > 479 ) + return; + if(gr_vtx2.y <0 || gr_vtx2.y > 479 ) + return; + + grDrawTriangle( &gr_vtx,&gr_vtx1,&gr_vtx2); +} + +void fast_plot(GLcontext *ctx,GLuint first,GLuint last ) +{ + struct vertex_buffer *VB = ctx->VB; + register GLuint i; + + if(VB->MonoColor) { + /* all same color */ + + gr_vtx.r = DOSMesa->red; + gr_vtx.g = DOSMesa->green; + gr_vtx.b = DOSMesa->blue; + + for(i=first;iClipMask[i]==0) { + gr_vtx.x = VB->Win[i][0]; + gr_vtx.y = FLIP(VB->Win[i][1]); + } + } + } +} + +/* TODO: */ +int vga_getpixel(x,y) +{ +/* return (int)SV_getPixel(x,y); */ + fprintf(stderr,"vga_getpixel: Not implemented yet\n"); + return 1; +} + +/* End of GLIDE section */ + +#endif // GLIDE +/**********************************************************************/ +/***** Miscellaneous functions *****/ +/**********************************************************************/ + + +static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height ) +{ + *width = DOSMesa->width = vga_getxdim(); + *height = DOSMesa->height = vga_getydim(); +} + + +/* Set current color index */ +static void set_index( GLcontext *ctx, GLuint index ) +{ + DOSMesa->index = index; + /*vga_setcolor( index );*/ +} + + +/* Set current drawing color */ +static void set_color( GLcontext *ctx, + GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ) +{ + DOSMesa->red = red; + DOSMesa->green = green; + DOSMesa->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 void clear( GLcontext *ctx, + GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + vga_clear(); +} + + +static GLboolean set_buffer( GLcontext *ctx, + GLenum mode ) +{ + /* 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_index_span( GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLuint index[], + const GLubyte mask[] ) +{ + int i; + y = FLIP(y); +#ifdef UNIVBE + SV_beginPixel(); +#endif + for (i=0;iindex ); +#ifdef UNIVBE + SV_beginPixel(); +#endif + for (i=0;ired, DOSMesa->green, DOSMesa->blue ); + for (i=0; iindex ); +#ifdef UNIVBE + SV_beginPixel(); +#endif + for (i=0; iindex); +#else + vga_drawpixel( x[i], FLIP(y[i]) ); +#endif + } + } +#ifdef UNIVBE + SV_endPixel(); +#endif +} + + + +static void write_color_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte r[], const GLubyte g[], + const GLubyte b[], const GLubyte a[], + const GLubyte mask[] ) +{ + int i; +#ifdef UNIVBE + SV_beginPixel(); +#endif + for (i=0; ired, DOSMesa->green, DOSMesa->blue ); +#ifdef UNIVBE + SV_beginPixel(); +#endif + for (i=0; iDriver.UpdateState = DOSmesa_setup_DD_pointers; + + 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 = choose_points_function(); + ctx->Driver.LineFunc = choose_line_function(); + ctx->Driver.TriangleFunc = choose_triangle_function(); + + + /* Pixel/span writing functions: */ + /* TODO: use different funcs for 8, 16, 32-bit depths */ + ctx->Driver.WriteColorSpan = write_color_span; + ctx->Driver.WriteMonocolorSpan = write_monocolor_span; + ctx->Driver.WriteColorPixels = write_color_pixels; + ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels; + ctx->Driver.WriteIndexSpan = write_index_span; + ctx->Driver.WriteMonoindexSpan = write_monoindex_span; + ctx->Driver.WriteIndexPixels = write_index_pixels; + ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels; + + /* Pixel/span reading functions: */ + /* TODO: use different funcs for 8, 16, 32-bit depths */ + ctx->Driver.ReadIndexSpan = read_index_span; + ctx->Driver.ReadColorSpan = read_color_span; + ctx->Driver.ReadIndexPixels = read_index_pixels; + ctx->Driver.ReadColorPixels = read_color_pixels; +} + +/* + * Create a new VGA/Mesa context and return a handle to it. + */ +DOSMesaContext DOSMesaCreateContext( void ) +{ + DOSMesaContext ctx; + GLboolean rgb_flag; + GLfloat redscale, greenscale, bluescale, alphascale; + GLboolean db_flag = GL_FALSE; + GLboolean alpha_flag = GL_FALSE; + int colors; + GLint index_bits; + GLint redbits, greenbits, bluebits, alphabits; + +#if !defined(UNIVBE) && !defined(GLIDE) && !defined(MGL) + video_buffer = (unsigned char *) malloc( vga_getxdim() * vga_getydim() ); + + memset(video_buffer,0, vga_getxdim() * vga_getydim() ); + + memset(rgbtable,0,sizeof( rgbtable ) ); +#endif + +#if defined( DJGPP ) && !defined(UNIVBE) && !defined(GLIDE) + dos_seg = _go32_conventional_mem_selector(); +#endif + + /* 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 { + restore_video_mode(); + fprintf(stderr,"[%d] >16 bit color not implemented yet!\n",colors); + return NULL; + } + + ctx = (DOSMesaContext) calloc( 1, sizeof(struct DOSmesa_context) ); + if (!ctx) { + return NULL; + } + + ctx->gl_vis = gl_create_visual( rgb_flag, + alpha_flag, + db_flag, + 16, /* depth_size */ + 8, /* stencil_size */ + 16, /* accum_size */ + index_bits, + redscale, + greenscale, + bluescale, + alphascale, + redbits, greenbits, + bluebits, alphabits); + + ctx->gl_ctx = gl_create_context( ctx->gl_vis, + NULL, /* share list context */ + (void *) ctx + ); + + 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 DOSMesaDestroyContext( DOSMesaContext 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==DOSMesa) { + DOSMesa = NULL; + } + } +} + + + +/* + * Make the specified VGA/Mesa context the current one. + */ +void DOSMesaMakeCurrent( DOSMesaContext ctx ) +{ + DOSMesa = ctx; + gl_make_current( ctx->gl_ctx, ctx->gl_buffer ); + DOSmesa_setup_DD_pointers( ctx->gl_ctx ); + + 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. + */ +DOSMesaContext DOSMesaGetCurrentContext( void ) +{ + return DOSMesa; +} + + +/* + * Swap front/back buffers for current context if double buffered. + */ +void DOSMesaSwapBuffers( void ) +{ +#if !defined(UNIVBE) +/* Assume double buffering is available if in UNIVBE, + if it isn`t its taken care of anyway */ +// if (DOSMesa->gl_vis->DBflag) +#endif + { + vga_flip(); + } +} + + +#else + +/* + * Need this to provide at least one external definition when DOS is + * not defined on the compiler command line. + */ + +int gl_DOS_dummy_function(void) +{ + return 0; +} + +#endif /*DOS*/ + diff --git a/src/mesa/drivers/ggi/ggimesa.conf.in b/src/mesa/drivers/ggi/ggimesa.conf.in new file mode 100644 index 0000000..7213233 --- /dev/null +++ b/src/mesa/drivers/ggi/ggimesa.conf.in @@ -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 index 0000000..fbc586e --- /dev/null +++ b/src/mesa/drivers/glide/fxapi.c @@ -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 + * CARD/ FB/ + * TM/ TMU/" + * where: CARD is the card used for the current context, + * FB is the number of MB for the framebuffer, + * TM is the number of MB for the texture memory, + * 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 + * - 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 + * - fixed a Voodoo Rush related problem in the fxwgl.c + * + * Daryll Strauss + * - 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;i0) { + 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 index 0000000..b2f3a7a --- /dev/null +++ b/src/mesa/drivers/glide/fxdd.c @@ -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;ycurrentFB); + +#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 index 0000000..fc7c38d --- /dev/null +++ b/src/mesa/drivers/glide/fxddspan.c @@ -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 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 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;icurrentFB, 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;icolor; + ++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;icolor; + } + + 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> 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;icurrentFB,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;icurrentFB,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;icurrentFB,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;iDriverCtx; + 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; iDepth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;i= *zptr) { + *zptr = z[i]; + passed++; + } else { + *m = 0; + } + } + } + } else { + /* Don't update Z buffer */ + for (i=0;i= *zptr) { + /* pass */ + passed++; + } else { + *m = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0;i *zptr) { + *zptr = z[i]; + passed++; + } else { + *m = 0; + } + } + } + } else { + /* Don't update Z buffer */ + for (i=0;i *zptr) { + /* pass */ + passed++; + } else { + *m = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;iDriverCtx; + 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; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; 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= zval) { + /* pass */ + } else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0; 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 zval) { + /* pass */ + } else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; iDriver.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 index 0000000..05ef775 --- /dev/null +++ b/src/mesa/drivers/glide/fxddtex.c @@ -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;itmi.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;iPaletteSize;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;iTexture.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> 3); + } + } else { + unsigned short r,g,b; + + for(y=0;y> 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++> 4); + } + } else { + unsigned short r,g,b,a; + + for(y=0;y> 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;yWidth; + 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;yData+(yoffset*image->Width+xoffset)*3); + dst=destimg+(yoffset*image->Width+xoffset); + + simgw=(image->Width-width)*3; + dimgw=image->Width-width; + for(y=0;y> 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> 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 index 0000000..bb8f5b8 --- /dev/null +++ b/src/mesa/drivers/glide/fxdrv.h @@ -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 +#include +#include +#include +#include + +#if defined(__linux__) +#include +#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 index 0000000..3ced928 --- /dev/null +++ b/src/mesa/drivers/glide/fxglidew.c @@ -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 +#include + + +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 index 0000000..17f3956 --- /dev/null +++ b/src/mesa/drivers/glide/fxglidew.h @@ -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 + +/* + * 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 index 0000000..af76f4c --- /dev/null +++ b/src/mesa/drivers/glide/fxopengl.def @@ -0,0 +1,467 @@ +EXPORTS + glAccum + glAlphaFunc + glAreTexturesResident + glArrayElement + glBegin + glBindTexture + glBitmap + glBlendFunc + glCallList + glCallLists + glClear + glClearAccum + glClearIndex + glClearColor + glClearDepth + glClearStencil + glClipPlane + glColor3b + glColor3d + glColor3f + glColor3i + glColor3s + glColor3ub + glColor3ui + glColor3us + glColor4b + glColor4d + glColor4f + glColor4i + glColor4s + glColor4ub + glColor4ui + glColor4us + glColor3bv + glColor3dv + glColor3fv + glColor3iv + glColor3sv + glColor3ubv + glColor3uiv + glColor3usv + glColor4bv + glColor4dv + glColor4fv + glColor4iv + glColor4sv + glColor4ubv + glColor4uiv + glColor4usv + glColorMask + glColorMaterial + glColorPointer + glColorTableEXT + glColorSubTableEXT + glCopyPixels + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glCullFace + glDepthFunc + glDepthMask + glDepthRange + glDeleteLists + glDeleteTextures + glDisable + glDisableClientState + glDrawArrays + glDrawBuffer + glDrawElements + glDrawPixels + glEnable + glEnableClientState + glEnd + glEndList + glEvalCoord1d + glEvalCoord1f + glEvalCoord1dv + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2f + glEvalCoord2dv + glEvalCoord2fv + glEvalPoint1 + glEvalPoint2 + glEvalMesh1 + glEdgeFlag + glEdgeFlagv + glEdgeFlagPointer + glEvalMesh2 + glFeedbackBuffer + glFinish + glFlush + glFogf + glFogi + glFogfv + glFogiv + glFrontFace + glFrustum + glGenLists + glGenTextures + glGetBooleanv + glGetClipPlane + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPointerv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGeniv + glGetTexGendv + glGetTexGenfv + glGetTexImage + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glGetTexParameterfv + glGetTexParameteriv + glHint + glIndexd + glIndexf + glIndexi + glIndexs + glIndexub + glIndexdv + glIndexfv + glIndexiv + glIndexsv + glIndexubv + glIndexMask + glIndexPointer + glInterleavedArrays + glInitNames + glIsList + glIsTexture + glLightf + glLighti + glLightfv + glLightiv + glLightModelf + glLightModeli + glLightModelfv + glLightModeliv + glLineWidth + glLineStipple + glListBase + glLoadIdentity + glLoadMatrixd + glLoadMatrixf + glLoadName + glLogicOp + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glMaterialf + glMateriali + glMaterialfv + glMaterialiv + glMatrixMode + glMultMatrixd + glMultMatrixf + glNewList + glNormal3b + glNormal3d + glNormal3f + glNormal3i + glNormal3s + glNormal3bv + glNormal3dv + glNormal3fv + glNormal3iv + glNormal3sv + glNormalPointer + glOrtho + glPassThrough + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glPixelStoref + glPixelStorei + glPixelTransferf + glPixelTransferi + glPixelZoom + glPointSize + glPolygonMode + glPolygonOffset + glPolygonOffsetEXT + glPolygonStipple + glPopAttrib + glPopClientAttrib + glPopMatrix + glPopName + glPrioritizeTextures + glPushMatrix + glRasterPos2d + glRasterPos2f + glRasterPos2i + glRasterPos2s + glRasterPos3d + glRasterPos3f + glRasterPos3i + glRasterPos3s + glRasterPos4d + glRasterPos4f + glRasterPos4i + glRasterPos4s + glRasterPos2dv + glRasterPos2fv + glRasterPos2iv + glRasterPos2sv + glRasterPos3dv + glRasterPos3fv + glRasterPos3iv + glRasterPos3sv + glRasterPos4dv + glRasterPos4fv + glRasterPos4iv + glRasterPos4sv + glReadBuffer + glReadPixels + glRectd + glRectf + glRecti + glRects + glRectdv + glRectfv + glRectiv + glRectsv + glScissor + glIsEnabled + glPushAttrib + glPushClientAttrib + glPushName + glRenderMode + glRotated + glRotatef + glSelectBuffer + glScaled + glScalef + glShadeModel + glStencilFunc + glStencilMask + glStencilOp + glTexCoord1d + glTexCoord1f + glTexCoord1i + glTexCoord1s + glTexCoord2d + glTexCoord2f + glTexCoord2i + glTexCoord2s + glTexCoord3d + glTexCoord3f + glTexCoord3i + glTexCoord3s + glTexCoord4d + glTexCoord4f + glTexCoord4i + glTexCoord4s + glTexCoord1dv + glTexCoord1fv + glTexCoord1iv + glTexCoord1sv + glTexCoord2dv + glTexCoord2fv + glTexCoord2iv + glTexCoord2sv + glTexCoord3dv + glTexCoord3fv + glTexCoord3iv + glTexCoord3sv + glTexCoord4dv + glTexCoord4fv + glTexCoord4iv + glTexCoord4sv + glTexCoordPointer + glTexGend + glTexGenf + glTexGeni + glTexGendv + glTexGeniv + glTexGenfv + glTexEnvf + glTexEnvi + glTexEnvfv + glTexEnviv + glTexImage1D + glTexImage2D + glTexParameterf + glTexParameteri + glTexParameterfv + glTexParameteriv + glTexSubImage1D + glTexSubImage2D + glTranslated + glTranslatef + glVertex2d + glVertex2f + glVertex2i + glVertex2s + glVertex3d + glVertex3f + glVertex3i + glVertex3s + glVertex4d + glVertex4f + glVertex4i + glVertex4s + glVertex2dv + glVertex2fv + glVertex2iv + glVertex2sv + glVertex3dv + glVertex3fv + glVertex3iv + glVertex3sv + glVertex4dv + glVertex4fv + glVertex4iv + glVertex4sv + glVertexPointer + glViewport + glBlendEquationEXT + glBlendColorEXT + glVertexPointerEXT + glNormalPointerEXT + glColorPointerEXT + glIndexPointerEXT + glTexCoordPointerEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glArrayElementEXT + glDrawArraysEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glPrioritizeTexturesEXT + glCopyTexSubImage3DEXT + glTexImage3DEXT + glTexSubImage3DEXT + glWindowPos4fMESA + glWindowPos2iMESA + glWindowPos2sMESA + glWindowPos2fMESA + glWindowPos2dMESA + glWindowPos2ivMESA + glWindowPos2svMESA + glWindowPos2fvMESA + glWindowPos2dvMESA + glWindowPos3iMESA + glWindowPos3sMESA + glWindowPos3fMESA + glWindowPos3dMESA + glWindowPos3ivMESA + glWindowPos3svMESA + glWindowPos3fvMESA + glWindowPos3dvMESA + glWindowPos4iMESA + glWindowPos4sMESA + glWindowPos4dMESA + glWindowPos4ivMESA + glWindowPos4svMESA + glWindowPos4fvMESA + glWindowPos4dvMESA + glResizeBuffersMESA + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext +;wglDescribeLayerPlane + wglGetCurrentContext + wglGetCurrentDC +;wglGetLayerPaletteEntries + wglGetProcAddress + wglMakeCurrent +;wglRealizeLayerPalette +;wglSetLayerPaletteEntries + wglShareLists + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + wglChoosePixelFormat + ChoosePixelFormat + wglDescribePixelFormat + DescribePixelFormat + wglGetPixelFormat + GetPixelFormat + wglSetPixelFormat + SetPixelFormat + wglSwapBuffers + SwapBuffers + gl3DfxSetPaletteEXT + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB + fxMesaCreateContext + fxMesaCreateBestContext + fxMesaDestroyContext + fxMesaSelectCurrentBoard + fxMesaMakeCurrent + fxMesaGetCurrentContext + fxMesaSwapBuffers + fxMesaSetNearFar + fxMesaUpdateScreenSize + fxQueryHardware + fxCloseHardware + OSMesaCreateContext + OSMesaDestroyContext + OSMesaGetCurrentContext + OSMesaGetDepthBuffer + OSMesaGetIntegerv + OSMesaMakeCurrent + OSMesaPixelStore diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c new file mode 100644 index 0000000..9996499 --- /dev/null +++ b/src/mesa/drivers/glide/fxsetup.c @@ -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;iFog.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 index 0000000..5ee145e --- /dev/null +++ b/src/mesa/drivers/glide/fxtexman.c @@ -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(startadrstartAddress) { + 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;itmi.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 index 0000000..cbea79a --- /dev/null +++ b/src/mesa/drivers/glide/fxwgl.c @@ -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 +#include +#include + +#ifdef __cplusplus + } +#endif + +#include +#include +#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 index 0000000..25bba5b --- /dev/null +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -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 +#include +#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;irowaddr[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;irowaddr[i] = origin + (i * (ctx->rowlength*3)); + } + } else { + /* 4-byte RGBA mode */ + GLuint *origin = (GLuint *) ctx->buffer; + for (i=0;irowaddr[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;irowaddr[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;irowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3)); + } + } else { + /* 4-byte RGBA mode */ + GLuint *origin = (GLuint *) ctx->buffer; + for (i=0;irowaddr[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;iclearpixel; + } + } + } + } + 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;irowlength * osmesa->height; + ptr4 = (GLuint *) osmesa->buffer; + for (i=0;iclearpixel; + } + } + else { + /* Clear part of RGBA buffer */ + GLint i, j; + for (i=0;iclearpixel; + } + } + } + } + } + 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;iDriverCtx; + GLuint *ptr4 = PIXELADDR4( x, y ); + const GLuint *rgba4 = (const GLuint *) rgba; + GLuint i; + if (mask) { + for (i=0;iDriverCtx; + 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;iDriverCtx; + GLuint *ptr4 = PIXELADDR4(x,y); + GLuint i; + for (i=0;ipixel; + } + } +} + + + +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;iDriverCtx; + GLuint i; + for (i=0;ipixel; + } + } +} + + +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;iDriverCtx; + 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;iDriverCtx; + GLubyte *ptr3 = PIXELADDR3( x, y); + GLuint i; + GLint rind = osmesa->rind; + GLint gind = osmesa->gind; + GLint bind = osmesa->bind; + if (mask) { + for (i=0;iDriverCtx; + GLubyte *ptr3 = PIXELADDR3( x, y); + GLuint i; + GLint rind = osmesa->rind; + GLint gind = osmesa->gind; + GLint bind = osmesa->bind; + if (mask) { + for (i=0;iDriverCtx; + + 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;iDriverCtx; + GLuint i; + GLint rind = osmesa->rind; + GLint gind = osmesa->gind; + GLint bind = osmesa->bind; + + for (i=0;iDriverCtx; + 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;iDriverCtx; + GLuint i; + GLint rind = osmesa->rind; + GLint gind = osmesa->gind; + GLint bind = osmesa->bind; + GLubyte *ptr3 = PIXELADDR3( x, y); + for (i=0;iDriverCtx; + GLuint i; + GLint rind = osmesa->rind; + GLint gind = osmesa->gind; + GLint bind = osmesa->bind; + for (i=0;iDriverCtx; + GLubyte *ptr1 = PIXELADDR1(x,y); + GLuint i; + if (mask) { + for (i=0;iDriverCtx; + GLubyte *ptr1 = PIXELADDR1(x,y); + GLuint i; + if (mask) { + for (i=0;iDriverCtx; + GLubyte *ptr1 = PIXELADDR1(x,y); + GLuint i; + for (i=0;ipixel; + } + } +} + + +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;iDriverCtx; + GLuint i; + for (i=0;ipixel; + } + } +} + + +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;iDriverCtx; + GLuint i; + for (i=0;iDriverCtx; + 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;iDriverCtx; +#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;iDriverCtx; + + 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 index 0000000..4c4d9f7 --- /dev/null +++ b/src/mesa/drivers/svga/svgamesa.c @@ -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 +#include +#include +#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;iindex ); + for (i=0;ired, SVGAMesa->green, SVGAMesa->blue ); + for (i=0; iindex ); + for (i=0; ired, SVGAMesa->green, SVGAMesa->blue ); + for (i=0; iDriver.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 index 0000000..40ead30 --- /dev/null +++ b/src/mesa/drivers/windows/colors.h @@ -0,0 +1,499 @@ +/* File name : colors.h + * Version : 2.3 + * + * Header file for display driver for Mesa 2.3 under + * Windows95 and WindowsNT + * This file defines macros and global variables needed + * for converting color format + * + * 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 based on the + * Windows NT driver for Mesa, written by Mark Leaming + * (mark@rsinc.com). + */ + +/* $Log: ddcolors.h 1997/6/14 by Li Wei(liwei@aiar.xjtu.edu.cn) + * Macros for pixel format defined + */ + +/* + * $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 + * + * Revision 2.0.2 1997/4/30 15:58:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Add LUTs need for dithering + */ + +/* + * $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 + * + * Revision 2.0.1 1997/4/29 15:52:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Add BGR8 Macro + */ + +/* + * $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 + * + * Revision 2.0 1996/11/15 10:55:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Initial revision + */ +/* Values for wmesa->pixelformat: */ + +#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ +#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ +#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ +#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ +#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ +#define PF_BADFORMAT 11 +#define PF_INDEX8 12 + +char ColorMap16[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, +0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, +0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, +0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06, +0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, +0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, +0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09, +0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A, +0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, +0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C, +0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D, +0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E, +0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, +0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, +0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, +0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, +0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, +0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, +0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19, +0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, +0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B, +0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C, +0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D, +0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E, +0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}; + +#define BGR8(r,g,b) (unsigned)(((BYTE)(b & 0xc0 | (g & 0xe0)>>2 | (r & 0xe0)>>5))) +#ifdef DDRAW +#define BGR16(r,g,b) ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(g&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[r])) << 11))) +#else +#define BGR16(r,g,b) ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(ColorMap16[g]) << 5)) | (((WORD)(BYTE)(ColorMap16[r])) << 10))) +#endif +#define BGR24(r,g,b) (unsigned long)(((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16))) << 8) +#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16))) + + + +/* + * If pixelformat==PF_8A8B8G8R: + */ +#define PACK_8A8B8G8R( R, G, B, A ) \ + ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) ) + + +/* + * If pixelformat==PF_8R8G8B: + */ +#define PACK_8R8G8B( R, G, B) ( ((R) << 16) | ((G) << 8) | (B) ) + + +/* + * If pixelformat==PF_5R6G5B: + */ + + +#ifdef DDRAW +#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(G&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[R])) << 11))) +#else +#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(ColorMap16[G]) << 5)) | (((WORD)(BYTE)(ColorMap16[R])) << 10))) +#endif +/*---------------------------------------------------------------------------- + +Division lookup tables. These tables compute 0-255 divided by 51 and +modulo 51. These tables could approximate gamma correction. + +*/ + +char unsigned const aDividedBy51Rounded[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +}; + +char unsigned const aDividedBy51[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, +}; + +char unsigned const aModulo51[256] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, +}; + +/*---------------------------------------------------------------------------- + +Multiplication LUTs. These compute 0-5 times 6 and 36. + +*/ + +char unsigned const aTimes6[6] = +{ + 0, 6, 12, 18, 24, 30 +}; + +char unsigned const aTimes36[6] = +{ + 0, 36, 72, 108, 144, 180 +}; + + +/*---------------------------------------------------------------------------- + +Dither matrices for 8 bit to 2.6 bit halftones. + +*/ + +char unsigned const aHalftone16x16[256] = +{ + 0, 44, 9, 41, 3, 46, 12, 43, 1, 44, 10, 41, 3, 46, 12, 43, + 34, 16, 25, 19, 37, 18, 28, 21, 35, 16, 26, 19, 37, 18, 28, 21, + 38, 6, 47, 3, 40, 9, 50, 6, 38, 7, 47, 4, 40, 9, 49, 6, + 22, 28, 13, 31, 25, 31, 15, 34, 22, 29, 13, 32, 24, 31, 15, 34, + 2, 46, 12, 43, 1, 45, 10, 42, 2, 45, 11, 42, 1, 45, 11, 42, + 37, 18, 27, 21, 35, 17, 26, 20, 36, 17, 27, 20, 36, 17, 26, 20, + 40, 8, 49, 5, 38, 7, 48, 4, 39, 8, 48, 5, 39, 7, 48, 4, + 24, 30, 15, 33, 23, 29, 13, 32, 23, 30, 14, 33, 23, 29, 14, 32, + 2, 46, 12, 43, 0, 44, 10, 41, 3, 47, 12, 44, 0, 44, 10, 41, + 37, 18, 27, 21, 35, 16, 25, 19, 37, 19, 28, 22, 35, 16, 25, 19, + 40, 9, 49, 5, 38, 7, 47, 4, 40, 9, 50, 6, 38, 6, 47, 3, + 24, 30, 15, 34, 22, 29, 13, 32, 25, 31, 15, 34, 22, 28, 13, 31, + 1, 45, 11, 42, 2, 46, 11, 42, 1, 45, 10, 41, 2, 46, 11, 43, + 36, 17, 26, 20, 36, 17, 27, 21, 35, 16, 26, 20, 36, 18, 27, 21, + 39, 8, 48, 4, 39, 8, 49, 5, 38, 7, 48, 4, 39, 8, 49, 5, + 23, 29, 14, 33, 24, 30, 14, 33, 23, 29, 13, 32, 24, 30, 14, 33, +}; + +char unsigned const aHalftone8x8[64] = +{ + 0, 38, 9, 47, 2, 40, 11, 50, + 25, 12, 35, 22, 27, 15, 37, 24, + 6, 44, 3, 41, 8, 47, 5, 43, + 31, 19, 28, 15, 34, 21, 31, 18, + 1, 39, 11, 49, 0, 39, 10, 48, + 27, 14, 36, 23, 26, 13, 35, 23, + 7, 46, 4, 43, 7, 45, 3, 42, + 33, 20, 30, 17, 32, 19, 29, 16, +}; + +char unsigned const aHalftone4x4_1[16] = +{ + 0, 25, 6, 31, + 38, 12, 44, 19, + 9, 35, 3, 28, + 47, 22, 41, 15 +}; + +char unsigned const aHalftone4x4_2[16] = +{ + 41, 3, 9, 28, + 35, 15, 22, 47, + 6, 25, 38, 0, + 19, 44, 31, 12 +}; + +/*************************************************************************** + aWinGHalftoneTranslation + + Translates a 2.6 bit-per-pixel halftoned representation into the + slightly rearranged WinG Halftone Palette. +*/ + +char unsigned const aWinGHalftoneTranslation[216] = +{ + 0, + 29, + 30, + 31, + 32, + 249, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 250, + 250, + 57, + 58, + 59, + 251, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 250, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 227, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 151, + 120, + 121, + 122, + 123, + 124, + 228, + 125, + 126, + 229, + 133, + 162, + 135, + 131, + 132, + 137, + 166, + 134, + 140, + 130, + 136, + 143, + 138, + 139, + 174, + 141, + 142, + 177, + 129, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 157, + 152, + 153, + 154, + 155, + 156, + 192, + 158, + 159, + 160, + 161, + 196, + 163, + 164, + 165, + 127, + 199, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 207, + 175, + 176, + 210, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 224, + 193, + 194, + 195, + 252, + 252, + 197, + 198, + 128, + 253, + 252, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 230, + 208, + 209, + 231, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 254, + 223, + 232, + 225, + 226, + 255, +}; \ 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 index 0000000..933e3ba --- /dev/null +++ b/src/mesa/drivers/windows/mesa_extend.c @@ -0,0 +1,211 @@ +/* File: mesa_extend.c for wmesa-2.3 + Written by Li Wei (liwei@aiar.xjtu.edu.cn) +*/ + +/******************************************************************* + Users can use the following keys to control the view + + The following four key combinations can shift the view correspondingly, + function in both stereo and normal mode. + Ctrl+left arrow + Ctrl+right arrow + Ctrl+up arrow + Ctrl+down arrow + + F (captital letter) shift the camera far from objects + N (captital letter) shift the camera near from objects + S (captital letter) toggle between normal and stereo mode + I (captital letter) increase the distance between two views + D (captital letter) decrease the distance between two views + + if the Key function defined by user maps any key appearing above, it will be + masked by the program. Hence, user should either modify his own code or + modify function defaultKeyProc at the end of this file +*******************************************************************/ + +/* Log 6/14, 1997 + * revision 1.01 + * struct DisplayOptions defined for tk_ddmesa.c to read the initial file + */ + +#include "mesa_extend.h" +#include "gltk.h" +#include +#ifndef NO_STEREO + #include "stereo.h" +#endif +#ifndef NO_PARALLEL +// #include "parallel.h" +#endif + +GLenum (*userKeyProc) (int, GLenum) = NULL; + +GLfloat viewDistance = 1.0; +GLfloat deltaView = 0.1; +GLfloat deltaShift = 0.1; + +GLuint viewShift = SHIFT_NONE; +GLuint viewTag = 0 ; + +GLenum imageRendered = GL_FALSE; + +GLenum glImageRendered() +{ + return imageRendered; +} + +//Code added by Li Wei to enable stereo display +GLenum defaultKeyProc(int key, GLenum mask ) +{ + GLenum flag = GL_FALSE ; + if(mask & TK_CONTROL){ + flag = GL_TRUE ; + switch(key){ + case TK_LEFT: + viewShift = SHIFT_LEFT; + break; + case TK_RIGHT: + viewShift = SHIFT_RIGHT; + break; + case TK_UP: + viewShift = SHIFT_UP; + break; + case TK_DOWN: + viewShift = SHIFT_DOWN; + break; + default: + flag = GL_FALSE ; + } + } + if(flag == GL_FALSE){ + flag = GL_TRUE ; + switch(key){ + case TK_F: + viewShift = SHIFT_FAR; + break; + case TK_N: + viewShift = SHIFT_NEAR; + break; + +#if !defined(NO_STEREO) + case TK_D: + viewDistance-= deltaView; + break; + case TK_I: + viewDistance+= deltaView; + break; + case TK_S: + toggleStereoMode(); + break; +#endif + +#if !defined(NO_PARALLEL) + case TK_P: + if(machineType == MASTER) + toggleParallelMode(); + break; +#endif + default: + flag = GL_FALSE; + } + } + + if(userKeyProc) + flag=flag||(*userKeyProc)(key, mask); + +#if !defined(NO_PARALLEL) + if(parallelFlag&&key!=TK_P&&machineType == MASTER){ + PRKeyDown(key,mask); + } +#endif + + return flag; +} + +/* The following function implemented key board control of the display, + availabe even in normal mode so long the driver is linked into exe file. +*/ +void shiftView() +{ + GLfloat cm[16]; + if(viewShift != SHIFT_NONE){ +/* glGetFloatv(GL_MODELVIEW_MATRIX,cm); + glMatrixMode(GL_MODELVIEW); +*/ + GLint matrix_mode; + glGetIntegerv(GL_MATRIX_MODE,&matrix_mode); +/* if(matrix_mode!=GL_PROJECTION) + glMatrixMode(GL_PROJECTION); + glGetFloatv(GL_PROJECTION_MATRIX,cm); + glLoadIdentity(); + switch(viewShift){ + case SHIFT_LEFT: + glTranslatef(-deltaShift,0,0); + break; + case SHIFT_RIGHT: + glTranslatef(deltaShift,0,0); + break; + case SHIFT_UP: + glTranslatef(0,deltaShift,0); + break; + case SHIFT_DOWN: + glTranslatef(0,-deltaShift,0); + break; + case SHIFT_FAR: + glTranslatef(0,0,-deltaShift); + break; + case SHIFT_NEAR: + glTranslatef(0,0,deltaShift); + break; + } + + viewShift = SHIFT_NONE; + glMultMatrixf( cm ); + if(matrix_mode!=GL_PROJECTION) + glMatrixMode(matrix_mode); + + } +*/ + if(matrix_mode!=GL_MODELVIEW) + glMatrixMode(GL_MODELVIEW); + glGetFloatv(GL_MODELVIEW_MATRIX,cm); + glLoadIdentity(); + switch(viewShift){ + case SHIFT_LEFT: + glTranslatef(-deltaShift,0,0); + break; + case SHIFT_RIGHT: + glTranslatef(deltaShift,0,0); + break; + case SHIFT_UP: + glTranslatef(0,deltaShift,0); + break; + case SHIFT_DOWN: + glTranslatef(0,-deltaShift,0); + break; + case SHIFT_FAR: + glTranslatef(0,0,-deltaShift); + break; + case SHIFT_NEAR: + glTranslatef(0,0,deltaShift); + break; + } + + viewShift = SHIFT_NONE; + glMultMatrixf( cm ); + if(matrix_mode!=GL_MODELVIEW) + glMatrixMode(matrix_mode); + + } +} + + +void getDisplayOptions( void) +{ + displayOptions.stereo = GetPrivateProfileInt("DISPLAY", "STEREO",1,"ddmesa.ini" ); + displayOptions.fullScreen = GetPrivateProfileInt("DISPLAY", "FULLSCREEN",0,"ddmesa.ini" ); + displayOptions.mode = GetPrivateProfileInt("DISPLAY", "MODE",1, "ddmesa.ini"); + displayOptions.bpp = GetPrivateProfileInt("DISPLAY", "BPP", 32, "ddmesa.ini"); + +} +//end modification diff --git a/src/mesa/drivers/windows/mesa_extend.h b/src/mesa/drivers/windows/mesa_extend.h new file mode 100644 index 0000000..66a8a77 --- /dev/null +++ b/src/mesa/drivers/windows/mesa_extend.h @@ -0,0 +1,43 @@ +/* mesa_extend.h + * for wmesa-2.3 + * Written by Li Wei (liwei@aiar.xjtu.edu.cn) + */ + +/* Log 6/14, 1997 + * revision 1.01 + * struct DisplayOptions defined for tk_ddmesa.c to read the initial file + */ + +#include +#include +#include +#include + +typedef enum SHIFT{ SHIFT_NONE, SHIFT_LEFT,SHIFT_RIGHT,SHIFT_UP,SHIFT_DOWN,SHIFT_FAR,SHIFT_NEAR}; + +extern GLfloat deltaView ; + +extern GLuint viewShift; + +extern GLenum glImageRendered(); + +extern GLenum imageRendered ; + +extern GLfloat deltaView ; + +extern GLfloat deltaShift; + +void shiftView( void ); + +struct DISPLAY_OPTIONS { + int stereo; + int fullScreen; + int mode; + int bpp; +}; + +extern struct DISPLAY_OPTIONS displayOptions; +extern void getDisplayOptions( void); + +GLenum defaultKeyProc(int, GLenum); +extern GLenum (*userKeyProc) (int, GLenum); diff --git a/src/mesa/drivers/windows/stereo.h b/src/mesa/drivers/windows/stereo.h new file mode 100644 index 0000000..544af54 --- /dev/null +++ b/src/mesa/drivers/windows/stereo.h @@ -0,0 +1,47 @@ +/* File name stereov.h + header file for stereo display driver +*************************************************************** +* 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 * +*************************************************************** + +*/ +#if defined( __WIN32__) || defined (WIN32) + #include +#endif + +typedef enum VIEW_INDICATOR { FIRST, SECOND}; + +#define MAXIMUM_DISPLAY_LIST 99 + +extern GLenum stereoBuffer; + +extern GLint displayList; + +extern GLint stereo_flag ; + +extern GLfloat viewDistance; + +extern GLuint viewTag; + +extern GLuint displayListBase; + +extern GLuint numOfLists; + +extern GLenum stereoCompile; + +extern GLenum stereoShowing; + +extern void glShowStereo(GLuint list); + +extern void toggleStereoMode(); + diff --git a/src/mesa/drivers/windows/wgl.c b/src/mesa/drivers/windows/wgl.c new file mode 100644 index 0000000..d5f577d --- /dev/null +++ b/src/mesa/drivers/windows/wgl.c @@ -0,0 +1,518 @@ +/* $Id: wgl.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */ + +/* +* 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. +* +*/ + +/* +* File name : wgl.c +* WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru +* Some things originated from the 3Dfx WGL functions +*/ + +#ifdef WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +#ifdef __cplusplus +} +#endif + +#include +#include +#include "wmesadef.h" +#include "GL/wmesa.h" +#include "types.h" + +#define MAX_MESA_ATTRS 20 + +struct __extensions__ +{ + PROC proc; + char *name; +}; + +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + +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)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" } +}; + +int qt_ext = sizeof(ext) / sizeof(ext[0]); + +struct __pixelformat__ pix[] = +{ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_TRUE + }, + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_FALSE + }, +}; + +int qt_pix = sizeof(pix) / sizeof(pix[0]); + +typedef struct { + WMesaContext ctx; + HDC hdc; +} MesaWglCtx; + +#define MESAWGL_CTX_MAX_COUNT 20 + +static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; + +static unsigned ctx_count = 0; +static unsigned ctx_current = -1; +static unsigned curPFD = 0; + +GLAPI BOOL GLWINAPI wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask) +{ + return(FALSE); +} + +GLAPI HGLRC GLWINAPI wglCreateContext(HDC hdc) +{ + HWND hWnd; + int i = 0; + if(!(hWnd = WindowFromDC(hdc))) + { + SetLastError(0); + return(NULL); + } + if (!ctx_count) + { + for(i=0;inSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) + { + SetLastError(0); + return(0); + } + for(i = 0;i < qt_valid_pix;i++) + { + delta = 0; + 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->iPixelType != pix[i].pfd.iPixelType) + delta++; + if(delta < bestdelta) + { + best = i + 1; + bestdelta = delta; + if(bestdelta == 0) + break; + } + } + if(best == -1) + { + SetLastError(0); + return(0); + } + return(best); +} + +GLAPI int GLWINAPI 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)) + { + SetLastError(0); + return(0); + } + *ppfd = pix[iPixelFormat - 1].pfd; + return(qt_valid_pix); +} + +/* +* GetProcAddress - return the address of an appropriate extension +*/ +GLAPI PROC GLWINAPI wglGetProcAddress(LPCSTR lpszProc) +{ + int i; + for(i = 0;i < qt_ext;i++) + if(!strcmp(lpszProc,ext[i].name)) + return(ext[i].proc); + + SetLastError(0); + return(NULL); +} + +GLAPI int GLWINAPI wglGetPixelFormat(HDC hdc) +{ + if(curPFD == 0) + { + SetLastError(0); + return(0); + } + return(curPFD); +} + +GLAPI BOOL GLWINAPI wglSetPixelFormat(HDC hdc,int iPixelFormat, + 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); +} + +GLAPI BOOL GLWINAPI wglSwapBuffers(HDC hdc) +{ + if (ctx_current < 0) + return FALSE; + + if(wgl_ctx[ctx_current].ctx == NULL) { + SetLastError(0); + return(FALSE); + } + WMesaSwapBuffers(); + return(TRUE); +} + +#endif /* WIN32 */ diff --git a/src/mesa/drivers/windows/wing32.def b/src/mesa/drivers/windows/wing32.def new file mode 100644 index 0000000..ac8fc1d --- /dev/null +++ b/src/mesa/drivers/windows/wing32.def @@ -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 index 0000000..d2c0a56 --- /dev/null +++ b/src/mesa/drivers/windows/wmesa.c @@ -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 +#include +#include +#include +#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 +#endif + +#ifdef __CYGWIN32__ +#include "macros.h" +#include +#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 (iclearpixel); + 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; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; ipixel; + 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; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + else { + for (i=0; ihPal,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; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP])); + } + else { + for (i=0; ihPal,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; ipixel), GetGValue(Current->pixel), GetBValue(Current->pixel)); + } + else { + for (i=0; ipixel); + } + 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; iScreenMem+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; iScreenMem+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; irgb_flag==GL_TRUE); + for (i=0; ipixel), + 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; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+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; irgb_flag==GL_TRUE); + for (i=0; iDriver.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 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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; + 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;iDriverCtx; + 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;iColorPtr->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;xxColorPtr->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;xxColorPtr->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 index 0000000..57269fb --- /dev/null +++ b/src/mesa/drivers/windows/wmesaBackup.c @@ -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 +#include +#include +#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 +#endif + +#ifdef __CYGWIN32__ +#include "macros.h" +#include +#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 (iclearpixel); + 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; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; ipixel; + 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; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + else { + for (i=0; ihPal,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; iScreenMem+y*Current->ScanWidth+x; + y = FLIP(y); + if (mask) { + for (i=0; ihPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP])); + } + else { + for (i=0; ihPal,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; ipixel), GetGValue(Current->pixel), GetBValue(Current->pixel)); + } + else { + for (i=0; ipixel); + } + 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; iScreenMem+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; iScreenMem+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; irgb_flag==GL_TRUE); + for (i=0; ipixel), + 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; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+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; irgb_flag==GL_TRUE); + for (i=0; iDriver.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 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 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 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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; + 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;iDriverCtx; + 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;iColor[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;xxColor[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;xxColor[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 index 0000000..afaeece --- /dev/null +++ b/src/mesa/drivers/windows/wmesaOld.c @@ -0,0 +1,2737 @@ +/* + * 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: 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 + * + * Revision 1.0 1997/06/14 17:51:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * New display driver for Mesa 2.x using Microsoft Direct Draw + * Initial vision + */ + + +#define WMESA_STEREO_C + +#include +#include +#include +#include +#include "wmesadef.h" +#include "context.h" +#include "dd.h" +#include "xform.h" +#include "vb.h" +#include "matrix.h" +#include "depth.h" + +#ifdef PROFILE +// #include "profile.h" +#endif + +#ifdef DITHER + #include +#endif + +#ifdef __CYGWIN32__ +#include "macros.h" +#include +#define CopyMemory memcpy +#endif +#include "mesa_extend.h" +#include "colors.h" + +#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 ) +{ + 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; + + 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{ + lpb += Current->ScanWidth; + memcpy(lpb, Current->pbPixels, iSize*4); + i++; + } + while(iclearpixel); + 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) +} + + + +/* 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 /*, GLuint *depth */) +{ + + int New_Size; + RECT CR; + + STARTPROFILE + GetClientRect(Current->Window,&CR); + + *width=CR.right; + *height=CR.bottom; +// *depth = Current->depth; + + 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 color-index pixels with a boolean mask. */ +static void write_index_span( 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; iScreenMem+FLIP(y)*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; ipixel; + ENDPROFILE(write_monoindex_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 color pixels with a boolean mask. */ +static void write_color_span( GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLubyte + red[], const GLubyte green[], + const GLubyte blue[], const GLubyte alpha[], + 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; iScreenMem+y*Current->ScanWidth+x; + y=FLIP(y); + if (mask) { + for (i=0; ihPal,RGB(red[i],green[i],blue[i])); + } + else { + for (i=0; ihPal,RGB(red[i],green[i],blue[i])); + } + } + ENDPROFILE(write_color_span) + +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_monocolor_span( 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; ipixel), GetGValue(Current->pixel), GetBValue(Current->pixel)); + } + else { + for (i=0; ipixel); + } + + DD_RELEASEDC; + + ENDPROFILE(write_monocolor_span) +} + + + +/**********************************************************************/ +/***** Array-based pixel drawing *****/ +/**********************************************************************/ + + +/* Write an array of pixels with a boolean mask. */ +static void write_index_pixels( 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; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; + *Mem = index[i]; + } + } + ENDPROFILE(write_index_pixels) +} + + + +/* + * Write an array of pixels with a boolean mask. The current color + * index is used for all pixels. + */ +static void write_monoindex_pixels( 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; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; + *Mem = Current->pixel; + } + } + ENDPROFILE(write_monoindex_pixels) +} + + + +/* Write an array of pixels with a boolean mask. */ +static void write_color_pixels( GLcontext* ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte r[], const GLubyte g[], + const GLubyte b[], const GLubyte a[], + const GLubyte mask[] ) +{ + STARTPROFILE + GLuint i; + PWMC pwc = Current; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; ipixel), + GetGValue(Current->pixel), GetBValue(Current->pixel)); + DD_RELEASEDC; + ENDPROFILE(write_monocolor_pixels) +} + + + +/**********************************************************************/ +/***** Read spans/arrays of pixels *****/ +/**********************************************************************/ + + +/* Read a horizontal span of color-index pixels. */ +static void read_index_span( 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; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]); + } + } + ENDPROFILE(read_index_pixels) +} + + + +/* Read a horizontal span of color pixels. */ +static void read_color_span( GLcontext* ctx, + GLuint n, GLint x, GLint y, + GLubyte red[], GLubyte green[], + GLubyte blue[], GLubyte alpha[] ) +{ + STARTPROFILE + UINT i; + COLORREF Color; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + y=FLIP(y); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iDriver.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.WriteColorSpan = write_color_span; + ctx->Driver.WriteMonocolorSpan = write_monocolor_span; + ctx->Driver.WriteColorPixels = write_color_pixels; + ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels; + ctx->Driver.WriteIndexSpan = write_index_span; + ctx->Driver.WriteMonoindexSpan = write_monoindex_span; + ctx->Driver.WriteIndexPixels = write_index_pixels; + ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadIndexSpan = read_index_span; + ctx->Driver.ReadColorSpan = read_color_span; + ctx->Driver.ReadIndexPixels = read_index_pixels; + ctx->Driver.ReadColorPixels = read_color_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 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 */ + 16, /* depth_bits */ + 8, /* stencil_bits */ + 8, /* accum_bits */ + 8, + 255.0, 255.0, 255.0, 255.0, + 8,8,8,8 ); + + if (!c->gl_visual) { + return NULL; + } + + /* allocate a new Mesa context */ + c->gl_ctx = gl_create_context( c->gl_visual, NULL,c); + + 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; + } +// 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); + Current = c; + setup_DD_pointers(c->gl_ctx); + 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 / 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 /*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; + HRESULT ddrval; + + // 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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; +#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;iDriverCtx; +#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;iDriverCtx; +#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;xxDriverCtx; +#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;xxDriverCtx; + 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;iDriverCtx; + 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;iColor[pv][0], \ + VB->Color[pv][1], VB->Color[pv][2], xx, yy); \ + pRow[i] = pixelDithered; \ + zRow[i] = z; \ + } \ + ffz += fdzdx; \ + } \ +} +#include "tritemp.h" +} + +/* + * 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;xxColor[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\ + *pixel = pixelDithered; \ + ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ + } \ +} +#include "tritemp.h" +} + +/* + * 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;xxColor[pv][0], \ + VB->Color[pv][1], VB->Color[pv][2], xx, yy); \ + *pixel = pixelDithered; \ + } \ +} +#include "tritemp.h" +} + + + + +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/wmesa_stereo.c b/src/mesa/drivers/windows/wmesa_stereo.c new file mode 100644 index 0000000..ea721a1 --- /dev/null +++ b/src/mesa/drivers/windows/wmesa_stereo.c @@ -0,0 +1,1872 @@ +/* + WMesa_stereo.c +*/ +// Stereo display feature added by Li Wei +// Updated 1996/10/06 11:16:15 CST +// Paralell render feature added by Li Wei +// liwei@aiar.xjtu.edu.cn +// http://sun.aiar.xjtu.edu.cn + +#define WMESA_STEREO_C + +#include +#include +#include +#include + +#include +#include "context.h" +#include "dd.h" +#include "xform.h" +#include "vb.h" +#include "matrix.h" +#include "depth.h" + +#ifdef PROFILE + #include "profile.h" +#endif + +#include + +// Code added by Li Wei to enable stereo display and Paralell render + + +/*#include "mesa_extend.h"*/ + +#if !defined(NO_STEREO) + + #include "gl\glu.h" + #include "stereo.h" + + PBYTE Buffer_Stereo; + + void WMesaCreateStereoBuffer(void); + + void WMesaInterleave( GLenum aView); + + void WMesaDestroyStereoBuffer(void); + + void WMesaShowStereo(GLuint list); +#endif +#if !defined(NO_PARALLEL) + #include "parallel.h" +#endif + +/* end of added code*/ + +/* Bit's used for dest: */ +#define FRONT_PIXMAP 1 +#define BACK_PIXMAP 2 +#define BACK_XIMAGE 4 + +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->db_flag) ? Current->dib.hDC : Current->hDC ) +#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->height-(Y)-1) + +#define STARTPROFILE +#define ENDPROFILE(PARA) + +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 + ); + +BOOL wmFlush(PWMC pwc); + +/* + * Useful macros: + Modified from file osmesa.c + */ + +#define PIXELADDR(X,Y) ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp) + + +/* 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)){ + 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 ) +{ + DWORD dwColor; + WORD wColor; + LPDWORD lpdw = (LPDWORD)Current->pbPixels; + LPWORD lpw = (LPWORD)Current->pbPixels; + LPBYTE lpb = Current->pbPixels; + + STARTPROFILE + + if (all){ + x=y=0; + width=Current->width; + height=Current->height; + } + if (Current->rgb_flag==GL_TRUE){ + if(Current->db_flag==GL_TRUE){ + UINT nBypp = Current->cColorBits / 8; + int i = 0; + int iSize; + + if(nBypp == 2){ + iSize = (Current->width * Current->height) / nBypp; + + wColor = BGR16(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + dwColor = MAKELONG(wColor, wColor); + } + else if(nBypp == 4){ + iSize = (Current->width * Current->height); + + dwColor = BGR32(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + } + // + // This is the 24bit case + // + else { + + iSize = (Current->width * Current->height) / nBypp; + + dwColor = BGR24(GetRValue(Current->clearpixel), + GetGValue(Current->clearpixel), + GetBValue(Current->clearpixel)); + + + while(i < iSize){ + *lpdw = dwColor; + lpb += nBypp; + lpdw = (LPDWORD)lpb; + i++; + } + + // ENDPROFILE(clear) + + return; + } + + while(i < iSize){ + *lpdw = dwColor; + lpdw++; + i++; + } + } + 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; + } + } + else { + int i; + char *Mem=Current->ScreenMem+y*Current->ScanWidth+x; + for (i=0; iclearpixel,width); + Mem+=width; + } + } + ENDPROFILE(clear) +} + + + +/* 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 ) +{ + /* No op */ +} + + + +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 /*, GLuint *depth */) +{ + + int New_Size; + RECT CR; + + STARTPROFILE + GetClientRect(Current->Window,&CR); + + *width=CR.right; + *height=CR.bottom; +// *depth = Current->depth; + + 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){ + if (Current->rgb_flag==GL_TRUE){ + wmDeleteBackingStore(Current); + wmCreateBackingStore(Current, Current->width, Current->height); + } + else{ + Current->ScanWidth=Current->width; + if ((Current->ScanWidth%sizeof(long))!=0) + Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long))); + + Current->IndexFormat->bmiHeader.biWidth=Current->width; + + if (Current->IndexFormat->bmiHeader.biHeight<0) + Current->IndexFormat->bmiHeader.biHeight=-(Current->height); + else + Current->IndexFormat->bmiHeader.biHeight=Current->height; + + Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem)); + + DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM)); + } +//Code added by Li Wei to enable stereo display +// Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE +#if !defined(NO_STEREO) + if(stereo_flag +#if !defined(NO_PARALLEL) + &&!parallelFlag +#endif + ) { + if(stereoBuffer == GL_TRUE) + WMesaDestroyStereoBuffer(); + WMesaCreateStereoBuffer(); + } +#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 +//end modification + + } + } + + 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]==0) { + 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]==0) { + 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; + } +} + +/**********************************************************************/ +/***** Optimized triangle rendering *****/ +/**********************************************************************/ + + +/* + * Smooth-shaded, z-less triangle, RGBA color. + */ +static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2, GLuint pv ) +{ +UINT nBypp = Current->cColorBits / 8; +GLbyte* img; +GLushort* img16; +GLuint *img24 ,*img32; +#define INTERP_Z 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INNER_LOOP( LEFT, RIGHT, Y ) \ +{ \ + GLint i, len = RIGHT-LEFT; \ + img = PIXELADDR(LEFT,Y); \ + for (i=0;icColorBits / 8; +GLubyte r, g, b ; +GLushort pixel16 = BGR16(r,g,b); +GLuint pixel24 = BGR24(r,g,b); +GLuint pixel32 = BGR32(r,g,b); + +#define INTERP_Z 1 +#define SETUP_CODE \ + r = VB->Color[pv][0]; \ + g = VB->Color[pv][1]; \ + b = VB->Color[pv][2]; + +#define INNER_LOOP( LEFT, RIGHT, Y ) \ +{ \ + GLint i, len = RIGHT-LEFT; \ + img = PIXELADDR(LEFT,Y); \ + for (i=0;iPolygon.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 + && ctx->Visual->RGBAflag) { + if (ctx->Light.ShadeModel==GL_SMOOTH) { + return smooth_color_z_triangle; + } + else { + return flat_color_z_triangle; + } + } + return NULL; +} + + +/* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */ +static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv ) +{ + STARTPROFILE + POINT *Pts=(POINT *) malloc(n*sizeof(POINT)); + HDC DC=DD_GETDC; + HPEN Pen; + HBRUSH Brush; + HPEN Old_Pen; + HBRUSH Old_Brush; + GLint pixel; + GLuint i; + + 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); + } + + Pen=CreatePen(PS_SOLID,1,pixel); + Brush=CreateSolidBrush(pixel); + Old_Pen=SelectObject(DC,Pen); + Old_Brush=SelectObject(DC,Brush); + + for (i=0; igl_ctx->VB->Win[j][0]; + Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] ); + } + + BEGINGDICALL + + Polygon(DC,Pts,n); + SelectObject(DC,Old_Pen); + SelectObject(DC,Old_Brush); + DeleteObject(Pen); + DeleteObject(Brush); + DD_RELEASEDC; + free(Pts); + + ENDGDICALL + + ENDPROFILE(fast_flat_rgb_polygon) +} + + + +/* Return pointer to accerated polygon function */ +static polygon_func choose_polygon_function( GLcontext* ctx ) +{ + STARTPROFILE + if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag + && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0 + && !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) { + ENDPROFILE(choose_polygon_function) + return fast_flat_rgb_polygon; + } + else { + ENDPROFILE(choose_polygon_function) + return NULL; + } +} + + + +/**********************************************************************/ +/***** Span-based pixel drawing *****/ +/**********************************************************************/ + + +/* Write a horizontal span of color-index pixels with a boolean mask. */ +static void write_index_span( GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLuint index[], + const GLubyte mask[] ) +{ + STARTPROFILE + GLuint i; + char *Mem=Current->ScreenMem+y*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; iScreenMem+y*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; ipixel; + ENDPROFILE(write_monoindex_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 color pixels with a boolean mask. */ +static void write_color_span( GLcontext* ctx, + GLuint n, GLint x, GLint y, + const GLubyte + red[], const GLubyte green[], + const GLubyte blue[], const GLubyte alpha[], + 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; iScreenMem+y*Current->ScanWidth+x; + if (mask) { + for (i=0; ihPal,RGB(red[i],green[i],blue[i])); + } + else { + for (i=0; ihPal,RGB(red[i],green[i],blue[i])); + } + } + ENDPROFILE(write_color_span) + +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_monocolor_span( 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; ipixel), GetGValue(Current->pixel), GetBValue(Current->pixel)); + } + else { + for (i=0; ipixel); + } + + DD_RELEASEDC; + + ENDPROFILE(write_monocolor_span) +} + + + +/**********************************************************************/ +/***** Array-based pixel drawing *****/ +/**********************************************************************/ + + +/* Write an array of pixels with a boolean mask. */ +static void write_index_pixels( 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; iScreenMem+y[i]*Current->ScanWidth+x[i]; + *Mem = index[i]; + } + } + ENDPROFILE(write_index_pixels) +} + + + +/* + * Write an array of pixels with a boolean mask. The current color + * index is used for all pixels. + */ +static void write_monoindex_pixels( 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; iScreenMem+y[i]*Current->ScanWidth+x[i]; + *Mem = Current->pixel; + } + } + ENDPROFILE(write_monoindex_pixels) +} + + + +/* Write an array of pixels with a boolean mask. */ +static void write_color_pixels( GLcontext* ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte r[], const GLubyte g[], + const GLubyte b[], const GLubyte a[], + const GLubyte mask[] ) +{ + STARTPROFILE + GLuint i; + PWMC pwc = Current; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; ipixel), + GetGValue(Current->pixel), GetBValue(Current->pixel)); + DD_RELEASEDC; + ENDPROFILE(write_monocolor_pixels) +} + + + +/**********************************************************************/ +/***** Read spans/arrays of pixels *****/ +/**********************************************************************/ + + +/* Read a horizontal span of color-index pixels. */ +static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[]) +{ + STARTPROFILE + GLuint i; + char *Mem=Current->ScreenMem+y*Current->ScanWidth+x; + assert(Current->rgb_flag==GL_FALSE); + for (i=0; irgb_flag==GL_FALSE); + for (i=0; iScreenMem+y[i]*Current->ScanWidth+x[i]); + } + } + ENDPROFILE(read_index_pixels) +} + + + +/* Read a horizontal span of color pixels. */ +static void read_color_span( GLcontext* ctx, + GLuint n, GLint x, GLint y, + GLubyte red[], GLubyte green[], + GLubyte blue[], GLubyte alpha[] ) +{ + STARTPROFILE + UINT i; + COLORREF Color; + HDC DC=DD_GETDC; + assert(Current->rgb_flag==GL_TRUE); + y=FLIP(y); + for (i=0; irgb_flag==GL_TRUE); + for (i=0; iDriver.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 ); + // ctx->Driver.TriangleFunc = choose_polygon_function(ctx); + + /* Pixel/span writing functions: */ + ctx->Driver.WriteColorSpan = write_color_span; + ctx->Driver.WriteMonocolorSpan = write_monocolor_span; + ctx->Driver.WriteColorPixels = write_color_pixels; + ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels; + ctx->Driver.WriteIndexSpan = write_index_span; + ctx->Driver.WriteMonoindexSpan = write_monoindex_span; + ctx->Driver.WriteIndexPixels = write_index_pixels; + ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels; + + /* Pixel/span reading functions: */ + ctx->Driver.ReadIndexSpan = read_index_span; + ctx->Driver.ReadColorSpan = read_color_span; + ctx->Driver.ReadIndexPixels = read_index_pixels; + ctx->Driver.ReadColorPixels = read_color_pixels; +} + +// +// MesaGL32 is the DLL version of MesaGL for Win32 +// + +/**********************************************************************/ +/***** 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 Window=hWnd; + c->hDC = GetDC(hWnd); + + if (rgb_flag==GL_FALSE) + { + c->rgb_flag = GL_FALSE; + c->pixel = 1; + db_flag=GL_TRUE; // WinG requires double buffering + //c->gl_ctx->BufferDepth = windepth; + } + 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; +// c->hDC GetDC(c->Window); + /* Double buffered */ + if (c->rgb_flag==GL_TRUE) + { + //DC = c->hDC = hDC; + +// DC = c->hDC = GetDC(c->Window); + wmCreateBackingStore(c, c->width, c->height); +// ReleaseDC(c->Window,DC); + } + else + { + c->dib.hDC=WinGCreateDC(); + Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD)); + c->hPal=Pal; + GetPalette(Pal,Rec->bmiColors); + WinGRecommendDIBFormat(Rec); + Rec->bmiHeader.biWidth=c->width; + Rec->bmiHeader.biHeight*=c->height; + Rec->bmiHeader.biClrUsed=PAL_SIZE; + if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8) + { + MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK); + exit(1); + } + c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem)); + c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM); + WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors); + c->IndexFormat=Rec; + c->ScanWidth=c->width; + c->cColorBits = 8; + if ((c->ScanWidth%sizeof(long))!=0) + c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long))); + } + } + else + { + /* Single Buffered */ + c->db_flag = 0; + +// wmCreateBackingStore(c, c->width, c->height); + } + + + + c->gl_visual = gl_create_visual(rgb_flag, + GL_FALSE, /* software alpha */ + db_flag, /* db_flag */ + 16, /* depth_bits */ + 8, /* stencil_bits */ + 8, /* accum_bits */ + 8, + 255.0, 255.0, 255.0, 255.0 ); + + if (!c->gl_visual) { + return NULL; + } + + /* allocate a new Mesa context */ + c->gl_ctx = gl_create_context( c->gl_visual, NULL,c); + + 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; + } +// setup_DD_pointers(c->gl_ctx); + + return c; +} + + + +void /*APIENTRY*/ WMesaDestroyContext( void ) +{ + WMesaContext c = Current; + ReleaseDC(c->Window,c->hDC); + WC = c; + + gl_destroy_visual( c->gl_visual ); + gl_destroy_framebuffer( c->gl_buffer ); + gl_destroy_context( c->gl_ctx ); + + if (c->db_flag){ + wmDeleteBackingStore(c); + +//Code added by Li Wei to enable parallel render +#if !defined(NO_STEREO) + if(stereoBuffer==GL_TRUE){ + WMesaDestroyStereoBuffer(); + stereoBuffer=GL_FALSE; + } +#endif +// End modification + } + free( (void *) c ); +//Code added by Li Wei 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); + Current = c; + setup_DD_pointers(c->gl_ctx); + if (Current->gl_ctx->Viewport.Width==0) { + /* initialize viewport to window size */ + gl_Viewport( Current->gl_ctx, + 0, 0, Current->width, Current->height ); + } +} + + + +void /*APIENTRY*/ WMesaSwapBuffers( void ) +{ + HDC DC = Current->hDC; + if (Current->db_flag) + { + if (Current->rgb_flag) + wmFlush(Current); + else + WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0); + } +} + + + +void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal) +{ + if (Current && Current->rgb_flag==GL_FALSE) + { + Current->hPal=Pal; + GetPalette(Pal,Current->IndexFormat->bmiColors); + WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors); + } +} + +// +// 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; + pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL); + 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 = lxSize; + + wmCreateDIBSection(hdc, pwc, pbmi, iUsage); + + if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) { + wmCreatePalette( pwc ); + wmSetDibColors( pwc ); + } + + 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 GLWINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags ) +{ + return(TRUE); +} + +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); + +} + +// +// 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->hDC, 0, nColors, pColTab ); + + if(!bRet) + dwErr = GetLastError(); + + free( pColTab ); + free( pPal ); + + return(bRet); +} + +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 / 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; + + lpdw = (LPDWORD)lpb; + lpw = (LPWORD)lpb; + + if(nBypp == 2) + *lpw = BGR16(r,g,b); + else if (nBypp == 3){ + *lpdw = BGR24(r,g,b); + } + else + *lpdw = BGR32(r,g,b); + } + else{ + HDC DC = DD_GETDC; + SetPixel(DC, 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 = dwScanWidth; + + 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 = ((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->hbmDIB = CreateDIBitmap(hic, + &(pwc->bmi.bmiHeader), + CBM_INIT, + pwc->pbPixels, + &(pwc->bmi), + DIB_RGB_COLORS); +*/ + pwc->hbmDIB = CreateDIBSection(hic, + &(pwc->bmi.bmiHeader), + DIB_RGB_COLORS, + &(pwc->pbPixels), + pwc->dib.hFileMap, + 0); + 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; + + +// wmFlushBits(pwc); + + bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, + pwc->dib.hDC, 0, 0, SRCCOPY); + + if(!bRet) + dwErr = GetLastError(); + + pwc->dib.fFlushed = TRUE; + + return(TRUE); + +} + + +// The following code is added by Li Wei to enable stereo display + +#if !defined(NO_STEREO) + +void WMesaCreateStereoBuffer() +{ + /* Must use double buffer and not in parallelMode */ + if (! Current->db_flag +#if !defined(NO_PARALLEL) + || parallelFlag +#endif + ) + return; + + Buffer_Stereo = malloc( Current->ScanWidth * Current->height); + ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height); + stereoBuffer = GL_TRUE ; +} + +void WMesaDestroyStereoBuffer() +{ + /* Must use double buffer and not in parallelMode */ + if (! Current->db_flag +#if !defined(NO_PARALLEL) + || parallelFlag +#endif + ) + return; + if(stereoBuffer){ + free(Buffer_Stereo); + stereoBuffer = GL_FALSE ; + } +} + +void WMesaInterleave(GLenum aView) +{ + int offset; + unsigned line; + LPBYTE dest; + LPBYTE src; + if(aView == FIRST) + offset = 0; + else offset = 1; + + dest = Buffer_Stereo + offset * Current->ScanWidth; + if(Current->rgb_flag ) + src = Current->pbPixels + Current->ScanWidth*(Current->height/2); + else + src = Current->ScreenMem; + + for(line = 0; lineheight/2; line ++){ + CopyMemory(dest, src, Current->ScanWidth); + dest += 2*Current->ScanWidth; + src += Current->ScanWidth; + } + if(aView == SECOND) + if(Current->rgb_flag) + CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height); + else + CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height); +} + +void WMesaShowStereo(GLuint list) +{ + + GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; + GLfloat cm[16]; + // Must use double Buffer + if( ! Current-> db_flag ) + return; + + glViewport(0,0,Current->width,Current->height/2); + + glGetFloatv(GL_MODELVIEW_MATRIX,cm); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(viewDistance/2,0.0,0.0 , + viewDistance/2,0.0,-1.0, + 0.0,1.0,0.0 ); + glMultMatrixf( cm ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glCallList( list ); + glPopMatrix(); + glFlush(); + WMesaInterleave( FIRST ); + + glGetFloatv(GL_MODELVIEW_MATRIX,cm); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(-viewDistance/2,0.0,0.0 , + -viewDistance/2,0.0,-1.0, + 0.0,1.0,0.0 ); + glMultMatrixf(cm); + glMatrixMode(GL_MODELVIEW); + glCallList(list); + glFlush(); + WMesaInterleave( SECOND ); + glViewport(0,0,Current->width,Current->height); + 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 + { + WMesaCreateStereoBuffer(); + } + } + else { + stereo_flag = 0; + if(stereoBuffer==GL_TRUE) +#if !defined(NO_PARALLEL) + if(!parallelFlag) +#endif + if(stereoBuffer==GL_TRUE){ + WMesaDestroyStereoBuffer(); + } + } +} + +/* 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 diff --git a/src/mesa/drivers/windows/wmesadef.h b/src/mesa/drivers/windows/wmesadef.h new file mode 100644 index 0000000..7cd4bb9 --- /dev/null +++ b/src/mesa/drivers/windows/wmesadef.h @@ -0,0 +1,154 @@ +/* File name : wmesadef.h + * Version : 2.3 + * + * Header file for display driver for Mesa 2.3 under + * Windows95, WindowsNT and Win32 + * + * 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 based on the + * Windows NT driver for Mesa, written by Mark Leaming + * (mark@rsinc.com). + */ + +/* + * $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 + * + * Initial version 1997/6/14 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + */ + +/* + * $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 + * + * Revision 2.1 1996/11/15 10:54:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * a new element added to wmesa_context : + * dither_flag + */ + +/* + * $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 + * + * Revision 2.0 1996/11/15 10:54:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn) + * Initial revision + */ + + + +#ifndef DDMESADEF_H +#define DDMESADEF_H + +#include +#include +#include "context.h" +#ifdef DDRAW + #include +#endif +//#include "profile.h" + +#define REDBITS 0x03 +#define REDSHIFT 0x00 +#define GREENBITS 0x03 +#define GREENSHIFT 0x03 +#define BLUEBITS 0x02 +#define BLUESHIFT 0x06 + +typedef struct _dibSection{ + HDC hDC; + HANDLE hFileMap; + BOOL fFlushed; + LPVOID base; +}WMDIBSECTION, *PWMDIBSECTION; + + +typedef struct wmesa_context{ + GLcontext *gl_ctx; /* The core GL/Mesa context */ + GLvisual *gl_visual; /* Describes the buffers */ + GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ + + + HWND Window; + HDC hDC; + HPALETTE hPalette; + HPALETTE hOldPalette; + HPEN hPen; + HPEN hOldPen; + HCURSOR hOldCursor; + COLORREF crColor; + // 3D projection stuff + RECT drawRect; + UINT uiDIBoffset; + // OpenGL stuff + HPALETTE hGLPalette; + GLuint width; + GLuint height; + GLuint ScanWidth; + GLboolean db_flag; //* double buffered? + GLboolean rgb_flag; //* RGB mode? + GLboolean dither_flag; //* use dither when 256 color mode for RGB? + GLuint depth; //* bits per pixel (1, 8, 24, etc) + ULONG pixel; // current color index or RGBA pixel value + ULONG clearpixel; //* pixel for clearing the color buffers + PBYTE ScreenMem; // WinG memory + BITMAPINFO *IndexFormat; + HPALETTE hPal; // Current Palette + HPALETTE hPalHalfTone; + + + WMDIBSECTION dib; + BITMAPINFO bmi; + HBITMAP hbmDIB; + HBITMAP hOldBitmap; + HBITMAP Old_Compat_BM; + HBITMAP Compat_BM; // Bitmap for double buffering + PBYTE pbPixels; + int nColors; + BYTE cColorBits; + int pixelformat; + +#ifdef DDRAW + LPDIRECTDRAW lpDD; // DirectDraw object +// LPDIRECTDRAW2 lpDD2; // DirectDraw object + LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface + LPDIRECTDRAWSURFACE lpDDSOffScreen; // DirectDraw off screen surface + LPDIRECTDRAWPALETTE lpDDPal; // DirectDraw palette + BOOL bActive; // is application active? + DDSURFACEDESC ddsd; + int fullScreen; + int gMode ; +#endif + RECT rectOffScreen; + RECT rectSurface; + HWND hwnd; + DWORD pitch; + PBYTE addrOffScreen; +//#ifdef PROFILE +// MESAPROF profile; +//#endif +} *PWMC; + + +#define PAGE_FILE 0xffffffff + + + +#endif diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c new file mode 100644 index 0000000..12567fe --- /dev/null +++ b/src/mesa/drivers/x11/fakeglx.c @@ -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 +#include +#include +#include +#include +#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;ioverlay_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; idisplay == 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;idisplay==dpy && VisualTable[i]->vishandle==vinfo) { + return VisualTable[i]; + } + } + /* try to match visual id */ + for (i=0;idisplay==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;ioverlay_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;ilayer!=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 index 0000000..b65bada --- /dev/null +++ b/src/mesa/drivers/x11/glxapi.c @@ -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 +#include +#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 index 0000000..79a2804 --- /dev/null +++ b/src/mesa/drivers/x11/realglx.c @@ -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 +#include +#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 index 0000000..9587db6 --- /dev/null +++ b/src/mesa/drivers/x11/realglx.h @@ -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 +#include +#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 index 0000000..c0e0a5f --- /dev/null +++ b/src/mesa/drivers/x11/xfonts.c @@ -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 +#include +#include +#include +#include +#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 + +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 index 0000000..256a47f --- /dev/null +++ b/src/mesa/drivers/x11/xmesaP.h @@ -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 +#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 index 0000000..115f16c --- /dev/null +++ b/src/mesa/main/Imakefile @@ -0,0 +1,127 @@ +#define DoNormalLib NO +#define DoSharedLib YES +#define DoDebugLib NO +#define DoProfileLib NO +#define LibName MESAGL +#define SoRev SOX11REV +#define LibHeaders NO + +#include + +REQUIREDLIBS = $(X11ROOT)\\XFree86\\lib\\ Xext X11 +BUILDLIBDIR = $(TOP)\\lib + +INCLUDES = -I$(TOP)\\include + +SRCS = \ +accum.c \ +alpha.c \ +alphabuf.c \ +api1.c \ +api2.c \ +attrib.c \ +bitmap.c \ +blend.c \ +bresenhm.c \ +clip.c \ +context.c \ +copypix.c \ +dd.c \ +depth.c \ +draw.c \ +drawpix.c \ +enable.c \ +eval2.c \ +feedback.c \ +fog.c \ +fortran.c \ +get.c \ +hash.c \ +glx.c \ +interp.c \ +light.c \ +lines.c \ +list.c \ +logic.c \ +masking.c \ +misc.c \ +osmesa.c \ +pb.c \ +pixel.c \ +points.c \ +polygons.c \ +readpix.c \ +scissor.c \ +span.c \ +stencil.c \ +svgamesa.c \ +texture.c \ +varray.c \ +vb.c \ +vertex.c \ +xfonts.c \ +xform.c \ +xmesa1.c \ +xmesa2.c \ +xmesa3.c + +OBJS = \ +accum.o \ +alpha.o \ +alphabuf.o \ +api1.o \ +api2.o \ +attrib.o \ +bitmap.o \ +blend.o \ +bresenhm.o \ +clip.o \ +context.o \ +copypix.o \ +dd.o \ +depth.o \ +draw.o \ +drawpix.o \ +enable.o \ +eval2.o \ +feedback.o \ +fog.o \ +fortran.o \ +get.o \ +hash.o \ +glx.o \ +interp.o \ +light.o \ +lines.o \ +list.o \ +logic.o \ +masking.o \ +misc.o \ +osmesa.o \ +pb.o \ +pixel.o \ +points.o \ +polygons.o \ +readpix.o \ +scissor.o \ +span.o \ +stencil.o \ +svgamesa.o \ +texture.o \ +varray.o \ +vb.o \ +vertex.o \ +xfonts.o \ +xform.o \ +xmesa1.o \ +xmesa2.o \ +xmesa3.o +xmesa4.o + +LINTLIBS = + +#include + +DependTarget() + + \ No newline at end of file diff --git a/src/mesa/main/KNOWN_BUGS b/src/mesa/main/KNOWN_BUGS new file mode 100644 index 0000000..9c9076b --- /dev/null +++ b/src/mesa/main/KNOWN_BUGS @@ -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 index 0000000..27c3556 --- /dev/null +++ b/src/mesa/main/Makefile.DJ @@ -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 index 0000000..e6419b5 --- /dev/null +++ b/src/mesa/main/Makefile.X11 @@ -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 index 0000000..29a8a13 --- /dev/null +++ b/src/mesa/main/accum.c @@ -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 +#include +#include +#include +#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;jBuffer->Accum + ypos * width4 + xpos * 4; + GLuint i; + gl_read_rgba_span(ctx, width, xpos, ypos, rgba); + for (i=0;iDriver.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;iDriver.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;jBuffer->Accum + ypos * width4 + xpos*4; + for (i=0;iColor.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;jBuffer->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;iAccum.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 index 0000000..dd641da --- /dev/null +++ b/src/mesa/main/accum.h @@ -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 index 0000000..78f4d05 --- /dev/null +++ b/src/mesa/main/attrib.c @@ -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 +#include +#include +#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;iClipPlane[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;iLight[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; iTexGen[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;iTransform.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; iTexture.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 index 0000000..0661c261 --- /dev/null +++ b/src/mesa/main/attrib.h @@ -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 index 0000000..10119ac --- /dev/null +++ b/src/mesa/main/blend.c @@ -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 +#include +#include +#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> 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;iColor.BlendEquation==GL_MIN_EXT); + (void) ctx; + + for (i=0;iColor.BlendEquation==GL_MAX_EXT); + (void) ctx; + + for (i=0;i> 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;iColor.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; iColor.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 index 0000000..837ea9d --- /dev/null +++ b/src/mesa/main/blend.h @@ -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 index 0000000..9feaf24 --- /dev/null +++ b/src/mesa/main/clip.c @@ -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 +#include +#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;pTransform.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 index 0000000..03e09ca --- /dev/null +++ b/src/mesa/main/clip.h @@ -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 index 0000000..22d785b --- /dev/null +++ b/src/mesa/main/colortab.c @@ -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 index 0000000..8e75f13 --- /dev/null +++ b/src/mesa/main/colortab.h @@ -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 index 0000000..0b35aba --- /dev/null +++ b/src/mesa/main/config.h @@ -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 index 0000000..55c7467 --- /dev/null +++ b/src/mesa/main/context.c @@ -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 +#include +#include +#include +#include +#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 +#include + + +/* + * 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;iDefaultD[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;iDefaultD[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;iPoints[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;iPoints[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; iTextureMatrix[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; iCurrent.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; iCurrent.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;iLight.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; iTexture.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;iTransform.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;iTexture.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;iTexture.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 index 0000000..f136da4 --- /dev/null +++ b/src/mesa/main/context.h @@ -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 index 0000000..479d73e --- /dev/null +++ b/src/mesa/main/dd.h @@ -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 index 0000000..6d5a2be --- /dev/null +++ b/src/mesa/main/depth.c @@ -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 +#include +#include +#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; iDepth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;i= *zptr) { + *zptr = z[i]; + passed++; + } + else { + *m = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + for (i=0;i= *zptr) { + /* pass */ + passed++; + } + else { + *m = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0;i *zptr) { + *zptr = z[i]; + passed++; + } + else { + *m = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + for (i=0;i *zptr) { + /* pass */ + passed++; + } + else { + *m = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + for (i=0;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; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; i= *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + for (i=0; i= *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0; i *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + for (i=0; i *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + for (i=0; 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;iBuffer->Depth) { + GLdepth *zptr = Z_ADDRESS( ctx, x, y ); + MEMCPY( depth, zptr, n * sizeof(GLdepth) ); + } + else { + GLuint i; + for (i=0;iBuffer->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 index 0000000..559afc6 --- /dev/null +++ b/src/mesa/main/depth.h @@ -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 index 0000000..d6ab057 --- /dev/null +++ b/src/mesa/main/descrip.mms @@ -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 index 0000000..001de03 --- /dev/null +++ b/src/mesa/main/dlist.c @@ -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 +#include +#include +#include +#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;iExecuteFlag) { + (*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;iExecuteFlag) { + (*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;iExecuteFlag) { + (*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->CallDepthCallDepthList.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;iShared->DisplayList, range); + if (base) { + /* reserve the list IDs by with empty/dummy lists */ + GLint i; + for (i=0; iShared->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;iList.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 index 0000000..c5a5918 --- /dev/null +++ b/src/mesa/main/dlist.h @@ -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 index 0000000..a78f345 --- /dev/null +++ b/src/mesa/main/drawpix.c @@ -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 +#include +#include +#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; iCurrent.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; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (void *) src, NULL); + src += rowLength * 4; + destY++; + } + } + else { + /* with zooming */ + GLint row; + for (row=0; rowVisual->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; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (void *) src, NULL); + src += rowLength * 3; + destY++; + } + } + else { + /* with zooming */ + GLint row; + for (row=0; rowVisual->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; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (void *) rgb, NULL); + src += rowLength; + destY++; + } + } + else { + /* with zooming */ + GLint row; + assert(drawWidth < MAX_WIDTH); + for (row=0; rowVisual->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; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (void *) rgba, NULL); + src += rowLength*2; + destY++; + } + } + else { + /* with zooming */ + GLint row; + assert(drawWidth < MAX_WIDTH); + for (row=0; rowVisual->RGBAflag) { + /* convert CI data to RGBA */ + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + GLint row; + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (const GLubyte (*)[4])rgba, + NULL); + src += rowLength; + destY++; + } + return GL_TRUE; + } + else { + /* with zooming */ + GLint row; + for (row=0; rowPixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + for (row=0; rowDriver.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;iType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *src = (GLubyte *) image->Data + i * width; + for (j=0;jData + i * width; + for (j=0;jData + i * widthInBytes; + for (j=0;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;iData + 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; iCurrent.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;jData + 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;jData + j * width; + for (i=0;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;iType) { + case GL_UNSIGNED_SHORT: + { + GLushort *src = (GLushort *) image->Data + i * width; + for (j=0;jData + i * width; + for (j=0;jData + i * width; + for (j=0;jPixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) { + for (j=0;jPixel.DepthScale + ctx->Pixel.DepthBias; + } + } + + /* clamp depth values to [0,1] and convert from floats to integers */ + for (j=0;jVisual->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;iRasterMask==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;iType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *src = (GLubyte *) image->Data + i * width * components; + for (j=0;jData + i * width * components; + for (j=0;jPixel.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;jDriver.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 index 0000000..cb517ce --- /dev/null +++ b/src/mesa/main/drawpix.h @@ -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 index 0000000..7f661fb --- /dev/null +++ b/src/mesa/main/enable.c @@ -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 +#include +#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 index 0000000..92a916a --- /dev/null +++ b/src/mesa/main/enable.h @@ -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 index 0000000..69b520e --- /dev/null +++ b/src/mesa/main/enums.c @@ -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 +#include + + +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 index 0000000..028c9b4 --- /dev/null +++ b/src/mesa/main/enums.h @@ -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 index 0000000..74604a2 --- /dev/null +++ b/src/mesa/main/eval.c @@ -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 +#include +#include +#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 constant curve */ + { + for(k=0; k 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 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 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 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 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; iEvalMap.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;iEvalMap.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;iEvalMap.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;iEvalMap.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 +#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 index 0000000..a19dc47 --- /dev/null +++ b/src/mesa/main/extensions.h @@ -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 index 0000000..4251aae --- /dev/null +++ b/src/mesa/main/feedback.c @@ -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 +#include +#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;iSelect.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.NameStackDepthSelect.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.NameStackDepthSelect.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 index 0000000..99a4b7a --- /dev/null +++ b/src/mesa/main/feedback.h @@ -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 index 0000000..1579c8c --- /dev/null +++ b/src/mesa/main/fog.c @@ -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 +#include +#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;iFog.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;iProjectionMatrix.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;iFog.Index); + } + } + break; + case GL_EXP: + for (i=0;iFog.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;iFog.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 index 0000000..cf9dceb --- /dev/null +++ b/src/mesa/main/fog.h @@ -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 index 0000000..65a682c --- /dev/null +++ b/src/mesa/main/get.c @@ -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 +#include +#include +#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 index 0000000..c4e5504 --- /dev/null +++ b/src/mesa/main/get.h @@ -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 index 0000000..3d533c8 --- /dev/null +++ b/src/mesa/main/hash.c @@ -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 +#include +#include +#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;iTable[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;iTable[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 index 0000000..a38159c --- /dev/null +++ b/src/mesa/main/hash.h @@ -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 index 0000000..46c33a6 --- /dev/null +++ b/src/mesa/main/image.c @@ -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 +#include +#include +#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> 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> 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> 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;iType == GL_FLOAT); + for (j=0; jType == GL_FLOAT); + for (j=0; jType == 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> 8) & 0xff) | ((value&0xff) << 8); + *fDst++ = SHORT_TO_FLOAT(value); + } + } + else { + for (j=0;jType == GL_FLOAT); + if (packing->SwapBytes) { + for (j=0;j> 24) & 0x000000ff) | + ((value >> 8) & 0x0000ff00) | + ((value << 8) & 0x00ff0000) | + ((value << 24) & 0xff000000); + *fDst++ = INT_TO_FLOAT(value); + } + } + else { + for (j=0;jType == 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;iSwapBytes) { + /* 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; iLsbFirst) { + 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; dWidth = 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; dSwapBytes) { + for (j=0;j> 8) & 0xff) | ((value&0xff) << 8); + if (normalize) { + *dst++ = USHORT_TO_FLOAT(value); + } + else { + *dst++ = (GLfloat) value; + } + } + } + else { + if (normalize) { + for (j=0;jSwapBytes) { + for (j=0;j> 8) & 0xff) | ((value&0xff) << 8); + if (normalize) { + *dst++ = SHORT_TO_FLOAT(value); + } + else { + *dst++ = (GLfloat) value; + } + } + } + else { + if (normalize) { + for (j=0;jSwapBytes) { + GLuint value; + for (j=0;j> 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;jSwapBytes) { + GLint value; + for (j=0;j> 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;jSwapBytes) { + GLint value; + for (j=0;j> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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; iData; + for (i=0; iData; + for (i=0; i= 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;iPixel.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;iSwapBytes) { + gl_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) destination; + switch (format) { + case GL_RED: + for (i=0;iSwapBytes) { + gl_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) destination; + switch (format) { + case GL_RED: + for (i=0;iSwapBytes) { + gl_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) destination; + switch (format) { + case GL_RED: + for (i=0;iSwapBytes) { + gl_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) destination; + switch (format) { + case GL_RED: + for (i=0;iSwapBytes) { + 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 +#include +#include +#include +#include +#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;iSpotExpTable[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 index 0000000..18d25e9 --- /dev/null +++ b/src/mesa/main/light.h @@ -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 index 0000000..ed671d7 --- /dev/null +++ b/src/mesa/main/lines.c @@ -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 +#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 index 0000000..f85a7a4 --- /dev/null +++ b/src/mesa/main/lines.h @@ -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 index 0000000..61e8974 --- /dev/null +++ b/src/mesa/main/macros.h @@ -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 +#include + + +#ifdef DEBUG +# include +# 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 index 0000000..c645994 --- /dev/null +++ b/src/mesa/main/matrix.c @@ -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 +#include +#include +#include +#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<m; + GLuint mask = 0; + GLuint i; + + for (i = 0 ; i < 16 ; i++) + { + if (m[i] == 0.0) mask |= (1<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 index 0000000..f89993e --- /dev/null +++ b/src/mesa/main/matrix.h @@ -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 index 0000000..d24ee6b --- /dev/null +++ b/src/mesa/main/mesa.conf @@ -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 index 0000000..316c357 --- /dev/null +++ b/src/mesa/main/pixel.c @@ -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 +#include +#include +#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;iPixel.MapStoS[i] = (GLint) values[i]; + } + break; + case GL_PIXEL_MAP_I_TO_I: + ctx->Pixel.MapItoIsize = mapsize; + for (i=0;iPixel.MapItoI[i] = (GLint) values[i]; + } + break; + case GL_PIXEL_MAP_I_TO_R: + ctx->Pixel.MapItoRsize = mapsize; + for (i=0;iPixel.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;iPixel.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;iPixel.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;iPixel.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;iPixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + ctx->Pixel.MapGtoGsize = mapsize; + for (i=0;iPixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + ctx->Pixel.MapBtoBsize = mapsize; + for (i=0;iPixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + ctx->Pixel.MapAtoAsize = mapsize; + for (i=0;iPixel.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;iPixel.MapItoIsize;i++) { + values[i] = (GLfloat) ctx->Pixel.MapItoI[i]; + } + break; + case GL_PIXEL_MAP_S_TO_S: + for (i=0;iPixel.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;iPixel.MapItoRsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_G: + for (i=0;iPixel.MapItoGsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_B: + for (i=0;iPixel.MapItoBsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_A: + for (i=0;iPixel.MapItoAsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] ); + } + break; + case GL_PIXEL_MAP_R_TO_R: + for (i=0;iPixel.MapRtoRsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + for (i=0;iPixel.MapGtoGsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + for (i=0;iPixel.MapBtoBsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + for (i=0;iPixel.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;iPixel.MapItoIsize;i++) { + values[i] = (GLushort) ctx->Pixel.MapItoI[i]; + } + break; + case GL_PIXEL_MAP_S_TO_S: + for (i=0;iPixel.MapStoSsize;i++) { + values[i] = (GLushort) ctx->Pixel.MapStoS[i]; + } + break; + case GL_PIXEL_MAP_I_TO_R: + for (i=0;iPixel.MapItoRsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_G: + for (i=0;iPixel.MapItoGsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_B: + for (i=0;iPixel.MapItoBsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_A: + for (i=0;iPixel.MapItoAsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] ); + } + break; + case GL_PIXEL_MAP_R_TO_R: + for (i=0;iPixel.MapRtoRsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + for (i=0;iPixel.MapGtoGsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + for (i=0;iPixel.MapBtoBsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + for (i=0;iPixel.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;iPixel.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;iPixel.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;iPixel.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;iPixel.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> shift) + offset; + } + } + else { + for (i=0;iPixel.MapItoIsize - 1; + GLuint i; + for (i=0;iPixel.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;iPixel.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;iPixel.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;iPixel.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> shift) + offset; + } + } + else { + for (i=0;iPixel.MapStoSsize - 1; + GLuint i; + for (i=0;iPixel.MapStoS[ stencil[i] & mask ]; + } +} + diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h new file mode 100644 index 0000000..c592d06 --- /dev/null +++ b/src/mesa/main/pixel.h @@ -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 index 0000000..928acc8 --- /dev/null +++ b/src/mesa/main/points.c @@ -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 (dist2ColorPtr->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 (dist2ColorPtr->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 (dist2ColorPtr->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 (dist2ColorPtr->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 index 0000000..a53ce9b --- /dev/null +++ b/src/mesa/main/points.h @@ -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 index 0000000..8369003 --- /dev/null +++ b/src/mesa/main/polygon.c @@ -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 +#include +#include +#include +#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 index 0000000..ac591bb --- /dev/null +++ b/src/mesa/main/polygon.h @@ -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 index 0000000..000af37 --- /dev/null +++ b/src/mesa/main/rastpos.c @@ -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 +#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; texSetCurrent.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; texSetCurrent.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 index 0000000..44dfbab --- /dev/null +++ b/src/mesa/main/rastpos.h @@ -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 index 0000000..994d955 --- /dev/null +++ b/src/mesa/main/simple_list.h @@ -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 index 0000000..69bd701 --- /dev/null +++ b/src/mesa/main/stencil.c @@ -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 +#include +#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;i0) { + stencil[i] = s-1; + } + } + } + } + else { + for (i=0;i0) { + stencil[i] = (invmask & s) | (wrtmask & (s-1)); + } + } + } + } + break; + case GL_INCR_WRAP_EXT: + if (invmask==0) { + for (i=0;iStencil.Function) { + case GL_NEVER: + /* always fail */ + for (i=0;iStencil.Ref & ctx->Stencil.ValueMask; + for (i=0;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iDriver.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;iStencil.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;i0) { + *sptr = *sptr - 1; + } + } + } + } + else { + for (i=0;i0) { + *sptr = (invmask & *sptr) | (wrtmask & (*sptr-1)); + } + } + } + } + break; + case GL_INCR_WRAP_EXT: + if (invmask==0) { + for (i=0;iStencil.Function) { + case GL_NEVER: + /* always fail */ + for (i=0;iStencil.Ref & ctx->Stencil.ValueMask; + for (i=0;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iStencil.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;iDriver.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;iStencil.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;iBuffer->Stencil) { + GLstencil *s = STENCIL_ADDRESS( x, y ); +#if STENCIL_BITS == 8 + MEMCPY( s, stencil, n * sizeof(GLstencil) ); +#else + GLuint i; + for (i=0;iBuffer->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 index 0000000..989cd98 --- /dev/null +++ b/src/mesa/main/stencil.h @@ -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 index 0000000..f2f301e --- /dev/null +++ b/src/mesa/main/teximage.c @@ -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 +#include +#include +#include +#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; jHeight; j++) { + GLubyte bitMask = 128; + for (i=0; iWidth; 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; pixelData)[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; pixelFormat) { + 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; pixelFormat) { + 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 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 && levelConst.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 && levelConst.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 && levelConst.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;jWidth * 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;jWidth * 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;kWidth * 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;kWidth * 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;jDriver.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;jData + ( zoffset + (dsty+j) * texwidth + dstx) * components; + + switch (format) { + case GL_ALPHA: + for (i=0;iDriver.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 index 0000000..eb72f961 --- /dev/null +++ b/src/mesa/main/teximage.h @@ -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 index 0000000..78691d2 --- /dev/null +++ b/src/mesa/main/texobj.c @@ -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 +#include +#include +#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;iImage[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; iConst.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; iConst.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; iConst.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;iShared, 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;i0) { + t = (struct gl_texture_object *) + HashLookup(ctx->Shared->TexObjects, texName[i]); + if (t) { + GLuint u; + for (u=0; uTexture.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;i0) { + 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;iShared->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 index 0000000..655c823 --- /dev/null +++ b/src/mesa/main/texobj.h @@ -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 index 0000000..eee5eaa --- /dev/null +++ b/src/mesa/main/texstate.c @@ -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 +#include +#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 index 0000000..870693b --- /dev/null +++ b/src/mesa/main/texstate.h @@ -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 index 0000000..b63d6a7 --- /dev/null +++ b/src/mesa/main/varray.c @@ -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 +#include +#include +#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;imaybe_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 index 0000000..fc81a61 --- /dev/null +++ b/src/mesa/main/varray.h @@ -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 index 0000000..f91a90b --- /dev/null +++ b/src/mesa/x86/3dnow.c @@ -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 + */ +#if defined(USE_3DNOW_ASM) +#include "3dnow.h" + +#include +#include +#include +#include + +#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 index 0000000..b06cc5b --- /dev/null +++ b/src/mesa/x86/3dnow.h @@ -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 + */ + + +#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 index 0000000..3c92220 --- /dev/null +++ b/src/mesa/x86/assyntax.h @@ -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 index 0000000..7d30be9 --- /dev/null +++ b/src/mesa/x86/common_x86.c @@ -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 + */ + +#include +#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 index 0000000..c8c5eff --- /dev/null +++ b/src/mesa/x86/mmx.h @@ -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 index 0000000..7bd9ec3 --- /dev/null +++ b/src/mesa/x86/mmx_blend.S @@ -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 index 0000000..fe3bb34 --- /dev/null +++ b/src/mesa/x86/x86.c @@ -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 +#include +#include +#include + +#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 index 0000000..c7aca91 --- /dev/null +++ b/src/mesa/x86/x86.h @@ -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 -- 2.7.4