From 964d7bcc860b5b2ad828f071d20c662ec279e85e Mon Sep 17 00:00:00 2001 From: pixhawk Date: Fri, 1 Oct 2010 08:37:55 +0200 Subject: [PATCH] Removing GLUT dependency --- lib/glut-3.7.6/CHANGES | 988 ++ lib/glut-3.7.6/FAQ.glut | 915 ++ lib/glut-3.7.6/Glut.cf | 197 + lib/glut-3.7.6/IAFA-PACKAGE | 9 + lib/glut-3.7.6/Imakefile | 7 + lib/glut-3.7.6/NOTICE | 15 + lib/glut-3.7.6/Portability.txt | 135 + lib/glut-3.7.6/README | 186 + lib/glut-3.7.6/README-win32.txt | 613 + lib/glut-3.7.6/README.ada | 42 + lib/glut-3.7.6/README.fortran | 190 + lib/glut-3.7.6/README.glut2 | 84 + lib/glut-3.7.6/README.glut3 | 114 + lib/glut-3.7.6/README.ibm-shlib | 79 + lib/glut-3.7.6/README.inventor | 57 + lib/glut-3.7.6/README.irix6 | 68 + lib/glut-3.7.6/README.irix64bit | 6 + lib/glut-3.7.6/README.linux | 29 + lib/glut-3.7.6/README.man | 80 + lib/glut-3.7.6/README.mesa | 33 + lib/glut-3.7.6/README.mui | 91 + lib/glut-3.7.6/README.xinput | 265 + lib/glut-3.7.6/adainclude/GL/glut.adb | 118 + lib/glut-3.7.6/adainclude/GL/glut.ads | 920 ++ lib/glut-3.7.6/glut-3.7.6.pro | 167 + lib/glut-3.7.6/glut.dsw | 29 + lib/glut-3.7.6/glutdefs | 50 + lib/glut-3.7.6/include/GL/fgl.h | 1707 ++ lib/glut-3.7.6/include/GL/fglu.h | 210 + lib/glut-3.7.6/include/GL/fglut.h | 321 + lib/glut-3.7.6/include/GL/glsmap.h | 137 + lib/glut-3.7.6/include/GL/glut.h | 716 + lib/glut-3.7.6/include/GL/glutf90.h | 81 + lib/glut-3.7.6/include/GL/tube.h | 205 + lib/glut-3.7.6/include/mui/browser.h | 47 + lib/glut-3.7.6/include/mui/displaylist.h | 61 + lib/glut-3.7.6/include/mui/gizmo.h | 241 + lib/glut-3.7.6/include/mui/hslider.h | 39 + lib/glut-3.7.6/include/mui/mui.h | 156 + lib/glut-3.7.6/include/mui/textlist.h | 38 + lib/glut-3.7.6/include/mui/uicolor.h | 63 + lib/glut-3.7.6/include/mui/vslider.h | 39 + lib/glut-3.7.6/lib/Imakefile | 13 + lib/glut-3.7.6/lib/_all.dsp | 63 + lib/glut-3.7.6/lib/dll.dsw | 41 + lib/glut-3.7.6/lib/fglut.n32/ObjectType.mk | 2 + lib/glut-3.7.6/lib/fglut.n64/ObjectType.mk | 2 + lib/glut-3.7.6/lib/fglut/ObjectType.mk | 2 + lib/glut-3.7.6/lib/fglut/fglut.c | 287 + lib/glut-3.7.6/lib/fglut/fglut_8x13.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_9x15.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_hel10.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_hel12.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_hel18.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_mroman.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_roman.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_tr10.c | 11 + lib/glut-3.7.6/lib/fglut/fglut_tr24.c | 11 + lib/glut-3.7.6/lib/gle.n32/ObjectType.mk | 2 + lib/glut-3.7.6/lib/gle.n64/ObjectType.mk | 3 + lib/glut-3.7.6/lib/gle/Imakefile | 30 + lib/glut-3.7.6/lib/gle/ObjectType.mk | 2 + lib/glut-3.7.6/lib/gle/copy.h | 18 + lib/glut-3.7.6/lib/gle/ex_angle.c | 519 + lib/glut-3.7.6/lib/gle/ex_cut_round.c | 1314 ++ lib/glut-3.7.6/lib/gle/ex_raw.c | 948 ++ lib/glut-3.7.6/lib/gle/extrude.c | 787 + lib/glut-3.7.6/lib/gle/extrude.h | 94 + lib/glut-3.7.6/lib/gle/gle.dsp | 173 + lib/glut-3.7.6/lib/gle/gle_dll.dsp | 180 + lib/glut-3.7.6/lib/gle/gutil.h | 91 + lib/glut-3.7.6/lib/gle/intersect.c | 67 + lib/glut-3.7.6/lib/gle/intersect.h | 391 + lib/glut-3.7.6/lib/gle/port.h | 296 + lib/glut-3.7.6/lib/gle/qmesh.c | 196 + lib/glut-3.7.6/lib/gle/rot.h | 98 + lib/glut-3.7.6/lib/gle/rot_prince.c | 303 + lib/glut-3.7.6/lib/gle/rotate.c | 134 + lib/glut-3.7.6/lib/gle/round_cap.c | 211 + lib/glut-3.7.6/lib/gle/segment.c | 423 + lib/glut-3.7.6/lib/gle/segment.h | 95 + lib/glut-3.7.6/lib/gle/texgen.c | 404 + lib/glut-3.7.6/lib/gle/tube_gc.h | 73 + lib/glut-3.7.6/lib/gle/urotate.c | 217 + lib/glut-3.7.6/lib/gle/view.c | 308 + lib/glut-3.7.6/lib/gle/vvector.h | 1339 ++ lib/glut-3.7.6/lib/glsmap.n32/ObjectType.mk | 2 + lib/glut-3.7.6/lib/glsmap.n64/ObjectType.mk | 3 + lib/glut-3.7.6/lib/glsmap/Imakefile | 32 + lib/glut-3.7.6/lib/glsmap/ObjectType.mk | 2 + lib/glut-3.7.6/lib/glsmap/glsmap.dsp | 172 + lib/glut-3.7.6/lib/glsmap/glsmapint.h | 102 + lib/glut-3.7.6/lib/glsmap/smap_buildsmap.c | 227 + lib/glut-3.7.6/lib/glsmap/smap_context.c | 20 + lib/glut-3.7.6/lib/glsmap/smap_create.c | 98 + lib/glut-3.7.6/lib/glsmap/smap_destroy.c | 34 + lib/glut-3.7.6/lib/glsmap/smap_drawmesh.c | 50 + lib/glut-3.7.6/lib/glsmap/smap_flag.c | 20 + lib/glut-3.7.6/lib/glsmap/smap_get.c | 32 + lib/glut-3.7.6/lib/glsmap/smap_getfunc.c | 20 + lib/glut-3.7.6/lib/glsmap/smap_gettexdim.c | 21 + lib/glut-3.7.6/lib/glsmap/smap_gettexobj.c | 31 + lib/glut-3.7.6/lib/glsmap/smap_getvec.c | 33 + lib/glut-3.7.6/lib/glsmap/smap_makemesh.c | 253 + lib/glut-3.7.6/lib/glsmap/smap_nearfar.c | 26 + lib/glut-3.7.6/lib/glsmap/smap_origin.c | 34 + lib/glut-3.7.6/lib/glsmap/smap_render.c | 26 + lib/glut-3.7.6/lib/glsmap/smap_rvec2st.c | 79 + lib/glut-3.7.6/lib/glsmap/smap_set.c | 32 + lib/glut-3.7.6/lib/glsmap/smap_setfunc.c | 20 + lib/glut-3.7.6/lib/glsmap/smap_setvec.c | 33 + lib/glut-3.7.6/lib/glsmap/smap_texdim.c | 21 + lib/glut-3.7.6/lib/glsmap/smap_texobj.c | 31 + lib/glut-3.7.6/lib/glut.n32/ObjectType.mk | 2 + lib/glut-3.7.6/lib/glut.n64/ObjectType.mk | 3 + lib/glut-3.7.6/lib/glut/Imakefile | 174 + lib/glut-3.7.6/lib/glut/MonoRoman.stroke | 503 + lib/glut-3.7.6/lib/glut/ObjectType.mk | 2 + lib/glut-3.7.6/lib/glut/Roman.stroke | 604 + lib/glut-3.7.6/lib/glut/capturexfont.c | 352 + lib/glut-3.7.6/lib/glut/glut.def | 126 + lib/glut-3.7.6/lib/glut/glut.ico | Bin 0 -> 3638 bytes lib/glut-3.7.6/lib/glut/glut.rc | 1 + lib/glut-3.7.6/lib/glut/glut32.dsp | 351 + lib/glut-3.7.6/lib/glut/glut_8x13.c | 2073 +++ lib/glut-3.7.6/lib/glut/glut_9x15.c | 2075 +++ lib/glut-3.7.6/lib/glut/glut_bitmap.c | 57 + lib/glut-3.7.6/lib/glut/glut_bwidth.c | 58 + lib/glut-3.7.6/lib/glut/glut_cindex.c | 252 + lib/glut-3.7.6/lib/glut/glut_cmap.c | 395 + lib/glut-3.7.6/lib/glut/glut_cursor.c | 201 + lib/glut-3.7.6/lib/glut/glut_dials.c | 26 + lib/glut-3.7.6/lib/glut/glut_dstr.c | 1637 ++ lib/glut-3.7.6/lib/glut/glut_event.c | 1386 ++ lib/glut-3.7.6/lib/glut/glut_ext.c | 53 + lib/glut-3.7.6/lib/glut/glut_fcb.c | 164 + lib/glut-3.7.6/lib/glut/glut_fullscrn.c | 52 + lib/glut-3.7.6/lib/glut/glut_gamemode.c | 674 + lib/glut-3.7.6/lib/glut/glut_get.c | 216 + lib/glut-3.7.6/lib/glut/glut_glxext.c | 48 + lib/glut-3.7.6/lib/glut/glut_hel10.c | 1778 +++ lib/glut-3.7.6/lib/glut/glut_hel12.c | 1788 +++ lib/glut-3.7.6/lib/glut/glut_hel18.c | 1897 +++ lib/glut-3.7.6/lib/glut/glut_init.c | 370 + lib/glut-3.7.6/lib/glut/glut_input.c | 645 + lib/glut-3.7.6/lib/glut/glut_joy.c | 80 + lib/glut-3.7.6/lib/glut/glut_key.c | 29 + lib/glut-3.7.6/lib/glut/glut_keyctrl.c | 29 + lib/glut-3.7.6/lib/glut/glut_keyup.c | 29 + lib/glut-3.7.6/lib/glut/glut_menu.c | 1010 ++ lib/glut-3.7.6/lib/glut/glut_menu2.c | 185 + lib/glut-3.7.6/lib/glut/glut_mesa.c | 57 + lib/glut-3.7.6/lib/glut/glut_modifier.c | 31 + lib/glut-3.7.6/lib/glut/glut_mroman.c | 2451 +++ lib/glut-3.7.6/lib/glut/glut_overlay.c | 607 + lib/glut-3.7.6/lib/glut/glut_roman.c | 2451 +++ lib/glut-3.7.6/lib/glut/glut_shapes.c | 596 + lib/glut-3.7.6/lib/glut/glut_space.c | 35 + lib/glut-3.7.6/lib/glut/glut_stroke.c | 42 + lib/glut-3.7.6/lib/glut/glut_swap.c | 47 + lib/glut-3.7.6/lib/glut/glut_swidth.c | 58 + lib/glut-3.7.6/lib/glut/glut_tablet.c | 33 + lib/glut-3.7.6/lib/glut/glut_teapot.c | 210 + lib/glut-3.7.6/lib/glut/glut_tr10.c | 1777 +++ lib/glut-3.7.6/lib/glut/glut_tr24.c | 2060 +++ lib/glut-3.7.6/lib/glut/glut_util.c | 86 + lib/glut-3.7.6/lib/glut/glut_vidresize.c | 230 + lib/glut-3.7.6/lib/glut/glut_warp.c | 23 + lib/glut-3.7.6/lib/glut/glut_win.c | 1014 ++ lib/glut-3.7.6/lib/glut/glut_winmisc.c | 122 + lib/glut-3.7.6/lib/glut/glutbitmap.h | 32 + lib/glut-3.7.6/lib/glut/glutint.h | 779 + lib/glut-3.7.6/lib/glut/glutstroke.h | 42 + lib/glut-3.7.6/lib/glut/glutwin32.h | 48 + lib/glut-3.7.6/lib/glut/layerutil.c | 201 + lib/glut-3.7.6/lib/glut/layerutil.h | 55 + lib/glut-3.7.6/lib/glut/mesa.patch2 | 38 + lib/glut-3.7.6/lib/glut/stroke.h | 134 + lib/glut-3.7.6/lib/glut/strokegen.y | 649 + lib/glut-3.7.6/lib/glut/strokelex.l | 131 + lib/glut-3.7.6/lib/glut/win32_glx.c | 254 + lib/glut-3.7.6/lib/glut/win32_glx.h | 58 + lib/glut-3.7.6/lib/glut/win32_menu.c | 531 + lib/glut-3.7.6/lib/glut/win32_util.c | 134 + lib/glut-3.7.6/lib/glut/win32_winproc.c | 763 + lib/glut-3.7.6/lib/glut/win32_x11.c | 403 + lib/glut-3.7.6/lib/glut/win32_x11.h | 319 + lib/glut-3.7.6/lib/lib.dsw | 89 + lib/glut-3.7.6/lib/mui.n32/ObjectType.mk | 2 + lib/glut-3.7.6/lib/mui.n64/ObjectType.mk | 3 + lib/glut-3.7.6/lib/mui/Imakefile | 26 + lib/glut-3.7.6/lib/mui/ObjectType.mk | 2 + lib/glut-3.7.6/lib/mui/browseparse.c | 98 + lib/glut-3.7.6/lib/mui/browser.c | 419 + lib/glut-3.7.6/lib/mui/button.c | 508 + lib/glut-3.7.6/lib/mui/dirent32.h | 96 + lib/glut-3.7.6/lib/mui/displaylist.c | 154 + lib/glut-3.7.6/lib/mui/gizmo.c | 447 + lib/glut-3.7.6/lib/mui/glutmui.c | 184 + lib/glut-3.7.6/lib/mui/hslider.c | 488 + lib/glut-3.7.6/lib/mui/miscui.c | 129 + lib/glut-3.7.6/lib/mui/mui.c | 638 + lib/glut-3.7.6/lib/mui/mui.dsp | 137 + lib/glut-3.7.6/lib/mui/pulldown.c | 469 + lib/glut-3.7.6/lib/mui/textlist.c | 438 + lib/glut-3.7.6/lib/mui/uicolor.c | 139 + lib/glut-3.7.6/lib/mui/vslider.c | 490 + lib/glut-3.7.6/man/Imakefile | 7 + lib/glut-3.7.6/man/gle/Imakefile | 39 + lib/glut-3.7.6/man/gle/gle.man | 66 + lib/glut-3.7.6/man/gle/gleExtrusion.man | 57 + lib/glut-3.7.6/man/gle/gleHelicoid.man | 48 + lib/glut-3.7.6/man/gle/gleLathe.man | 62 + lib/glut-3.7.6/man/gle/glePolyCone.man | 42 + lib/glut-3.7.6/man/gle/glePolyCylinder.man | 42 + lib/glut-3.7.6/man/gle/gleScrew.man | 43 + lib/glut-3.7.6/man/gle/gleSetJoinStyle.man | 88 + lib/glut-3.7.6/man/gle/gleSpiral.man | 110 + lib/glut-3.7.6/man/gle/gleSuperExtrusion.man | 64 + lib/glut-3.7.6/man/gle/gleTextureMode.man | 160 + lib/glut-3.7.6/man/gle/gleToroid.man | 48 + lib/glut-3.7.6/man/gle/gleTwistExtrusion.man | 66 + lib/glut-3.7.6/man/glut/Imakefile | 132 + lib/glut-3.7.6/man/glut/glut.man | 247 + lib/glut-3.7.6/man/glut/glutAddMenuEntry.man | 26 + lib/glut-3.7.6/man/glut/glutAddSubMenu.man | 27 + lib/glut-3.7.6/man/glut/glutAttachMenu.man | 29 + .../man/glut/glutBitmapCharacter.man | 102 + lib/glut-3.7.6/man/glut/glutBitmapWidth.man | 34 + lib/glut-3.7.6/man/glut/glutButtonBoxFunc.man | 37 + .../man/glut/glutChangeToMenuEntry.man | 32 + .../man/glut/glutChangeToSubMenu.man | 32 + lib/glut-3.7.6/man/glut/glutCopyColormap.man | 47 + lib/glut-3.7.6/man/glut/glutCreateMenu.man | 61 + .../man/glut/glutCreateSubWindow.man | 47 + lib/glut-3.7.6/man/glut/glutCreateWindow.man | 43 + lib/glut-3.7.6/man/glut/glutDestroyMenu.man | 22 + lib/glut-3.7.6/man/glut/glutDestroyWindow.man | 25 + lib/glut-3.7.6/man/glut/glutDeviceGet.man | 85 + lib/glut-3.7.6/man/glut/glutDialsFunc.man | 37 + lib/glut-3.7.6/man/glut/glutDisplayFunc.man | 59 + lib/glut-3.7.6/man/glut/glutEnterGameMode.man | 72 + lib/glut-3.7.6/man/glut/glutEntryFunc.man | 31 + .../man/glut/glutEstablishOverlay.man | 97 + .../man/glut/glutExtensionSupported.man | 49 + .../man/glut/glutForceJoystickFunc.man | 40 + lib/glut-3.7.6/man/glut/glutFullScreen.man | 38 + lib/glut-3.7.6/man/glut/glutGameModeGet.man | 52 + .../man/glut/glutGameModeString.man | 20 + lib/glut-3.7.6/man/glut/glutGet.man | 161 + lib/glut-3.7.6/man/glut/glutGetColor.man | 33 + lib/glut-3.7.6/man/glut/glutGetModifiers.man | 35 + lib/glut-3.7.6/man/glut/glutIdleFunc.man | 73 + .../man/glut/glutIgnoreKeyRepeat.man | 30 + lib/glut-3.7.6/man/glut/glutInit.man | 81 + .../man/glut/glutInitDisplayMode.man | 93 + .../man/glut/glutInitDisplayString.man | 250 + .../man/glut/glutInitWindowPosition.man | 74 + lib/glut-3.7.6/man/glut/glutJoystickFunc.man | 67 + lib/glut-3.7.6/man/glut/glutKeyboardFunc.man | 38 + .../man/glut/glutKeyboardUpFunc.man | 47 + lib/glut-3.7.6/man/glut/glutLayerGet.man | 51 + lib/glut-3.7.6/man/glut/glutMainLoop.man | 20 + .../man/glut/glutMenuStatusFunc.man | 50 + lib/glut-3.7.6/man/glut/glutMotionFunc.man | 34 + lib/glut-3.7.6/man/glut/glutMouseFunc.man | 45 + .../man/glut/glutOverlayDisplayFunc.man | 49 + lib/glut-3.7.6/man/glut/glutPopWindow.man | 24 + .../man/glut/glutPositionWindow.man | 39 + .../man/glut/glutPostOverlayRedisplay.man | 88 + lib/glut-3.7.6/man/glut/glutPostRedisplay.man | 37 + .../man/glut/glutRemoveMenuItem.man | 23 + lib/glut-3.7.6/man/glut/glutRemoveOverlay.man | 26 + lib/glut-3.7.6/man/glut/glutReportErrors.man | 29 + lib/glut-3.7.6/man/glut/glutReshapeFunc.man | 41 + lib/glut-3.7.6/man/glut/glutReshapeWindow.man | 40 + lib/glut-3.7.6/man/glut/glutSetColor.man | 35 + lib/glut-3.7.6/man/glut/glutSetCursor.man | 99 + lib/glut-3.7.6/man/glut/glutSetKeyRepeat.man | 30 + lib/glut-3.7.6/man/glut/glutSetMenu.man | 23 + lib/glut-3.7.6/man/glut/glutSetWindow.man | 26 + .../man/glut/glutSetWindowTitle.man | 30 + lib/glut-3.7.6/man/glut/glutShowOverlay.man | 26 + lib/glut-3.7.6/man/glut/glutShowWindow.man | 28 + lib/glut-3.7.6/man/glut/glutSolidCone.man | 34 + lib/glut-3.7.6/man/glut/glutSolidCube.man | 25 + .../man/glut/glutSolidDodecahedron.man | 23 + .../man/glut/glutSolidIcosahedron.man | 23 + .../man/glut/glutSolidOctahedron.man | 23 + lib/glut-3.7.6/man/glut/glutSolidSphere.man | 31 + lib/glut-3.7.6/man/glut/glutSolidTeapot.man | 42 + .../man/glut/glutSolidTetrahedron.man | 23 + lib/glut-3.7.6/man/glut/glutSolidTorus.man | 36 + .../man/glut/glutSpaceballButtonFunc.man | 36 + .../man/glut/glutSpaceballMotionFunc.man | 34 + .../man/glut/glutSpaceballRotateFunc.man | 35 + lib/glut-3.7.6/man/glut/glutSpecialFunc.man | 102 + lib/glut-3.7.6/man/glut/glutSpecialUpFunc.man | 105 + .../man/glut/glutStrokeCharacter.man | 66 + lib/glut-3.7.6/man/glut/glutStrokeWidth.man | 35 + lib/glut-3.7.6/man/glut/glutSwapBuffers.man | 30 + .../man/glut/glutTabletButtonFunc.man | 39 + .../man/glut/glutTabletMotionFunc.man | 34 + lib/glut-3.7.6/man/glut/glutTimerFunc.man | 37 + lib/glut-3.7.6/man/glut/glutUseLayer.man | 28 + .../man/glut/glutVisibilityFunc.man | 39 + lib/glut-3.7.6/man/glut/glutWarpPointer.man | 39 + lib/glut-3.7.6/mkmkfiles.imake | 65 + lib/glut-3.7.6/mkmkfiles.sgi | 12 + lib/glut-3.7.6/progs/Imakefile | 14 + lib/glut-3.7.6/progs/ada/README | 10 + lib/glut-3.7.6/progs/ada/ada_sphere.adb | 40 + lib/glut-3.7.6/progs/ada/ada_sphere_procs.adb | 60 + lib/glut-3.7.6/progs/ada/ada_sphere_procs.ads | 10 + lib/glut-3.7.6/progs/ada/bezmesh.adb | 71 + lib/glut-3.7.6/progs/ada/bezmesh_procs.adb | 116 + lib/glut-3.7.6/progs/ada/bezmesh_procs.ads | 46 + lib/glut-3.7.6/progs/ada/cone.adb | 68 + lib/glut-3.7.6/progs/ada/cone_procs.adb | 120 + lib/glut-3.7.6/progs/ada/cone_procs.ads | 44 + lib/glut-3.7.6/progs/ada/dof.adb | 68 + lib/glut-3.7.6/progs/ada/dof_procs.adb | 200 + lib/glut-3.7.6/progs/ada/dof_procs.ads | 62 + lib/glut-3.7.6/progs/ada/fog.adb | 67 + lib/glut-3.7.6/progs/ada/fog_procs.adb | 162 + lib/glut-3.7.6/progs/ada/fog_procs.ads | 48 + lib/glut-3.7.6/progs/ada/jitter.ads | 182 + lib/glut-3.7.6/progs/ada/pickdepth.adb | 69 + lib/glut-3.7.6/progs/ada/pickdepth_procs.adb | 166 + lib/glut-3.7.6/progs/ada/pickdepth_procs.ads | 45 + lib/glut-3.7.6/progs/ada/scenebamb.adb | 68 + lib/glut-3.7.6/progs/ada/scenebamb_procs.adb | 109 + lib/glut-3.7.6/progs/ada/scenebamb_procs.ads | 42 + lib/glut-3.7.6/progs/ada/teapots.adb | 70 + lib/glut-3.7.6/progs/ada/teapots_procs.adb | 178 + lib/glut-3.7.6/progs/ada/teapots_procs.ads | 50 + lib/glut-3.7.6/progs/ada/texgen.adb | 68 + lib/glut-3.7.6/progs/ada/texgen_procs.adb | 121 + lib/glut-3.7.6/progs/ada/texgen_procs.ads | 42 + lib/glut-3.7.6/progs/ada/texturesurf.adb | 68 + .../progs/ada/texturesurf_procs.adb | 139 + .../progs/ada/texturesurf_procs.ads | 44 + lib/glut-3.7.6/progs/advanced.dsw | 659 + lib/glut-3.7.6/progs/advanced/Imakefile | 83 + lib/glut-3.7.6/progs/advanced/README | 53 + lib/glut-3.7.6/progs/advanced/Times-Italic.bw | Bin 0 -> 29864 bytes lib/glut-3.7.6/progs/advanced/_all.dsp | 63 + lib/glut-3.7.6/progs/advanced/accumaa.c | 277 + lib/glut-3.7.6/progs/advanced/accumaa.dsp | 88 + lib/glut-3.7.6/progs/advanced/addfog.c | 296 + lib/glut-3.7.6/progs/advanced/addfog.h | 8 + lib/glut-3.7.6/progs/advanced/af_depthcue.c | 163 + lib/glut-3.7.6/progs/advanced/af_depthcue.dsp | 96 + lib/glut-3.7.6/progs/advanced/af_teapots.c | 222 + lib/glut-3.7.6/progs/advanced/af_teapots.dsp | 92 + lib/glut-3.7.6/progs/advanced/boundary.c | 349 + lib/glut-3.7.6/progs/advanced/boundary.dsp | 88 + lib/glut-3.7.6/progs/advanced/comp.c | 182 + lib/glut-3.7.6/progs/advanced/comp.dsp | 96 + lib/glut-3.7.6/progs/advanced/convolve.c | 397 + lib/glut-3.7.6/progs/advanced/convolve.dsp | 88 + lib/glut-3.7.6/progs/advanced/csg.c | 343 + lib/glut-3.7.6/progs/advanced/csg.dsp | 88 + lib/glut-3.7.6/progs/advanced/decal.c | 123 + lib/glut-3.7.6/progs/advanced/decal.dsp | 88 + lib/glut-3.7.6/progs/advanced/dissolve.c | 441 + lib/glut-3.7.6/progs/advanced/dissolve.dsp | 88 + lib/glut-3.7.6/progs/advanced/envmap.c | 1195 ++ lib/glut-3.7.6/progs/advanced/envmap.dsp | 96 + lib/glut-3.7.6/progs/advanced/envphong.c | 671 + lib/glut-3.7.6/progs/advanced/envphong.dsp | 88 + lib/glut-3.7.6/progs/advanced/field.c | 258 + lib/glut-3.7.6/progs/advanced/field.dsp | 88 + lib/glut-3.7.6/progs/advanced/genmipmap.c | 192 + lib/glut-3.7.6/progs/advanced/genmipmap.dsp | 96 + lib/glut-3.7.6/progs/advanced/haloed.c | 274 + lib/glut-3.7.6/progs/advanced/haloed.dsp | 88 + lib/glut-3.7.6/progs/advanced/hello2rts.c | 636 + lib/glut-3.7.6/progs/advanced/hello2rts.dsp | 100 + lib/glut-3.7.6/progs/advanced/hiddenline.c | 335 + lib/glut-3.7.6/progs/advanced/hiddenline.dsp | 88 + lib/glut-3.7.6/progs/advanced/imgproc.c | 288 + lib/glut-3.7.6/progs/advanced/imgproc.dsp | 96 + lib/glut-3.7.6/progs/advanced/izoom.c | 671 + lib/glut-3.7.6/progs/advanced/izoom.h | 49 + lib/glut-3.7.6/progs/advanced/logopoints.h | 33 + lib/glut-3.7.6/progs/advanced/mipmap_lines.c | 301 + .../progs/advanced/mipmap_lines.dsp | 104 + lib/glut-3.7.6/progs/advanced/motionblur.c | 241 + lib/glut-3.7.6/progs/advanced/motionblur.dsp | 88 + lib/glut-3.7.6/progs/advanced/multilight.c | 536 + lib/glut-3.7.6/progs/advanced/multilight.dsp | 88 + lib/glut-3.7.6/progs/advanced/nvidia_logo.c | 239 + lib/glut-3.7.6/progs/advanced/occlude.c | 488 + lib/glut-3.7.6/progs/advanced/occlude.dsp | 88 + lib/glut-3.7.6/progs/advanced/pointburst.c | 567 + lib/glut-3.7.6/progs/advanced/pointburst.dsp | 88 + lib/glut-3.7.6/progs/advanced/projshadow.c | 377 + lib/glut-3.7.6/progs/advanced/projshadow.dsp | 88 + lib/glut-3.7.6/progs/advanced/projtex.c | 916 ++ lib/glut-3.7.6/progs/advanced/projtex.dsp | 96 + lib/glut-3.7.6/progs/advanced/rasonly.c | 326 + lib/glut-3.7.6/progs/advanced/rasonly.dsp | 88 + .../progs/advanced/redblue_stereo.c | 289 + .../progs/advanced/redblue_stereo.dsp | 88 + lib/glut-3.7.6/progs/advanced/rts.c | 2168 +++ lib/glut-3.7.6/progs/advanced/rtshadow.h | 182 + lib/glut-3.7.6/progs/advanced/sgiflag.c | 488 + lib/glut-3.7.6/progs/advanced/sgiflag.dsp | 88 + lib/glut-3.7.6/progs/advanced/sgiflag.h | 67 + lib/glut-3.7.6/progs/advanced/shadowfun.c | 1163 ++ lib/glut-3.7.6/progs/advanced/shadowfun.dsp | 88 + lib/glut-3.7.6/progs/advanced/shadowmap.c | 447 + lib/glut-3.7.6/progs/advanced/shadowmap.dsp | 88 + lib/glut-3.7.6/progs/advanced/shadowvol.c | 373 + lib/glut-3.7.6/progs/advanced/shadowvol.dsp | 88 + lib/glut-3.7.6/progs/advanced/silhouette.c | 248 + lib/glut-3.7.6/progs/advanced/silhouette.dsp | 88 + lib/glut-3.7.6/progs/advanced/softshadow.c | 405 + lib/glut-3.7.6/progs/advanced/softshadow.dsp | 88 + lib/glut-3.7.6/progs/advanced/sphere.c | 187 + lib/glut-3.7.6/progs/advanced/tess.c | 206 + lib/glut-3.7.6/progs/advanced/tess.dsp | 92 + lib/glut-3.7.6/progs/advanced/textext.c | 186 + lib/glut-3.7.6/progs/advanced/textext.dsp | 104 + lib/glut-3.7.6/progs/advanced/textile.c | 427 + lib/glut-3.7.6/progs/advanced/textile.dsp | 96 + lib/glut-3.7.6/progs/advanced/textmap.c | 328 + lib/glut-3.7.6/progs/advanced/textmap.h | 30 + lib/glut-3.7.6/progs/advanced/textrim.c | 285 + lib/glut-3.7.6/progs/advanced/textrim.dsp | 96 + lib/glut-3.7.6/progs/advanced/texture.c | 245 + lib/glut-3.7.6/progs/advanced/texture.h | 7 + lib/glut-3.7.6/progs/advanced/texwinalign.c | 354 + lib/glut-3.7.6/progs/advanced/texwinalign.dsp | 88 + lib/glut-3.7.6/progs/advanced/tvertex.c | 281 + lib/glut-3.7.6/progs/advanced/tvertex.dsp | 88 + lib/glut-3.7.6/progs/advanced/videoresize.c | 617 + lib/glut-3.7.6/progs/advanced/videoresize.dsp | 92 + lib/glut-3.7.6/progs/advanced/vox.c | 892 ++ lib/glut-3.7.6/progs/advanced/vox.dsp | 88 + lib/glut-3.7.6/progs/advanced/warp.c | 284 + lib/glut-3.7.6/progs/advanced/warp.dsp | 96 + lib/glut-3.7.6/progs/advanced/zcomposite.c | 437 + lib/glut-3.7.6/progs/advanced/zcomposite.dsp | 88 + lib/glut-3.7.6/progs/advanced97.dsw | 779 + lib/glut-3.7.6/progs/advanced97/Imakefile | 77 + lib/glut-3.7.6/progs/advanced97/_all.dsp | 63 + lib/glut-3.7.6/progs/advanced97/accconvolve.c | 223 + .../progs/advanced97/accconvolve.dsp | 96 + lib/glut-3.7.6/progs/advanced97/accumaa.c | 272 + lib/glut-3.7.6/progs/advanced97/accumaa.dsp | 88 + lib/glut-3.7.6/progs/advanced97/alphablend.c | 176 + .../progs/advanced97/alphablend.dsp | 88 + .../progs/advanced97/alphablendnosort.c | 171 + .../progs/advanced97/alphablendnosort.dsp | 88 + lib/glut-3.7.6/progs/advanced97/billboard.c | 339 + lib/glut-3.7.6/progs/advanced97/billboard.dsp | 96 + lib/glut-3.7.6/progs/advanced97/bubble.c | 450 + lib/glut-3.7.6/progs/advanced97/bubble.dsp | 96 + lib/glut-3.7.6/progs/advanced97/bump.c | 879 + lib/glut-3.7.6/progs/advanced97/bump.dsp | 96 + lib/glut-3.7.6/progs/advanced97/chromakey.c | 262 + lib/glut-3.7.6/progs/advanced97/chromakey.dsp | 96 + .../progs/advanced97/chromakey_fancy.c | 325 + .../progs/advanced97/chromakey_fancy.dsp | 96 + lib/glut-3.7.6/progs/advanced97/cloud.c | 243 + lib/glut-3.7.6/progs/advanced97/cloud.dsp | 96 + lib/glut-3.7.6/progs/advanced97/cloudl.c | 285 + lib/glut-3.7.6/progs/advanced97/cloudl.dsp | 96 + lib/glut-3.7.6/progs/advanced97/complexity.c | 234 + .../progs/advanced97/complexity.dsp | 88 + lib/glut-3.7.6/progs/advanced97/csg.c | 1408 ++ lib/glut-3.7.6/progs/advanced97/csg.dsp | 88 + lib/glut-3.7.6/progs/advanced97/d.c | 129 + lib/glut-3.7.6/progs/advanced97/decal.c | 611 + lib/glut-3.7.6/progs/advanced97/decal.dsp | 88 + lib/glut-3.7.6/progs/advanced97/dissolve.c | 443 + lib/glut-3.7.6/progs/advanced97/dissolve.dsp | 88 + lib/glut-3.7.6/progs/advanced97/explode.c | 388 + lib/glut-3.7.6/progs/advanced97/explode.dsp | 96 + lib/glut-3.7.6/progs/advanced97/fire.c | 480 + lib/glut-3.7.6/progs/advanced97/fire.dsp | 108 + .../progs/advanced97/genspheremap.c | 291 + .../progs/advanced97/genspheremap.dsp | 96 + lib/glut-3.7.6/progs/advanced97/highlight.c | 704 + lib/glut-3.7.6/progs/advanced97/highlight.dsp | 96 + lib/glut-3.7.6/progs/advanced97/interp.c | 261 + lib/glut-3.7.6/progs/advanced97/interp.dsp | 96 + lib/glut-3.7.6/progs/advanced97/lightmap.c | 1052 ++ lib/glut-3.7.6/progs/advanced97/lightmap.dsp | 96 + lib/glut-3.7.6/progs/advanced97/lightp.c | 315 + lib/glut-3.7.6/progs/advanced97/lightp.dsp | 96 + lib/glut-3.7.6/progs/advanced97/line.c | 224 + lib/glut-3.7.6/progs/advanced97/line.dsp | 88 + .../progs/advanced97/multiaccumaa.c | 436 + .../progs/advanced97/multiaccumaa.dsp | 88 + .../progs/advanced97/multialphablend.c | 202 + .../progs/advanced97/multialphablend.dsp | 88 + .../progs/advanced97/multialphablendnosort.c | 190 + .../advanced97/multialphablendnosort.dsp | 88 + lib/glut-3.7.6/progs/advanced97/multimirror.c | 367 + .../progs/advanced97/multimirror.dsp | 88 + .../progs/advanced97/multiscreendoor.c | 195 + .../progs/advanced97/multiscreendoor.dsp | 88 + .../progs/advanced97/multispheremap.c | 737 + .../progs/advanced97/multispheremap.dsp | 96 + lib/glut-3.7.6/progs/advanced97/noise.c | 263 + lib/glut-3.7.6/progs/advanced97/noise.dsp | 88 + lib/glut-3.7.6/progs/advanced97/nthsurfdemo.c | 590 + .../progs/advanced97/nthsurfdemo.dsp | 88 + lib/glut-3.7.6/progs/advanced97/paint.c | 266 + lib/glut-3.7.6/progs/advanced97/paint.dsp | 96 + lib/glut-3.7.6/progs/advanced97/projtex.c | 837 + lib/glut-3.7.6/progs/advanced97/projtex.dsp | 96 + lib/glut-3.7.6/progs/advanced97/sbias.c | 192 + lib/glut-3.7.6/progs/advanced97/sbias.dsp | 96 + lib/glut-3.7.6/progs/advanced97/screendoor.c | 194 + .../progs/advanced97/screendoor.dsp | 88 + lib/glut-3.7.6/progs/advanced97/sm.c | 112 + lib/glut-3.7.6/progs/advanced97/sm.h | 5 + lib/glut-3.7.6/progs/advanced97/smoke.c | 397 + lib/glut-3.7.6/progs/advanced97/smoke.dsp | 96 + lib/glut-3.7.6/progs/advanced97/softshadow2.c | 632 + .../progs/advanced97/softshadow2.dsp | 88 + lib/glut-3.7.6/progs/advanced97/spectral.c | 518 + lib/glut-3.7.6/progs/advanced97/spectral.dsp | 88 + lib/glut-3.7.6/progs/advanced97/sphere.c | 185 + lib/glut-3.7.6/progs/advanced97/tess.c | 185 + lib/glut-3.7.6/progs/advanced97/tess.dsp | 92 + lib/glut-3.7.6/progs/advanced97/texgen.c | 292 + lib/glut-3.7.6/progs/advanced97/texgen.dsp | 88 + lib/glut-3.7.6/progs/advanced97/texmovie.c | 192 + lib/glut-3.7.6/progs/advanced97/texmovie.dsp | 92 + lib/glut-3.7.6/progs/advanced97/texpage.c | 503 + lib/glut-3.7.6/progs/advanced97/texpage.dsp | 92 + lib/glut-3.7.6/progs/advanced97/textile.c | 365 + lib/glut-3.7.6/progs/advanced97/textile.dsp | 92 + lib/glut-3.7.6/progs/advanced97/texture.c | 256 + lib/glut-3.7.6/progs/advanced97/texture.dsp | 88 + lib/glut-3.7.6/progs/advanced97/texture.h | 16 + lib/glut-3.7.6/progs/advanced97/underwater.c | 220 + .../progs/advanced97/underwater.dsp | 96 + .../progs/advanced97/usespheremap.c | 252 + .../progs/advanced97/usespheremap.dsp | 96 + lib/glut-3.7.6/progs/advanced97/vapor.c | 376 + lib/glut-3.7.6/progs/advanced97/vapor.dsp | 96 + lib/glut-3.7.6/progs/advanced97/volume.c | 666 + lib/glut-3.7.6/progs/advanced97/volume.dsp | 89 + lib/glut-3.7.6/progs/advanced97/warp.c | 323 + lib/glut-3.7.6/progs/advanced97/warp.dsp | 96 + lib/glut-3.7.6/progs/advanced97/water.c | 322 + lib/glut-3.7.6/progs/advanced97/water.dsp | 96 + lib/glut-3.7.6/progs/advanced97/zcomposite.c | 430 + .../progs/advanced97/zcomposite.dsp | 88 + lib/glut-3.7.6/progs/aux2glut.sed | 55 + lib/glut-3.7.6/progs/bucciarelli.dsw | 149 + lib/glut-3.7.6/progs/bucciarelli/Imakefile | 22 + lib/glut-3.7.6/progs/bucciarelli/README | 155 + lib/glut-3.7.6/progs/bucciarelli/_all.dsp | 63 + lib/glut-3.7.6/progs/bucciarelli/bw.rgb | Bin 0 -> 54196 bytes lib/glut-3.7.6/progs/bucciarelli/dteapot.c | 196 + lib/glut-3.7.6/progs/bucciarelli/fire.c | 697 + lib/glut-3.7.6/progs/bucciarelli/fire.dsp | 96 + .../progs/bucciarelli/glbpaltex.dsp | 88 + lib/glut-3.7.6/progs/bucciarelli/glbpaltx.c | 160 + lib/glut-3.7.6/progs/bucciarelli/gltest.c | 535 + lib/glut-3.7.6/progs/bucciarelli/gltest.dsp | 88 + lib/glut-3.7.6/progs/bucciarelli/image.c | 232 + lib/glut-3.7.6/progs/bucciarelli/image.h | 16 + lib/glut-3.7.6/progs/bucciarelli/mnt.bin | 1 + lib/glut-3.7.6/progs/bucciarelli/paltex.c | 175 + lib/glut-3.7.6/progs/bucciarelli/paltex.dsp | 88 + lib/glut-3.7.6/progs/bucciarelli/ray.c | 862 + lib/glut-3.7.6/progs/bucciarelli/ray.dsp | 88 + lib/glut-3.7.6/progs/bucciarelli/s128.rgb | Bin 0 -> 54258 bytes lib/glut-3.7.6/progs/bucciarelli/shadow.c | 117 + lib/glut-3.7.6/progs/bucciarelli/sources.c | 85 + lib/glut-3.7.6/progs/bucciarelli/teapot.c | 594 + lib/glut-3.7.6/progs/bucciarelli/teapot.dsp | 104 + lib/glut-3.7.6/progs/bucciarelli/terrain.c | 596 + lib/glut-3.7.6/progs/bucciarelli/terrain.dsp | 88 + lib/glut-3.7.6/progs/bucciarelli/tile.rgb | Bin 0 -> 53807 bytes lib/glut-3.7.6/progs/bucciarelli/tree2.rgb | Bin 0 -> 24816 bytes lib/glut-3.7.6/progs/bucciarelli/tunnel.c | 534 + lib/glut-3.7.6/progs/bucciarelli/tunnel.dsp | 100 + lib/glut-3.7.6/progs/contrib.dsw | 209 + lib/glut-3.7.6/progs/contrib/Imakefile | 26 + lib/glut-3.7.6/progs/contrib/_all.dsp | 63 + lib/glut-3.7.6/progs/contrib/agv_example.c | 215 + lib/glut-3.7.6/progs/contrib/agv_viewer.dsp | 96 + lib/glut-3.7.6/progs/contrib/agviewer.c | 497 + lib/glut-3.7.6/progs/contrib/agviewer.h | 104 + lib/glut-3.7.6/progs/contrib/engine.c | 75 + lib/glut-3.7.6/progs/contrib/fractals.c | 713 + lib/glut-3.7.6/progs/contrib/fractals.dsp | 96 + lib/glut-3.7.6/progs/contrib/fracviewer.c | 498 + lib/glut-3.7.6/progs/contrib/fracviewer.h | 104 + lib/glut-3.7.6/progs/contrib/gears.c | 569 + lib/glut-3.7.6/progs/contrib/gears.dsp | 88 + lib/glut-3.7.6/progs/contrib/hanoi.c | 469 + lib/glut-3.7.6/progs/contrib/hanoi.dsp | 88 + lib/glut-3.7.6/progs/contrib/hanoi2.c | 444 + lib/glut-3.7.6/progs/contrib/hanoi2.dsp | 94 + lib/glut-3.7.6/progs/contrib/lineblend.c | 257 + lib/glut-3.7.6/progs/contrib/lineblend.dsp | 88 + lib/glut-3.7.6/progs/contrib/moth.c | 1372 ++ lib/glut-3.7.6/progs/contrib/moth.dsp | 88 + lib/glut-3.7.6/progs/contrib/noof.c | 475 + lib/glut-3.7.6/progs/contrib/noof.dsp | 88 + lib/glut-3.7.6/progs/contrib/rings.c | 279 + lib/glut-3.7.6/progs/contrib/rings.dsp | 88 + lib/glut-3.7.6/progs/contrib/steam.c | 621 + lib/glut-3.7.6/progs/contrib/steam.dsp | 88 + lib/glut-3.7.6/progs/contrib/text3d.c | 509 + lib/glut-3.7.6/progs/contrib/text3d.dsp | 88 + lib/glut-3.7.6/progs/contrib/worms.c | 519 + lib/glut-3.7.6/progs/contrib/worms.dsp | 88 + lib/glut-3.7.6/progs/data/00.rgb | Bin 0 -> 13275 bytes lib/glut-3.7.6/progs/data/01.rgb | Bin 0 -> 13552 bytes lib/glut-3.7.6/progs/data/02.rgb | Bin 0 -> 13284 bytes lib/glut-3.7.6/progs/data/03.rgb | Bin 0 -> 14103 bytes lib/glut-3.7.6/progs/data/04.rgb | Bin 0 -> 14205 bytes lib/glut-3.7.6/progs/data/05.rgb | Bin 0 -> 7160 bytes lib/glut-3.7.6/progs/data/brick.rgb | Bin 0 -> 66048 bytes lib/glut-3.7.6/progs/data/brush.rgb | Bin 0 -> 10097 bytes lib/glut-3.7.6/progs/data/clouds.bw | Bin 0 -> 17352 bytes lib/glut-3.7.6/progs/data/explosion.rgba | Bin 0 -> 15925 bytes lib/glut-3.7.6/progs/data/f15.data | 13182 +++++++++++++++ lib/glut-3.7.6/progs/data/fendi.rgb | Bin 0 -> 169124 bytes lib/glut-3.7.6/progs/data/flame/f00 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f01 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f02 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f03 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f04 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f05 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f06 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f07 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f08 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f09 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f10 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f11 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f12 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f13 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f14 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f15 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f16 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f17 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f18 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f19 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f20 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f21 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f22 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f23 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f24 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f25 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f26 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f27 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f28 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f29 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f30 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/flame/f31 | Bin 0 -> 16896 bytes lib/glut-3.7.6/progs/data/light.bw | Bin 0 -> 11979 bytes lib/glut-3.7.6/progs/data/mandrill.rgb | Bin 0 -> 53783 bytes lib/glut-3.7.6/progs/data/sea.rgb | Bin 0 -> 14705 bytes lib/glut-3.7.6/progs/data/sgi.bw | Bin 0 -> 12800 bytes lib/glut-3.7.6/progs/data/smoke.bw | Bin 0 -> 25430 bytes lib/glut-3.7.6/progs/data/spheremap.rgb | Bin 0 -> 12045 bytes lib/glut-3.7.6/progs/data/swamp.rgb | Bin 0 -> 27039 bytes lib/glut-3.7.6/progs/data/water.bw | Bin 0 -> 4608 bytes lib/glut-3.7.6/progs/data/wood.rgb | Bin 0 -> 12800 bytes lib/glut-3.7.6/progs/demos.dsw | 341 + lib/glut-3.7.6/progs/demos/Imakefile | 13 + lib/glut-3.7.6/progs/demos/_all.dsp | 63 + lib/glut-3.7.6/progs/demos/atlantis/Imakefile | 14 + .../progs/demos/atlantis/atlantis.c | 262 + .../progs/demos/atlantis/atlantis.dsp | 108 + .../progs/demos/atlantis/atlantis.h | 65 + lib/glut-3.7.6/progs/demos/atlantis/dolphin.c | 1934 +++ lib/glut-3.7.6/progs/demos/atlantis/shark.c | 1308 ++ lib/glut-3.7.6/progs/demos/atlantis/swim.c | 188 + lib/glut-3.7.6/progs/demos/atlantis/whale.c | 1798 +++ lib/glut-3.7.6/progs/demos/bluepony/Imakefile | 16 + .../progs/demos/bluepony/bluepony.c | 507 + .../progs/demos/bluepony/bluepony.dsp | 96 + lib/glut-3.7.6/progs/demos/bluepony/logo.bw | Bin 0 -> 16401 bytes lib/glut-3.7.6/progs/demos/bluepony/readtex.c | 307 + lib/glut-3.7.6/progs/demos/bluepony/readtex.h | 10 + lib/glut-3.7.6/progs/demos/bounce/Imakefile | 24 + lib/glut-3.7.6/progs/demos/bounce/bounce.c | 943 ++ lib/glut-3.7.6/progs/demos/bounce/bounce.dsp | 112 + lib/glut-3.7.6/progs/demos/bounce/glui.c | 509 + lib/glut-3.7.6/progs/demos/bounce/glui.h | 18 + lib/glut-3.7.6/progs/demos/bounce/tb.c | 147 + lib/glut-3.7.6/progs/demos/bounce/tb.h | 86 + lib/glut-3.7.6/progs/demos/bounce/trackball.c | 346 + lib/glut-3.7.6/progs/demos/bounce/trackball.h | 81 + lib/glut-3.7.6/progs/demos/chess/Imakefile | 16 + lib/glut-3.7.6/progs/demos/chess/animate.c | 131 + lib/glut-3.7.6/progs/demos/chess/chess.c | 995 ++ lib/glut-3.7.6/progs/demos/chess/chess.dsp | 108 + lib/glut-3.7.6/progs/demos/chess/chess.h | 36 + lib/glut-3.7.6/progs/demos/chess/chess.inp | 62 + lib/glut-3.7.6/progs/demos/chess/main.c | 200 + lib/glut-3.7.6/progs/demos/chess/pathplan.c | 85 + lib/glut-3.7.6/progs/demos/chess/texture.c | 203 + lib/glut-3.7.6/progs/demos/geoface/Imakefile | 15 + lib/glut-3.7.6/progs/demos/geoface/README | 32 + lib/glut-3.7.6/progs/demos/geoface/display.c | 313 + .../progs/demos/geoface/faceline.dat | 257 + lib/glut-3.7.6/progs/demos/geoface/fileio.c | 289 + .../progs/demos/geoface/geoface.dsp | 112 + lib/glut-3.7.6/progs/demos/geoface/head.h | 101 + lib/glut-3.7.6/progs/demos/geoface/index.dat | 239 + lib/glut-3.7.6/progs/demos/geoface/main.c | 572 + .../progs/demos/geoface/make_face.c | 529 + lib/glut-3.7.6/progs/demos/geoface/memory.h | 29 + lib/glut-3.7.6/progs/demos/geoface/muscle.c | 213 + lib/glut-3.7.6/progs/demos/geoface/muscle.dat | 91 + lib/glut-3.7.6/progs/demos/glflare/Flare1.bw | Bin 0 -> 12222 bytes lib/glut-3.7.6/progs/demos/glflare/Flare2.bw | Bin 0 -> 6648 bytes lib/glut-3.7.6/progs/demos/glflare/Flare3.bw | Bin 0 -> 12856 bytes lib/glut-3.7.6/progs/demos/glflare/Flare4.bw | Bin 0 -> 5683 bytes lib/glut-3.7.6/progs/demos/glflare/Flare5.bw | Bin 0 -> 11099 bytes lib/glut-3.7.6/progs/demos/glflare/Flare6.bw | Bin 0 -> 10540 bytes lib/glut-3.7.6/progs/demos/glflare/Imakefile | 16 + lib/glut-3.7.6/progs/demos/glflare/OpenGL.bw | Bin 0 -> 5813 bytes lib/glut-3.7.6/progs/demos/glflare/Shine0.bw | Bin 0 -> 5756 bytes lib/glut-3.7.6/progs/demos/glflare/Shine1.bw | Bin 0 -> 6254 bytes lib/glut-3.7.6/progs/demos/glflare/Shine2.bw | Bin 0 -> 5880 bytes lib/glut-3.7.6/progs/demos/glflare/Shine3.bw | Bin 0 -> 6258 bytes lib/glut-3.7.6/progs/demos/glflare/Shine4.bw | Bin 0 -> 5884 bytes lib/glut-3.7.6/progs/demos/glflare/Shine5.bw | Bin 0 -> 6021 bytes lib/glut-3.7.6/progs/demos/glflare/Shine6.bw | Bin 0 -> 5806 bytes lib/glut-3.7.6/progs/demos/glflare/Shine7.bw | Bin 0 -> 6152 bytes lib/glut-3.7.6/progs/demos/glflare/Shine8.bw | Bin 0 -> 5930 bytes lib/glut-3.7.6/progs/demos/glflare/Shine9.bw | Bin 0 -> 5913 bytes lib/glut-3.7.6/progs/demos/glflare/glflare.c | 331 + .../progs/demos/glflare/glflare.dsp | 100 + lib/glut-3.7.6/progs/demos/glflare/loadlum.c | 182 + lib/glut-3.7.6/progs/demos/glflare/loadlum.h | 11 + lib/glut-3.7.6/progs/demos/glflare/vec3d.c | 73 + lib/glut-3.7.6/progs/demos/gliq/Imakefile | 29 + lib/glut-3.7.6/progs/demos/gliq/board.c | 343 + lib/glut-3.7.6/progs/demos/gliq/boards.txt | 40 + lib/glut-3.7.6/progs/demos/gliq/game.c | 172 + lib/glut-3.7.6/progs/demos/gliq/gliq.c | 409 + lib/glut-3.7.6/progs/demos/gliq/gliq.dsp | 116 + lib/glut-3.7.6/progs/demos/gliq/gliq.h | 75 + lib/glut-3.7.6/progs/demos/gliq/pick.c | 171 + lib/glut-3.7.6/progs/demos/gliq/score.c | 277 + lib/glut-3.7.6/progs/demos/gliq/tb.c | 123 + lib/glut-3.7.6/progs/demos/gliq/tb.h | 95 + lib/glut-3.7.6/progs/demos/gliq/trackball.c | 169 + lib/glut-3.7.6/progs/demos/gliq/trackball.h | 95 + lib/glut-3.7.6/progs/demos/glutmech/Imakefile | 15 + .../progs/demos/glutmech/glutmech.c | 1764 ++ .../progs/demos/glutmech/glutmech.dsp | 88 + lib/glut-3.7.6/progs/demos/ideas/Imakefile | 20 + lib/glut-3.7.6/progs/demos/ideas/a.c | 194 + lib/glut-3.7.6/progs/demos/ideas/b.c | 146 + lib/glut-3.7.6/progs/demos/ideas/d.c | 154 + .../progs/demos/ideas/draw_holder.c | 1358 ++ lib/glut-3.7.6/progs/demos/ideas/draw_lamp.c | 826 + lib/glut-3.7.6/progs/demos/ideas/draw_logo.c | 524 + .../progs/demos/ideas/draw_logo_line.c | 378 + .../progs/demos/ideas/draw_logo_shadow.c | 488 + lib/glut-3.7.6/progs/demos/ideas/e.c | 151 + lib/glut-3.7.6/progs/demos/ideas/f.c | 175 + lib/glut-3.7.6/progs/demos/ideas/h.c | 187 + lib/glut-3.7.6/progs/demos/ideas/i.c | 132 + lib/glut-3.7.6/progs/demos/ideas/ideas.c | 1056 ++ lib/glut-3.7.6/progs/demos/ideas/ideas.dsp | 172 + lib/glut-3.7.6/progs/demos/ideas/m.c | 228 + lib/glut-3.7.6/progs/demos/ideas/n.c | 161 + lib/glut-3.7.6/progs/demos/ideas/o.c | 151 + lib/glut-3.7.6/progs/demos/ideas/objects.h | 61 + lib/glut-3.7.6/progs/demos/ideas/p.c | 184 + lib/glut-3.7.6/progs/demos/ideas/r.c | 139 + lib/glut-3.7.6/progs/demos/ideas/s.c | 142 + lib/glut-3.7.6/progs/demos/ideas/t.c | 165 + lib/glut-3.7.6/progs/demos/ideas/w.c | 245 + lib/glut-3.7.6/progs/demos/lorenz/Imakefile | 15 + lib/glut-3.7.6/progs/demos/lorenz/lorenz.c | 644 + lib/glut-3.7.6/progs/demos/lorenz/lorenz.dsp | 88 + lib/glut-3.7.6/progs/demos/newave/Imakefile | 16 + lib/glut-3.7.6/progs/demos/newave/newave.c | 890 ++ lib/glut-3.7.6/progs/demos/newave/newave.dsp | 96 + .../progs/demos/newave/spheremap.rgb | Bin 0 -> 143414 bytes lib/glut-3.7.6/progs/demos/newave/texmap.rgb | Bin 0 -> 810169 bytes lib/glut-3.7.6/progs/demos/newave/texture.c | 283 + lib/glut-3.7.6/progs/demos/newave/texture.h | 11 + .../progs/demos/opengl_logo/Imakefile | 16 + .../progs/demos/opengl_logo/def_logo.c | 622 + .../progs/demos/opengl_logo/opengl_logo.c | 133 + .../progs/demos/opengl_logo/opengl_logo.dsp | 92 + lib/glut-3.7.6/progs/demos/particle/Imakefile | 15 + .../progs/demos/particle/particle.c | 728 + .../progs/demos/particle/particle.dsp | 88 + .../progs/demos/rollercoaster/Imakefile | 16 + .../progs/demos/rollercoaster/defrc.c | 305 + .../progs/demos/rollercoaster/matrix.c | 113 + .../progs/demos/rollercoaster/matrix.h | 18 + lib/glut-3.7.6/progs/demos/rollercoaster/rc.c | 703 + .../progs/demos/rollercoaster/rc.def | 217 + .../demos/rollercoaster/rollercoaster.dsp | 100 + lib/glut-3.7.6/progs/demos/skyfly/Imakefile | 14 + lib/glut-3.7.6/progs/demos/skyfly/clouds.bw | Bin 0 -> 16625 bytes lib/glut-3.7.6/progs/demos/skyfly/database.c | 522 + lib/glut-3.7.6/progs/demos/skyfly/fly.c | 282 + lib/glut-3.7.6/progs/demos/skyfly/gm_main.c | 341 + lib/glut-3.7.6/progs/demos/skyfly/image.c | 33 + lib/glut-3.7.6/progs/demos/skyfly/perfdraw.c | 331 + lib/glut-3.7.6/progs/demos/skyfly/random.c | 376 + lib/glut-3.7.6/progs/demos/skyfly/skyfly.c | 777 + lib/glut-3.7.6/progs/demos/skyfly/skyfly.dsp | 116 + lib/glut-3.7.6/progs/demos/skyfly/skyfly.h | 206 + lib/glut-3.7.6/progs/demos/skyfly/terrain.bw | 42 + lib/glut-3.7.6/progs/demos/smooth/Imakefile | 23 + .../progs/demos/smooth/data/dolphins.mtl | 25 + .../progs/demos/smooth/data/dolphins.obj | 2562 +++ lib/glut-3.7.6/progs/demos/smooth/dirent32.h | 96 + lib/glut-3.7.6/progs/demos/smooth/glm.c | 1837 +++ lib/glut-3.7.6/progs/demos/smooth/glm.h | 247 + lib/glut-3.7.6/progs/demos/smooth/gltb.c | 173 + lib/glut-3.7.6/progs/demos/smooth/gltb.h | 95 + lib/glut-3.7.6/progs/demos/smooth/gltx.c | 240 + lib/glut-3.7.6/progs/demos/smooth/gltx.h | 35 + lib/glut-3.7.6/progs/demos/smooth/smooth.c | 574 + lib/glut-3.7.6/progs/demos/smooth/smooth.dsp | 126 + lib/glut-3.7.6/progs/demos/smooth/trackball.c | 169 + lib/glut-3.7.6/progs/demos/smooth/trackball.h | 95 + lib/glut-3.7.6/progs/demos/sunlight/Imakefile | 15 + lib/glut-3.7.6/progs/demos/sunlight/globe.raw | Bin 0 -> 196612 bytes .../progs/demos/sunlight/sunlight.c | 531 + .../progs/demos/sunlight/sunlight.dsp | 88 + lib/glut-3.7.6/progs/demos/sysview/README | 27 + lib/glut-3.7.6/progs/demos/sysview/sysview.c | 442 + .../progs/demos/sysview/sysview.dsp | 89 + .../progs/demos/underwater/Imakefile | 16 + .../progs/demos/underwater/caust00.bw | Bin 0 -> 5337 bytes .../progs/demos/underwater/caust01.bw | Bin 0 -> 5368 bytes .../progs/demos/underwater/caust02.bw | Bin 0 -> 5362 bytes .../progs/demos/underwater/caust03.bw | Bin 0 -> 5358 bytes .../progs/demos/underwater/caust04.bw | Bin 0 -> 5357 bytes .../progs/demos/underwater/caust05.bw | Bin 0 -> 5365 bytes .../progs/demos/underwater/caust06.bw | Bin 0 -> 5355 bytes .../progs/demos/underwater/caust07.bw | Bin 0 -> 5357 bytes .../progs/demos/underwater/caust08.bw | Bin 0 -> 5362 bytes .../progs/demos/underwater/caust09.bw | Bin 0 -> 5364 bytes .../progs/demos/underwater/caust10.bw | Bin 0 -> 5367 bytes .../progs/demos/underwater/caust11.bw | Bin 0 -> 5365 bytes .../progs/demos/underwater/caust12.bw | Bin 0 -> 5364 bytes .../progs/demos/underwater/caust13.bw | Bin 0 -> 5372 bytes .../progs/demos/underwater/caust14.bw | Bin 0 -> 5370 bytes .../progs/demos/underwater/caust15.bw | Bin 0 -> 5372 bytes .../progs/demos/underwater/caust16.bw | Bin 0 -> 5370 bytes .../progs/demos/underwater/caust17.bw | Bin 0 -> 5373 bytes .../progs/demos/underwater/caust18.bw | Bin 0 -> 5356 bytes .../progs/demos/underwater/caust19.bw | Bin 0 -> 5361 bytes .../progs/demos/underwater/caust20.bw | Bin 0 -> 5366 bytes .../progs/demos/underwater/caust21.bw | Bin 0 -> 5368 bytes .../progs/demos/underwater/caust22.bw | Bin 0 -> 5365 bytes .../progs/demos/underwater/caust23.bw | Bin 0 -> 5360 bytes .../progs/demos/underwater/caust24.bw | Bin 0 -> 5355 bytes .../progs/demos/underwater/caust25.bw | Bin 0 -> 5353 bytes .../progs/demos/underwater/caust26.bw | Bin 0 -> 5358 bytes .../progs/demos/underwater/caust27.bw | Bin 0 -> 5357 bytes .../progs/demos/underwater/caust28.bw | Bin 0 -> 5354 bytes .../progs/demos/underwater/caust29.bw | Bin 0 -> 5352 bytes .../progs/demos/underwater/caust30.bw | Bin 0 -> 5341 bytes .../progs/demos/underwater/caust31.bw | Bin 0 -> 5353 bytes lib/glut-3.7.6/progs/demos/underwater/dino.c | 129 + lib/glut-3.7.6/progs/demos/underwater/dino.h | 9 + .../progs/demos/underwater/floor.rgb | Bin 0 -> 54270 bytes .../progs/demos/underwater/texload.c | 253 + .../progs/demos/underwater/texload.h | 12 + .../progs/demos/underwater/underwater.c | 633 + .../progs/demos/underwater/underwater.dsp | 104 + lib/glut-3.7.6/progs/demos/walker/Imakefile | 15 + .../progs/demos/walker/Impossible.cset | 17 + lib/glut-3.7.6/progs/demos/walker/MrFlex.cset | 17 + lib/glut-3.7.6/progs/demos/walker/Ouch.cset | 17 + lib/glut-3.7.6/progs/demos/walker/README | 119 + lib/glut-3.7.6/progs/demos/walker/bound.cset | 17 + lib/glut-3.7.6/progs/demos/walker/dunk.cset | 17 + lib/glut-3.7.6/progs/demos/walker/kick.cset | 17 + lib/glut-3.7.6/progs/demos/walker/models.c | 691 + .../progs/demos/walker/moonwalk.cset | 17 + .../progs/demos/walker/reverse_dunk.cset | 17 + .../progs/demos/walker/running.cset | 17 + .../progs/demos/walker/walk_backwards.cset | 17 + lib/glut-3.7.6/progs/demos/walker/walker.c | 1112 ++ lib/glut-3.7.6/progs/demos/walker/walker.dsp | 108 + lib/glut-3.7.6/progs/demos/walker/walker.h | 13 + .../progs/demos/walker/walking.cset | 17 + .../progs/demos/walker/walkviewer.c | 493 + .../progs/demos/walker/walkviewer.h | 104 + .../progs/demos/walker/win32_dirent.h | 51 + lib/glut-3.7.6/progs/demos/yacme/Editor.c | 1372 ++ lib/glut-3.7.6/progs/demos/yacme/Imakefile | 17 + lib/glut-3.7.6/progs/demos/yacme/RGBA.h | 268 + lib/glut-3.7.6/progs/demos/yacme/invertmat.c | 212 + lib/glut-3.7.6/progs/demos/yacme/mallocbis.h | 13 + lib/glut-3.7.6/progs/demos/yacme/yacme.dsp | 100 + lib/glut-3.7.6/progs/examples.dsw | 839 + lib/glut-3.7.6/progs/examples/Imakefile | 105 + lib/glut-3.7.6/progs/examples/_all.dsp | 63 + lib/glut-3.7.6/progs/examples/abgr.c | 217 + lib/glut-3.7.6/progs/examples/abgr.dsp | 88 + lib/glut-3.7.6/progs/examples/bitfont.c | 130 + lib/glut-3.7.6/progs/examples/bitfont.dsp | 88 + lib/glut-3.7.6/progs/examples/blender.c | 161 + lib/glut-3.7.6/progs/examples/blender.dsp | 88 + lib/glut-3.7.6/progs/examples/circlefit.c | 277 + lib/glut-3.7.6/progs/examples/circlefit.dsp | 88 + lib/glut-3.7.6/progs/examples/cube.c | 93 + lib/glut-3.7.6/progs/examples/cube.dsp | 88 + lib/glut-3.7.6/progs/examples/dials.c | 145 + lib/glut-3.7.6/progs/examples/dials.dsp | 88 + lib/glut-3.7.6/progs/examples/dials2.c | 140 + lib/glut-3.7.6/progs/examples/dials2.dsp | 88 + lib/glut-3.7.6/progs/examples/dinoball.c | 332 + lib/glut-3.7.6/progs/examples/dinoball.dsp | 88 + lib/glut-3.7.6/progs/examples/dinodraw.c | 420 + lib/glut-3.7.6/progs/examples/dinodraw.dsp | 96 + lib/glut-3.7.6/progs/examples/dinoshade.c | 891 ++ lib/glut-3.7.6/progs/examples/dinoshade.dsp | 88 + lib/glut-3.7.6/progs/examples/dinospin.c | 352 + lib/glut-3.7.6/progs/examples/dinospin.dsp | 96 + lib/glut-3.7.6/progs/examples/editgrid.c | 314 + lib/glut-3.7.6/progs/examples/editgrid.dsp | 88 + lib/glut-3.7.6/progs/examples/evaltest.c | 507 + lib/glut-3.7.6/progs/examples/evaltest.dsp | 88 + lib/glut-3.7.6/progs/examples/fogtst.c | 261 + lib/glut-3.7.6/progs/examples/fogtst.dsp | 88 + lib/glut-3.7.6/progs/examples/fontdemo.c | 102 + lib/glut-3.7.6/progs/examples/fontdemo.dsp | 88 + lib/glut-3.7.6/progs/examples/glpuzzle.c | 1439 ++ lib/glut-3.7.6/progs/examples/glpuzzle.dsp | 96 + lib/glut-3.7.6/progs/examples/glutdino.c | 244 + lib/glut-3.7.6/progs/examples/glutdino.dsp | 88 + lib/glut-3.7.6/progs/examples/glutplane.c | 270 + lib/glut-3.7.6/progs/examples/glutplane.dsp | 88 + .../progs/examples/gouraudtriangle.ps | 109 + lib/glut-3.7.6/progs/examples/halomagic.c | 1094 ++ lib/glut-3.7.6/progs/examples/halomagic.dsp | 88 + lib/glut-3.7.6/progs/examples/highlight.c | 405 + lib/glut-3.7.6/progs/examples/highlight.dsp | 88 + lib/glut-3.7.6/progs/examples/lightlab.c | 284 + lib/glut-3.7.6/progs/examples/lightlab.dsp | 88 + lib/glut-3.7.6/progs/examples/logo.c | 89 + lib/glut-3.7.6/progs/examples/luminance16.c | 154 + lib/glut-3.7.6/progs/examples/luminance16.dsp | 88 + lib/glut-3.7.6/progs/examples/mjkimage.c | 13244 ++++++++++++++++ lib/glut-3.7.6/progs/examples/mjksift.c | 261 + lib/glut-3.7.6/progs/examples/mjksift.dsp | 92 + lib/glut-3.7.6/progs/examples/mjkwarp.c | 329 + lib/glut-3.7.6/progs/examples/mjkwarp.dsp | 92 + lib/glut-3.7.6/progs/examples/molehill.c | 153 + lib/glut-3.7.6/progs/examples/molehill.dsp | 88 + lib/glut-3.7.6/progs/examples/movelight.c | 289 + lib/glut-3.7.6/progs/examples/movelight.dsp | 88 + lib/glut-3.7.6/progs/examples/oclip.c | 207 + lib/glut-3.7.6/progs/examples/oclip.dsp | 88 + lib/glut-3.7.6/progs/examples/ohidden.c | 263 + lib/glut-3.7.6/progs/examples/ohidden.dsp | 88 + lib/glut-3.7.6/progs/examples/olight.c | 241 + lib/glut-3.7.6/progs/examples/olight.dsp | 88 + lib/glut-3.7.6/progs/examples/olympic.c | 412 + lib/glut-3.7.6/progs/examples/olympic.dsp | 88 + lib/glut-3.7.6/progs/examples/origami.c | 403 + lib/glut-3.7.6/progs/examples/origami.dsp | 88 + lib/glut-3.7.6/progs/examples/oversphere.c | 210 + lib/glut-3.7.6/progs/examples/oversphere.dsp | 88 + lib/glut-3.7.6/progs/examples/reflectdino.c | 405 + lib/glut-3.7.6/progs/examples/reflectdino.dsp | 88 + lib/glut-3.7.6/progs/examples/rendereps.c | 709 + lib/glut-3.7.6/progs/examples/rendereps.dsp | 88 + lib/glut-3.7.6/progs/examples/resolution.c | 264 + lib/glut-3.7.6/progs/examples/resolution.dsp | 88 + lib/glut-3.7.6/progs/examples/sb2db.c | 297 + lib/glut-3.7.6/progs/examples/sb2db.dsp | 88 + lib/glut-3.7.6/progs/examples/scene.c | 175 + lib/glut-3.7.6/progs/examples/scene.dsp | 88 + lib/glut-3.7.6/progs/examples/screendoor.c | 371 + lib/glut-3.7.6/progs/examples/screendoor.dsp | 88 + lib/glut-3.7.6/progs/examples/scube.c | 703 + lib/glut-3.7.6/progs/examples/scube.dsp | 88 + lib/glut-3.7.6/progs/examples/simple.c | 62 + lib/glut-3.7.6/progs/examples/simple.dsp | 88 + lib/glut-3.7.6/progs/examples/sphere.c | 302 + lib/glut-3.7.6/progs/examples/sphere.dsp | 88 + lib/glut-3.7.6/progs/examples/sphere2.c | 62 + lib/glut-3.7.6/progs/examples/sphere2.dsp | 88 + lib/glut-3.7.6/progs/examples/splatlogo.c | 226 + lib/glut-3.7.6/progs/examples/splatlogo.dsp | 92 + lib/glut-3.7.6/progs/examples/spots.c | 350 + lib/glut-3.7.6/progs/examples/spots.dsp | 88 + lib/glut-3.7.6/progs/examples/stars.c | 387 + lib/glut-3.7.6/progs/examples/stars.dsp | 88 + lib/glut-3.7.6/progs/examples/stenciltst.c | 147 + lib/glut-3.7.6/progs/examples/stenciltst.dsp | 88 + lib/glut-3.7.6/progs/examples/stereo.c | 33 + lib/glut-3.7.6/progs/examples/stereo.dsp | 88 + lib/glut-3.7.6/progs/examples/stroke.c | 100 + lib/glut-3.7.6/progs/examples/stroke.dsp | 88 + lib/glut-3.7.6/progs/examples/subwin.c | 88 + lib/glut-3.7.6/progs/examples/subwin.dsp | 88 + lib/glut-3.7.6/progs/examples/surfgrid.c | 588 + lib/glut-3.7.6/progs/examples/surfgrid.dsp | 88 + lib/glut-3.7.6/progs/examples/texenv.c | 753 + lib/glut-3.7.6/progs/examples/texenv.dsp | 88 + lib/glut-3.7.6/progs/examples/trackball.c | 346 + lib/glut-3.7.6/progs/examples/trackball.h | 81 + lib/glut-3.7.6/progs/examples/trippy.c | 471 + lib/glut-3.7.6/progs/examples/trippy.dsp | 88 + lib/glut-3.7.6/progs/examples/triselect.c | 421 + lib/glut-3.7.6/progs/examples/triselect.dsp | 88 + lib/glut-3.7.6/progs/examples/zoomdino.c | 464 + lib/glut-3.7.6/progs/examples/zoomdino.dsp | 88 + lib/glut-3.7.6/progs/fortran/example.f | 114 + lib/glut-3.7.6/progs/fortran/fbitfont.f | 70 + lib/glut-3.7.6/progs/fortran/fscene.f | 126 + lib/glut-3.7.6/progs/fortran/sphere.f | 54 + lib/glut-3.7.6/progs/gameglut.dsw | 29 + lib/glut-3.7.6/progs/gameglut/Imakefile | 14 + lib/glut-3.7.6/progs/gameglut/asteroids.c | 441 + lib/glut-3.7.6/progs/gameglut/asteroids.dsp | 88 + lib/glut-3.7.6/progs/gameglut/asteroids.dsw | 29 + lib/glut-3.7.6/progs/glc/Imakefile | 14 + lib/glut-3.7.6/progs/glc/README | 15 + lib/glut-3.7.6/progs/glc/glcdemo.c | 111 + lib/glut-3.7.6/progs/gle.dsw | 365 + lib/glut-3.7.6/progs/gle/Imakefile | 62 + lib/glut-3.7.6/progs/gle/README | 9 + lib/glut-3.7.6/progs/gle/_all.dsp | 63 + lib/glut-3.7.6/progs/gle/beam.c | 118 + lib/glut-3.7.6/progs/gle/beam.dsp | 89 + lib/glut-3.7.6/progs/gle/candlestick.c | 424 + lib/glut-3.7.6/progs/gle/candlestick.dsp | 89 + lib/glut-3.7.6/progs/gle/cone.c | 103 + lib/glut-3.7.6/progs/gle/cone.dsp | 93 + lib/glut-3.7.6/progs/gle/cylinder.c | 92 + lib/glut-3.7.6/progs/gle/cylinder.dsp | 93 + lib/glut-3.7.6/progs/gle/helix.c | 48 + lib/glut-3.7.6/progs/gle/helix.dsp | 93 + lib/glut-3.7.6/progs/gle/helix2.c | 51 + lib/glut-3.7.6/progs/gle/helix2.dsp | 93 + lib/glut-3.7.6/progs/gle/helix3.c | 50 + lib/glut-3.7.6/progs/gle/helix3.dsp | 93 + lib/glut-3.7.6/progs/gle/helix4.c | 66 + lib/glut-3.7.6/progs/gle/helix4.dsp | 93 + lib/glut-3.7.6/progs/gle/helixtex.c | 48 + lib/glut-3.7.6/progs/gle/helixtex.dsp | 101 + lib/glut-3.7.6/progs/gle/horn.c | 137 + lib/glut-3.7.6/progs/gle/horn.dsp | 93 + lib/glut-3.7.6/progs/gle/joinoffset.c | 145 + lib/glut-3.7.6/progs/gle/joinoffset.dsp | 93 + lib/glut-3.7.6/progs/gle/mainjoin.c | 135 + lib/glut-3.7.6/progs/gle/mainsimple.c | 82 + lib/glut-3.7.6/progs/gle/maintex.c | 257 + lib/glut-3.7.6/progs/gle/martini.c | 250 + lib/glut-3.7.6/progs/gle/martini.dsp | 97 + lib/glut-3.7.6/progs/gle/screw.c | 124 + lib/glut-3.7.6/progs/gle/screw.dsp | 97 + lib/glut-3.7.6/progs/gle/taper.c | 218 + lib/glut-3.7.6/progs/gle/taper.dsp | 93 + lib/glut-3.7.6/progs/gle/texas.c | 228 + lib/glut-3.7.6/progs/gle/texas.dsp | 93 + lib/glut-3.7.6/progs/gle/texture.c | 150 + lib/glut-3.7.6/progs/gle/texture.h | 26 + lib/glut-3.7.6/progs/gle/trackball.c | 346 + lib/glut-3.7.6/progs/gle/trackball.h | 81 + lib/glut-3.7.6/progs/gle/transport.c | 379 + lib/glut-3.7.6/progs/gle/transport.dsp | 89 + lib/glut-3.7.6/progs/gle/twistoid.c | 211 + lib/glut-3.7.6/progs/gle/twistoid.dsp | 93 + lib/glut-3.7.6/progs/gle/twoid.c | 329 + lib/glut-3.7.6/progs/gle/twoid.dsp | 89 + lib/glut-3.7.6/progs/inventor/Imakefile | 22 + lib/glut-3.7.6/progs/inventor/duck.iv | Bin 0 -> 22712 bytes lib/glut-3.7.6/progs/inventor/globe.c++ | 240 + lib/glut-3.7.6/progs/inventor/globe.rgb | Bin 0 -> 109862 bytes lib/glut-3.7.6/progs/inventor/glutduck.c++ | 290 + lib/glut-3.7.6/progs/mesademos.dsw | 194 + lib/glut-3.7.6/progs/mesademos/Imakefile | 26 + lib/glut-3.7.6/progs/mesademos/README | 21 + lib/glut-3.7.6/progs/mesademos/_all.dsp | 63 + lib/glut-3.7.6/progs/mesademos/bounce.c | 204 + lib/glut-3.7.6/progs/mesademos/bounce.dsp | 88 + lib/glut-3.7.6/progs/mesademos/brick.rgb | Bin 0 -> 51607 bytes lib/glut-3.7.6/progs/mesademos/gamma.c | 166 + lib/glut-3.7.6/progs/mesademos/gamma.dsp | 88 + lib/glut-3.7.6/progs/mesademos/gears.c | 330 + lib/glut-3.7.6/progs/mesademos/gears.dsp | 88 + lib/glut-3.7.6/progs/mesademos/image.c | 220 + lib/glut-3.7.6/progs/mesademos/image.h | 20 + lib/glut-3.7.6/progs/mesademos/isosurf.c | 316 + lib/glut-3.7.6/progs/mesademos/isosurf.dat | 7179 +++++++++ lib/glut-3.7.6/progs/mesademos/isosurf.dsp | 88 + lib/glut-3.7.6/progs/mesademos/offset.c | 299 + lib/glut-3.7.6/progs/mesademos/offset.dsp | 88 + lib/glut-3.7.6/progs/mesademos/reflect.c | 379 + lib/glut-3.7.6/progs/mesademos/reflect.dsp | 96 + lib/glut-3.7.6/progs/mesademos/spin.c | 160 + lib/glut-3.7.6/progs/mesademos/spin.dsp | 88 + lib/glut-3.7.6/progs/mesademos/tess_demo.c | 376 + lib/glut-3.7.6/progs/mesademos/tess_demo.dsp | 88 + lib/glut-3.7.6/progs/mesademos/texobj.c | 292 + lib/glut-3.7.6/progs/mesademos/texobj.dsp | 88 + lib/glut-3.7.6/progs/mesademos/tr.c | 236 + lib/glut-3.7.6/progs/mesademos/tr.h | 95 + lib/glut-3.7.6/progs/mesademos/trdemo.c | 167 + lib/glut-3.7.6/progs/mesademos/trdemo.dsp | 96 + lib/glut-3.7.6/progs/mesademos/winpos.c | 215 + lib/glut-3.7.6/progs/mesademos/winpos.dsp | 88 + lib/glut-3.7.6/progs/mui.dsw | 59 + lib/glut-3.7.6/progs/mui/Imakefile | 10 + lib/glut-3.7.6/progs/mui/_all.dsp | 63 + lib/glut-3.7.6/progs/mui/calc/Imakefile | 16 + lib/glut-3.7.6/progs/mui/calc/calc.c | 753 + lib/glut-3.7.6/progs/mui/calc/calc.dsp | 88 + lib/glut-3.7.6/progs/mui/calc/calc.h | 86 + lib/glut-3.7.6/progs/perf_harness.dsw | 29 + lib/glut-3.7.6/progs/perf_harness/Imakefile | 14 + lib/glut-3.7.6/progs/perf_harness/README | 40 + .../progs/perf_harness/gl_harness.c | 154 + .../progs/perf_harness/perf_torus.dsp | 92 + lib/glut-3.7.6/progs/perf_harness/torus.c | 61 + lib/glut-3.7.6/progs/redbook.dsw | 974 ++ lib/glut-3.7.6/progs/redbook/Imakefile | 92 + lib/glut-3.7.6/progs/redbook/_all.dsp | 63 + lib/glut-3.7.6/progs/redbook/aaindex.c | 153 + lib/glut-3.7.6/progs/redbook/aaindex.dsp | 88 + lib/glut-3.7.6/progs/redbook/aapoly.c | 172 + lib/glut-3.7.6/progs/redbook/aapoly.dsp | 88 + lib/glut-3.7.6/progs/redbook/aargb.c | 149 + lib/glut-3.7.6/progs/redbook/aargb.dsp | 88 + lib/glut-3.7.6/progs/redbook/accanti.c | 168 + lib/glut-3.7.6/progs/redbook/accanti.dsp | 88 + lib/glut-3.7.6/progs/redbook/accpersp.c | 240 + lib/glut-3.7.6/progs/redbook/accpersp.dsp | 88 + lib/glut-3.7.6/progs/redbook/alpha.c | 143 + lib/glut-3.7.6/progs/redbook/alpha.dsp | 88 + lib/glut-3.7.6/progs/redbook/alpha3D.c | 175 + lib/glut-3.7.6/progs/redbook/alpha3D.dsp | 88 + lib/glut-3.7.6/progs/redbook/anti.c | 111 + lib/glut-3.7.6/progs/redbook/anti.dsp | 88 + lib/glut-3.7.6/progs/redbook/aux2glut.sed | 55 + lib/glut-3.7.6/progs/redbook/bezcurve.c | 114 + lib/glut-3.7.6/progs/redbook/bezcurve.dsp | 88 + lib/glut-3.7.6/progs/redbook/bezmesh.c | 148 + lib/glut-3.7.6/progs/redbook/bezmesh.dsp | 88 + lib/glut-3.7.6/progs/redbook/checker.c | 125 + lib/glut-3.7.6/progs/redbook/checker.dsp | 88 + lib/glut-3.7.6/progs/redbook/clip.c | 108 + lib/glut-3.7.6/progs/redbook/clip.dsp | 88 + lib/glut-3.7.6/progs/redbook/colormat.c | 153 + lib/glut-3.7.6/progs/redbook/colormat.dsp | 88 + lib/glut-3.7.6/progs/redbook/cube.c | 97 + lib/glut-3.7.6/progs/redbook/cube.dsp | 88 + lib/glut-3.7.6/progs/redbook/depthcue.c | 102 + lib/glut-3.7.6/progs/redbook/depthcue.dsp | 88 + lib/glut-3.7.6/progs/redbook/dof.c | 238 + lib/glut-3.7.6/progs/redbook/dof.dsp | 88 + lib/glut-3.7.6/progs/redbook/double.c | 119 + lib/glut-3.7.6/progs/redbook/double.dsp | 88 + lib/glut-3.7.6/progs/redbook/drawf.c | 103 + lib/glut-3.7.6/progs/redbook/drawf.dsp | 88 + lib/glut-3.7.6/progs/redbook/feedback.c | 171 + lib/glut-3.7.6/progs/redbook/feedback.dsp | 88 + lib/glut-3.7.6/progs/redbook/fog.c | 186 + lib/glut-3.7.6/progs/redbook/fog.dsp | 88 + lib/glut-3.7.6/progs/redbook/fogindex.c | 138 + lib/glut-3.7.6/progs/redbook/fogindex.dsp | 88 + lib/glut-3.7.6/progs/redbook/font.c | 167 + lib/glut-3.7.6/progs/redbook/font.dsp | 88 + lib/glut-3.7.6/progs/redbook/hello.c | 95 + lib/glut-3.7.6/progs/redbook/hello.dsp | 88 + lib/glut-3.7.6/progs/redbook/image.c | 159 + lib/glut-3.7.6/progs/redbook/image.dsp | 88 + lib/glut-3.7.6/progs/redbook/jitter.h | 222 + lib/glut-3.7.6/progs/redbook/light.c | 113 + lib/glut-3.7.6/progs/redbook/light.dsp | 88 + lib/glut-3.7.6/progs/redbook/lines.c | 138 + lib/glut-3.7.6/progs/redbook/lines.dsp | 88 + lib/glut-3.7.6/progs/redbook/list.c | 125 + lib/glut-3.7.6/progs/redbook/list.dsp | 88 + lib/glut-3.7.6/progs/redbook/material.c | 293 + lib/glut-3.7.6/progs/redbook/material.dsp | 88 + lib/glut-3.7.6/progs/redbook/mipmap.c | 165 + lib/glut-3.7.6/progs/redbook/mipmap.dsp | 88 + lib/glut-3.7.6/progs/redbook/model.c | 126 + lib/glut-3.7.6/progs/redbook/model.dsp | 88 + lib/glut-3.7.6/progs/redbook/movelight.c | 148 + lib/glut-3.7.6/progs/redbook/movelight.dsp | 88 + lib/glut-3.7.6/progs/redbook/nurbs.c | 176 + lib/glut-3.7.6/progs/redbook/nurbs.dsp | 88 + lib/glut-3.7.6/progs/redbook/pickdepth.c | 204 + lib/glut-3.7.6/progs/redbook/pickdepth.dsp | 88 + lib/glut-3.7.6/progs/redbook/picksquare.c | 197 + lib/glut-3.7.6/progs/redbook/picksquare.dsp | 88 + lib/glut-3.7.6/progs/redbook/plane.c | 157 + lib/glut-3.7.6/progs/redbook/plane.dsp | 88 + lib/glut-3.7.6/progs/redbook/planet.c | 123 + lib/glut-3.7.6/progs/redbook/planet.dsp | 88 + lib/glut-3.7.6/progs/redbook/polyoff.c | 237 + lib/glut-3.7.6/progs/redbook/polyoff.dsp | 88 + lib/glut-3.7.6/progs/redbook/polys.c | 124 + lib/glut-3.7.6/progs/redbook/polys.dsp | 88 + lib/glut-3.7.6/progs/redbook/quadric.c | 189 + lib/glut-3.7.6/progs/redbook/quadric.dsp | 88 + lib/glut-3.7.6/progs/redbook/robot.c | 132 + lib/glut-3.7.6/progs/redbook/robot.dsp | 88 + lib/glut-3.7.6/progs/redbook/sccolorlight.c | 127 + lib/glut-3.7.6/progs/redbook/sccolorlight.dsp | 88 + lib/glut-3.7.6/progs/redbook/scene.c | 127 + lib/glut-3.7.6/progs/redbook/scene.dsp | 88 + lib/glut-3.7.6/progs/redbook/scenebamb.c | 126 + lib/glut-3.7.6/progs/redbook/scenebamb.dsp | 88 + lib/glut-3.7.6/progs/redbook/sceneflat.c | 126 + lib/glut-3.7.6/progs/redbook/sceneflat.dsp | 88 + lib/glut-3.7.6/progs/redbook/select.c | 222 + lib/glut-3.7.6/progs/redbook/select.dsp | 88 + lib/glut-3.7.6/progs/redbook/smooth.c | 106 + lib/glut-3.7.6/progs/redbook/smooth.dsp | 88 + lib/glut-3.7.6/progs/redbook/stencil.c | 177 + lib/glut-3.7.6/progs/redbook/stencil.dsp | 88 + lib/glut-3.7.6/progs/redbook/stroke.c | 181 + lib/glut-3.7.6/progs/redbook/stroke.dsp | 88 + lib/glut-3.7.6/progs/redbook/surface.c | 217 + lib/glut-3.7.6/progs/redbook/surface.dsp | 88 + lib/glut-3.7.6/progs/redbook/teaambient.c | 148 + lib/glut-3.7.6/progs/redbook/teaambient.dsp | 88 + lib/glut-3.7.6/progs/redbook/teapots.c | 206 + lib/glut-3.7.6/progs/redbook/teapots.dsp | 88 + lib/glut-3.7.6/progs/redbook/tess.c | 241 + lib/glut-3.7.6/progs/redbook/tess.dsp | 88 + lib/glut-3.7.6/progs/redbook/tesswind.c | 290 + lib/glut-3.7.6/progs/redbook/tesswind.dsp | 88 + lib/glut-3.7.6/progs/redbook/texbind.c | 172 + lib/glut-3.7.6/progs/redbook/texbind.dsp | 88 + lib/glut-3.7.6/progs/redbook/texgen.c | 207 + lib/glut-3.7.6/progs/redbook/texgen.dsp | 88 + lib/glut-3.7.6/progs/redbook/texprox.c | 120 + lib/glut-3.7.6/progs/redbook/texprox.dsp | 88 + lib/glut-3.7.6/progs/redbook/texsub.c | 187 + lib/glut-3.7.6/progs/redbook/texsub.dsp | 88 + lib/glut-3.7.6/progs/redbook/texturesurf.c | 141 + lib/glut-3.7.6/progs/redbook/texturesurf.dsp | 88 + lib/glut-3.7.6/progs/redbook/torus.c | 152 + lib/glut-3.7.6/progs/redbook/torus.dsp | 88 + lib/glut-3.7.6/progs/redbook/trim.c | 181 + lib/glut-3.7.6/progs/redbook/trim.dsp | 88 + lib/glut-3.7.6/progs/redbook/unproject.c | 126 + lib/glut-3.7.6/progs/redbook/unproject.dsp | 88 + lib/glut-3.7.6/progs/redbook/varray.c | 195 + lib/glut-3.7.6/progs/redbook/varray.dsp | 88 + lib/glut-3.7.6/progs/redbook/wrap.c | 180 + lib/glut-3.7.6/progs/redbook/wrap.dsp | 88 + lib/glut-3.7.6/progs/sgi-stereo/README | 35 + .../progs/sgi-stereo/fullscreen_stereo.c | 69 + .../progs/sgi-stereo/fullscreen_stereo.h | 22 + .../progs/sgi-stereo/stereo-plane.c | 209 + lib/glut-3.7.6/progs/spheremap.dsw | 137 + lib/glut-3.7.6/progs/spheremap/Imakefile | 10 + lib/glut-3.7.6/progs/spheremap/README | 15 + lib/glut-3.7.6/progs/spheremap/_all.dsp | 63 + .../progs/spheremap/glsmap/Imakefile | 15 + .../progs/spheremap/glsmap/fakeraytrace.c | 722 + .../progs/spheremap/glsmap/fakeraytrace.dsp | 88 + .../progs/spheremap/glsmap/rtsmap.c | 480 + .../progs/spheremap/glsmap/rtsmap.dsp | 88 + .../progs/spheremap/hacks/Imakefile | 16 + .../progs/spheremap/hacks/cview2smap.c | 336 + .../progs/spheremap/hacks/cview2smap.dsp | 96 + .../progs/spheremap/hacks/drawmesh.c | 55 + .../progs/spheremap/hacks/makemesh.c | 292 + .../progs/spheremap/hacks/sixviews.c | 291 + .../progs/spheremap/hacks/sixviews.dsp | 88 + .../progs/spheremap/hacks/smapmesh.c | 515 + .../progs/spheremap/hacks/smapmesh.dsp | 88 + .../progs/spheremap/hacks/smapmesh.h | 38 + .../progs/spheremap/hacks/st2rvec.c | 85 + .../progs/spheremap/hacks/st2rvec.dsp | 88 + lib/glut-3.7.6/progs/texfont.dsw | 86 + lib/glut-3.7.6/progs/texfont/Imakefile | 17 + lib/glut-3.7.6/progs/texfont/README | 35 + lib/glut-3.7.6/progs/texfont/TexFont.h | 93 + lib/glut-3.7.6/progs/texfont/_all.dsp | 63 + lib/glut-3.7.6/progs/texfont/abgr.dsp | 88 + lib/glut-3.7.6/progs/texfont/curlfont.txf | Bin 0 -> 8980 bytes lib/glut-3.7.6/progs/texfont/default.txf | Bin 0 -> 9196 bytes lib/glut-3.7.6/progs/texfont/djb.txf | Bin 0 -> 9292 bytes lib/glut-3.7.6/progs/texfont/gentexfont.c | 560 + lib/glut-3.7.6/progs/texfont/gentexfont.dsp | 88 + lib/glut-3.7.6/progs/texfont/haeberli.txf | Bin 0 -> 8980 bytes lib/glut-3.7.6/progs/texfont/rockfont.txf | Bin 0 -> 8416 bytes lib/glut-3.7.6/progs/texfont/showtxf.c | 156 + lib/glut-3.7.6/progs/texfont/showtxf.dsp | 92 + lib/glut-3.7.6/progs/texfont/simpletxf.c | 183 + lib/glut-3.7.6/progs/texfont/simpletxf.dsp | 92 + lib/glut-3.7.6/progs/texfont/sorority.txf | Bin 0 -> 9316 bytes lib/glut-3.7.6/progs/texfont/texfont.c | 645 + lib/glut-3.7.6/progs/texfont/txfdemo.c | 436 + lib/glut-3.7.6/progs/texfont/txfdemo.dsp | 92 + lib/glut-3.7.6/progs/tiff/Imakefile | 26 + lib/glut-3.7.6/progs/tiff/README | 49 + lib/glut-3.7.6/progs/tiff/depthdof.c | 561 + lib/glut-3.7.6/progs/tiff/face.tif | Bin 0 -> 21032 bytes lib/glut-3.7.6/progs/tiff/scalebias.c | 482 + lib/glut-3.7.6/progs/tiff/showtiff.c | 369 + lib/glut-3.7.6/progs/tiff/spiral.tif | Bin 0 -> 49356 bytes lib/glut-3.7.6/progs/tiff/textiff.c | 206 + lib/glut-3.7.6/progs/tiff/tiffsift.c | 307 + lib/glut-3.7.6/progs/tiff/writetiff.c | 330 + lib/glut-3.7.6/test/Imakefile | 12 + lib/glut-3.7.6/test/glut/Imakefile | 98 + lib/glut-3.7.6/test/glut/_all.dsp | 63 + lib/glut-3.7.6/test/glut/atexit_test.c | 41 + lib/glut-3.7.6/test/glut/bigtest.c | 2597 +++ lib/glut-3.7.6/test/glut/bigtest.dsp | 90 + lib/glut-3.7.6/test/glut/cursor_test.c | 193 + lib/glut-3.7.6/test/glut/cursor_test.dsp | 90 + lib/glut-3.7.6/test/glut/joy_test.c | 72 + lib/glut-3.7.6/test/glut/joy_test.dsp | 90 + lib/glut-3.7.6/test/glut/keyup_test.c | 104 + lib/glut-3.7.6/test/glut/keyup_test.dsp | 90 + lib/glut-3.7.6/test/glut/menu_test.c | 165 + lib/glut-3.7.6/test/glut/menu_test.dsp | 90 + lib/glut-3.7.6/test/glut/over_test.c | 388 + lib/glut-3.7.6/test/glut/over_test.dsp | 90 + lib/glut-3.7.6/test/glut/shape_test.c | 194 + lib/glut-3.7.6/test/glut/shape_test.dsp | 90 + lib/glut-3.7.6/test/glut/test1.c | 91 + lib/glut-3.7.6/test/glut/test1.dsp | 90 + lib/glut-3.7.6/test/glut/test10.c | 127 + lib/glut-3.7.6/test/glut/test10.dsp | 90 + lib/glut-3.7.6/test/glut/test11.c | 28 + lib/glut-3.7.6/test/glut/test11.dsp | 90 + lib/glut-3.7.6/test/glut/test12.c | 177 + lib/glut-3.7.6/test/glut/test12.dsp | 90 + lib/glut-3.7.6/test/glut/test13.c | 129 + lib/glut-3.7.6/test/glut/test13.dsp | 90 + lib/glut-3.7.6/test/glut/test14.c | 151 + lib/glut-3.7.6/test/glut/test14.dsp | 90 + lib/glut-3.7.6/test/glut/test15.c | 83 + lib/glut-3.7.6/test/glut/test15.dsp | 90 + lib/glut-3.7.6/test/glut/test16.c | 136 + lib/glut-3.7.6/test/glut/test16.dsp | 90 + lib/glut-3.7.6/test/glut/test17.c | 289 + lib/glut-3.7.6/test/glut/test17.dsp | 90 + lib/glut-3.7.6/test/glut/test18.c | 210 + lib/glut-3.7.6/test/glut/test18.dsp | 90 + lib/glut-3.7.6/test/glut/test19.c | 67 + lib/glut-3.7.6/test/glut/test19.dsp | 90 + lib/glut-3.7.6/test/glut/test2.c | 177 + lib/glut-3.7.6/test/glut/test2.dsp | 90 + lib/glut-3.7.6/test/glut/test20.c | 139 + lib/glut-3.7.6/test/glut/test20.dsp | 90 + lib/glut-3.7.6/test/glut/test21.c | 189 + lib/glut-3.7.6/test/glut/test21.dsp | 90 + lib/glut-3.7.6/test/glut/test22.c | 209 + lib/glut-3.7.6/test/glut/test22.dsp | 90 + lib/glut-3.7.6/test/glut/test23.c | 138 + lib/glut-3.7.6/test/glut/test23.dsp | 90 + lib/glut-3.7.6/test/glut/test24.c | 146 + lib/glut-3.7.6/test/glut/test24.dsp | 90 + lib/glut-3.7.6/test/glut/test25.c | 162 + lib/glut-3.7.6/test/glut/test25.dsp | 90 + lib/glut-3.7.6/test/glut/test26.c | 145 + lib/glut-3.7.6/test/glut/test26.dsp | 90 + lib/glut-3.7.6/test/glut/test27.c | 105 + lib/glut-3.7.6/test/glut/test27.dsp | 90 + lib/glut-3.7.6/test/glut/test28.c | 56 + lib/glut-3.7.6/test/glut/test28.dsp | 90 + lib/glut-3.7.6/test/glut/test29.c | 162 + lib/glut-3.7.6/test/glut/test3.c | 92 + lib/glut-3.7.6/test/glut/test3.dsp | 90 + lib/glut-3.7.6/test/glut/test4.c | 60 + lib/glut-3.7.6/test/glut/test4.dsp | 90 + lib/glut-3.7.6/test/glut/test5.c | 133 + lib/glut-3.7.6/test/glut/test5.dsp | 90 + lib/glut-3.7.6/test/glut/test6.c | 539 + lib/glut-3.7.6/test/glut/test6.dsp | 90 + lib/glut-3.7.6/test/glut/test7.c | 199 + lib/glut-3.7.6/test/glut/test7.dsp | 90 + lib/glut-3.7.6/test/glut/test8.c | 164 + lib/glut-3.7.6/test/glut/test8.dsp | 90 + lib/glut-3.7.6/test/glut/test9.c | 145 + lib/glut-3.7.6/test/glut/test9.dsp | 90 + lib/glut-3.7.6/test/glut/tests.dsp | 86 + lib/glut-3.7.6/test/glut/timer_test.c | 68 + lib/glut-3.7.6/test/glut/timer_test.dsp | 90 + lib/glut-3.7.6/test/mui/Imakefile | 17 + lib/glut-3.7.6/test/mui/mui_test.c | 161 + lib/glut-3.7.6/test/mui/mui_test.dsp | 90 + lib/glut-3.7.6/test/mui/multi_test.c | 85 + lib/glut-3.7.6/test/mui/multi_test.dsp | 90 + lib/glut-3.7.6/test/test.dsw | 839 + qgroundcontrol.pri | 2 +- qgroundcontrol.pro | 3 +- src/ui/map3D/QGCGlut.h | 602 + src/ui/map3D/QMap3DWidget.cc | 13 +- 1405 files changed, 297410 insertions(+), 8 deletions(-) create mode 100644 lib/glut-3.7.6/CHANGES create mode 100644 lib/glut-3.7.6/FAQ.glut create mode 100644 lib/glut-3.7.6/Glut.cf create mode 100644 lib/glut-3.7.6/IAFA-PACKAGE create mode 100644 lib/glut-3.7.6/Imakefile create mode 100644 lib/glut-3.7.6/NOTICE create mode 100644 lib/glut-3.7.6/Portability.txt create mode 100644 lib/glut-3.7.6/README create mode 100644 lib/glut-3.7.6/README-win32.txt create mode 100644 lib/glut-3.7.6/README.ada create mode 100644 lib/glut-3.7.6/README.fortran create mode 100644 lib/glut-3.7.6/README.glut2 create mode 100644 lib/glut-3.7.6/README.glut3 create mode 100644 lib/glut-3.7.6/README.ibm-shlib create mode 100644 lib/glut-3.7.6/README.inventor create mode 100644 lib/glut-3.7.6/README.irix6 create mode 100644 lib/glut-3.7.6/README.irix64bit create mode 100644 lib/glut-3.7.6/README.linux create mode 100644 lib/glut-3.7.6/README.man create mode 100644 lib/glut-3.7.6/README.mesa create mode 100644 lib/glut-3.7.6/README.mui create mode 100644 lib/glut-3.7.6/README.xinput create mode 100644 lib/glut-3.7.6/adainclude/GL/glut.adb create mode 100644 lib/glut-3.7.6/adainclude/GL/glut.ads create mode 100644 lib/glut-3.7.6/glut-3.7.6.pro create mode 100644 lib/glut-3.7.6/glut.dsw create mode 100644 lib/glut-3.7.6/glutdefs create mode 100644 lib/glut-3.7.6/include/GL/fgl.h create mode 100644 lib/glut-3.7.6/include/GL/fglu.h create mode 100644 lib/glut-3.7.6/include/GL/fglut.h create mode 100644 lib/glut-3.7.6/include/GL/glsmap.h create mode 100644 lib/glut-3.7.6/include/GL/glut.h create mode 100644 lib/glut-3.7.6/include/GL/glutf90.h create mode 100644 lib/glut-3.7.6/include/GL/tube.h create mode 100644 lib/glut-3.7.6/include/mui/browser.h create mode 100644 lib/glut-3.7.6/include/mui/displaylist.h create mode 100644 lib/glut-3.7.6/include/mui/gizmo.h create mode 100644 lib/glut-3.7.6/include/mui/hslider.h create mode 100644 lib/glut-3.7.6/include/mui/mui.h create mode 100644 lib/glut-3.7.6/include/mui/textlist.h create mode 100644 lib/glut-3.7.6/include/mui/uicolor.h create mode 100644 lib/glut-3.7.6/include/mui/vslider.h create mode 100644 lib/glut-3.7.6/lib/Imakefile create mode 100644 lib/glut-3.7.6/lib/_all.dsp create mode 100644 lib/glut-3.7.6/lib/dll.dsw create mode 100644 lib/glut-3.7.6/lib/fglut.n32/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/fglut.n64/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/fglut/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/fglut/fglut.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_8x13.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_9x15.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_hel10.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_hel12.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_hel18.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_mroman.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_roman.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_tr10.c create mode 100644 lib/glut-3.7.6/lib/fglut/fglut_tr24.c create mode 100644 lib/glut-3.7.6/lib/gle.n32/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/gle.n64/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/gle/Imakefile create mode 100644 lib/glut-3.7.6/lib/gle/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/gle/copy.h create mode 100644 lib/glut-3.7.6/lib/gle/ex_angle.c create mode 100644 lib/glut-3.7.6/lib/gle/ex_cut_round.c create mode 100644 lib/glut-3.7.6/lib/gle/ex_raw.c create mode 100644 lib/glut-3.7.6/lib/gle/extrude.c create mode 100644 lib/glut-3.7.6/lib/gle/extrude.h create mode 100644 lib/glut-3.7.6/lib/gle/gle.dsp create mode 100644 lib/glut-3.7.6/lib/gle/gle_dll.dsp create mode 100644 lib/glut-3.7.6/lib/gle/gutil.h create mode 100644 lib/glut-3.7.6/lib/gle/intersect.c create mode 100644 lib/glut-3.7.6/lib/gle/intersect.h create mode 100644 lib/glut-3.7.6/lib/gle/port.h create mode 100644 lib/glut-3.7.6/lib/gle/qmesh.c create mode 100644 lib/glut-3.7.6/lib/gle/rot.h create mode 100644 lib/glut-3.7.6/lib/gle/rot_prince.c create mode 100644 lib/glut-3.7.6/lib/gle/rotate.c create mode 100644 lib/glut-3.7.6/lib/gle/round_cap.c create mode 100644 lib/glut-3.7.6/lib/gle/segment.c create mode 100644 lib/glut-3.7.6/lib/gle/segment.h create mode 100644 lib/glut-3.7.6/lib/gle/texgen.c create mode 100644 lib/glut-3.7.6/lib/gle/tube_gc.h create mode 100644 lib/glut-3.7.6/lib/gle/urotate.c create mode 100644 lib/glut-3.7.6/lib/gle/view.c create mode 100644 lib/glut-3.7.6/lib/gle/vvector.h create mode 100644 lib/glut-3.7.6/lib/glsmap.n32/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glsmap.n64/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glsmap/Imakefile create mode 100644 lib/glut-3.7.6/lib/glsmap/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glsmap/glsmap.dsp create mode 100644 lib/glut-3.7.6/lib/glsmap/glsmapint.h create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_buildsmap.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_context.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_create.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_destroy.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_drawmesh.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_flag.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_get.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_getfunc.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_gettexdim.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_gettexobj.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_getvec.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_makemesh.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_nearfar.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_origin.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_render.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_rvec2st.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_set.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_setfunc.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_setvec.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_texdim.c create mode 100644 lib/glut-3.7.6/lib/glsmap/smap_texobj.c create mode 100644 lib/glut-3.7.6/lib/glut.n32/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glut.n64/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glut/Imakefile create mode 100644 lib/glut-3.7.6/lib/glut/MonoRoman.stroke create mode 100644 lib/glut-3.7.6/lib/glut/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/glut/Roman.stroke create mode 100644 lib/glut-3.7.6/lib/glut/capturexfont.c create mode 100644 lib/glut-3.7.6/lib/glut/glut.def create mode 100644 lib/glut-3.7.6/lib/glut/glut.ico create mode 100644 lib/glut-3.7.6/lib/glut/glut.rc create mode 100644 lib/glut-3.7.6/lib/glut/glut32.dsp create mode 100644 lib/glut-3.7.6/lib/glut/glut_8x13.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_9x15.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_bitmap.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_bwidth.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_cindex.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_cmap.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_cursor.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_dials.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_dstr.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_event.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_ext.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_fcb.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_fullscrn.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_gamemode.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_get.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_glxext.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_hel10.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_hel12.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_hel18.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_init.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_input.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_joy.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_key.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_keyctrl.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_keyup.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_menu.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_menu2.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_mesa.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_modifier.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_mroman.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_overlay.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_roman.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_shapes.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_space.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_stroke.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_swap.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_swidth.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_tablet.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_teapot.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_tr10.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_tr24.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_util.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_vidresize.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_warp.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_win.c create mode 100644 lib/glut-3.7.6/lib/glut/glut_winmisc.c create mode 100644 lib/glut-3.7.6/lib/glut/glutbitmap.h create mode 100644 lib/glut-3.7.6/lib/glut/glutint.h create mode 100644 lib/glut-3.7.6/lib/glut/glutstroke.h create mode 100644 lib/glut-3.7.6/lib/glut/glutwin32.h create mode 100644 lib/glut-3.7.6/lib/glut/layerutil.c create mode 100644 lib/glut-3.7.6/lib/glut/layerutil.h create mode 100644 lib/glut-3.7.6/lib/glut/mesa.patch2 create mode 100644 lib/glut-3.7.6/lib/glut/stroke.h create mode 100644 lib/glut-3.7.6/lib/glut/strokegen.y create mode 100644 lib/glut-3.7.6/lib/glut/strokelex.l create mode 100644 lib/glut-3.7.6/lib/glut/win32_glx.c create mode 100644 lib/glut-3.7.6/lib/glut/win32_glx.h create mode 100644 lib/glut-3.7.6/lib/glut/win32_menu.c create mode 100644 lib/glut-3.7.6/lib/glut/win32_util.c create mode 100644 lib/glut-3.7.6/lib/glut/win32_winproc.c create mode 100644 lib/glut-3.7.6/lib/glut/win32_x11.c create mode 100644 lib/glut-3.7.6/lib/glut/win32_x11.h create mode 100644 lib/glut-3.7.6/lib/lib.dsw create mode 100644 lib/glut-3.7.6/lib/mui.n32/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/mui.n64/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/mui/Imakefile create mode 100644 lib/glut-3.7.6/lib/mui/ObjectType.mk create mode 100644 lib/glut-3.7.6/lib/mui/browseparse.c create mode 100644 lib/glut-3.7.6/lib/mui/browser.c create mode 100644 lib/glut-3.7.6/lib/mui/button.c create mode 100644 lib/glut-3.7.6/lib/mui/dirent32.h create mode 100644 lib/glut-3.7.6/lib/mui/displaylist.c create mode 100644 lib/glut-3.7.6/lib/mui/gizmo.c create mode 100644 lib/glut-3.7.6/lib/mui/glutmui.c create mode 100644 lib/glut-3.7.6/lib/mui/hslider.c create mode 100644 lib/glut-3.7.6/lib/mui/miscui.c create mode 100644 lib/glut-3.7.6/lib/mui/mui.c create mode 100644 lib/glut-3.7.6/lib/mui/mui.dsp create mode 100644 lib/glut-3.7.6/lib/mui/pulldown.c create mode 100644 lib/glut-3.7.6/lib/mui/textlist.c create mode 100644 lib/glut-3.7.6/lib/mui/uicolor.c create mode 100644 lib/glut-3.7.6/lib/mui/vslider.c create mode 100644 lib/glut-3.7.6/man/Imakefile create mode 100644 lib/glut-3.7.6/man/gle/Imakefile create mode 100644 lib/glut-3.7.6/man/gle/gle.man create mode 100644 lib/glut-3.7.6/man/gle/gleExtrusion.man create mode 100644 lib/glut-3.7.6/man/gle/gleHelicoid.man create mode 100644 lib/glut-3.7.6/man/gle/gleLathe.man create mode 100644 lib/glut-3.7.6/man/gle/glePolyCone.man create mode 100644 lib/glut-3.7.6/man/gle/glePolyCylinder.man create mode 100644 lib/glut-3.7.6/man/gle/gleScrew.man create mode 100644 lib/glut-3.7.6/man/gle/gleSetJoinStyle.man create mode 100644 lib/glut-3.7.6/man/gle/gleSpiral.man create mode 100644 lib/glut-3.7.6/man/gle/gleSuperExtrusion.man create mode 100644 lib/glut-3.7.6/man/gle/gleTextureMode.man create mode 100644 lib/glut-3.7.6/man/gle/gleToroid.man create mode 100644 lib/glut-3.7.6/man/gle/gleTwistExtrusion.man create mode 100644 lib/glut-3.7.6/man/glut/Imakefile create mode 100644 lib/glut-3.7.6/man/glut/glut.man create mode 100644 lib/glut-3.7.6/man/glut/glutAddMenuEntry.man create mode 100644 lib/glut-3.7.6/man/glut/glutAddSubMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutAttachMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutBitmapCharacter.man create mode 100644 lib/glut-3.7.6/man/glut/glutBitmapWidth.man create mode 100644 lib/glut-3.7.6/man/glut/glutButtonBoxFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutChangeToMenuEntry.man create mode 100644 lib/glut-3.7.6/man/glut/glutChangeToSubMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutCopyColormap.man create mode 100644 lib/glut-3.7.6/man/glut/glutCreateMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutCreateSubWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutCreateWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutDestroyMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutDestroyWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutDeviceGet.man create mode 100644 lib/glut-3.7.6/man/glut/glutDialsFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutDisplayFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutEnterGameMode.man create mode 100644 lib/glut-3.7.6/man/glut/glutEntryFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutEstablishOverlay.man create mode 100644 lib/glut-3.7.6/man/glut/glutExtensionSupported.man create mode 100644 lib/glut-3.7.6/man/glut/glutForceJoystickFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutFullScreen.man create mode 100644 lib/glut-3.7.6/man/glut/glutGameModeGet.man create mode 100644 lib/glut-3.7.6/man/glut/glutGameModeString.man create mode 100644 lib/glut-3.7.6/man/glut/glutGet.man create mode 100644 lib/glut-3.7.6/man/glut/glutGetColor.man create mode 100644 lib/glut-3.7.6/man/glut/glutGetModifiers.man create mode 100644 lib/glut-3.7.6/man/glut/glutIdleFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutIgnoreKeyRepeat.man create mode 100644 lib/glut-3.7.6/man/glut/glutInit.man create mode 100644 lib/glut-3.7.6/man/glut/glutInitDisplayMode.man create mode 100644 lib/glut-3.7.6/man/glut/glutInitDisplayString.man create mode 100644 lib/glut-3.7.6/man/glut/glutInitWindowPosition.man create mode 100644 lib/glut-3.7.6/man/glut/glutJoystickFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutKeyboardFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutKeyboardUpFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutLayerGet.man create mode 100644 lib/glut-3.7.6/man/glut/glutMainLoop.man create mode 100644 lib/glut-3.7.6/man/glut/glutMenuStatusFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutMotionFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutMouseFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutOverlayDisplayFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutPopWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutPositionWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutPostOverlayRedisplay.man create mode 100644 lib/glut-3.7.6/man/glut/glutPostRedisplay.man create mode 100644 lib/glut-3.7.6/man/glut/glutRemoveMenuItem.man create mode 100644 lib/glut-3.7.6/man/glut/glutRemoveOverlay.man create mode 100644 lib/glut-3.7.6/man/glut/glutReportErrors.man create mode 100644 lib/glut-3.7.6/man/glut/glutReshapeFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutReshapeWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetColor.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetCursor.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetKeyRepeat.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetMenu.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutSetWindowTitle.man create mode 100644 lib/glut-3.7.6/man/glut/glutShowOverlay.man create mode 100644 lib/glut-3.7.6/man/glut/glutShowWindow.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidCone.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidCube.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidDodecahedron.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidIcosahedron.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidOctahedron.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidSphere.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidTeapot.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidTetrahedron.man create mode 100644 lib/glut-3.7.6/man/glut/glutSolidTorus.man create mode 100644 lib/glut-3.7.6/man/glut/glutSpaceballButtonFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutSpaceballMotionFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutSpaceballRotateFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutSpecialFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutSpecialUpFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutStrokeCharacter.man create mode 100644 lib/glut-3.7.6/man/glut/glutStrokeWidth.man create mode 100644 lib/glut-3.7.6/man/glut/glutSwapBuffers.man create mode 100644 lib/glut-3.7.6/man/glut/glutTabletButtonFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutTabletMotionFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutTimerFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutUseLayer.man create mode 100644 lib/glut-3.7.6/man/glut/glutVisibilityFunc.man create mode 100644 lib/glut-3.7.6/man/glut/glutWarpPointer.man create mode 100644 lib/glut-3.7.6/mkmkfiles.imake create mode 100644 lib/glut-3.7.6/mkmkfiles.sgi create mode 100644 lib/glut-3.7.6/progs/Imakefile create mode 100644 lib/glut-3.7.6/progs/ada/README create mode 100644 lib/glut-3.7.6/progs/ada/ada_sphere.adb create mode 100644 lib/glut-3.7.6/progs/ada/ada_sphere_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/ada_sphere_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/bezmesh.adb create mode 100644 lib/glut-3.7.6/progs/ada/bezmesh_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/bezmesh_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/cone.adb create mode 100644 lib/glut-3.7.6/progs/ada/cone_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/cone_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/dof.adb create mode 100644 lib/glut-3.7.6/progs/ada/dof_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/dof_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/fog.adb create mode 100644 lib/glut-3.7.6/progs/ada/fog_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/fog_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/jitter.ads create mode 100644 lib/glut-3.7.6/progs/ada/pickdepth.adb create mode 100644 lib/glut-3.7.6/progs/ada/pickdepth_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/pickdepth_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/scenebamb.adb create mode 100644 lib/glut-3.7.6/progs/ada/scenebamb_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/scenebamb_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/teapots.adb create mode 100644 lib/glut-3.7.6/progs/ada/teapots_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/teapots_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/texgen.adb create mode 100644 lib/glut-3.7.6/progs/ada/texgen_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/texgen_procs.ads create mode 100644 lib/glut-3.7.6/progs/ada/texturesurf.adb create mode 100644 lib/glut-3.7.6/progs/ada/texturesurf_procs.adb create mode 100644 lib/glut-3.7.6/progs/ada/texturesurf_procs.ads create mode 100644 lib/glut-3.7.6/progs/advanced.dsw create mode 100644 lib/glut-3.7.6/progs/advanced/Imakefile create mode 100644 lib/glut-3.7.6/progs/advanced/README create mode 100644 lib/glut-3.7.6/progs/advanced/Times-Italic.bw create mode 100644 lib/glut-3.7.6/progs/advanced/_all.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/accumaa.c create mode 100644 lib/glut-3.7.6/progs/advanced/accumaa.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/addfog.c create mode 100644 lib/glut-3.7.6/progs/advanced/addfog.h create mode 100644 lib/glut-3.7.6/progs/advanced/af_depthcue.c create mode 100644 lib/glut-3.7.6/progs/advanced/af_depthcue.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/af_teapots.c create mode 100644 lib/glut-3.7.6/progs/advanced/af_teapots.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/boundary.c create mode 100644 lib/glut-3.7.6/progs/advanced/boundary.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/comp.c create mode 100644 lib/glut-3.7.6/progs/advanced/comp.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/convolve.c create mode 100644 lib/glut-3.7.6/progs/advanced/convolve.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/csg.c create mode 100644 lib/glut-3.7.6/progs/advanced/csg.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/decal.c create mode 100644 lib/glut-3.7.6/progs/advanced/decal.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/dissolve.c create mode 100644 lib/glut-3.7.6/progs/advanced/dissolve.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/envmap.c create mode 100644 lib/glut-3.7.6/progs/advanced/envmap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/envphong.c create mode 100644 lib/glut-3.7.6/progs/advanced/envphong.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/field.c create mode 100644 lib/glut-3.7.6/progs/advanced/field.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/genmipmap.c create mode 100644 lib/glut-3.7.6/progs/advanced/genmipmap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/haloed.c create mode 100644 lib/glut-3.7.6/progs/advanced/haloed.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/hello2rts.c create mode 100644 lib/glut-3.7.6/progs/advanced/hello2rts.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/hiddenline.c create mode 100644 lib/glut-3.7.6/progs/advanced/hiddenline.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/imgproc.c create mode 100644 lib/glut-3.7.6/progs/advanced/imgproc.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/izoom.c create mode 100644 lib/glut-3.7.6/progs/advanced/izoom.h create mode 100644 lib/glut-3.7.6/progs/advanced/logopoints.h create mode 100644 lib/glut-3.7.6/progs/advanced/mipmap_lines.c create mode 100644 lib/glut-3.7.6/progs/advanced/mipmap_lines.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/motionblur.c create mode 100644 lib/glut-3.7.6/progs/advanced/motionblur.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/multilight.c create mode 100644 lib/glut-3.7.6/progs/advanced/multilight.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/nvidia_logo.c create mode 100644 lib/glut-3.7.6/progs/advanced/occlude.c create mode 100644 lib/glut-3.7.6/progs/advanced/occlude.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/pointburst.c create mode 100644 lib/glut-3.7.6/progs/advanced/pointburst.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/projshadow.c create mode 100644 lib/glut-3.7.6/progs/advanced/projshadow.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/projtex.c create mode 100644 lib/glut-3.7.6/progs/advanced/projtex.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/rasonly.c create mode 100644 lib/glut-3.7.6/progs/advanced/rasonly.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/redblue_stereo.c create mode 100644 lib/glut-3.7.6/progs/advanced/redblue_stereo.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/rts.c create mode 100644 lib/glut-3.7.6/progs/advanced/rtshadow.h create mode 100644 lib/glut-3.7.6/progs/advanced/sgiflag.c create mode 100644 lib/glut-3.7.6/progs/advanced/sgiflag.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/sgiflag.h create mode 100644 lib/glut-3.7.6/progs/advanced/shadowfun.c create mode 100644 lib/glut-3.7.6/progs/advanced/shadowfun.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/shadowmap.c create mode 100644 lib/glut-3.7.6/progs/advanced/shadowmap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/shadowvol.c create mode 100644 lib/glut-3.7.6/progs/advanced/shadowvol.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/silhouette.c create mode 100644 lib/glut-3.7.6/progs/advanced/silhouette.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/softshadow.c create mode 100644 lib/glut-3.7.6/progs/advanced/softshadow.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/sphere.c create mode 100644 lib/glut-3.7.6/progs/advanced/tess.c create mode 100644 lib/glut-3.7.6/progs/advanced/tess.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/textext.c create mode 100644 lib/glut-3.7.6/progs/advanced/textext.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/textile.c create mode 100644 lib/glut-3.7.6/progs/advanced/textile.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/textmap.c create mode 100644 lib/glut-3.7.6/progs/advanced/textmap.h create mode 100644 lib/glut-3.7.6/progs/advanced/textrim.c create mode 100644 lib/glut-3.7.6/progs/advanced/textrim.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/texture.c create mode 100644 lib/glut-3.7.6/progs/advanced/texture.h create mode 100644 lib/glut-3.7.6/progs/advanced/texwinalign.c create mode 100644 lib/glut-3.7.6/progs/advanced/texwinalign.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/tvertex.c create mode 100644 lib/glut-3.7.6/progs/advanced/tvertex.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/videoresize.c create mode 100644 lib/glut-3.7.6/progs/advanced/videoresize.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/vox.c create mode 100644 lib/glut-3.7.6/progs/advanced/vox.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/warp.c create mode 100644 lib/glut-3.7.6/progs/advanced/warp.dsp create mode 100644 lib/glut-3.7.6/progs/advanced/zcomposite.c create mode 100644 lib/glut-3.7.6/progs/advanced/zcomposite.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97.dsw create mode 100644 lib/glut-3.7.6/progs/advanced97/Imakefile create mode 100644 lib/glut-3.7.6/progs/advanced97/_all.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/accconvolve.c create mode 100644 lib/glut-3.7.6/progs/advanced97/accconvolve.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/accumaa.c create mode 100644 lib/glut-3.7.6/progs/advanced97/accumaa.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/alphablend.c create mode 100644 lib/glut-3.7.6/progs/advanced97/alphablend.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/alphablendnosort.c create mode 100644 lib/glut-3.7.6/progs/advanced97/alphablendnosort.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/billboard.c create mode 100644 lib/glut-3.7.6/progs/advanced97/billboard.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/bubble.c create mode 100644 lib/glut-3.7.6/progs/advanced97/bubble.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/bump.c create mode 100644 lib/glut-3.7.6/progs/advanced97/bump.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/chromakey.c create mode 100644 lib/glut-3.7.6/progs/advanced97/chromakey.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/chromakey_fancy.c create mode 100644 lib/glut-3.7.6/progs/advanced97/chromakey_fancy.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/cloud.c create mode 100644 lib/glut-3.7.6/progs/advanced97/cloud.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/cloudl.c create mode 100644 lib/glut-3.7.6/progs/advanced97/cloudl.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/complexity.c create mode 100644 lib/glut-3.7.6/progs/advanced97/complexity.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/csg.c create mode 100644 lib/glut-3.7.6/progs/advanced97/csg.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/d.c create mode 100644 lib/glut-3.7.6/progs/advanced97/decal.c create mode 100644 lib/glut-3.7.6/progs/advanced97/decal.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/dissolve.c create mode 100644 lib/glut-3.7.6/progs/advanced97/dissolve.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/explode.c create mode 100644 lib/glut-3.7.6/progs/advanced97/explode.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/fire.c create mode 100644 lib/glut-3.7.6/progs/advanced97/fire.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/genspheremap.c create mode 100644 lib/glut-3.7.6/progs/advanced97/genspheremap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/highlight.c create mode 100644 lib/glut-3.7.6/progs/advanced97/highlight.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/interp.c create mode 100644 lib/glut-3.7.6/progs/advanced97/interp.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/lightmap.c create mode 100644 lib/glut-3.7.6/progs/advanced97/lightmap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/lightp.c create mode 100644 lib/glut-3.7.6/progs/advanced97/lightp.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/line.c create mode 100644 lib/glut-3.7.6/progs/advanced97/line.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multiaccumaa.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multiaccumaa.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multialphablend.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multialphablend.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multialphablendnosort.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multialphablendnosort.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multimirror.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multimirror.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multiscreendoor.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multiscreendoor.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/multispheremap.c create mode 100644 lib/glut-3.7.6/progs/advanced97/multispheremap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/noise.c create mode 100644 lib/glut-3.7.6/progs/advanced97/noise.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/nthsurfdemo.c create mode 100644 lib/glut-3.7.6/progs/advanced97/nthsurfdemo.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/paint.c create mode 100644 lib/glut-3.7.6/progs/advanced97/paint.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/projtex.c create mode 100644 lib/glut-3.7.6/progs/advanced97/projtex.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/sbias.c create mode 100644 lib/glut-3.7.6/progs/advanced97/sbias.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/screendoor.c create mode 100644 lib/glut-3.7.6/progs/advanced97/screendoor.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/sm.c create mode 100644 lib/glut-3.7.6/progs/advanced97/sm.h create mode 100644 lib/glut-3.7.6/progs/advanced97/smoke.c create mode 100644 lib/glut-3.7.6/progs/advanced97/smoke.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/softshadow2.c create mode 100644 lib/glut-3.7.6/progs/advanced97/softshadow2.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/spectral.c create mode 100644 lib/glut-3.7.6/progs/advanced97/spectral.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/sphere.c create mode 100644 lib/glut-3.7.6/progs/advanced97/tess.c create mode 100644 lib/glut-3.7.6/progs/advanced97/tess.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/texgen.c create mode 100644 lib/glut-3.7.6/progs/advanced97/texgen.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/texmovie.c create mode 100644 lib/glut-3.7.6/progs/advanced97/texmovie.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/texpage.c create mode 100644 lib/glut-3.7.6/progs/advanced97/texpage.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/textile.c create mode 100644 lib/glut-3.7.6/progs/advanced97/textile.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/texture.c create mode 100644 lib/glut-3.7.6/progs/advanced97/texture.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/texture.h create mode 100644 lib/glut-3.7.6/progs/advanced97/underwater.c create mode 100644 lib/glut-3.7.6/progs/advanced97/underwater.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/usespheremap.c create mode 100644 lib/glut-3.7.6/progs/advanced97/usespheremap.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/vapor.c create mode 100644 lib/glut-3.7.6/progs/advanced97/vapor.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/volume.c create mode 100644 lib/glut-3.7.6/progs/advanced97/volume.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/warp.c create mode 100644 lib/glut-3.7.6/progs/advanced97/warp.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/water.c create mode 100644 lib/glut-3.7.6/progs/advanced97/water.dsp create mode 100644 lib/glut-3.7.6/progs/advanced97/zcomposite.c create mode 100644 lib/glut-3.7.6/progs/advanced97/zcomposite.dsp create mode 100644 lib/glut-3.7.6/progs/aux2glut.sed create mode 100644 lib/glut-3.7.6/progs/bucciarelli.dsw create mode 100644 lib/glut-3.7.6/progs/bucciarelli/Imakefile create mode 100644 lib/glut-3.7.6/progs/bucciarelli/README create mode 100644 lib/glut-3.7.6/progs/bucciarelli/_all.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/bw.rgb create mode 100644 lib/glut-3.7.6/progs/bucciarelli/dteapot.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/fire.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/fire.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/glbpaltex.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/glbpaltx.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/gltest.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/gltest.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/image.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/image.h create mode 100644 lib/glut-3.7.6/progs/bucciarelli/mnt.bin create mode 100644 lib/glut-3.7.6/progs/bucciarelli/paltex.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/paltex.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/ray.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/ray.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/s128.rgb create mode 100644 lib/glut-3.7.6/progs/bucciarelli/shadow.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/sources.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/teapot.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/teapot.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/terrain.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/terrain.dsp create mode 100644 lib/glut-3.7.6/progs/bucciarelli/tile.rgb create mode 100644 lib/glut-3.7.6/progs/bucciarelli/tree2.rgb create mode 100644 lib/glut-3.7.6/progs/bucciarelli/tunnel.c create mode 100644 lib/glut-3.7.6/progs/bucciarelli/tunnel.dsp create mode 100644 lib/glut-3.7.6/progs/contrib.dsw create mode 100644 lib/glut-3.7.6/progs/contrib/Imakefile create mode 100644 lib/glut-3.7.6/progs/contrib/_all.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/agv_example.c create mode 100644 lib/glut-3.7.6/progs/contrib/agv_viewer.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/agviewer.c create mode 100644 lib/glut-3.7.6/progs/contrib/agviewer.h create mode 100644 lib/glut-3.7.6/progs/contrib/engine.c create mode 100644 lib/glut-3.7.6/progs/contrib/fractals.c create mode 100644 lib/glut-3.7.6/progs/contrib/fractals.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/fracviewer.c create mode 100644 lib/glut-3.7.6/progs/contrib/fracviewer.h create mode 100644 lib/glut-3.7.6/progs/contrib/gears.c create mode 100644 lib/glut-3.7.6/progs/contrib/gears.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/hanoi.c create mode 100644 lib/glut-3.7.6/progs/contrib/hanoi.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/hanoi2.c create mode 100644 lib/glut-3.7.6/progs/contrib/hanoi2.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/lineblend.c create mode 100644 lib/glut-3.7.6/progs/contrib/lineblend.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/moth.c create mode 100644 lib/glut-3.7.6/progs/contrib/moth.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/noof.c create mode 100644 lib/glut-3.7.6/progs/contrib/noof.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/rings.c create mode 100644 lib/glut-3.7.6/progs/contrib/rings.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/steam.c create mode 100644 lib/glut-3.7.6/progs/contrib/steam.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/text3d.c create mode 100644 lib/glut-3.7.6/progs/contrib/text3d.dsp create mode 100644 lib/glut-3.7.6/progs/contrib/worms.c create mode 100644 lib/glut-3.7.6/progs/contrib/worms.dsp create mode 100644 lib/glut-3.7.6/progs/data/00.rgb create mode 100644 lib/glut-3.7.6/progs/data/01.rgb create mode 100644 lib/glut-3.7.6/progs/data/02.rgb create mode 100644 lib/glut-3.7.6/progs/data/03.rgb create mode 100644 lib/glut-3.7.6/progs/data/04.rgb create mode 100644 lib/glut-3.7.6/progs/data/05.rgb create mode 100644 lib/glut-3.7.6/progs/data/brick.rgb create mode 100644 lib/glut-3.7.6/progs/data/brush.rgb create mode 100644 lib/glut-3.7.6/progs/data/clouds.bw create mode 100644 lib/glut-3.7.6/progs/data/explosion.rgba create mode 100644 lib/glut-3.7.6/progs/data/f15.data create mode 100644 lib/glut-3.7.6/progs/data/fendi.rgb create mode 100644 lib/glut-3.7.6/progs/data/flame/f00 create mode 100644 lib/glut-3.7.6/progs/data/flame/f01 create mode 100644 lib/glut-3.7.6/progs/data/flame/f02 create mode 100644 lib/glut-3.7.6/progs/data/flame/f03 create mode 100644 lib/glut-3.7.6/progs/data/flame/f04 create mode 100644 lib/glut-3.7.6/progs/data/flame/f05 create mode 100644 lib/glut-3.7.6/progs/data/flame/f06 create mode 100644 lib/glut-3.7.6/progs/data/flame/f07 create mode 100644 lib/glut-3.7.6/progs/data/flame/f08 create mode 100644 lib/glut-3.7.6/progs/data/flame/f09 create mode 100644 lib/glut-3.7.6/progs/data/flame/f10 create mode 100644 lib/glut-3.7.6/progs/data/flame/f11 create mode 100644 lib/glut-3.7.6/progs/data/flame/f12 create mode 100644 lib/glut-3.7.6/progs/data/flame/f13 create mode 100644 lib/glut-3.7.6/progs/data/flame/f14 create mode 100644 lib/glut-3.7.6/progs/data/flame/f15 create mode 100644 lib/glut-3.7.6/progs/data/flame/f16 create mode 100644 lib/glut-3.7.6/progs/data/flame/f17 create mode 100644 lib/glut-3.7.6/progs/data/flame/f18 create mode 100644 lib/glut-3.7.6/progs/data/flame/f19 create mode 100644 lib/glut-3.7.6/progs/data/flame/f20 create mode 100644 lib/glut-3.7.6/progs/data/flame/f21 create mode 100644 lib/glut-3.7.6/progs/data/flame/f22 create mode 100644 lib/glut-3.7.6/progs/data/flame/f23 create mode 100644 lib/glut-3.7.6/progs/data/flame/f24 create mode 100644 lib/glut-3.7.6/progs/data/flame/f25 create mode 100644 lib/glut-3.7.6/progs/data/flame/f26 create mode 100644 lib/glut-3.7.6/progs/data/flame/f27 create mode 100644 lib/glut-3.7.6/progs/data/flame/f28 create mode 100644 lib/glut-3.7.6/progs/data/flame/f29 create mode 100644 lib/glut-3.7.6/progs/data/flame/f30 create mode 100644 lib/glut-3.7.6/progs/data/flame/f31 create mode 100644 lib/glut-3.7.6/progs/data/light.bw create mode 100644 lib/glut-3.7.6/progs/data/mandrill.rgb create mode 100644 lib/glut-3.7.6/progs/data/sea.rgb create mode 100644 lib/glut-3.7.6/progs/data/sgi.bw create mode 100644 lib/glut-3.7.6/progs/data/smoke.bw create mode 100644 lib/glut-3.7.6/progs/data/spheremap.rgb create mode 100644 lib/glut-3.7.6/progs/data/swamp.rgb create mode 100644 lib/glut-3.7.6/progs/data/water.bw create mode 100644 lib/glut-3.7.6/progs/data/wood.rgb create mode 100644 lib/glut-3.7.6/progs/demos.dsw create mode 100644 lib/glut-3.7.6/progs/demos/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/_all.dsp create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/atlantis.c create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/atlantis.dsp create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/atlantis.h create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/dolphin.c create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/shark.c create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/swim.c create mode 100644 lib/glut-3.7.6/progs/demos/atlantis/whale.c create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/bluepony.c create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/bluepony.dsp create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/logo.bw create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/readtex.c create mode 100644 lib/glut-3.7.6/progs/demos/bluepony/readtex.h create mode 100644 lib/glut-3.7.6/progs/demos/bounce/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/bounce/bounce.c create mode 100644 lib/glut-3.7.6/progs/demos/bounce/bounce.dsp create mode 100644 lib/glut-3.7.6/progs/demos/bounce/glui.c create mode 100644 lib/glut-3.7.6/progs/demos/bounce/glui.h create mode 100644 lib/glut-3.7.6/progs/demos/bounce/tb.c create mode 100644 lib/glut-3.7.6/progs/demos/bounce/tb.h create mode 100644 lib/glut-3.7.6/progs/demos/bounce/trackball.c create mode 100644 lib/glut-3.7.6/progs/demos/bounce/trackball.h create mode 100644 lib/glut-3.7.6/progs/demos/chess/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/chess/animate.c create mode 100644 lib/glut-3.7.6/progs/demos/chess/chess.c create mode 100644 lib/glut-3.7.6/progs/demos/chess/chess.dsp create mode 100644 lib/glut-3.7.6/progs/demos/chess/chess.h create mode 100644 lib/glut-3.7.6/progs/demos/chess/chess.inp create mode 100644 lib/glut-3.7.6/progs/demos/chess/main.c create mode 100644 lib/glut-3.7.6/progs/demos/chess/pathplan.c create mode 100644 lib/glut-3.7.6/progs/demos/chess/texture.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/geoface/README create mode 100644 lib/glut-3.7.6/progs/demos/geoface/display.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/faceline.dat create mode 100644 lib/glut-3.7.6/progs/demos/geoface/fileio.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/geoface.dsp create mode 100644 lib/glut-3.7.6/progs/demos/geoface/head.h create mode 100644 lib/glut-3.7.6/progs/demos/geoface/index.dat create mode 100644 lib/glut-3.7.6/progs/demos/geoface/main.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/make_face.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/memory.h create mode 100644 lib/glut-3.7.6/progs/demos/geoface/muscle.c create mode 100644 lib/glut-3.7.6/progs/demos/geoface/muscle.dat create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare1.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare2.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare3.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare4.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare5.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Flare6.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/glflare/OpenGL.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine0.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine1.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine2.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine3.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine4.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine5.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine6.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine7.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine8.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/Shine9.bw create mode 100644 lib/glut-3.7.6/progs/demos/glflare/glflare.c create mode 100644 lib/glut-3.7.6/progs/demos/glflare/glflare.dsp create mode 100644 lib/glut-3.7.6/progs/demos/glflare/loadlum.c create mode 100644 lib/glut-3.7.6/progs/demos/glflare/loadlum.h create mode 100644 lib/glut-3.7.6/progs/demos/glflare/vec3d.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/gliq/board.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/boards.txt create mode 100644 lib/glut-3.7.6/progs/demos/gliq/game.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/gliq.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/gliq.dsp create mode 100644 lib/glut-3.7.6/progs/demos/gliq/gliq.h create mode 100644 lib/glut-3.7.6/progs/demos/gliq/pick.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/score.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/tb.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/tb.h create mode 100644 lib/glut-3.7.6/progs/demos/gliq/trackball.c create mode 100644 lib/glut-3.7.6/progs/demos/gliq/trackball.h create mode 100644 lib/glut-3.7.6/progs/demos/glutmech/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/glutmech/glutmech.c create mode 100644 lib/glut-3.7.6/progs/demos/glutmech/glutmech.dsp create mode 100644 lib/glut-3.7.6/progs/demos/ideas/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/ideas/a.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/b.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/d.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/draw_holder.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/draw_lamp.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/draw_logo.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/draw_logo_line.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/draw_logo_shadow.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/e.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/f.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/h.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/i.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/ideas.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/ideas.dsp create mode 100644 lib/glut-3.7.6/progs/demos/ideas/m.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/n.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/o.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/objects.h create mode 100644 lib/glut-3.7.6/progs/demos/ideas/p.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/r.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/s.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/t.c create mode 100644 lib/glut-3.7.6/progs/demos/ideas/w.c create mode 100644 lib/glut-3.7.6/progs/demos/lorenz/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/lorenz/lorenz.c create mode 100644 lib/glut-3.7.6/progs/demos/lorenz/lorenz.dsp create mode 100644 lib/glut-3.7.6/progs/demos/newave/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/newave/newave.c create mode 100644 lib/glut-3.7.6/progs/demos/newave/newave.dsp create mode 100644 lib/glut-3.7.6/progs/demos/newave/spheremap.rgb create mode 100644 lib/glut-3.7.6/progs/demos/newave/texmap.rgb create mode 100644 lib/glut-3.7.6/progs/demos/newave/texture.c create mode 100644 lib/glut-3.7.6/progs/demos/newave/texture.h create mode 100644 lib/glut-3.7.6/progs/demos/opengl_logo/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/opengl_logo/def_logo.c create mode 100644 lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.c create mode 100644 lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.dsp create mode 100644 lib/glut-3.7.6/progs/demos/particle/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/particle/particle.c create mode 100644 lib/glut-3.7.6/progs/demos/particle/particle.dsp create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/defrc.c create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/matrix.c create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/matrix.h create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/rc.c create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/rc.def create mode 100644 lib/glut-3.7.6/progs/demos/rollercoaster/rollercoaster.dsp create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/clouds.bw create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/database.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/fly.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/gm_main.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/image.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/perfdraw.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/random.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/skyfly.c create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/skyfly.dsp create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/skyfly.h create mode 100644 lib/glut-3.7.6/progs/demos/skyfly/terrain.bw create mode 100644 lib/glut-3.7.6/progs/demos/smooth/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/smooth/data/dolphins.mtl create mode 100644 lib/glut-3.7.6/progs/demos/smooth/data/dolphins.obj create mode 100644 lib/glut-3.7.6/progs/demos/smooth/dirent32.h create mode 100644 lib/glut-3.7.6/progs/demos/smooth/glm.c create mode 100644 lib/glut-3.7.6/progs/demos/smooth/glm.h create mode 100644 lib/glut-3.7.6/progs/demos/smooth/gltb.c create mode 100644 lib/glut-3.7.6/progs/demos/smooth/gltb.h create mode 100644 lib/glut-3.7.6/progs/demos/smooth/gltx.c create mode 100644 lib/glut-3.7.6/progs/demos/smooth/gltx.h create mode 100644 lib/glut-3.7.6/progs/demos/smooth/smooth.c create mode 100644 lib/glut-3.7.6/progs/demos/smooth/smooth.dsp create mode 100644 lib/glut-3.7.6/progs/demos/smooth/trackball.c create mode 100644 lib/glut-3.7.6/progs/demos/smooth/trackball.h create mode 100644 lib/glut-3.7.6/progs/demos/sunlight/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/sunlight/globe.raw create mode 100644 lib/glut-3.7.6/progs/demos/sunlight/sunlight.c create mode 100644 lib/glut-3.7.6/progs/demos/sunlight/sunlight.dsp create mode 100644 lib/glut-3.7.6/progs/demos/sysview/README create mode 100644 lib/glut-3.7.6/progs/demos/sysview/sysview.c create mode 100644 lib/glut-3.7.6/progs/demos/sysview/sysview.dsp create mode 100644 lib/glut-3.7.6/progs/demos/underwater/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust00.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust01.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust02.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust03.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust04.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust05.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust06.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust07.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust08.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust09.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust10.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust11.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust12.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust13.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust14.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust15.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust16.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust17.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust18.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust19.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust20.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust21.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust22.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust23.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust24.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust25.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust26.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust27.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust28.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust29.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust30.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/caust31.bw create mode 100644 lib/glut-3.7.6/progs/demos/underwater/dino.c create mode 100644 lib/glut-3.7.6/progs/demos/underwater/dino.h create mode 100644 lib/glut-3.7.6/progs/demos/underwater/floor.rgb create mode 100644 lib/glut-3.7.6/progs/demos/underwater/texload.c create mode 100644 lib/glut-3.7.6/progs/demos/underwater/texload.h create mode 100644 lib/glut-3.7.6/progs/demos/underwater/underwater.c create mode 100644 lib/glut-3.7.6/progs/demos/underwater/underwater.dsp create mode 100644 lib/glut-3.7.6/progs/demos/walker/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/walker/Impossible.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/MrFlex.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/Ouch.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/README create mode 100644 lib/glut-3.7.6/progs/demos/walker/bound.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/dunk.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/kick.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/models.c create mode 100644 lib/glut-3.7.6/progs/demos/walker/moonwalk.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/reverse_dunk.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/running.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/walk_backwards.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/walker.c create mode 100644 lib/glut-3.7.6/progs/demos/walker/walker.dsp create mode 100644 lib/glut-3.7.6/progs/demos/walker/walker.h create mode 100644 lib/glut-3.7.6/progs/demos/walker/walking.cset create mode 100644 lib/glut-3.7.6/progs/demos/walker/walkviewer.c create mode 100644 lib/glut-3.7.6/progs/demos/walker/walkviewer.h create mode 100644 lib/glut-3.7.6/progs/demos/walker/win32_dirent.h create mode 100644 lib/glut-3.7.6/progs/demos/yacme/Editor.c create mode 100644 lib/glut-3.7.6/progs/demos/yacme/Imakefile create mode 100644 lib/glut-3.7.6/progs/demos/yacme/RGBA.h create mode 100644 lib/glut-3.7.6/progs/demos/yacme/invertmat.c create mode 100644 lib/glut-3.7.6/progs/demos/yacme/mallocbis.h create mode 100644 lib/glut-3.7.6/progs/demos/yacme/yacme.dsp create mode 100644 lib/glut-3.7.6/progs/examples.dsw create mode 100644 lib/glut-3.7.6/progs/examples/Imakefile create mode 100644 lib/glut-3.7.6/progs/examples/_all.dsp create mode 100644 lib/glut-3.7.6/progs/examples/abgr.c create mode 100644 lib/glut-3.7.6/progs/examples/abgr.dsp create mode 100644 lib/glut-3.7.6/progs/examples/bitfont.c create mode 100644 lib/glut-3.7.6/progs/examples/bitfont.dsp create mode 100644 lib/glut-3.7.6/progs/examples/blender.c create mode 100644 lib/glut-3.7.6/progs/examples/blender.dsp create mode 100644 lib/glut-3.7.6/progs/examples/circlefit.c create mode 100644 lib/glut-3.7.6/progs/examples/circlefit.dsp create mode 100644 lib/glut-3.7.6/progs/examples/cube.c create mode 100644 lib/glut-3.7.6/progs/examples/cube.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dials.c create mode 100644 lib/glut-3.7.6/progs/examples/dials.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dials2.c create mode 100644 lib/glut-3.7.6/progs/examples/dials2.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dinoball.c create mode 100644 lib/glut-3.7.6/progs/examples/dinoball.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dinodraw.c create mode 100644 lib/glut-3.7.6/progs/examples/dinodraw.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dinoshade.c create mode 100644 lib/glut-3.7.6/progs/examples/dinoshade.dsp create mode 100644 lib/glut-3.7.6/progs/examples/dinospin.c create mode 100644 lib/glut-3.7.6/progs/examples/dinospin.dsp create mode 100644 lib/glut-3.7.6/progs/examples/editgrid.c create mode 100644 lib/glut-3.7.6/progs/examples/editgrid.dsp create mode 100644 lib/glut-3.7.6/progs/examples/evaltest.c create mode 100644 lib/glut-3.7.6/progs/examples/evaltest.dsp create mode 100644 lib/glut-3.7.6/progs/examples/fogtst.c create mode 100644 lib/glut-3.7.6/progs/examples/fogtst.dsp create mode 100644 lib/glut-3.7.6/progs/examples/fontdemo.c create mode 100644 lib/glut-3.7.6/progs/examples/fontdemo.dsp create mode 100644 lib/glut-3.7.6/progs/examples/glpuzzle.c create mode 100644 lib/glut-3.7.6/progs/examples/glpuzzle.dsp create mode 100644 lib/glut-3.7.6/progs/examples/glutdino.c create mode 100644 lib/glut-3.7.6/progs/examples/glutdino.dsp create mode 100644 lib/glut-3.7.6/progs/examples/glutplane.c create mode 100644 lib/glut-3.7.6/progs/examples/glutplane.dsp create mode 100644 lib/glut-3.7.6/progs/examples/gouraudtriangle.ps create mode 100644 lib/glut-3.7.6/progs/examples/halomagic.c create mode 100644 lib/glut-3.7.6/progs/examples/halomagic.dsp create mode 100644 lib/glut-3.7.6/progs/examples/highlight.c create mode 100644 lib/glut-3.7.6/progs/examples/highlight.dsp create mode 100644 lib/glut-3.7.6/progs/examples/lightlab.c create mode 100644 lib/glut-3.7.6/progs/examples/lightlab.dsp create mode 100644 lib/glut-3.7.6/progs/examples/logo.c create mode 100644 lib/glut-3.7.6/progs/examples/luminance16.c create mode 100644 lib/glut-3.7.6/progs/examples/luminance16.dsp create mode 100644 lib/glut-3.7.6/progs/examples/mjkimage.c create mode 100644 lib/glut-3.7.6/progs/examples/mjksift.c create mode 100644 lib/glut-3.7.6/progs/examples/mjksift.dsp create mode 100644 lib/glut-3.7.6/progs/examples/mjkwarp.c create mode 100644 lib/glut-3.7.6/progs/examples/mjkwarp.dsp create mode 100644 lib/glut-3.7.6/progs/examples/molehill.c create mode 100644 lib/glut-3.7.6/progs/examples/molehill.dsp create mode 100644 lib/glut-3.7.6/progs/examples/movelight.c create mode 100644 lib/glut-3.7.6/progs/examples/movelight.dsp create mode 100644 lib/glut-3.7.6/progs/examples/oclip.c create mode 100644 lib/glut-3.7.6/progs/examples/oclip.dsp create mode 100644 lib/glut-3.7.6/progs/examples/ohidden.c create mode 100644 lib/glut-3.7.6/progs/examples/ohidden.dsp create mode 100644 lib/glut-3.7.6/progs/examples/olight.c create mode 100644 lib/glut-3.7.6/progs/examples/olight.dsp create mode 100644 lib/glut-3.7.6/progs/examples/olympic.c create mode 100644 lib/glut-3.7.6/progs/examples/olympic.dsp create mode 100644 lib/glut-3.7.6/progs/examples/origami.c create mode 100644 lib/glut-3.7.6/progs/examples/origami.dsp create mode 100644 lib/glut-3.7.6/progs/examples/oversphere.c create mode 100644 lib/glut-3.7.6/progs/examples/oversphere.dsp create mode 100644 lib/glut-3.7.6/progs/examples/reflectdino.c create mode 100644 lib/glut-3.7.6/progs/examples/reflectdino.dsp create mode 100644 lib/glut-3.7.6/progs/examples/rendereps.c create mode 100644 lib/glut-3.7.6/progs/examples/rendereps.dsp create mode 100644 lib/glut-3.7.6/progs/examples/resolution.c create mode 100644 lib/glut-3.7.6/progs/examples/resolution.dsp create mode 100644 lib/glut-3.7.6/progs/examples/sb2db.c create mode 100644 lib/glut-3.7.6/progs/examples/sb2db.dsp create mode 100644 lib/glut-3.7.6/progs/examples/scene.c create mode 100644 lib/glut-3.7.6/progs/examples/scene.dsp create mode 100644 lib/glut-3.7.6/progs/examples/screendoor.c create mode 100644 lib/glut-3.7.6/progs/examples/screendoor.dsp create mode 100644 lib/glut-3.7.6/progs/examples/scube.c create mode 100644 lib/glut-3.7.6/progs/examples/scube.dsp create mode 100644 lib/glut-3.7.6/progs/examples/simple.c create mode 100644 lib/glut-3.7.6/progs/examples/simple.dsp create mode 100644 lib/glut-3.7.6/progs/examples/sphere.c create mode 100644 lib/glut-3.7.6/progs/examples/sphere.dsp create mode 100644 lib/glut-3.7.6/progs/examples/sphere2.c create mode 100644 lib/glut-3.7.6/progs/examples/sphere2.dsp create mode 100644 lib/glut-3.7.6/progs/examples/splatlogo.c create mode 100644 lib/glut-3.7.6/progs/examples/splatlogo.dsp create mode 100644 lib/glut-3.7.6/progs/examples/spots.c create mode 100644 lib/glut-3.7.6/progs/examples/spots.dsp create mode 100644 lib/glut-3.7.6/progs/examples/stars.c create mode 100644 lib/glut-3.7.6/progs/examples/stars.dsp create mode 100644 lib/glut-3.7.6/progs/examples/stenciltst.c create mode 100644 lib/glut-3.7.6/progs/examples/stenciltst.dsp create mode 100644 lib/glut-3.7.6/progs/examples/stereo.c create mode 100644 lib/glut-3.7.6/progs/examples/stereo.dsp create mode 100644 lib/glut-3.7.6/progs/examples/stroke.c create mode 100644 lib/glut-3.7.6/progs/examples/stroke.dsp create mode 100644 lib/glut-3.7.6/progs/examples/subwin.c create mode 100644 lib/glut-3.7.6/progs/examples/subwin.dsp create mode 100644 lib/glut-3.7.6/progs/examples/surfgrid.c create mode 100644 lib/glut-3.7.6/progs/examples/surfgrid.dsp create mode 100644 lib/glut-3.7.6/progs/examples/texenv.c create mode 100644 lib/glut-3.7.6/progs/examples/texenv.dsp create mode 100644 lib/glut-3.7.6/progs/examples/trackball.c create mode 100644 lib/glut-3.7.6/progs/examples/trackball.h create mode 100644 lib/glut-3.7.6/progs/examples/trippy.c create mode 100644 lib/glut-3.7.6/progs/examples/trippy.dsp create mode 100644 lib/glut-3.7.6/progs/examples/triselect.c create mode 100644 lib/glut-3.7.6/progs/examples/triselect.dsp create mode 100644 lib/glut-3.7.6/progs/examples/zoomdino.c create mode 100644 lib/glut-3.7.6/progs/examples/zoomdino.dsp create mode 100644 lib/glut-3.7.6/progs/fortran/example.f create mode 100644 lib/glut-3.7.6/progs/fortran/fbitfont.f create mode 100644 lib/glut-3.7.6/progs/fortran/fscene.f create mode 100644 lib/glut-3.7.6/progs/fortran/sphere.f create mode 100644 lib/glut-3.7.6/progs/gameglut.dsw create mode 100644 lib/glut-3.7.6/progs/gameglut/Imakefile create mode 100644 lib/glut-3.7.6/progs/gameglut/asteroids.c create mode 100644 lib/glut-3.7.6/progs/gameglut/asteroids.dsp create mode 100644 lib/glut-3.7.6/progs/gameglut/asteroids.dsw create mode 100644 lib/glut-3.7.6/progs/glc/Imakefile create mode 100644 lib/glut-3.7.6/progs/glc/README create mode 100644 lib/glut-3.7.6/progs/glc/glcdemo.c create mode 100644 lib/glut-3.7.6/progs/gle.dsw create mode 100644 lib/glut-3.7.6/progs/gle/Imakefile create mode 100644 lib/glut-3.7.6/progs/gle/README create mode 100644 lib/glut-3.7.6/progs/gle/_all.dsp create mode 100644 lib/glut-3.7.6/progs/gle/beam.c create mode 100644 lib/glut-3.7.6/progs/gle/beam.dsp create mode 100644 lib/glut-3.7.6/progs/gle/candlestick.c create mode 100644 lib/glut-3.7.6/progs/gle/candlestick.dsp create mode 100644 lib/glut-3.7.6/progs/gle/cone.c create mode 100644 lib/glut-3.7.6/progs/gle/cone.dsp create mode 100644 lib/glut-3.7.6/progs/gle/cylinder.c create mode 100644 lib/glut-3.7.6/progs/gle/cylinder.dsp create mode 100644 lib/glut-3.7.6/progs/gle/helix.c create mode 100644 lib/glut-3.7.6/progs/gle/helix.dsp create mode 100644 lib/glut-3.7.6/progs/gle/helix2.c create mode 100644 lib/glut-3.7.6/progs/gle/helix2.dsp create mode 100644 lib/glut-3.7.6/progs/gle/helix3.c create mode 100644 lib/glut-3.7.6/progs/gle/helix3.dsp create mode 100644 lib/glut-3.7.6/progs/gle/helix4.c create mode 100644 lib/glut-3.7.6/progs/gle/helix4.dsp create mode 100644 lib/glut-3.7.6/progs/gle/helixtex.c create mode 100644 lib/glut-3.7.6/progs/gle/helixtex.dsp create mode 100644 lib/glut-3.7.6/progs/gle/horn.c create mode 100644 lib/glut-3.7.6/progs/gle/horn.dsp create mode 100644 lib/glut-3.7.6/progs/gle/joinoffset.c create mode 100644 lib/glut-3.7.6/progs/gle/joinoffset.dsp create mode 100644 lib/glut-3.7.6/progs/gle/mainjoin.c create mode 100644 lib/glut-3.7.6/progs/gle/mainsimple.c create mode 100644 lib/glut-3.7.6/progs/gle/maintex.c create mode 100644 lib/glut-3.7.6/progs/gle/martini.c create mode 100644 lib/glut-3.7.6/progs/gle/martini.dsp create mode 100644 lib/glut-3.7.6/progs/gle/screw.c create mode 100644 lib/glut-3.7.6/progs/gle/screw.dsp create mode 100644 lib/glut-3.7.6/progs/gle/taper.c create mode 100644 lib/glut-3.7.6/progs/gle/taper.dsp create mode 100644 lib/glut-3.7.6/progs/gle/texas.c create mode 100644 lib/glut-3.7.6/progs/gle/texas.dsp create mode 100644 lib/glut-3.7.6/progs/gle/texture.c create mode 100644 lib/glut-3.7.6/progs/gle/texture.h create mode 100644 lib/glut-3.7.6/progs/gle/trackball.c create mode 100644 lib/glut-3.7.6/progs/gle/trackball.h create mode 100644 lib/glut-3.7.6/progs/gle/transport.c create mode 100644 lib/glut-3.7.6/progs/gle/transport.dsp create mode 100644 lib/glut-3.7.6/progs/gle/twistoid.c create mode 100644 lib/glut-3.7.6/progs/gle/twistoid.dsp create mode 100644 lib/glut-3.7.6/progs/gle/twoid.c create mode 100644 lib/glut-3.7.6/progs/gle/twoid.dsp create mode 100644 lib/glut-3.7.6/progs/inventor/Imakefile create mode 100644 lib/glut-3.7.6/progs/inventor/duck.iv create mode 100644 lib/glut-3.7.6/progs/inventor/globe.c++ create mode 100644 lib/glut-3.7.6/progs/inventor/globe.rgb create mode 100644 lib/glut-3.7.6/progs/inventor/glutduck.c++ create mode 100644 lib/glut-3.7.6/progs/mesademos.dsw create mode 100644 lib/glut-3.7.6/progs/mesademos/Imakefile create mode 100644 lib/glut-3.7.6/progs/mesademos/README create mode 100644 lib/glut-3.7.6/progs/mesademos/_all.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/bounce.c create mode 100644 lib/glut-3.7.6/progs/mesademos/bounce.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/brick.rgb create mode 100644 lib/glut-3.7.6/progs/mesademos/gamma.c create mode 100644 lib/glut-3.7.6/progs/mesademos/gamma.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/gears.c create mode 100644 lib/glut-3.7.6/progs/mesademos/gears.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/image.c create mode 100644 lib/glut-3.7.6/progs/mesademos/image.h create mode 100644 lib/glut-3.7.6/progs/mesademos/isosurf.c create mode 100644 lib/glut-3.7.6/progs/mesademos/isosurf.dat create mode 100644 lib/glut-3.7.6/progs/mesademos/isosurf.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/offset.c create mode 100644 lib/glut-3.7.6/progs/mesademos/offset.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/reflect.c create mode 100644 lib/glut-3.7.6/progs/mesademos/reflect.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/spin.c create mode 100644 lib/glut-3.7.6/progs/mesademos/spin.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/tess_demo.c create mode 100644 lib/glut-3.7.6/progs/mesademos/tess_demo.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/texobj.c create mode 100644 lib/glut-3.7.6/progs/mesademos/texobj.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/tr.c create mode 100644 lib/glut-3.7.6/progs/mesademos/tr.h create mode 100644 lib/glut-3.7.6/progs/mesademos/trdemo.c create mode 100644 lib/glut-3.7.6/progs/mesademos/trdemo.dsp create mode 100644 lib/glut-3.7.6/progs/mesademos/winpos.c create mode 100644 lib/glut-3.7.6/progs/mesademos/winpos.dsp create mode 100644 lib/glut-3.7.6/progs/mui.dsw create mode 100644 lib/glut-3.7.6/progs/mui/Imakefile create mode 100644 lib/glut-3.7.6/progs/mui/_all.dsp create mode 100644 lib/glut-3.7.6/progs/mui/calc/Imakefile create mode 100644 lib/glut-3.7.6/progs/mui/calc/calc.c create mode 100644 lib/glut-3.7.6/progs/mui/calc/calc.dsp create mode 100644 lib/glut-3.7.6/progs/mui/calc/calc.h create mode 100644 lib/glut-3.7.6/progs/perf_harness.dsw create mode 100644 lib/glut-3.7.6/progs/perf_harness/Imakefile create mode 100644 lib/glut-3.7.6/progs/perf_harness/README create mode 100644 lib/glut-3.7.6/progs/perf_harness/gl_harness.c create mode 100644 lib/glut-3.7.6/progs/perf_harness/perf_torus.dsp create mode 100644 lib/glut-3.7.6/progs/perf_harness/torus.c create mode 100644 lib/glut-3.7.6/progs/redbook.dsw create mode 100644 lib/glut-3.7.6/progs/redbook/Imakefile create mode 100644 lib/glut-3.7.6/progs/redbook/_all.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/aaindex.c create mode 100644 lib/glut-3.7.6/progs/redbook/aaindex.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/aapoly.c create mode 100644 lib/glut-3.7.6/progs/redbook/aapoly.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/aargb.c create mode 100644 lib/glut-3.7.6/progs/redbook/aargb.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/accanti.c create mode 100644 lib/glut-3.7.6/progs/redbook/accanti.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/accpersp.c create mode 100644 lib/glut-3.7.6/progs/redbook/accpersp.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/alpha.c create mode 100644 lib/glut-3.7.6/progs/redbook/alpha.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/alpha3D.c create mode 100644 lib/glut-3.7.6/progs/redbook/alpha3D.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/anti.c create mode 100644 lib/glut-3.7.6/progs/redbook/anti.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/aux2glut.sed create mode 100644 lib/glut-3.7.6/progs/redbook/bezcurve.c create mode 100644 lib/glut-3.7.6/progs/redbook/bezcurve.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/bezmesh.c create mode 100644 lib/glut-3.7.6/progs/redbook/bezmesh.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/checker.c create mode 100644 lib/glut-3.7.6/progs/redbook/checker.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/clip.c create mode 100644 lib/glut-3.7.6/progs/redbook/clip.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/colormat.c create mode 100644 lib/glut-3.7.6/progs/redbook/colormat.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/cube.c create mode 100644 lib/glut-3.7.6/progs/redbook/cube.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/depthcue.c create mode 100644 lib/glut-3.7.6/progs/redbook/depthcue.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/dof.c create mode 100644 lib/glut-3.7.6/progs/redbook/dof.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/double.c create mode 100644 lib/glut-3.7.6/progs/redbook/double.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/drawf.c create mode 100644 lib/glut-3.7.6/progs/redbook/drawf.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/feedback.c create mode 100644 lib/glut-3.7.6/progs/redbook/feedback.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/fog.c create mode 100644 lib/glut-3.7.6/progs/redbook/fog.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/fogindex.c create mode 100644 lib/glut-3.7.6/progs/redbook/fogindex.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/font.c create mode 100644 lib/glut-3.7.6/progs/redbook/font.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/hello.c create mode 100644 lib/glut-3.7.6/progs/redbook/hello.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/image.c create mode 100644 lib/glut-3.7.6/progs/redbook/image.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/jitter.h create mode 100644 lib/glut-3.7.6/progs/redbook/light.c create mode 100644 lib/glut-3.7.6/progs/redbook/light.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/lines.c create mode 100644 lib/glut-3.7.6/progs/redbook/lines.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/list.c create mode 100644 lib/glut-3.7.6/progs/redbook/list.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/material.c create mode 100644 lib/glut-3.7.6/progs/redbook/material.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/mipmap.c create mode 100644 lib/glut-3.7.6/progs/redbook/mipmap.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/model.c create mode 100644 lib/glut-3.7.6/progs/redbook/model.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/movelight.c create mode 100644 lib/glut-3.7.6/progs/redbook/movelight.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/nurbs.c create mode 100644 lib/glut-3.7.6/progs/redbook/nurbs.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/pickdepth.c create mode 100644 lib/glut-3.7.6/progs/redbook/pickdepth.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/picksquare.c create mode 100644 lib/glut-3.7.6/progs/redbook/picksquare.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/plane.c create mode 100644 lib/glut-3.7.6/progs/redbook/plane.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/planet.c create mode 100644 lib/glut-3.7.6/progs/redbook/planet.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/polyoff.c create mode 100644 lib/glut-3.7.6/progs/redbook/polyoff.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/polys.c create mode 100644 lib/glut-3.7.6/progs/redbook/polys.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/quadric.c create mode 100644 lib/glut-3.7.6/progs/redbook/quadric.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/robot.c create mode 100644 lib/glut-3.7.6/progs/redbook/robot.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/sccolorlight.c create mode 100644 lib/glut-3.7.6/progs/redbook/sccolorlight.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/scene.c create mode 100644 lib/glut-3.7.6/progs/redbook/scene.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/scenebamb.c create mode 100644 lib/glut-3.7.6/progs/redbook/scenebamb.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/sceneflat.c create mode 100644 lib/glut-3.7.6/progs/redbook/sceneflat.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/select.c create mode 100644 lib/glut-3.7.6/progs/redbook/select.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/smooth.c create mode 100644 lib/glut-3.7.6/progs/redbook/smooth.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/stencil.c create mode 100644 lib/glut-3.7.6/progs/redbook/stencil.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/stroke.c create mode 100644 lib/glut-3.7.6/progs/redbook/stroke.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/surface.c create mode 100644 lib/glut-3.7.6/progs/redbook/surface.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/teaambient.c create mode 100644 lib/glut-3.7.6/progs/redbook/teaambient.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/teapots.c create mode 100644 lib/glut-3.7.6/progs/redbook/teapots.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/tess.c create mode 100644 lib/glut-3.7.6/progs/redbook/tess.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/tesswind.c create mode 100644 lib/glut-3.7.6/progs/redbook/tesswind.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/texbind.c create mode 100644 lib/glut-3.7.6/progs/redbook/texbind.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/texgen.c create mode 100644 lib/glut-3.7.6/progs/redbook/texgen.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/texprox.c create mode 100644 lib/glut-3.7.6/progs/redbook/texprox.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/texsub.c create mode 100644 lib/glut-3.7.6/progs/redbook/texsub.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/texturesurf.c create mode 100644 lib/glut-3.7.6/progs/redbook/texturesurf.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/torus.c create mode 100644 lib/glut-3.7.6/progs/redbook/torus.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/trim.c create mode 100644 lib/glut-3.7.6/progs/redbook/trim.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/unproject.c create mode 100644 lib/glut-3.7.6/progs/redbook/unproject.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/varray.c create mode 100644 lib/glut-3.7.6/progs/redbook/varray.dsp create mode 100644 lib/glut-3.7.6/progs/redbook/wrap.c create mode 100644 lib/glut-3.7.6/progs/redbook/wrap.dsp create mode 100644 lib/glut-3.7.6/progs/sgi-stereo/README create mode 100644 lib/glut-3.7.6/progs/sgi-stereo/fullscreen_stereo.c create mode 100644 lib/glut-3.7.6/progs/sgi-stereo/fullscreen_stereo.h create mode 100644 lib/glut-3.7.6/progs/sgi-stereo/stereo-plane.c create mode 100644 lib/glut-3.7.6/progs/spheremap.dsw create mode 100644 lib/glut-3.7.6/progs/spheremap/Imakefile create mode 100644 lib/glut-3.7.6/progs/spheremap/README create mode 100644 lib/glut-3.7.6/progs/spheremap/_all.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/glsmap/Imakefile create mode 100644 lib/glut-3.7.6/progs/spheremap/glsmap/fakeraytrace.c create mode 100644 lib/glut-3.7.6/progs/spheremap/glsmap/fakeraytrace.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/glsmap/rtsmap.c create mode 100644 lib/glut-3.7.6/progs/spheremap/glsmap/rtsmap.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/Imakefile create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/cview2smap.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/cview2smap.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/drawmesh.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/makemesh.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/sixviews.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/sixviews.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/smapmesh.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/smapmesh.dsp create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/smapmesh.h create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/st2rvec.c create mode 100644 lib/glut-3.7.6/progs/spheremap/hacks/st2rvec.dsp create mode 100644 lib/glut-3.7.6/progs/texfont.dsw create mode 100644 lib/glut-3.7.6/progs/texfont/Imakefile create mode 100644 lib/glut-3.7.6/progs/texfont/README create mode 100644 lib/glut-3.7.6/progs/texfont/TexFont.h create mode 100644 lib/glut-3.7.6/progs/texfont/_all.dsp create mode 100644 lib/glut-3.7.6/progs/texfont/abgr.dsp create mode 100644 lib/glut-3.7.6/progs/texfont/curlfont.txf create mode 100644 lib/glut-3.7.6/progs/texfont/default.txf create mode 100644 lib/glut-3.7.6/progs/texfont/djb.txf create mode 100644 lib/glut-3.7.6/progs/texfont/gentexfont.c create mode 100644 lib/glut-3.7.6/progs/texfont/gentexfont.dsp create mode 100644 lib/glut-3.7.6/progs/texfont/haeberli.txf create mode 100644 lib/glut-3.7.6/progs/texfont/rockfont.txf create mode 100644 lib/glut-3.7.6/progs/texfont/showtxf.c create mode 100644 lib/glut-3.7.6/progs/texfont/showtxf.dsp create mode 100644 lib/glut-3.7.6/progs/texfont/simpletxf.c create mode 100644 lib/glut-3.7.6/progs/texfont/simpletxf.dsp create mode 100644 lib/glut-3.7.6/progs/texfont/sorority.txf create mode 100644 lib/glut-3.7.6/progs/texfont/texfont.c create mode 100644 lib/glut-3.7.6/progs/texfont/txfdemo.c create mode 100644 lib/glut-3.7.6/progs/texfont/txfdemo.dsp create mode 100644 lib/glut-3.7.6/progs/tiff/Imakefile create mode 100644 lib/glut-3.7.6/progs/tiff/README create mode 100644 lib/glut-3.7.6/progs/tiff/depthdof.c create mode 100644 lib/glut-3.7.6/progs/tiff/face.tif create mode 100644 lib/glut-3.7.6/progs/tiff/scalebias.c create mode 100644 lib/glut-3.7.6/progs/tiff/showtiff.c create mode 100644 lib/glut-3.7.6/progs/tiff/spiral.tif create mode 100644 lib/glut-3.7.6/progs/tiff/textiff.c create mode 100644 lib/glut-3.7.6/progs/tiff/tiffsift.c create mode 100644 lib/glut-3.7.6/progs/tiff/writetiff.c create mode 100644 lib/glut-3.7.6/test/Imakefile create mode 100644 lib/glut-3.7.6/test/glut/Imakefile create mode 100644 lib/glut-3.7.6/test/glut/_all.dsp create mode 100644 lib/glut-3.7.6/test/glut/atexit_test.c create mode 100644 lib/glut-3.7.6/test/glut/bigtest.c create mode 100644 lib/glut-3.7.6/test/glut/bigtest.dsp create mode 100644 lib/glut-3.7.6/test/glut/cursor_test.c create mode 100644 lib/glut-3.7.6/test/glut/cursor_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/joy_test.c create mode 100644 lib/glut-3.7.6/test/glut/joy_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/keyup_test.c create mode 100644 lib/glut-3.7.6/test/glut/keyup_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/menu_test.c create mode 100644 lib/glut-3.7.6/test/glut/menu_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/over_test.c create mode 100644 lib/glut-3.7.6/test/glut/over_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/shape_test.c create mode 100644 lib/glut-3.7.6/test/glut/shape_test.dsp create mode 100644 lib/glut-3.7.6/test/glut/test1.c create mode 100644 lib/glut-3.7.6/test/glut/test1.dsp create mode 100644 lib/glut-3.7.6/test/glut/test10.c create mode 100644 lib/glut-3.7.6/test/glut/test10.dsp create mode 100644 lib/glut-3.7.6/test/glut/test11.c create mode 100644 lib/glut-3.7.6/test/glut/test11.dsp create mode 100644 lib/glut-3.7.6/test/glut/test12.c create mode 100644 lib/glut-3.7.6/test/glut/test12.dsp create mode 100644 lib/glut-3.7.6/test/glut/test13.c create mode 100644 lib/glut-3.7.6/test/glut/test13.dsp create mode 100644 lib/glut-3.7.6/test/glut/test14.c create mode 100644 lib/glut-3.7.6/test/glut/test14.dsp create mode 100644 lib/glut-3.7.6/test/glut/test15.c create mode 100644 lib/glut-3.7.6/test/glut/test15.dsp create mode 100644 lib/glut-3.7.6/test/glut/test16.c create mode 100644 lib/glut-3.7.6/test/glut/test16.dsp create mode 100644 lib/glut-3.7.6/test/glut/test17.c create mode 100644 lib/glut-3.7.6/test/glut/test17.dsp create mode 100644 lib/glut-3.7.6/test/glut/test18.c create mode 100644 lib/glut-3.7.6/test/glut/test18.dsp create mode 100644 lib/glut-3.7.6/test/glut/test19.c create mode 100644 lib/glut-3.7.6/test/glut/test19.dsp create mode 100644 lib/glut-3.7.6/test/glut/test2.c create mode 100644 lib/glut-3.7.6/test/glut/test2.dsp create mode 100644 lib/glut-3.7.6/test/glut/test20.c create mode 100644 lib/glut-3.7.6/test/glut/test20.dsp create mode 100644 lib/glut-3.7.6/test/glut/test21.c create mode 100644 lib/glut-3.7.6/test/glut/test21.dsp create mode 100644 lib/glut-3.7.6/test/glut/test22.c create mode 100644 lib/glut-3.7.6/test/glut/test22.dsp create mode 100644 lib/glut-3.7.6/test/glut/test23.c create mode 100644 lib/glut-3.7.6/test/glut/test23.dsp create mode 100644 lib/glut-3.7.6/test/glut/test24.c create mode 100644 lib/glut-3.7.6/test/glut/test24.dsp create mode 100644 lib/glut-3.7.6/test/glut/test25.c create mode 100644 lib/glut-3.7.6/test/glut/test25.dsp create mode 100644 lib/glut-3.7.6/test/glut/test26.c create mode 100644 lib/glut-3.7.6/test/glut/test26.dsp create mode 100644 lib/glut-3.7.6/test/glut/test27.c create mode 100644 lib/glut-3.7.6/test/glut/test27.dsp create mode 100644 lib/glut-3.7.6/test/glut/test28.c create mode 100644 lib/glut-3.7.6/test/glut/test28.dsp create mode 100644 lib/glut-3.7.6/test/glut/test29.c create mode 100644 lib/glut-3.7.6/test/glut/test3.c create mode 100644 lib/glut-3.7.6/test/glut/test3.dsp create mode 100644 lib/glut-3.7.6/test/glut/test4.c create mode 100644 lib/glut-3.7.6/test/glut/test4.dsp create mode 100644 lib/glut-3.7.6/test/glut/test5.c create mode 100644 lib/glut-3.7.6/test/glut/test5.dsp create mode 100644 lib/glut-3.7.6/test/glut/test6.c create mode 100644 lib/glut-3.7.6/test/glut/test6.dsp create mode 100644 lib/glut-3.7.6/test/glut/test7.c create mode 100644 lib/glut-3.7.6/test/glut/test7.dsp create mode 100644 lib/glut-3.7.6/test/glut/test8.c create mode 100644 lib/glut-3.7.6/test/glut/test8.dsp create mode 100644 lib/glut-3.7.6/test/glut/test9.c create mode 100644 lib/glut-3.7.6/test/glut/test9.dsp create mode 100644 lib/glut-3.7.6/test/glut/tests.dsp create mode 100644 lib/glut-3.7.6/test/glut/timer_test.c create mode 100644 lib/glut-3.7.6/test/glut/timer_test.dsp create mode 100644 lib/glut-3.7.6/test/mui/Imakefile create mode 100644 lib/glut-3.7.6/test/mui/mui_test.c create mode 100644 lib/glut-3.7.6/test/mui/mui_test.dsp create mode 100644 lib/glut-3.7.6/test/mui/multi_test.c create mode 100644 lib/glut-3.7.6/test/mui/multi_test.dsp create mode 100644 lib/glut-3.7.6/test/test.dsw create mode 100644 src/ui/map3D/QGCGlut.h diff --git a/lib/glut-3.7.6/CHANGES b/lib/glut-3.7.6/CHANGES new file mode 100644 index 0000000000..44111f525c --- /dev/null +++ b/lib/glut-3.7.6/CHANGES @@ -0,0 +1,988 @@ + +GLUT Change Log +================ + +NOTE: This document is potentially incomplete. + + +GLUT 3.7 -> 3.7.1 +------------------ + + o Added a default icon for glut windows (Win32 only). + + o Added workspace and project files for compiling with + Microsoft Visual Studio (6 or greater). + + o Updated some of the demo programs. + + +GLUT 3.6 -> 3.7 +---------------- + + o Added to the ability to automatically link with + the necessary GLUT and OpenGL libraries. Define GLUT_NO_LIB_PRAGMA + to disable this (you need to disable this when compiling the + library itself). Define GLUT_USE_SGI_OPENGL for auto library + linking with the SGI OpenGL for Windows libraries. Define + GLUT_NO_WARNINGS_DISABLE to avoid warnings that GLUT programs + typically want to suppress. + + o Port of IRIS GL newave "wave physics" demo by Erik Larsen + (cayman@sprintmail.com). Look in progs/demos/newave + + o The glutSolidTeapot and glutWireTeapot do not tesselate as + finely as in previous releases. Expect the teapot to render + much faster as of GLUT 3.7. + + o The lib/*/Imakefile files have been updated to make it easier + to build shared/debug/profiling versions of the various GLUT + libraries. See Question 44 in the "FAQ.glut" files for + more details. + + o Fix progs/advanced/textext example to work on little-endian machines. + + o Fixed a performance bug in progs/advanced/rts.c that eliminates + one full shadow volume rendering pass. If you have the silhouette + shadow volume geometry, you can use GL_INVERT and draw the shadow + volume with a single pass with both front & back faces enabled + instead of two distinct passes for front and back as would be + needed if GL_INCR/GL_DECR were used. Also fixed the near and + far clipping planes for better depth precision with 16-bit + depth bufffers. + + o Improve the efficiency of Win32's wglMakeCurrent calls. It + turns out that Microsoft does not "short circuit" a redundant + wglMakeCurrent (ie, if you make current to the same context + and same DC you are already bound to, it is not a no-up). + Now, GLUT uses wglGetCurrentContext and wglGetCurrentDC to + determine when not to redundantly call wglMakeCurrent. + + This also reduced the calling of GetDC within Win32 GLUT. + + Note that the GLX version still assumes that a redundant + glXMakeCurrent is short circuited. + + o Call glutDestroyWindow (and glutLeaveGameMode) destroys the + window (or game mode window) before returning. Previously, + the X11 implementation didn't do an explicit flush so the + window could still be on the screen after glutDestroyWindow + (or glutLeaveGameMode) returned. The Win32 behavior was + corret in GLUT 3.6. + + o Work around Microsoft's bug where atexit callbacks are not + called if exit is called from within a DLL. I had to add new + routines glutCreateWindowWITHEXIT, glutCreateMenuWITHEXIT, + and glutInitWITHEXIT that pass in the exit routine's function + pointer so GLUT can call this routine and exit with the + atexit callbacks called correctly. + + o Added lib/glsmap library for dynamic real-time sphere mapping. + See the demos in progs/spheremap/glsmap + + Builds for N32, O32, and N64 for IRIX. + + rtsmap has an environment reflected in a sphere, teapot, or + icosahedron (8 passes). Very cool. fakeraytrace goes one + step further and has two reflective objects, then does an + extra recursive pass so that one of the spheres is actually + reflecting the reflection in the other sphere. Wow. + + o Man pages updated. + + Version number in man pages changed to 3.7. + + My email address changed to mjk@nvidia.com + + New man pages: + glutEnterGameMode + glutForceJoystickFunc + glutGameModeGet + glutGameModeString + glutIgnoreKeyRepeat + glutJoystickFunc + glutKeyboardUpFunc + glutSetKeyRepeat + glutSpecialUpFunc + + Updated man pages: + glutDeviceGet + glutGet + glutSolidTeapot + + o Updated the ./linux/* files for GLUT 3.7. + + o The GLUT library should compile with a C++ compiler now. I make + no promises that the entirety of GLUT can compile with a C++ + compiler though. Brian Paul wanted this for Mesa which does + expect to build with a C++ compiler. Christoph M. Hoffmann + brought up this issue. + + o Added proto dynamic sphere mapping programs in + progs/spheremap/hacks to help you understand the steps in + making a dynamic sphere map. + + o Added program demonstrating window space texture coordinate + generation at progs/advanced/texwinalign.c; demonstrates how + texture matrix can be be used to generated texture coordinates + in window space. + + o The -iconic command line option works for Win32 GLUT programs + now. The new test28 actually tests the -iconic command line option. + + o Added the glutGameModeString, glutEnterGameMode, glutLeaveGameMode, + and glutGameModeGet calls for "full screen" game mode display + change switching. Only the Win32 implementation really does + display mode changes. See lib/glut/glut_gamemode.c + + o Several demos added a -fullscreen option to use the new GLUT + game mode functionality. I generally also fixed these to + match the window aspect ratio. Examples: underwater, txfdemo + + o Sort of fixed how WM_ACTIVATE messages get processed in the + Win32 GLUT implementation. + + o Moved the Win32 WinProc function out of win32_util.c into + its own win32_winproc.c file. + + o Building the GLUT library debug for Win32 works now (changes + to the Makefile.win setup). + + o Added a poor man's stereo example by Walter Vannini + (walterv@jps.net, waltervannini@hotmail.com). The idea + is to draw the left eye in red and right eye in blue + and use cheap red/blue filter stereo glasses to see + the stereo separation. See progs/advanced/redblue_stereo.c + + o Improve GLUT static library implementation. Now if you don't + use the GLUT menu API, you don't get this code included in your + binary. Reduces GLUT program text size by 25% for such non-menu + GLUT programs. + + o Add gleGetNumSlices and gleSetNumSlices entry points to control + the tessellation level (previously, always a constant 20). + + o Improved dependencies in SGI Makefiles in lib/*/Makefile.sgi + + o Added progs/gle/martini.c example. Spinning martini glass. + + o Should work on VMS 7.0. Changes suggested by Jouk Jansen + (joukj@crys.chem.uva.nl). Mainly changes to GLUT library itself + to deal with VMS 7.0's POSIX-compliant support for gettimeofday. + + o Added GLUT version of "skyfly" terrain fly over demo. See + progs/demos/skyfly + + o Update of GLUT frequently asked questions. See FAQ.glut + + o Added workaround to real-time shadow demos so they work on old + (pre-IRIX 6.5) Octane and Impact systems. The work around makes + sure the feedback buffer is always at least 2048 entries big to + force use of software feedback. See progs/advanced/rts.c and + progs/advanced/shadowfun.c + + o Add work-around in hello2rts for Riva 128 and 128 ZX to make + hello2rts start by default with the stencil invariant hack + enabled. This makes sure that hello2rts use the software + rasterizer for all rendering so the shadows look right. Other + platforms may need this support. There is a menu option to + flip it on if need be. + + o Added a "win32pfd" (Win32 Pixel Format Descriptor) capability + name for the Win32 version of GLUT's glutInitDisplayString + parser. This lets you select a specific pixel format descriptor, + much as "xvisual" allows one to do with X11. This is intended + to facilitate benchmark construction with GLUT where particular + PFDs can be selected for benchmarking or testing. Also documented + on glutInitDisplayString man page. Win32 GLUT only. + + o Add glutGet(GLUT_WINDOW_FORMAT_ID) to return the window system + dependent window format ID (Visual ID for X11; Pixel Format + Descriptor Number for Win32). This should help people be able + to report bugs and now precisely what format ID they are + testing and/or benchmarking. Note that these values can change + between X servers, hardware, and OpenGL implementations. + + o Fix glutGet(GLUT_WINDOW_COLORMAP_SIZE) bug in X11 GLUT + implementation. The routine now correctly returns the colormap + size of the current layer (previously it returned the size + of the normal layer which was a totally bogus value for an + RGBA normal layer). + + o Fixed SEE ALSO section of glutDeviceGet man page. + + o glutInitDisplayString now knows how to use the SGIX_fbconfig + extension to access 16-bit StaticGray luminance visuals. + These high-resolution luminance (1 component) visuals are + excellent for medical imaging applications that need the + 16 bits per pixel resolution. + + To get a luminance window, do: + + glutInitDisplayString("luminance"); + + Note that few systems actually support 16-bit luminance visuals. + InfiniteReality does. I'm not aware of any other systems that + do. + + o Added missing GLUT entry points to the GLUT Ada binding + and interface files. + + o Added progs/demos/sysview, an IRIX operating system 3D + monitor. Only compiles on SGI machines, though it could + easily be adapted to other operating systems. Courtesy + of Javier Velasco . + + o Win32 GLUT didn't generate keyboard callback for Delete key + (ascii 127) before; now it does. + + o Fix warning in glut_input.c when compiling on Alpha due + to XInput extension API snafu. Pointed out by Tom Holroyd + compiling on a Linux Alpha machine. + + o Fixed bug reported by Rune Hasvold in + win32_glx.c where Win32 GLUT was always requesting a 1 + bit depth buffer at least. Now, GLUT requests zero bits + of DEPTH unless you request a depth buffer. Apparently + this bug was fixed in the Mesa version of GLUT a while + back, but didn't get to my GLUT source until now. + +GLUT 3.5 -> 3.6 +---------------- + + o The GLUT .zip file now has "Makefile" be a copy of "Makefile.win" + instead of "Makefile.sgi". This makes it easier for Win32 GLUT + users to just do an "nmake" to build GLUT. + + o Updated various README files for GLUT 3.6. + + o Update GLUT man page revs to say 3.6. + + o Fixed bug in Win32 accumulation buffer allocation code. Thanks to + Nate and Layne Christensen . + + o Fix bug in Win32 GLUT where pushing/popping a subwindow would + also reposition the window to its parent's origin. Now, push/pop + operations do not disturb the window position. + + o Fix all VC++ Win32 warnings and improve the GLUT.DLL speed + and size by macro'izing Xlib routines and eliminating X11-only + functionality from the Win32 version of the library. + + o Fixed various bugs in Win32 GLUT menu handling. The glutChange* + and glutRemoveMenuItem routines should work pretty well now. + + o Fix Win32 GLUT bug where a reshape did not properly result in + repair-damage, ie. glutLayerGet(GLUT_NORMAL_DAMAGED) didn't work + right in GLUT 3.5. + + o The "walker" demo's win32_dirent.h code got update to read directory + correctly for Windows 95 (does Win32 FindFirstFile on "." operate + differently from Windows NT? It seems like "*" works the way "." + should.) + + o X11 GLUT now detects when you set up an infinite loop due to + recursive submenu nesting. In previous GLUT implementations, + this could lead to an infinite loop with the X server grabbed; + now it leads to a GLUT fatal error. + + o GLUT now exits with a fatal error if glXCreateContext (or + wglCreateContext) fails instead of crashing. + + o Win32 "make test" infrastructure in place. + + o Ideas in Motion demo builds better now. + + o Substantially improve the performance of glutSolidTorus and + glutWireTorus by using quad strips instead of independent quads. + Also, generally made the looping more efficient. Thanks to + Emmanuel Maa BERRIET (eberriet@sky.fr) for pointing out the + inefficiencies. + + o Include Linas Vepstas's GLE library with GLUT (based on GLE 2.2.6). + Includes man pages at man/gle and examples at progs/gle + + The GLE Tubing and Extrusion Library is a graphics application + programming interface (API). The library consists of a number of + "C" language subroutines for drawing tubing and extrusions. + + Several bugs in GLE 2.2.6 are fixed here, particularly to make + GLE work well under Win32. + + o Fixed bugs in MUI so that it can support multiple user interface + windows. Added muiAttachUIList to associate a UI list with a GLUT + window. + + o More MUI enchancements to allow "disabled" greyed-out UI elements + courtesy of Tom Davis. + + o gliq, a pegboard game of IQ by Kiri Wagstaff, is at progs/demos/gliq + + o Add Nate Robin's port of the IRIS GL bounce program to OpenGL; see + progs/demos/bounce (includes a slider GUI element). + + o Add Nate Robin's "smooth" 3D object viewer without automatic nice + normal generation. + + o glflare, an OpenGL version of the D3D flare idea by Stephen Coy of + Microsoft. See progs/demos/glflare + + o Resolve gcc warnings (picky, picky) in lib/glut. This includes + not relying on the libc having strdup (not required by ANSI C or + POSIX). + + o Fix array bound overflow bug in progs/examples/stars.c + + o Handle fopen failure in progs/texfont/gentexfont.c + + o Add many more Ada GLUT examples; see progs/ada + + o Support X11R6's XK_KP_* keysyms for the keypad. Previously, + the Home,Left,Right,etc keys on the numeric keypad (when num lock + is off) got ignored. Now they should work. Thanks to Paul + Henning (phenning@cs.uiowa.edu) for pointing out this problem. + + o It is now possible to catch a Unix signal in a signal handler and + add a glutIdleFunc and know that the GLUT main loop will + immediately drop out of waiting for the event and call the idle + callback. This makes it possible to reliably respond to signals + from within a GLUT program. (Just on Unix systems, not Win32.) + + o Added progs/demos/lorenz, Lorenz Attractor Demo. + + o Added progs/examples/editgrid.c + + o Improved progs/mesademos/texobj.c + + o Fixed progs/redbook/surface.c to request a depth buffer. + + o Added progs/advanced/pointburst.c demonstrating a particle system. + + o Added progs/advanced/sgiflag.c demonstrating dynamic real-time + NURBS trimming. + + o progs/advanced/envmap.c supports OpenGL 1.1 now. + + o Fix GLUT library compilation problem on DEC Unix 4.0 on Alpha + machines reported by Ray S. Babcock (babcock@cs.montana.edu). + See glut_dstr.c + + o Fix single buffered GLUT programs that needed to be calling + glFlush at the end of the frame. Reported by + fossum@austin.ibm.com (Gordon C. Fossum). + + o Fix Fortran build error under IRIX 6.5 (use sed instead of grep). + + o Use "-Wl,-ignore_unresolved" SGI linker option to get around + problems in buggy SGI OpenGL Fortran bindings having extension + routines that are not implemented in the supplied OpenGL. + + o Added Brian Paul's marvelous Blue Pony demo in demos/bluepony + + I had requested a Blue Pony from SIGGRAPH as one of my "special + needs" for our SIGGRAPH '97 "OpenGL and Window System Integration" + course. Brian came through with this virtual Blue Pony. Thanks, + Brian! + + o Fixed a problem in test/glut/bigtest.c where if it ran too + long, it would stop rotation due to numeric problems. + + o Make new glut_swap.c and glut_cmap.c files to help keep + glutSwapWindow and the color index GLUT entrypoints out of + statically linked GLUT programs that do not use these routines. + + o Fix many warnings. + +GLUT 3.4 -> 3.5 +---------------- + + o Henk Kok (kok@wins.uva.nl) contributes another cool demo. See + progs/demos/opengl_logo + + o README.win32 now named README.win + + o Add the MUI (micro-UI) library developed for GLUT experimentally + based on SGI's Showcase user interface library. This code was + developed by Tom Davis (davis@sgi.com). + + o The test directory now has subdirectories. test/glut has + all the previous GLUT API tests. + + o Added menus to progs/advanced/projtex.c + + o Added tiffsift.c showing how to do "sifting" texture distortions + with OpenGL's third texture coordinate. + + o Improve lib/glut/glut_menu.c by having the code check if the + default visual is in the overlay so that it will get chosen + as the pop-up menu visual to minimize colormap flashing. + Suggested by Thomas Roell (thomas@xig.com). + + o Fix bug in glutStrokeLength and glutBitmapLength reported by Tom + Carroll . + + o Added shadowfun.c, boundary.c, hello2rts.c and rts.c as + examples of how to do fancy stenciled shadow volumes. See + the progs/advanced subdirectory. + + o Now man pages get installed with "glut" suffix. Should avoid + situations where GLUT's intro.3 clobber's systems intro.3 + because GLUT should now install intro.3glut + + o Changes to Glut.cf for Digital Unix (Alpha) suggested by + Dr Andrej Panjkov (A.Panjkov@latrobe.edu.au). + + o Added demos/chess and demos/rollercoaster demos written by + Henk Kok (kok@wins.uva.nl). Very nice. + + o Michael Gold's "rasterization only" demo uses OpenGL as just + a rasterization interfaces. See progs/advanced/rasonly.c + + o progs/demos/underwater shows OpenGL-based rendering of underwater + caustics effects. Very cool! + + o Added progs/perf_harness directory with an example of how + to create an application specific GLUT-based OpenGL benchmark. + + o Remove lib/glut/cannotate.c from distribution (no one should care). + + o Portability improvements throughout, particularly to Win32. + +GLUT 3.3 -> 3.4 +---------------- + + o Add glutStrokeLength and glutBitmapLength calls to glut.h + (previously undocumented). Will be documented part of GLUT 4 + API. + + o Added man discussion of glutStrokeLength, glutBitmapLength, + and glutWarpPointer. + + o Used ANSI C "const" keyword in glut API and implementation + as appropriate (this helped make Ada binding generation + easier). + + o README.win32 added; this is from Nate Robins's GLUT 3.3 + Win32 distribution. + + o SGI Makefiles use $(TOP)/glutdefs for shared GLUT-related + macros. + + o Add workaround for Microsoft's OpenGL 1.1 implementation. + MS OpenGL 1.1 does not advance the raster position by the + xoffset and yoffset of glBitmap if the specified bitmap + has a width or height of zero (it is just a no-op); this is + not what OpenGL specifies. I've fixed the GLUT bitmap fonts + to not use null bitmaps #ifdef WIN32 and instead use a 1x1 + bitmap with not bit set. capturexfont.c has been changed to + generate code with the #ifdef WIN32 workaround. + + o Fix bug in -geometry handling for negative window positions. + Now "-geometry 400x500-23-34" does not crash GLUT programs. + + o Makefile support for SGI machines so that you can set your + OBJECT_STYLE environment variable to one of SGI's various ABIs + and ISAs. This can let you compile GLUT fully 64-bit with + R10K instructions or mereley old 32-bit ABI. For example, + to compile N32 with only R4K instructions, do a + "setenv OBJECT_STYLE N32_M3". + + o Put header files in include/GL instead of GL - this would make + it esier to support other libraries within the GLUT distribution + (possibly libtiff) that wouldn't want a header to be in the GL + subdirectory. + + o Add GLUT 4 glutReportErrors entry point. + + o New cool game-oriented rendering demos: dinoreflect.c dinoshade.c + and halomagic.c + + o Support HP's Color Recovery System since Mesa uses it. + + o Add the libtiff examples in progs/tiff: showtiff, writetiff, + and textiff + + o Add the new OpenGL Programming Guide 2nd Edition examples to the + GLUT distribution. + + o added progs/mesademos/trdemo.c - Brian Paul's tiled rendering demo. + + o added progs/demos/geoface - facial animation demo. + + o no long export internal symbols in libglut that should have been static. + See lib/glut/Makefile.sgi's "make symcheck" rule. + + o glutInitDisplayString implemented. See test23. Also works automatically + with Mesa. + + o Added popup menu overlay color cell allocation logic for Sun's + Creator hardware. See test24. + + o Enhanced tests and fixed messages in a few places. + +GLUT 3.2 -> 3.3 +---------------- + + o The SGI Makefiles always build O32 executables. In IRIX 6.4, the + default executable type changes to N32; to avoid Makefile + sommersaults, we just keep use at O32. + + o Get rid of all the __glutFatalError calls in the GLUT test suite. + Naughty to be using a GLUT internal function. + + o Introduced some new entry points that will be part of the official + GLUT 4 API when it is finalized for video resize & window status. + The video resize API is useful for hardware with full screen + video resize (ie, InfiniteReality). The window status callback + extends the information of the previous visibility callback to + tell you when the window is fully vs. partially visible and + when the window is hidden vs. fully obscured. GUIs typically want + to know when a window gets unmapped; programs that rely on a + fully unobscured frame buffer (such as histogram occlusion culling) + need to know when the window is fully visisble. + + o progs/advanced/occlude.c demonstrates a histogram based occlusion + culling technique. It requires support of the histogram extension + and works best on a machine like RealityEngine. + + o glutSolidCube and glutWireCube efficiency improved. + + o Added progs/examples/cube.c - simple demo to draw a 3D cube. + + o Fixed warning message from glutSetWindow. + + o glutFullScreen called on a window before it is mapped now + properly overrides the WM_NORMAL_HINTS to ensure that the window + is positioned at 0,0 (ie, no random or interactive placement + by the window manager). + + o For IRIX 6.3 and IRIX 6.4, eliminate X server routine trips for + interning atoms using SGI's fast atoms optimization. + + o Added a GLUT introduction man page. Either "man glut" or "man intro". + + o Previously, timer callbacks could be starved by continous X + events. Now, timer callbacks and X event processing are handled + at the same priority. test/timer_test.c helps verify the improved + behavior. + + o Add IAFA for submitting GLUT to sunsite.unc.edu for anonymous + ftp; based on Mesa version. + + o SGI Makefiles work with MIPS 7.10 compilers now. + + o Fixed more warnings. + + o advanced: Fixed overlay bug in zcomposite. + + o demos: Fixed OpenGL bug in glutmech. + + o demos: Fixed atlantis to have a more reasonable near/far range for + machines with limited depth buffer resolution (<=16 bits). + + o Improved comments in places. + + o libglut: Fixed message if Motif atom intern'ing failed for fullscreen. + +GLUT 3.1 -> 3.2 +---------------- + + o Complete Unix-style nroff man pages for all the GLUT library + routines. See README.man for details. + + o Implement the MESA_SWAP_HACK. If you set the MESA_SWAP_HACK + enviornment variable and you are using Mesa, GLUT will attempt + to simply do a glXSwapBuffers to repair damage to a double + buffered GLUT window that appears to have been last displayed + using a glutSwapBuffers call. This can *greatly* improve the + redraw performance of GLUT programs running under Mesa when + they are damaged (for example by popup menus that are not in + the overlays). See lib/glut/glut_mesa.c This idea was suggested + by Brian Paul on the Mesa mailing list. + + Note that some poorly behaved (probably buggy, actually) GLUT + programs may no redraw correctly with MESA_SWAP_HACK. The + optimization relies upon your display callback being idempotent + and that the window is not otherwise rendered to by other + callback routines. + + o Port Brian Paul's various Mesa 2.0 demo programs to use + GLUT: bounce, gamma, gears, isosurf, offset, reflect, + spin, tess_demo, texobj, & winpos. The reflect program + is definitely worth checking out. + + o Include GLUT examples presented by Tom McReynolds and + David Blythe at the "Advanced OpenGL Rendering" course at + SIGGRAPH '96. + + o Add progs/examples/simple.c showing how to simply draw + a single triangle with OpenGL. How long would an equivalent + Direct3D immediate program be? Much longer... + + o Screen door transparency example using polygon stippling + based on code from Tim Hall. progs/examples/screendoor.c + + o Fix bug where glutRemoveMenuItem about recalculating + the menu's width in pixel that would sometimes cause an + X protocol error. + + o Make sure that when a popup menu is finished that if the + initiating window has an overlay, the overlay colormap + is installed. An overlay popup menu could otherwise knock + out the window's overlay colormap. + + o Fix an "off by one" error in the window number printed out + in a fatal error message when a redisplay is generated on + a window without a display callback. + + o Make consistent puncutation in some fatal error messages. + + o Some work to make example programs easier to build on + Windows NT and 95 (probably not complete; report bugs + please). + +GLUT 3.0 -> 3.1 +---------------- + + o The various shape rendering routines use single + precision instead of double precision. + + o The box shape rendering routines don't generate + redundant normals. + + o Make glutExtensionSupported more robust. + + o Added test20 for glutExtensionSupported. + + o Fixed Makefile in /usr/share/src/GLUT images. + + o Fixed multisample complication bug in dinospin.c + + o Fixed multiple includes in moth.c + + o Add contribed steam.c and glutmech demos (cool!). + + o Added fontdemo and evaltest in progs/examples. + + o Fix an HP/UX compilation problem with libglut.a + + o Fix GETTIMEOFDAY macro to take two args on a Sun. Why does + Sun claim to be SVR4 when they have a BSD (2 parameter + gettimeoday)? + + o Add an #ifdef to glut_win.c for working around Solaris + 2.4 and 2.5 bug in XmuLookupStandardColormap. + +GLUT 2.3 -> 3.0 +---------------- + + o Major version change so GLUT 3.0 does have API additions! + + o Added yacme (yet another colormap editor) demo by Patrick Bouchaud + (SGI Switzerland). + + o Updated glut.h so that GLUT_XLIB_IMPLEMENTATION=5 for 3.0 + and GLUT_API_VERSION=3 for 3.0. + + o Change all the sample programs to _not_ #include or + . From the spec: "Because a very large window system + software vendor (who will remain nameless) has an apparent + inability to appreciate that OpenGL's API is independent of their + window system API, portable ANSI C GLUT programs should not + directly include or . Instead, ANSI C GLUT + programs should rely on to include the necessary + OpenGL and GLU related header files." Sigh. + + o New Helvetica fonts: 10, 12, and 18 point versions. + GLUT_BITMAP_HELVETICA_10, GLUT_BITMAP_HELVETICA_12, and + GLUT_BITMAP_HELVETICA_18. + + o Implement glutFullScreen. + + o Implement glutSetCursor. + + o Implement glutGetModifiers. + + o Implement glutBitmapWidth and glutStrokeWidth. + + o Reimplement test2 to use glutGet(GLUT_ELAPSED_TIME) instead of + the less than portable gettimeofday. + + o Ripped out all the support for compiling earlier GLUT API + versions. It got very ugly and hard to maintain. + + o Added GLUT_LUMINANCE to GLUT verison 3 API and documented it, but + it is not implemented as part of GLUT 3.0; should be in 3.1. + + o Added OpenVMS support to GLUT library with much help from Andy Vesper. + + o The display mode mask parameter for glutInitDisplayMode and the + milliseconds parameter for glutTimerFunc are now of type unsigned + int (previously unsigned long). + + o glutMenuStatus obsoletes glutMenuState. The callback registered + by glutMenuStatus is triggered just like glutMenuState, except + that an additional two parameters pass the X and Y location of the + mouse when the menu status changes. This is to remedy problems a + GLUT program using glutPassiveMotion might have re-sync'ing with + the mouse position after menu use. + + o In previous releases of GLUT, various user input events were + discarded when menus were in use. Now, these callbacks are + generated. If the effect of the events should be performed after + the menu is released, it is up to the GLUT program to delay the + action. + + o Careful to ignore Enter/LeaveNotify events that come + from the pop-up window pointer grab and ungrab (ie, + Enter/LeaveNotify events not marked NotifyNormal for their mode. + Eliminates "spurious" entry events. + + o Fixed bug with new work (like subwindow creation is a display callback) + not being placed on the work queue and getting lost. + + o Fix memory corruption bug in caching of values returned by + glXChooseVisual; no longer cache. + + o Fixed bug with glutCopyColormap sometimes not accurately + re-establishing the WM_COLORMAP_WINDOWS property. + + o Fixed bug in deliver of enter and left callbacks. Before "virtual" + enter and leave (X protocol teminology) were being reported. The + semantic for the entry callback is it is entering and leaving + a GLUT windows real estate that counts; not passing through + the window hiearchy. + + o Add XFlush to __glutFinishMenu in case menu call back will want to + read from a terminal window. In this case, the X server may still + be grabbed since the XUngrabPointer hasn't been flushed out of + Xlib's buffers to the X server for processing (deadlock!). + + o Don't allow modification of menus while in use. Spec ammended to + say "It is illegal to create or destroy menus or change, add, or + remove menu items while a menu (and any cascaded sub-menus) are in + use (i.e., popped up)." Allowing modifications of menus while in + use was dubious, the semantics would be unclear, and even more + unfortunate, might vary from system to system. + + o Spec warns that you should not call routines that require a current + window or menu when there is not a current window or menu (like + before you create one or if you destroy the current one). + + o Fixed bug where glutSpecialFunc callback would only operate if + a glutKeyboardFunc callback was also registered. + + o Fixed bug in color index visual selection so that largest number + of bits of color resolution is preferred to smallest. + + o Fixed bug where if a double buffer X window was used to emulate + a single buffer window, GLUT should set the OpenGL read mode + to GL_FRONT (it was only changing the draw mode). + + o Fixed an obscure ordering bug with simultaneous glutPushWindow and + glutPopWindow calls on different subwindows of the same window. + + o Now, it is a fatal error to receive an expose event with no + display callback registered (it was stupid to allow mapped windows + that made no attempt to redisplay). The spec has been changed to + say NULL can not be passed to glutDisplayFunc; previously, it + said this would disable the callback. Stupid. What was I thinking? + + o GLUT spec is indexed now and generally improved. + + o Support for IRIX 6.2's N32 and N64 object style to take advantage + of new MIPS processor instruction sets. See lib/glut.n32 and + lib/glut.n64 (IRIX 6.x only). + + o Fortran bindings also available for N32 and N64. See lib/fglut.n32 + and lib/fglut.n64. + + o Tests support the new API version 3 interfaces. + + o Contributed "bigtest" test program. + + o Added splatlogo example demonstrating pixel path functionality. + + o Added zoomdino program demonstrating use overlay rubber-banding. + + o Contributed demo programs: hanoi, hanoi2, gears, moth, text3d, + and noof. + + o Contributed SGI stereo program: stereo-plane + + o Being out of colors in the default colormap without overlay planes + will no longer lead to a fatal error when allocating the color gray + for a pop-up menu. Instead, GLUT finds the closest matching color + automatically. Help from Brian Paul to code this. + + o Eliminated Glut64.mk from all Makefile.sgi's + +GLUT 2.2 -> 2.3 +---------------- + + o Fix obscure problem with how X Input extension button press and + release events get selected; it seems GLUT should also be + selecting for the DeviceButtonPressGrab event class since this + ensures that a release will be delivered to the same window as the + press; that was my intent for how buttons presses and releases + should work. I just didn't know you needed this obscure event + class to be selected. Such a grab is the default for pointer + events. + + o If windows are indirect, make sure that a glFinish is properly + done for all windows that have been made current to recently (ie, + last main loop iteration). This helps ensure windows don't get + ahead of themselves. Previously, GLUT simply did a glFinish to + whatever window GLUT happened to be made current to last at the + end of each main loop iteration. + + o Fix what can be considered a bug where calling glutPostRedisplay + within a display callback would not leave the redisplay set; this + applies other routines that set work state needing to be done. + Essentially, clear the workMask before the work callbacks are done + instead of after. The new test15 tests this. + + o To support other OpenGL higher-level library that might want to + be able to call glXMakeCurrent, GLUT should not try to track + make current state and short circuit glXMakeCurrent calls when + GLUT believes the window/context are already current. glXMakeCurrent + should implement the same "short circuit" case, but can appropriately + track the changed state from multiple libraries. + + o The glutRemoveMenuItem routine was totally busted previous to 2.3. + Now it is fixed and test14 is a regression test for it. + + o Add Greg Humphreys's hanoi program to progs/contrib + + o Examples demonstrating Open Inventor used with GLUT found in + progs/inventor + + o New progs/examples programs: abgr, triselect, texenv, stenciltst, + stars, fogtst + +GLUT 2.1 -> GLUT 2.2 +--------------------- + + o Fixed bug in glutGet(GLUT_WINDOW_X) and glutGet(GLUT_WINDOW_Y). + + o Added Philip Winston's human kinetics demo in progs/demos/walker + (COOL!). + + o Improved test suite. + + o Work around SunOS 4.x's non-ANSI compliant realloc. + + o Better handle delivery of reshape callback. + + o Pre-build stroke font C files to avoid having to rely on lex/yacc + working correctly. Too many Linux systems missing flex/bison or + having verisons that resulted in undefined symbols while building + strokegen. + + o Better portability, mostly avoiding compiler warnings. + + o 64-bit clean (as far as I know!). + + o Compiles right for systems like DEC Alpha that support GLX 1.1 but + do not support GLX_SGIS_multisample extension. + + o At Brian Paul's request for better Mesa support, changed colormap + allocation to work if RGBA window has PsueoColor visual. + + o Fix Drew Bliss reported bug in colormap allocation (resulted in + GLUT programs not correctly sharing colormaps). + + o Interesting bug involving the fact that XFlush may actually + read X protocol into Xlib's internal buffers so if you call + XFlush, then select on the X socket, you might find nothing to + read, but when in fact there is data in the Xlib internal buffers + that should be processed. Using ISDN (I guess it has weird + network properties) showed this bug in a GLUT test13. The fix is + to use XPending after XFlush. + + o Improve X Input documentation references in the GLUT spec. + + o Widen margins so spec kills less trees. + + o Clarify GLUT spec to explain glutGet values returned by + GLUT_WINDOW_X, GLUT_WINDOW_Y, GLUT_WINDOW_WIDTH, and + GLUT_WINDOW_HEIGHT as being returned in pixels. + + o Make sure consistently using reshape (and not resize) within GLUT + spec. + + o GLUT spec should document that glutExtensionSupported, + glutCreateWindow, and glutCreateSubwindow return int. + +GLUT 2.0 -> GLUT 2.1 +--------------------- + + o XCOMM comments in Imakefiles results in unusable Makefiles + for systems that pre-date an X11R5-based imake. + + o The rings.c and worms.c examples use "float" returning + versions of trigonometric functions (ie, cosf, sinf, etc.). While + ANSI C reserves these names for their logical purpose, many + systems do not implement these functions. + + o Calls to __glutWarning in glut_cindex in places lack + variable %d argument. + + o Intended comments in lib/Imakefile cause avoiable + warnings for some C pre-processors. + + o Old (pre-X11R6) versions of Xlib did not have XK_Page_Up + and XK_Page_Down keysym defs in /usr/include/X11/keysymdef.h + These are aliases to XK_Prior and XK_Next. + + o The X11R5 to_wfont derived strokegen program for converting + PEX fonts to C data structures was full of memory access + bugs. On most systems, they were not fatal. That's + what I get for trying to steal PEX code I gues. :-) + + o Various Purify-detected memory access bugs within the + GLUT library have been fixed. + + o Better Imakefile handling of lex usage in lib/glut/Imakefile + + o Better document colormap management routines. + + o Correctly document the prototype for glutCreateSubWindow + + o Add documentation usage hint explaining glutGetWindow + and glutGetMenu can be used to determine what window + or menu a callback is for. + + o Fix bug in glutDetachMenu + + o Fix bug in delivery of visibility callback for subwindows + of an unmapped top-level window. + + o scube.c should use more likely to be optimized + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) instead of + glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA) + + o Supression of various compiler detected warnings through + the GLUT distribution. + + o Use of the "polygon offset" extension if available in origami.c + + o SGI mkmkfiles.sgi script doesn't make Fortran by default now; + see instructions in README.fortran + + o Improvements to the test programs. + + o Avoid X Input extension calls when extension is present but + no devices are available. + +GLUT 1.0 -> GLUT 2.0 +--------------------- + + o API extensions; see README.glut2 + + o Bug fixes. + + o More demos. + + o Update documentation. + +- Mark diff --git a/lib/glut-3.7.6/FAQ.glut b/lib/glut-3.7.6/FAQ.glut new file mode 100644 index 0000000000..fab74c9f80 --- /dev/null +++ b/lib/glut-3.7.6/FAQ.glut @@ -0,0 +1,915 @@ + +An on-line (possibly more up-to-date) version of this GLUT Frequently +Asked Questions list can be found at: + + http://reality.sgi.com/opengl/glut3/glut-faq.html + +Here are few questions I expect to be frequently asked about GLUT 3.5. +First, here are tag-line summaries of the question subject matter. + +Q1: Problems building GLUT. I've tried to use the "mkmkfiles.imake" + script to generate Makefiles so I can build GLUT, but it doesn't + seem to work. What should I try? + +Q2: More GUI features. GLUT needs improved menus, dialog boxes, + scrollbars, text entry fields, etc. to be useful to me. What + should I do? + +Q3: New with GLUT 3.0. What new things are in GLUT 3.0? + +Q4: GLUT for Windows 95 and NT. Is there a version of GLUT for + Windows NT or Windows 95? + +Q5: GLUT for OS/2. Is there a version of GLUT for OS/2? + +Q6: GLUT for Power Macintosh. Is there a version of GLUT for the + Power Macintosh? + +Q7: GLUT 3.0 incompatibilities. I'm hesitant about upgrading to GLUT + 3.0 since I've got things working will with GLUT 2.3. Is the + transition painful? + +Q8: GLUT and Motif. So how do I use GLUT and Motif together? + +Q9: aux convension to GLUT. I have a bunch of simple OpenGL programs + using the aux toolkit descibed in the OpenGL Programming Guide + (the "red" book). Is there an easy way to convert them to GLUT? + +Q10: SGI N32 and 64-bit support. I have IRIX 6.2 (or 6.1) and I'd + like to write GLUT programs run in true 64-bit and/or benefit + from the recent, faster MIPS processors. How do I build GLUT to + support these newer application binary interfaces (ABIs)? + +Q11: FORTRAN and GLUT. I'd like to write FORTRAN programs using GLUT + and OpenGL. How do I use GLUT with FORTRAN? + +Q12: Sophisticated input devices. I'd like to use the sophisticated + input devices that GLUT supports. What should I know about this? + +Q13: GLUT and Open Inventor. Can I use GLUT and Open Inventor? + +Q14: GLUT, Sun, and Overlays. I have Sun workstation, and it is + supposed to support overlays. So why does GLUT not use them? + +Q15: The GLUT stroke font. The stroke font used for GLUT looks + familar. Where did it come from? + +Q16: My book about GLUT. I read in the NOTICE file that you are + writing a book on programming OpenGL for the X Window System. + Where can I get it? + +Q17: GLUT and Microsoft portability. You mention an unnamed bu "very + large window system software vendor" as the reason portable GLUT + programs should not directly include and + directly. What's the vendor and what are the details? + +Q18: GLUT and networking. I want my GLUT program to read and send + information over a socket to some other program. How do I do + this in in GLUT? + +Q19: Asking GLUT questions. Where's the best place to ask questions + about GLUT or OpenGL? Can I just email them to you? + +Q20: Free OpenGL. My workstation doesn't have OpenGL. Where can I get a + free copy to use with GLUT? + +Q21: GLUT overlay example code. I hear GLUT 3.0 has overlay support. + Where is an example? + +Q22: BadMatch errors running GLUT programs. I get BadMatch X protocol + errors when I run GLUT programs. What gives? + +Q23: New in GLUT 3.1. What is new in GLUT 3.1? + +Q24: Shared libraries for Linux. How do I make Linux shared libraries + for GLUT? + +Q25: New in GLUT 3.2. What is new in GLUT 3.2? + +Q26: GLUT API man pages. I've heard GLUT 3.2 has man pages. How do I + use them? + +Q27: Fast window repair for Mesa. What is the MESA_SWAP_HACK in GLUT + 3.2? How does it help Mesa users avoid excessive window redraws? + +Q28: Advanced GLUT example .rgb image file. I try to run the examples in + progs/advanced but they don't work for lack of image files. + Where can I get those files? + +Q29: IRIX 6.3 and 6.4 fast atoms support issues for older IRIX + releases. Why doesn't GLUT programs compiled on IRIX 6.4 or 6.3 + work earlier releases? + +Q30: GLUT for the Power Macintosh. Can I get a version of GLUT for the + Power Macintosh? + +Q31: New in GLUT 3.4. What is new in GLUT 3.4? + +Q32: Cosmo3D beta and GLUT problem. I installed SGI's Cosmo3D beta and + GLUT, and I'm having problems compiling GLUT programs. What gives? + +Q33: New in GLUT 3.5. What is new in GLUT 3.5? + +Q34: Using the precompiled GLUT DLLs with Borland compilers. How do I use + the precompiled Win32 GLUT DLLs with Borland compilers? + +Q35: Using GLUT with C++. Are there any C++ wrappers for GLUT? + +Q36: Avoiding the Console window for Win32 GLUT programs. How do you avoid + the Console window appearing when you compiler a Win32 GLUT + application with Microsoft compilers? + +Q37: New in GLUT 3.6. What is new in GLUT 3.6? + +Q38: O2 build problmes with glXChannelRectSyncSGIX. On my IRIX 6.3 SGI O2 + workstation, why do I get errors about "glXChannelRectSyncSGIX" + being unresolved building certain GLUT examples? + +Q39: Using GLUT with Microsoft OpenGL 1.1 and compiling GLUT with + Borland compilers causes GLUT applications to generates floating + point exceptions. What can be done? + +Q40: Using GLUT with SGI OpenGL for Windows and compiling with + Borland compilers results in linking problems. What can be + done? + +Q41: What is GameGLUT? + +Q42: I use a callback registered with "atexit" to clean up my temporary + files and stuff. Under Windows, my atexit callback is not being + called if you quit by application by clicking the X box or using + the Windows Close border menu. What gives? + +Q43: My Unix GLUT program has a variable named "select". When I run + my program it crashes on startup in code that is not mine. + What gives? + +Q44: I use Imakefiles to build GLUT. How do I make shared/debug/profiling + versions of the various GLUT libraries? + +-- + +Q1: I've tried to use the "mkmkfiles.imake" script to generate + Makefiles so I can build GLUT, but it doesn't seem to work. What + should I try? + +A1: While Imakefiles are supposted to be system independent (hence + the "I"), the commands to translate Imakefiles into Makefiles + varies from system to system. The X Consortium provides a command + called "xmkmf", but vendors do not put this command in a + consistent place. The "mkmkfiles.imake" script tries its best to + generate Makefiles, but may get confused by different vendors + configurations that I am not aware of. + + It is also possible the imake configuration files (typically + located at /usr/lib/X11/config) are buggy or from a very old + version of X. + + SGI users can benefit from using the "mkmkfile.sgi" script that + uses SGI's parallel make, though "mkmkfiles.imake" should work + too. + +-- + +Q2: GLUT needs improved menus, dialog boxes, scrollbars, text + entry fields, etc. to be useful to me. What should I do? + +A2: GLUT does not pretend to be a full-featured graphical user + interface toolkit. + + You _could_ write these sorts of GUI objects using GLUT and OpenGL + if you needed to. The other alternative is to use Motif or + whatever full featured toolkit you have. + + A little toolkit called micro-UI uses OpenGL for rendering and is + based on GLUT. The toolkit was developed by Tom Davis. See the + README.mui file the accompanies GLUT 3.5 and up. + +-- + +Q3: What new things are in GLUT 3.0? + +A3: See README.glut3 or read The OpenGL Utility (GLUT) Programming + Interface document. + +-- + +Q4: Is there a version of GLUT for Windows NT or Windows 95? + +A4: As of GLUT 3.5, GLUT now builds for both Win32 and X11 window + systems. Much thanks to Nate Robins. See the README.win file + contained in GLUT 3.5 for details. GLUT 3.6 improved the Win32 + GLUT support considerably. + +-- + +Q5: Is there a version of GLUT for OS/2? + +A5: Yes. I believe a version based on GLUT 2.x is distributed on an + OS/2 OpenGL developer's CD-ROM. + + You may have reasonable luck porting the Win32 version of the + GLUT 3.6 distribution to OS/2. If you manage to do this, please + contact me. + +-- + +Q6: Is there a version of GLUT for the Power Macintosh? + +A6: Conix Graphics supplies GLUT 3.5 with their Macintosh OpenGL + implementation. See http://www.conix3d.com. + + Was told by Template Graphics that an incomplete version of + GLUT had been developed for their OpenGL product for the Power + Macintosh. I am not sure if it was ever completed or made + available. + + + +-- + +Q7: I'm hesitant about upgrading to GLUT 3.0 since I've got things + working will with GLUT 2.3. Is the transition painful? + +A7: I do not believe so. There are two changes worth noting that + _may_ affect programs you have written. + + First, you need a display callback registered before your display + your windows on the screen. It did not make sense for this to not + be true. In all likeihood, this should not affect your GLUT + programs if they written well. + + Second, you can no longer change, create, or destroy menus while + pop-up menus are in use. Before, you could do this, but it meant + a menu might be changed while in use. It was near impossible to + describe what should happen in the case of menus being changed + while in use that was likely to be portable to the way other + window systems handled menus, so I made the practice illegal. + + You can register a menu status callback to know when menus become + used and unused to avoid changing menus while they are in use. + + For more details about what has changed, see the CHANGES file. + +-- + +Q8: So how do I use GLUT and Motif together? + +A8: You don't. To make GLUT simple and easy-to-program, GLUT + supplies its own event processing loop. This makes it nearly + impossible to combine GLUT and Motif. If you want Motif, you + probably want a full-featured toolkit, and you ship skip GLUT and + implement your application directly in Motif. + +-- + +Q9: I have a bunch of simple OpenGL programs using the aux toolkit + descibed in the OpenGL Programming Guide (the "red" book). Is + there an easy way to convert them to GLUT? + +A9: In the progs/redbook directory, there is a script named + aux2glut.sed It will give you a good start at converting simple + aux calls to their GLUT equivalents. It is a good start, but + you'll still have to hand edit some things. + + Here's a usage example: + + sed -f aux2glut.sed < aux_prog. > glut_prog.c + + Note that the second edition of the OpenGL Programming Guide uses + GLUT and not the aux toolkit. + +-- + +Q10: I have IRIX 6.2 (or 6.1) and I'd like to write GLUT programs + run in true 64-bit and/or benefit from the recent, faster MIPS + processors. How do I build GLUT to support these newer + application binary interfaces (ABIs)? + +A10: See README.irix6 + +-- + +Q11: I'd like to write FORTRAN programs using GLUT and OpenGL. How + do I use GLUT with FORTRAN? + +A11: GLUT does have a FORTRAN language binding. + + For instructions for building a binding library for Silicon + Graphics workstations, see README.fortran + + If you want to use GLUT and OpenGL or Mesa on with Fortran on + non-SGI systems, I recommend that you check, William Mitchell's + f90gl home page: http://math.nist.gov/f90gl/ + +-- + +Q12: I'd like to use the sophisticated input devices that GLUT + supports. What should I know about this? + +A12: GLUT uses the X Input extension to talk to these devices. Because + the X Input extension gives a framework for supporting input + devices, but does not manadate how particular devices are + supported, it is possible that each vendor supports the same input + devices differently. + + GLUT as implemented supports SGI's means of advertising the + tablet, dial & button box, and Spaceball devices. I am not sure + how other vendors support these devices. For the details of SGI's + support for these devices, see README.xinput Since there is no + benefit in each vendor supporting these same devices in a + different an incompatible way, I encourage other vendors to + implement their devices in this same manner. + +-- + +Q13: Can I use GLUT and Open Inventor? + +A13: Yes. See the README.inventor file. Also, some source code + examples can be found at progs/inventor + + Because the Open Inventor development enviornment is not supported + on all systems, the Inventor example programs are not built by + default, and the Makefile there only support SGI systems. + +-- + +Q14: I have Sun workstation, and it is supposed to support overlays. + So why does GLUT not use them? + +A14: GLUT uses the SERVER_OVERLAY_VISUALS convention that advertises + overlay visuals. Most major workstation vendors support this + convention (DEC, HP, IBM, SGI), but Sun only support the + SERVER_OVERLAY_VISUALS in their latest Creator 3D hardware. + +-- + +Q15: The stroke font used for GLUT looks familar. Where did it come + from? + +A15: The data for the "stroke roman" font is lifted from the X11R5 + PEX sample implementation. + +-- + +Q16: I read in the NOTICE file that you are writing a book on + programming OpenGL for the X Window System. Where can I get it? + +A16: My book titled "Programming OpenGL for the X Window System" was + released in August of 1996. The book is published by + Addison-Wesley and the ISBN is 0-201-48359-9. If you have seen + the "red" and "blue" OpenGL books, this book looks very similar, + but has a green cover. More information can be found at: + + http://reality.sgi.com/mjk_asd/OpenGLforX.html + http://aw.com/devpress/titles/48359.html + + The book includes a tutorial chapter introducing the entire GLUT + API. Another chapter uses GLUT-based examples to explain various + OpenGL rendering features. An appedix describes the GLUT API + in detail. If you use GLUT, this book will be very helpful. + + A Japanese translation is also available now (ISBN4-7952-9703-7). + +-- + +Q17: You mention an unnamed bu "very large window system software + vendor" as the reason portable GLUT programs should not directly + include and directly. What's the vendor and + what are the details? + +A17: Microsoft. It's version of requires to be + included before can be included because of Microsoft + function declaration conventions. Sigh. + +-- + +Q18: I want my GLUT program to read and send information over a socket + to some other program. How do I do this in in GLUT? + +A18: You can not do it currently. I am considering such support for + a possible GLUT 4.0. I'd like to have a portable solution. + + What you'd like is a callback that would tell you when a socket is + ready for reading and writing. I'm hoping to find a way to + support this in an operating system independent manner. Does + anyone know of a good portable interface for networked bytestream + connections? + + For now, you've got the source code to GLUT and you could hack it + into GLUT for whatever particular interface your operating system + provides. + +-- + +Q19: Where's the best place to ask questions about GLUT or OpenGL? Can + I just email them to you? + +A19: While I may try to return email if I have time, the best place + is the comp.graphics.api.opengl newsgroup. This gives a lot more + people a chance to answer your question and you'll probably get an + answer much faster than sending me email. Plus, I may not know + the answer though someone on the "net" may know it. + +-- + +Q20: My workstation doesn't have OpenGL. Where can I get a free copy + to use with GLUT? + +A20: OpenGL is licensed by Silicon Graphics and is not available as + "free" or "public domain" software, but workstation vendors + typically bundle OpenGL software with their workstation. However, + there is a package called Mesa written by Brian Paul at the + University of Wisconsin that implements the OpenGL API. (To be + branded as "OpenGL", an implementation must be licensed _and_ pass + the Architectural Review Board's conformance suite, so Mesa is not + an official "OpenGL" implementation.) Mesa does work with GLUT. + + Mesa 2.5 and beyond include GLUT with the Mesa source code + distribution. + +-- + +Q21: I hear GLUT 3.0 has overlay support. Where is an example? + +A21: Look at progs/examples/zoomdino.c for an example of using overlays + for rubber-banding and display of a help message, both in the + overlays. Also, test/over_test.c exercises all of the overlay + routines. + +-- + +Q22: I get BadMatch X protocol errors when I run GLUT programs. What gives? + +A22: There is a bug in the Solaris 2.4 and 2.5 implementation of +XmuLookupStandardColormap (fixed in Solaris 2.6). When you compile GLUT +on Solaris 2.4 or 2.5, please apply the following patch and compile +with -DSOLARIS_2_4_BUG to workaround the problem. See the comment in +the patch below. This code is already in GLUT 3.1. + +*** glut_win.c Wed Apr 24 14:06:08 1996 +--- glut_win.c.bad Wed Apr 24 14:03:58 1996 +*************** +*** 398,414 **** + case TrueColor: + case DirectColor: + *colormap = NULL; /* NULL if RGBA */ +- #ifndef SOLARIS_2_4_BUG +- /* Solaris 2.4 has a bug in its XmuLookupStandardColormap +- implementation. Please compile your Solaris 2.4 version +- of GLUT with -DSOLARIS_2_4_BUG to work around this bug. +- The symptom of the bug is that programs will get a +- BadMatch error from X_CreateWindow when creating a GLUT +- window because Solaris 2.4 creates a corrupted +- RGB_DEFAULT_MAP property. Note that this workaround +- prevents Colormap sharing between applications, perhaps +- leading unnecessary colormap installations or colormap +- flashing. */ + status = XmuLookupStandardColormap(__glutDisplay, + vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, + /* replace */ False, /* retain */ True); +--- 398,403 ---- +*************** +*** 423,429 **** + return; + } + } +- #endif + /* If no standard colormap but TrueColor, just make a + private one. */ + /* XXX Should do a better job of internal sharing for +--- 412,417 ---- + +-- + +Q23: What is new in GLUT 3.1? + +A23: GLUT 3.1 is largely a maintence release. There are some new programs, a + few minor GLUT library bug fixes, but mostly GLUT 3.1 is to make sure GLUT + builds cleanly on various platforms like SunOS, HP/UX, Solaris, and Linux. + See the CHANGES file included in the distribution for more details. + +-- + +Q24: How do I make Linux shared libraries for GLUT? + +A24: Peter F. Martone (pmarton@mailbox.bgsu.edu) has written some + instructions for making a Linux shared library for GLUT. You can grab + the instructions for doing so from + http://pizza.bgsu.edu/cgi-bin/cgiwrap/~pmarton/makeMainIndex + +-- + +Q25: What is new in GLUT 3.2? + +A25: Like GLUT 3.1, GLUT 3.2 is a maintence release. Along with bug + fixes to the core GLUT library, many new GLUT example programs + have been added. The portability of the examples has been + improved so that most should build using Windows 95 and NT. + Also, GLUT API man pages are now included. See the CHANGES file + included in the distribution for more details. + +-- + +Q26: I've heard GLUT 3.2 has man pages. How do I use them? + +A26: Please see the README.man file for details. The easiest way for + SGI users to get the man pages is to install the "glut_dev.man.glut" + subsystem included with the pre-compiled SGI GLUT images. + +-- + +Q27: What is the MESA_SWAP_HACK in GLUT 3.2? How does it help Mesa + users avoid excessive window redraws? + +A27: The GLX specification states that the state of a window's back + color buffer after a glXSwapBuffers is undefined. However, the + freeware Mesa implementation of the OpenGL API always leaves + the back buffer with its previous contents (ie, it simply + "copies" the back buffer contents to the front buffer). + + Because Mesa lacks hardware acceleration and is often slow to + redraw a window, this presents the opportunity to speed + redrawing a window damaged by window system interactions by + simply calling glXSwapBuffers again. + + If you set the MESA_SWAP_HACK enviornment variable, GLUT 3.2 + will try to repair double buffered windows not otherwise + needing a redisplay because of glutPostRedisplay by calling + glXSwapBuffers when Mesa is the OpenGL implementation being + used and the last display callback called glutSwapBuffers. + + In general, this means if you see MESA_SWAP_HACK when using + Mesa, double buffered GLUT programs will redraw very quickly + after being damaged but still operate well if they've been + correctly written to use glutPostRedisplay to trigger + application required redraws. + + I encourage all Mesa users to set the MESA_SWAP_HACK environment + variable. + +-- + +Q28: I try to run the examples in progs/advanced but they don't work + for lack of image files. Where can I get those files? + +A28: Yes, the image files these examples use are large and were + seperated out from the main GLUT source code distribution. + Get the glut_data.tar.gz file from where you got your + GLUT distribution. Untar these data files over your glut + distribution so the "data" directory is at the same level + as "progs". Then do a "make links" in the progs/advanced + directory to make symbolic links. + + See the progs/advanced/README file for more details. + +-- + +Q29: Why doesn't GLUT programs compiled on IRIX 6.4 or 6.3 work + earlier releases? + +A29: First, SGI never guarantees that an executable built on a later + IRIX release will work on an earlier release. Sometimes it works; + more often than not it does not. GLUT takes advantage of a new X + optimization in IRIX 6.3 called "fast atoms". This optimization + lets X clients determine common atom values without an X server + round-trip. This helps X performance. + + If you compile the GLUT library on an IRIX 6.3 or IRIX 6.4 + machine, the library will support fast atoms. This will mean that + if you run executables linked against the "fast atom enabled" + version of the GLUT library, you'll get a run-time link error + saying something like: + + 17062:glut_example: rld: Fatal Error: attemped access to + unresolvable symbol in projtex: _XSGIFastInternAtom + + Do not be alarmed. If you want, you can recompile the GLUT + library with the -DNO_FAST_ATOMS and get a version of the library + that doesn't have the support so that GLUT executables built with + a library compiled without "fast atoms" can work on earlier IRIX + releases. Note that even if you do compile with -DNO_FAST_ATOMS, + there is still no guarantee that an IRIX executable compiled on a + newer release will actually work on an older release (but at + least you'll have a chance!). + + Note that the precompiled images lack "fast atoms" support so + they will work fine with IRIX releases before IRIX 6.3 and 6.4. + +-- + +Q30: Can I get a version of GLUT for the Power Macintosh? + +A30: Conix Graphics has released a port of GLUT + 3.2 I believe. Try checking the Conix Graphics web site + http://www.conix3d.com for current info. + +-- + +Q31: What is new in GLUT 3.4? + +A31: GLUT 3.4 is an incremental release. An Ada binding for SGI + machines is included along with an Ada example. Many new sample + programs. Several such as dinoshade.c demonstrate real-time + rendering techniques relevant for games. Examples using Sam + Leffler's libtiff library for loading, drawing and writing TIFF + image files. GLUT version of the facial animation "geoview" + decibed in the Parke and Water's book "Computer Facial + Animation". New API interfaces to be made part of the GLUT 4 API + update (not yet fully finalized though). glutInitDisplayMode for + example. Improved portability and a few bug fixes. + +-- + +Q32: I installed SGI's Cosmo3D beta and GLUT, and I'm having problems + compiling GLUT programs. What gives? + +A32: Unfortunately, SGI's Cosmo3D beta images install a DSO for GLUT + (libglut.so) that does not fully implement the GLUT API and lacks + some of the newer GLUT 3.4 entrypoints as well. The problem is + that a DSO takes preferenc over an archive when you compile with + an option like "-lglut". While the Cosmo3D beta installs a + libglut.so, my GLUT distribution and images only build and + install an archive. There are a couple of solutions: + + 1) Explicitly link your GLUT programs with libglut.a (the + archive version of GLUT). For example, put "/usr/lib/libglut.a" + on your compile line instead of "-lglut". + + 2) You can convert the GLUT 3.4 archive into a DSO: + + su + cd /usr/lib + mv libglut.so libglut.so.cosmo + cc -32 -o libglut.so -shared -all libglut.a + cd /usr/lib32 + mv libglut.so libglut.so.cosmo + cc -n32 -o libglut.so -shared -all libglut.a + + The new DSO generated from the GLUT 3.4 DSO should be + compatible with the old Cosmo version. This will mean that + all the GLUT programs you build will need the libglut.so on + the machine they run on. + + 3) Remove the Cosmo3D beta. + +-- + +Q33: What is new in GLUT 3.5? + +A33: The most significant change with GLUT 3.5 is unifying the X + Window System and Win32 versions of GLUT into a single source + code distribution. Henk Kok contributed several cool new demos + (rollercoaster, chess, opengl_logo). All the demos build cleanly + under Win32. Lots of bug fixes. Interesting new OpenGL rendering + techniques are demonstrated in a number of new examples: + movelight, dinoshade, halomagic, rendereps, movelight, shadowfun, + torus_test, underwater, texfont, reflectdino. + +-- + +Q34: How do I use the precompiled Win32 GLUT DLLs with Borland compilers? + +A34: The "implib" command should let you generate a GLUT.LIB that works + with Borland compilers from the precompiled GLUT.DLL Here is an + example: + + C:\>implib -f C:\GLUT\LIB\GLUT.LIB C:\WINDOWS\SYSTEM\GLUT.DLL + + After this, then link C:\GLUT\LIB\GLUT.LIB to your project + + Likewise, for the Microsoft GLUT32.DLL: + + C:\>implib -f C:\GLUT\LIB\GLUT32.LIB C:\WINDOWS\SYSTEM\GLUT32.DLL + + Suggested by Carter . + + The "-f" option is suggested by Kris Matson . + +-- + +Q35: Are there any C++ wrappers for GLUT? + +A35: Yes, George Stetten (stetten@acpub.duke.edu) of Duke University has + made available the GlutMaster C++ wrapper classes. See: + + http://www.duke.edu/~stetten/GlutMaster/GlutMaster.html + http://www.duke.edu/~stetten/GlutMaster/README.txt + +-- + +Q36: How do you avoid the Console window appearing when you compiler a + Win32 GLUT application with Microsoft compilers? + +A36: Try using the following Microsoft Visual C compiler flags: + + /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup + + These are linker options... if main or wmain are defined, MSVC + build a CONSOLE app by default; hence the need for + /SUBSYSTEM:WINDOWS. if /SUBSYSTEM:WINDOWS is defined, MSVC + expects WinMain or wWinMain to be defined; hence the need to + /ENTRY:mainCRTStartup (eg the entry point is the usual C main). + + stdout/stderr are [apparently] not "attached"; output via printf + is simply "eaten" unless redirected at the command-line or by a + parent program. + + Information thanks to Jean-David Marrow (jd@riverbed.com). + +-- + +Q37: What is new in GLUT 3.6? + +A37: GLUT 3.6 adds/improves the following: + + o Win32 GLUT performance improvements. + + o Win32 GLUT confromance improvements. + + o Linas Vepstas's GLE Tubing & Extrusions Library is + included with GLUT, including nroff man pages and + demo programs. + + o More GLUT-based OpenGL demos and examples (and bug + fixes to existing demos and examples). + + o glutPostWindowRedisplay and glutPostWindowOverlayRedisplay + entry points added for posting redisplays on non-current + windows (for faster multi-window updates). + + o Bug fixes and minor functionality improvements to Tom Davis's + micro-UI GLUT-based user interface toolkit. + + See the "CHANGES" file that accompanies GLUT 3.6 for a fuller + list of changes. + +-- + +Q38: On my IRIX 6.3 SGI O2 workstation, why do I get errors about + "glXChannelRectSyncSGIX" being unresolved building certain GLUT + examples? + +A38: The original IRIX 6.3 release for the O2 workstation accidently + advertised support for the dynamic video resize extension supported + on SGI's high-end InfiniteReality graphics system. This confuses + GLUT into providing its dynamic video resize sub-API. + + This problem is fixed by patch 1979 (and its successor patches). + Because patch 1979 (and its successor patches) also help O2's + OpenGL rendering performance, I strongly recommend requesting + the latest O2 OpenGL patch from SGI customer support. + + Once the patch is installed, your build errors will be resolved. + +-- + +Q39: Using GLUT with Microsoft OpenGL 1.1 and compiling GLUT with + Borland compilers causes GLUT applications to generates floating + point exceptions. What can be done? + +A39: Under certain conditions (e.g. while rendering solid surfaces + with lighting enabled) MS libraries cause some illegal operations + like floating point overflow or division by zero. The default + behaviour of Microsoft compilers is to mask (ignore) floating + point exceptions, while Borland compilers do not. A function of + Borland run-time library allows to mask exceptions. Modify + glut_init.c by adding the following lines to the function + __glutOpenWin32Connection. + +#ifdef __BORLANDC__ +#include + _control87(MCW_EM,MCW_EM); +#endif + + With this modification, compiling the GLUT library with your + Borland compilers and using GLUT with Microsoft OpenGL should + work fine. + + GLUT 3.7 will have this change already included in the GLUT + library source code distribution. + + This advice comes from Pier Giorgio Esposito (mc2172@mclink.it). + +-- + +Q40: Using GLUT with SGI OpenGL for Windows and compiling with + Borland compilers results in linking problems. What can be + done? + +A40: Some care must be taken when linking GLUT.DLL or programs + that use it with Borland compilers. The import library + IMPORT32.LIB already contains the functions exported by + the Microsoft OpenGL libraries, thus SGI OpenGL import + libraries must be listed _before_ import32 in the Borland + tlink command line. + + This advice comes from Pier Giorgio Esposito (mc2172@mclink.it). + +-- + +Q41: What is GameGLUT? + +A41: GameGLUT is a set of API extension to GLUT to be released in + GLUT 3.7. These extensions provide keyboard release callbacks, + disabling of keyboard auto repeat, joystick callbacks, and full + screen resolution setting. + +-- + +Q42: I use a callback registered with "atexit" to clean up my temporary + files and stuff. Under Windows, my atexit callback is not being + called if you quit by application by clicking the X box or using + the Windows Close border menu. What gives? + +Q42: Windows has multiple C run-time libraries (CRTs). The GLUT.DLL + is linked against the MSVCRT.LIB CRT (for multi-threaded, DLL + programs). The OPENGL.DLL and GLU.DLL libraries are also linked + with MSVCR.LIB. By default, the Visual C++ compiler links with + the LIBC.LIB CRT (for single-threaded, non-DLL programs). + + Static data in one CRT is not shared with other CRTs in the + Win32 environment. In general, mixing CRTs in a single program + is bad. In particular, an atexit callback registered with one + CRT will not be called when the exit routine of another CRT is + called. + + The "/MD" option forces use of the MSVCRT.LIB (the one GLUT.DLL is + linked with). If you use the "/MD" option, then atexit callbacks + should occur just fine even if you application exits through a + GLUT fatal error or the user exits from the Windows close border + or clicks the X button. + + Do not use the "/ML" or "/MT" options when linking GLUT programs + under Win32. The options link with the LIBC.LIB and LIBCMT.LIB + libraries respectively. + + Be aware you can also link with these libraries explicitly (instead + of using the options) by putting LIBC.LIB or LIBCMT.LIB on your + command line. Avoid this practice since it will also cause + problems. + +-- + +Q43: My Unix GLUT program has a variable named "select". When I run + my program it crashes on startup in code that is not mine. + What gives? + +Q43: There is a Unix system call called "select" that is used by both + the GLUT library and the Xlib library. If you name a variable + "select", the linker will pre-empt the C library version of select + with your variable. When GLUT or Xlib try to call the "select" + routine, they jump to your data instead and crash your application. + + The crash will be deep in GLUT or Xlib and this will likely be + very confusing. + + Rename your variable to a different name, and the problem will + be fixed. + + Note that other names such as "connect", "socket", "read", and + "write" will cause similiar problems if used as variable names or + routine names in GLUT programs. If in doubt, try doing "man XXX" + where XXX is the suspicious variable name. If you get the manual + page for a C library function, pick another name. + +-- + +Q44: I use Imakefiles to build GLUT. How do I make shared/debug/profiling + versions of the various GLUT libraries? + +A44: This is much easier as of GLUT 3.7. Now, just edit the various + GLUT library Imakefiles (that is "lib/*/Imakefile") and set the + lines to say: + +#define DoNormalLib YES +#define DoSharedLib YES +#define DoDebugLib YES +#define DoProfileLib YES + + Change any of these to "NO" if you don't want the respective + type of library built. + + The do: + + cd lib + make clean + make Makefiles + make depend + make clean + make + + That's all there is to it. If you have problems with this procedure, + the most likely cause is that your Imake configuration files do not + have the appropriate rules for your compiler for building + shared/debug/profiling libraries. + + Check your Library.tmp file (often found in + /usr/lib/X11/config/Library.tmpl) if you have problems. + + (The previous README.linux and README.ibm-shlib files are + deprecated in favor of the advise above.) + +-- + +- Mark diff --git a/lib/glut-3.7.6/Glut.cf b/lib/glut-3.7.6/Glut.cf new file mode 100644 index 0000000000..34fd17a4ff --- /dev/null +++ b/lib/glut-3.7.6/Glut.cf @@ -0,0 +1,197 @@ +XCOMM Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. +XCOMM Glut.cf - GLUT distribution Imakefile configuration info + +/* LINUX USERS: Remove the "/* " characters in the #define line + below this comment in order to use Linux shared objects. */ +/* #define UseSharedObjects 1 /**/ + +/* MESA USERS: Remove the "/* " characters in the #define line + below this comment and change the "#define MesaDir" line to + match the top-level directory of your Mesa source tree. */ +/* #define UseMesa 1 /**/ +#define MesaDir /usr/Mesa-3.0 /* UPDATE ME! */ + +#ifdef UseMesa +XCOMM using Mesa (the freeware OpenGL implementation) by Brian Paul +MESA_DIR = MesaDir +MESA_INCLUDE = -I$(MESA_DIR)/include +MESA_LIB = -L$(MESA_DIR)/lib +MESAGL = $(MESA_LIB) -lMesaGL +MESAGLU = $(MESA_LIB) -lMesaGLU +#endif + +#ifndef MathLibrary /* introduced with X11R6 */ +#define MathLibrary -lm +#endif + +#ifndef SaberProgramTarget /* in X11R5 but removed in X11R6 */ +#define SaberProgramTarget(program,srclist,objlist,locallibs,syslibs) +#endif + +#ifdef SunArchitecture + +/* + * Solaris has a non-standard way of placing libraries + * and header files. This should work for Template Graphics Systems' + * OpenGL implementation, assuming your OGLHOME and OPENWINHOME + * environment variables are set correctly. + */ +EXTRA_INCLUDES = -I$(TOP)/include -I$(OGLHOME)/include -I$(OPENWINHOME)/include $(MESA_INCLUDE) +#ifdef UseMesa +OPENGL = $(MESAGL) +GLU = $(MESAGLU) +#else +OPENGL = -L$(OGLHOME)/lib -lGL -L$(OPENWINHOME) -ldga +GLU = -L$(OGLHOME)/lib -lGLU +#endif +/* XXX Is this right, Template?? */ +INVENTOR = -L$(OGLHOME)/lib -lInventor +GLUT_DEPLIBS = $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLUT_LIBS = $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +MUI_DEPLIBS = $(DEPMUI) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +MUI_LIBS = $(MUI) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLE_DEPLIBS = $(DEPGLE) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLE_LIBS = $(GLE) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLSMAP_DEPLIBS = $(DEPGLSMAP) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLSMAP_LIBS = $(GLSMAP) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary + +#else /* Everybody but Sun... */ +#ifdef AlphaArchitecture + +/* Alpha suggestions from Andrej Panjkov (mataap@pop.latrobe.edu.au). */ + +/* Andrej writes: There is a bug in one of the imake configuration + files supplied with Digital Unix 3.2c that will cause the build to + fail. In the file /usr/lib/X11/config/osflib.tmpl, the reference to + libXi.a should be changed to libXi.so (which is in the correct + directory /usr/shlib). Root access is needed to fix this bug. I + don't know if the bug persists in later versions of DU. */ + +#if 0 /* Not using now. */ +/* + * Digital puts all Imake symbols for use with OpenGL in OpenGL.tmpl, so use + * the contents of that file instead of the definitions here. + */ +#include +EXTRA_INCLUDES = GLUTInclude $(MESA_INCLUDE) +#else +EXTRA_INCLUDES = -I$(TOP)/include $(MESA_INCLUDE) +#endif + +INVENTOR = -lInventor + +/* Suggested by Andrej Panjkov (mataap@pop.latrobe.edu.au) */ +DEPGLUTLIB = $(TOP)/lib/glut/libglut.a +GLUTLIB = $(TOP)/lib/glut/libglut.a + +GLUT_LIBS = $(GLUTLIB) $(GLULIB) $(GLLIB) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLUT_DEPLIBS = $(DEPGLUTLIB) $(DEPGLULIB) $(DEPGLLIB) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +MUI_LIBS = $(MUI) $(GLUTLIB) $(GLULIB) $(GLLIB) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +MUI_DEPLIBS = $(DEPMUI) $(DEPGLUTLIB) $(DEPGLULIB) $(DEPGLLIB) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLE_LIBS = $(GLE) $(GLUTLIB) $(GLULIB) $(GLLIB) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLE_DEPLIBS = $(DEPGLE) $(DEPGLUTLIB) $(DEPGLULIB) $(DEPGLLIB) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLSMAP_LIBS = $(GLSMAP) $(GLUTLIB) $(GLULIB) $(GLLIB) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLSMAP_DEPLIBS = $(DEPGLSMAP) $(DEPGLUTLIB) $(DEPGLULIB) $(DEPGLLIB) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) + +#else /* Everybody but Sun or DEC Alpha... */ + +/* + * This should work for normal vendors that put their OpenGL and X + * libraries and headers in standard places (or at least where + * imake configuration files know where they are). + */ + +#ifdef HPArchitecture +/* Nate Robbins (E&S) reports that HP does not have its Xmu.h header in + the standard place. */ +XMU_HEADERS = /usr/contrib/X11R5/include/ +EXTRA_INCLUDES = -I$(TOP)/include -I$(XMU_HEADERS) $(MESA_INCLUDE) +#else +EXTRA_INCLUDES = -I$(TOP)/include $(MESA_INCLUDE) +#endif + +GLUT_DEPLIBS = $(DEPGLUT) $(DEPXMULIB) $(DEPXLIB) +GLUT_LIBS = $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XLIB) MathLibrary +#ifdef UseMesa +OPENGL = $(MESAGL) +GLU = $(MESAGLU) +#else +OPENGL = -lGL +GLU = -lGLU +#endif +INVENTOR = -lInventor +GLUT_DEPLIBS = $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLUT_LIBS = $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +MUI_DEPLIBS = $(DEPMUI) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +MUI_LIBS = $(MUI) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLE_DEPLIBS = $(DEPGLE) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLE_LIBS = $(GLE) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary +GLSMAP_DEPLIBS = $(DEPGLSMAP) $(DEPGLUT) $(DEPXMULIB) $(DEPXILIB) $(DEPXLIB) +GLSMAP_LIBS = $(GLSMAP) $(GLUT) $(GLU) $(OPENGL) $(XMULIB) $(XILIB) $(XLIB) MathLibrary + +#endif +#endif + +#ifdef UseSharedObjects +# for Linux shared objects + +#ifndef AlphaArchitecture +DEPGLUT = $(TOP)/lib/glut/libglut.so /* from PFM 6/31/96 */ +GLUT = $(TOP)/lib/glut/libglut.so /* from PFM 6/31/96 */ +#endif +DEPMUI = $(TOP)/lib/mui/libmui.so +MUI = $(TOP)/lib/mui/libmui.so +DEPGLE = $(TOP)/lib/gle/libgle.so +GLE = $(TOP)/lib/gle/libgle.so +DEPGLSMAP = $(TOP)/lib/glsmap/libglsmap.so +GLSMAP = $(TOP)/lib/glsmap/libglsmap.so + +#else +# for static objects + +#ifndef AlphaArchitecture +DEPGLUT = $(TOP)/lib/glut/libglut.a +GLUT = $(TOP)/lib/glut/libglut.a +#endif +DEPMUI = $(TOP)/lib/mui/libmui.a +MUI = $(TOP)/lib/mui/libmui.a +DEPGLE = $(TOP)/lib/gle/libgle.a +GLE = $(TOP)/lib/gle/libgle.a +DEPGLSMAP = $(TOP)/lib/glsmap/libglsmap.a +GLSMAP = $(TOP)/lib/glsmap/libglsmap.a + +#endif + +CXXEXTRA_INCLUDES = -I/usr/include/CC $(EXTRA_INCLUDES) $(MESA_INCLUDE) +GLUT_INVENTOR_DEPLIBS = $(GLUT_DEPLIBS) +GLUT_INVENTOR_LIBS = $(INVENTOR) $(GLUT_LIBS) + +#ifdef SGIArchitecture +/* For SGI C++ compiler, need to search extra dirs in make depend */ +#undef CplusplusDependIncludes +#define CplusplusDependIncludes -I$(ROOT)/usr/include/CC +#endif + +#ifndef NullParameter +/* + * NullParameter should be #define'ed to nothing in Imake.rules, but it has + * been reported to me that this is not always the case. If not, let + * Glut.cf #define it to nothing. + */ +#define NullParameter +#endif + +#define GlutTestProgramTarget(name) NormalProgramTarget(name,name.o,$(GLUT_DEPLIBS),$(GLUT_LIBS),NullParameter) +#define MuiTestProgramTarget(name) NormalProgramTarget(name,name.o,$(MUI_DEPLIBS),$(MUI_LIBS),NullParameter) +#define SimpleGlutProgramTarget(name) NormalProgramTarget(name,name.o,$(GLUT_DEPLIBS),$(GLUT_LIBS),NullParameter) +#define NormalGlutProgramTarget(name,objs) NormalProgramTarget(name,objs,$(GLUT_DEPLIBS),$(GLUT_LIBS),NullParameter) +#define SimpleMuiProgramTarget(name) NormalProgramTarget(name,name.o,$(MUI_DEPLIBS),$(MUI_LIBS),NullParameter) +#define NormalMuiProgramTarget(name,objs) NormalProgramTarget(name,objs,$(MUI_DEPLIBS),$(MUI_LIBS),NullParameter) +#define SimpleGleProgramTarget(name) NormalProgramTarget(name,name.o,$(GLE_DEPLIBS),$(GLE_LIBS),NullParameter) +#define NormalGleProgramTarget(name,objs) NormalProgramTarget(name,objs,$(GLE_DEPLIBS),$(GLE_LIBS),NullParameter) +#define SimpleGlsmapProgramTarget(name) NormalProgramTarget(name,name.o,$(GLSMAP_DEPLIBS),$(GLSMAP_LIBS),NullParameter) +#define NormalGlsmapProgramTarget(name,objs) NormalProgramTarget(name,objs,$(GLSMAP_DEPLIBS),$(GLSMAP_LIBS),NullParameter) +#define SimpleGlutInventorProgramTarget(name) NormalCplusplusProgramTarget(name,name.o,$(GLUT_INVENTOR_DEPLIBS),$(GLUT_INVENTOR_LIBS),NullParameter) +#define NormalGlutInventorProgramTarget(name,objs) NormalCplusplusProgramTarget(name,objs,$(GLUT_INVENTOR_DEPLIBS),$(GLUT_INVENTOR_LIBS),NullParameter) + +XCOMM end Glut.cf - GLUT distribution Imakefile configuration info diff --git a/lib/glut-3.7.6/IAFA-PACKAGE b/lib/glut-3.7.6/IAFA-PACKAGE new file mode 100644 index 0000000000..d201d716ae --- /dev/null +++ b/lib/glut-3.7.6/IAFA-PACKAGE @@ -0,0 +1,9 @@ +Title: OpenGL Utility Toolkit (GLUT) +Version: 3.7 +Description: A 3-D graphics library which uses the OpenGL API. +Author: Mark J. Kilgard mjk@nvidia.com +Maintained-by: Mark J. Kilgard mjk@nvidia.com +Maintained-at: http://reality.sgi.com/opengl/glut3/glut3.html +Platforms: Any Unix system with ANSI C and X and OpenGL or Mesa -OR- Windows 95 or NT PC. +Copying-Policy: Freely redistributable, not public domain, see NOTICE +Keywords: Mesa, OpenGL, GLUT, windowing library diff --git a/lib/glut-3.7.6/Imakefile b/lib/glut-3.7.6/Imakefile new file mode 100644 index 0000000000..c80a7d9090 --- /dev/null +++ b/lib/glut-3.7.6/Imakefile @@ -0,0 +1,7 @@ +#define IHaveSubdirs +#define PassCDebugFlags + +SUBDIRS = lib test progs + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) diff --git a/lib/glut-3.7.6/NOTICE b/lib/glut-3.7.6/NOTICE new file mode 100644 index 0000000000..60309d4dff --- /dev/null +++ b/lib/glut-3.7.6/NOTICE @@ -0,0 +1,15 @@ +NOTICE: The OpenGL Utility Toolkit (GLUT) distribution contains source +code published in a book titled "Programming OpenGL for the X Window +System" (ISBN: 0-201-48359-9) published by Addison-Wesley. The +programs and associated files contained in the distribution were +developed by Mark J. Kilgard and are Copyright 1994, 1995, 1996, 1997, 1998 +by Mark J. Kilgard (unless otherwise noted). The programs are not in the +public domain, but they are freely distributable without licensing +fees. These programs are provided without guarantee or warrantee +expressed or implied. + +I acknowledge the assistance provided by William Mitchell in developing +GLUT's "fbc" interface for use by the f90gl Fortran 90 binding. + +- Mark Kilgard + August 28, 1998 diff --git a/lib/glut-3.7.6/Portability.txt b/lib/glut-3.7.6/Portability.txt new file mode 100644 index 0000000000..e0663afcbd --- /dev/null +++ b/lib/glut-3.7.6/Portability.txt @@ -0,0 +1,135 @@ + +This note collects a bunch of portability issues that I've found in +ensuring that GLUT example source code is truly portable. I encourage +contributors to the GLUT source code distribution to review these +guidelines: + + o Avoid variables, routines, or structure elements named "new" or + "delete" to avoid these C++ keywords. + + o Avoid the "near" and "far" keywords introduced by Intel. Instead + try using "nnear" and "ffar" since these are common names in + graphics programming. + + o Do not assume the defines M_PI. Instead, after including + , say the following: + +----------------------------------------------------------------------- +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +----------------------------------------------------------------------- + + o If you use the GLU tessellator, when you define or declare + callback functions, use the "CALLBACK" calling convention + identifier. This is required for the callbacks to work correctly + under Win32. After including , say the following: + +----------------------------------------------------------------------- +/* Win32 calling conventions. */ +#ifndef CALLBACK +#define CALLBACK +#endif +----------------------------------------------------------------------- + + Then using a GLU tessellator begin callback as an example say: + +----------------------------------------------------------------------- +static void CALLBACK +begin(GLenum type, void *polyData) +{ + glBegin(type); +} +----------------------------------------------------------------------- + + When registering the callback, say: + + gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) &begin); + + o Avoid the floating point trig and exponential functions such as + "sinf", "cosf", "expf", etc. These functions are reserved by ANSI + C but not mandated. Instead use the double precision mandated + functions "sin", "cos", "exp", etc. Some systems also support + "fcos", "fsin", etc; definitely avoid these. + + o Do not use the EXIT_FAILURE and EXIT_SUCCESS constants defined by + ANSI C. Some old systems do not define these in stdlib.h but are + otherwise ANSI C compliant. Instead use "exit(1);" for failure + and "exit(0);" for success. + + o Use "rand" to generate random number. Do not use "random" or "drand48" + since they are not supported under Win32. + + o Avoid using "gettimeofday" or other system dependent routines to + determine a timestamp. Instead use + + timestamp = glutGet(GLUT_ELAPSED_TIME); + + o If you need to read a directory, check out the "win32_direct.h" + file used in progs/demos/walker/walker.c + + o Try to avoid including since it is not in Win32. + + o If your program runs in single buffered mode, be sure to call + glFlush() at the end of your display callback. Some OpenGL + implementations need a glFlush for pending graphics commands + to fully execute. Note that glutSwapBuffers performs an + implicit glFlush operation. + + o Avoid using strdup because strdup is not an actual ANSI C or + POSIX required routine. Indeed, OpenVMS does not support it. + And standard Linux libc only advertises strdup in string.h + if BSD or SVID routines are requested. Instead, directly include + the routine below: + +----------------------------------------------------------------------- +static char * +stralloc(const char *string) +{ + char *copy; + + copy = malloc(strlen(string) + 1); + if (copy == NULL) + return NULL; + strcpy(copy, string); + return copy; +} +----------------------------------------------------------------------- + + o Do not #include ; some platforms like IBM's AIX do not + have a getopt.h header file. Instead, you can portabily rely on + getopt() to be declared in on Unix machines. Still, + Win32 does not have a builtin getopt. + + o IBM's AIX defines "quad" to be a 64-bit type in . + Avoid using quad as a variable name. + + o HP's HP-UX 10.20 may have a type or otherwise define "time". + Avoid using time as a variable name. XXX GLUT doesn't do this + well currently. + + o GLU 1.2 introduced the types GLUquadric, GLUnurbs, and + GLUtesselator as aliases for the older GLUquadricObj, GLUnurbsObj, + and GLUtesselatorObj type names. Avoid the newer type names; use + the older names with the "Obj" suffix since all versions of GLU + support the Obj-suffixed types. (Note: yes, the GLU API has + GLUtesselatorObj is spelled incorrectly - tessellator should have + two l's.) + + o Do not include to get the standard C malloc/free + routines. Instead, include . FreeBSD and probably + other systems lack a . + + o Linux systems prototype a function called "idle" in . + This can result in an error in GLUT programs that name their + idle callback "idle" and include . Do no use a function + named idle if you include . + + o The SunOS 5.6 version of requires that also + be included because the assert() macro uses stderr. Be sure to + include along with everywhere to avoid + build errors on SunOS 5.6. + +- Mark Kilgard + October 17, 1998 diff --git a/lib/glut-3.7.6/README b/lib/glut-3.7.6/README new file mode 100644 index 0000000000..4dbf9730af --- /dev/null +++ b/lib/glut-3.7.6/README @@ -0,0 +1,186 @@ + +This directory and its subdirectories contains the OpenGL Utility +Toolkit (GLUT) distribution. See the NOTICE for legal terms. + +VERSION: + +Release 3.7, Novermber 22, 1998. + +SUPPORTED PLATFORMS: + +This distribution should compile for: + + o Microsoft Windows 95, Windows 98, or Windows NT with Microsoft + OpenGL 1.1 (bundled standard with these systems) or SGI OpenGL + for Windows (aka Cosmo OpenGL). + + o SGI workstation running IRIX 5.2 or higher supporting OpenGL, + including 64-bit and N32 support IRIX 6.1, 6.2, 6.3, 6.4, and + 6.5. + + o DEC Alpha workstation running OSF/1 and OpenVMS with Open3D + layered product. + + o IBM RS/6000 workstations running AIX with OpenGL support. + + o Metro Link's Metro OpenGL for Linux. + + o Sun's OpenGL implementation for its workstations or Template + Graphics Software's OpenGL for Sun workstations. + + o Mesa 3.x (and 2.x) for Unix workstations, including Linux PCs + and SunOS 4.1.x. + + o Most other Unix workstations supporting either OpenGL or Mesa. + +MICROSOFT WINDOWS 95 and NT BUILD INSTRUCTIONS: <-- IMPORTANT! + +Read the "README-win32.txt" accompanying file. + +MESA BUILD INSTRUCTIONS: <-- IMPORTANT! + +Mesa 3.x and higher provide an implementation of GLUT in Mesa's +"MesaDemos" source code distribution. The official GLUT source +code distribution may or may not be more current than the version +of the GLUT library included with the MesaDemos distribution. + +Please note that even though the MesaDemos distribution contains +the source code for the GLUT library, the many GLUT source code +examples and demos in the GLUT source code distribution are not +part of Mesa. + +To ease building the GLUT source code distribution for Mesa, +users, see the note in the Glut.cf file in this directory. If +you uncomment the line saying "#define UseMesa 1" and then +set the "MesaDir" #define to the location of your Mesa source +code distribution, GLUT should build easily with Mesa. + +MAKEFILE GENERATION TO BUILD GLUT: <-- IMPORTANT! + +Use "mkmkfiles.sgi" to put Makefiles using the SGI Makefile conventions +in place. Use "mkmkfiles.imake" to put Makefiles generated from +Imakefiles in place. Run one of these two commands in this directory, +then do a "make". + +FREQUENTLY ASKED QUESTIONS ABOUT GLUT: + +See FAQ.glut + +CONTENTS OVERVIEW BY DIRECTORY: + + GL - GLUT interface header files + + lib - source code for GLUT libraries + + glut - GLUT library implementation + + mui - Tom Davis's GLUT-based micro-UI user interface library + + gle - Linas Vepstas's GLE Tubing & Extrusions library + + fglut - GLUT FORTRAN bindings (IRIX only) + glut.n32 - "N32" version of the GLUT library (IRIX only). + fglut.n32 - "N32" version of the GLUT library (IRIX only). + glut.n64 - 64-bit version of the GLUT library (IRIX only). + fglut.n64 - 64-bit version of the GLUT library (IRIX only). + mui.n32 - "N32" version of micro-UI library (IRIX only). + mui.n64 - 64-bit version of micro-UI library (IRIX only). + gle.n32 - "N32" version of GLE Tubing & Extrusions library (IRIX only). + gle.n64 - 64-bit version of GLE Tubing & Extrusions library (IRIX only). + + test - test programs + + glut - GLUT library tests + + mui - micro-UI library test + + progs - programs using GLUT + + examples - misc. GLUT examples + + redbook - examples from the OpenGL Programming Guide ported to GLUT + + advanced - GLUT examples demonstrating advanced OpenGL rendering + techniques. The programs are largely based on the SIGGRAPH '96 + course taught by David Blythe and Tom McReynolds. + + contrib - contributed GLUT examples + + demos - more involved OpenGL demos using GLUT + + fortran - GLUT FORTRAN examples + + glc - An example of using OpenGL's Character Rendering API + included in IRIX 6.2 and beyond. + + inventor - Two GLUT-based Open Inventor examples. + + mesademos - Ports to GLUT of programs developed by Brian Paul + that are distributed with Mesa. + + texfont - Tools and demos for using texture mapped fonts. + + tiff - Examples of using Sam Leffler's libtiff library for + reading, display, and writing TIFF image files. + + ada - Examples using the GLUT ADA binding. + +DOCUMENTATION: + +See the other README files in this directory. There is a complete +specification for GLUT API version 3 in PostScript available by +anonymous ftp accompanying this distribution. GLUT includes a full set +of nroff man pages for the GLUT API version 3. nroff man pages for +GLE are also included. + +ACCOMPANYING DATA FILES: + +Another separate GLUT data distribution contains a "data" subdirectory +containing large data files used by some of the examples in the +"progs/advanced" subdirectory. See the file "progs/advanced/README" +for more details. + +GLUT MAILING LIST: + +To subscribe to the GLUT mailing list, send an electronic mail message +with the word "subscribe" in the first line of the message to +glut-request@perp.com Messages intended for the GLUT mailing list can +be sent to glut@prep.com + +A SHAMELESS BUT HOPEFULLY HELPFUL PLUG: + +I've written a book titled "Programming OpenGL for the X Window System" +(ISBN: 0-201-48359-9) published by Addison-Wesley. It includes both a +complete tutorial and documentation for GLUT, as well as a full +explanation of using OpenGL with the X Window System's Xlib and +Xt/Motif interfaces. If you use GLUT, I believe you'll find this +book very informative. See: + + http://reality.sgi.com/mjk/OpenGLforX.html + +BUG REPORTING: + +Send bug reports by electronic mail to mjk@nvidia.com (I now work +for NVIDIA Corporation, not Silicon Graphics). + +Questions of a general interest about GLUT will be answered on the +comp.graphics.api.opengl newsgroup. + +ACKNOWLEDGEMENTS: + +Much thanks to OpenGL engineers at DEC, IBM, Microsoft, SGI, Sun, and +TGS. Of particular mention are Brian Paul from the University of +Wisconsin, Nate Robins at the Univeristy of Utah, and Craig Groeschel +of Metro Link Inc. for helping me ensure the portability of this code +to non-SGI graphics platforms. Also thank you to GLUT users who +supplied me with feedback and bug fixes. + +Nate Robin's effort to combine his Win32 GLUT with GLUT 3.5 were most +excellent. Tom Davis contributed the micro-UI library. GLUT 3.5's +testing on PCs was greatly aided by Petri Nordlund, Brian Buchner, +Leath Muller, Stephen Speicher, and I've probably missed others. Henk +Kok is responsible for the several way cool demos in GLUT 3.5. Thanks +for your help! + +- Mark Kilgard + mjk@nvidia.com diff --git a/lib/glut-3.7.6/README-win32.txt b/lib/glut-3.7.6/README-win32.txt new file mode 100644 index 0000000000..67c8d413e0 --- /dev/null +++ b/lib/glut-3.7.6/README-win32.txt @@ -0,0 +1,613 @@ + + + GLUT for Win32 README + --------------------- + + +VERSION/INFO: + + This is GLUT for Win32 version 3.7.6 as of Nov 8th 2001. + See the COPYRIGHT section for distribution and copyright notices. + Send all bug reports and questions for this version of GLUT to + Nate Robins [nate@pobox.com]. + + For more information about GLUT for Win32, see the web page: + www.pobox.com/~nate/glut.html or subscribe to the GLUT for Win32 + mailing list by sending e-mail to majordomo@perp.com with + "subscribe glut" in the body of the message. + + For general information about GLUT, see the GLUT web page: + http://reality.sgi.com/opengl/glut3/glut3.html and be sure to + check the GLUT FAQ first for any questions that you may have: + http://reality.sgi.com/opengl/glut3/glut-faq.html + + +COMPILING/INSTALLATION: + + o Precompiled versions of the DLL and import library can be + found on the GLUT for Win32 web page mentioned above. + + o Microsoft Developer Studio 6 workspace and project files have + been included in the source code distribution. + + To build the glut dll: + First, open Microsoft Developer Studio. + Then, select File -> Open Workspace and find the glut.dsw file + in the file dialog and double-click on it. + Finally, select Build -> Build glut32.dll. + When the build is finished, it will copy: + glut32.dll to %WinDir%\System, + glut32.lib to $(MSDevDir)\..\..\VC98\lib, and + glut.h to $(MSDevDir)\..\..\VC98\include\GL. + + Additional workspace files have been included in the progs, test + and lib directories to build the progs, tests and libs respectively. + + +BORLAND NOTES: + + From what I understand, Borland supplies a utility that + converts Microsoft Visual C++ .libs into Borland compatible + files. Therefore, the best method for Borland users is + probably to get the precompiled versions of the library and + convert the library. To create an import library for Borland + from the DLLs, use the following command (from a command prompt): + IMPLIB glut32.lib glut32.dll + If IMPLIB crashes when called this way, try + IMPLIB glut32.lib glut32.def + using the glut32.def file in this distribution. + + +FORTRAN NOTES: + + Bill Mitchell [william.mitchell@nist.gov] has put considerable + effort into getting GLUT to work with different compilers for + Fortran 90. He indicates that you should copy the f90glut.h + file to your $(MSDevDir)\..\..\VC98\include\GL directory. + Then, just build GLUT as usual. The Fortran 90 interface, f90gl, + can be obtained at http://math.nist.gov/f90gl and contains + installation instructions and usage examples. + + +MISC NOTES: + + o Overlay support is not implemented, nor are there any plans to + implement it in the near future. + + o To customize the windows icon, you can use the resource name + GLUT_ICON. For example, create an icon named "glut.ico", and + create a file called glut.rc that contains the following: + GLUT_ICON ICON glut.ico + then compile the glut.rc file with the following: + rc /r glut + and link the resulting glut.res file into your executable + (just like you would an object file). + Alternatively, you can simply add the glut.rc file to your + project if you are using Microsoft Developer Studio. + + +IMPLEMENTATION DEPENDENT DIFFERENCES: + + There are a few differences between the Win32 version of GLUT + and the X11 version of GLUT. Those are outlined here. Note + that MOST of these differences are allowed by the GLUT + specification. Bugs and unsupported features are outlined in + the UNSUPPORTED/BUGS section. + + o glutInit: + The following command line options have no meaning (and are + ignored) in GLUT for Win32: + -display, -indirect, -direct, -sync. + + o glutInitWindowPosition, glutPositionWindow: + Win32 has two different coordinate systems for windows. + One is in terms of client space and the other is the whole + window space (including the decorations). If you + glutPositionWindow(0, 0), GLUT for Win32 will place the + window CLIENT area at 0, 0. This will cause the window + decorations (title bar and left edge) to be OFF-SCREEN, but + it gives the user the most flexibility in positioning. + HOWEVER, if the user specifies glutInitWindowPosition(0, 0), + the window is placed relative to window space at 0, 0. + This will cause the window to be opened in the upper left + corner with all the decorations showing. This behaviour is + acceptable under the current GLUT specification. + + o glutSetIconTitle, glutSetWindowTitle: + There is no separation between Icon title and Window title + in Win32. Therefore, setting an icon title in Win32 has + no effect. + + o glutSetCursor: + As indicated in the GLUT specification, cursors may be + different on different platforms. This is the case in GLUT + for Win32. For the most part, the cursors will match the + meaning, but not necessarily the shape. Notable exceptions + are the GLUT_CURSOR_INFO & GLUT_CURSOR_SPRAY which use the + crosshair cursor and the GLUT_CURSOR_CYCLE which uses the + 'no' or 'destroy' cursor in Win32. + + o glutVisibilityFunc: + Win32 seems to be unable to determine if a window is fully + obscured. Therefore, the visibility of a GLUT window is + only reflected by its Iconic, Hidden or Shown state. That + is, even if a window is fully obscured, in GLUT for Win32, + it is still "visible". + + o glutEntryFunc: + Window Focus is handled differently in Win32 and X. + Specifically, the "window manager" in Win32 uses a "click to + focus" policy. That is, in order for a window to receive + focus, a mouse button must be clicked in it. Likewise, in + order for a window to loose focus, a mouse button must be + clicked outside the window (or in another window). + Therefore, the Enter and Leave notification provided by GLUT + may behave differently in the Win32 and in X11 versions. + There is a viable workaround for this. A program called + "Tweak UI" is provided by Microsoft which can be used to + change the focus policy in Win32 to "focus follows mouse". + It is available from the Microsoft Web Pages: + http://www.microsoft.com/windows/software/PowerToy.htm + + o glutCopyColormap: + GLUT for Win32 always copies the colormap. There is never + any sharing of colormaps. This is probably okay, since + Win32 merges the logical palette and the physical palette + anyway, so even if there are two windows with totally + different colors in their colormaps, Win32 will find a + (hopefully) good match between them. + + o glutIdleFunc + menus: + The glut idle function will NOT be called when a menu is + active. This causes all animation to stop when a menu is + active (in general, this is probably okay). Timer + functions will still fire, however. If the timer callback + draws into the rendering context, the drawing will not show + up until after the menu has finished, though. + + +UNSUPPORTED/BUGS: + + o glutAttachMenu: + Win32 only likes to work with left and right mouse buttons. + Especially so with popup menus. Therefore, when attaching + the menu to the middle mouse button, the LEFT mouse button + must be used to select from the menu. + + o glutSpaceball*, glutButtonBox*, glutTablet*, glutDials*: + None of the special input devices are supported at this + time. + + o When resizing or moving a GLUT for Win32 window, no updating + is performed. This causes the window to leave "tracks" on + the screen when getting bigger or when previously obscured + parts are being revealed. I put in a bit of a kludgy + workaround for those that absolutely can't have the weird + lines. The reshape callback is called multiple times for + reshapes. Therefore, in the reshape callback, some drawing + can be done. It should probably be limited to a color buffer + clear. + + o The video resizing capabilities of GLUT 3.3+ for X11 is + currently unimplemented (this is probably ok, since it + really isn't part of the spec until 4.0). I doubt that + this will ever be part of GLUT for Win32, since there is no + hardware to support it. A hack could simply change the + resolution of the desktop. + + +CHANGES/FIXES: + + (Nov 8, '01) + x Released 3.7.6 + + (Nov 8, '01) + x Changed fullscreen mode from TOPMOST back to simply TOP, since + (it turns out) many people use windows atop a GLUT window. + + (Nov 8, '01) + x Added code to prevent CPU spiking when no idle function is + registered. Otherwise, if an idle function is registered, spike + CPU so that the idle function gets all the attention it needs and + if this is a problem on the program side, the user can stick a + sleep() in their idle function. I believe that this strikes the + best balance betweeen GLUT being fast, and also being "nice" to + other processes. Thanks to James Wright for reporting this bug. + + (Nov 8, '01) + x Fixed bug in motion callback handler which wasn't setting the + current window, so multiple window apps (e.g., any GLUI app) + wouldn't get the callback correctly. + + (Oct 4, '01) + x Fixed bug in glutEnterGameMode() that caused new windows to not + be in "fullscreen" mode, so they got window decorations. + + (Oct 4, '01) + x Fixed bug in glutEnterGameMode() that caused new windows to not + be in "fullscreen" mode, so they got window decorations. + + (Oct 3, '01) + x Fixed bug in getVisualInfoFromString(): visuals not reloaded on + display mode change. Reload visuals each time they are queried. + This fixes a problem with Win32 because the list of availabe Visuals + (Pixelformats) changes after a change in displaymode. The problem + occurs when switching to gamemode and back. Thanks to Michael + Wimmer for pointing this out & providing the fix. + + (Oct 3, '01) + x Fixed bug in XGetVisualInfo(): pixelformats enumerated incorrectly. + Passing 0 as a pixelformat index to DescribePixelFormat gives + unpredictible results (e.g., this fails on the Voodoo opengl32.dll + and always reports 0 as the last available pixelformat index). + Thanks to Michael Wimmer for pointing this out & providing the fix. + + (Oct 3, '01) + x Fixed bug in glXGetConfig(): pixelformats enumerated incorrectly. The + test was OpenGL support OR draw to window, but should be AND. Thanks + to Michael Wimmer for pointing this out & providing the fix. + + (Sep 28, '01) + x Fixed glutChangeToSubMenu()/glutChangeToMenuEntry() bug where if you + went back and forth between a submenu and a plain entry, the submenu + wouldn't be updated properly. + + (Sep 28, '01) + x glutSetIconTitle() is now a nop. + + (Sep 28, '01) + x glutFullScreen() now sets the window as TOPMOST, therefore, the + window will always be on top (this essentially disables alt-tabbing). + + (Sep 28, '01) + x The key repeat ignore flag is now honored correctly. + + (Sep 28, '01) + x Key presses are now reported more accurately and fully, in + particular, modified up events (i.e., SHIFT-2) are now reported + correctly. + + (Sep 28, '01) + x Subwindows nested arbitrarily deep get their keyboard callbacks + correctly now. + + (Sep 28, '01) + x Major rewrite of the window procedure code to clean it up and make + way for other bug fixes. + + (Sep 23, '01) + x Fixed noof example program to use RAND_MAX instead of assumed + max of 2147483647.0. (Now it looks _much_ better!) + + (Sep 22, '01) + x Fixed sunlight example program. globe.raw data file was corrupt, + added a new one. + + (Sep 22, '01) + x Fixed zcomposite example program to print message if overlay + support is not found (instead of crashing). + + (Jan 22, '01) + x Fixed malloc(0) bug in Win32 version of XGetVisualInfo. Thanks + to Kekoa Proudfoot for bringing this to my attention. + + (Dec 12, '00) + x Added data files for the advanced & advanced97 programs. + + (Dec 12, '00) + x Added Developer Studio 6 project and workspace files for pretty + much everything (the stuff left out was usually unix specific). + + (Dec 7, '00) + x Fixed several compilation problems & corrupt files. Thanks to + Alexander Stohr for bringing these to my attention and providing + detailed fixes. + + (Dec 6, '00) + x Fixed compiler support for lcc. Thanks to Gordon for bringing + this to my attention and debugging fixes. + + (Nov 8, '00) + x Fixed submenu problem (sometimes the menu callback was not + called for valid items). Thanks to Michael Keeley. + + (Oct 16, '00) + x Corrected corrupt duck.iv file. Thanks to Jon Willeke for finding + this problem. + + (Sept 27, '00) + x Fixed bug in processWorkList that could cause a hang. Thanks to + Bill Volz & Daniel Azuma. + + (Sept 26, '00) + x Added mui DLL project file (thanks to DMWeldy@ugsolutions.com). + + (Sept 9, '00) + x Fixed Delete key bug (crash when no keyboard callback was + registered, but a special key callback was). Thanks to + Kent Bowling (kent_bowling@hotmail.com) for finding this bug. + + (May 18, '00) + x Fixed subwindow keyboard callbacks. + + (May 22, '97) + o Menus don't work under Windows 95 + x Fixed! Added a unique identifier to each menu item, and a + search function to grab a menu item given the unique identifier. + + (May 21, '97) + o A few minor bug fixes here and there. + x Thanks to Bruce Silberman and Chris Vale for their help with + this. We now have a DLL! + + (Apr 25, '97) + o DLL version of the library is coming (as soon as I figure out + how to do it -- if you know, let me know). + x Thanks to Bruce Silberman and Chris Vale for their help with + this. We now have a DLL! + + (Apr 24, '97) + x Added returns to KEY_DOWN etc messages so that the F10 key + doesn't toggle the system menu anymore. + + (Apr 7, '97) + o Palette is incorrect for modes other than TrueColor. + x Fixed this by forcing a default palette in modes that aren't + Truecolor in order to 'simulate' it. The applications + program shouldn't have to do this IMHO, but I guess we + can't argue with Microsoft (well, we can, but what good + will it do?). + + (Apr 2, '97) + x Added glut.ide file for Borland users. + + (Apr 2, '97) + x Fixed a bug in the WM_QUERYNEWPALETTE message. Wasn't + checking for a null colormap, then de-ref'd it. Oops. + + (Mar 13, '97) + o glutTimerFunc: + Currently, GLUT for Win32 programs busy waits when there is + an outstanding timer event (i.e., there is no select() + call). I haven't found this to be a problem, but I plan to + fix it just because I can't bear the thought of a busy wait. + x Added a timer event and a wait in the main loop. This fixes + the CPU spike. + + (Mar 11, '97) + x Fixed subwindow visibility. The visibility callback of + subwindows wasn't being called, now it is. + + (Mar 11, '97) + o glutGetHDC, glutGetHWND: + In order to support additional dialog boxes, wgl fonts, and + a host of other Win32 dependent structures, two functions + have been added that operate on the current window in GLUT. + The first (glutGetHDC) returns a handle to the current + windows device context. The second (glutGetHWND) returns + handle to the current window. + x Took these out to preserve GLUT portability. + + (Mar 11, '97) + x Fixed the glutWarpPointer() coordinates. Were relative to + the screen, now relative to window (client area) origin + (which is what they're supposed to be). + + (Mar 11, '97) + o glutCreateMenu, glutIdleFunc: + Menu's are modal in Win32. That is, they don't allow any + messages to be processed while they are up. Therefore, if + an idle function exists, it will not be called while + processing a menu. + x Fixed! I've put in a timer function that fires every + millisecond while a menu is up. The timer function handles + idle and timer events only (which should be the only + functions that are firing when a menu is up anyway). + + (Mar 7 '97) + x Fixed minor bugs tracked down by the example programs. + + (Mar 6, '97) + x Merged 3.3 GLUT for X11 into 3.2 GLUT for Win32. New code + structure allows for EASY merging! + + o In Win32, the parent gets the right to set the cursor of + any of its children. Therefore, a child windows cursor + will 'blink' between its cursor and its parent. + x Fixed this by checking whether the cursor is in a child + window or not. + + (Feb 28 '97) + o On initial bringup apps are getting 2 display callbacks. + x Fixed by the Fev 28 re-write. + + o Some multiple window (not subwindow) functionality is messed up. + See the sphere.exe program. + x Fixed by the Feb 28 re-write. + + o GLUT for Win32 supports color index mode ONLY in a paletted + display mode (i.e., 256 or 16 color mode). + x Fixed this in the re-write. If you can get a color index + visual (pixel format) you can use color index mode. + + (Feb 28 '97) + o Quite a few bugs (and incompatibilities) were being caused + by the structure that I used in the previous port of GLUT. + Therefore I decided that it would be best to "get back to + the roots". I re-implemented most of glut trying to stick + with the structure layed out by Mark. The result is a much + more stable version that passes ALL (!) (except overlay) + the tests provided by Mark. In addition, this new + structure will allow future enhancements by Mark to be + integrated much more quickly into the Win32 version. Also, + I'm now ordering the bugs in reverse, so that the most + recently fixed appear at the top of the list. + + (9/8/96) + o Changed the glutGetModifiers code to produce an error if not + called in the core input callbacks. + + (9/11/96) + o If the alt key is pressed with more than one other modifier key + it acts as if it is stuck -- it stays selected until pressed + and released again. + x Fixed. + + (9/12/96) + o When a submenu is attached to a menu, sometimes a GPF occurs. + Fixed. Needed to set the submenu before referencing it's members. + + o Kenny: Also, one little problem, I attached the menu to the + right-button, but when the left-button is pressed I detach + it to give the right-button new meaning; if I pop-up the menu and I + don't want to select anything, like most users, I click off of the + menu to make it disappear. When I do this, I get a GLUT error and + the program terminates because I am altering the menu attachment + from within the button press while the menu is active. + x Fixed. Needed to finish the menu when the user presses the button, + not just when a button is released. + + o GLUT for Win32 emulates a middle mouse button by checking if + both mouse buttons are down. This causes a lot of problems with + the menu and other multiple mouse button things. + x Fixed. No more middle mouse button emulation. Perhaps it would + be a good idea to emulate the middle mouse button (if not present) + with a key? + + (9/15/96) + o Added code to accept a user defined icon. If no icon is provided, + a default icon is loaded. + + (9/19/96) + o Shane: Command line options seem to be screwed up. (9/13) + x Fixed. The geometry command line was broken, and so was the + gldebug command line. + + o Fixed a bug in the default glut reshape. It was looking for the + parent of the current window and GPF'ing if there wasn't a parent. + Put in a check for a parent, and if none is there, use the + child. + + o Idle function sucks up all processor cycles. (9/8/96) + x I don't know if this is avoidable. If you have a tight rendering + loop, it may be that the processor time is going to be sucked up + no matter what. You can add a sleep() to the end of your render + loop if you would like to yeild to other processes and you don't + care too much about the speed of your rendering loop. If you have + Hardware that supports OpenGL (like a 3Dpro card, or GLint card) + then this should be less of a problem, since it won't be rendering + in software. (9/11/96) + + o If a window is fully obscured by another window, the visibility + callback is NOT called. As far as I can tell, this is a limitation + of the Win32 api, but a workaround is being searched for. (9/8/96) + x Limitation of the Win32 API + + o Fixed the entry functions. They only work if the keyboard focus + changes. Therefore, in most Win32 systems, the mouse must be + pressed outside of the window to get a GLUT_LEFT message and + then pressed inside the window for a GLUT_ENTERED message. + + o Alt modifier key doesn't work with keyboard callback. (9/8/96) + x Probably okay, because the glut spec says that these keys can + be intercepted by the system (which the alt key is...) (9/11/96) + + (11/17/96) + o glutRemoveMenuItem() not working properly. + x Thanks to Gary (grc@maple.civeng.rutgers.edu) for the fix to + this one. + + o Timer functions are messed up. + x Thanks to Joseph Galbraith for the fix to this one. + + (12/9/96) + o One (minor) difference came up between the X version of glut + and the nt one which you should know about. It is not a new + problem, and it concerns co-ords returned to the pointer + callbacks. (glutMotionFunc, glutMouseFunc) + Under X, you get co-ords in the range 0 +/- 2^15, under NT + you get 0..2^16. This is only really a problem when moving + above or to the left of the window. + eg dragging one pixel ABOVE the window will give :- + under x11 : y = -1 + under nt : y = 2^16 -1 + x Put in fix provided by Shane Clauson. + + (12/17/96) + o Idle functions not working properly for multiple windows. + x Fixed this by posting an idle message to every window in the + window list when idle. + + (12/18/96) + o glutSetCursor() was misbehaving (lthomas@cco.caltech.edu). + x Win32 requires that the hCursor member of the window class + be set to NULL when the class is registered or whenever the + mouse is moved, the original cursor is replaced (go + figure!). Now sets the cursor whenever a WM_MOUSEMOVE message + is received, because the WM_SETCURSOR event resets the cursor + even when in the decoration area. + + o Geometry is not being handled quite right. The numbers don't + take into account the window decorations. That is, if I say + make a window 100x100, then the WHOLE window (not just the + client area) is 100x100. Therefore, the client (opengl) area + is smaller than 100x100. (9/8/96) + x Fixed. Added code to subtract the decoration size on glutGet() + and add the decoration size on glutReshapeWindow(). + + o Multiple glutPostRedisplay() calls are NOT being combined. + To get round the "coalesce" problem on glutPostRedisplay, + the easiest solution is to roll-your-own coalesce by + keeping a global "dirty" flag in the app (eg replace all + calls to glutPostRedisplay with image_dirty=TRUE;), and to + handle image_dirty with a single glutPostRedisplay in the + idle callback when required. (erk - but increases + performance for my particular app (a rendering engine on + the end of a pipleine with a stream of graphics updates) by + a couple of orders of magnitude ! ) (9/8/96) + x Added code to coalesce redisplays. Every idle cycle, a + check is made to see which windows need redisplay, if they + need it, a redisplay is posted. The glutPostRedisplay() + call is just a stub that sets a flag. + + +THANKS: + + Special thanks to the following people for extensive testing, + suggestions, fixes and help: + + Alexander Stohr + Shane Clauson + Kenny Hoff + Richard Readings + Paul McQuesten + Philip Winston + JaeWoo Ahn + Joseph Galbraith + Paula Higgins + Sam Fortin + Chris Vale + Bill Mitchell + + and of course, the original author of GLUT: + Mark Kilgard. + + and many others... + + +COPYRIGHT: + +The OpenGL Utility Toolkit distribution for Win32 (Windows NT & +Windows 95) contains source code modified from the original source +code for GLUT version 3.3 which was developed by Mark J. Kilgard. The +original source code for GLUT is Copyright 1997 by Mark J. Kilgard. +GLUT for Win32 is Copyright 1997 by Nate Robins and is not in the +public domain, but it is freely distributable without licensing fees. +It is provided without guarantee or warrantee expressed or implied. +It was ported with the permission of Mark J. Kilgard by Nate Robins. + +THIS SOURCE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +OpenGL (R) is a registered trademark of Silicon Graphics, Inc. diff --git a/lib/glut-3.7.6/README.ada b/lib/glut-3.7.6/README.ada new file mode 100644 index 0000000000..308495c9ad --- /dev/null +++ b/lib/glut-3.7.6/README.ada @@ -0,0 +1,42 @@ + +GLUT 3.4 was the first release of GLUT to support an Ada language +binding for SGI's Ada run-time and development environment. (With a +bit of work, GLUT could probably be easily be adapted to other Ada +development environments, assuming the environment already has an +OpenGL binding.) + +To use the SGI Ada binding, please make sure that the following GNAT +(SGI's Ada compiler) subsystems are installed on your system: + + Ada Execution-only Environment (eoe) + ------------------------------------- + gnat_eoe.sw.lib + + Ada Development Option (dev) + ----------------------------- + gnat_dev.bindings.GL + gnat_dev.bindings.std + gnat_dev.lib.src + gnat_dev.lib.obj + gnat_dev.sw.gnat + +The GLUT Ada binding was developed and tested with the IRIX 5.3 and 6.2 +gnat_dev and gnat_eoe images (v3.07, built 960827). + +Some fairly simple GLUT examples written in Ada can be found in the +progs/ada subdirectory. GLUT 3.6 expanded the number of Ada example +programs included in the GLUT source code distribution. GLUT's actual +Ada binding is found in the adainclude/GL subdirectory. + +To build the Ada binding and example programs, first build GLUT +normally, then: + + cd adainclude/GL + make glut.o + cd ../../progs/ada + make + +Good luck! + +- Mark Kilgard + November 12, 1997 diff --git a/lib/glut-3.7.6/README.fortran b/lib/glut-3.7.6/README.fortran new file mode 100644 index 0000000000..e9f9771bd8 --- /dev/null +++ b/lib/glut-3.7.6/README.fortran @@ -0,0 +1,190 @@ +GLUT Fortran users, + +BUILD INSTRUCTIONS +=================== + +To build the GLUT Fortran API, do the following: + + 1) Make sure you are running IRIX 5.3, 6.1, or 6.2 or higher on + a Silicon Graphics workstation. + + >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + If you are not on an SGI workstation, I suggest you try out + the f90gl, a public domain implementation the official Fortran + 90 bindings for OpenGL. See the web site at: + + http://math.nist.gov/f90gl/ + + f90gl implements a Fortran 90 interface for OpenGL 1.1, GLU 1.2, + GLUT 3.7, and several extensions. f90gl supports both Unix + workstations, Linux PCs, and Windows 95/NT PCs. + + William Mitchell deserves special credit for developing the + f90gl implementation and pushing for a standard OpenGL + Fortran 90 binding. + + Also, note that GLUT 3.7 has a new "friend" interface for use + by f90gl to ensure future interoperability between f90gl + and future GLUT revisions. + <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + 2) Make sure you have Fortran compilers and OpenGL Fortran + libraries installed (make sure you have the right support + installed for the "object style" you wish to build). + + The following Fortran subsystems are particularly important + to have installed: + + ftn77_dev.sw.util -- utiles for building Fortran to C bindings + gl_dev.sw.fortran -- OpenGL Fortran binding libraries + + 3) Run "mkmkfiles.sgi" in this directory. + + 4) Make sure you have built the "lib/glut" and "lib/fglut" + directories: + + (cd lib/glut; make) + (cd lib/fglut; make) + + 5) Change to one of the GLUT Fortran library directories, + depending on what "object style" you wish to build: + + O32 (old 32-bit ABI) - "cd lib/fglut" + N64 (new 64-bit ABI) - "cd lib/fglut.n64" (IRIX 6.1 & 6.2 only) + N32 (new 32-bit ABI) - "cd lib/fglut.n32" (IRIX 6.2 only) + + (If you are building a given "object style", make sure you + build the accompanying GLUT library implementation. See + README.irix6) + + 6) Execute "make" in the directory. + +NOTES +====== + +All GLUT functionality is available through the GLUT Fortran API. + +A number of example GLUT Fortran examples are built in the directory as +examples of how to write GLUT Fortran programs. + +There are a number of caveats to using the GLUT Fortran API: + + o The GLUT Fortran API is not built by default. + + See the build instructions above. You will need the IRIX Fortran + development option installed. + + o The implementation of the GLUT Fortran API is probably only useful + to IRIX users because the generation of Fortran-to-C wrappers is + inherently dependent on vendor-dependent calling convention + dependencies. + + o The IRIX GLUT Fortran API is implemented as a set of wrappers to + to the GLUT C implementation. As such, there is a very slight + overhead to calling OpenGL routine through the GLUT Fortran + binding (this applies to the OpenGL Fortran wrapper routines as + well). + + o The ARB's official OpenGL Fortran API prefixes every routine and + constant with the letter F. The justification was to avoid name + space collisions with the C names. Nearly all modern Fortran + compilers avoid these name space clashes via other means (underbar + suffixing of Fortran routines is used by most Unix Fortran + compilers). + + The GLUT Fortran API does _not_ use such prefixing conventions + because of the documentation and coding confusion introduced by + such prefixes. Bending over backwards to support anachronistic + compliers does not justify this confusion. + + While the official OpenGL Fortran API, prefixes both routine and + constant names, there is no technical justification for prefixing + constant names. In practice, it creates a reasonable amount of + coding and documentation confusion (the confusion is heightened by + Fortran's default implicit variable initialization so you don't + realize the lack of a constant prefix until run-time) and pushes + names one character towards identifier limits. + + The GLUT distribution supplies its own version of "GL/fgl.h" and + "GL/fglu.h" which does not F-prefix constants. GLUT users are + encouraged to not use the F-prefixed constants. (The GLUT + supplied "GL/fgl.h" also works around problems discussed in the + next bullet.) + + Perhaps the OpenGL ARB will reconsider the F-prefix or (as an + unfortunate compromise) support both F prefixed and non F prefixed + constant names. + + o A OpenGL Fortran API implementation was released with IRIX 5.3 + (it was not previously available in IRIX). While the Fortran + wrappers work, there are a number of difficulties with using the + IRIX 5.3 OpenGL Fortran bindings: + + + Make sure you have the "Fortran 77 OpenGL Graphic Library" + subsystem installed. Its name is: ftn_dev.sw.opengl + + + The OpenGL Fortran man pages incorrectly document a number of + calls taking REAL*4 (real) parameters when they in fact + require REAL*8 (double precision) parameters. An example is + fglviewport. Any OpenGL (or GLU) routine that takes double's + as parameters in the C API, takes REAL*8's in the Fortran + API. Be very careful to use the dble intrinsic whenever + passing non-REAL*8 values to such routines! + + + The OpenGL Fortran man pages also do not add the F-prefixes + to constants discussed in the man pages. Because GLUT + supplies a "GL/fgl.h" without F-prefixes, this should be a + "good thing." + + + The "GL/fgl.h" header file describing the OpenGL Fortran API + contains identifiers over 32 characters long. While the MIPS + Fortran compiler should treat this as a soft warning and + truncate the identifiers to 32 characters, the compiler + generates a fatal error. For this reason, the "GL/fgl.h" in + this distribution has truncated by hand the "GL/fgl.h" + identifiers over 32 characters to 32 characters. + + o IRIX 6.2's OpenGL Fortran binding was quite bungled and is + basically unusable. + + A workaround for this problem is to compile your OpenGL Fortran + programs with the compiler option "-Wl,-ignore_unresolved". This + tells the compiler to ignore unresolved symbols. + + Then, when you run the OpenGL Fortran binaries, tell the run-time + linker (rld) to ignore unresolved symbols like this: + + setenv _RLD_ARGS -ignore_unresolved + + SGI patches 1892 (IRIX 6.3 and 6.4 OpenGL Fortran bindings) and + 2360 (IRIX 6.2 OpenGL Fortran bindings) should fix problems in the + OpenGL Fortran binding library. + + o Because GLUT fonts are compiled into programs and programs + should only have the fonts compiled into them that they use, + GLUT font names like GLUT_BITMAP_TIMES_ROMAN_24 are really + symbols so the linker should only pull in used fonts. + Unfortunately, if a data symbol is declared EXTERNAL, the + IRIX Fortran compiler pulls in the symbol whether the symbol + is used or not. For this reason, "GL/fglut.h" does not + explictly declare EXTERNAL the GLUT font symbols. GLUT + Fortran programmers should explicitly declare EXTERNAL + the GLUT fonts they use. + + o Neither the MicroUI (mui) or Tubing and Extrusion library (gle) + have Fortran bindings. + +INSTALLATION +============= + +If you want to install the resulting archives into the right system +library directories, do the following: + + FOR N32: cp lib/fglut.n32/libfglut.a /usr/lib32 + + FOR N64: cp lib/fglut.n64/libfglut.a /usr/lib64 + +Also, make sure to install the GLUT library implementation versions for +the given object style too. + +- Mark Kilgard diff --git a/lib/glut-3.7.6/README.glut2 b/lib/glut-3.7.6/README.glut2 new file mode 100644 index 0000000000..11d0ce2f2b --- /dev/null +++ b/lib/glut-3.7.6/README.glut2 @@ -0,0 +1,84 @@ + +CHANGES for GLUT API version 2 +------------------------------- + +GLUT API version 2 should be fully compatible with the GLUT API +version 1. + +Here are the GLUT API version 2 additions in more detail: + + GLUT_MULTISAMPLE - a display mode bit mask for requesting + multi-sampling (hw anti-aliasing) available for Reality Engine + class graphics hardware (IRIX 5.3 has multi-sampling GLX + extension). + + GLUT_STEREO - a display mode bit mask for requesting + a stereo (quad buffering) OpenGL visual. + + glutGet(GLUT_WINDOW_NUM_SAMPLES) - returns number of + samples for multisampling for the window. + + glutGet(GLUT_WINDOW_STEREO) - boolean for it window supports + stereo. + + glutGet(GLUT_ELAPSED_TIME) - an OS-portable way to + get the elapsed time in milliseconds since glutInit + + glutDeviceGet(GLUT_HAS_KEYBOARD) - if keyboard supported. + + glutDeviceGet(GLUT_HAS_MOUSE) - if mouse supported. + + glutDeviceGet(GLUT_HAS_SPACEBALL) - if spaceball supported. + + glutDeviceGet(GLUT_HAS_DIAL_AND_BUTTON_BOX) - if dial and + button box supported. + + glutDeviceGet(GLUT_HAS_TABLET) - if tablet supported. + + glutDeviceGet(GLUT_NUM_MOUSE_BUTTONS) - number of mouse + buttons supported. + + glutDeviceGet(GLUT_NUM_SPACEBALL_BUTTONS) - number of + spaceball buttons supported. + + glutDeviceGet(GLUT_NUM_BUTTON_BOX_BUTTONS) - number of + button box buttons supported. + + glutDeviceGet(GLUT_NUM_DIALS) - number of dials supported. + + glutDeviceGet(GLUT_NUM_TABLET_BUTTONS) - number of table + buttons supported. + + glutSpecialFunc - register callback for keyboard function + and directional keys. + + glutSpaceballMotionFunc - register callback for spaceball + motion. + + glutSpaceballRotateFunc - register callback for spaceball + rotations. + + glutSpaceballButtonFunc - register callback for spaceball + button events. + + glutButtonBoxFunc - register callback for button box button + events. + + glutDialsFunc - register callback for dial motion. + + glutTabletMotionFunc - register callback for tablet motion. + + glutTabletButtonFunc - register callback for tablet button + events. + + glutExtensionSupported - report if a given OpenGL extension + is supported. + +Also there are a handful of minor bug fixes (of course). + +The stereo and multisampling stuff is probably (for now) interesting +mainly to Reality Engine graphics users. The new device support uses +the X Input extension. It works with SGI versions of the devices. I'm +investigating how portable the current code is for other vendor's +advertising of their similar X Input devices. + diff --git a/lib/glut-3.7.6/README.glut3 b/lib/glut-3.7.6/README.glut3 new file mode 100644 index 0000000000..c4b17a6759 --- /dev/null +++ b/lib/glut-3.7.6/README.glut3 @@ -0,0 +1,114 @@ + +CHANGES for GLUT API version 3 +------------------------------- + +GLUT API version 3 should be (almost) fully compatible with the +GLUT API version 2. See the GLUT 3 specification for full details. + +Please be aware of two obscure reasons that programs that worked +under GLUT API version 2 may need slight modification for GLUT 3. + + 1) You are now _required_ to have a display callback registered + for any GLUT window displayed to the screen. Otherwise a + fatal error is generated. It would be a bug in your program + otherwise! In conjunction with this, you can no longer + call glutDisplayFunc(NULL) to unregister a display callback. + + 2) It is a fatal error now to modify a GLUT pop-up menu while + menus are in use. There were too many semantic problems with + changing menus that may be currently displayed. To determine + if menus are in use, you can use the "menu use" callback registered + with glutMenuStatusFunc + +Here are the GLUT API version 3 additions in more detail: + + void glutSetCursor(int cursor) + int glutGet(GLUT_WINDOW_CURSOR) + + Provides a way to set (and get) the window's cursor to one + of several enumerated cursor shapes including "none", + "stop-watch", "arrow", "crosshair", "pull left/up/down/etc.", + or "inherit". + + void glutFullScreen(void) + + Attempts to make the window as large as the window system + permits (ie, the screen size). Borders will be automatically + disabled if possible. + + void glutMenuStatus(void (*)(int status, int x, int y)) + + The existing glutMenuState routine's callback did not + provide the X & Y location when the menu state changed + which made it impossible to correctly implement locate + highlight in conjunction with menus. glutMenuStatus + returns the location. + + GLUT_BITMAP_HELVETICA_10 + GLUT_BITMAP_HELVETICA_12 + GLUT_BITMAP_HELVETICA_18 + + New bitmap fonts in a nicer font at nicer sizes. + + int glutStrokeLength(void *, char *string) + int glutBitmapLength(void *, char *string) + + Given a font handle and a string, returns the length in + modelview units or pixels respectively for the string + if rendered with the font. + + int glutCurrentModifiers(void) + + When called from within a keyboard, special keyboard, mouse + button, or mouse callback, returns a bitmask representing + the modifier keys active when the event generating the callback + occured. This will let you implement Alt+ combinations + and such. + + void glutEstablishOverlays(void) + void glutRemoveOverlays(void) + void glutOverlayDisplayFunc(void (*func)(void)) + void glutPostOverlayRedisplay(void) + void glutUseLayer(GLenum layer) + void glutLayerGet(GLenum type) + void glutShowOverlay(void) + void glutHideOverlay(void) + + This API provides a way to "add" an overlay to a GLUT window. + The overlay is like IRIS GL overlay support in that the overlay + completely overlaps the window. You setup the layer with + glutEstablishOverlay. You switch between the normal plane + and overlay using glutUseLayer. You can register an independent + callback for redisplaying the overlay, or use a unified display + callback for both layers. + + I believe this is a very simple overlay facility that will be + readily useful for OpenGL programs wanting access to overlay + planes. + + GLUT_LUMINANCE + + This is a new display mode that is like OpenGL's basic RGBA + color model, but has no Green or Blue components (and Alpha + is optional). The Red component represents single component + (or "luminance") data (between 0.0 and 1.0). The component + is integerized to between 0 and glutGet(GLUT_WINDOW_COLORMAP_SIZE)-1 + and looked up in a per-window color map. GLUT's glutSetColor, + glutGetColor, and glutCopyColormap work on a GLUT_LUMINANCE + window. The initial colormap of GLUT_LUMINANCE windows is + initialized to be a linear gray ramp. + + GLUT_LUMINANCE is very much like a color index window with + an RGBA rendering model. GLUT_LUMINANCE should be useful for + scientific visualization. + + Only some platforms will support GLUT_LUMINANCE. SGI's IMPACT + and InfiniteReality systems should provide GLUT_LUMINANCE + support, however while the GLUT version 3 API provides GLUT_LUMINANCE, + GLUT 3.0 does not implement GLUT_LUMINANCE support. + + Exact specifics of how GLUT_LUMINANCE operates are subject to + change. + +Also there are a handful of minor bug fixes (of course). + diff --git a/lib/glut-3.7.6/README.ibm-shlib b/lib/glut-3.7.6/README.ibm-shlib new file mode 100644 index 0000000000..f1c301d8f0 --- /dev/null +++ b/lib/glut-3.7.6/README.ibm-shlib @@ -0,0 +1,79 @@ +The information below is probably no longer accurate. Please see +Question 44 in the "FAQ.glut" file for instructions for building +shared libraries today. + +- Mark Kilgard + November 25, 1998 + +-------------- + +IBM users wanting a GLUT shared library, + +I can't verify or maintain this information, but it could be useful to +someone on an IBM wanting to make shared libraries. I pass this +information on in case it is helpful. + +In theory, the better approach would be to use the imake rules for +building shared libraries. + +(I'm not too interestested in maitaining a shared library for GLUT since +the GLUT code is fairly small and portably maintaining shared libraries +for the wide variety of machines GLUT can run on would be a royal pain.) + +- Mark + +From gaitat@innerdoor.austin.ibm.com Thu Jul 20 08:57:58 1995 +Message-Id: <9507201557.AA20345@innerdoor.austin.ibm.com> +To: mjk@sgi.sgi.com +Subject: shared libglut.a +Date: Thu, 20 Jul 95 10:57:49 -0600 +From: Athanasios Gaitatzes + + +For the IBM platform I have made some changes to Glut.cf and lib/glut/Imakefile +in order to get a shared libglut.a so that the executables for the tests +and examples are not very big. +Here are the changes: +--------------------- +diff Glut.cf* +18d15 +< EXTRA_INCLUDES = -DAIXV3 -I$(TOP)/../include -I$(TOP) +21,22d17 +< ARFLAGS = crlo +< RANLIB = true +24d18 +< OPENGL = $(TOP)/../lib/libMesaGL.a +26d19 +< GLU = $(TOP)/../lib/libMesaGLU.a +--------------------- +diff lib/glut/Imakefile* +31,40c31 +< all:: libglut.a +< +< libglut.a: $(OBJS) +< rm -f libglut.a libglut.exp shrglut.o +< echo "#! libglut.a" > libglut.exp +< echo "noentry" >> libglut.exp +< create_exp $(OBJS) >> libglut.exp +< $(CC) -bM:SRE -o shrglut.o $(OBJS) -L../../../lib -lMesaGL -lMesaGLU +-lX +mu -lXi -lXext -lX11 -lm -lc -bE:libglut.exp -enoentry +< ar $(ARFLAGS) $@ shrglut.o +< $(RANLIB) $@ +--- +> NormalLibraryTarget(glut,$(OBJS)) + +and you also need a create_exp script somewhere in your path: +#!/bin/csh +/usr/ucb/nm $* | awk '/ [BD] /{print $3}' | sort | uniq + +Athanasios G. Gaitatzes (Saki) +internet: gaitat@vnet.ibm.com | http://www.cs.purdue.edu/homes/mgg/saki.html +internal: gaitat@austin.ibm.com | http://w3.austin.ibm.com/~gaitat +These statements and/or opinions are not necessarily those of IBM + + __ () , + / ) /`-'| _/_ _/_ + /--/ / / __. o / __. / __. _ _ +/ ( o /__-<_(_/|_<_<__(_/|_<__/ |_ +(Please note that I no longer work at Silicon Graphics. Try contacting +Peter Daifuku | The tablet puck buttons. + | | + | <2> <4> | + | | + | <3> | + \ / + +-----+ + + Device manufacturer: Hitachi + +SGI Virtual Pointer: + + Device type: VIRTUAL_POINTER + Device name: virtual_pointer + Classes: 2 + ButtonClass + Number buttons: 5 + ValuatorClass + Device mode: Absolute + Number axes: 2 + Axis 1 + Minimum value: 0 + Maximum value: 1280 + Resolution: 200 + Axis 2 + Minimum value: 0 + Maximum value: 1024 + Resolution: 200 + Physical layout: n/a + Device manufacturer: n/a + Notes: The virtual_pointer allows multiple physical devices to "push" + a single logical pointer. The virtual pointer is an SGI feature. + +SGI Mouse: + + Device type: MOUSE + Device name: mouse + Classes: 2 + ButtonClass + Number buttons: 3 + ValuatorClass + Device mode: Absolute + Number axes: 2 + Axis 1 + Minimum value: 0 + Maximum value: 65000 + Resolution: 200 + Axis 2 + Minimum value: 0 + Maximum value: 65000 + Resolution: 200 + Physical layout: + + +-------------+ + | | + | [1] [2] [3] | <--- Buttons on mouse w/ button numbers. + | | + | | + | | + | | + +-------------+ + + Axis 1 is for mouse motion in X axis (left & right) + Axis 2 is for mouse motion in Y axis (top & bottom) + + Device manufacturer: SGI + + diff --git a/lib/glut-3.7.6/adainclude/GL/glut.adb b/lib/glut-3.7.6/adainclude/GL/glut.adb new file mode 100644 index 0000000000..7ceb3457ad --- /dev/null +++ b/lib/glut-3.7.6/adainclude/GL/glut.adb @@ -0,0 +1,118 @@ +-- Generated from glut.h +-- Date: Sun Apr 6 14:32:02 1997 +-- +-- Command line definitions: +-- -D__ANSI_C__ -D_LANGUAGE_C -DGENERATING_ADA_BINDING -D__unix -D__sgi +-- -D__mips -D__host_mips -D__EXTENSIONS__ -D__EDG -D__DSO__ -D__STDC__ +-- -D_SYSTYPE_SVR4 -D_MODERN_C -D_MIPS_SZPTR=32 -D_MIPS_SZLONG=32 +-- -D_MIPS_SZINT=32 -D_MIPS_SIM=_MIPS_SIM_ABI32 +-- -D_MIPS_ISA=_MIPS_ISA_MIPS1 -D_MIPS_FPSET=16 -D_MIPSEB +-- + +package body Glut is + + function glutCreateWindow (title : String) return Integer is + Result : Integer; + c_title : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (title); + begin + Result := glutCreateWindow (c_title); + Interfaces.C.Strings.Free (c_title); + return Result; + end glutCreateWindow; + + procedure glutInitDisplayString (name : String) is + c_name : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (name); + begin + glutInitDisplayString (c_name); + Interfaces.C.Strings.Free (c_name); + end glutInitDisplayString; + + procedure glutSetWindowTitle (title : String) is + c_title : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (title); + begin + glutSetWindowTitle (c_title); + Interfaces.C.Strings.Free (c_title); + end glutSetWindowTitle; + + procedure glutSetIconTitle (title : String) is + c_title : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (title); + begin + glutSetIconTitle (c_title); + Interfaces.C.Strings.Free (c_title); + end glutSetIconTitle; + + function glutBitmapLength (font : access Interfaces.C.Extensions.Void_Ptr; + str : String) return Integer is + Result : Integer; + c_str : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (str); + begin + Result := glutBitmapLength (font, c_str); + Interfaces.C.Strings.Free (c_str); + return Result; + end glutBitmapLength; + + function glutStrokeLength (font : access Interfaces.C.Extensions.Void_Ptr; + str : String) return Integer is + Result : Integer; + c_str : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (str); + begin + Result := glutStrokeLength (font, c_str); + Interfaces.C.Strings.Free (c_str); + return Result; + end glutStrokeLength; + + procedure glutAddMenuEntry (label : String; value : Integer) is + c_label : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (label); + begin + glutAddMenuEntry (c_label, value); + Interfaces.C.Strings.Free (c_label); + end glutAddMenuEntry; + + procedure glutAddSubMenu (label : String; submenu : Integer) is + c_label : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (label); + begin + glutAddSubMenu (c_label, submenu); + Interfaces.C.Strings.Free (c_label); + end glutAddSubMenu; + + procedure glutChangeToMenuEntry (item : Integer; + label : String; + value : Integer) is + c_label : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (label); + begin + glutChangeToMenuEntry (item, c_label, value); + Interfaces.C.Strings.Free (c_label); + end glutChangeToMenuEntry; + + procedure glutChangeToSubMenu (item : Integer; + label : String; + submenu : Integer) is + c_label : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (label); + begin + glutChangeToSubMenu (item, c_label, submenu); + Interfaces.C.Strings.Free (c_label); + end glutChangeToSubMenu; + + function glutExtensionSupported (name : String) return Integer is + Result : Integer; + c_name : Interfaces.C.Strings.Chars_Ptr := + Interfaces.C.Strings.New_String (name); + begin + Result := glutExtensionSupported (c_name); + Interfaces.C.Strings.Free (c_name); + return Result; + end glutExtensionSupported; + + +end Glut; + diff --git a/lib/glut-3.7.6/adainclude/GL/glut.ads b/lib/glut-3.7.6/adainclude/GL/glut.ads new file mode 100644 index 0000000000..ec296c0c2b --- /dev/null +++ b/lib/glut-3.7.6/adainclude/GL/glut.ads @@ -0,0 +1,920 @@ +-- Generated from glut.h +-- Date: Sun Apr 6 14:32:02 1997 +-- +-- Command line definitions: +-- -D__ANSI_C__ -D_LANGUAGE_C -DGENERATING_ADA_BINDING -D__unix -D__sgi +-- -D__mips -D__host_mips -D__EXTENSIONS__ -D__EDG -D__DSO__ -D__STDC__ +-- -D_SYSTYPE_SVR4 -D_MODERN_C -D_MIPS_SZPTR=32 -D_MIPS_SZLONG=32 +-- -D_MIPS_SZINT=32 -D_MIPS_SIM=_MIPS_SIM_ABI32 +-- -D_MIPS_ISA=_MIPS_ISA_MIPS1 -D_MIPS_FPSET=16 -D_MIPSEB +-- + +with Interfaces.C; +with Interfaces.C.Extensions; +with Interfaces.C.Strings; +with GL; +package Glut is + + -- Copyright (c) Mark J. Kilgard, 1994, 1995, 1996. + -- 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. * + -- ** + -- 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 : constant := 4; -- VERSION 4 API NOT FINALIZED + +-- ** +-- 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 : constant := 7; + + -- Display mode bit masks. + + GLUT_RGB : constant := 0; + GLUT_RGBA : constant := 0; + GLUT_INDEX : constant := 1; + GLUT_SINGLE : constant := 0; + GLUT_DOUBLE : constant := 2; + GLUT_ACCUM : constant := 4; + GLUT_ALPHA : constant := 8; + GLUT_DEPTH : constant := 16; + GLUT_STENCIL : constant := 32; + GLUT_MULTISAMPLE : constant := 128; + GLUT_STEREO : constant := 256; + GLUT_LUMINANCE : constant := 512; + + -- Mouse buttons. + + GLUT_LEFT_BUTTON : constant := 0; + GLUT_MIDDLE_BUTTON : constant := 1; + GLUT_RIGHT_BUTTON : constant := 2; + + -- Mouse button callback state. + + GLUT_DOWN : constant := 0; + GLUT_UP : constant := 1; + + -- function keys + + GLUT_KEY_F1 : constant := 1; + GLUT_KEY_F2 : constant := 2; + GLUT_KEY_F3 : constant := 3; + GLUT_KEY_F4 : constant := 4; + GLUT_KEY_F5 : constant := 5; + GLUT_KEY_F6 : constant := 6; + GLUT_KEY_F7 : constant := 7; + GLUT_KEY_F8 : constant := 8; + GLUT_KEY_F9 : constant := 9; + GLUT_KEY_F10 : constant := 10; + GLUT_KEY_F11 : constant := 11; + GLUT_KEY_F12 : constant := 12; + + -- directional keys + + GLUT_KEY_LEFT : constant := 100; + GLUT_KEY_UP : constant := 101; + GLUT_KEY_RIGHT : constant := 102; + GLUT_KEY_DOWN : constant := 103; + GLUT_KEY_PAGE_UP : constant := 104; + GLUT_KEY_PAGE_DOWN : constant := 105; + GLUT_KEY_HOME : constant := 106; + GLUT_KEY_END : constant := 107; + GLUT_KEY_INSERT : constant := 108; + + -- Entry/exit callback state. + + GLUT_LEFT : constant := 0; + GLUT_ENTERED : constant := 1; + + -- Menu usage callback state. + + GLUT_MENU_NOT_IN_USE : constant := 0; + GLUT_MENU_IN_USE : constant := 1; + + -- Visibility callback state. + + GLUT_NOT_VISIBLE : constant := 0; + GLUT_VISIBLE : constant := 1; + + -- Window status callback state. + + GLUT_HIDDEN : constant := 0; + GLUT_FULLY_RETAINED : constant := 1; + GLUT_PARTIALLY_RETAINED : constant := 2; + GLUT_FULLY_COVERED : constant := 3; + + -- Color index component selection values. + + GLUT_RED : constant := 0; + GLUT_GREEN : constant := 1; + GLUT_BLUE : constant := 2; + + -- Layers for use. + + GLUT_NORMAL : constant := 0; + GLUT_OVERLAY : constant := 1; + + -- Stroke font opaque addresses (use constants instead in source code). + + glutStrokeRoman : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, glutStrokeRoman, "glutStrokeRoman", "glutStrokeRoman"); + + glutStrokeMonoRoman : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutStrokeMonoRoman, + "glutStrokeMonoRoman", + "glutStrokeMonoRoman"); + + -- Stroke font constants (use these in GLUT program). + -- Bitmap font opaque addresses (use constants instead in source code). + + glutBitmap9By15 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, glutBitmap9By15, "glutBitmap9By15", "glutBitmap9By15"); + + glutBitmap8By13 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, glutBitmap8By13, "glutBitmap8By13", "glutBitmap8By13"); + + glutBitmapTimesRoman10 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutBitmapTimesRoman10, + "glutBitmapTimesRoman10", + "glutBitmapTimesRoman10"); + + glutBitmapTimesRoman24 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutBitmapTimesRoman24, + "glutBitmapTimesRoman24", + "glutBitmapTimesRoman24"); + + glutBitmapHelvetica10 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutBitmapHelvetica10, + "glutBitmapHelvetica10", + "glutBitmapHelvetica10"); + + glutBitmapHelvetica12 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutBitmapHelvetica12, + "glutBitmapHelvetica12", + "glutBitmapHelvetica12"); + + glutBitmapHelvetica18 : aliased Interfaces.C.Extensions.Void_Ptr; + pragma Import (C, + glutBitmapHelvetica18, + "glutBitmapHelvetica18", + "glutBitmapHelvetica18"); + + -- Bitmap font constants (use these in GLUT program). + -- glutGet parameters. + + GLUT_WINDOW_X : constant := 100; + GLUT_WINDOW_Y : constant := 101; + GLUT_WINDOW_WIDTH : constant := 102; + GLUT_WINDOW_HEIGHT : constant := 103; + GLUT_WINDOW_BUFFER_SIZE : constant := 104; + GLUT_WINDOW_STENCIL_SIZE : constant := 105; + GLUT_WINDOW_DEPTH_SIZE : constant := 106; + GLUT_WINDOW_RED_SIZE : constant := 107; + GLUT_WINDOW_GREEN_SIZE : constant := 108; + GLUT_WINDOW_BLUE_SIZE : constant := 109; + GLUT_WINDOW_ALPHA_SIZE : constant := 110; + GLUT_WINDOW_ACCUM_RED_SIZE : constant := 111; + GLUT_WINDOW_ACCUM_GREEN_SIZE : constant := 112; + GLUT_WINDOW_ACCUM_BLUE_SIZE : constant := 113; + GLUT_WINDOW_ACCUM_ALPHA_SIZE : constant := 114; + GLUT_WINDOW_DOUBLEBUFFER : constant := 115; + GLUT_WINDOW_RGBA : constant := 116; + GLUT_WINDOW_PARENT : constant := 117; + GLUT_WINDOW_NUM_CHILDREN : constant := 118; + GLUT_WINDOW_COLORMAP_SIZE : constant := 119; + GLUT_WINDOW_NUM_SAMPLES : constant := 120; + GLUT_WINDOW_STEREO : constant := 121; + GLUT_WINDOW_CURSOR : constant := 122; + GLUT_SCREEN_WIDTH : constant := 200; + GLUT_SCREEN_HEIGHT : constant := 201; + GLUT_SCREEN_WIDTH_MM : constant := 202; + GLUT_SCREEN_HEIGHT_MM : constant := 203; + GLUT_MENU_NUM_ITEMS : constant := 300; + GLUT_DISPLAY_MODE_POSSIBLE : constant := 400; + GLUT_INIT_WINDOW_X : constant := 500; + GLUT_INIT_WINDOW_Y : constant := 501; + GLUT_INIT_WINDOW_WIDTH : constant := 502; + GLUT_INIT_WINDOW_HEIGHT : constant := 503; + GLUT_INIT_DISPLAY_MODE : constant := 504; + GLUT_ELAPSED_TIME : constant := 700; + + -- glutDeviceGet parameters. + + GLUT_HAS_KEYBOARD : constant := 600; + GLUT_HAS_MOUSE : constant := 601; + GLUT_HAS_SPACEBALL : constant := 602; + GLUT_HAS_DIAL_AND_BUTTON_BOX : constant := 603; + GLUT_HAS_TABLET : constant := 604; + GLUT_NUM_MOUSE_BUTTONS : constant := 605; + GLUT_NUM_SPACEBALL_BUTTONS : constant := 606; + GLUT_NUM_BUTTON_BOX_BUTTONS : constant := 607; + GLUT_NUM_DIALS : constant := 608; + GLUT_NUM_TABLET_BUTTONS : constant := 609; + + -- glutLayerGet parameters. + + GLUT_OVERLAY_POSSIBLE : constant := 800; + GLUT_LAYER_IN_USE : constant := 801; + GLUT_HAS_OVERLAY : constant := 802; + GLUT_TRANSPARENT_INDEX : constant := 803; + GLUT_NORMAL_DAMAGED : constant := 804; + GLUT_OVERLAY_DAMAGED : constant := 805; + + -- glutVideoResizeGet parameters. + + GLUT_VIDEO_RESIZE_POSSIBLE : constant := 900; + GLUT_VIDEO_RESIZE_IN_USE : constant := 901; + GLUT_VIDEO_RESIZE_X_DELTA : constant := 902; + GLUT_VIDEO_RESIZE_Y_DELTA : constant := 903; + GLUT_VIDEO_RESIZE_WIDTH_DELTA : constant := 904; + GLUT_VIDEO_RESIZE_HEIGHT_DELTA : constant := 905; + GLUT_VIDEO_RESIZE_X : constant := 906; + GLUT_VIDEO_RESIZE_Y : constant := 907; + GLUT_VIDEO_RESIZE_WIDTH : constant := 908; + GLUT_VIDEO_RESIZE_HEIGHT : constant := 909; + + -- glutUseLayer parameters. + -- glutGetModifiers return mask. + + GLUT_ACTIVE_SHIFT : constant := 1; + GLUT_ACTIVE_CTRL : constant := 2; + GLUT_ACTIVE_ALT : constant := 4; + + -- glutSetCursor parameters. + -- Basic arrows. + + GLUT_CURSOR_RIGHT_ARROW : constant := 0; + GLUT_CURSOR_LEFT_ARROW : constant := 1; + + -- Symbolic cursor shapes. + + GLUT_CURSOR_INFO : constant := 2; + GLUT_CURSOR_DESTROY : constant := 3; + GLUT_CURSOR_HELP : constant := 4; + GLUT_CURSOR_CYCLE : constant := 5; + GLUT_CURSOR_SPRAY : constant := 6; + GLUT_CURSOR_WAIT : constant := 7; + GLUT_CURSOR_TEXT : constant := 8; + GLUT_CURSOR_CROSSHAIR : constant := 9; + + -- Directional cursors. + + GLUT_CURSOR_UP_DOWN : constant := 10; + GLUT_CURSOR_LEFT_RIGHT : constant := 11; + + -- Sizing cursors. + + GLUT_CURSOR_TOP_SIDE : constant := 12; + GLUT_CURSOR_BOTTOM_SIDE : constant := 13; + GLUT_CURSOR_LEFT_SIDE : constant := 14; + GLUT_CURSOR_RIGHT_SIDE : constant := 15; + GLUT_CURSOR_TOP_LEFT_CORNER : constant := 16; + GLUT_CURSOR_TOP_RIGHT_CORNER : constant := 17; + GLUT_CURSOR_BOTTOM_RIGHT_CORNER : constant := 18; + GLUT_CURSOR_BOTTOM_LEFT_CORNER : constant := 19; + + -- Inherit from parent window. + + GLUT_CURSOR_INHERIT : constant := 100; + + -- Blank cursor. + + GLUT_CURSOR_NONE : constant := 101; + + -- Fullscreen crosshair (if available). + + GLUT_CURSOR_FULL_CROSSHAIR : constant := 102; + + -- GLUT initialization sub-API. + + procedure glutInit (argcp : access Integer; + argv : access Interfaces.C.Strings.Chars_Ptr); + pragma Import (C, glutInit, "glutInit", "glutInit"); + + procedure glutInitDisplayMode (mode : Interfaces.C.unsigned); + pragma Import (C, + glutInitDisplayMode, + "glutInitDisplayMode", + "glutInitDisplayMode"); + + procedure glutInitDisplayString (string : Interfaces.C.Strings.Chars_Ptr); + pragma Import (C, + glutInitDisplayString, + "glutInitDisplayString", + "glutInitDisplayString"); + + procedure glutInitWindowPosition (x : Integer; y : Integer); + pragma Import (C, + glutInitWindowPosition, + "glutInitWindowPosition", + "glutInitWindowPosition"); + + procedure glutInitWindowSize (width : Integer; height : Integer); + pragma Import (C, + glutInitWindowSize, + "glutInitWindowSize", + "glutInitWindowSize"); + + procedure glutMainLoop; + pragma Import (C, glutMainLoop, "glutMainLoop", "glutMainLoop"); + + -- GLUT window sub-API. + + function glutCreateWindow + (title : Interfaces.C.Strings.Chars_Ptr) return Integer; + pragma Import (C, glutCreateWindow, "glutCreateWindow", "glutCreateWindow"); + + function glutCreateWindow (title : String) return Integer; + + function glutCreateSubWindow (win : Integer; + x : Integer; + y : Integer; + width : Integer; + height : Integer) return Integer; + pragma Import (C, + glutCreateSubWindow, + "glutCreateSubWindow", + "glutCreateSubWindow"); + + procedure glutDestroyWindow (win : Integer); + pragma Import (C, + glutDestroyWindow, + "glutDestroyWindow", + "glutDestroyWindow"); + + procedure glutPostRedisplay; + pragma Import (C, + glutPostRedisplay, + "glutPostRedisplay", + "glutPostRedisplay"); + + procedure glutPostWindowRedisplay (win : Integer); + pragma Import (C, + glutPostWindowRedisplay, + "glutPostWindowRedisplay", + "glutPostWindowRedisplay"); + + procedure glutSwapBuffers; + pragma Import (C, glutSwapBuffers, "glutSwapBuffers", "glutSwapBuffers"); + + function glutGetWindow return Integer; + pragma Import (C, glutGetWindow, "glutGetWindow", "glutGetWindow"); + + procedure glutSetWindow (win : Integer); + pragma Import (C, glutSetWindow, "glutSetWindow", "glutSetWindow"); + + procedure glutSetWindowTitle (title : Interfaces.C.Strings.Chars_Ptr); + pragma Import (C, + glutSetWindowTitle, + "glutSetWindowTitle", + "glutSetWindowTitle"); + + procedure glutSetWindowTitle (title : String); + + procedure glutSetIconTitle (title : Interfaces.C.Strings.Chars_Ptr); + pragma Import (C, glutSetIconTitle, "glutSetIconTitle", "glutSetIconTitle"); + + procedure glutSetIconTitle (title : String); + + procedure glutPositionWindow (x : Integer; y : Integer); + pragma Import (C, + glutPositionWindow, + "glutPositionWindow", + "glutPositionWindow"); + + procedure glutReshapeWindow (width : Integer; height : Integer); + pragma Import (C, + glutReshapeWindow, + "glutReshapeWindow", + "glutReshapeWindow"); + + procedure glutPopWindow; + pragma Import (C, glutPopWindow, "glutPopWindow", "glutPopWindow"); + + procedure glutPushWindow; + pragma Import (C, glutPushWindow, "glutPushWindow", "glutPushWindow"); + + procedure glutIconifyWindow; + pragma Import (C, + glutIconifyWindow, + "glutIconifyWindow", + "glutIconifyWindow"); + + procedure glutShowWindow; + pragma Import (C, glutShowWindow, "glutShowWindow", "glutShowWindow"); + + procedure glutHideWindow; + pragma Import (C, glutHideWindow, "glutHideWindow", "glutHideWindow"); + + procedure glutFullScreen; + pragma Import (C, glutFullScreen, "glutFullScreen", "glutFullScreen"); + + procedure glutSetCursor (cursor : Integer); + pragma Import (C, glutSetCursor, "glutSetCursor", "glutSetCursor"); + + procedure glutWarpPointer (x : Integer; y : Integer); + pragma Import (C, glutWarpPointer, "glutWarpPointer", "glutWarpPointer"); + + -- GLUT overlay sub-API. + + procedure glutEstablishOverlay; + pragma Import (C, + glutEstablishOverlay, + "glutEstablishOverlay", + "glutEstablishOverlay"); + + procedure glutRemoveOverlay; + pragma Import (C, + glutRemoveOverlay, + "glutRemoveOverlay", + "glutRemoveOverlay"); + + procedure glutUseLayer (layer : GL.GLenum); + pragma Import (C, glutUseLayer, "glutUseLayer", "glutUseLayer"); + + procedure glutPostOverlayRedisplay; + pragma Import (C, + glutPostOverlayRedisplay, + "glutPostOverlayRedisplay", + "glutPostOverlayRedisplay"); + + procedure glutPostWindowOverlayRedisplay (win : Integer); + pragma Import (C, + glutPostWindowOverlayRedisplay, + "glutPostWindowOverlayRedisplay", + "glutPostWindowOverlayRedisplay"); + + procedure glutShowOverlay; + pragma Import (C, glutShowOverlay, "glutShowOverlay", "glutShowOverlay"); + + procedure glutHideOverlay; + pragma Import (C, glutHideOverlay, "glutHideOverlay", "glutHideOverlay"); + + -- GLUT menu sub-API. + + type Glut_proc_1 is access procedure (P1 : Integer); + + function glutCreateMenu (P1 : Glut_proc_1) return Integer; + pragma Import (C, glutCreateMenu, "glutCreateMenu", "glutCreateMenu"); + + procedure glutDestroyMenu (menu : Integer); + pragma Import (C, glutDestroyMenu, "glutDestroyMenu", "glutDestroyMenu"); + + function glutGetMenu return Integer; + pragma Import (C, glutGetMenu, "glutGetMenu", "glutGetMenu"); + + procedure glutSetMenu (menu : Integer); + pragma Import (C, glutSetMenu, "glutSetMenu", "glutSetMenu"); + + procedure glutAddMenuEntry (label : Interfaces.C.Strings.Chars_Ptr; + value : Integer); + pragma Import (C, glutAddMenuEntry, "glutAddMenuEntry", "glutAddMenuEntry"); + + procedure glutAddMenuEntry (label : String; value : Integer); + + procedure glutAddSubMenu (label : Interfaces.C.Strings.Chars_Ptr; + submenu : Integer); + pragma Import (C, glutAddSubMenu, "glutAddSubMenu", "glutAddSubMenu"); + + procedure glutAddSubMenu (label : String; submenu : Integer); + + procedure glutChangeToMenuEntry (item : Integer; + label : Interfaces.C.Strings.Chars_Ptr; + value : Integer); + pragma Import (C, + glutChangeToMenuEntry, + "glutChangeToMenuEntry", + "glutChangeToMenuEntry"); + + procedure glutChangeToMenuEntry (item : Integer; + label : String; + value : Integer); + + procedure glutChangeToSubMenu (item : Integer; + label : Interfaces.C.Strings.Chars_Ptr; + submenu : Integer); + pragma Import (C, + glutChangeToSubMenu, + "glutChangeToSubMenu", + "glutChangeToSubMenu"); + + procedure glutChangeToSubMenu (item : Integer; + label : String; + submenu : Integer); + + procedure glutRemoveMenuItem (item : Integer); + pragma Import (C, + glutRemoveMenuItem, + "glutRemoveMenuItem", + "glutRemoveMenuItem"); + + procedure glutAttachMenu (button : Integer); + pragma Import (C, glutAttachMenu, "glutAttachMenu", "glutAttachMenu"); + + procedure glutDetachMenu (button : Integer); + pragma Import (C, glutDetachMenu, "glutDetachMenu", "glutDetachMenu"); + + -- GLUT callback sub-API. + + type Glut_proc_2 is access procedure; + + procedure glutDisplayFunc (P1 : Glut_proc_2); + pragma Import (C, glutDisplayFunc, "glutDisplayFunc", "glutDisplayFunc"); + + type Glut_proc_3 is access procedure (width : Integer; height : Integer); + + procedure glutReshapeFunc (P1 : Glut_proc_3); + pragma Import (C, glutReshapeFunc, "glutReshapeFunc", "glutReshapeFunc"); + + type Glut_proc_4 is access + procedure (key : Interfaces.C.unsigned_char; x : Integer; y : Integer); + + procedure glutKeyboardFunc (P1 : Glut_proc_4); + pragma Import (C, glutKeyboardFunc, "glutKeyboardFunc", "glutKeyboardFunc"); + + type Glut_proc_5 is access + procedure (button : Integer; state : Integer; x : Integer; y : Integer); + + procedure glutMouseFunc (P1 : Glut_proc_5); + pragma Import (C, glutMouseFunc, "glutMouseFunc", "glutMouseFunc"); + + type Glut_proc_6 is access procedure (x : Integer; y : Integer); + + procedure glutMotionFunc (P1 : Glut_proc_6); + pragma Import (C, glutMotionFunc, "glutMotionFunc", "glutMotionFunc"); + + type Glut_proc_7 is access procedure (x : Integer; y : Integer); + + procedure glutPassiveMotionFunc (P1 : Glut_proc_7); + pragma Import (C, + glutPassiveMotionFunc, + "glutPassiveMotionFunc", + "glutPassiveMotionFunc"); + + type Glut_proc_8 is access procedure (state : Integer); + + procedure glutEntryFunc (P1 : Glut_proc_8); + pragma Import (C, glutEntryFunc, "glutEntryFunc", "glutEntryFunc"); + + type Glut_proc_9 is access procedure (state : Integer); + + procedure glutVisibilityFunc (P1 : Glut_proc_9); + pragma Import (C, + glutVisibilityFunc, + "glutVisibilityFunc", + "glutVisibilityFunc"); + + type Glut_proc_10 is access procedure; + + procedure glutIdleFunc (P1 : Glut_proc_10); + pragma Import (C, glutIdleFunc, "glutIdleFunc", "glutIdleFunc"); + + type Glut_proc_11 is access procedure (value : Integer); + + procedure glutTimerFunc (millis : Interfaces.C.unsigned; + P2 : Glut_proc_11; + value : Integer); + pragma Import (C, glutTimerFunc, "glutTimerFunc", "glutTimerFunc"); + + type Glut_proc_12 is access procedure (state : Integer); + + procedure glutMenuStateFunc (P1 : Glut_proc_12); + pragma Import (C, + glutMenuStateFunc, + "glutMenuStateFunc", + "glutMenuStateFunc"); + + type Glut_proc_13 is access + procedure (key : Integer; x : Integer; y : Integer); + + procedure glutSpecialFunc (P1 : Glut_proc_13); + pragma Import (C, glutSpecialFunc, "glutSpecialFunc", "glutSpecialFunc"); + + type Glut_proc_14 is access + procedure (x : Integer; y : Integer; z : Integer); + + procedure glutSpaceballMotionFunc (P1 : Glut_proc_14); + pragma Import (C, + glutSpaceballMotionFunc, + "glutSpaceballMotionFunc", + "glutSpaceballMotionFunc"); + + type Glut_proc_15 is access + procedure (x : Integer; y : Integer; z : Integer); + + procedure glutSpaceballRotateFunc (P1 : Glut_proc_15); + pragma Import (C, + glutSpaceballRotateFunc, + "glutSpaceballRotateFunc", + "glutSpaceballRotateFunc"); + + type Glut_proc_16 is access procedure (button : Integer; state : Integer); + + procedure glutSpaceballButtonFunc (P1 : Glut_proc_16); + pragma Import (C, + glutSpaceballButtonFunc, + "glutSpaceballButtonFunc", + "glutSpaceballButtonFunc"); + + type Glut_proc_17 is access procedure (button : Integer; state : Integer); + + procedure glutButtonBoxFunc (P1 : Glut_proc_17); + pragma Import (C, + glutButtonBoxFunc, + "glutButtonBoxFunc", + "glutButtonBoxFunc"); + + type Glut_proc_18 is access procedure (dial : Integer; value : Integer); + + procedure glutDialsFunc (P1 : Glut_proc_18); + pragma Import (C, glutDialsFunc, "glutDialsFunc", "glutDialsFunc"); + + type Glut_proc_19 is access procedure (x : Integer; y : Integer); + + procedure glutTabletMotionFunc (P1 : Glut_proc_19); + pragma Import (C, + glutTabletMotionFunc, + "glutTabletMotionFunc", + "glutTabletMotionFunc"); + + type Glut_proc_20 is access + procedure (button : Integer; state : Integer; x : Integer; y : Integer); + + procedure glutTabletButtonFunc (P1 : Glut_proc_20); + pragma Import (C, + glutTabletButtonFunc, + "glutTabletButtonFunc", + "glutTabletButtonFunc"); + + type Glut_proc_21 is access + procedure (status : Integer; x : Integer; y : Integer); + + procedure glutMenuStatusFunc (P1 : Glut_proc_21); + pragma Import (C, + glutMenuStatusFunc, + "glutMenuStatusFunc", + "glutMenuStatusFunc"); + + type Glut_proc_22 is access procedure; + + procedure glutOverlayDisplayFunc (P1 : Glut_proc_22); + pragma Import (C, + glutOverlayDisplayFunc, + "glutOverlayDisplayFunc", + "glutOverlayDisplayFunc"); + + type Glut_proc_23 is access procedure (state : Integer); + + procedure glutWindowStatusFunc (P1 : Glut_proc_23); + pragma Import (C, + glutWindowStatusFunc, + "glutWindowStatusFunc", + "glutWindowStatusFunc"); + + -- GLUT color index sub-API. + + procedure glutSetColor (P1 : Integer; + red : GL.GLfloat; + green : GL.GLfloat; + blue : GL.GLfloat); + pragma Import (C, glutSetColor, "glutSetColor", "glutSetColor"); + + function glutGetColor + (ndx : Integer; component : Integer) return GL.GLfloat; + pragma Import (C, glutGetColor, "glutGetColor", "glutGetColor"); + + procedure glutCopyColormap (win : Integer); + pragma Import (C, glutCopyColormap, "glutCopyColormap", "glutCopyColormap"); + + -- GLUT state retrieval sub-API. + + function glutGet (type_Id : GL.GLenum) return Integer; + pragma Import (C, glutGet, "glutGet", "glutGet"); + + function glutDeviceGet (type_Id : GL.GLenum) return Integer; + pragma Import (C, glutDeviceGet, "glutDeviceGet", "glutDeviceGet"); + + -- GLUT extension support sub-API + + function glutExtensionSupported + (name : Interfaces.C.Strings.Chars_Ptr) return Integer; + pragma Import (C, + glutExtensionSupported, + "glutExtensionSupported", + "glutExtensionSupported"); + + function glutExtensionSupported (name : String) return Integer; + + function glutGetModifiers return Integer; + pragma Import (C, glutGetModifiers, "glutGetModifiers", "glutGetModifiers"); + + function glutLayerGet (type_Id : GL.GLenum) return Integer; + pragma Import (C, glutLayerGet, "glutLayerGet", "glutLayerGet"); + + -- GLUT font sub-API + + procedure glutBitmapCharacter (font : access Interfaces.C.Extensions.Void_Ptr; + character : Integer); + pragma Import (C, + glutBitmapCharacter, + "glutBitmapCharacter", + "glutBitmapCharacter"); + + function glutBitmapWidth + (font : access Interfaces.C.Extensions.Void_Ptr; + character : Integer) return Integer; + pragma Import (C, glutBitmapWidth, "glutBitmapWidth", "glutBitmapWidth"); + + procedure glutStrokeCharacter + (font : access Interfaces.C.Extensions.Void_Ptr; + character : Integer); + pragma Import (C, + glutStrokeCharacter, + "glutStrokeCharacter", + "glutStrokeCharacter"); + + function glutStrokeWidth + (font : access Interfaces.C.Extensions.Void_Ptr; + character : Integer) return Integer; + pragma Import (C, glutStrokeWidth, "glutStrokeWidth", "glutStrokeWidth"); + + function glutStrokeLength + (font : access Interfaces.C.Extensions.Void_Ptr; + string : Interfaces.C.Strings.Chars_Ptr) return Integer; + pragma Import (C, glutStrokeLength, "glutStrokeLength", "glutStrokeLength"); + + function glutBitmapLength + (font : access Interfaces.C.Extensions.Void_Ptr; + string : Interfaces.C.Strings.Chars_Ptr) return Integer; + pragma Import (C, glutBitmapLength, "glutBitmapLength", "glutBitmapLength"); + + -- GLUT pre-built models sub-API + + procedure glutWireSphere (radius : GL.GLdouble; + slices : GL.GLint; + stacks : GL.GLint); + pragma Import (C, glutWireSphere, "glutWireSphere", "glutWireSphere"); + + procedure glutSolidSphere (radius : GL.GLdouble; + slices : GL.GLint; + stacks : GL.GLint); + pragma Import (C, glutSolidSphere, "glutSolidSphere", "glutSolidSphere"); + + procedure glutWireCone (base : GL.GLdouble; + height : GL.GLdouble; + slices : GL.GLint; + stacks : GL.GLint); + pragma Import (C, glutWireCone, "glutWireCone", "glutWireCone"); + + procedure glutSolidCone (base : GL.GLdouble; + height : GL.GLdouble; + slices : GL.GLint; + stacks : GL.GLint); + pragma Import (C, glutSolidCone, "glutSolidCone", "glutSolidCone"); + + procedure glutWireCube (size : GL.GLdouble); + pragma Import (C, glutWireCube, "glutWireCube", "glutWireCube"); + + procedure glutSolidCube (size : GL.GLdouble); + pragma Import (C, glutSolidCube, "glutSolidCube", "glutSolidCube"); + + procedure glutWireTorus (innerRadius : GL.GLdouble; + outerRadius : GL.GLdouble; + sides : GL.GLint; + rings : GL.GLint); + pragma Import (C, glutWireTorus, "glutWireTorus", "glutWireTorus"); + + procedure glutSolidTorus (innerRadius : GL.GLdouble; + outerRadius : GL.GLdouble; + sides : GL.GLint; + rings : GL.GLint); + pragma Import (C, glutSolidTorus, "glutSolidTorus", "glutSolidTorus"); + + procedure glutWireDodecahedron; + pragma Import (C, + glutWireDodecahedron, + "glutWireDodecahedron", + "glutWireDodecahedron"); + + procedure glutSolidDodecahedron; + pragma Import (C, + glutSolidDodecahedron, + "glutSolidDodecahedron", + "glutSolidDodecahedron"); + + procedure glutWireTeapot (size : GL.GLdouble); + pragma Import (C, glutWireTeapot, "glutWireTeapot", "glutWireTeapot"); + + procedure glutSolidTeapot (size : GL.GLdouble); + pragma Import (C, glutSolidTeapot, "glutSolidTeapot", "glutSolidTeapot"); + + procedure glutWireOctahedron; + pragma Import (C, + glutWireOctahedron, + "glutWireOctahedron", + "glutWireOctahedron"); + + procedure glutSolidOctahedron; + pragma Import (C, + glutSolidOctahedron, + "glutSolidOctahedron", + "glutSolidOctahedron"); + + procedure glutWireTetrahedron; + pragma Import (C, + glutWireTetrahedron, + "glutWireTetrahedron", + "glutWireTetrahedron"); + + procedure glutSolidTetrahedron; + pragma Import (C, + glutSolidTetrahedron, + "glutSolidTetrahedron", + "glutSolidTetrahedron"); + + procedure glutWireIcosahedron; + pragma Import (C, + glutWireIcosahedron, + "glutWireIcosahedron", + "glutWireIcosahedron"); + + procedure glutSolidIcosahedron; + pragma Import (C, + glutSolidIcosahedron, + "glutSolidIcosahedron", + "glutSolidIcosahedron"); + + function glutVideoResizeGet (param : GL.GLenum) return Integer; + pragma Import (C, + glutVideoResizeGet, + "glutVideoResizeGet", + "glutVideoResizeGet"); + + procedure glutSetupVideoResizing; + pragma Import (C, + glutSetupVideoResizing, + "glutSetupVideoResizing", + "glutSetupVideoResizing"); + + procedure glutStopVideoResizing; + pragma Import (C, + glutStopVideoResizing, + "glutStopVideoResizing", + "glutStopVideoResizing"); + + procedure glutVideoResize (x : Integer; + y : Integer; + width : Integer; + height : Integer); + pragma Import (C, glutVideoResize, "glutVideoResize", "glutVideoResize"); + + procedure glutVideoPan (x : Integer; + y : Integer; + width : Integer; + height : Integer); + pragma Import (C, glutVideoPan, "glutVideoPan", "glutVideoPan"); + +end Glut; + diff --git a/lib/glut-3.7.6/glut-3.7.6.pro b/lib/glut-3.7.6/glut-3.7.6.pro new file mode 100644 index 0000000000..b956c8b903 --- /dev/null +++ b/lib/glut-3.7.6/glut-3.7.6.pro @@ -0,0 +1,167 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Mi Sep 29 21:06:53 2010 +###################################################################### + +TEMPLATE = lib +TARGET = +DEPENDPATH += . \ + include/GL \ + include/mui \ + lib/fglut \ + lib/gle \ + lib/glsmap \ + lib/glut \ + lib/mui +INCLUDEPATH += . \ + include \ + lib/glut \ + lib/gle \ + lib/glsmap + +# Input +HEADERS += include/GL/fgl.h \ + include/GL/fglu.h \ + include/GL/fglut.h \ + include/GL/glsmap.h \ + include/GL/glut.h \ + include/GL/glutf90.h \ + include/GL/tube.h \ + include/mui/browser.h \ + include/mui/displaylist.h \ + include/mui/gizmo.h \ + include/mui/hslider.h \ + include/mui/mui.h \ + include/mui/textlist.h \ + include/mui/uicolor.h \ + include/mui/vslider.h \ + lib/gle/copy.h \ + lib/gle/extrude.h \ + lib/gle/gutil.h \ + lib/gle/intersect.h \ + lib/gle/port.h \ + lib/gle/rot.h \ + lib/gle/segment.h \ + lib/gle/tube_gc.h \ + lib/gle/vvector.h \ + lib/glsmap/glsmapint.h \ + lib/glut/glutbitmap.h \ + lib/glut/glutint.h \ + lib/glut/glutstroke.h \ + lib/glut/glutwin32.h \ + lib/glut/layerutil.h \ + lib/glut/stroke.h \ + lib/glut/win32_glx.h \ + lib/glut/win32_x11.h \ + lib/mui/dirent32.h +LEXSOURCES += lib/glut/strokelex.l +YACCSOURCES += lib/glut/strokegen.y +SOURCES += lib/fglut/fglut.c \ + lib/fglut/fglut_8x13.c \ + lib/fglut/fglut_9x15.c \ + lib/fglut/fglut_hel10.c \ + lib/fglut/fglut_hel12.c \ + lib/fglut/fglut_hel18.c \ + lib/fglut/fglut_mroman.c \ + lib/fglut/fglut_roman.c \ + lib/fglut/fglut_tr10.c \ + lib/fglut/fglut_tr24.c \ + lib/gle/ex_angle.c \ + lib/gle/ex_cut_round.c \ + lib/gle/ex_raw.c \ + lib/gle/extrude.c \ + lib/gle/intersect.c \ + lib/gle/qmesh.c \ + lib/gle/rot_prince.c \ + lib/gle/rotate.c \ + lib/gle/round_cap.c \ + lib/gle/segment.c \ + lib/gle/texgen.c \ + lib/gle/urotate.c \ + lib/gle/view.c \ + lib/glsmap/smap_buildsmap.c \ + lib/glsmap/smap_context.c \ + lib/glsmap/smap_create.c \ + lib/glsmap/smap_destroy.c \ + lib/glsmap/smap_drawmesh.c \ + lib/glsmap/smap_flag.c \ + lib/glsmap/smap_get.c \ + lib/glsmap/smap_getfunc.c \ + lib/glsmap/smap_gettexdim.c \ + lib/glsmap/smap_gettexobj.c \ + lib/glsmap/smap_getvec.c \ + lib/glsmap/smap_makemesh.c \ + lib/glsmap/smap_nearfar.c \ + lib/glsmap/smap_origin.c \ + lib/glsmap/smap_render.c \ + lib/glsmap/smap_rvec2st.c \ + lib/glsmap/smap_set.c \ + lib/glsmap/smap_setfunc.c \ + lib/glsmap/smap_setvec.c \ + lib/glsmap/smap_texdim.c \ + lib/glsmap/smap_texobj.c \ + lib/glut/capturexfont.c \ + lib/glut/glut_8x13.c \ + lib/glut/glut_9x15.c \ + lib/glut/glut_bitmap.c \ + lib/glut/glut_bwidth.c \ + lib/glut/glut_cindex.c \ + lib/glut/glut_cmap.c \ + lib/glut/glut_cursor.c \ + lib/glut/glut_dials.c \ + lib/glut/glut_dstr.c \ + lib/glut/glut_event.c \ + lib/glut/glut_ext.c \ + lib/glut/glut_fcb.c \ + lib/glut/glut_fullscrn.c \ + lib/glut/glut_gamemode.c \ + lib/glut/glut_get.c \ + lib/glut/glut_glxext.c \ + lib/glut/glut_hel10.c \ + lib/glut/glut_hel12.c \ + lib/glut/glut_hel18.c \ + lib/glut/glut_init.c \ + lib/glut/glut_input.c \ + lib/glut/glut_joy.c \ + lib/glut/glut_key.c \ + lib/glut/glut_keyctrl.c \ + lib/glut/glut_keyup.c \ + lib/glut/glut_menu.c \ + lib/glut/glut_menu2.c \ + lib/glut/glut_mesa.c \ + lib/glut/glut_modifier.c \ + lib/glut/glut_mroman.c \ + lib/glut/glut_overlay.c \ + lib/glut/glut_roman.c \ + lib/glut/glut_shapes.c \ + lib/glut/glut_space.c \ + lib/glut/glut_stroke.c \ + lib/glut/glut_swap.c \ + lib/glut/glut_swidth.c \ + lib/glut/glut_tablet.c \ + lib/glut/glut_teapot.c \ + lib/glut/glut_tr10.c \ + lib/glut/glut_tr24.c \ + lib/glut/glut_util.c \ + lib/glut/glut_vidresize.c \ + lib/glut/glut_warp.c \ + lib/glut/glut_win.c \ + lib/glut/glut_winmisc.c \ + lib/glut/layerutil.c \ + lib/glut/win32_glx.c \ + lib/glut/win32_menu.c \ + lib/glut/win32_util.c \ + lib/glut/win32_winproc.c \ + lib/glut/win32_x11.c \ + lib/mui/browseparse.c \ + lib/mui/browser.c \ + lib/mui/button.c \ + lib/mui/displaylist.c \ + lib/mui/gizmo.c \ + lib/mui/glutmui.c \ + lib/mui/hslider.c \ + lib/mui/miscui.c \ + lib/mui/mui.c \ + lib/mui/pulldown.c \ + lib/mui/textlist.c \ + lib/mui/uicolor.c \ + lib/mui/vslider.c diff --git a/lib/glut-3.7.6/glut.dsw b/lib/glut-3.7.6/glut.dsw new file mode 100644 index 0000000000..e796b28919 --- /dev/null +++ b/lib/glut-3.7.6/glut.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "glut32"=".\lib\glut\glut32.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/glutdefs b/lib/glut-3.7.6/glutdefs new file mode 100644 index 0000000000..05955b92c3 --- /dev/null +++ b/lib/glut-3.7.6/glutdefs @@ -0,0 +1,50 @@ +# +# glutdefs - common SGI Makefile defines for building GLUT +# +# Copyright (c) Mark J. Kilgard, 1997. +# + +# By default, we build for the "least common denominator" +# object style with is "old" 32-bit style. Set your +# OBJECT_STYLE environment variable to build GLUT's demos +# and examples with some other ABI. For example, to build +# N32 with -mips3 support, use: +# +# setenv OBJECT_STYLE N32_M3 +# +#if !defined(OBJECT_STYLE) +OBJECT_STYLE=32 +#endif + +# Object style logic. Note: the NONE and R32 object style +# are not supported. +# +#if $(OBJECT_STYLE) == "64" +GLUT_LIB_SUFFIX=.n64 +#elif $(OBJECT_STYLE) == "64_M3" +GLUT_LIB_SUFFIX=.n64 +#elif $(OBJECT_STYLE) == "64_M4" +GLUT_LIB_SUFFIX=.n64 +#elif $(OBJECT_STYLE) == "32_ABI" +GLUT_LIB_SUFFIX= +#elif $(OBJECT_STYLE) == "N32" +GLUT_LIB_SUFFIX=.n32 +#elif $(OBJECT_STYLE) == "N32_M3" +GLUT_LIB_SUFFIX=.n32 +#elif $(OBJECT_STYLE) == "N32_M4" +GLUT_LIB_SUFFIX=.n32 +#elif $(OBJECT_STYLE) == "32" +GLUT_LIB_SUFFIX= +#elif $(OBJECT_STYLE) == "32_M2" +GLUT_LIB_SUFFIX= +#else +GLUT_LIB_SUFFIX= +#endif + +# Where to find the GLUT archive for the appropriate object style. +# +GLUT = $(TOP)/lib/glut$(GLUT_LIB_SUFFIX)/libglut.a +FGLUT = $(TOP)/lib/fglut$(GLUT_LIB_SUFFIX)/libfglut.a +MUI = $(TOP)/lib/mui$(GLUT_LIB_SUFFIX)/libmui.a +GLE = $(TOP)/lib/gle$(GLUT_LIB_SUFFIX)/libgle.a +GLSMAP = $(TOP)/lib/glsmap$(GLUT_LIB_SUFFIX)/libglsmap.a diff --git a/lib/glut-3.7.6/include/GL/fgl.h b/lib/glut-3.7.6/include/GL/fgl.h new file mode 100644 index 0000000000..64f981e6ec --- /dev/null +++ b/lib/glut-3.7.6/include/GL/fgl.h @@ -0,0 +1,1707 @@ + +C GLUT version of "GL/fgl.h" + +C Modifications from SGI IRIX 5.3 version: +C 1) F prefix removed from OpenGL constants. +C 2) Constants over 32 characters truncated to 32 characters. + +C *********************************************************** + +C AttribMask + integer*4 GL_CURRENT_BIT + parameter ( GL_CURRENT_BIT = 1 ) + integer*4 GL_POINT_BIT + parameter ( GL_POINT_BIT = 2 ) + integer*4 GL_LINE_BIT + parameter ( GL_LINE_BIT = 4 ) + integer*4 GL_POLYGON_BIT + parameter ( GL_POLYGON_BIT = 8 ) + integer*4 GL_POLYGON_STIPPLE_BIT + parameter ( GL_POLYGON_STIPPLE_BIT = 16 ) + integer*4 GL_PIXEL_MODE_BIT + parameter ( GL_PIXEL_MODE_BIT = 32 ) + integer*4 GL_LIGHTING_BIT + parameter ( GL_LIGHTING_BIT = 64 ) + integer*4 GL_FOG_BIT + parameter ( GL_FOG_BIT = 128 ) + integer*4 GL_DEPTH_BUFFER_BIT + parameter ( GL_DEPTH_BUFFER_BIT = 256 ) + integer*4 GL_ACCUM_BUFFER_BIT + parameter ( GL_ACCUM_BUFFER_BIT = 512 ) + integer*4 GL_STENCIL_BUFFER_BIT + parameter ( GL_STENCIL_BUFFER_BIT = 1024 ) + integer*4 GL_VIEWPORT_BIT + parameter ( GL_VIEWPORT_BIT = 2048 ) + integer*4 GL_TRANSFORM_BIT + parameter ( GL_TRANSFORM_BIT = 4096 ) + integer*4 GL_ENABLE_BIT + parameter ( GL_ENABLE_BIT = 8192 ) + integer*4 GL_COLOR_BUFFER_BIT + parameter ( GL_COLOR_BUFFER_BIT = 16384 ) + integer*4 GL_HINT_BIT + parameter ( GL_HINT_BIT = 32768 ) + integer*4 GL_EVAL_BIT + parameter ( GL_EVAL_BIT = 65536 ) + integer*4 GL_LIST_BIT + parameter ( GL_LIST_BIT = 131072 ) + integer*4 GL_TEXTURE_BIT + parameter ( GL_TEXTURE_BIT = 262144 ) + integer*4 GL_SCISSOR_BIT + parameter ( GL_SCISSOR_BIT = 524288 ) + integer*4 GL_ALL_ATTRIB_BITS + parameter ( GL_ALL_ATTRIB_BITS = 1048575 ) +C GL_MULTISAMPLE_BIT_EXT + +C ClearBufferMask +C GL_COLOR_BUFFER_BIT +C GL_ACCUM_BUFFER_BIT +C GL_STENCIL_BUFFER_BIT +C GL_DEPTH_BUFFER_BIT + +C Boolean + integer*4 GL_FALSE + parameter ( GL_FALSE = 0 ) + integer*4 GL_TRUE + parameter ( GL_TRUE = 1 ) + +C BeginMode + integer*4 GL_POINTS + parameter ( GL_POINTS = 0 ) + integer*4 GL_LINES + parameter ( GL_LINES = 1 ) + integer*4 GL_LINE_LOOP + parameter ( GL_LINE_LOOP = 2 ) + integer*4 GL_LINE_STRIP + parameter ( GL_LINE_STRIP = 3 ) + integer*4 GL_TRIANGLES + parameter ( GL_TRIANGLES = 4 ) + integer*4 GL_TRIANGLE_STRIP + parameter ( GL_TRIANGLE_STRIP = 5 ) + integer*4 GL_TRIANGLE_FAN + parameter ( GL_TRIANGLE_FAN = 6 ) + integer*4 GL_QUADS + parameter ( GL_QUADS = 7 ) + integer*4 GL_QUAD_STRIP + parameter ( GL_QUAD_STRIP = 8 ) + integer*4 GL_POLYGON + parameter ( GL_POLYGON = 9 ) + +C AccumOp + integer*4 GL_ACCUM + parameter ( GL_ACCUM = 256 ) + integer*4 GL_LOAD + parameter ( GL_LOAD = 257 ) + integer*4 GL_RETURN + parameter ( GL_RETURN = 258 ) + integer*4 GL_MULT + parameter ( GL_MULT = 259 ) + integer*4 GL_ADD + parameter ( GL_ADD = 260 ) + +C AlphaFunction + integer*4 GL_NEVER + parameter ( GL_NEVER = 512 ) + integer*4 GL_LESS + parameter ( GL_LESS = 513 ) + integer*4 GL_EQUAL + parameter ( GL_EQUAL = 514 ) + integer*4 GL_LEQUAL + parameter ( GL_LEQUAL = 515 ) + integer*4 GL_GREATER + parameter ( GL_GREATER = 516 ) + integer*4 GL_NOTEQUAL + parameter ( GL_NOTEQUAL = 517 ) + integer*4 GL_GEQUAL + parameter ( GL_GEQUAL = 518 ) + integer*4 GL_ALWAYS + parameter ( GL_ALWAYS = 519 ) + +C BlendingFactorDest + integer*4 GL_ZERO + parameter ( GL_ZERO = 0 ) + integer*4 GL_ONE + parameter ( GL_ONE = 1 ) + integer*4 GL_SRC_COLOR + parameter ( GL_SRC_COLOR = 768 ) + integer*4 GL_ONE_MINUS_SRC_COLOR + parameter ( GL_ONE_MINUS_SRC_COLOR = 769 ) + integer*4 GL_SRC_ALPHA + parameter ( GL_SRC_ALPHA = 770 ) + integer*4 GL_ONE_MINUS_SRC_ALPHA + parameter ( GL_ONE_MINUS_SRC_ALPHA = 771 ) + integer*4 GL_DST_ALPHA + parameter ( GL_DST_ALPHA = 772 ) + integer*4 GL_ONE_MINUS_DST_ALPHA + parameter ( GL_ONE_MINUS_DST_ALPHA = 773 ) +C GL_CONSTANT_COLOR_EXT +C GL_ONE_MINUS_CONSTANT_COLOR_EXT +C GL_CONSTANT_ALPHA_EXT +C GL_ONE_MINUS_CONSTANT_ALPHA_EXT + +C BlendingFactorSrc +C GL_ZERO +C GL_ONE + integer*4 GL_DST_COLOR + parameter ( GL_DST_COLOR = 774 ) + integer*4 GL_ONE_MINUS_DST_COLOR + parameter ( GL_ONE_MINUS_DST_COLOR = 775 ) + integer*4 GL_SRC_ALPHA_SATURATE + parameter ( GL_SRC_ALPHA_SATURATE = 776 ) +C GL_SRC_ALPHA +C GL_ONE_MINUS_SRC_ALPHA +C GL_DST_ALPHA +C GL_ONE_MINUS_DST_ALPHA +C GL_CONSTANT_COLOR_EXT +C GL_ONE_MINUS_CONSTANT_COLOR_EXT +C GL_CONSTANT_ALPHA_EXT +C GL_ONE_MINUS_CONSTANT_ALPHA_EXT + +C BlendingMode +C GL_LOGIC_OP +C GL_FUNC_ADD_EXT +C GL_MIN_EXT +C GL_MAX_EXT +C GL_FUNC_SUBTRACT_EXT +C GL_FUNC_REVERSE_SUBTRACT_EXT + +C ColorMaterialFace +C GL_FRONT +C GL_BACK +C GL_FRONT_AND_BACK + +C ColorMaterialParameter +C GL_AMBIENT +C GL_DIFFUSE +C GL_SPECULAR +C GL_EMISSION +C GL_AMBIENT_AND_DIFFUSE + +C ConvolutionBorderMode +C GL_REDUCE_EXT + +C ConvolutionParameter +C GL_CONVOLUTION_BORDER_MODE_EXT +C GL_CONVOLUTION_FILTER_SCALE_EXT +C GL_CONVOLUTION_FILTER_BIAS_EXT + +C ConvolutionTarget +C GL_CONVOLUTION_1D_EXT +C GL_CONVOLUTION_2D_EXT + +C CullFaceMode +C GL_FRONT +C GL_BACK +C GL_FRONT_AND_BACK + +C DepthFunction +C GL_NEVER +C GL_LESS +C GL_EQUAL +C GL_LEQUAL +C GL_GREATER +C GL_NOTEQUAL +C GL_GEQUAL +C GL_ALWAYS + +C DrawBufferMode + integer*4 GL_NONE + parameter ( GL_NONE = 0 ) + integer*4 GL_FRONT_LEFT + parameter ( GL_FRONT_LEFT = 1024 ) + integer*4 GL_FRONT_RIGHT + parameter ( GL_FRONT_RIGHT = 1025 ) + integer*4 GL_BACK_LEFT + parameter ( GL_BACK_LEFT = 1026 ) + integer*4 GL_BACK_RIGHT + parameter ( GL_BACK_RIGHT = 1027 ) + integer*4 GL_FRONT + parameter ( GL_FRONT = 1028 ) + integer*4 GL_BACK + parameter ( GL_BACK = 1029 ) + integer*4 GL_LEFT + parameter ( GL_LEFT = 1030 ) + integer*4 GL_RIGHT + parameter ( GL_RIGHT = 1031 ) + integer*4 GL_FRONT_AND_BACK + parameter ( GL_FRONT_AND_BACK = 1032 ) + integer*4 GL_AUX0 + parameter ( GL_AUX0 = 1033 ) + integer*4 GL_AUX1 + parameter ( GL_AUX1 = 1034 ) + integer*4 GL_AUX2 + parameter ( GL_AUX2 = 1035 ) + integer*4 GL_AUX3 + parameter ( GL_AUX3 = 1036 ) + +C Enable +C GL_FOG +C GL_LIGHTING +C GL_TEXTURE_1D +C GL_TEXTURE_2D +C GL_LINE_STIPPLE +C GL_POLYGON_STIPPLE +C GL_CULL_FACE +C GL_ALPHA_TEST +C GL_BLEND +C GL_LOGIC_OP +C GL_DITHER +C GL_STENCIL_TEST +C GL_DEPTH_TEST +C GL_CLIP_PLANE0 +C GL_CLIP_PLANE1 +C GL_CLIP_PLANE2 +C GL_CLIP_PLANE3 +C GL_CLIP_PLANE4 +C GL_CLIP_PLANE5 +C GL_LIGHT0 +C GL_LIGHT1 +C GL_LIGHT2 +C GL_LIGHT3 +C GL_LIGHT4 +C GL_LIGHT5 +C GL_LIGHT6 +C GL_LIGHT7 +C GL_TEXTURE_GEN_S +C GL_TEXTURE_GEN_T +C GL_TEXTURE_GEN_R +C GL_TEXTURE_GEN_Q +C GL_MAP1_VERTEX_3 +C GL_MAP1_VERTEX_4 +C GL_MAP1_COLOR_4 +C GL_MAP1_INDEX +C GL_MAP1_NORMAL +C GL_MAP1_TEXTURE_COORD_1 +C GL_MAP1_TEXTURE_COORD_2 +C GL_MAP1_TEXTURE_COORD_3 +C GL_MAP1_TEXTURE_COORD_4 +C GL_MAP2_VERTEX_3 +C GL_MAP2_VERTEX_4 +C GL_MAP2_COLOR_4 +C GL_MAP2_INDEX +C GL_MAP2_NORMAL +C GL_MAP2_TEXTURE_COORD_1 +C GL_MAP2_TEXTURE_COORD_2 +C GL_MAP2_TEXTURE_COORD_3 +C GL_MAP2_TEXTURE_COORD_4 +C GL_POINT_SMOOTH +C GL_LINE_SMOOTH +C GL_POLYGON_SMOOTH +C GL_SCISSOR_TEST +C GL_COLOR_MATERIAL +C GL_NORMALIZE +C GL_AUTO_NORMAL +C GL_CONVOLUTION_1D_EXT +C GL_CONVOLUTION_2D_EXT +C GL_SEPARABLE_2D_EXT +C GL_HISTOGRAM_EXT +C GL_MINMAX_EXT +C GL_POLYGON_OFFSET_EXT +C GL_TEXTURE_3D_EXT +C GL_MULTISAMPLE_SGIS +C GL_SAMPLE_ALPHA_TO_MASK_SGIS +C GL_SAMPLE_ALPHA_TO_ONE_SGIS +C GL_SAMPLE_MASK_SGIS + +C ErrorCode + integer*4 GL_NO_ERROR + parameter ( GL_NO_ERROR = 0 ) + integer*4 GL_INVALID_ENUM + parameter ( GL_INVALID_ENUM = 1280 ) + integer*4 GL_INVALID_VALUE + parameter ( GL_INVALID_VALUE = 1281 ) + integer*4 GL_INVALID_OPERATION + parameter ( GL_INVALID_OPERATION = 1282 ) + integer*4 GL_STACK_OVERFLOW + parameter ( GL_STACK_OVERFLOW = 1283 ) + integer*4 GL_STACK_UNDERFLOW + parameter ( GL_STACK_UNDERFLOW = 1284 ) + integer*4 GL_OUT_OF_MEMORY + parameter ( GL_OUT_OF_MEMORY = 1285 ) +C GL_TABLE_TOO_LARGE_EXT +C GL_TEXTURE_TOO_LARGE_EXT + +C FeedBackMode + integer*4 GL_2D + parameter ( GL_2D = 1536 ) + integer*4 GL_3D + parameter ( GL_3D = 1537 ) + integer*4 GL_3D_COLOR + parameter ( GL_3D_COLOR = 1538 ) + integer*4 GL_3D_COLOR_TEXTURE + parameter ( GL_3D_COLOR_TEXTURE = 1539 ) + integer*4 GL_4D_COLOR_TEXTURE + parameter ( GL_4D_COLOR_TEXTURE = 1540 ) + +C FeedBackToken + integer*4 GL_PASS_THROUGH_TOKEN + parameter ( GL_PASS_THROUGH_TOKEN = 1792 ) + integer*4 GL_POINT_TOKEN + parameter ( GL_POINT_TOKEN = 1793 ) + integer*4 GL_LINE_TOKEN + parameter ( GL_LINE_TOKEN = 1794 ) + integer*4 GL_POLYGON_TOKEN + parameter ( GL_POLYGON_TOKEN = 1795 ) + integer*4 GL_BITMAP_TOKEN + parameter ( GL_BITMAP_TOKEN = 1796 ) + integer*4 GL_DRAW_PIXEL_TOKEN + parameter ( GL_DRAW_PIXEL_TOKEN = 1797 ) + integer*4 GL_COPY_PIXEL_TOKEN + parameter ( GL_COPY_PIXEL_TOKEN = 1798 ) + integer*4 GL_LINE_RESET_TOKEN + parameter ( GL_LINE_RESET_TOKEN = 1799 ) + +C FogMode +C GL_LINEAR + integer*4 GL_EXP + parameter ( GL_EXP = 2048 ) + integer*4 GL_EXP2 + parameter ( GL_EXP2 = 2049 ) + +C FogParameter +C GL_FOG_COLOR +C GL_FOG_DENSITY +C GL_FOG_END +C GL_FOG_INDEX +C GL_FOG_MODE +C GL_FOG_START + +C FrontFaceDirection + integer*4 GL_CW + parameter ( GL_CW = 2304 ) + integer*4 GL_CCW + parameter ( GL_CCW = 2305 ) + +C GetConvolutionParameter +C GL_CONVOLUTION_BORDER_MODE_EXT +C GL_CONVOLUTION_FILTER_SCALE_EXT +C GL_CONVOLUTION_FILTER_BIAS_EXT +C GL_CONVOLUTION_FORMAT_EXT +C GL_CONVOLUTION_WIDTH_EXT +C GL_CONVOLUTION_HEIGHT_EXT +C GL_MAX_CONVOLUTION_WIDTH_EXT +C GL_MAX_CONVOLUTION_HEIGHT_EXT + +C GetHistogramParameter +C GL_HISTOGRAM_WIDTH_EXT +C GL_HISTOGRAM_FORMAT_EXT +C GL_HISTOGRAM_RED_SIZE_EXT +C GL_HISTOGRAM_GREEN_SIZE_EXT +C GL_HISTOGRAM_BLUE_SIZE_EXT +C GL_HISTOGRAM_ALPHA_SIZE_EXT +C GL_HISTOGRAM_LUMINANCE_SIZE_EXT +C GL_HISTOGRAM_SINK_EXT + +C GetMapTarget + integer*4 GL_COEFF + parameter ( GL_COEFF = 2560 ) + integer*4 GL_ORDER + parameter ( GL_ORDER = 2561 ) + integer*4 GL_DOMAIN + parameter ( GL_DOMAIN = 2562 ) + +C GetMinmaxParameter +C GL_MINMAX_FORMAT_EXT +C GL_MINMAX_SINK_EXT + +C GetPixelMap + integer*4 GL_PIXEL_MAP_I_TO_I + parameter ( GL_PIXEL_MAP_I_TO_I = 3184 ) + integer*4 GL_PIXEL_MAP_S_TO_S + parameter ( GL_PIXEL_MAP_S_TO_S = 3185 ) + integer*4 GL_PIXEL_MAP_I_TO_R + parameter ( GL_PIXEL_MAP_I_TO_R = 3186 ) + integer*4 GL_PIXEL_MAP_I_TO_G + parameter ( GL_PIXEL_MAP_I_TO_G = 3187 ) + integer*4 GL_PIXEL_MAP_I_TO_B + parameter ( GL_PIXEL_MAP_I_TO_B = 3188 ) + integer*4 GL_PIXEL_MAP_I_TO_A + parameter ( GL_PIXEL_MAP_I_TO_A = 3189 ) + integer*4 GL_PIXEL_MAP_R_TO_R + parameter ( GL_PIXEL_MAP_R_TO_R = 3190 ) + integer*4 GL_PIXEL_MAP_G_TO_G + parameter ( GL_PIXEL_MAP_G_TO_G = 3191 ) + integer*4 GL_PIXEL_MAP_B_TO_B + parameter ( GL_PIXEL_MAP_B_TO_B = 3192 ) + integer*4 GL_PIXEL_MAP_A_TO_A + parameter ( GL_PIXEL_MAP_A_TO_A = 3193 ) + +C GetTarget + integer*4 GL_CURRENT_COLOR + parameter ( GL_CURRENT_COLOR = 2816 ) + integer*4 GL_CURRENT_INDEX + parameter ( GL_CURRENT_INDEX = 2817 ) + integer*4 GL_CURRENT_NORMAL + parameter ( GL_CURRENT_NORMAL = 2818 ) + integer*4 GL_CURRENT_TEXTURE_COORDS + parameter ( GL_CURRENT_TEXTURE_COORDS = 2819 ) + integer*4 GL_CURRENT_RASTER_COLOR + parameter ( GL_CURRENT_RASTER_COLOR = 2820 ) + integer*4 GL_CURRENT_RASTER_INDEX + parameter ( GL_CURRENT_RASTER_INDEX = 2821 ) + integer*4 GL_CURRENT_RASTER_TEXTURE_COORDS + parameter ( GL_CURRENT_RASTER_TEXTURE_COORDS = 2822 ) + integer*4 GL_CURRENT_RASTER_POSITION + parameter ( GL_CURRENT_RASTER_POSITION = 2823 ) + integer*4 GL_CURRENT_RASTER_POSITION_VALID + parameter ( GL_CURRENT_RASTER_POSITION_VALID = 2824 ) + integer*4 GL_CURRENT_RASTER_DISTANCE + parameter ( GL_CURRENT_RASTER_DISTANCE = 2825 ) + integer*4 GL_POINT_SMOOTH + parameter ( GL_POINT_SMOOTH = 2832 ) + integer*4 GL_POINT_SIZE + parameter ( GL_POINT_SIZE = 2833 ) + integer*4 GL_POINT_SIZE_RANGE + parameter ( GL_POINT_SIZE_RANGE = 2834 ) + integer*4 GL_POINT_SIZE_GRANULARITY + parameter ( GL_POINT_SIZE_GRANULARITY = 2835 ) + integer*4 GL_LINE_SMOOTH + parameter ( GL_LINE_SMOOTH = 2848 ) + integer*4 GL_LINE_WIDTH + parameter ( GL_LINE_WIDTH = 2849 ) + integer*4 GL_LINE_WIDTH_RANGE + parameter ( GL_LINE_WIDTH_RANGE = 2850 ) + integer*4 GL_LINE_WIDTH_GRANULARITY + parameter ( GL_LINE_WIDTH_GRANULARITY = 2851 ) + integer*4 GL_LINE_STIPPLE + parameter ( GL_LINE_STIPPLE = 2852 ) + integer*4 GL_LINE_STIPPLE_PATTERN + parameter ( GL_LINE_STIPPLE_PATTERN = 2853 ) + integer*4 GL_LINE_STIPPLE_REPEAT + parameter ( GL_LINE_STIPPLE_REPEAT = 2854 ) + integer*4 GL_LIST_MODE + parameter ( GL_LIST_MODE = 2864 ) + integer*4 GL_MAX_LIST_NESTING + parameter ( GL_MAX_LIST_NESTING = 2865 ) + integer*4 GL_LIST_BASE + parameter ( GL_LIST_BASE = 2866 ) + integer*4 GL_LIST_INDEX + parameter ( GL_LIST_INDEX = 2867 ) + integer*4 GL_POLYGON_MODE + parameter ( GL_POLYGON_MODE = 2880 ) + integer*4 GL_POLYGON_SMOOTH + parameter ( GL_POLYGON_SMOOTH = 2881 ) + integer*4 GL_POLYGON_STIPPLE + parameter ( GL_POLYGON_STIPPLE = 2882 ) + integer*4 GL_EDGE_FLAG + parameter ( GL_EDGE_FLAG = 2883 ) + integer*4 GL_CULL_FACE + parameter ( GL_CULL_FACE = 2884 ) + integer*4 GL_CULL_FACE_MODE + parameter ( GL_CULL_FACE_MODE = 2885 ) + integer*4 GL_FRONT_FACE + parameter ( GL_FRONT_FACE = 2886 ) + integer*4 GL_LIGHTING + parameter ( GL_LIGHTING = 2896 ) + integer*4 GL_LIGHT_MODEL_LOCAL_VIEWER + parameter ( GL_LIGHT_MODEL_LOCAL_VIEWER = 2897 ) + integer*4 GL_LIGHT_MODEL_TWO_SIDE + parameter ( GL_LIGHT_MODEL_TWO_SIDE = 2898 ) + integer*4 GL_LIGHT_MODEL_AMBIENT + parameter ( GL_LIGHT_MODEL_AMBIENT = 2899 ) + integer*4 GL_SHADE_MODEL + parameter ( GL_SHADE_MODEL = 2900 ) + integer*4 GL_COLOR_MATERIAL_FACE + parameter ( GL_COLOR_MATERIAL_FACE = 2901 ) + integer*4 GL_COLOR_MATERIAL_PARAMETER + parameter ( GL_COLOR_MATERIAL_PARAMETER = 2902 ) + integer*4 GL_COLOR_MATERIAL + parameter ( GL_COLOR_MATERIAL = 2903 ) + integer*4 GL_FOG + parameter ( GL_FOG = 2912 ) + integer*4 GL_FOG_INDEX + parameter ( GL_FOG_INDEX = 2913 ) + integer*4 GL_FOG_DENSITY + parameter ( GL_FOG_DENSITY = 2914 ) + integer*4 GL_FOG_START + parameter ( GL_FOG_START = 2915 ) + integer*4 GL_FOG_END + parameter ( GL_FOG_END = 2916 ) + integer*4 GL_FOG_MODE + parameter ( GL_FOG_MODE = 2917 ) + integer*4 GL_FOG_COLOR + parameter ( GL_FOG_COLOR = 2918 ) + integer*4 GL_DEPTH_RANGE + parameter ( GL_DEPTH_RANGE = 2928 ) + integer*4 GL_DEPTH_TEST + parameter ( GL_DEPTH_TEST = 2929 ) + integer*4 GL_DEPTH_WRITEMASK + parameter ( GL_DEPTH_WRITEMASK = 2930 ) + integer*4 GL_DEPTH_CLEAR_VALUE + parameter ( GL_DEPTH_CLEAR_VALUE = 2931 ) + integer*4 GL_DEPTH_FUNC + parameter ( GL_DEPTH_FUNC = 2932 ) + integer*4 GL_ACCUM_CLEAR_VALUE + parameter ( GL_ACCUM_CLEAR_VALUE = 2944 ) + integer*4 GL_STENCIL_TEST + parameter ( GL_STENCIL_TEST = 2960 ) + integer*4 GL_STENCIL_CLEAR_VALUE + parameter ( GL_STENCIL_CLEAR_VALUE = 2961 ) + integer*4 GL_STENCIL_FUNC + parameter ( GL_STENCIL_FUNC = 2962 ) + integer*4 GL_STENCIL_VALUE_MASK + parameter ( GL_STENCIL_VALUE_MASK = 2963 ) + integer*4 GL_STENCIL_FAIL + parameter ( GL_STENCIL_FAIL = 2964 ) + integer*4 GL_STENCIL_PASS_DEPTH_FAIL + parameter ( GL_STENCIL_PASS_DEPTH_FAIL = 2965 ) + integer*4 GL_STENCIL_PASS_DEPTH_PASS + parameter ( GL_STENCIL_PASS_DEPTH_PASS = 2966 ) + integer*4 GL_STENCIL_REF + parameter ( GL_STENCIL_REF = 2967 ) + integer*4 GL_STENCIL_WRITEMASK + parameter ( GL_STENCIL_WRITEMASK = 2968 ) + integer*4 GL_MATRIX_MODE + parameter ( GL_MATRIX_MODE = 2976 ) + integer*4 GL_NORMALIZE + parameter ( GL_NORMALIZE = 2977 ) + integer*4 GL_VIEWPORT + parameter ( GL_VIEWPORT = 2978 ) + integer*4 GL_MODELVIEW_STACK_DEPTH + parameter ( GL_MODELVIEW_STACK_DEPTH = 2979 ) + integer*4 GL_PROJECTION_STACK_DEPTH + parameter ( GL_PROJECTION_STACK_DEPTH = 2980 ) + integer*4 GL_TEXTURE_STACK_DEPTH + parameter ( GL_TEXTURE_STACK_DEPTH = 2981 ) + integer*4 GL_MODELVIEW_MATRIX + parameter ( GL_MODELVIEW_MATRIX = 2982 ) + integer*4 GL_PROJECTION_MATRIX + parameter ( GL_PROJECTION_MATRIX = 2983 ) + integer*4 GL_TEXTURE_MATRIX + parameter ( GL_TEXTURE_MATRIX = 2984 ) + integer*4 GL_ATTRIB_STACK_DEPTH + parameter ( GL_ATTRIB_STACK_DEPTH = 2992 ) + integer*4 GL_ALPHA_TEST + parameter ( GL_ALPHA_TEST = 3008 ) + integer*4 GL_ALPHA_TEST_FUNC + parameter ( GL_ALPHA_TEST_FUNC = 3009 ) + integer*4 GL_ALPHA_TEST_REF + parameter ( GL_ALPHA_TEST_REF = 3010 ) + integer*4 GL_DITHER + parameter ( GL_DITHER = 3024 ) + integer*4 GL_BLEND_DST + parameter ( GL_BLEND_DST = 3040 ) + integer*4 GL_BLEND_SRC + parameter ( GL_BLEND_SRC = 3041 ) + integer*4 GL_BLEND + parameter ( GL_BLEND = 3042 ) + integer*4 GL_LOGIC_OP_MODE + parameter ( GL_LOGIC_OP_MODE = 3056 ) + integer*4 GL_LOGIC_OP + parameter ( GL_LOGIC_OP = 3057 ) + integer*4 GL_AUX_BUFFERS + parameter ( GL_AUX_BUFFERS = 3072 ) + integer*4 GL_DRAW_BUFFER + parameter ( GL_DRAW_BUFFER = 3073 ) + integer*4 GL_READ_BUFFER + parameter ( GL_READ_BUFFER = 3074 ) + integer*4 GL_SCISSOR_BOX + parameter ( GL_SCISSOR_BOX = 3088 ) + integer*4 GL_SCISSOR_TEST + parameter ( GL_SCISSOR_TEST = 3089 ) + integer*4 GL_INDEX_CLEAR_VALUE + parameter ( GL_INDEX_CLEAR_VALUE = 3104 ) + integer*4 GL_INDEX_WRITEMASK + parameter ( GL_INDEX_WRITEMASK = 3105 ) + integer*4 GL_COLOR_CLEAR_VALUE + parameter ( GL_COLOR_CLEAR_VALUE = 3106 ) + integer*4 GL_COLOR_WRITEMASK + parameter ( GL_COLOR_WRITEMASK = 3107 ) + integer*4 GL_INDEX_MODE + parameter ( GL_INDEX_MODE = 3120 ) + integer*4 GL_RGBA_MODE + parameter ( GL_RGBA_MODE = 3121 ) + integer*4 GL_DOUBLEBUFFER + parameter ( GL_DOUBLEBUFFER = 3122 ) + integer*4 GL_STEREO + parameter ( GL_STEREO = 3123 ) + integer*4 GL_RENDER_MODE + parameter ( GL_RENDER_MODE = 3136 ) + integer*4 GL_PERSPECTIVE_CORRECTION_HINT + parameter ( GL_PERSPECTIVE_CORRECTION_HINT = 3152 ) + integer*4 GL_POINT_SMOOTH_HINT + parameter ( GL_POINT_SMOOTH_HINT = 3153 ) + integer*4 GL_LINE_SMOOTH_HINT + parameter ( GL_LINE_SMOOTH_HINT = 3154 ) + integer*4 GL_POLYGON_SMOOTH_HINT + parameter ( GL_POLYGON_SMOOTH_HINT = 3155 ) + integer*4 GL_FOG_HINT + parameter ( GL_FOG_HINT = 3156 ) + integer*4 GL_TEXTURE_GEN_S + parameter ( GL_TEXTURE_GEN_S = 3168 ) + integer*4 GL_TEXTURE_GEN_T + parameter ( GL_TEXTURE_GEN_T = 3169 ) + integer*4 GL_TEXTURE_GEN_R + parameter ( GL_TEXTURE_GEN_R = 3170 ) + integer*4 GL_TEXTURE_GEN_Q + parameter ( GL_TEXTURE_GEN_Q = 3171 ) + integer*4 GL_PIXEL_MAP_I_TO_I_SIZE + parameter ( GL_PIXEL_MAP_I_TO_I_SIZE = 3248 ) + integer*4 GL_PIXEL_MAP_S_TO_S_SIZE + parameter ( GL_PIXEL_MAP_S_TO_S_SIZE = 3249 ) + integer*4 GL_PIXEL_MAP_I_TO_R_SIZE + parameter ( GL_PIXEL_MAP_I_TO_R_SIZE = 3250 ) + integer*4 GL_PIXEL_MAP_I_TO_G_SIZE + parameter ( GL_PIXEL_MAP_I_TO_G_SIZE = 3251 ) + integer*4 GL_PIXEL_MAP_I_TO_B_SIZE + parameter ( GL_PIXEL_MAP_I_TO_B_SIZE = 3252 ) + integer*4 GL_PIXEL_MAP_I_TO_A_SIZE + parameter ( GL_PIXEL_MAP_I_TO_A_SIZE = 3253 ) + integer*4 GL_PIXEL_MAP_R_TO_R_SIZE + parameter ( GL_PIXEL_MAP_R_TO_R_SIZE = 3254 ) + integer*4 GL_PIXEL_MAP_G_TO_G_SIZE + parameter ( GL_PIXEL_MAP_G_TO_G_SIZE = 3255 ) + integer*4 GL_PIXEL_MAP_B_TO_B_SIZE + parameter ( GL_PIXEL_MAP_B_TO_B_SIZE = 3256 ) + integer*4 GL_PIXEL_MAP_A_TO_A_SIZE + parameter ( GL_PIXEL_MAP_A_TO_A_SIZE = 3257 ) + integer*4 GL_UNPACK_SWAP_BYTES + parameter ( GL_UNPACK_SWAP_BYTES = 3312 ) + integer*4 GL_UNPACK_LSB_FIRST + parameter ( GL_UNPACK_LSB_FIRST = 3313 ) + integer*4 GL_UNPACK_ROW_LENGTH + parameter ( GL_UNPACK_ROW_LENGTH = 3314 ) + integer*4 GL_UNPACK_SKIP_ROWS + parameter ( GL_UNPACK_SKIP_ROWS = 3315 ) + integer*4 GL_UNPACK_SKIP_PIXELS + parameter ( GL_UNPACK_SKIP_PIXELS = 3316 ) + integer*4 GL_UNPACK_ALIGNMENT + parameter ( GL_UNPACK_ALIGNMENT = 3317 ) + integer*4 GL_PACK_SWAP_BYTES + parameter ( GL_PACK_SWAP_BYTES = 3328 ) + integer*4 GL_PACK_LSB_FIRST + parameter ( GL_PACK_LSB_FIRST = 3329 ) + integer*4 GL_PACK_ROW_LENGTH + parameter ( GL_PACK_ROW_LENGTH = 3330 ) + integer*4 GL_PACK_SKIP_ROWS + parameter ( GL_PACK_SKIP_ROWS = 3331 ) + integer*4 GL_PACK_SKIP_PIXELS + parameter ( GL_PACK_SKIP_PIXELS = 3332 ) + integer*4 GL_PACK_ALIGNMENT + parameter ( GL_PACK_ALIGNMENT = 3333 ) + integer*4 GL_MAP_COLOR + parameter ( GL_MAP_COLOR = 3344 ) + integer*4 GL_MAP_STENCIL + parameter ( GL_MAP_STENCIL = 3345 ) + integer*4 GL_INDEX_SHIFT + parameter ( GL_INDEX_SHIFT = 3346 ) + integer*4 GL_INDEX_OFFSET + parameter ( GL_INDEX_OFFSET = 3347 ) + integer*4 GL_RED_SCALE + parameter ( GL_RED_SCALE = 3348 ) + integer*4 GL_RED_BIAS + parameter ( GL_RED_BIAS = 3349 ) + integer*4 GL_ZOOM_X + parameter ( GL_ZOOM_X = 3350 ) + integer*4 GL_ZOOM_Y + parameter ( GL_ZOOM_Y = 3351 ) + integer*4 GL_GREEN_SCALE + parameter ( GL_GREEN_SCALE = 3352 ) + integer*4 GL_GREEN_BIAS + parameter ( GL_GREEN_BIAS = 3353 ) + integer*4 GL_BLUE_SCALE + parameter ( GL_BLUE_SCALE = 3354 ) + integer*4 GL_BLUE_BIAS + parameter ( GL_BLUE_BIAS = 3355 ) + integer*4 GL_ALPHA_SCALE + parameter ( GL_ALPHA_SCALE = 3356 ) + integer*4 GL_ALPHA_BIAS + parameter ( GL_ALPHA_BIAS = 3357 ) + integer*4 GL_DEPTH_SCALE + parameter ( GL_DEPTH_SCALE = 3358 ) + integer*4 GL_DEPTH_BIAS + parameter ( GL_DEPTH_BIAS = 3359 ) + integer*4 GL_MAX_EVAL_ORDER + parameter ( GL_MAX_EVAL_ORDER = 3376 ) + integer*4 GL_MAX_LIGHTS + parameter ( GL_MAX_LIGHTS = 3377 ) + integer*4 GL_MAX_CLIP_PLANES + parameter ( GL_MAX_CLIP_PLANES = 3378 ) + integer*4 GL_MAX_TEXTURE_SIZE + parameter ( GL_MAX_TEXTURE_SIZE = 3379 ) + integer*4 GL_MAX_PIXEL_MAP_TABLE + parameter ( GL_MAX_PIXEL_MAP_TABLE = 3380 ) + integer*4 GL_MAX_ATTRIB_STACK_DEPTH + parameter ( GL_MAX_ATTRIB_STACK_DEPTH = 3381 ) + integer*4 GL_MAX_MODELVIEW_STACK_DEPTH + parameter ( GL_MAX_MODELVIEW_STACK_DEPTH = 3382 ) + integer*4 GL_MAX_NAME_STACK_DEPTH + parameter ( GL_MAX_NAME_STACK_DEPTH = 3383 ) + integer*4 GL_MAX_PROJECTION_STACK_DEPTH + parameter ( GL_MAX_PROJECTION_STACK_DEPTH = 3384 ) + integer*4 GL_MAX_TEXTURE_STACK_DEPTH + parameter ( GL_MAX_TEXTURE_STACK_DEPTH = 3385 ) + integer*4 GL_MAX_VIEWPORT_DIMS + parameter ( GL_MAX_VIEWPORT_DIMS = 3386 ) + integer*4 GL_SUBPIXEL_BITS + parameter ( GL_SUBPIXEL_BITS = 3408 ) + integer*4 GL_INDEX_BITS + parameter ( GL_INDEX_BITS = 3409 ) + integer*4 GL_RED_BITS + parameter ( GL_RED_BITS = 3410 ) + integer*4 GL_GREEN_BITS + parameter ( GL_GREEN_BITS = 3411 ) + integer*4 GL_BLUE_BITS + parameter ( GL_BLUE_BITS = 3412 ) + integer*4 GL_ALPHA_BITS + parameter ( GL_ALPHA_BITS = 3413 ) + integer*4 GL_DEPTH_BITS + parameter ( GL_DEPTH_BITS = 3414 ) + integer*4 GL_STENCIL_BITS + parameter ( GL_STENCIL_BITS = 3415 ) + integer*4 GL_ACCUM_RED_BITS + parameter ( GL_ACCUM_RED_BITS = 3416 ) + integer*4 GL_ACCUM_GREEN_BITS + parameter ( GL_ACCUM_GREEN_BITS = 3417 ) + integer*4 GL_ACCUM_BLUE_BITS + parameter ( GL_ACCUM_BLUE_BITS = 3418 ) + integer*4 GL_ACCUM_ALPHA_BITS + parameter ( GL_ACCUM_ALPHA_BITS = 3419 ) + integer*4 GL_NAME_STACK_DEPTH + parameter ( GL_NAME_STACK_DEPTH = 3440 ) + integer*4 GL_AUTO_NORMAL + parameter ( GL_AUTO_NORMAL = 3456 ) + integer*4 GL_MAP1_COLOR_4 + parameter ( GL_MAP1_COLOR_4 = 3472 ) + integer*4 GL_MAP1_INDEX + parameter ( GL_MAP1_INDEX = 3473 ) + integer*4 GL_MAP1_NORMAL + parameter ( GL_MAP1_NORMAL = 3474 ) + integer*4 GL_MAP1_TEXTURE_COORD_1 + parameter ( GL_MAP1_TEXTURE_COORD_1 = 3475 ) + integer*4 GL_MAP1_TEXTURE_COORD_2 + parameter ( GL_MAP1_TEXTURE_COORD_2 = 3476 ) + integer*4 GL_MAP1_TEXTURE_COORD_3 + parameter ( GL_MAP1_TEXTURE_COORD_3 = 3477 ) + integer*4 GL_MAP1_TEXTURE_COORD_4 + parameter ( GL_MAP1_TEXTURE_COORD_4 = 3478 ) + integer*4 GL_MAP1_VERTEX_3 + parameter ( GL_MAP1_VERTEX_3 = 3479 ) + integer*4 GL_MAP1_VERTEX_4 + parameter ( GL_MAP1_VERTEX_4 = 3480 ) + integer*4 GL_MAP2_COLOR_4 + parameter ( GL_MAP2_COLOR_4 = 3504 ) + integer*4 GL_MAP2_INDEX + parameter ( GL_MAP2_INDEX = 3505 ) + integer*4 GL_MAP2_NORMAL + parameter ( GL_MAP2_NORMAL = 3506 ) + integer*4 GL_MAP2_TEXTURE_COORD_1 + parameter ( GL_MAP2_TEXTURE_COORD_1 = 3507 ) + integer*4 GL_MAP2_TEXTURE_COORD_2 + parameter ( GL_MAP2_TEXTURE_COORD_2 = 3508 ) + integer*4 GL_MAP2_TEXTURE_COORD_3 + parameter ( GL_MAP2_TEXTURE_COORD_3 = 3509 ) + integer*4 GL_MAP2_TEXTURE_COORD_4 + parameter ( GL_MAP2_TEXTURE_COORD_4 = 3510 ) + integer*4 GL_MAP2_VERTEX_3 + parameter ( GL_MAP2_VERTEX_3 = 3511 ) + integer*4 GL_MAP2_VERTEX_4 + parameter ( GL_MAP2_VERTEX_4 = 3512 ) + integer*4 GL_MAP1_GRID_DOMAIN + parameter ( GL_MAP1_GRID_DOMAIN = 3536 ) + integer*4 GL_MAP1_GRID_SEGMENTS + parameter ( GL_MAP1_GRID_SEGMENTS = 3537 ) + integer*4 GL_MAP2_GRID_DOMAIN + parameter ( GL_MAP2_GRID_DOMAIN = 3538 ) + integer*4 GL_MAP2_GRID_SEGMENTS + parameter ( GL_MAP2_GRID_SEGMENTS = 3539 ) + integer*4 GL_TEXTURE_1D + parameter ( GL_TEXTURE_1D = 3552 ) + integer*4 GL_TEXTURE_2D + parameter ( GL_TEXTURE_2D = 3553 ) +C GL_BLEND_COLOR_EXT +C GL_BLEND_EQUATION_EXT +C GL_CONVOLUTION_1D_EXT +C GL_CONVOLUTION_2D_EXT +C GL_SEPARABLE_2D_EXT +C GL_POST_CONVOLUTION_RED_SCALE_EXT +C GL_POST_CONVOLUTION_GREEN_SCALE_EXT +C GL_POST_CONVOLUTION_BLUE_SCALE_EXT +C GL_POST_CONVOLUTION_ALPHA_SCALE_EXT +C GL_POST_CONVOLUTION_RED_BIAS_EXT +C GL_POST_CONVOLUTION_GREEN_BIAS_EXT +C GL_POST_CONVOLUTION_BLUE_BIAS_EXT +C GL_POST_CONVOLUTION_ALPHA_BIAS_EXT +C GL_HISTOGRAM_EXT +C GL_MINMAX_EXT +C GL_POLYGON_OFFSET_EXT +C GL_POLYGON_OFFSET_FACTOR_EXT +C GL_POLYGON_OFFSET_BIAS_EXT +C GL_PACK_SKIP_IMAGES_EXT +C GL_PACK_IMAGE_HEIGHT_EXT +C GL_UNPACK_SKIP_IMAGES_EXT +C GL_UNPACK_IMAGE_HEIGHT_EXT +C GL_TEXTURE_3D_EXT +C GL_MAX_3D_TEXTURE_SIZE_EXT +C GL_DETAIL_TEXTURE_2D_BINDING_SGIS +C GL_MULTISAMPLE_SGIS +C GL_SAMPLE_ALPHA_TO_MASK_SGIS +C GL_SAMPLE_ALPHA_TO_ONE_SGIS +C GL_SAMPLE_MASK_SGIS +C GL_SAMPLE_BUFFERS_SGIS +C GL_SAMPLES_SGIS +C GL_SAMPLE_MASK_VALUE_SGIS +C GL_SAMPLE_MASK_INVERT_SGIS +C GL_SAMPLE_PATTERN_SGIS + +C GetTextureParameter +C GL_TEXTURE_MAG_FILTER +C GL_TEXTURE_MIN_FILTER +C GL_TEXTURE_WRAP_S +C GL_TEXTURE_WRAP_T + integer*4 GL_TEXTURE_WIDTH + parameter ( GL_TEXTURE_WIDTH = 4096 ) + integer*4 GL_TEXTURE_HEIGHT + parameter ( GL_TEXTURE_HEIGHT = 4097 ) + integer*4 GL_TEXTURE_COMPONENTS + parameter ( GL_TEXTURE_COMPONENTS = 4099 ) + integer*4 GL_TEXTURE_BORDER_COLOR + parameter ( GL_TEXTURE_BORDER_COLOR = 4100 ) + integer*4 GL_TEXTURE_BORDER + parameter ( GL_TEXTURE_BORDER = 4101 ) +C GL_TEXTURE_RED_SIZE_EXT +C GL_TEXTURE_GREEN_SIZE_EXT +C GL_TEXTURE_BLUE_SIZE_EXT +C GL_TEXTURE_ALPHA_SIZE_EXT +C GL_TEXTURE_LUMINANCE_SIZE_EXT +C GL_TEXTURE_INTENSITY_SIZE_EXT +C GL_TEXTURE_DEPTH_EXT +C GL_TEXTURE_WRAP_R_EXT +C GL_DETAIL_TEXTURE_LEVEL_SGIS +C GL_DETAIL_TEXTURE_MODE_SGIS +C GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS +C GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS + +C HintMode + integer*4 GL_DONT_CARE + parameter ( GL_DONT_CARE = 4352 ) + integer*4 GL_FASTEST + parameter ( GL_FASTEST = 4353 ) + integer*4 GL_NICEST + parameter ( GL_NICEST = 4354 ) + +C HintTarget +C GL_PERSPECTIVE_CORRECTION_HINT +C GL_POINT_SMOOTH_HINT +C GL_LINE_SMOOTH_HINT +C GL_POLYGON_SMOOTH_HINT +C GL_FOG_HINT + +C HistogramTarget +C GL_HISTOGRAM_EXT +C GL_PROXY_HISTOGRAM_EXT + +C LightModelParameter +C GL_LIGHT_MODEL_AMBIENT +C GL_LIGHT_MODEL_LOCAL_VIEWER +C GL_LIGHT_MODEL_TWO_SIDE + +C LightParameter + integer*4 GL_AMBIENT + parameter ( GL_AMBIENT = 4608 ) + integer*4 GL_DIFFUSE + parameter ( GL_DIFFUSE = 4609 ) + integer*4 GL_SPECULAR + parameter ( GL_SPECULAR = 4610 ) + integer*4 GL_POSITION + parameter ( GL_POSITION = 4611 ) + integer*4 GL_SPOT_DIRECTION + parameter ( GL_SPOT_DIRECTION = 4612 ) + integer*4 GL_SPOT_EXPONENT + parameter ( GL_SPOT_EXPONENT = 4613 ) + integer*4 GL_SPOT_CUTOFF + parameter ( GL_SPOT_CUTOFF = 4614 ) + integer*4 GL_CONSTANT_ATTENUATION + parameter ( GL_CONSTANT_ATTENUATION = 4615 ) + integer*4 GL_LINEAR_ATTENUATION + parameter ( GL_LINEAR_ATTENUATION = 4616 ) + integer*4 GL_QUADRATIC_ATTENUATION + parameter ( GL_QUADRATIC_ATTENUATION = 4617 ) + +C ListMode + integer*4 GL_COMPILE + parameter ( GL_COMPILE = 4864 ) + integer*4 GL_COMPILE_AND_EXECUTE + parameter ( GL_COMPILE_AND_EXECUTE = 4865 ) + +C ListNameType + integer*4 GL_BYTE + parameter ( GL_BYTE = 5120 ) + integer*4 GL_UNSIGNED_BYTE + parameter ( GL_UNSIGNED_BYTE = 5121 ) + integer*4 GL_SHORT + parameter ( GL_SHORT = 5122 ) + integer*4 GL_UNSIGNED_SHORT + parameter ( GL_UNSIGNED_SHORT = 5123 ) + integer*4 GL_INT + parameter ( GL_INT = 5124 ) + integer*4 GL_UNSIGNED_INT + parameter ( GL_UNSIGNED_INT = 5125 ) + integer*4 GL_FLOAT + parameter ( GL_FLOAT = 5126 ) + integer*4 GL_2_BYTES + parameter ( GL_2_BYTES = 5127 ) + integer*4 GL_3_BYTES + parameter ( GL_3_BYTES = 5128 ) + integer*4 GL_4_BYTES + parameter ( GL_4_BYTES = 5129 ) + +C LogicOp + integer*4 GL_CLEAR + parameter ( GL_CLEAR = 5376 ) + integer*4 GL_AND + parameter ( GL_AND = 5377 ) + integer*4 GL_AND_REVERSE + parameter ( GL_AND_REVERSE = 5378 ) + integer*4 GL_COPY + parameter ( GL_COPY = 5379 ) + integer*4 GL_AND_INVERTED + parameter ( GL_AND_INVERTED = 5380 ) + integer*4 GL_NOOP + parameter ( GL_NOOP = 5381 ) + integer*4 GL_XOR + parameter ( GL_XOR = 5382 ) + integer*4 GL_OR + parameter ( GL_OR = 5383 ) + integer*4 GL_NOR + parameter ( GL_NOR = 5384 ) + integer*4 GL_EQUIV + parameter ( GL_EQUIV = 5385 ) + integer*4 GL_INVERT + parameter ( GL_INVERT = 5386 ) + integer*4 GL_OR_REVERSE + parameter ( GL_OR_REVERSE = 5387 ) + integer*4 GL_COPY_INVERTED + parameter ( GL_COPY_INVERTED = 5388 ) + integer*4 GL_OR_INVERTED + parameter ( GL_OR_INVERTED = 5389 ) + integer*4 GL_NAND + parameter ( GL_NAND = 5390 ) + integer*4 GL_SET + parameter ( GL_SET = 5391 ) + +C MapTarget +C GL_MAP1_COLOR_4 +C GL_MAP1_INDEX +C GL_MAP1_NORMAL +C GL_MAP1_TEXTURE_COORD_1 +C GL_MAP1_TEXTURE_COORD_2 +C GL_MAP1_TEXTURE_COORD_3 +C GL_MAP1_TEXTURE_COORD_4 +C GL_MAP1_VERTEX_3 +C GL_MAP1_VERTEX_4 +C GL_MAP2_COLOR_4 +C GL_MAP2_INDEX +C GL_MAP2_NORMAL +C GL_MAP2_TEXTURE_COORD_1 +C GL_MAP2_TEXTURE_COORD_2 +C GL_MAP2_TEXTURE_COORD_3 +C GL_MAP2_TEXTURE_COORD_4 +C GL_MAP2_VERTEX_3 +C GL_MAP2_VERTEX_4 + +C MaterialFace +C GL_FRONT +C GL_BACK +C GL_FRONT_AND_BACK + +C MaterialParameter + integer*4 GL_EMISSION + parameter ( GL_EMISSION = 5632 ) + integer*4 GL_SHININESS + parameter ( GL_SHININESS = 5633 ) + integer*4 GL_AMBIENT_AND_DIFFUSE + parameter ( GL_AMBIENT_AND_DIFFUSE = 5634 ) + integer*4 GL_COLOR_INDEXES + parameter ( GL_COLOR_INDEXES = 5635 ) +C GL_AMBIENT +C GL_DIFFUSE +C GL_SPECULAR + +C MatrixMode + integer*4 GL_MODELVIEW + parameter ( GL_MODELVIEW = 5888 ) + integer*4 GL_PROJECTION + parameter ( GL_PROJECTION = 5889 ) + integer*4 GL_TEXTURE + parameter ( GL_TEXTURE = 5890 ) + +C MeshMode1 +C GL_POINT +C GL_LINE + +C MeshMode2 +C GL_POINT +C GL_LINE +C GL_FILL + +C MinmaxTarget +C GL_MINMAX_EXT + +C PixelCopyType + integer*4 GL_COLOR + parameter ( GL_COLOR = 6144 ) + integer*4 GL_DEPTH + parameter ( GL_DEPTH = 6145 ) + integer*4 GL_STENCIL + parameter ( GL_STENCIL = 6146 ) + +C PixelFormat + integer*4 GL_COLOR_INDEX + parameter ( GL_COLOR_INDEX = 6400 ) + integer*4 GL_STENCIL_INDEX + parameter ( GL_STENCIL_INDEX = 6401 ) + integer*4 GL_DEPTH_COMPONENT + parameter ( GL_DEPTH_COMPONENT = 6402 ) + integer*4 GL_RED + parameter ( GL_RED = 6403 ) + integer*4 GL_GREEN + parameter ( GL_GREEN = 6404 ) + integer*4 GL_BLUE + parameter ( GL_BLUE = 6405 ) + integer*4 GL_ALPHA + parameter ( GL_ALPHA = 6406 ) + integer*4 GL_RGB + parameter ( GL_RGB = 6407 ) + integer*4 GL_RGBA + parameter ( GL_RGBA = 6408 ) + integer*4 GL_LUMINANCE + parameter ( GL_LUMINANCE = 6409 ) + integer*4 GL_LUMINANCE_ALPHA + parameter ( GL_LUMINANCE_ALPHA = 6410 ) +C GL_ABGR_EXT + +C PixelInternalFormat +C GL_ALPHA4_EXT +C GL_ALPHA8_EXT +C GL_ALPHA12_EXT +C GL_ALPHA16_EXT +C GL_LUMINANCE4_EXT +C GL_LUMINANCE8_EXT +C GL_LUMINANCE12_EXT +C GL_LUMINANCE16_EXT +C GL_LUMINANCE4_ALPHA4_EXT +C GL_LUMINANCE6_ALPHA2_EXT +C GL_LUMINANCE8_ALPHA8_EXT +C GL_LUMINANCE12_ALPHA4_EXT +C GL_LUMINANCE12_ALPHA12_EXT +C GL_LUMINANCE16_ALPHA16_EXT +C GL_INTENSITY_EXT +C GL_INTENSITY4_EXT +C GL_INTENSITY8_EXT +C GL_INTENSITY12_EXT +C GL_INTENSITY16_EXT +C GL_RGB2_EXT +C GL_RGB4_EXT +C GL_RGB5_EXT +C GL_RGB8_EXT +C GL_RGB10_EXT +C GL_RGB12_EXT +C GL_RGB16_EXT +C GL_RGBA2_EXT +C GL_RGBA4_EXT +C GL_RGB5_A1_EXT +C GL_RGBA8_EXT +C GL_RGB10_A2_EXT +C GL_RGBA12_EXT +C GL_RGBA16_EXT + +C PixelMap +C GL_PIXEL_MAP_I_TO_I +C GL_PIXEL_MAP_S_TO_S +C GL_PIXEL_MAP_I_TO_R +C GL_PIXEL_MAP_I_TO_G +C GL_PIXEL_MAP_I_TO_B +C GL_PIXEL_MAP_I_TO_A +C GL_PIXEL_MAP_R_TO_R +C GL_PIXEL_MAP_G_TO_G +C GL_PIXEL_MAP_B_TO_B +C GL_PIXEL_MAP_A_TO_A + +C PixelStore +C GL_UNPACK_SWAP_BYTES +C GL_UNPACK_LSB_FIRST +C GL_UNPACK_ROW_LENGTH +C GL_UNPACK_SKIP_ROWS +C GL_UNPACK_SKIP_PIXELS +C GL_UNPACK_ALIGNMENT +C GL_PACK_SWAP_BYTES +C GL_PACK_LSB_FIRST +C GL_PACK_ROW_LENGTH +C GL_PACK_SKIP_ROWS +C GL_PACK_SKIP_PIXELS +C GL_PACK_ALIGNMENT +C GL_PACK_SKIP_IMAGES_EXT +C GL_PACK_IMAGE_HEIGHT_EXT +C GL_UNPACK_SKIP_IMAGES_EXT +C GL_UNPACK_IMAGE_HEIGHT_EXT + +C PixelTransfer +C GL_MAP_COLOR +C GL_MAP_STENCIL +C GL_INDEX_SHIFT +C GL_INDEX_OFFSET +C GL_RED_SCALE +C GL_RED_BIAS +C GL_GREEN_SCALE +C GL_GREEN_BIAS +C GL_BLUE_SCALE +C GL_BLUE_BIAS +C GL_ALPHA_SCALE +C GL_ALPHA_BIAS +C GL_DEPTH_SCALE +C GL_DEPTH_BIAS +C GL_POST_CONVOLUTION_RED_SCALE_EXT +C GL_POST_CONVOLUTION_GREEN_SCALE_EXT +C GL_POST_CONVOLUTION_BLUE_SCALE_EXT +C GL_POST_CONVOLUTION_ALPHA_SCALE_EXT +C GL_POST_CONVOLUTION_RED_BIAS_EXT +C GL_POST_CONVOLUTION_GREEN_BIAS_EXT +C GL_POST_CONVOLUTION_BLUE_BIAS_EXT +C GL_POST_CONVOLUTION_ALPHA_BIAS_EXT + +C PixelType + integer*4 GL_BITMAP + parameter ( GL_BITMAP = 6656 ) +C GL_BYTE +C GL_UNSIGNED_BYTE +C GL_SHORT +C GL_UNSIGNED_SHORT +C GL_INT +C GL_UNSIGNED_INT +C GL_FLOAT + +C PolygonMode + integer*4 GL_POINT + parameter ( GL_POINT = 6912 ) + integer*4 GL_LINE + parameter ( GL_LINE = 6913 ) + integer*4 GL_FILL + parameter ( GL_FILL = 6914 ) + +C ReadBufferMode +C GL_FRONT_LEFT +C GL_FRONT_RIGHT +C GL_BACK_LEFT +C GL_BACK_RIGHT +C GL_FRONT +C GL_BACK +C GL_LEFT +C GL_RIGHT +C GL_AUX0 +C GL_AUX1 +C GL_AUX2 +C GL_AUX3 + +C RenderingMode + integer*4 GL_RENDER + parameter ( GL_RENDER = 7168 ) + integer*4 GL_FEEDBACK + parameter ( GL_FEEDBACK = 7169 ) + integer*4 GL_SELECT + parameter ( GL_SELECT = 7170 ) + +C SamplePattern +C GL_1PASS_SGIS +C GL_2PASS_0_SGIS +C GL_2PASS_1_SGIS +C GL_4PASS_0_SGIS +C GL_4PASS_1_SGIS +C GL_4PASS_2_SGIS +C GL_4PASS_3_SGIS + +C SeparableTarget +C GL_SEPARABLE_2D_EXT + +C ShadingModel + integer*4 GL_FLAT + parameter ( GL_FLAT = 7424 ) + integer*4 GL_SMOOTH + parameter ( GL_SMOOTH = 7425 ) + +C StencilFunction +C GL_NEVER +C GL_LESS +C GL_EQUAL +C GL_LEQUAL +C GL_GREATER +C GL_NOTEQUAL +C GL_GEQUAL +C GL_ALWAYS + +C StencilOp +C GL_ZERO + integer*4 GL_KEEP + parameter ( GL_KEEP = 7680 ) + integer*4 GL_REPLACE + parameter ( GL_REPLACE = 7681 ) + integer*4 GL_INCR + parameter ( GL_INCR = 7682 ) + integer*4 GL_DECR + parameter ( GL_DECR = 7683 ) +C GL_INVERT + +C StringName + integer*4 GL_VENDOR + parameter ( GL_VENDOR = 7936 ) + integer*4 GL_RENDERER + parameter ( GL_RENDERER = 7937 ) + integer*4 GL_VERSION + parameter ( GL_VERSION = 7938 ) + integer*4 GL_EXTENSIONS + parameter ( GL_EXTENSIONS = 7939 ) + +C TextureCoordName + integer*4 GL_S + parameter ( GL_S = 8192 ) + integer*4 GL_T + parameter ( GL_T = 8193 ) + integer*4 GL_R + parameter ( GL_R = 8194 ) + integer*4 GL_Q + parameter ( GL_Q = 8195 ) + +C TextureEnvMode + integer*4 GL_MODULATE + parameter ( GL_MODULATE = 8448 ) + integer*4 GL_DECAL + parameter ( GL_DECAL = 8449 ) +C GL_BLEND +C GL_REPLACE_EXT + +C TextureEnvParameter + integer*4 GL_TEXTURE_ENV_MODE + parameter ( GL_TEXTURE_ENV_MODE = 8704 ) + integer*4 GL_TEXTURE_ENV_COLOR + parameter ( GL_TEXTURE_ENV_COLOR = 8705 ) + +C TextureEnvTarget + integer*4 GL_TEXTURE_ENV + parameter ( GL_TEXTURE_ENV = 8960 ) + +C TextureGenMode + integer*4 GL_EYE_LINEAR + parameter ( GL_EYE_LINEAR = 9216 ) + integer*4 GL_OBJECT_LINEAR + parameter ( GL_OBJECT_LINEAR = 9217 ) + integer*4 GL_SPHERE_MAP + parameter ( GL_SPHERE_MAP = 9218 ) + +C TextureGenParameter + integer*4 GL_TEXTURE_GEN_MODE + parameter ( GL_TEXTURE_GEN_MODE = 9472 ) + integer*4 GL_OBJECT_PLANE + parameter ( GL_OBJECT_PLANE = 9473 ) + integer*4 GL_EYE_PLANE + parameter ( GL_EYE_PLANE = 9474 ) + +C TextureMagFilter + integer*4 GL_NEAREST + parameter ( GL_NEAREST = 9728 ) + integer*4 GL_LINEAR + parameter ( GL_LINEAR = 9729 ) +C GL_LINEAR_DETAIL_SGIS +C GL_LINEAR_DETAIL_ALPHA_SGIS +C GL_LINEAR_DETAIL_COLOR_SGIS +C GL_LINEAR_SHARPEN_SGIS +C GL_LINEAR_SHARPEN_ALPHA_SGIS +C GL_LINEAR_SHARPEN_COLOR_SGIS + +C TextureMinFilter +C GL_NEAREST +C GL_LINEAR + integer*4 GL_NEAREST_MIPMAP_NEAREST + parameter ( GL_NEAREST_MIPMAP_NEAREST = 9984 ) + integer*4 GL_LINEAR_MIPMAP_NEAREST + parameter ( GL_LINEAR_MIPMAP_NEAREST = 9985 ) + integer*4 GL_NEAREST_MIPMAP_LINEAR + parameter ( GL_NEAREST_MIPMAP_LINEAR = 9986 ) + integer*4 GL_LINEAR_MIPMAP_LINEAR + parameter ( GL_LINEAR_MIPMAP_LINEAR = 9987 ) + +C TextureParameterName + integer*4 GL_TEXTURE_MAG_FILTER + parameter ( GL_TEXTURE_MAG_FILTER = 10240 ) + integer*4 GL_TEXTURE_MIN_FILTER + parameter ( GL_TEXTURE_MIN_FILTER = 10241 ) + integer*4 GL_TEXTURE_WRAP_S + parameter ( GL_TEXTURE_WRAP_S = 10242 ) + integer*4 GL_TEXTURE_WRAP_T + parameter ( GL_TEXTURE_WRAP_T = 10243 ) +C GL_TEXTURE_BORDER_COLOR +C GL_TEXTURE_WRAP_R_EXT +C GL_DETAIL_TEXTURE_LEVEL_SGIS +C GL_DETAIL_TEXTURE_MODE_SGIS + +C TextureTarget +C GL_TEXTURE_1D +C GL_TEXTURE_2D +C GL_PROXY_TEXTURE_1D_EXT +C GL_PROXY_TEXTURE_2D_EXT +C GL_TEXTURE_3D_EXT +C GL_PROXY_TEXTURE_3D_EXT +C GL_DETAIL_TEXTURE_2D_SGIS + +C TextureWrapMode + integer*4 GL_CLAMP + parameter ( GL_CLAMP = 10496 ) + integer*4 GL_REPEAT + parameter ( GL_REPEAT = 10497 ) + +C ClipPlaneName + integer*4 GL_CLIP_PLANE0 + parameter ( GL_CLIP_PLANE0 = 12288 ) + integer*4 GL_CLIP_PLANE1 + parameter ( GL_CLIP_PLANE1 = 12289 ) + integer*4 GL_CLIP_PLANE2 + parameter ( GL_CLIP_PLANE2 = 12290 ) + integer*4 GL_CLIP_PLANE3 + parameter ( GL_CLIP_PLANE3 = 12291 ) + integer*4 GL_CLIP_PLANE4 + parameter ( GL_CLIP_PLANE4 = 12292 ) + integer*4 GL_CLIP_PLANE5 + parameter ( GL_CLIP_PLANE5 = 12293 ) + +C LightName + integer*4 GL_LIGHT0 + parameter ( GL_LIGHT0 = 16384 ) + integer*4 GL_LIGHT1 + parameter ( GL_LIGHT1 = 16385 ) + integer*4 GL_LIGHT2 + parameter ( GL_LIGHT2 = 16386 ) + integer*4 GL_LIGHT3 + parameter ( GL_LIGHT3 = 16387 ) + integer*4 GL_LIGHT4 + parameter ( GL_LIGHT4 = 16388 ) + integer*4 GL_LIGHT5 + parameter ( GL_LIGHT5 = 16389 ) + integer*4 GL_LIGHT6 + parameter ( GL_LIGHT6 = 16390 ) + integer*4 GL_LIGHT7 + parameter ( GL_LIGHT7 = 16391 ) + +C Extensions + integer*4 GL_EXT_abgr + parameter ( GL_EXT_abgr = 1 ) + integer*4 GL_EXT_blend_color + parameter ( GL_EXT_blend_color = 1 ) + integer*4 GL_EXT_blend_logic_op + parameter ( GL_EXT_blend_logic_op = 1 ) + integer*4 GL_EXT_blend_minmax + parameter ( GL_EXT_blend_minmax = 1 ) + integer*4 GL_EXT_blend_subtract + parameter ( GL_EXT_blend_subtract = 1 ) + integer*4 GL_EXT_convolution + parameter ( GL_EXT_convolution = 1 ) + integer*4 GL_EXT_histogram + parameter ( GL_EXT_histogram = 1 ) + integer*4 GL_EXT_polygon_offset + parameter ( GL_EXT_polygon_offset = 1 ) + integer*4 GL_EXT_subtexture + parameter ( GL_EXT_subtexture = 1 ) + integer*4 GL_EXT_texture + parameter ( GL_EXT_texture = 1 ) + integer*4 GL_EXT_texture3D + parameter ( GL_EXT_texture3D = 1 ) + integer*4 GL_SGIS_detail_texture + parameter ( GL_SGIS_detail_texture = 1 ) + integer*4 GL_SGIS_multisample + parameter ( GL_SGIS_multisample = 1 ) + integer*4 GL_SGIS_sharpen_texture + parameter ( GL_SGIS_sharpen_texture = 1 ) + +C EXT_abgr + integer*4 GL_ABGR_EXT + parameter ( GL_ABGR_EXT = 32768 ) + +C EXT_blend_color + integer*4 GL_CONSTANT_COLOR_EXT + parameter ( GL_CONSTANT_COLOR_EXT = 32769 ) + integer*4 GL_ONE_MINUS_CONSTANT_COLOR_EXT + parameter ( GL_ONE_MINUS_CONSTANT_COLOR_EXT = 32770 ) + integer*4 GL_CONSTANT_ALPHA_EXT + parameter ( GL_CONSTANT_ALPHA_EXT = 32771 ) + integer*4 GL_ONE_MINUS_CONSTANT_ALPHA_EXT + parameter ( GL_ONE_MINUS_CONSTANT_ALPHA_EXT = 32772 ) + integer*4 GL_BLEND_COLOR_EXT + parameter ( GL_BLEND_COLOR_EXT = 32773 ) + +C EXT_blend_minmax + integer*4 GL_FUNC_ADD_EXT + parameter ( GL_FUNC_ADD_EXT = 32774 ) + integer*4 GL_MIN_EXT + parameter ( GL_MIN_EXT = 32775 ) + integer*4 GL_MAX_EXT + parameter ( GL_MAX_EXT = 32776 ) + integer*4 GL_BLEND_EQUATION_EXT + parameter ( GL_BLEND_EQUATION_EXT = 32777 ) + +C EXT_blend_subtract + integer*4 GL_FUNC_SUBTRACT_EXT + parameter ( GL_FUNC_SUBTRACT_EXT = 32778 ) + integer*4 GL_FUNC_REVERSE_SUBTRACT_EXT + parameter ( GL_FUNC_REVERSE_SUBTRACT_EXT = 32779 ) + +C EXT_convolution + integer*4 GL_CONVOLUTION_1D_EXT + parameter ( GL_CONVOLUTION_1D_EXT = 32784 ) + integer*4 GL_CONVOLUTION_2D_EXT + parameter ( GL_CONVOLUTION_2D_EXT = 32785 ) + integer*4 GL_SEPARABLE_2D_EXT + parameter ( GL_SEPARABLE_2D_EXT = 32786 ) + integer*4 GL_CONVOLUTION_BORDER_MODE_EXT + parameter ( GL_CONVOLUTION_BORDER_MODE_EXT = 32787 ) + integer*4 GL_CONVOLUTION_FILTER_SCALE_EXT + parameter ( GL_CONVOLUTION_FILTER_SCALE_EXT = 32788 ) + integer*4 GL_CONVOLUTION_FILTER_BIAS_EXT + parameter ( GL_CONVOLUTION_FILTER_BIAS_EXT = 32789 ) + integer*4 GL_REDUCE_EXT + parameter ( GL_REDUCE_EXT = 32790 ) + integer*4 GL_CONVOLUTION_FORMAT_EXT + parameter ( GL_CONVOLUTION_FORMAT_EXT = 32791 ) + integer*4 GL_CONVOLUTION_WIDTH_EXT + parameter ( GL_CONVOLUTION_WIDTH_EXT = 32792 ) + integer*4 GL_CONVOLUTION_HEIGHT_EXT + parameter ( GL_CONVOLUTION_HEIGHT_EXT = 32793 ) + integer*4 GL_MAX_CONVOLUTION_WIDTH_EXT + parameter ( GL_MAX_CONVOLUTION_WIDTH_EXT = 32794 ) + integer*4 GL_MAX_CONVOLUTION_HEIGHT_EXT + parameter ( GL_MAX_CONVOLUTION_HEIGHT_EXT = 32795 ) + integer*4 GL_POST_CONVOLUTION_RED_SCALE_EX + parameter ( GL_POST_CONVOLUTION_RED_SCALE_EX = 32796 ) + integer*4 GL_POST_CONVOLUTION_GREEN_SCALE_ + parameter ( GL_POST_CONVOLUTION_GREEN_SCALE_ = 32797 ) + integer*4 GL_POST_CONVOLUTION_BLUE_SCALE_E + parameter ( GL_POST_CONVOLUTION_BLUE_SCALE_E = 32798 ) + integer*4 GL_POST_CONVOLUTION_ALPHA_SCALE_ + parameter ( GL_POST_CONVOLUTION_ALPHA_SCALE_ = 32799 ) + integer*4 GL_POST_CONVOLUTION_RED_BIAS_EXT + parameter ( GL_POST_CONVOLUTION_RED_BIAS_EXT = 32800 ) + integer*4 GL_POST_CONVOLUTION_GREEN_BIAS_E + parameter ( GL_POST_CONVOLUTION_GREEN_BIAS_E = 32801 ) + integer*4 GL_POST_CONVOLUTION_BLUE_BIAS_EX + parameter ( GL_POST_CONVOLUTION_BLUE_BIAS_EX = 32802 ) + integer*4 GL_POST_CONVOLUTION_ALPHA_BIAS_E + parameter ( GL_POST_CONVOLUTION_ALPHA_BIAS_E = 32803 ) + +C EXT_histogram + integer*4 GL_HISTOGRAM_EXT + parameter ( GL_HISTOGRAM_EXT = 32804 ) + integer*4 GL_PROXY_HISTOGRAM_EXT + parameter ( GL_PROXY_HISTOGRAM_EXT = 32805 ) + integer*4 GL_HISTOGRAM_WIDTH_EXT + parameter ( GL_HISTOGRAM_WIDTH_EXT = 32806 ) + integer*4 GL_HISTOGRAM_FORMAT_EXT + parameter ( GL_HISTOGRAM_FORMAT_EXT = 32807 ) + integer*4 GL_HISTOGRAM_RED_SIZE_EXT + parameter ( GL_HISTOGRAM_RED_SIZE_EXT = 32808 ) + integer*4 GL_HISTOGRAM_GREEN_SIZE_EXT + parameter ( GL_HISTOGRAM_GREEN_SIZE_EXT = 32809 ) + integer*4 GL_HISTOGRAM_BLUE_SIZE_EXT + parameter ( GL_HISTOGRAM_BLUE_SIZE_EXT = 32810 ) + integer*4 GL_HISTOGRAM_ALPHA_SIZE_EXT + parameter ( GL_HISTOGRAM_ALPHA_SIZE_EXT = 32811 ) + integer*4 GL_HISTOGRAM_LUMINANCE_SIZE_EXT + parameter ( GL_HISTOGRAM_LUMINANCE_SIZE_EXT = 32812 ) + integer*4 GL_HISTOGRAM_SINK_EXT + parameter ( GL_HISTOGRAM_SINK_EXT = 32813 ) + integer*4 GL_MINMAX_EXT + parameter ( GL_MINMAX_EXT = 32814 ) + integer*4 GL_MINMAX_FORMAT_EXT + parameter ( GL_MINMAX_FORMAT_EXT = 32815 ) + integer*4 GL_MINMAX_SINK_EXT + parameter ( GL_MINMAX_SINK_EXT = 32816 ) + integer*4 GL_TABLE_TOO_LARGE_EXT + parameter ( GL_TABLE_TOO_LARGE_EXT = 32817 ) + +C EXT_polygon_offset + integer*4 GL_POLYGON_OFFSET_EXT + parameter ( GL_POLYGON_OFFSET_EXT = 32823 ) + integer*4 GL_POLYGON_OFFSET_FACTOR_EXT + parameter ( GL_POLYGON_OFFSET_FACTOR_EXT = 32824 ) + integer*4 GL_POLYGON_OFFSET_BIAS_EXT + parameter ( GL_POLYGON_OFFSET_BIAS_EXT = 32825 ) + +C EXT_texture + integer*4 GL_ALPHA4_EXT + parameter ( GL_ALPHA4_EXT = 32827 ) + integer*4 GL_ALPHA8_EXT + parameter ( GL_ALPHA8_EXT = 32828 ) + integer*4 GL_ALPHA12_EXT + parameter ( GL_ALPHA12_EXT = 32829 ) + integer*4 GL_ALPHA16_EXT + parameter ( GL_ALPHA16_EXT = 32830 ) + integer*4 GL_LUMINANCE4_EXT + parameter ( GL_LUMINANCE4_EXT = 32831 ) + integer*4 GL_LUMINANCE8_EXT + parameter ( GL_LUMINANCE8_EXT = 32832 ) + integer*4 GL_LUMINANCE12_EXT + parameter ( GL_LUMINANCE12_EXT = 32833 ) + integer*4 GL_LUMINANCE16_EXT + parameter ( GL_LUMINANCE16_EXT = 32834 ) + integer*4 GL_LUMINANCE4_ALPHA4_EXT + parameter ( GL_LUMINANCE4_ALPHA4_EXT = 32835 ) + integer*4 GL_LUMINANCE6_ALPHA2_EXT + parameter ( GL_LUMINANCE6_ALPHA2_EXT = 32836 ) + integer*4 GL_LUMINANCE8_ALPHA8_EXT + parameter ( GL_LUMINANCE8_ALPHA8_EXT = 32837 ) + integer*4 GL_LUMINANCE12_ALPHA4_EXT + parameter ( GL_LUMINANCE12_ALPHA4_EXT = 32838 ) + integer*4 GL_LUMINANCE12_ALPHA12_EXT + parameter ( GL_LUMINANCE12_ALPHA12_EXT = 32839 ) + integer*4 GL_LUMINANCE16_ALPHA16_EXT + parameter ( GL_LUMINANCE16_ALPHA16_EXT = 32840 ) + integer*4 GL_INTENSITY_EXT + parameter ( GL_INTENSITY_EXT = 32841 ) + integer*4 GL_INTENSITY4_EXT + parameter ( GL_INTENSITY4_EXT = 32842 ) + integer*4 GL_INTENSITY8_EXT + parameter ( GL_INTENSITY8_EXT = 32843 ) + integer*4 GL_INTENSITY12_EXT + parameter ( GL_INTENSITY12_EXT = 32844 ) + integer*4 GL_INTENSITY16_EXT + parameter ( GL_INTENSITY16_EXT = 32845 ) + integer*4 GL_RGB2_EXT + parameter ( GL_RGB2_EXT = 32846 ) + integer*4 GL_RGB4_EXT + parameter ( GL_RGB4_EXT = 32847 ) + integer*4 GL_RGB5_EXT + parameter ( GL_RGB5_EXT = 32848 ) + integer*4 GL_RGB8_EXT + parameter ( GL_RGB8_EXT = 32849 ) + integer*4 GL_RGB10_EXT + parameter ( GL_RGB10_EXT = 32850 ) + integer*4 GL_RGB12_EXT + parameter ( GL_RGB12_EXT = 32851 ) + integer*4 GL_RGB16_EXT + parameter ( GL_RGB16_EXT = 32852 ) + integer*4 GL_RGBA2_EXT + parameter ( GL_RGBA2_EXT = 32853 ) + integer*4 GL_RGBA4_EXT + parameter ( GL_RGBA4_EXT = 32854 ) + integer*4 GL_RGB5_A1_EXT + parameter ( GL_RGB5_A1_EXT = 32855 ) + integer*4 GL_RGBA8_EXT + parameter ( GL_RGBA8_EXT = 32856 ) + integer*4 GL_RGB10_A2_EXT + parameter ( GL_RGB10_A2_EXT = 32857 ) + integer*4 GL_RGBA12_EXT + parameter ( GL_RGBA12_EXT = 32858 ) + integer*4 GL_RGBA16_EXT + parameter ( GL_RGBA16_EXT = 32859 ) + integer*4 GL_TEXTURE_RED_SIZE_EXT + parameter ( GL_TEXTURE_RED_SIZE_EXT = 32860 ) + integer*4 GL_TEXTURE_GREEN_SIZE_EXT + parameter ( GL_TEXTURE_GREEN_SIZE_EXT = 32861 ) + integer*4 GL_TEXTURE_BLUE_SIZE_EXT + parameter ( GL_TEXTURE_BLUE_SIZE_EXT = 32862 ) + integer*4 GL_TEXTURE_ALPHA_SIZE_EXT + parameter ( GL_TEXTURE_ALPHA_SIZE_EXT = 32863 ) + integer*4 GL_TEXTURE_LUMINANCE_SIZE_EXT + parameter ( GL_TEXTURE_LUMINANCE_SIZE_EXT = 32864 ) + integer*4 GL_TEXTURE_INTENSITY_SIZE_EXT + parameter ( GL_TEXTURE_INTENSITY_SIZE_EXT = 32865 ) + integer*4 GL_REPLACE_EXT + parameter ( GL_REPLACE_EXT = 32866 ) + integer*4 GL_PROXY_TEXTURE_1D_EXT + parameter ( GL_PROXY_TEXTURE_1D_EXT = 32867 ) + integer*4 GL_PROXY_TEXTURE_2D_EXT + parameter ( GL_PROXY_TEXTURE_2D_EXT = 32868 ) + integer*4 GL_TEXTURE_TOO_LARGE_EXT + parameter ( GL_TEXTURE_TOO_LARGE_EXT = 32869 ) + +C EXT_texture3D + integer*4 GL_PACK_SKIP_IMAGES_EXT + parameter ( GL_PACK_SKIP_IMAGES_EXT = 32875 ) + integer*4 GL_PACK_IMAGE_HEIGHT_EXT + parameter ( GL_PACK_IMAGE_HEIGHT_EXT = 32876 ) + integer*4 GL_UNPACK_SKIP_IMAGES_EXT + parameter ( GL_UNPACK_SKIP_IMAGES_EXT = 32877 ) + integer*4 GL_UNPACK_IMAGE_HEIGHT_EXT + parameter ( GL_UNPACK_IMAGE_HEIGHT_EXT = 32878 ) + integer*4 GL_TEXTURE_3D_EXT + parameter ( GL_TEXTURE_3D_EXT = 32879 ) + integer*4 GL_PROXY_TEXTURE_3D_EXT + parameter ( GL_PROXY_TEXTURE_3D_EXT = 32880 ) + integer*4 GL_TEXTURE_DEPTH_EXT + parameter ( GL_TEXTURE_DEPTH_EXT = 32881 ) + integer*4 GL_TEXTURE_WRAP_R_EXT + parameter ( GL_TEXTURE_WRAP_R_EXT = 32882 ) + integer*4 GL_MAX_3D_TEXTURE_SIZE_EXT + parameter ( GL_MAX_3D_TEXTURE_SIZE_EXT = 32883 ) + +C SGIS_detail_texture + integer*4 GL_DETAIL_TEXTURE_2D_SGIS + parameter ( GL_DETAIL_TEXTURE_2D_SGIS = 32917 ) + integer*4 GL_DETAIL_TEXTURE_2D_BINDING_SGI + parameter ( GL_DETAIL_TEXTURE_2D_BINDING_SGI = 32918 ) + integer*4 GL_LINEAR_DETAIL_SGIS + parameter ( GL_LINEAR_DETAIL_SGIS = 32919 ) + integer*4 GL_LINEAR_DETAIL_ALPHA_SGIS + parameter ( GL_LINEAR_DETAIL_ALPHA_SGIS = 32920 ) + integer*4 GL_LINEAR_DETAIL_COLOR_SGIS + parameter ( GL_LINEAR_DETAIL_COLOR_SGIS = 32921 ) + integer*4 GL_DETAIL_TEXTURE_LEVEL_SGIS + parameter ( GL_DETAIL_TEXTURE_LEVEL_SGIS = 32922 ) + integer*4 GL_DETAIL_TEXTURE_MODE_SGIS + parameter ( GL_DETAIL_TEXTURE_MODE_SGIS = 32923 ) + integer*4 GL_DETAIL_TEXTURE_FUNC_POINTS_S + parameter ( GL_DETAIL_TEXTURE_FUNC_POINTS_S = 32924 ) + +C SGIS_multisample + integer*4 GL_MULTISAMPLE_BIT_EXT + parameter ( GL_MULTISAMPLE_BIT_EXT = 536870912 ) + integer*4 GL_MULTISAMPLE_SGIS + parameter ( GL_MULTISAMPLE_SGIS = 32925 ) + integer*4 GL_SAMPLE_ALPHA_TO_MASK_SGIS + parameter ( GL_SAMPLE_ALPHA_TO_MASK_SGIS = 32926 ) + integer*4 GL_SAMPLE_ALPHA_TO_ONE_SGIS + parameter ( GL_SAMPLE_ALPHA_TO_ONE_SGIS = 32927 ) + integer*4 GL_SAMPLE_MASK_SGIS + parameter ( GL_SAMPLE_MASK_SGIS = 32928 ) + integer*4 GL_1PASS_SGIS + parameter ( GL_1PASS_SGIS = 32929 ) + integer*4 GL_2PASS_0_SGIS + parameter ( GL_2PASS_0_SGIS = 32930 ) + integer*4 GL_2PASS_1_SGIS + parameter ( GL_2PASS_1_SGIS = 32931 ) + integer*4 GL_4PASS_0_SGIS + parameter ( GL_4PASS_0_SGIS = 32932 ) + integer*4 GL_4PASS_1_SGIS + parameter ( GL_4PASS_1_SGIS = 32933 ) + integer*4 GL_4PASS_2_SGIS + parameter ( GL_4PASS_2_SGIS = 32934 ) + integer*4 GL_4PASS_3_SGIS + parameter ( GL_4PASS_3_SGIS = 32935 ) + integer*4 GL_SAMPLE_BUFFERS_SGIS + parameter ( GL_SAMPLE_BUFFERS_SGIS = 32936 ) + integer*4 GL_SAMPLES_SGIS + parameter ( GL_SAMPLES_SGIS = 32937 ) + integer*4 GL_SAMPLE_MASK_VALUE_SGIS + parameter ( GL_SAMPLE_MASK_VALUE_SGIS = 32938 ) + integer*4 GL_SAMPLE_MASK_INVERT_SGIS + parameter ( GL_SAMPLE_MASK_INVERT_SGIS = 32939 ) + integer*4 GL_SAMPLE_PATTERN_SGIS + parameter ( GL_SAMPLE_PATTERN_SGIS = 32940 ) + +C SGIS_sharpen_texture + integer*4 GL_LINEAR_SHARPEN_SGIS + parameter ( GL_LINEAR_SHARPEN_SGIS = 32941 ) + integer*4 GL_LINEAR_SHARPEN_ALPHA_SGIS + parameter ( GL_LINEAR_SHARPEN_ALPHA_SGIS = 32942 ) + integer*4 GL_LINEAR_SHARPEN_COLOR_SGIS + parameter ( GL_LINEAR_SHARPEN_COLOR_SGIS = 32943 ) + integer*4 GL_SHARPEN_TEXTURE_FUNC_POINTS_S + parameter ( GL_SHARPEN_TEXTURE_FUNC_POINTS_S = 32944 ) + +C *********************************************************** + + + character*128 fglGetString + integer fglGetError + integer*4 fglRenderMode + logical*1 fglAreTexturesResidentEXT + logical*1 fglIsEnabled + logical*1 fglIsList + logical*1 fglIsTextureEXT + logical*4 fglGenLists + logical*4 fglGenTexturesEXT diff --git a/lib/glut-3.7.6/include/GL/fglu.h b/lib/glut-3.7.6/include/GL/fglu.h new file mode 100644 index 0000000000..0b0497675f --- /dev/null +++ b/lib/glut-3.7.6/include/GL/fglu.h @@ -0,0 +1,210 @@ + +C GLUT version of "GL/fgl.h" + +C Modifications from SGI IRIX 5.3 version: +C 1) F prefix removed from GLU constants. +C 2) Fix GLU_TRUE and GLU_FALSE. + +C *** Generic constants *** + +C Errors: (return value 0 = no error) + integer*4 GLU_INVALID_ENUM + parameter ( GLU_INVALID_ENUM = 100900 ) + integer*4 GLU_INVALID_VALUE + parameter ( GLU_INVALID_VALUE = 100901 ) + integer*4 GLU_OUT_OF_MEMORY + parameter ( GLU_OUT_OF_MEMORY = 100902 ) + +C For laughs: + integer*4 GLU_TRUE + parameter ( GLU_TRUE = 1 ) + integer*4 GLU_FALSE + parameter ( GLU_FALSE = 0 ) + + +C *** Quadric constants *** + +C Types of normals: + integer*4 GLU_SMOOTH + parameter ( GLU_SMOOTH = 100000 ) + integer*4 GLU_FLAT + parameter ( GLU_FLAT = 100001 ) + integer*4 GLU_NONE + parameter ( GLU_NONE = 100002 ) + +C DrawStyle types: + integer*4 GLU_POINT + parameter ( GLU_POINT = 100010 ) + integer*4 GLU_LINE + parameter ( GLU_LINE = 100011 ) + integer*4 GLU_FILL + parameter ( GLU_FILL = 100012 ) + integer*4 GLU_SILHOUETTE + parameter ( GLU_SILHOUETTE = 100013 ) + +C Orientation types: + integer*4 GLU_OUTSIDE + parameter ( GLU_OUTSIDE = 100020 ) + integer*4 GLU_INSIDE + parameter ( GLU_INSIDE = 100021 ) + +C Callback types: +C GLU_ERROR 100103 + + +C *** Tesselation constants *** + +C Callback types: + integer*4 GLU_BEGIN + parameter ( GLU_BEGIN = 100100 ) + integer*4 GLU_VERTEX + parameter ( GLU_VERTEX = 100101 ) + integer*4 GLU_END + parameter ( GLU_END = 100102 ) + integer*4 GLU_ERROR + parameter ( GLU_ERROR = 100103 ) + integer*4 GLU_EDGE_FLAG + parameter ( GLU_EDGE_FLAG = 100104 ) + +C Contours types: + integer*4 GLU_CW + parameter ( GLU_CW = 100120 ) + integer*4 GLU_CCW + parameter ( GLU_CCW = 100121 ) + integer*4 GLU_INTERIOR + parameter ( GLU_INTERIOR = 100122 ) + integer*4 GLU_EXTERIOR + parameter ( GLU_EXTERIOR = 100123 ) + integer*4 GLU_UNKNOWN + parameter ( GLU_UNKNOWN = 100124 ) + + integer*4 GLU_TESS_ERROR1 + parameter ( GLU_TESS_ERROR1 = 100151 ) + integer*4 GLU_TESS_ERROR2 + parameter ( GLU_TESS_ERROR2 = 100152 ) + integer*4 GLU_TESS_ERROR3 + parameter ( GLU_TESS_ERROR3 = 100153 ) + integer*4 GLU_TESS_ERROR4 + parameter ( GLU_TESS_ERROR4 = 100154 ) + integer*4 GLU_TESS_ERROR5 + parameter ( GLU_TESS_ERROR5 = 100155 ) + integer*4 GLU_TESS_ERROR6 + parameter ( GLU_TESS_ERROR6 = 100156 ) + integer*4 GLU_TESS_ERROR7 + parameter ( GLU_TESS_ERROR7 = 100157 ) + integer*4 GLU_TESS_ERROR8 + parameter ( GLU_TESS_ERROR8 = 100158 ) + + +C *** NURBS constants *** + +C Properties: + integer*4 GLU_AUTO_LOAD_MATRIX + parameter ( GLU_AUTO_LOAD_MATRIX = 100200 ) + integer*4 GLU_CULLING + parameter ( GLU_CULLING = 100201 ) + integer*4 GLU_SAMPLING_TOLERANCE + parameter ( GLU_SAMPLING_TOLERANCE = 100203 ) + integer*4 GLU_DISPLAY_MODE + parameter ( GLU_DISPLAY_MODE = 100204 ) + +C Trimming curve types + integer*4 GLU_MAP1_TRIM_2 + parameter ( GLU_MAP1_TRIM_2 = 100210 ) + integer*4 GLU_MAP1_TRIM_3 + parameter ( GLU_MAP1_TRIM_3 = 100211 ) + +C Display modes: +C GLU_FILL 100012 + integer*4 GLU_OUTLINE_POLYGON + parameter ( GLU_OUTLINE_POLYGON = 100240 ) + integer*4 GLU_OUTLINE_PATCH + parameter ( GLU_OUTLINE_PATCH = 100241 ) + +C Callbacks: +C GLU_ERROR 100103 + +C Errors: + integer*4 GLU_NURBS_ERROR1 + parameter ( GLU_NURBS_ERROR1 = 100251 ) + integer*4 GLU_NURBS_ERROR2 + parameter ( GLU_NURBS_ERROR2 = 100252 ) + integer*4 GLU_NURBS_ERROR3 + parameter ( GLU_NURBS_ERROR3 = 100253 ) + integer*4 GLU_NURBS_ERROR4 + parameter ( GLU_NURBS_ERROR4 = 100254 ) + integer*4 GLU_NURBS_ERROR5 + parameter ( GLU_NURBS_ERROR5 = 100255 ) + integer*4 GLU_NURBS_ERROR6 + parameter ( GLU_NURBS_ERROR6 = 100256 ) + integer*4 GLU_NURBS_ERROR7 + parameter ( GLU_NURBS_ERROR7 = 100257 ) + integer*4 GLU_NURBS_ERROR8 + parameter ( GLU_NURBS_ERROR8 = 100258 ) + integer*4 GLU_NURBS_ERROR9 + parameter ( GLU_NURBS_ERROR9 = 100259 ) + integer*4 GLU_NURBS_ERROR10 + parameter ( GLU_NURBS_ERROR10 = 100260 ) + integer*4 GLU_NURBS_ERROR11 + parameter ( GLU_NURBS_ERROR11 = 100261 ) + integer*4 GLU_NURBS_ERROR12 + parameter ( GLU_NURBS_ERROR12 = 100262 ) + integer*4 GLU_NURBS_ERROR13 + parameter ( GLU_NURBS_ERROR13 = 100263 ) + integer*4 GLU_NURBS_ERROR14 + parameter ( GLU_NURBS_ERROR14 = 100264 ) + integer*4 GLU_NURBS_ERROR15 + parameter ( GLU_NURBS_ERROR15 = 100265 ) + integer*4 GLU_NURBS_ERROR16 + parameter ( GLU_NURBS_ERROR16 = 100266 ) + integer*4 GLU_NURBS_ERROR17 + parameter ( GLU_NURBS_ERROR17 = 100267 ) + integer*4 GLU_NURBS_ERROR18 + parameter ( GLU_NURBS_ERROR18 = 100268 ) + integer*4 GLU_NURBS_ERROR19 + parameter ( GLU_NURBS_ERROR19 = 100269 ) + integer*4 GLU_NURBS_ERROR20 + parameter ( GLU_NURBS_ERROR20 = 100270 ) + integer*4 GLU_NURBS_ERROR21 + parameter ( GLU_NURBS_ERROR21 = 100271 ) + integer*4 GLU_NURBS_ERROR22 + parameter ( GLU_NURBS_ERROR22 = 100272 ) + integer*4 GLU_NURBS_ERROR23 + parameter ( GLU_NURBS_ERROR23 = 100273 ) + integer*4 GLU_NURBS_ERROR24 + parameter ( GLU_NURBS_ERROR24 = 100274 ) + integer*4 GLU_NURBS_ERROR25 + parameter ( GLU_NURBS_ERROR25 = 100275 ) + integer*4 GLU_NURBS_ERROR26 + parameter ( GLU_NURBS_ERROR26 = 100276 ) + integer*4 GLU_NURBS_ERROR27 + parameter ( GLU_NURBS_ERROR27 = 100277 ) + integer*4 GLU_NURBS_ERROR28 + parameter ( GLU_NURBS_ERROR28 = 100278 ) + integer*4 GLU_NURBS_ERROR29 + parameter ( GLU_NURBS_ERROR29 = 100279 ) + integer*4 GLU_NURBS_ERROR30 + parameter ( GLU_NURBS_ERROR30 = 100280 ) + integer*4 GLU_NURBS_ERROR31 + parameter ( GLU_NURBS_ERROR31 = 100281 ) + integer*4 GLU_NURBS_ERROR32 + parameter ( GLU_NURBS_ERROR32 = 100282 ) + integer*4 GLU_NURBS_ERROR33 + parameter ( GLU_NURBS_ERROR33 = 100283 ) + integer*4 GLU_NURBS_ERROR34 + parameter ( GLU_NURBS_ERROR34 = 100284 ) + integer*4 GLU_NURBS_ERROR35 + parameter ( GLU_NURBS_ERROR35 = 100285 ) + integer*4 GLU_NURBS_ERROR36 + parameter ( GLU_NURBS_ERROR36 = 100286 ) + integer*4 GLU_NURBS_ERROR37 + parameter ( GLU_NURBS_ERROR37 = 100287 ) + + + character*128 fgluErrorString + character*128 fgluGetString + integer*4 fgluBuild1DMipmaps + integer*4 fgluBuild2DMipmaps + integer*4 fgluProject + integer*4 fgluScaleImage + integer*4 fgluUnProject diff --git a/lib/glut-3.7.6/include/GL/fglut.h b/lib/glut-3.7.6/include/GL/fglut.h new file mode 100644 index 0000000000..e0ad8536d9 --- /dev/null +++ b/lib/glut-3.7.6/include/GL/fglut.h @@ -0,0 +1,321 @@ + +C Copyright (c) Mark J. Kilgard, 1994. + +C This program is freely distributable without licensing fees +C and is provided without guarantee or warrantee expressed or +C implied. This program is -not- in the public domain. + +C GLUT Fortran header file + +C display mode bit masks + integer*4 GLUT_RGB + parameter ( GLUT_RGB = 0 ) + integer*4 GLUT_RGBA + parameter ( GLUT_RGBA = 0 ) + integer*4 GLUT_INDEX + parameter ( GLUT_INDEX = 1 ) + integer*4 GLUT_SINGLE + parameter ( GLUT_SINGLE = 0 ) + integer*4 GLUT_DOUBLE + parameter ( GLUT_DOUBLE = 2 ) + integer*4 GLUT_ACCUM + parameter ( GLUT_ACCUM = 4 ) + integer*4 GLUT_ALPHA + parameter ( GLUT_ALPHA = 8 ) + integer*4 GLUT_DEPTH + parameter ( GLUT_DEPTH = 16 ) + integer*4 GLUT_STENCIL + parameter ( GLUT_STENCIL = 32 ) + integer*4 GLUT_MULTISAMPLE + parameter ( GLUT_MULTISAMPLE = 128 ) + integer*4 GLUT_STEREO + parameter ( GLUT_STEREO = 256 ) + +C mouse buttons + integer*4 GLUT_LEFT_BUTTON + parameter ( GLUT_LEFT_BUTTON = 0 ) + integer*4 GLUT_MIDDLE_BUTTON + parameter ( GLUT_MIDDLE_BUTTON = 1 ) + integer*4 GLUT_RIGHT_BUTTON + parameter ( GLUT_RIGHT_BUTTON = 2 ) + +C mouse button callback state + integer*4 GLUT_DOWN + parameter ( GLUT_DOWN = 0 ) + integer*4 GLUT_UP + parameter ( GLUT_UP = 1 ) + +C special key callback values + integer*4 GLUT_KEY_F1 + parameter ( GLUT_KEY_F1 = 1 ) + integer*4 GLUT_KEY_F2 + parameter ( GLUT_KEY_F2 = 2 ) + integer*4 GLUT_KEY_F3 + parameter ( GLUT_KEY_F3 = 3 ) + integer*4 GLUT_KEY_F4 + parameter ( GLUT_KEY_F4 = 4 ) + integer*4 GLUT_KEY_F5 + parameter ( GLUT_KEY_F5 = 5 ) + integer*4 GLUT_KEY_F6 + parameter ( GLUT_KEY_F6 = 6 ) + integer*4 GLUT_KEY_F7 + parameter ( GLUT_KEY_F7 = 7 ) + integer*4 GLUT_KEY_F8 + parameter ( GLUT_KEY_F8 = 8 ) + integer*4 GLUT_KEY_F9 + parameter ( GLUT_KEY_F9 = 9 ) + integer*4 GLUT_KEY_F10 + parameter ( GLUT_KEY_F10 = 10 ) + integer*4 GLUT_KEY_F11 + parameter ( GLUT_KEY_F11 = 11 ) + integer*4 GLUT_KEY_F12 + parameter ( GLUT_KEY_F12 = 12 ) + integer*4 GLUT_KEY_LEFT + parameter ( GLUT_KEY_LEFT = 100 ) + integer*4 GLUT_KEY_UP + parameter ( GLUT_KEY_UP = 101 ) + integer*4 GLUT_KEY_RIGHT + parameter ( GLUT_KEY_RIGHT = 102 ) + integer*4 GLUT_KEY_DOWN + parameter ( GLUT_KEY_DOWN = 103 ) + integer*4 GLUT_KEY_PAGE_UP + parameter ( GLUT_KEY_PAGE_UP = 104 ) + integer*4 GLUT_KEY_PAGE_DOWN + parameter ( GLUT_KEY_PAGE_DOWN = 105 ) + integer*4 GLUT_KEY_HOME + parameter ( GLUT_KEY_HOME = 106 ) + integer*4 GLUT_KEY_END + parameter ( GLUT_KEY_END = 107 ) + integer*4 GLUT_KEY_INSERT + parameter ( GLUT_KEY_INSERT = 108 ) + +C entry/exit callback state + integer*4 GLUT_LEFT + parameter ( GLUT_LEFT = 0 ) + integer*4 GLUT_ENTERED + parameter ( GLUT_ENTERED = 1 ) + +C menu usage callback state + integer*4 GLUT_MENU_NOT_IN_USE + parameter ( GLUT_MENU_NOT_IN_USE = 0 ) + integer*4 GLUT_MENU_IN_USE + parameter ( GLUT_MENU_IN_USE = 1 ) + +C visibility callback state + integer*4 GLUT_NOT_VISIBLE + parameter ( GLUT_NOT_VISIBLE = 0 ) + integer*4 GLUT_VISIBLE + parameter ( GLUT_VISIBLE = 1 ) + +C color index component selection values + integer*4 GLUT_RED + parameter ( GLUT_RED = 0 ) + integer*4 GLUT_GREEN + parameter ( GLUT_GREEN = 1 ) + integer*4 GLUT_BLUE + parameter ( GLUT_BLUE = 2 ) + +C XXX Unfortunately, SGI's Fortran compiler links with +C EXTERNAL data even if it is not used. This defeats +C the purpose of GLUT naming fonts via opaque symbols. +C This means GLUT Fortran programmers should explicitly +C declared EXTERNAL GLUT fonts in subroutines where +C the fonts are used. + +C stroke font opaque names +C external GLUT_STROKE_ROMAN +C external GLUT_STROKE_MONO_ROMAN + +C bitmap font opaque names +C external GLUT_BITMAP_9_BY_15 +C external GLUT_BITMAP_8_BY_13 +C external GLUT_BITMAP_TIMES_ROMAN_10 +C external GLUT_BITMAP_TIMES_ROMAN_24 +C external GLUT_BITMAP_HELVETICA_10 +C external GLUT_BITMAP_HELVETICA_12 +C external GLUT_BITMAP_HELVETICA_18 + +C glutGet parameters + integer*4 GLUT_WINDOW_X + parameter ( GLUT_WINDOW_X = 100 ) + integer*4 GLUT_WINDOW_Y + parameter ( GLUT_WINDOW_Y = 101 ) + integer*4 GLUT_WINDOW_WIDTH + parameter ( GLUT_WINDOW_WIDTH = 102 ) + integer*4 GLUT_WINDOW_HEIGHT + parameter ( GLUT_WINDOW_HEIGHT = 103 ) + integer*4 GLUT_WINDOW_BUFFER_SIZE + parameter ( GLUT_WINDOW_BUFFER_SIZE = 104 ) + integer*4 GLUT_WINDOW_STENCIL_SIZE + parameter ( GLUT_WINDOW_STENCIL_SIZE = 105 ) + integer*4 GLUT_WINDOW_DEPTH_SIZE + parameter ( GLUT_WINDOW_DEPTH_SIZE = 106 ) + integer*4 GLUT_WINDOW_RED_SIZE + parameter ( GLUT_WINDOW_RED_SIZE = 107 ) + integer*4 GLUT_WINDOW_GREEN_SIZE + parameter ( GLUT_WINDOW_GREEN_SIZE = 108 ) + integer*4 GLUT_WINDOW_BLUE_SIZE + parameter ( GLUT_WINDOW_BLUE_SIZE = 109 ) + integer*4 GLUT_WINDOW_ALPHA_SIZE + parameter ( GLUT_WINDOW_ALPHA_SIZE = 110 ) + integer*4 GLUT_WINDOW_ACCUM_RED_SIZE + parameter ( GLUT_WINDOW_ACCUM_RED_SIZE = 111 ) + integer*4 GLUT_WINDOW_ACCUM_GREEN_SIZE + parameter ( GLUT_WINDOW_ACCUM_GREEN_SIZE = 112 ) + integer*4 GLUT_WINDOW_ACCUM_BLUE_SIZE + parameter ( GLUT_WINDOW_ACCUM_BLUE_SIZE = 113 ) + integer*4 GLUT_WINDOW_ACCUM_ALPHA_SIZE + parameter ( GLUT_WINDOW_ACCUM_ALPHA_SIZE = 114 ) + integer*4 GLUT_WINDOW_DOUBLEBUFFER + parameter ( GLUT_WINDOW_DOUBLEBUFFER = 115 ) + integer*4 GLUT_WINDOW_RGBA + parameter ( GLUT_WINDOW_RGBA = 116 ) + integer*4 GLUT_WINDOW_PARENT + parameter ( GLUT_WINDOW_PARENT = 117 ) + integer*4 GLUT_WINDOW_NUM_CHILDREN + parameter ( GLUT_WINDOW_NUM_CHILDREN = 118 ) + integer*4 GLUT_WINDOW_COLORMAP_SIZE + parameter ( GLUT_WINDOW_COLORMAP_SIZE = 119 ) + integer*4 GLUT_WINDOW_NUM_SAMPLES + parameter ( GLUT_WINDOW_NUM_SAMPLES = 120 ) + integer*4 GLUT_WINDOW_STEREO + parameter ( GLUT_WINDOW_STEREO = 121 ) + integer*4 GLUT_WINDOW_CURSOR + parameter ( GLUT_WINDOW_CURSOR = 122 ) + integer*4 GLUT_SCREEN_WIDTH + parameter ( GLUT_SCREEN_WIDTH = 200 ) + integer*4 GLUT_SCREEN_HEIGHT + parameter ( GLUT_SCREEN_HEIGHT = 201 ) + integer*4 GLUT_SCREEN_WIDTH_MM + parameter ( GLUT_SCREEN_WIDTH_MM = 202 ) + integer*4 GLUT_SCREEN_HEIGHT_MM + parameter ( GLUT_SCREEN_HEIGHT_MM = 203 ) + integer*4 GLUT_MENU_NUM_ITEMS + parameter ( GLUT_MENU_NUM_ITEMS = 300 ) + integer*4 GLUT_DISPLAY_MODE_POSSIBLE + parameter ( GLUT_DISPLAY_MODE_POSSIBLE = 400 ) + integer*4 GLUT_INIT_WINDOW_X + parameter ( GLUT_INIT_WINDOW_X = 500 ) + integer*4 GLUT_INIT_WINDOW_Y + parameter ( GLUT_INIT_WINDOW_Y = 501 ) + integer*4 GLUT_INIT_WINDOW_WIDTH + parameter ( GLUT_INIT_WINDOW_WIDTH = 502 ) + integer*4 GLUT_INIT_WINDOW_HEIGHT + parameter ( GLUT_INIT_WINDOW_HEIGHT = 503 ) + integer*4 GLUT_INIT_DISPLAY_MODE + parameter ( GLUT_INIT_DISPLAY_MODE = 504 ) + integer*4 GLUT_ELAPSED_TIME + parameter ( GLUT_ELAPSED_TIME = 700 ) + +C glutDeviceGet parameters + integer*4 GLUT_HAS_KEYBOARD + parameter ( GLUT_HAS_KEYBOARD = 600 ) + integer*4 GLUT_HAS_MOUSE + parameter ( GLUT_HAS_MOUSE = 601 ) + integer*4 GLUT_HAS_SPACEBALL + parameter ( GLUT_HAS_SPACEBALL = 602 ) + integer*4 GLUT_HAS_DIAL_AND_BUTTON_BOX + parameter ( GLUT_HAS_DIAL_AND_BUTTON_BOX = 603 ) + integer*4 GLUT_HAS_TABLET + parameter ( GLUT_HAS_TABLET = 604 ) + integer*4 GLUT_NUM_MOUSE_BUTTONS + parameter ( GLUT_NUM_MOUSE_BUTTONS = 605 ) + integer*4 GLUT_NUM_SPACEBALL_BUTTONS + parameter ( GLUT_NUM_SPACEBALL_BUTTONS = 606 ) + integer*4 GLUT_NUM_BUTTON_BOX_BUTTONS + parameter ( GLUT_NUM_BUTTON_BOX_BUTTONS = 607 ) + integer*4 GLUT_NUM_DIALS + parameter ( GLUT_NUM_DIALS = 608 ) + integer*4 GLUT_NUM_TABLET_BUTTONS + parameter ( GLUT_NUM_TABLET_BUTTONS = 609 ) + +C glutLayerGet parameters + integer*4 GLUT_OVERLAY_POSSIBLE + parameter ( GLUT_OVERLAY_POSSIBLE = 800 ) + integer*4 GLUT_LAYER_IN_USE + parameter ( GLUT_LAYER_IN_USE = 801 ) + integer*4 GLUT_HAS_OVERLAY + parameter ( GLUT_HAS_OVERLAY = 802 ) + integer*4 GLUT_TRANSPARENT_INDEX + parameter ( GLUT_TRANSPARENT_INDEX = 803 ) + integer*4 GLUT_NORMAL_DAMAGED + parameter ( GLUT_NORMAL_DAMAGED = 804 ) + integer*4 GLUT_OVERLAY_DAMAGED + parameter ( GLUT_OVERLAY_DAMAGED = 805 ) + +C glutUseLayer parameters + integer*4 GLUT_NORMAL + parameter ( GLUT_NORMAL = 0 ) + integer*4 GLUT_OVERLAY + parameter ( GLUT_OVERLAY = 1 ) + +C glutGetModifiers return mask + integer*4 GLUT_ACTIVE_SHIFT + parameter ( GLUT_ACTIVE_SHIFT = 1 ) + integer*4 GLUT_ACTIVE_CTRL + parameter ( GLUT_ACTIVE_CTRL = 2 ) + integer*4 GLUT_ACTIVE_ALT + parameter ( GLUT_ACTIVE_ALT = 4 ) + +C glutSetCursor parameters + integer*4 GLUT_CURSOR_RIGHT_ARROW + parameter ( GLUT_CURSOR_RIGHT_ARROW = 0 ) + integer*4 GLUT_CURSOR_LEFT_ARROW + parameter ( GLUT_CURSOR_LEFT_ARROW = 1 ) + integer*4 GLUT_CURSOR_INFO + parameter ( GLUT_CURSOR_INFO = 2 ) + integer*4 GLUT_CURSOR_DESTROY + parameter ( GLUT_CURSOR_DESTROY = 3 ) + integer*4 GLUT_CURSOR_HELP + parameter ( GLUT_CURSOR_HELP = 4 ) + integer*4 GLUT_CURSOR_CYCLE + parameter ( GLUT_CURSOR_CYCLE = 5 ) + integer*4 GLUT_CURSOR_SPRAY + parameter ( GLUT_CURSOR_SPRAY = 6 ) + integer*4 GLUT_CURSOR_WAIT + parameter ( GLUT_CURSOR_WAIT = 7 ) + integer*4 GLUT_CURSOR_TEXT + parameter ( GLUT_CURSOR_TEXT = 8 ) + integer*4 GLUT_CURSOR_CROSSHAIR + parameter ( GLUT_CURSOR_CROSSHAIR = 9 ) + integer*4 GLUT_CURSOR_UP_DOWN + parameter ( GLUT_CURSOR_UP_DOWN = 10 ) + integer*4 GLUT_CURSOR_LEFT_RIGHT + parameter ( GLUT_CURSOR_LEFT_RIGHT = 11 ) + integer*4 GLUT_CURSOR_TOP_SIDE + parameter ( GLUT_CURSOR_TOP_SIDE = 12 ) + integer*4 GLUT_CURSOR_BOTTOM_SIDE + parameter ( GLUT_CURSOR_BOTTOM_SIDE = 13 ) + integer*4 GLUT_CURSOR_LEFT_SIDE + parameter ( GLUT_CURSOR_LEFT_SIDE = 14 ) + integer*4 GLUT_CURSOR_RIGHT_SIDE + parameter ( GLUT_CURSOR_RIGHT_SIDE = 15 ) + integer*4 GLUT_CURSOR_TOP_LEFT_CORNER + parameter ( GLUT_CURSOR_TOP_LEFT_CORNER = 16 ) + integer*4 GLUT_CURSOR_TOP_RIGHT_CORNER + parameter ( GLUT_CURSOR_TOP_RIGHT_CORNER = 17 ) + integer*4 GLUT_CURSOR_BOTTOM_RIGHT_CORNER + parameter ( GLUT_CURSOR_BOTTOM_RIGHT_CORNER = 18 ) + integer*4 GLUT_CURSOR_BOTTOM_LEFT_CORNER + parameter ( GLUT_CURSOR_BOTTOM_LEFT_CORNER = 19 ) + integer*4 GLUT_CURSOR_INHERIT + parameter ( GLUT_CURSOR_INHERIT = 100 ) + integer*4 GLUT_CURSOR_NONE + parameter ( GLUT_CURSOR_NONE = 101 ) + integer*4 GLUT_CURSOR_FULL_CROSSHAIR + parameter ( GLUT_CURSOR_FULL_CROSSHAIR = 102 ) + +C GLUT functions + integer*4 glutcreatewindow + integer*4 glutcreatesubwindow + integer*4 glutgetwindow + integer*4 glutcreatemenu + integer*4 glutgetmenu + real glutgetcolor + integer*4 glutget + integer*4 glutdeviceget + integer*4 glutextensionsupported + +C GLUT NULL name + external glutnull + diff --git a/lib/glut-3.7.6/include/GL/glsmap.h b/lib/glut-3.7.6/include/GL/glsmap.h new file mode 100644 index 0000000000..b97fa9acfd --- /dev/null +++ b/lib/glut-3.7.6/include/GL/glsmap.h @@ -0,0 +1,137 @@ +#ifndef __glsmap_h__ +#define __glsmap_h__ + +/* Copyright (c) Mark J. Kilgard, 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. */ + +#if defined(_WIN32) + +/* Try hard to avoid including to avoid name space pollution, + but Win32's needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif +# ifndef CALLBACK + /* XXX This is from Win32's */ +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define WINGDIAPI __declspec(dllimport) +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ + +#endif /* _WIN32 */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SMAP_CLEAR_SMAP_TEXTURE = 0x1, + SMAP_GENERATE_VIEW_MIPMAPS = 0x2, + SMAP_GENERATE_SMAP_MIPMAPS = 0x4, + SMAP_GENERATE_MIPMAPS = 0x6 /* both of above */ +} SphereMapFlags; + +/* Cube view enumerants. */ +enum { + SMAP_FRONT = 0, + SMAP_TOP = 1, + SMAP_BOTTOM = 2, + SMAP_LEFT = 3, + SMAP_RIGHT = 4, + SMAP_BACK = 5 +}; + +typedef struct _SphereMap SphereMap; + +extern SphereMap *smapCreateSphereMap(SphereMap *shareSmap); +extern void smapDestroySphereMap(SphereMap *smap); + +extern void smapConfigureSphereMapMesh(SphereMap *smap, int steps, int rings, int edgeExtend); + +extern void smapSetSphereMapTexObj(SphereMap *smap, GLuint texobj); +extern void smapSetViewTexObj(SphereMap *smap, GLuint texobj); +extern void smapSetViewTexObjs(SphereMap *smap, GLuint texobjs[6]); +extern void smapGetSphereMapTexObj(SphereMap *smap, GLuint *texobj); +extern void smapGetViewTexObj(SphereMap *smap, GLuint *texobj); +extern void smapGetViewTexObjs(SphereMap *smap, GLuint texobjs[6]); + +extern void smapSetFlags(SphereMap *smap, SphereMapFlags flags); +extern void smapGetFlags(SphereMap *smap, SphereMapFlags *flags); + +extern void smapSetViewOrigin(SphereMap *smap, GLint x, GLint y); +extern void smapSetSphereMapOrigin(SphereMap *smap, GLint x, GLint y); +extern void smapGetViewOrigin(SphereMap *smap, GLint *x, GLint *y); +extern void smapGetSphereMapOrigin(SphereMap *smap, GLint *x, GLint *y); + +extern void smapSetEye(SphereMap *smap, GLfloat eyex, GLfloat eyey, GLfloat eyez); +extern void smapSetEyeVector(SphereMap *smap, GLfloat *eye); +extern void smapSetUp(SphereMap *smap, GLfloat upx, GLfloat upy, GLfloat upz); +extern void smapSetUpVector(SphereMap *smap, GLfloat *up); +extern void smapSetObject(SphereMap *smap, GLfloat objx, GLfloat objy, GLfloat objz); +extern void smapSetObjectVector(SphereMap *smap, GLfloat *obj); +extern void smapGetEye(SphereMap *smap, GLfloat *eyex, GLfloat *eyey, GLfloat *eyez); +extern void smapGetEyeVector(SphereMap *smap, GLfloat *eye); +extern void smapGetUp(SphereMap *smap, GLfloat *upx, GLfloat *upy, GLfloat *upz); +extern void smapGetUpVector(SphereMap *smap, GLfloat *up); +extern void smapGetObject(SphereMap *smap, GLfloat *objx, GLfloat *objy, GLfloat *objz); +extern void smapGetObjectVector(SphereMap *smap, GLfloat *obj); + +extern void smapSetNearFar(SphereMap *smap, GLfloat viewNear, GLfloat viewFar); +extern void smapGetNearFar(SphereMap *smap, GLfloat *viewNear, GLfloat *viewFar); + +extern void smapSetSphereMapTexDim(SphereMap *smap, GLsizei texdim); +extern void smapSetViewTexDim(SphereMap *smap, GLsizei texdim); +extern void smapGetSphereMapTexDim(SphereMap *smap, GLsizei *texdim); +extern void smapGetViewTexDim(SphereMap *smap, GLsizei *texdim); + +extern void smapSetContextData(SphereMap *smap, void *context); +extern void smapGetContextData(SphereMap *smap, void **context); + +extern void smapSetPositionLightsFunc(SphereMap *smap, void (*positionLights)(int view, void *context)); +extern void smapSetDrawViewFunc(SphereMap *smap, void (*drawView)(int view, void *context)); +extern void smapGetPositionLightsFunc(SphereMap *smap, void (**positionLights)(int view, void *context)); +extern void smapGetDrawViewFunc(SphereMap *smap, void (**drawView)(int view, void *context)); + +extern void smapGenViewTex(SphereMap *smap, int view); +extern void smapGenViewTexs(SphereMap *smap); +extern void smapGenSphereMapFromViewTexs(SphereMap *smap); +extern void smapGenSphereMap(SphereMap *smap); +extern void smapGenSphereMapWithOneViewTex(SphereMap *smap); + +extern int smapRvecToSt(float rvec[3], float st[2]); +extern void smapStToRvec(float *st, float *rvec); + +#ifdef __cplusplus +} + +#endif +#endif /* __glsmap_h__ */ diff --git a/lib/glut-3.7.6/include/GL/glut.h b/lib/glut-3.7.6/include/GL/glut.h new file mode 100644 index 0000000000..aa7428f368 --- /dev/null +++ b/lib/glut-3.7.6/include/GL/glut.h @@ -0,0 +1,716 @@ +#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. */ + +#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. */ +# if 0 + /* This would put tons of macros and crap in our clean name space. */ +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ +# if defined( __LCC__ ) +# undef WINGDIAPI +# define WINGDIAPI __stdcall +# else + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +/* 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 + +/* GLUT API entry point declarations for Win32. */ +# ifdef GLUT_BUILDING_LIB +# define GLUTAPI __declspec(dllexport) +# else +# ifdef _DLL +# define GLUTAPI __declspec(dllimport) +# else +# define GLUTAPI extern +# endif +# endif + +/* GLUT callback calling convention for Win32. */ +# define GLUTCALLBACK __cdecl + +#endif /* _WIN32 */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +# ifndef GLUT_BUILDING_LIB +extern _CRTIMP void __cdecl exit(int); +# endif +#else +/* non-Win32 case. */ +/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ +# define APIENTRY +# define GLUT_APIENTRY_DEFINED +# define CALLBACK +/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ +# define GLUTAPI extern +# define GLUTCALLBACK +/* 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 + +#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 ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 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 APIENTRY glutInit(int *argcp, char **argv); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutInitDisplayString(const char *string); +#endif +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); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +#endif +#endif +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); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); +#endif +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); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutFullScreen(void); +GLUTAPI void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* 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); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutShowOverlay(void); +GLUTAPI void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif +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)); +#if (GLUT_API_VERSION >= 2) +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)); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); +GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY 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 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); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +GLUTAPI int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +GLUTAPI int APIENTRY glutGetModifiers(void); +GLUTAPI int APIENTRY glutLayerGet(GLenum type); +#endif + +/* 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); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* 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); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); +GLUTAPI void APIENTRY glutSetupVideoResizing(void); +GLUTAPI void APIENTRY glutStopVideoResizing(void); +GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); +GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +GLUTAPI void APIENTRY 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 APIENTRY glutIgnoreKeyRepeat(int ignore); +GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); +GLUTAPI void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) +#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) +#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) +#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) +#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) +#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) +#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) + +GLUTAPI void APIENTRY glutGameModeString(const char *string); +GLUTAPI int APIENTRY glutEnterGameMode(void); +GLUTAPI void APIENTRY glutLeaveGameMode(void); +GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#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 /* __glut_h__ */ diff --git a/lib/glut-3.7.6/include/GL/glutf90.h b/lib/glut-3.7.6/include/GL/glutf90.h new file mode 100644 index 0000000000..7dc1d6772a --- /dev/null +++ b/lib/glut-3.7.6/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. */ +GLUTAPI void* APIENTRY __glutGetFCB(int which); +GLUTAPI void APIENTRY __glutSetFCB(int which, void *func); + +#endif /* __glutf90_h__ */ diff --git a/lib/glut-3.7.6/include/GL/tube.h b/lib/glut-3.7.6/include/GL/tube.h new file mode 100644 index 0000000000..5ea54142b8 --- /dev/null +++ b/lib/glut-3.7.6/include/GL/tube.h @@ -0,0 +1,205 @@ +/* + * tube.h + * + * FUNCTION: + * Tubing and Extrusion header file. + * This file provides protypes and defines for the extrusion + * and tubing primitives. + * + * HISTORY: + * Linas Vepstas 1990, 1991 + */ + +#ifndef __TUBE_H__ +#define __TUBE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + GLE API revision history: + + GLE_API_VERSION is updated to reflect GLE API changes (interface + changes, semantic changes, deletions, or additions). + + GLE_API_VERSION=228 GLUT 3.7 release of GLE. +**/ +#ifndef GLE_API_VERSION /* allow this to be overriden */ +#define GLE_API_VERSION 228 +#endif + +#ifdef _WIN32 +#define OPENGL_10 +#endif + +/* some types */ +#define gleDouble double +typedef gleDouble gleAffine[2][3]; + +/* ====================================================== */ + +/* defines for tubing join styles */ +#define TUBE_JN_RAW 0x1 +#define TUBE_JN_ANGLE 0x2 +#define TUBE_JN_CUT 0x3 +#define TUBE_JN_ROUND 0x4 +#define TUBE_JN_MASK 0xf /* mask bits */ +#define TUBE_JN_CAP 0x10 + +/* determine how normal vectors are to be handled */ +#define TUBE_NORM_FACET 0x100 +#define TUBE_NORM_EDGE 0x200 +#define TUBE_NORM_PATH_EDGE 0x400 /* for spiral, lathe, helix primitives */ +#define TUBE_NORM_MASK 0xf00 /* mask bits */ + +/* closed or open countours */ +#define TUBE_CONTOUR_CLOSED 0x1000 + +#define GLE_TEXTURE_ENABLE 0x10000 +#define GLE_TEXTURE_STYLE_MASK 0xff +#define GLE_TEXTURE_VERTEX_FLAT 1 +#define GLE_TEXTURE_NORMAL_FLAT 2 +#define GLE_TEXTURE_VERTEX_CYL 3 +#define GLE_TEXTURE_NORMAL_CYL 4 +#define GLE_TEXTURE_VERTEX_SPH 5 +#define GLE_TEXTURE_NORMAL_SPH 6 +#define GLE_TEXTURE_VERTEX_MODEL_FLAT 7 +#define GLE_TEXTURE_NORMAL_MODEL_FLAT 8 +#define GLE_TEXTURE_VERTEX_MODEL_CYL 9 +#define GLE_TEXTURE_NORMAL_MODEL_CYL 10 +#define GLE_TEXTURE_VERTEX_MODEL_SPH 11 +#define GLE_TEXTURE_NORMAL_MODEL_SPH 12 + +#ifdef GL_32 +/* HACK for GL 3.2 -- needed because no way to tell if lighting is on. */ +#define TUBE_LIGHTING_ON 0x80000000 + +#define gleExtrusion extrusion +#define gleSetJoinStyle setjoinstyle +#define gleGetJoinStyle getjoinstyle +#define glePolyCone polycone +#define glePolyCylinder polycylinder +#define gleSuperExtrusion super_extrusion +#define gleTwistExtrusion twist_extrusion +#define gleSpiral spiral +#define gleLathe lathe +#define gleHelicoid helicoid +#define gleToroid toroid +#define gleScrew screw + +#endif /* GL_32 */ + +extern int gleGetJoinStyle (void); +extern void gleSetJoinStyle (int style); /* bitwise OR of flags */ +extern int gleGetNumSlices(void); +extern void gleSetNumSlices(int slices); + +/* draw polyclinder, specified as a polyline */ +extern void glePolyCylinder (int npoints, /* num points in polyline */ + gleDouble point_array[][3], /* polyline vertces */ + float color_array[][3], /* colors at polyline verts */ + gleDouble radius); /* radius of polycylinder */ + +/* draw polycone, specified as a polyline with radii */ +extern void glePolyCone (int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline vertices */ + float color_array[][3], /* colors at polyline verts */ + gleDouble radius_array[]); /* cone radii at polyline verts */ + +/* extrude arbitrary 2D contour along arbitrary 3D path */ +extern void gleExtrusion (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline vertices */ + float color_array[][3]); /* colors at polyline verts */ + +/* extrude 2D contour, specifying local rotations (twists) */ +extern void gleTwistExtrusion (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline vertices */ + float color_array[][3], /* color at polyline verts */ + gleDouble twist_array[]); /* countour twists (in degrees) */ + +/* extrude 2D contour, specifying local affine tranformations */ +extern void gleSuperExtrusion (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline vertices */ + float color_array[][3], /* color at polyline verts */ + gleDouble xform_array[][2][3]); /* 2D contour xforms */ + +/* spiral moves contour along helical path by parallel transport */ +extern void gleSpiral (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ + +/* lathe moves contour along helical path by helically shearing 3D space */ +extern void gleLathe (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ + +/* similar to spiral, except contour is a circle */ +extern void gleHelicoid (gleDouble rToroid, /* circle contour (torus) radius */ + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ + +/* similar to lathe, except contour is a circle */ +extern void gleToroid (gleDouble rToroid, /* circle contour (torus) radius */ + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ + +/* draws a screw shape */ +extern void gleScrew (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + gleDouble startz, /* start of segment */ + gleDouble endz, /* end of segment */ + gleDouble twist); /* number of rotations */ + +extern void gleTextureMode (int mode); + +#ifdef __cplusplus +} + +#endif +#endif /* __TUBE_H__ */ +/* ================== END OF FILE ======================= */ diff --git a/lib/glut-3.7.6/include/mui/browser.h b/lib/glut-3.7.6/include/mui/browser.h new file mode 100644 index 0000000000..3c97b52396 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/browser.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#define BROWSEFILE "/tmp/browserdata" + +extern char currentdirectoryname[]; +extern char currentfilename[]; +extern char browseprompt[]; + +extern int xcenter, ycenter; + +extern void parsebrowsefile(FILE *); +void setcurrentfilename(char *); diff --git a/lib/glut-3.7.6/include/mui/displaylist.h b/lib/glut-3.7.6/include/mui/displaylist.h new file mode 100644 index 0000000000..471430bb0a --- /dev/null +++ b/lib/glut-3.7.6/include/mui/displaylist.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#define P_UISHADOW 343 +#define P_UILINESHADOW 344 + +#define UI_FONT_BOLD 1 +#define UI_FONT_NORMAL 2 +#define UI_FONT_FIXED_PITCH 3 + +void uistartdraw(void); +void uirecti(int x, int y, int z, int w); +void uienddraw(void (*uicolor)()); +void uimove2i(int,int); +void uidraw2i(int,int); +void uirectfi(int x, int y, int z, int w); +void uiclear(void); +void uicmov2i(int x, int y); +void uicharstr(char *s, int font); +void uiendline(void); +void uipushviewport(void); +void uipopviewport(void); +void uiviewport(int x, int y, int width, int height); +void uipmv2i(int, int); +void uipdr2i(int, int); +void uipclos(void); +void uiendline(void); diff --git a/lib/glut-3.7.6/include/mui/gizmo.h b/lib/glut-3.7.6/include/mui/gizmo.h new file mode 100644 index 0000000000..b99469d8b7 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/gizmo.h @@ -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. + */ + + /* jot text editor source code. */ + /* Tom Davis */ + /* February 7, 1992 */ + +/* defines for gizmos */ + +#include + +#define BUTSTRLEN 60 +#define LABELSTRLEN 150 + +#define FONTWIDTH 9 /* for fixed font */ +#define BASELINE 9 + +/* BUTTON STUFF */ +#define PUSHBUTTON 3 +#define RADIOBUTTON 6 +#define INDICATOR 9 +#define BED 10 +#define BUTTON 11 + +#define BUTHEIGHT 28 +#define BUTWIDTH 75 +#define RADIOWIDTH 24 +#define RADIOHEIGHT 24 +#define TINYRADIOHEIGHT 16 +#define TINYRADIOWIDTH 16 + +typedef struct butn { + char str[BUTSTRLEN+1]; + int type; + void (*butcolor)(); + struct butn *link; /* for linking radio buttons, e.g. */ + muiObject *object; +} Button; + + +/* TEXT BOX STUFF */ +#define TBSTRLEN 200 +#define TEXTHEIGHT 17 +#define TEXTBOXHEIGHT 28 + +typedef struct { + char str[TBSTRLEN+1]; + char label[LABELSTRLEN+1]; + int tp1, tp2; + int charWidth; + int type; +} TextBox; + +TextBox *newtb(int xmin, int xmax); + +/* LABEL STUFF */ + +#define LBLSTRLEN 200 /* max length of a label string */ + +typedef struct { + char str[LBLSTRLEN+1]; +} Label; + +Label *newlabel(char *s); + +/* SLIDER STUFF */ + +#define SLIDERWIDTH 20 +#define MINSHALF 13 +#define ARROWHEIGHT 20 + +#define SCROLLDOWN -1 +#define SCROLLUP 1 +#define THUMB 2 + +typedef struct { + int scenter; /* the center of the thumb */ + int shalf; /* half of the thumb length */ + int oldpos; /* old scenter */ + int arrowdelta; /* arrow delta */ + int thumb; /* whether the thumb should show */ +} Slider; + +typedef Slider VSlider; +typedef Slider HSlider; + +/* TEXTLIST STUFF */ + +typedef struct { + int listheight; /* in lines of text */ + char **strs; /* text */ + int top; /* index into strs */ + int count; /* total number of strings */ + int selecteditem; /* index into selecteditem or -1 */ + int locateditem; /* index into locateditem or -1 */ +} TextList; + +/* PULLDOWN STUFF */ + +#define PULLDOWN_HEIGHT 25 + +typedef struct { + char title[40]; + int menu; + int xoffset; +} menuentry; + +typedef struct { + int count; + int ishelp; + menuentry menus[30]; + menuentry helpmenu; +} Pulldown; + + +/* Define for the settbtype() and gettypein() flag */ +#define TYPEIN_STRING 0 +#define TYPEIN_INT 1 +#define TYPEIN_FILE 2 +#define TYPEIN_FLOAT 3 + +/* Color Stuff */ + +extern Button *newbed(void); +extern Button *newbut(void); +extern Button *newradiobut(void); +extern Pulldown *newpd(void); +extern void drawbut(muiObject *); +extern void drawvs(muiObject *obj); +extern void drawhs(muiObject *obj); +extern void drawtl(muiObject *obj); +extern void drawradiobutton(muiObject *obj); +extern void drawtinyradio(muiObject *obj); +extern void drawpulldown(muiObject *obj); +extern int getcurrentcolor(void); +extern void setcurrentcolor(int c); +extern void drawedges(int, int, int, int, void (*)(void), void (*)(void)); +extern void loadbut(Button *, char *); +extern void drawbut(muiObject *); +extern int pressbut(muiObject *); +extern void drawlabel(muiObject *); +extern void drawboldlabel(muiObject *); +extern void loadtb(TextBox *, char *); +extern int handletb(muiObject *, int, int); +extern void drawtb(muiObject *); +extern int inbut(Button *, int, int); +extern int intb(muiObject *, int, int); +extern void activatetb(TextBox *); +extern void deactivatetb(TextBox *); +extern char *gettbstr(TextBox *); + +extern VSlider *newvs(muiObject *obj, int ymin, int ymax, int scenter, int shalf); +extern VSlider *newhs(muiObject *obj, int xmin, int xmax, int scenter, int shalf); +extern void drawsetup(void); +extern void drawrestore(void); +extern void backgrounddraw(int xmin, int ymin, int xmax, int ymax); +extern TextList *newtl(muiObject *obj, int listheight); + +extern enum muiReturnValue buttonhandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue nullhandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue textboxhandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue vshandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue hshandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue tlhandler(muiObject *obj, int event, int value, int x, int y); +extern enum muiReturnValue pdhandler(muiObject *obj, int event, int value, int x, int y); + + +/* mui events */ + +#define MUI_DEVICE_DOWN 1 +#define MUI_DEVICE_UP 2 +#define MUI_DEVICE_PRESS 3 +#define MUI_DEVICE_RELEASE 4 +#define MUI_DEVICE_CLICK 5 +#define MUI_DEVICE_DOUBLE_CLICK 6 +#define MUI_KEYSTROKE 7 + +#define MUI_BUTTONFONT 0 +#define MUI_BUTTONFONT_BOLD 0 + +typedef struct muicons { + struct muicons *next; + muiObject *object; +} muiCons; + +void muiBackgroundClear(void); + +void muiFreeObject(muiObject *obj); +int muiInObject(muiObject *obj, int x, int y); + +int muiGetLocate(muiObject *obj); +void muiSetLocate(muiObject *obj, int state); +int muiGetSelect(muiObject *obj); +void muiSetSelect(muiObject *obj, int state); +muiCons *muiGetListCons(int uilist); +muiObject *muiGetActiveTB(void); +void muiSetUIList(muiObject *obj, int list); +int muiGetUIList(muiObject *obj); + +void muiDrawObject(muiObject *obj); + +void muiError(char *s); + +muiObject *muiHitInList(int uilist, int x, int y); +void muiDrawUIList(int uilist); +void muiHandleEvent(int event, int value, int x, int y); + diff --git a/lib/glut-3.7.6/include/mui/hslider.h b/lib/glut-3.7.6/include/mui/hslider.h new file mode 100644 index 0000000000..9d81047310 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/hslider.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1990, 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. + */ + +void drawparths(VSlider *, int); +void adjusthsthumb(muiObject *, double, double); diff --git a/lib/glut-3.7.6/include/mui/mui.h b/lib/glut-3.7.6/include/mui/mui.h new file mode 100644 index 0000000000..50a3d4ae3e --- /dev/null +++ b/lib/glut-3.7.6/include/mui/mui.h @@ -0,0 +1,156 @@ +#ifndef __mui_h__ +#define __mui_h__ + +/* + * 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. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +enum muiObjType { MUI_BUTTON, MUI_LABEL, MUI_BOLDLABEL, MUI_TEXTBOX, + MUI_VSLIDER, MUI_TEXTLIST, MUI_RADIOBUTTON, + MUI_TINYRADIOBUTTON, MUI_PULLDOWN, MUI_HSLIDER }; + +/* MUI Return Values: */ + +enum muiReturnValue { MUI_NO_ACTION, + MUI_SLIDER_MOVE, + MUI_SLIDER_RETURN, + MUI_SLIDER_SCROLLDOWN, + MUI_SLIDER_SCROLLUP, + MUI_SLIDER_THUMB, + MUI_BUTTON_PRESS, + MUI_TEXTBOX_RETURN, + MUI_TEXTLIST_RETURN, + MUI_TEXTLIST_RETURN_CONFIRM +}; + +typedef struct muiobj { + enum muiObjType type; + int xmin, xmax, ymin, ymax; /* bounding box */ + short active; /* 1 = toggled on, or pressed radio button, or can + be typed in (textbox), etc */ + short enable; /* 1 = can be accessed; drawn with solid text */ + short select; /* 1 = pressed (must be located at the time */ + short locate; /* 1 = located; usually the cursor is over it */ + short visible; /* 1 = drawn. not visible => not enabled */ + enum muiReturnValue (*handler)(struct muiobj *obj, int event, int value, int x, int y); + int id; /* available for users */ + int uilist; + void * object; + void (*callback)(struct muiobj *, enum muiReturnValue); +} muiObject; + +/* General MUI Routines */ + +void muiInit(void); +void muiAttachUIList(int uilist); +void muiNewUIList(int listid); +void muiAddToUIList(int uilist, muiObject *obj); +void muiSetCallback(muiObject *obj, void (*callback)(muiObject *, enum muiReturnValue)); +void muiGetObjectSize(muiObject *obj, int *xmin, int *ymin, int *xmax, int *ymax); +void muiSetID(muiObject *obj, int id); +int muiGetID(muiObject *obj); + +/* for a click that doesn't hit anything: */ + +void muiSetNonMUIcallback(void (*nc)(int, int)); + +int muiGetVisible(muiObject *obj); +void muiSetVisible(muiObject *obj, int state); +int muiGetActive(muiObject *obj); +void muiSetActive(muiObject *obj, int state); +int muiGetEnable(muiObject *obj); +void muiSetEnable(muiObject *obj, int state); +void muiSetActiveUIList(int i); +int muiGetActiveUIList(void); + +/* Button Routines */ + +muiObject *muiNewButton(int xmin, int xmax, int ymin, int ymax); +void muiLoadButton(muiObject *but, char *str); +muiObject *muiNewRadioButton(int xmin, int ymin); +muiObject *muiNewTinyRadioButton(int xmin, int ymin); +void muiLinkButtons(muiObject *obj1, muiObject *obj2); +void muiClearRadio(muiObject *rad); + +/* Label Routines */ + +muiObject *muiNewLabel(int xmin, int ymin, char *label); +muiObject *muiNewBoldLabel(int xmin, int ymin, char *label); +void muiChangeLabel(muiObject *obj, char *s); + +/* Text Box Routines */ + +muiObject *muiNewTextbox(int xmin, int xmax, int ymin); +char *muiGetTBString(muiObject *obj); +void muiClearTBString(muiObject *obj); +void muiSetTBString(muiObject *obj, char *s); + +/* Vertical Slider Routines */ + +muiObject *muiNewVSlider(int xmin, int ymin, int ymax, int scenter, int shalf); +float muiGetVSVal(muiObject *obj); +void muiSetVSValue(muiObject *obj, float val); +void muiSetVSArrowDelta(muiObject *obj, int newd); + +/* Horizontal Slider Routines */ + +muiObject *muiNewHSlider(int xmin, int ymin, int xmax, int scenter, int shalf); +float muiGetHSVal(muiObject *obj); +void muiSetHSValue(muiObject *obj, float val); +void muiSetHSArrowDelta(muiObject *obj, int newd); + +/* Text List Routines */ + +muiObject *muiNewTextList(int xmin, int ymin, int xmax, int listheight); +void muiSetTLTop(muiObject *obj, float p); +int muiGetTLSelectedItem(muiObject *obj); +void muiSetTLStrings(muiObject *obj, char **s); +void muiSetTLTopInt(muiObject *obj, int top); + +/* Pulldown Menu Routines */ + +muiObject *muiNewPulldown(void); +void muiAddPulldownEntry(muiObject *obj, char *title, int menu, int ishelp); + +#ifdef __cplusplus +} + +#endif +#endif /* __mui_h__ */ diff --git a/lib/glut-3.7.6/include/mui/textlist.h b/lib/glut-3.7.6/include/mui/textlist.h new file mode 100644 index 0000000000..fabc5ce0a5 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/textlist.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1990, 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. + */ + +void drawparttl(TextList *, long); diff --git a/lib/glut-3.7.6/include/mui/uicolor.h b/lib/glut-3.7.6/include/mui/uicolor.h new file mode 100644 index 0000000000..2da2328427 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/uicolor.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +void uiBlack(void); +void uiVyDkGray(void); +void uiDkGray(void); +void uiMmGray(void); +void uiLtGray(void); +void uiVyLtGray(void); +void uiWhite(void); +void uiDkYellow(void); +void uiMmYellow(void); +void uiLtYellow(void); +void uiYellow(void); + +void uiBlue(void); + +void uiTerraCotta(void); +void uiDkTerraCotta(void); +void uiSlateBlue(void); + +void uiPupBlack(void); +void uiPupGray(void); +void uiPupWhite(void); +void uiPupClear(void); + +int getcurrentcolor(void); +void setcurrentcolor(int); +void uiBackground(void); diff --git a/lib/glut-3.7.6/include/mui/vslider.h b/lib/glut-3.7.6/include/mui/vslider.h new file mode 100644 index 0000000000..feb8dfedf6 --- /dev/null +++ b/lib/glut-3.7.6/include/mui/vslider.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1990, 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. + */ + +void drawpartvs(VSlider *, int); +void adjustvsthumb(muiObject *, double, double); diff --git a/lib/glut-3.7.6/lib/Imakefile b/lib/glut-3.7.6/lib/Imakefile new file mode 100644 index 0000000000..be822433a8 --- /dev/null +++ b/lib/glut-3.7.6/lib/Imakefile @@ -0,0 +1,13 @@ + +/* Copyright (c) Mark J. Kilgard, 1995. */ + +#define IHaveSubdirs +#define PassCDebugFlags + +/* NOTE: The fglut directory is GLUT FORTRAN bindings which are */ +/* specific to IRIX 5.x. See ../README.fortran */ + +SUBDIRS = glut mui gle glsmap + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) diff --git a/lib/glut-3.7.6/lib/_all.dsp b/lib/glut-3.7.6/lib/_all.dsp new file mode 100644 index 0000000000..2e26c30f32 --- /dev/null +++ b/lib/glut-3.7.6/lib/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/dll.dsw b/lib/glut-3.7.6/lib/dll.dsw new file mode 100644 index 0000000000..78bc5329ee --- /dev/null +++ b/lib/glut-3.7.6/lib/dll.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gle"=".\gle\gle.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gle_dll"=".\gle\gle_dll.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/lib/fglut.n32/ObjectType.mk b/lib/glut-3.7.6/lib/fglut.n32/ObjectType.mk new file mode 100644 index 0000000000..6116ff97eb --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut.n32/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_N32) +CSTYLE = $(CSTYLE_N32) diff --git a/lib/glut-3.7.6/lib/fglut.n64/ObjectType.mk b/lib/glut-3.7.6/lib/fglut.n64/ObjectType.mk new file mode 100644 index 0000000000..da57d5a870 --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut.n64/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_64) +CSTYLE = $(CSTYLE_64) diff --git a/lib/glut-3.7.6/lib/fglut/ObjectType.mk b/lib/glut-3.7.6/lib/fglut/ObjectType.mk new file mode 100644 index 0000000000..f94dc77f5f --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_32) +CSTYLE = $(CSTYLE_32) diff --git a/lib/glut-3.7.6/lib/fglut/fglut.c b/lib/glut-3.7.6/lib/fglut/fglut.c new file mode 100644 index 0000000000..b7a0b30beb --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut.c @@ -0,0 +1,287 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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. */ + +#ifndef WRAPPERS_ONLY + +#include + +extern int __Argc; +extern char **__Argv; + +static GLUTmenuStateFCB fortranMenuStateFunc; + +void +glutnull_(void) +{ +} + +void +glutinit_(void) +{ + glutInit(&__Argc, __Argv); +} + +static void +fortranMenuStateWrapper(int value) +{ + fortranMenuStateFunc(&value); +} + +static void +fortranReshapeWrapper(int w, int h) +{ + (*__glutCurrentWindow->freshape) (&w, &h); +} + +#if 0 /* XXX No IRIX joystick support for now. */ +static void +fortranJoystickWrapper(unsigned int button, int x, int y, int z) +{ + (*__glutCurrentWindow->fjoystick) (&button, &x, &y, &z); +} +#endif + +static void +fortranKeyboardWrapper(unsigned char ch, int x, int y) +{ + int chi = ch; + + (*__glutCurrentWindow->fkeyboard) (&chi, &x, &y); +} + +static void +fortranKeyboardUpWrapper(unsigned char ch, int x, int y) +{ + int chi = ch; + + (*__glutCurrentWindow->fkeyboardUp) (&chi, &x, &y); +} + +static void +fortranMouseWrapper(int btn, int state, int x, int y) +{ + (*__glutCurrentWindow->fmouse) (&btn, &state, &x, &y); +} + +static void +fortranMotionWrapper(int x, int y) +{ + (*__glutCurrentWindow->fmotion) (&x, &y); +} + +static void +fortranPassiveMotionWrapper(int x, int y) +{ + (*__glutCurrentWindow->fpassive) (&x, &y); +} + +static void +fortranEntryWrapper(int state) +{ + (*__glutCurrentWindow->fentry) (&state); +} + +static void +fortranVisibilityWrapper(int state) +{ + (*__glutCurrentWindow->fvisibility) (&state); +} + +static void +fortranTimerWrapper(int value) +{ + /* Relies on special knowledge that __glutTimerList points to + the GLUTtimer* currently being processed! */ + (*__glutTimerList->ffunc) (&value); +} + +static void +fortranSelectWrapper(int value) +{ + (*__glutItemSelected->menu->fselect) (&value); +} + +static void +fortranSpecialWrapper(int key, int x, int y) +{ + (*__glutCurrentWindow->fspecial) (&key, &x, &y); +} + +static void +fortranSpecialUpWrapper(int key, int x, int y) +{ + (*__glutCurrentWindow->fspecialUp) (&key, &x, &y); +} + +static void +fortranSpaceballMotionWrapper(int x, int y, int z) +{ + (*__glutCurrentWindow->fspaceMotion) (&x, &y, &z); +} + +static void +fortranSpaceballRotateWrapper(int x, int y, int z) +{ + (*__glutCurrentWindow->fspaceRotate) (&x, &y, &z); +} + +static void +fortranSpaceballButtonWrapper(int button, int state) +{ + (*__glutCurrentWindow->fspaceButton) (&button, &state); +} + +static void +fortranTabletMotionWrapper(int x, int y) +{ + (*__glutCurrentWindow->ftabletMotion) (&x, &y); +} + +static void +fortranTabletButtonWrapper(int button, int state, int x, int y) +{ + (*__glutCurrentWindow->ftabletButton) (&button, &state, &x, &y); +} + +static void +fortranDialsWrapper(int dial, int value) +{ + (*__glutCurrentWindow->fdials) (&dial, &value); +} + +static void +fortranButtonBoxWrapper(int button, int state) +{ + (*__glutCurrentWindow->fbuttonBox) (&button, &state); +} + +#endif /* WRAPPERS_ONLY */ + +#define glutfunc(Name,name,mixed,type) \ +void \ +glut##name##func(GLUT##type##FCB mixed) \ +{ \ + if(mixed == (GLUT##type## FCB) glutnull_) { \ + glut##Name ## Func(NULL); \ + } else { \ + glut##Name##Func(fortran##Name##Wrapper); \ + __glutCurrentWindow->f##mixed = mixed; \ + } \ +} + +glutfunc(Reshape, reshape, reshape, reshape) +glutfunc(Keyboard, keyboard, keyboard, keyboard) +glutfunc(KeyboardUp, keyboardup, keyboardUp, keyboard) +glutfunc(Mouse, mouse, mouse, mouse) +glutfunc(Motion, motion, motion, motion) +glutfunc(Entry, entry, entry, entry) +glutfunc(Visibility, visibility, visibility, visibility) +glutfunc(Special, special, special, special) +glutfunc(SpecialUp, specialup, specialUp, special) +glutfunc(Dials, dials, dials, dials) +glutfunc(SpaceballMotion, spaceballmotion, spaceMotion, spaceMotion) +glutfunc(SpaceballRotate, spaceballrotate, spaceRotate, spaceRotate) +glutfunc(SpaceballButton, spaceballbutton, spaceButton, spaceButton) +glutfunc(PassiveMotion, passivemotion, passive, passive) +glutfunc(ButtonBox, buttonbox, buttonBox, buttonBox) +glutfunc(TabletMotion, tabletmotion, tabletMotion, tabletMotion) +glutfunc(TabletButton, tabletbutton, tabletButton, tabletButton) + +/* Special callback cases. */ + +/* The display has no parameters passed so no need for wrapper. */ +void +glutdisplayfunc(GLUTdisplayFCB display) +{ + glutDisplayFunc((GLUTdisplayCB) display); +} + +int +glutcreatemenu(GLUTselectFCB select) +{ + int menu; + + menu = glutCreateMenu(fortranSelectWrapper); + __glutCurrentMenu->fselect = select; + return menu; +} + +void +gluttimerfunc(unsigned long interval, GLUTtimerFCB timer, int value) +{ + glutTimerFunc((unsigned int) interval, fortranTimerWrapper, value); + /* Relies on special __glutNewTimer variable side effect to + establish Fortran timer func! */ + __glutNewTimer->ffunc = timer; +} + +/* ARGSUSED */ +void +glutjoystickfunc(GLUTjoystickFCB joystick, int pollInterval) +{ +#if 0 /* XXX No IRIX joystick support for now. */ + if(joystick == (GLUTjoystickFCB) glutnull_) { + glutJoystickFunc(NULL, pollInterval); + } else { + glutJoystickFunc(fortranJoystickWrapper, pollInterval); + __glutCurrentWindow->fjoystick = joystick; + } +#endif +} + +void +glutidlefunc(GLUTidleFCB idleFunc) +{ + if (idleFunc == (GLUTidleFCB) glutnull_) { + glutIdleFunc(NULL); + } else { + glutIdleFunc(idleFunc); + } +} + +void +glutmenustatefunc(GLUTmenuStateFCB menuStateFunc) +{ + if (menuStateFunc == (GLUTmenuStateFCB) glutnull_) { + glutMenuStateFunc(NULL); + } else { + glutMenuStateFunc(fortranMenuStateWrapper); + fortranMenuStateFunc = menuStateFunc; + } +} + +void +glutbitmapcharacter(int *font, int ch) +{ + /* + * mkf2c gets confused by double pointers and void* pointers. + * So mkf2c does not complain, we consider the font handle to + * be an int*. But we really get an int** since Fortran + * passes by reference. So to "pedantically decode" the + * pointer, cast it first to int**, then dereference it, + * then cast the result to a void*. + */ + void *trueFont = (void *) *((int **) font); + + glutBitmapCharacter(trueFont, ch); +} + +void +glutstrokecharacter(int *font, int ch) +{ + /* + * mkf2c gets confused by double pointers and void* pointers. + * So mkf2c does not complain, we consider the font handle to + * be an int*. But we really get an int** since Fortran + * passes by reference. So to "pedantically decode" the + * pointer, cast it first to int**, then dereference it, + * then cast the result to a void*. + */ + void *trueFont = (void *) *((int **) font); + + glutStrokeCharacter(trueFont, ch); +} diff --git a/lib/glut-3.7.6/lib/fglut/fglut_8x13.c b/lib/glut-3.7.6/lib/fglut/fglut_8x13.c new file mode 100644 index 0000000000..9d6a91be0b --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_8x13.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_bitmap_8_by_13_ = &glutBitmap8By13; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_9x15.c b/lib/glut-3.7.6/lib/fglut/fglut_9x15.c new file mode 100644 index 0000000000..104372a960 --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_9x15.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_bitmap_9_by_15_ = &glutBitmap9By15; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_hel10.c b/lib/glut-3.7.6/lib/fglut/fglut_hel10.c new file mode 100644 index 0000000000..21f2c64f67 --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_hel10.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 + +void *glut_bitmap_helvetica_10_ = &glutBitmapHelvetica10; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_hel12.c b/lib/glut-3.7.6/lib/fglut/fglut_hel12.c new file mode 100644 index 0000000000..aec2600ceb --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_hel12.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 + +void *glut_bitmap_helvetica_12_ = &glutBitmapHelvetica12; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_hel18.c b/lib/glut-3.7.6/lib/fglut/fglut_hel18.c new file mode 100644 index 0000000000..4147834423 --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_hel18.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 + +void *glut_bitmap_helvetica_18 = &glutBitmapHelvetica18; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_mroman.c b/lib/glut-3.7.6/lib/fglut/fglut_mroman.c new file mode 100644 index 0000000000..60dafee772 --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_mroman.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_stroke_mono_roman_ = &glutStrokeMonoRoman; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_roman.c b/lib/glut-3.7.6/lib/fglut/fglut_roman.c new file mode 100644 index 0000000000..5ea07855cc --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_roman.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_stroke_roman_ = &glutStrokeRoman; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_tr10.c b/lib/glut-3.7.6/lib/fglut/fglut_tr10.c new file mode 100644 index 0000000000..946b82594f --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_tr10.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_bitmap_times_roman_10_ = &glutBitmapTimesRoman10; + diff --git a/lib/glut-3.7.6/lib/fglut/fglut_tr24.c b/lib/glut-3.7.6/lib/fglut/fglut_tr24.c new file mode 100644 index 0000000000..c6d45afc5a --- /dev/null +++ b/lib/glut-3.7.6/lib/fglut/fglut_tr24.c @@ -0,0 +1,11 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996. */ + +/* 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 + +void *glut_bitmap_times_roman_24_ = &glutBitmapTimesRoman24; + diff --git a/lib/glut-3.7.6/lib/gle.n32/ObjectType.mk b/lib/glut-3.7.6/lib/gle.n32/ObjectType.mk new file mode 100644 index 0000000000..6116ff97eb --- /dev/null +++ b/lib/glut-3.7.6/lib/gle.n32/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_N32) +CSTYLE = $(CSTYLE_N32) diff --git a/lib/glut-3.7.6/lib/gle.n64/ObjectType.mk b/lib/glut-3.7.6/lib/gle.n64/ObjectType.mk new file mode 100644 index 0000000000..55d0f47555 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle.n64/ObjectType.mk @@ -0,0 +1,3 @@ +LDOPTS = $(LDOPTS_64) +#OPTIMIZER = -O0 +CSTYLE = $(CSTYLE_64) diff --git a/lib/glut-3.7.6/lib/gle/Imakefile b/lib/glut-3.7.6/lib/gle/Imakefile new file mode 100644 index 0000000000..e71854647f --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/Imakefile @@ -0,0 +1,30 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#define DoNormalLib YES + +#include + +#include "../../Glut.cf" + +EXTRA_DEFINES = -DOPENGL_10 -DAUTO_TEXTURE -D__GUTIL_DOUBLE + +SRCS = ex_angle.c ex_cut_round.c ex_raw.c extrude.c intersect.c \ + rot_prince.c rotate.c round_cap.c segment.c texgen.c \ + urotate.c view.c + +OBJS = ex_angle.o ex_cut_round.o ex_raw.o extrude.o intersect.o \ + rot_prince.o rotate.o round_cap.o segment.o texgen.o \ + urotate.o view.o + +#ifdef LibraryObjectRule +LibraryObjectRule() +#else +/* XXX Very lame, you must be using pre-R5 config files! This + will probably do essentially what LibraryObjectRule does. */ +NormalLibraryObjectRule() +#endif + +NormalLibraryTarget(gle,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/lib/gle/ObjectType.mk b/lib/glut-3.7.6/lib/gle/ObjectType.mk new file mode 100644 index 0000000000..f94dc77f5f --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_32) +CSTYLE = $(CSTYLE_32) diff --git a/lib/glut-3.7.6/lib/gle/copy.h b/lib/glut-3.7.6/lib/gle/copy.h new file mode 100644 index 0000000000..1bfff4bad7 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/copy.h @@ -0,0 +1,18 @@ + +/* + * + * Written By Linas Vepstas November 1991 + */ + + +#define COPY_THREE_WORDS(A,B) { \ + struct three_words { long a, b, c, }; \ + *(struct three_words *) (A) = *(struct three_words *) (B); \ +} + +#define COPY_FOUR_WORDS(A,B) { \ + struct four_words { long a, b, c, d, }; \ + *(struct four_words *) (A) = *(struct four_words *) (B); \ +} + +/* ============================================================= */ diff --git a/lib/glut-3.7.6/lib/gle/ex_angle.c b/lib/glut-3.7.6/lib/gle/ex_angle.c new file mode 100644 index 0000000000..0798c230c2 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/ex_angle.c @@ -0,0 +1,519 @@ + +/* + * MODULE NAME: ex_angle.c + * + * FUNCTION: + * This module contains code that draws extrusions with angled + * joins ("angle join style"). It also inserts colors and normals + * where necessary, if appropriate. + * + * HISTORY: + * written by Linas Vepstas August/September 1991 + * split into multiple compile units, Linas, October 1991 + * added normal vectors Linas, October 1991 + * "code complete" (that is, I'm done), Linas Vepstas, October 1991 + * work around OpenGL's lack of support for concave polys, June 1994 + */ + +#include +#include +#include /* for the memcpy() subroutine */ +#include +#include "port.h" +#include "gutil.h" +#include "vvector.h" +#include "tube_gc.h" +#include "extrude.h" +#include "intersect.h" +#include "segment.h" + +/* ============================================================ */ +/* + * Algorithmic trivia: + * + * There is a slight bit of trivia which the super-duper exacto coder + * needs to know about the code in this module. It is this: + * + * This module attempts to correctly treat contour normal vectors + * by applying the inverse transpose of the 2D contour affine + * transformation to the 2D contour normals. This is perfectly correct, + * when applied to the "raw" join style. However, if the affine transform + * has a strong rotational component, AND the join style is angle or + * cut, then the normal vectors would continue to rotate as the + * intersect point is extrapolated. + * + * The extrapolation of the inverse-transpose matrix to the intersection + * point is not done. This would appear to be overkill for most + * situations. The viewer might possibly detect an artifact of the + * failure to do this correction IF all three of the following criteria + * were met: + * 1) The affine xform has a strong rotational component, + * 2) The angle between two succesive segments is sharp (greater than 15 or + * 30 degrees). + * 3) The join style is angle or cut. + * + * However, I beleive that it is highly unlikely that the viewer will + * detect any artifacts. The reason I beleive this is that a strong + * rotational component will twist a segment so strongly that the more + * visible artifact will be that a segment is composed of triangle strips. + * As the user attempts to minimize the tesselation artifacts by shortening + * segments, then the rotational component will decrease in proportion, + * and the lighting artifact will fall away. + * + * To summarize, there is a slight inexactness in this code. The author + * of the code beleives that this inexactness results in miniscule + * errors in every situation. + * + * Linas Vepstas March 1993 + */ + +/* ============================================================ */ + +void draw_angle_style_front_cap (int ncp, /* number of contour points */ + gleDouble bi[3], /* biscetor */ + gleDouble point_array[][3]) /* polyline */ +{ + int j; +#ifdef OPENGL_10 + GLUtriangulatorObj *tobj; +#endif /* OPENGL_10 */ + + if (bi[2] < 0.0) { + VEC_SCALE (bi, -1.0, bi); + } + +#ifdef GL_32 + /* old-style gl handles concave polygons no problem, so the code is + * simple. New-style gl is a lot more tricky. */ + /* draw the end cap */ + BGNPOLYGON (); + + N3F (bi); + for (j=0; j 0.0) { + VEC_SCALE (bi, -1.0, bi); + } + +#ifdef GL_32 + /* old-style gl handles concave polygons no problem, so the code is + * simple. New-style gl is a lot more tricky. */ + /* draw the end cap */ + BGNPOLYGON (); + + N3F (bi); + for (j=ncp-1; j>=0; j--) { + V3F (point_array[j], j, BACK_CAP); + } + ENDPOLYGON (); +#endif /* GL_32 */ + +#ifdef OPENGL_10 + N3F (bi); + + tobj = gluNewTess (); + gluTessCallback (tobj, GLU_BEGIN, glBegin); + gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); + gluTessCallback (tobj, GLU_END, glEnd); + gluBeginPolygon (tobj); + + for (j=ncp-1; j>=0; j--) { + gluTessVertex (tobj, point_array[j], point_array[j]); + } + gluEndPolygon (tobj); + gluDeleteTess (tobj); +#endif /* OPENGL_10 */ +} + +/* ============================================================ */ + +void extrusion_angle_join (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D normal vecs */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline */ + float color_array[][3], /* color of polyline */ + gleDouble xform_array[][2][3]) /* 2D contour xforms */ +{ + int i, j; + int inext, inextnext; + gleDouble m[4][4]; + gleDouble len; + gleDouble len_seg; + gleDouble diff[3]; + gleDouble bi_0[3], bi_1[3]; /* bisecting plane */ + gleDouble bisector_0[3], bisector_1[3]; /* bisecting plane */ + gleDouble end_point_0[3], end_point_1[3]; + gleDouble origin[3], neg_z[3]; + gleDouble yup[3]; /* alternate up vector */ + gleDouble *front_loop, *back_loop; /* contours in 3D */ + char * mem_anchor; + double *norm_loop; + double *front_norm, *back_norm, *tmp; /* contour normals in 3D */ + int first_time; + + /* By definition, the contour passed in has its up vector pointing in + * the y direction */ + if (up == NULL) { + yup[0] = 0.0; + yup[1] = 1.0; + yup[2] = 0.0; + } else { + VEC_COPY(yup, up); + } + + /* ========== "up" vector sanity check ========== */ + (void) up_sanity_check (yup, npoints, point_array); + + /* the origin is at the origin */ + origin [0] = 0.0; + origin [1] = 0.0; + origin [2] = 0.0; + + /* and neg_z is at neg z */ + neg_z[0] = 0.0; + neg_z[1] = 0.0; + neg_z[2] = 1.0; + + /* ignore all segments of zero length */ + i = 1; + inext = i; + FIND_NON_DEGENERATE_POINT (inext, npoints, len, diff, point_array); + len_seg = len; /* store for later use */ + + /* get the bisecting plane */ + bisecting_plane (bi_0, point_array[0], + point_array[1], + point_array[inext]); + /* reflect the up vector in the bisecting plane */ + VEC_REFLECT (yup, yup, bi_0); + + /* malloc the storage we'll need for relaying changed contours to the + * drawing routines. */ + mem_anchor = malloc (2 * 3 * ncp * sizeof(double) + + 2 * 3 * ncp * sizeof(gleDouble)); + front_loop = (gleDouble *) mem_anchor; + back_loop = front_loop + 3 * ncp; + front_norm = (double *) (back_loop + 3 * ncp); + back_norm = front_norm + 3 * ncp; + norm_loop = front_norm; + + /* may as well get the normals set up now */ + if (cont_normal != NULL) { + if (xform_array == NULL) { + for (j=0; j +#include +#include /* for the memcpy() subroutine */ +#include +#include "port.h" +#include "gutil.h" +#include "vvector.h" +#include "tube_gc.h" +#include "extrude.h" +#include "intersect.h" +#include "segment.h" + + +#ifdef NONCONCAVE_CAPS + +/* ============================================================ */ +/* + * This subroutine draws a flat cap, to close off the cut ends + * of the cut-style join. Because OpenGL doe not natively handle + * concave polygons, this will cause some artifacts to appear on the + * screen. + */ + +void draw_cut_style_cap_callback (int iloop, + double cap[][3], + float face_color[3], + gleDouble cut_vector[3], + gleDouble bisect_vector[3], + double norms[][3], + int frontwards) +{ + int i; + + if (face_color != NULL) C3F (face_color); + + if (frontwards) { + + /* if lighting is on, specify the endcap normal */ + if (cut_vector != NULL) { + /* if normal pointing in wrong direction, flip it. */ + if (cut_vector[2] < 0.0) { + VEC_SCALE (cut_vector, -1.0, cut_vector); + } + N3F_D (cut_vector); + } + BGNPOLYGON(); + for (i=0; i 0.0) + { VEC_SCALE (cut_vector, -1.0, cut_vector); } + N3F_D (cut_vector); + } + /* the sense of the loop is reversed for backfacing culling */ + BGNPOLYGON(); + for (i=iloop-1; i>-1; i--) { + V3F_D (cap[i], i, BACK_CAP); + } + ENDPOLYGON(); + } + +} + +#else /* NONCONCAVE_CAPS */ + +/* ============================================================ */ +/* + * This subroutine draws a flat cap, to close off the cut ends + * of the cut-style join. Properly handles concave endcaps. + */ + +/* ARGSUSED4 */ +static void draw_cut_style_cap_callback (int iloop, + double cap[][3], + float face_color[3], + gleDouble cut_vector[3], + gleDouble bisect_vector[3], + double norms[][3], + int frontwards) +{ + int i; +#ifdef OPENGL_10 + GLUtriangulatorObj *tobj; + tobj = gluNewTess (); + gluTessCallback (tobj, GLU_BEGIN, glBegin); + gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); + gluTessCallback (tobj, GLU_END, glEnd); +#endif /* OPENGL_10 */ + + if (face_color != NULL) C3F (face_color); + + if (frontwards) { + + /* if lighting is on, specify the endcap normal */ + if (cut_vector != NULL) { + /* if normal pointing in wrong direction, flip it. */ + if (cut_vector[2] < 0.0) { + VEC_SCALE (cut_vector, -1.0, cut_vector); + } + N3F_D (cut_vector); + } +#ifdef GL_32 + BGNPOLYGON(); + for (i=0; i 0.0) { + VEC_SCALE (cut_vector, -1.0, cut_vector); + } + N3F_D (cut_vector); + } + /* the sense of the loop is reversed for backfacing culling */ +#ifdef GL_32 + BGNPOLYGON(); + for (i=iloop-1; i>-1; i--) { + V3F_D (cap[i], i, BACK_CAP); + } + ENDPOLYGON(); +#endif /* GL_32 */ +#ifdef OPENGL_10 + gluBeginPolygon (tobj); + for (i=iloop-1; i>-1; i--) { + gluTessVertex (tobj, cap[i], cap[i]); + } + gluEndPolygon (tobj); +#endif /* OPENGL_10 */ + } + +#ifdef OPENGL_10 + gluDeleteTess (tobj); +#endif /* OPENGL_10 */ + +} +#endif /* NONCONCAVE_ENDCAPS */ + +/* ============================================================ */ +/* + * This subroutine matchs the cap callback template, but is a no-op + */ + +/* ARGSUSED */ +void null_cap_callback (int iloop, + double cap[][3], + float face_color[3], + gleDouble cut_vector[3], + gleDouble bisect_vector[3], + double norms[][3], + int frontwards) +{} + +/* ============================================================ */ +/* + * This little routine draws the little idd-biddy fillet triangle with + * the right color, normal, etc. + * + * HACK ALERT -- there are two aspects to this routine/interface that + * are "unfinished". + * 1) the third point of the triangle should get a color thats + * interpolated beween the front and back color. The interpolant + * is not currently being computed. The error introduced by not + * doing this should be tiny and/or non-exitant in almost all + * expected uses of this code. + * + * 2) additional normal vectors should be supplied, and these should + * be interpolated to fit. Currently, this is not being done. As + * above, the expected error of not doing this should be tiny and/or + * non-existant in almost all expected uses of this code. + */ +/* ARGSUSED6 */ +static void draw_fillet_triangle_plain + (gleDouble va[3], + gleDouble vb[3], + gleDouble vc[3], + int face, + float front_color[3], + float back_color[3]) +{ + + if (front_color != NULL) C3F (front_color); + BGNTMESH (-5, 0.0); + if (face) { + V3F (va, -1, FILLET); + V3F (vb, -1, FILLET); + } else { + V3F (vb, -1, FILLET); + V3F (va, -1, FILLET); + } + V3F (vc, -1, FILLET); + ENDTMESH (); + +} + +/* ============================================================ */ +/* + * This little routine draws the little idd-biddy fillet triangle with + * the right color, normal, etc. + * + * HACK ALERT -- there are two aspects to this routine/interface that + * are "unfinished". + * 1) the third point of the triangle should get a color thats + * interpolated beween the front and back color. The interpolant + * is not currently being computed. The error introduced by not + * doing this should be tiny and/or non-exitant in almost all + * expected uses of this code. + * + * 2) additional normal vectors should be supplied, and these should + * be interpolated to fit. Currently, this is not being done. As + * above, the expected error of not doing this should be tiny and/or + * non-existant in almost all expected uses of this code. + */ +/* ARGSUSED5 */ +static void draw_fillet_triangle_n_norms + (gleDouble va[3], + gleDouble vb[3], + gleDouble vc[3], + int face, + float front_color[3], + float back_color[3], + double na[3], + double nb[3]) +{ + + if (front_color != NULL) C3F (front_color); + BGNTMESH (-5, 0.0); + if (__TUBE_DRAW_FACET_NORMALS) { + N3F_D (na); + if (face) { + V3F (va, -1, FILLET); + V3F (vb, -1, FILLET); + } else { + V3F (vb, -1, FILLET); + V3F (va, -1, FILLET); + } + V3F (vc, -1, FILLET); + } else { + if (face) { + N3F_D (na); + V3F (va, -1, FILLET); + N3F_D (nb); + V3F (vb, -1, FILLET); + } else { + N3F_D (nb); + V3F (vb, -1, FILLET); + N3F_D (na); + V3F (va, -1, FILLET); + N3F_D (nb); + } + V3F (vc, -1, FILLET); + } + ENDTMESH (); + +} + +/* ============================================================ */ + +static void draw_fillets_and_join_plain + (int ncp, + gleDouble trimmed_loop[][3], + gleDouble untrimmed_loop[][3], + int is_trimmed[], + gleDouble bis_origin[3], + gleDouble bis_vector[3], + float front_color[3], + float back_color[3], + gleDouble cut_vector[3], + int face, + void ((*cap_callback) (int iloop, + double cap[][3], + float face_color[3], + gleDouble cut_vector[3], + gleDouble bisect_vector[3], + double norms[][3], + int frontwards))) +{ + int istop; + int icnt, icnt_prev, iloop; + double *cap_loop; + gleDouble sect[3]; + gleDouble tmp_vec[3]; + int save_style; + int was_trimmed = FALSE; + + cap_loop = (double *) malloc ((ncp+3)*3*sizeof (double)); + + /* if the first point on the contour isn't trimmed, go ahead and + * drop an edge down to the bisecting plane, (thus starting the + * join). (Only need to do this for cut join, its bad if done for + * round join). + * + * But if the first point is trimmed, keep going until one + * is found that is not trimmed, and start join there. */ + + icnt = 0; + iloop = 0; + if (!is_trimmed[0]) { + if (__TUBE_CUT_JOIN) { + VEC_SUM (tmp_vec, trimmed_loop[0], bis_vector); + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[0], + tmp_vec); + VEC_COPY ( (&cap_loop[3*iloop]), sect); + iloop ++; + } + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[0])); + iloop++; + icnt_prev = icnt; + icnt ++; + } else { + + /* else, loop until an untrimmed point is found */ + was_trimmed = TRUE; + while (is_trimmed[icnt]) { + icnt_prev = icnt; + icnt ++; + if (icnt >= ncp) { + free (cap_loop); + return; /* oops - everything was trimmed */ + } + } + } + + /* Start walking around the end cap. Every time the end loop is + * trimmed, we know we'll need to draw a fillet triangle. In + * addition, after every pair of visibility changes, we draw a cap. */ + if (__TUBE_CLOSE_CONTOUR) { + istop = ncp; + } else { + istop = ncp-1; + } + + /* save the join style, and disable a closed contour. + * Need to do this so partial contours don't close up. */ + save_style = gleGetJoinStyle (); + gleSetJoinStyle (save_style & ~TUBE_CONTOUR_CLOSED); + + for (; icnt_prev < istop; icnt_prev ++, icnt ++, icnt %= ncp) { + + /* There are four interesting cases for drawing caps and fillets: + * 1) this & previous point were trimmed. Don't do anything, + * advance counter. + * 2) this point trimmed, previous not -- draw fillet, and + * draw cap. + * 3) this point not trimmed, previous one was -- compute + * intersection point, draw fillet with it, and save + * point for cap contour. + * 4) this & previous point not trimmed -- save for endcap. + */ + + /* Case 1 -- noop, just advance pointers */ + if (is_trimmed[icnt_prev] && is_trimmed[icnt]) { + } + + /* Case 2 -- Hah! first point! compute intersect & draw fillet! */ + if (is_trimmed[icnt_prev] && !is_trimmed[icnt]) { + + /* important note: the array "untrimmed" contains valid + * untrimmed data ONLY when is_trim is TRUE. Otherwise, + * only "trim" containes valid data */ + + /* compute intersection */ + INNERSECT (sect, + bis_origin, + bis_vector, + untrimmed_loop[icnt_prev], + trimmed_loop[icnt]); + + /* Draw Fillet */ + draw_fillet_triangle_plain (trimmed_loop[icnt_prev], + trimmed_loop[icnt], + sect, + face, + front_color, + back_color); + + VEC_COPY ( (&cap_loop[3*iloop]), sect); + iloop ++; + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); + iloop++; + } + + /* Case 3 -- add to collection of points */ + if (!is_trimmed[icnt_prev] && !is_trimmed[icnt]) { + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); + iloop++; + } + + /* Case 4 -- Hah! last point! draw fillet & draw cap! */ + if (!is_trimmed[icnt_prev] && is_trimmed[icnt]) { + was_trimmed = TRUE; + + /* important note: the array "untrimmed" contains valid + * untrimmed data ONLY when is_trim is TRUE. Otherwise, + * only "trim" containes valid data */ + + /* compute intersection */ + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[icnt_prev], + untrimmed_loop[icnt]); + + /* Draw Fillet */ + draw_fillet_triangle_plain (trimmed_loop[icnt_prev], + trimmed_loop[icnt], + sect, + face, + front_color, + back_color); + + VEC_COPY ( (&cap_loop[3*iloop]), sect); + iloop ++; + + /* draw cap */ + if (iloop >= 3) (*cap_callback) (iloop, + (gleDouble (*)[3]) cap_loop, + front_color, + cut_vector, + bis_vector, + NULL, + face); + + /* reset cap counter */ + iloop = 0; + } + } + + /* now, finish up in the same way that we started. If the last + * point of the contour is visible, drop an edge to the bisecting + * plane, thus finishing the join, and then, draw the join! */ + + icnt --; /* decrement to make up for loop exit condititons */ + icnt += ncp; + icnt %= ncp; + if ((!is_trimmed[icnt]) && (iloop >= 2)) { + + VEC_SUM (tmp_vec, trimmed_loop[icnt], bis_vector); + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[icnt], + tmp_vec); + VEC_COPY ( (&cap_loop[3*iloop]), sect); + iloop ++; + + /* if nothing was ever trimmed, then we want to draw the + * cap the way the user asked for it -- closed or not closed. + * Therefore, reset the closure flag to its original state. + */ + if (!was_trimmed) { + gleSetJoinStyle (save_style); + } + + /* draw cap */ + (*cap_callback) (iloop, + (gleDouble (*)[3]) cap_loop, + front_color, + cut_vector, + bis_vector, + NULL, + face); + } + + /* rest to the saved style */ + gleSetJoinStyle (save_style); + free (cap_loop); +} + +/* ============================================================ */ + +void draw_fillets_and_join_n_norms + (int ncp, + gleDouble trimmed_loop[][3], + gleDouble untrimmed_loop[][3], + int is_trimmed[], + gleDouble bis_origin[3], + gleDouble bis_vector[3], + double normals[][3], + float front_color[3], + float back_color[3], + gleDouble cut_vector[3], + int face, + void ((*cap_callback) (int iloop, + double cap[][3], + float face_color[3], + gleDouble cut_vector[3], + gleDouble bisect_vector[3], + double norms[][3], + int frontwards))) +{ + int istop; + int icnt, icnt_prev, iloop; + double *cap_loop, *norm_loop; + gleDouble sect[3]; + gleDouble tmp_vec[3]; + int save_style; + int was_trimmed = FALSE; + + cap_loop = (double *) malloc ((ncp+3)*3*2*sizeof (double)); + norm_loop = cap_loop + (ncp+3)*3; + + /* if the first point on the contour isn't trimmed, go ahead and + * drop an edge down to the bisecting plane, (thus starting the + * join). (Only need to do this for cut join, its bad if done for + * round join). + * + * But if the first point is trimmed, keep going until one + * is found that is not trimmed, and start join there. */ + + icnt = 0; + iloop = 0; + if (!is_trimmed[0]) { + if (__TUBE_CUT_JOIN) { + VEC_SUM (tmp_vec, trimmed_loop[0], bis_vector); + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[0], + tmp_vec); + VEC_COPY ( (&cap_loop[3*iloop]), sect); + VEC_COPY ( (&norm_loop[3*iloop]), normals[0]); + iloop ++; + } + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[0])); + VEC_COPY ( (&norm_loop[3*iloop]), normals[0]); + iloop++; + icnt_prev = icnt; + icnt ++; + } else { + + /* else, loop until an untrimmed point is found */ + was_trimmed = TRUE; + while (is_trimmed[icnt]) { + icnt_prev = icnt; + icnt ++; + if (icnt >= ncp) { + free (cap_loop); + return; /* oops - everything was trimmed */ + } + } + } + + /* Start walking around the end cap. Every time the end loop is + * trimmed, we know we'll need to draw a fillet triangle. In + * addition, after every pair of visibility changes, we draw a cap. */ + if (__TUBE_CLOSE_CONTOUR) { + istop = ncp; + } else { + istop = ncp-1; + } + + /* save the join style, and disable a closed contour. + * Need to do this so partial contours don't close up. */ + save_style = gleGetJoinStyle (); + gleSetJoinStyle (save_style & ~TUBE_CONTOUR_CLOSED); + + for (; icnt_prev < istop; icnt_prev ++, icnt ++, icnt %= ncp) { + + /* There are four interesting cases for drawing caps and fillets: + * 1) this & previous point were trimmed. Don't do anything, + * advance counter. + * 2) this point trimmed, previous not -- draw fillet, and + * draw cap. + * 3) this point not trimmed, previous one was -- compute + * intersection point, draw fillet with it, and save + * point for cap contour. + * 4) this & previous point not trimmed -- save for endcap. + */ + + /* Case 1 -- noop, just advance pointers */ + if (is_trimmed[icnt_prev] && is_trimmed[icnt]) { + } + + /* Case 2 -- Hah! first point! compute intersect & draw fillet! */ + if (is_trimmed[icnt_prev] && !is_trimmed[icnt]) { + + /* important note: the array "untrimmed" contains valid + * untrimmed data ONLY when is_trim is TRUE. Otherwise, + * only "trim" containes valid data */ + + /* compute intersection */ + INNERSECT (sect, + bis_origin, + bis_vector, + untrimmed_loop[icnt_prev], + trimmed_loop[icnt]); + + /* Draw Fillet */ + draw_fillet_triangle_n_norms (trimmed_loop[icnt_prev], + trimmed_loop[icnt], + sect, + face, + front_color, + back_color, + normals[icnt_prev], + normals[icnt]); + VEC_COPY ( (&cap_loop[3*iloop]), sect); + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt_prev]); + iloop ++; + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); + iloop++; + } + + /* Case 3 -- add to collection of points */ + if (!is_trimmed[icnt_prev] && !is_trimmed[icnt]) { + VEC_COPY ( (&cap_loop[3*iloop]), (trimmed_loop[icnt])); + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); + iloop++; + } + + /* Case 4 -- Hah! last point! draw fillet & draw cap! */ + if (!is_trimmed[icnt_prev] && is_trimmed[icnt]) { + was_trimmed = TRUE; + + /* important note: the array "untrimmed" contains valid + * untrimmed data ONLY when is_trim is TRUE. Otherwise, + * only "trim" containes valid data */ + + /* compute intersection */ + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[icnt_prev], + untrimmed_loop[icnt]); + + /* Draw Fillet */ + draw_fillet_triangle_n_norms (trimmed_loop[icnt_prev], + trimmed_loop[icnt], + sect, + face, + front_color, + back_color, + normals[icnt_prev], + normals[icnt]); + + VEC_COPY ( (&cap_loop[3*iloop]), sect); + + /* OK, maybe phong normals are wrong, but at least facet + * normals will come out OK. */ + if (__TUBE_DRAW_FACET_NORMALS) { + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt_prev]); + } else { + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); + } + iloop ++; + + /* draw cap */ + if (iloop >= 3) (*cap_callback) (iloop, + (gleDouble (*)[3]) cap_loop, + front_color, + cut_vector, + bis_vector, + (gleDouble (*)[3]) norm_loop, + face); + + /* reset cap counter */ + iloop = 0; + } + } + + /* now, finish up in the same way that we started. If the last + * point of the contour is visible, drop an edge to the bisecting + * plane, thus finishing the join, and then, draw the join! */ + + icnt --; /* decrement to make up for loop exit condititons */ + icnt += ncp; + icnt %= ncp; + if ((!is_trimmed[icnt]) && (iloop >= 2)) { + + if (__TUBE_CUT_JOIN) { + VEC_SUM (tmp_vec, trimmed_loop[icnt], bis_vector); + INNERSECT (sect, + bis_origin, + bis_vector, + trimmed_loop[icnt], + tmp_vec); + VEC_COPY ( (&cap_loop[3*iloop]), sect); + VEC_COPY ( (&norm_loop[3*iloop]), normals[icnt]); + iloop ++; + } + + /* if nothing was ever trimmed, then we want to draw the + * cap the way the user asked for it -- closed or not closed. + * Therefore, reset the closure flag to its original state. + */ + if (!was_trimmed) { + gleSetJoinStyle (save_style); + } + + /* draw cap */ + (*cap_callback) (iloop, + (gleDouble (*)[3]) cap_loop, + front_color, + cut_vector, + bis_vector, + (gleDouble (*)[3]) norm_loop, + face); + } + + /* rest to the saved style */ + gleSetJoinStyle (save_style); + free (cap_loop); +} + +/* ============================================================ */ +/* This routine draws "cut" style extrusions. + */ + +void extrusion_round_or_cut_join (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2],/* 2D normal vecs */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline */ + float color_array[][3], /* color of polyline */ + gleDouble xform_array[][2][3]) /* 2D contour xforms */ +{ + int i, j; + int inext, inextnext; + gleDouble m[4][4]; + gleDouble tube_len, seg_len; + gleDouble diff[3]; + gleDouble bi_0[3], bi_1[3]; /* bisecting plane */ + gleDouble bisector_0[3], bisector_1[3]; /* bisecting plane */ + gleDouble cut_0[3], cut_1[3]; /* cutting planes */ + gleDouble lcut_0[3], lcut_1[3]; /* cutting planes */ + int valid_cut_0, valid_cut_1; /* flag -- cut vector is valid */ + gleDouble end_point_0[3], end_point_1[3]; + gleDouble torsion_point_0[3], torsion_point_1[3]; + gleDouble isect_point[3]; + gleDouble origin[3], neg_z[3]; + gleDouble yup[3]; /* alternate up vector */ + gleDouble *front_cap, *back_cap; /* arrays containing the end caps */ + gleDouble *front_loop, *back_loop; /* arrays containing the tube ends */ + double *front_norm, *back_norm; /* arrays containing normal vecs */ + double *norm_loop, *tmp; /* normal vectors, cast into 3d from 2d */ + int *front_is_trimmed, *back_is_trimmed; /* T or F */ + float *front_color, *back_color; /* pointers to segment colors */ + void ((*cap_callback) (int,double [][3],float [3],gleDouble [3], gleDouble [3], double [][3],int)); /* function callback to draw cap */ + void ((*tmp_cap_callback) (int,double [][3],float [3],gleDouble [3], gleDouble [3], double [][3],int)); /* function callback to draw cap */ + + int join_style_is_cut; /* TRUE if join style is cut */ + double dot; /* partial dot product */ + char *mem_anchor; + int first_time = TRUE; + gleDouble *cut_vec; + + /* create a local, block scope copy of of the join style. + * this will alleviate wasted cycles and register write-backs */ + /* choose the right callback, depending on the choosen join style */ + if (__TUBE_CUT_JOIN) { + join_style_is_cut = TRUE; + cap_callback = draw_cut_style_cap_callback; + } else { + join_style_is_cut = FALSE; + cap_callback = draw_round_style_cap_callback; + } + + /* By definition, the contour passed in has its up vector pointing in + * the y direction */ + if (up == NULL) { + yup[0] = 0.0; + yup[1] = 1.0; + yup[2] = 0.0; + } else { + VEC_COPY (yup, up); + } + + /* ========== "up" vector sanity check ========== */ + (void) up_sanity_check (yup, npoints, point_array); + + /* the origin is at the origin */ + origin [0] = 0.0; + origin [1] = 0.0; + origin [2] = 0.0; + + /* and neg_z is at neg z */ + neg_z[0] = 0.0; + neg_z[1] = 0.0; + neg_z[2] = 1.0; + + /* malloc the data areas that we'll need to store the end-caps */ + mem_anchor = malloc (4 * 3*ncp*sizeof(gleDouble) + + 2 * 3*ncp*sizeof(double) + + 2 * 1*ncp*sizeof(int)); + front_norm = (double *) mem_anchor; + back_norm = front_norm + 3*ncp; + front_loop = (gleDouble *) (back_norm + 3*ncp); + back_loop = front_loop + 3*ncp; + front_cap = back_loop + 3*ncp; + back_cap = front_cap + 3*ncp; + front_is_trimmed = (int *) (back_cap + 3*ncp); + back_is_trimmed = front_is_trimmed + ncp; + + /* ======================================= */ + + /* |-|-|-|-|-|-|-|-| SET UP FOR FIRST SEGMENT |-|-|-|-|-|-|-| */ + + /* ignore all segments of zero length */ + i = 1; + inext = i; + FIND_NON_DEGENERATE_POINT (inext, npoints, seg_len, diff, point_array); + tube_len = seg_len; /* store for later use */ + + /* may as well get the normals set up now */ + if (cont_normal != NULL) { + if (xform_array == NULL) { + norm_loop = front_norm; + back_norm = norm_loop; + for (j=0; j 0.0)) { +*/ + VEC_COPY ((&front_cap[3*j]), (&front_loop [3*j])); + VEC_COPY ((&front_loop[3*j]), isect_point); + front_is_trimmed[j] = TRUE; + } else { + front_is_trimmed[j] = FALSE; + } + + /* if intersection is behind the end of the segment, + * truncate to the end of the segment + * Note that coding front_loop [3*j+2] = -tube_len; + * doesn't work when twists are involved, */ + if (front_loop[3*j+2] < -tube_len) { + VEC_COPY( (&front_loop[3*j]), end_point_1); + } + + /* --------------------------------------------------- */ + /* The two end-points define a line. We did one endpoint + * above. Now do the other.Intersect this line + * against the clipping plane defined by the NEXT + * tube segment. */ + + /* if this and the last tube are co-linear, don't cut the angle + * if you do, a divide by zero will result. This and last tube + * are co-linear when the cut vector is of zero length */ + if (valid_cut_1 && join_style_is_cut) { + INNERSECT (isect_point, /* isect point (returned) */ + neg_z, /* point on intersecting plane */ + lcut_1, /* normal vector to plane */ + end_point_1, /* point on line */ + end_point_0); /* another point on the line */ + + if (lcut_1[2] > 0.0) { VEC_SCALE (lcut_1, -1.0, lcut_1); } + dot = lcut_1[0] * end_point_1[0]; + dot += lcut_1[1] * end_point_1[1]; + + + VEC_COPY ((&back_loop[3*j]), isect_point); + } else { + /* actual value of dot not interseting; need + * only be positive so that if test below failes */ + dot = 1.0; + VEC_COPY ((&back_loop[3*j]), end_point_1); + } + + INNERSECT (isect_point, /* intersection point (returned) */ + neg_z, /* point on intersecting plane */ + bisector_1, /* normal vector to plane */ + torsion_point_0, /* point on line */ + end_point_1); /* another point on the line */ + + /* cut out interior of intersecting tube */ + /* ... but save the uncut version for drawing the endcaps */ + /* ... note that cap contains valid data ONLY when is + *_trimmed is TRUE. */ +/* + if ((dot <= 0.0) || (back_loop[3*j+2] < -tube_len)) { +*/ + if ((dot <= 0.0) || (isect_point[2] > back_loop[3*j+2])) { + VEC_COPY ((&back_cap[3*j]), (&back_loop [3*j])); + VEC_COPY ((&back_loop[3*j]), isect_point); + back_is_trimmed[j] = TRUE; + } else { + back_is_trimmed[j] = FALSE; + } + + /* if intersection is behind the end of the segment, + * truncate to the end of the segment + * Note that coding back_loop [3*j+2] = 0.0; + * doesn't work when twists are involved, */ + if (back_loop[3*j+2] > 0.0) { + VEC_COPY( (&back_loop[3*j]), end_point_0); + } + } + + /* --------- END OF TMESH GENERATION -------------- */ + + /* |||||||||||||||||| START SEGMENT DRAW |||||||||||||||||||| */ + /* There are six different cases we can have for presence and/or + * absecnce of colors and normals, and for interpretation of + * normals. The blechy set of nested if statements below + * branch to each of the six cases */ + if (xform_array == NULL) { + if (color_array == NULL) { + if (cont_normal == NULL) { + draw_segment_plain (ncp, (gleVector *) front_loop, (gleVector *) back_loop, inext, seg_len); + } else + if (__TUBE_DRAW_FACET_NORMALS) { + draw_segment_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, + inext, seg_len); + } else { + draw_segment_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, + inext, seg_len); + } + } else { + if (cont_normal == NULL) { + draw_segment_color (ncp, (gleVector *) front_loop, (gleVector *) back_loop, + color_array[inext-1], + color_array[inext], inext, seg_len); + } else + if (__TUBE_DRAW_FACET_NORMALS) { + draw_segment_c_and_facet_n (ncp, + (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, + color_array[inext-1], + color_array[inext], inext, seg_len); + } else { + draw_segment_c_and_edge_n (ncp, + (gleVector *) front_loop, (gleVector *) back_loop, (gleVector *) norm_loop, + color_array[inext-1], + color_array[inext], inext, seg_len); + } + } + } else { + if (color_array == NULL) { + if (cont_normal == NULL) { + draw_segment_plain (ncp, (gleVector *) front_loop, (gleVector *) back_loop, inext, seg_len); + } else + if (__TUBE_DRAW_FACET_NORMALS) { + draw_binorm_segment_facet_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, + (gleVector *) front_norm, (gleVector *) back_norm, + inext, seg_len); + } else { + draw_binorm_segment_edge_n (ncp, (gleVector *) front_loop, (gleVector *) back_loop, + (gleVector *) front_norm, (gleVector *) back_norm, + inext, seg_len); + } + } else { + if (cont_normal == NULL) { + draw_segment_color (ncp, (gleVector *) front_loop, (gleVector *) back_loop, + color_array[inext-1], + color_array[inext], inext, seg_len); + } else + if (__TUBE_DRAW_FACET_NORMALS) { + draw_binorm_segment_c_and_facet_n (ncp, + (gleVector *) front_loop, (gleVector *) back_loop, + (gleVector *) front_norm, (gleVector *) back_norm, + color_array[inext-1], + color_array[inext], inext, seg_len); + } else { + draw_binorm_segment_c_and_edge_n (ncp, + (gleVector *) front_loop, (gleVector *) back_loop, + (gleVector *) front_norm, (gleVector *) back_norm, + color_array[inext-1], + color_array[inext], inext, seg_len); + } + } + } + /* |||||||||||||||||| END SEGMENT DRAW |||||||||||||||||||| */ + + /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + + /* if end caps are required, draw them. But don't draw any + * but the very first and last caps */ + if (first_time) { + first_time = FALSE; + tmp_cap_callback = cap_callback; + cap_callback = null_cap_callback; + if (__TUBE_DRAW_CAP) { + if (color_array != NULL) C3F (color_array[inext-1]); + draw_angle_style_front_cap (ncp, bisector_0, (gleDouble (*)[3]) front_loop); + } + } + /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + + /* $$$$$$$$$$$$$$$$ BEGIN -1, FILLET & JOIN DRAW $$$$$$$$$$$$$$$$$ */ + /* + * Now, draw the fillet triangles, and the join-caps. + */ + if (color_array != NULL) { + front_color = color_array[inext-1]; + back_color = color_array[inext]; + } else { + front_color = NULL; + back_color = NULL; + } + + if (cont_normal == NULL) { + /* the flag valid-cut is true if the cut vector has a valid + * value (i.e. if a degenerate case has not occured). + */ + if (valid_cut_0) { + cut_vec = lcut_0; + } else { + cut_vec = NULL; + } + draw_fillets_and_join_plain (ncp, + (gleVector *) front_loop, + (gleVector *) front_cap, + front_is_trimmed, + origin, + bisector_0, + front_color, + back_color, + cut_vec, + TRUE, + cap_callback); + + /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + if (inext == npoints-2) { + if (__TUBE_DRAW_CAP) { + if (color_array != NULL) C3F (color_array[inext]); + draw_angle_style_back_cap (ncp, bisector_1, (gleDouble (*)[3]) back_loop); + cap_callback = null_cap_callback; + } + } else { + /* restore ability to draw cap */ + cap_callback = tmp_cap_callback; + } + /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + + /* the flag valid-cut is true if the cut vector has a valid + * value (i.e. if a degenerate case has not occured). + */ + if (valid_cut_1) { + cut_vec = lcut_1; + } else { + cut_vec = NULL; + } + draw_fillets_and_join_plain (ncp, + (gleVector *) back_loop, + (gleVector *) back_cap, + back_is_trimmed, + neg_z, + bisector_1, + back_color, + front_color, + cut_vec, + FALSE, + cap_callback); + } else { + + /* the flag valid-cut is true if the cut vector has a valid + * value (i.e. if a degenerate case has not occured). + */ + if (valid_cut_0) { + cut_vec = lcut_0; + } else { + cut_vec = NULL; + } + draw_fillets_and_join_n_norms (ncp, + (gleVector *) front_loop, + (gleVector *) front_cap, + front_is_trimmed, + origin, + bisector_0, + (gleVector *) front_norm, + front_color, + back_color, + cut_vec, + TRUE, + cap_callback); + + /* v^v^v^v^v^v^v^v^v BEGIN END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + if (inext == npoints-2) { + if (__TUBE_DRAW_CAP) { + if (color_array != NULL) C3F (color_array[inext]); + draw_angle_style_back_cap (ncp, bisector_1, (gleDouble (*)[3]) back_loop); + cap_callback = null_cap_callback; + } + } else { + /* restore ability to draw cap */ + cap_callback = tmp_cap_callback; + } + /* v^v^v^v^v^v^v^v^v END END CAPS v^v^v^v^v^v^v^v^v^v^v^v */ + + /* the flag valid-cut is true if the cut vector has a valid + * value (i.e. if a degenerate case has not occured). + */ + if (valid_cut_1) { + cut_vec = lcut_1; + } else { + cut_vec = NULL; + } + draw_fillets_and_join_n_norms (ncp, + (gleVector *) back_loop, + (gleVector *) back_cap, + back_is_trimmed, + neg_z, + bisector_1, + (gleVector *) back_norm, + back_color, + front_color, + cut_vec, + FALSE, + cap_callback); + } + + /* $$$$$$$$$$$$$$$$ END FILLET & JOIN DRAW $$$$$$$$$$$$$$$$$ */ + + /* pop this matrix, do the next set */ + POPMATRIX (); + + /* slosh stuff over to next vertex */ + tmp = front_norm; + front_norm = back_norm; + back_norm = tmp; + + tube_len = seg_len; + i = inext; + inext = inextnext; + VEC_COPY (bi_0, bi_1); + VEC_COPY (cut_0, cut_1); + valid_cut_0 = valid_cut_1; + + /* reflect the up vector in the bisecting plane */ + VEC_REFLECT (yup, yup, bi_0); + } + /* |-|-|-|-|-|-|-|-| END LOOP OVER SEGMENTS |-|-|-|-|-|-|-| */ + + free (mem_anchor); + +} + +/* =================== END OF FILE =============================== */ diff --git a/lib/glut-3.7.6/lib/gle/ex_raw.c b/lib/glut-3.7.6/lib/gle/ex_raw.c new file mode 100644 index 0000000000..c54b7a1277 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/ex_raw.c @@ -0,0 +1,948 @@ +/* + * MODULE NAME: ex_raw.c + * + * FUNCTION: + * This module contains code that draws extrusions with square + * ("raw join style") end styles. It also inserts colors and normals + * where necessary, if appropriate. + * + * HISTORY: + * written by Linas Vepstas August/September 1991 + * split into multiple compile units, Linas, October 1991 + * added normal vectors Linas, October 1991 + * "code complete" (that is, I'm done), Linas Vepstas, October 1991 + * work around OpenGL's lack of support for concave polys, June 1994 + */ + +#include +#include +#include /* for the memcpy() subroutine */ +#include /* to get stderr defined */ +#include + +#include "port.h" +#include "gutil.h" +#include "vvector.h" +#include "tube_gc.h" +#include "extrude.h" +#include "intersect.h" +#include "segment.h" + +/* ============================================================ */ +/* + * The following routine is, in principle, very simple: + * all that it does is normalize the up vector, and makes + * sure that it is perpendicular to the initial polyline segment. + * + * In fact, this routine gets awfully complicated because: + * a) the first few segements of the polyline might be degenerate, + * b) up vecotr may be parallel to first few segments of polyline, + * c) etc. + * + */ + +void up_sanity_check (gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3]) /* polyline */ +{ + int i; + double len; + double diff[3]; + + /* now, right off the bat, we should make sure that the up vector + * is in fact perpendicular to the polyline direction */ + VEC_DIFF (diff, point_array[1], point_array[0]); + VEC_LENGTH (len, diff); + if (len == 0.0) { + /* This error message should go through "official" error interface */ +/* + fprintf (stderr, "Extrusion: Warning: initial segment zero length \n"); +*/ + + /* loop till we find something that ain't of zero length */ + for (i=1; i-1; j--) { + point [0] = contour[j][0]; + point [1] = contour[j][1]; + V3F (point, j, BACK_CAP); + } + } + ENDPOLYGON (); +#endif /* GL_32 */ + +#ifdef OPENGL_10 + /* malloc the @#$%^&* array that OpenGL wants ! */ + pts = (double *) malloc (3*ncp*sizeof(double)); + tobj = gluNewTess (); + gluTessCallback (tobj, GLU_BEGIN, glBegin); + gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); + gluTessCallback (tobj, GLU_END, glEnd); + gluBeginPolygon (tobj); + + /* draw the loop counter clockwise for the front cap */ + if (frontwards) { + for (j=1; j-1; j--) { + pts [3*j] = contour[j][0]; + pts [3*j+1] = contour[j][1]; + pts [3*j+2] = zval; + gluTessVertex (tobj, &pts[3*j], &pts[3*j]); + } + } + + gluEndPolygon (tobj); + free (pts); + gluDeleteTess (tobj); +#endif /* OPENGL_10 */ +} + + +/* ============================================================ */ +/* This routine does what it says: It draws a counter-clockwise cap + * from a 3D contour loop list + */ + +void draw_front_contour_cap (int ncp, /* number of contour points */ + gleDouble contour[][3]) /* 3D contour */ +{ + int j; +#ifdef OPENGL_10 + GLUtriangulatorObj *tobj; +#endif /* OPENGL_10 */ + +#ifdef GL_32 + /* old-style gl handles concave polygons no problem, so the code is + * simple. New-style gl is a lot more tricky. */ + /* draw the end cap */ + BGNPOLYGON (); + + for (j=0; j-1; j--) { + V3F (contour[j], j, BACK_CAP); + } + ENDPOLYGON (); +#endif /* GL_32 */ + +#ifdef OPENGL_10 + tobj = gluNewTess (); + gluTessCallback (tobj, GLU_BEGIN, glBegin); + gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); + gluTessCallback (tobj, GLU_END, glEnd); + gluBeginPolygon (tobj); + + /* draw the end cap */ + /* draw the loop clockwise for the back cap */ + /* the sense of the loop is reversed for backfacing culling */ + for (j=ncp-1; j>-1; j--) { + gluTessVertex (tobj, contour[j], contour[j]); + } + gluEndPolygon (tobj); + gluDeleteTess (tobj); +#endif /* OPENGL_10 */ +} + +/* ============================================================ */ +/* This routine draws a segment of raw-join-style tubing. + * Essentially, we assume that the proper transformations have already + * been performed to properly orient the tube segment -- our only task + * left is to render */ +/* PLAIN - NO COLOR, NO NORMAL */ + +void draw_raw_segment_plain (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble len, + int inext) + +{ + int j; + double point[3]; + + /* draw the tube segment */ + BGNTMESH (inext, len); + for (j=0; j +#include +#include /* for the memcpy() subroutine */ +#include +#include "gutil.h" +#include "vvector.h" +#include "tube_gc.h" +#include "extrude.h" +#include "intersect.h" + +/* ============================================================ */ +/* The routine below determines the type of join style that will be + * used for tubing. */ + +void gleSetJoinStyle (int style) +{ + INIT_GC(); + extrusion_join_style = style; +} + +int gleGetJoinStyle (void) +{ + INIT_GC(); + return (extrusion_join_style); +} + +/* ============================================================ */ +/* + * draw a general purpose extrusion + */ + +void gleSuperExtrusion (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline */ + float color_array[][3], /* color of polyline */ + gleDouble xform_array[][2][3]) /* 2D contour xforms */ +{ + INIT_GC(); + _gle_gc -> ncp = ncp; + _gle_gc -> contour = contour; + _gle_gc -> cont_normal = cont_normal; + _gle_gc -> up = up; + _gle_gc -> npoints = npoints; + _gle_gc -> point_array = point_array; + _gle_gc -> color_array = color_array; + _gle_gc -> xform_array = xform_array; + + switch (__TUBE_STYLE) { + case TUBE_JN_RAW: + (void) extrusion_raw_join (ncp, contour, cont_normal, up, + npoints, + point_array, color_array, + xform_array); + break; + + case TUBE_JN_ANGLE: + (void) extrusion_angle_join (ncp, contour, cont_normal, up, + npoints, + point_array, color_array, + xform_array); + break; + + case TUBE_JN_CUT: + case TUBE_JN_ROUND: + /* This routine used for both cut and round styles */ + (void) extrusion_round_or_cut_join (ncp, contour, cont_normal, up, + npoints, + point_array, color_array, + xform_array); + break; + + default: + break; + } +} + +/* ============================================================ */ + +void gleExtrusion (int ncp, /* number of contour points */ + gleDouble contour[][2], /* 2D contour */ + gleDouble cont_normal[][2], /* 2D contour normals */ + gleDouble up[3], /* up vector for contour */ + int npoints, /* numpoints in poly-line */ + gleDouble point_array[][3], /* polyline */ + float color_array[][3]) /* color of polyline */ +{ + gleSuperExtrusion (ncp, contour, cont_normal, up, + npoints, + point_array, color_array, + NULL); +} + +/* ============================================================ */ + +/* should really make this an adaptive algorithm ... */ +static int __gleSlices = 20; + +int +gleGetNumSlices(void) +{ + return __gleSlices; +} + +void +gleSetNumSlices(int slices) +{ + __gleSlices = slices; +} + +void gen_polycone (int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble radius, + gleDouble xform_array[][2][3]) +{ + int saved_style; + glePoint *circle = (glePoint*) malloc(sizeof(glePoint)*2*__gleSlices); + glePoint *norm = &circle[__gleSlices]; + double c, s; + int i; + double v21[3]; + double len; + gleDouble up[3]; + + INIT_GC(); + + /* this if statement forces this routine into double-duty for + * both the polycone and the polycylinder routines */ + if (xform_array != NULL) radius = 1.0; + + s = sin (2.0*M_PI/ ((double) __gleSlices)); + c = cos (2.0*M_PI/ ((double) __gleSlices)); + + norm [0][0] = 1.0; + norm [0][1] = 0.0; + circle [0][0] = radius; + circle [0][1] = 0.0; + + /* draw a norm using recursion relations */ + for (i=1; i<__gleSlices; i++) { + norm [i][0] = norm[i-1][0] * c - norm[i-1][1] * s; + norm [i][1] = norm[i-1][0] * s + norm[i-1][1] * c; + circle [i][0] = radius * norm[i][0]; + circle [i][1] = radius * norm[i][1]; + } + + /* avoid degenerate vectors */ + /* first, find a non-zero length segment */ + i=0; + FIND_NON_DEGENERATE_POINT(i,npoints,len,v21,point_array) + if (i == npoints) return; + + /* next, check to see if this segment lies along x-axis */ + if ((v21[0] == 0.0) && (v21[2] == 0.0)) { + up[0] = up[1] = up[2] = 1.0; + } else { + up[0] = up[2] = 0.0; + up[1] = 1.0; + } + + /* save the current join style */ + saved_style = extrusion_join_style; + extrusion_join_style |= TUBE_CONTOUR_CLOSED; + + /* if lighting is not turned on, don't send normals. + * MMODE is a good indicator of whether lighting is active */ + if (!__IS_LIGHTING_ON) { + gleSuperExtrusion (__gleSlices, circle, NULL, up, + npoints, point_array, color_array, + xform_array); + } else { + gleSuperExtrusion (__gleSlices, circle, norm, up, + npoints, point_array, color_array, + xform_array); + } + + /* restore the join style */ + extrusion_join_style = saved_style; + + free(circle); +} + +/* ============================================================ */ + +void glePolyCylinder (int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble radius) +{ + gen_polycone (npoints, point_array, color_array, radius, NULL); +} + +/* ============================================================ */ + +void glePolyCone (int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble radius_array[]) +{ + gleAffine * xforms; + int j; + + /* build 2D affine matrices from radius array */ + xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine)); + for (j=0; jinf) (1+x/N) ** N + * and take N=32. + */ + + /* initialize translation and delta translation */ + deltaTrans[0] = delta * dXformdTheta[0][2]; + deltaTrans[1] = delta * dXformdTheta[1][2]; + trans[0] = startXform[0][2]; + trans[1] = startXform[1][2]; + + /* prepare the tangent matrix */ + delta /= 32.0; + mA[0][0] = 1.0 + delta * dXformdTheta[0][0]; + mA[0][1] = delta * dXformdTheta[0][1]; + mA[1][0] = delta * dXformdTheta[1][0]; + mA[1][1] = 1.0 + delta * dXformdTheta[1][1]; + + /* compute exponential of matrix */ + MATRIX_PRODUCT_2X2 (mB, mA, mA); /* squared */ + MATRIX_PRODUCT_2X2 (mA, mB, mB); /* 4th power */ + MATRIX_PRODUCT_2X2 (mB, mA, mA); /* 8th power */ + MATRIX_PRODUCT_2X2 (mA, mB, mB); /* 16th power */ + MATRIX_PRODUCT_2X2 (mB, mA, mA); /* 32nd power */ + + /* initialize running matrix */ + COPY_MATRIX_2X2 (run, startXform); + + /* remember, the first point is hidden -- load some, any + * xform for the first point */ + xforms[0][0][0] = startXform[0][0]; + xforms[0][0][1] = startXform[0][1]; + xforms[0][0][2] = startXform[0][2]; + xforms[0][1][0] = startXform[1][0]; + xforms[0][1][1] = startXform[1][1]; + xforms[0][1][2] = startXform[1][2]; + + for (i=1; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=gle - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gle.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gle.mak" CFG="gle - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gle - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "gle - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gle - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "gle - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "gle - Win32 Release" +# Name "gle - Win32 Debug" +# Begin Source File + +SOURCE=.\copy.h +# End Source File +# Begin Source File + +SOURCE=.\ex_angle.c +# End Source File +# Begin Source File + +SOURCE=.\ex_cut_round.c +# End Source File +# Begin Source File + +SOURCE=.\ex_raw.c +# End Source File +# Begin Source File + +SOURCE=.\extrude.c +# End Source File +# Begin Source File + +SOURCE=.\extrude.h +# End Source File +# Begin Source File + +SOURCE=.\gutil.h +# End Source File +# Begin Source File + +SOURCE=.\intersect.c +# End Source File +# Begin Source File + +SOURCE=.\intersect.h +# End Source File +# Begin Source File + +SOURCE=.\port.h +# End Source File +# Begin Source File + +SOURCE=.\qmesh.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\rot.h +# End Source File +# Begin Source File + +SOURCE=.\rot_prince.c +# End Source File +# Begin Source File + +SOURCE=.\rotate.c +# End Source File +# Begin Source File + +SOURCE=.\round_cap.c +# End Source File +# Begin Source File + +SOURCE=.\segment.c +# End Source File +# Begin Source File + +SOURCE=.\segment.h +# End Source File +# Begin Source File + +SOURCE=.\texgen.c +# End Source File +# Begin Source File + +SOURCE=.\tube_gc.h +# End Source File +# Begin Source File + +SOURCE=.\urotate.c +# End Source File +# Begin Source File + +SOURCE=.\view.c +# End Source File +# Begin Source File + +SOURCE=.\vvector.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/gle/gle_dll.dsp b/lib/glut-3.7.6/lib/gle/gle_dll.dsp new file mode 100644 index 0000000000..1df5d6a886 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/gle_dll.dsp @@ -0,0 +1,180 @@ +# Microsoft Developer Studio Project File - Name="gle_dll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=gle_dll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gle_dll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gle_dll.mak" CFG="gle_dll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gle_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "gle_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gle_dll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLE_DLL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLE_DLL_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glu32.lib opengl32.lib /nologo /dll /machine:I386 /out:"Release/gle.dll" + +!ELSEIF "$(CFG)" == "gle_dll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLE_DLL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLE_DLL_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glu32.lib opengl32.lib /nologo /dll /debug /machine:I386 /out:"Debug/gle.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gle_dll - Win32 Release" +# Name "gle_dll - Win32 Debug" +# Begin Source File + +SOURCE=.\copy.h +# End Source File +# Begin Source File + +SOURCE=.\ex_angle.c +# End Source File +# Begin Source File + +SOURCE=.\ex_cut_round.c +# End Source File +# Begin Source File + +SOURCE=.\ex_raw.c +# End Source File +# Begin Source File + +SOURCE=.\extrude.c +# End Source File +# Begin Source File + +SOURCE=.\extrude.h +# End Source File +# Begin Source File + +SOURCE=.\gutil.h +# End Source File +# Begin Source File + +SOURCE=.\intersect.c +# End Source File +# Begin Source File + +SOURCE=.\intersect.h +# End Source File +# Begin Source File + +SOURCE=.\port.h +# End Source File +# Begin Source File + +SOURCE=.\qmesh.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\rot.h +# End Source File +# Begin Source File + +SOURCE=.\rot_prince.c +# End Source File +# Begin Source File + +SOURCE=.\rotate.c +# End Source File +# Begin Source File + +SOURCE=.\round_cap.c +# End Source File +# Begin Source File + +SOURCE=.\segment.c +# End Source File +# Begin Source File + +SOURCE=.\segment.h +# End Source File +# Begin Source File + +SOURCE=.\texgen.c +# End Source File +# Begin Source File + +SOURCE=.\tube_gc.h +# End Source File +# Begin Source File + +SOURCE=.\urotate.c +# End Source File +# Begin Source File + +SOURCE=.\view.c +# End Source File +# Begin Source File + +SOURCE=.\vvector.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/gle/gutil.h b/lib/glut-3.7.6/lib/gle/gutil.h new file mode 100644 index 0000000000..23296f694d --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/gutil.h @@ -0,0 +1,91 @@ + +/* + * gutil.h + * + * FUNCTION: + * Provide utilities that allow rotation to occur + * around any axis. + * + * HISTORY: + * created by Linas Vepstas 1990 + * added single & double precision, June 1991, Linas Vepstas + */ + +#ifndef __GUTIL_H__ +#define __GUTIL_H__ + +#define __GUTIL_DOUBLE + +#ifdef __GUTIL_DOUBLE +#define gutDouble double +#else +#define gutDouble float +#endif + + +#ifdef _NO_PROTO /* NO ANSI C PROTOTYPING */ + +/* Rotation Utilities */ +extern void rot_axis_f (); +extern void rot_about_axis_f (); +extern void rot_omega_f (); +extern void urot_axis_f (); +extern void urot_about_axis_f (); +extern void urot_omega_f (); + +/* double-precision versions */ +extern void rot_axis_d (); +extern void rot_about_axis_d (); +extern void rot_omega_d (); +extern void urot_axis_d (); +extern void urot_about_axis_d (); +extern void urot_omega_d (); + +/* viewpoint functions */ +extern void uview_direction_d (); +extern void uview_direction_f (); +extern void uviewpoint_d (); +extern void uviewpoint_f (); + +#else /* _NO_PROTO */ /* ANSI C PROTOTYPING */ + +/* Rotation Utilities */ +extern void rot_axis_f (float omega, float axis[3]); +extern void rot_about_axis_f (float angle, float axis[3]); +extern void rot_omega_f (float axis[3]); +extern void urot_axis_f (float m[4][4], float omega, float axis[3]); +extern void urot_about_axis_f (float m[4][4], float angle, float axis[3]); +extern void urot_omega_f (float m[4][4], float axis[3]); + +/* double-precision versions */ +extern void rot_axis_d (double omega, double axis[3]); +extern void rot_about_axis_d (double angle, double axis[3]); +extern void rot_omega_d (double axis[3]); +extern void urot_axis_d (double m[4][4], double omega, double axis[3]); +extern void urot_about_axis_d (double m[4][4], double angle, double axis[3]); +extern void urot_omega_d (double m[4][4], double axis[3]); + +/* viewpoint functions */ +extern void uview_direction_d (double m[4][4], /* returned */ + double v21[3], /* input */ + double up[3]); /* input */ + +extern void uview_direction_f (float m[4][4], /* returned */ + float v21[3], /* input */ + float up[3]); /* input */ + +extern void uviewpoint_d (double m[4][4], /* returned */ + double v1[3], /* input */ + double v2[3], /* input */ + double up[3]); /* input */ + +extern void uviewpoint_f (float m[4][4], /* returned */ + float v1[3], /* input */ + float v2[3], /* input */ + float up[3]); /* input */ + +#endif /* _NO_PROTO */ + +#endif /* _GUTIL_H__ */ + +/* ------------------- end of file ---------------------- */ diff --git a/lib/glut-3.7.6/lib/gle/intersect.c b/lib/glut-3.7.6/lib/gle/intersect.c new file mode 100644 index 0000000000..e1948ab441 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/intersect.c @@ -0,0 +1,67 @@ +/* + * FUNCTION: + * This file contains a number of utilities useful to 3D graphics in + * general, and to the generation of tubing and extrusions in particular + * + * HISTORY: + * Written by Linas Vepstas, August 1991 + */ + +#include "gutil.h" +#include "intersect.h" + +/* ========================================================== */ +/* + * The macro and subroutine INTERSECT are designed to compute the + * intersection of a line (defined by the points v1 and v2) and a plane + * (defined as plane which is normal to the vector n, and contains the + * point p). Both sect the array "sect", which is the point of + * interesection. + * + * The subroutine returns a value indicating if the specified inputs + * represented a degenerate case. Valid is TRUE if the computed + * intersection is valid, else it is FALSE. + */ + + +/* ========================================================== */ + +void intersect (gleDouble sect[3], /* returned */ + gleDouble p[3], /* input */ + gleDouble n[3], /* input */ + gleDouble v1[3], /* input */ + gleDouble v2[3]) /* input */ +{ + INTERSECT (sect, p, n, v1, v2); +} + +/* ========================================================== */ +/* + * The macro and subroutine BISECTING_PLANE compute a normal vecotr that + * describes the bisecting plane between three points (v1, v2 and v3). + * This bisecting plane has the following properties: + * 1) it contains the point v2 + * 2) the angle it makes with v21 == v2 - v1 is equal to the angle it + * makes with v32 == v3 - v2 + * 3) it is perpendicular to the plane defined by v1, v2, v3. + * + * Having input v1, v2, and v3, it returns a vector n. + * Note that n is NOT normalized (is NOT of unit length). + * + * The subroutine returns a value indicating if the specified inputs + * represented a degenerate case. Valid is TRUE if the computed + * intersection is valid, else it is FALSE. + */ + +int bisecting_plane (gleDouble n[3], /* returned */ + gleDouble v1[3], /* input */ + gleDouble v2[3], /* input */ + gleDouble v3[3]) /* input */ +{ + int valid; + + BISECTING_PLANE (valid, n, v1, v2, v3); + return (valid); +} + +/* ========================================================== */ diff --git a/lib/glut-3.7.6/lib/gle/intersect.h b/lib/glut-3.7.6/lib/gle/intersect.h new file mode 100644 index 0000000000..6cc81dab60 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/intersect.h @@ -0,0 +1,391 @@ +/* + * FUNCTION: + * This file contains a number of utilities useful to 3D graphics in + * general, and to the generation of tubing and extrusions in particular + * + * HISTORY: + * Written by Linas Vepstas, August 1991 + * Updated to correctly handle degenerate cases, Linas, February 1993 + */ + +#include +#include "port.h" +#include "vvector.h" + +#define BACKWARDS_INTERSECT (2) + +/* ========================================================== */ +/* + * the Degenerate_Tolerance token represents the greatest amount by + * which different scales in a graphics environment can differ before + * they should be considered "degenerate". That is, when one vector is + * a million times longer than another, changces are that the second will + * be less than a pixel long, and therefore was probably meant to be + * degenerate (by the CAD package, etc.) But what should this tolerance + * be? At least 1 in onethousand (since screen sizes are 1K pixels), but + * les than 1 in 4 million (since this is the limit of single-precision + * floating point accuracy). Of course, if double precision were used, + * then the tolerance could be increased. + * + * Potentially, this naive assumption could cause problems if the CAD + * package attempts to zoom in on small details, and turns out, certain + * points should not hvae been degenerate. The problem presented here + * is that the tolerance could run out before single-precision ran + * out, and so the CAD packages would perceive this as a "bug". + * One alternative is to fiddle around & try to tighten the tolerance. + * However, the right alternative is to code the graphics pipeline in + * double-precision (and tighten the tolerance). + * + * By the way, note that Degernate Tolerance is a "dimensionless" + * quantitiy -- it has no units -- it does not measure feet, inches, + * millimeters or pixels. It is used only in the computations of ratios + * and relative lengths. + */ + +/* + * Right now, the tolerance is set to 2 parts in a million, which + * corresponds to a 19-bit distinction of mantissas. Note that + * single-precsion numbers have 24 bit mantissas. + */ + +#define DEGENERATE_TOLERANCE (0.000002) + +/* ========================================================== */ +/* + * The macro and subroutine INTERSECT are designed to compute the + * intersection of a line (defined by the points v1 and v2) and a plane + * (defined as plane which is normal to the vector n, and contains the + * point p). Both return the point sect, which is the point of + * interesection. + * + * This MACRO attemps to be fairly robust by checking for a divide by + * zero. + */ + +/* ========================================================== */ +/* + * HACK ALERT + * The intersection parameter t has the nice property that if t>1, + * then the intersection is "in front of" p1, and if t<0, then the + * intersection is "behind" p2. Unfortunately, as the intersecting plane + * and the line become parallel, t wraps through infinity -- i.e. t can + * become so large that t becomes "greater than infinity" and comes back + * as a negative number (i.e. winding number hopped by one unit). We + * have no way of detecting this situation without adding gazzillions + * of lines of code of topological algebra to detect the winding number; + * and this would be incredibly difficult, and ruin performance. + * + * Thus, we've installed a cheap hack for use by the "cut style" drawing + * routines. If t proves to be a large negative number (more negative + * than -5), then we assume that t was positive and wound through + * infinity. This makes most cuts look good, without introducing bogus + * cuts at infinity. + */ +/* ========================================================== */ + +#define INTERSECT(sect,p,n,v1,v2) \ +{ \ + gleDouble deno, numer, t, omt; \ + \ + deno = (v1[0] - v2[0]) * n[0]; \ + deno += (v1[1] - v2[1]) * n[1]; \ + deno += (v1[2] - v2[2]) * n[2]; \ + \ + if (deno == 0.0) { \ + VEC_COPY (n, v1); \ + /* printf ("Intersect: Warning: line is coplanar with plane \n"); */ \ + } else { \ + \ + numer = (p[0] - v2[0]) * n[0]; \ + numer += (p[1] - v2[1]) * n[1]; \ + numer += (p[2] - v2[2]) * n[2]; \ + \ + t = numer / deno; \ + omt = 1.0 - t; \ + \ + sect[0] = t * v1[0] + omt * v2[0]; \ + sect[1] = t * v1[1] + omt * v2[1]; \ + sect[2] = t * v1[2] + omt * v2[2]; \ + } \ +} + +/* ========================================================== */ +/* + * The macro and subroutine BISECTING_PLANE compute a normal vector that + * describes the bisecting plane between three points (v1, v2 and v3). + * This bisecting plane has the following properties: + * 1) it contains the point v2 + * 2) the angle it makes with v21 == v2 - v1 is equal to the angle it + * makes with v32 == v3 - v2 + * 3) it is perpendicular to the plane defined by v1, v2, v3. + * + * Having input v1, v2, and v3, it returns a unit vector n. + * + * In some cases, the user may specify degenerate points, and still + * expect "reasonable" or "obvious" behaviour. The "expected" + * behaviour for these degenerate cases is: + * + * 1) if v1 == v2 == v3, then return n=0 + * 2) if v1 == v2, then return v32 (normalized). + * 3) if v2 == v3, then return v21 (normalized). + * 4) if v1, v2 and v3 co-linear, then return v21 (normalized). + * + * Mathematically, these special cases "make sense" -- we just have to + * code around potential divide-by-zero's in the code below. + */ + +/* ========================================================== */ + +#define BISECTING_PLANE(valid,n,v1,v2,v3) \ +{ \ + double v21[3], v32[3]; \ + double len21, len32; \ + double dot; \ + \ + VEC_DIFF (v21, v2, v1); \ + VEC_DIFF (v32, v3, v2); \ + \ + VEC_LENGTH (len21, v21); \ + VEC_LENGTH (len32, v32); \ + \ + if (len21 <= DEGENERATE_TOLERANCE * len32) { \ + \ + if (len32 == 0.0) { \ + /* all three points lie ontop of one-another */ \ + VEC_ZERO (n); \ + valid = FALSE; \ + } else { \ + /* return a normalized copy of v32 as bisector */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (n, len32, v32); \ + valid = TRUE; \ + } \ + \ + } else { \ + \ + valid = TRUE; \ + \ + if (len32 <= DEGENERATE_TOLERANCE * len21) { \ + /* return a normalized copy of v21 as bisector */ \ + len21 = 1.0 / len21; \ + VEC_SCALE (n, len21, v21); \ + \ + } else { \ + \ + /* normalize v21 to be of unit length */ \ + len21 = 1.0 / len21; \ + VEC_SCALE (v21, len21, v21); \ + \ + /* normalize v32 to be of unit length */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (v32, len32, v32); \ + \ + VEC_DOT_PRODUCT (dot, v32, v21); \ + \ + /* if dot == 1 or -1, then points are colinear */ \ + if ((dot >= (1.0-DEGENERATE_TOLERANCE)) || \ + (dot <= (-1.0+DEGENERATE_TOLERANCE))) { \ + VEC_COPY (n, v21); \ + } else { \ + \ + /* go do the full computation */ \ + n[0] = dot * (v32[0] + v21[0]) - v32[0] - v21[0]; \ + n[1] = dot * (v32[1] + v21[1]) - v32[1] - v21[1]; \ + n[2] = dot * (v32[2] + v21[2]) - v32[2] - v21[2]; \ + \ + /* if above if-test's passed, \ + * n should NEVER be of zero length */ \ + VEC_NORMALIZE (n); \ + } \ + } \ + } \ +} + +/* ========================================================== */ +/* + * The block of code below is ifdef'd out, and is here for reference + * purposes only. It performs the "mathematically right thing" for + * computing a bisecting plane, but is, unfortunately, subject ot noise + * in the presence of near degenerate points. Since computer graphics, + * due to sloppy coding, laziness, or correctness, is filled with + * degenerate points, we can't really use this version. The code above + * is far more appropriate for graphics. + */ + +#ifdef MATHEMATICALLY_EXACT_GRAPHICALLY_A_KILLER +#define BISECTING_PLANE(n,v1,v2,v3) \ +{ \ + double v21[3], v32[3]; \ + double len21, len32; \ + double dot; \ + \ + VEC_DIFF (v21, v2, v1); \ + VEC_DIFF (v32, v3, v2); \ + \ + VEC_LENGTH (len21, v21); \ + VEC_LENGTH (len32, v32); \ + \ + if (len21 == 0.0) { \ + \ + if (len32 == 0.0) { \ + /* all three points lie ontop of one-another */ \ + VEC_ZERO (n); \ + valid = FALSE; \ + } else { \ + /* return a normalized copy of v32 as bisector */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (n, len32, v32); \ + } \ + \ + } else { \ + \ + /* normalize v21 to be of unit length */ \ + len21 = 1.0 / len21; \ + VEC_SCALE (v21, len21, v21); \ + \ + if (len32 == 0.0) { \ + /* return a normalized copy of v21 as bisector */ \ + VEC_COPY (n, v21); \ + } else { \ + \ + /* normalize v32 to be of unit length */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (v32, len32, v32); \ + \ + VEC_DOT_PRODUCT (dot, v32, v21); \ + \ + /* if dot == 1 or -1, then points are colinear */ \ + if ((dot == 1.0) || (dot == -1.0)) { \ + VEC_COPY (n, v21); \ + } else { \ + \ + /* go do the full computation */ \ + n[0] = dot * (v32[0] + v21[0]) - v32[0] - v21[0]; \ + n[1] = dot * (v32[1] + v21[1]) - v32[1] - v21[1]; \ + n[2] = dot * (v32[2] + v21[2]) - v32[2] - v21[2]; \ + \ + /* if above if-test's passed, \ + * n should NEVER be of zero length */ \ + VEC_NORMALIZE (n); \ + } \ + } \ + } \ +} +#endif + +/* ========================================================== */ +/* + * This macro computes the plane perpendicular to the the plane + * defined by three points, and whose normal vector is givven as the + * difference between the two vectors ... + * + * (See way below for the "math" model if you want to understand this. + * The comments about relative errors above apply here.) + */ + +#define CUTTING_PLANE(valid,n,v1,v2,v3) \ +{ \ + double v21[3], v32[3]; \ + double len21, len32; \ + double lendiff; \ + \ + VEC_DIFF (v21, v2, v1); \ + VEC_DIFF (v32, v3, v2); \ + \ + VEC_LENGTH (len21, v21); \ + VEC_LENGTH (len32, v32); \ + \ + if (len21 <= DEGENERATE_TOLERANCE * len32) { \ + \ + if (len32 == 0.0) { \ + /* all three points lie ontop of one-another */ \ + VEC_ZERO (n); \ + valid = FALSE; \ + } else { \ + /* return a normalized copy of v32 as cut-vector */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (n, len32, v32); \ + valid = TRUE; \ + } \ + \ + } else { \ + \ + valid = TRUE; \ + \ + if (len32 <= DEGENERATE_TOLERANCE * len21) { \ + /* return a normalized copy of v21 as cut vector */ \ + len21 = 1.0 / len21; \ + VEC_SCALE (n, len21, v21); \ + } else { \ + \ + /* normalize v21 to be of unit length */ \ + len21 = 1.0 / len21; \ + VEC_SCALE (v21, len21, v21); \ + \ + /* normalize v32 to be of unit length */ \ + len32 = 1.0 / len32; \ + VEC_SCALE (v32, len32, v32); \ + \ + VEC_DIFF (n, v21, v32); \ + VEC_LENGTH (lendiff, n); \ + \ + /* if the perp vector is very small, then the two \ + * vectors are darn near collinear, and the cut \ + * vector is probably poorly defined. */ \ + if (lendiff < DEGENERATE_TOLERANCE) { \ + VEC_ZERO (n); \ + valid = FALSE; \ + } else { \ + lendiff = 1.0 / lendiff; \ + VEC_SCALE (n, lendiff, n); \ + } \ + } \ + } \ +} + +/* ========================================================== */ + +#ifdef MATHEMATICALLY_EXACT_GRAPHICALLY_A_KILLER +#define CUTTING_PLANE(n,v1,v2,v3) \ +{ \ + double v21[3], v32[3]; \ + \ + VEC_DIFF (v21, v2, v1); \ + VEC_DIFF (v32, v3, v2); \ + \ + VEC_NORMALIZE (v21); \ + VEC_NORMALIZE (v32); \ + \ + VEC_DIFF (n, v21, v32); \ + VEC_NORMALIZE (n); \ +} +#endif + + +/* ============================================================ */ +/* This macro is used in several places to cycle through a series of + * points to find the next non-degenerate point in a series */ + +#define FIND_NON_DEGENERATE_POINT(inext,npoints,len,diff,point_array) \ +{ \ + gleDouble slen; \ + gleDouble summa[3]; \ + \ + do { \ + /* get distance to next point */ \ + VEC_DIFF (diff, point_array[inext+1], point_array[inext]); \ + VEC_LENGTH (len, diff); \ + VEC_SUM (summa, point_array[inext+1], point_array[inext]); \ + VEC_LENGTH (slen, summa); \ + slen *= DEGENERATE_TOLERANCE; \ + inext ++; \ + } while ((len <= slen) && (inext < npoints-1)); \ +} + +/* ========================================================== */ + +extern int bisecting_plane (gleDouble n[3], /* returned */ + gleDouble v1[3], /* input */ + gleDouble v2[3], /* input */ + gleDouble v3[3]); /* input */ + diff --git a/lib/glut-3.7.6/lib/gle/port.h b/lib/glut-3.7.6/lib/gle/port.h new file mode 100644 index 0000000000..d9e6c83907 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/port.h @@ -0,0 +1,296 @@ + +/* + * port.h + * + * FUNCTION: + * This file contains defines for porting the tubing toolkit from GL to + * OpenGL to some callback scheme. + * + * HISTORY: + * Created by Linas Vepstas -- February 1993 + * Added auto texture coord generation hacks, Linas April 1994 + */ + +#ifndef __GLE_PORT_H__ +#define __GLE_PORT_H__ + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* ====================================================== */ +/* Some compilers can't handle multiply-subscripted array's */ + +#ifdef FUNKY_C +typedef gleDouble gleVector; +#define AVAL(arr,n,i,j) arr(6*n+3*i+j) +#define VVAL(arr,n,i) arr(3*n+i) + +#else /* FUNKY_C */ +typedef double gleVector[3]; +typedef double glePoint[2]; +#define AVAL(arr,n,i,j) arr[n][i][j] +#define VVAL(arr,n,i) arr[n][i]; + +#endif /* FUNKY_C */ + +/* ====================================================== */ +/* These are used to convey info about topography to the + * texture mapping routines */ + +#define FRONT 1 +#define BACK 2 +#define FRONT_CAP 3 +#define BACK_CAP 4 +#define FILLET 5 + +/* ====================================================== */ + +#define __GLE_DOUBLE + +/* ====================================================== */ + +#ifdef __GLE_DOUBLE +#define gleDouble double +#define urot_axis(a,b,c) urot_axis_d(a,b,c) +#define uview_direction(a,b,c) uview_direction_d(a,b,c) +#define uviewpoint(a,b,c,d) uviewpoint_d(a,b,c,d) +#define MULTMATRIX(m) MULTMATRIX_D(m) +#define LOADMATRIX(m) LOADMATRIX_D(m) +#define V3F(x,j,id) V3F_D(x,j,id) +#define N3F(x) N3F_D(x) +#define T2F(x,y) T2F_D(x,y) +#else +#define gleDouble float +#define urot_axis(a,b,c) urot_axis_f(a,b,c) +#define uview_direction(a,b,c) uview_direction_f(a,b,c) +#define uviewpoint(a,b,c,d) uviewpoint_f(a,b,c,d) +#define MULTMATRIX(m) MULTMATRIX_F(m) +#define LOADMATRIX(m) LOADMATRIX_F(m) +#define V3F(x,j,id) V3F_F(x,j,id) +#define N3F(x) N3F_F(x) +#define T2F(x,y) T2F_F(x,y) +#endif + +/* ====================================================== */ + +#if (defined DEBUG_GL_32 || DEBUG_OPENGL_10) +#undef GL_32 +#undef OPENGL_10 + +#define BGNTMESH(i,len) printf ("bgntmesh() \n"); +#define ENDTMESH() printf ("endtmesh() \n"); +#define BGNPOLYGON() printf ("bgnpolygon() \n"); +#define ENDPOLYGON() printf ("endpolygon() \n"); +#define V3F_F(x,j,id) printf ("v3f(x) %f %f %f \n", x[0], x[1], x[2]); +#define V3F_D(x,j,id) printf ("v3d(x) %f %f %f \n", x[0], x[1], x[2]); +#define N3F_F(x) printf ("n3f(x) %f %f %f \n", x[0], x[1], x[2]); +#define N3F_D(x) printf ("n3d(x) %f %f %f \n", x[0], x[1], x[2]); +#define C3F(x) printf ("c3f(x) %f %f %f \n", x[0], x[1], x[2]); + +#define POPMATRIX() printf ("popmatrix () \n"); +#define PUSHMATRIX() printf ("pushmatrix() \n"); +#define MULTMATRIX_F(x) MULTMATRIX_D(x) +#define LOADMATRIX_F(x) LOADMATRIX_D(x) + + +#define LOADMATRIX_D(x) { \ + int i, j; \ + printf ("loadmatrix (x) \n"); \ + for (i=0; i<4; i++) { \ + for (j=0; j<4; j++) { \ + printf ( "%f ", x[i][j]); \ + } \ + printf (" \n"); \ + } \ +} + +#define MULTMATRIX_D(x) { \ + int i, j; \ + printf ("multmatrix (x) \n"); \ + for (i=0; i<4; i++) { \ + for (j=0; j<4; j++) { \ + printf ( "%f ", x[i][j]); \ + } \ + printf (" \n"); \ + } \ +} + +#define __IS_LIGHTING_ON (1) + +#endif + +/* ====================================================== */ + +#ifdef GL_32 + +#include + +#define BGNTMESH(i,len) bgntmesh() +#define ENDTMESH() endtmesh() +#define BGNPOLYGON() bgnpolygon() +#define ENDPOLYGON() endpolygon() +#define V3F_F(x,j,id) v3f(x) +#define V3F_D(x,j,id) v3d(x) +#define N3F_F(x) n3f(x) +#define T2F_F(x,y) +#define T2F_D(x,y) +#define C3F(x) c3f(x) + +#define POPMATRIX() popmatrix () +#define PUSHMATRIX() pushmatrix() +#define MULTMATRIX_F(x) multmatrix (x) +#define LOADMATRIX_F(x) loadmatrix (x) + +#define N3F_D(x) { \ + float nnn[3]; \ + nnn[0] = (float) x[0]; \ + nnn[1] = (float) x[1]; \ + nnn[2] = (float) x[2]; \ + n3f (nnn); \ +} + +#define LOADMATRIX_D(x) { \ + int i, j; \ + float mmm[4][4]; \ + for (i=0; i<4; i++) { \ + for (j=0; j<4; j++) { \ + mmm[i][j] = (float) x[i][j]; \ + } \ + } \ + loadmatrix(mmm); \ +} + +#define MULTMATRIX_D(x) { \ + int i, j; \ + float mmm[4][4]; \ + for (i=0; i<4; i++) { \ + for (j=0; j<4; j++) { \ + mmm[i][j] = (float) x[i][j]; \ + } \ + } \ + multmatrix(mmm); \ +} + +/* #define __IS_LIGHTING_ON (MSINGLE == getmmode()) */ +#define __IS_LIGHTING_ON (extrusion_join_style & TUBE_LIGHTING_ON) + +#endif /* GL_32 */ + +/* ====================================================== */ +#ifdef OPENGL_10 + +#if defined(_WIN32) +#include +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#endif +#include +#include + +/* +#define N3F_F(x) { \ + float nnn[3]; \ + nnn[0] = - (float) x[0]; \ + nnn[1] = - (float) x[1]; \ + nnn[2] = - (float) x[2]; \ + glNormal3fv (nnn); \ +} +#define N3F_D(x) { \ + float nnn[3]; \ + nnn[0] = - (float) x[0]; \ + nnn[1] = - (float) x[1]; \ + nnn[2] = - (float) x[2]; \ + glNormal3fv (nnn); \ +} +*/ + +#define C3F(x) glColor3fv(x) +#define T2F_F(x,y) glTexCoord2f(x,y) +#define T2F_D(x,y) glTexCoord2d(x,y) + +#define POPMATRIX() glPopMatrix() +#define PUSHMATRIX() glPushMatrix() + +#define MULTMATRIX_F(x) glMultMatrixf ((const GLfloat *)x) +#define LOADMATRIX_F(x) glLoadMatrixf ((const GLfloat *)x) + +#define MULTMATRIX_D(x) glMultMatrixd ((const GLdouble *)x) +#define LOADMATRIX_D(x) glLoadMatrixd ((const GLdouble *)x) + +#define __IS_LIGHTING_ON (glIsEnabled(GL_LIGHTING)) + +/* ====================================================== */ +#ifdef AUTO_TEXTURE + +#define BGNTMESH(i,len) { \ + if(_gle_gc -> bgn_gen_texture) (*(_gle_gc -> bgn_gen_texture))(i,len);\ + glBegin (GL_TRIANGLE_STRIP); \ +} + +#define BGNPOLYGON() { \ + if(_gle_gc -> bgn_gen_texture) (*(_gle_gc -> bgn_gen_texture))();\ + glBegin (GL_POLYGON); \ +} + +#define N3F_F(x) { \ + if(_gle_gc -> n3f_gen_texture) (*(_gle_gc -> n3f_gen_texture))(x); \ + glNormal3fv(x); \ +} + +#define N3F_D(x) { \ + if(_gle_gc -> n3d_gen_texture) (*(_gle_gc -> n3d_gen_texture))(x); \ + glNormal3dv(x); \ +} + +#define V3F_F(x,j,id) { \ + if(_gle_gc -> v3f_gen_texture) (*(_gle_gc -> v3f_gen_texture))(x,j,id);\ + glVertex3fv(x); \ +} + +#define V3F_D(x,j,id) { \ + if(_gle_gc -> v3d_gen_texture) (*(_gle_gc -> v3d_gen_texture))(x,j,id); \ + glVertex3dv(x); \ +} + +#define ENDTMESH() { \ + if(_gle_gc -> end_gen_texture) (*(_gle_gc -> end_gen_texture))(); \ + glEnd (); \ +} + +#define ENDPOLYGON() { \ + if(_gle_gc -> end_gen_texture) (*(_gle_gc -> end_gen_texture))(); \ + glEnd (); \ +} + +/* ====================================================== */ +#else /* AUTO_TEXTURE */ + +#define BGNTMESH(i,len) glBegin (GL_TRIANGLE_STRIP); +#define BGNPOLYGON() glBegin (GL_POLYGON); + +#define N3F_F(x) glNormal3fv(x) +#define N3F_D(x) glNormal3dv(x) +#define V3F_F(x,j,id) glVertex3fv(x); +#define V3F_D(x,j,id) glVertex3dv(x); + +#define ENDTMESH() glEnd () +#define ENDPOLYGON() glEnd() + +#endif /* AUTO_TEXTURE */ + +#endif /* OPENGL_10 */ + +/* ====================================================== */ + + +#endif /* __GLE_PORT_H__ */ +/* ================== END OF FILE ======================= */ diff --git a/lib/glut-3.7.6/lib/gle/qmesh.c b/lib/glut-3.7.6/lib/gle/qmesh.c new file mode 100644 index 0000000000..c6ea83fb89 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/qmesh.c @@ -0,0 +1,196 @@ + +/* + * This file contains routines to support the SGI compatible quad-mesh + * primitve. + * + * Written By Linas Vepstas November 1991 + */ + +#include + +struct _emu_qmesh_vertex_pair { + float ca[3]; + float na[3]; + float va[4]; + + float cb[3]; + float nb[3]; + float vb[4]; + }; + +#define QMESH 6 +static int bgnmode = 0; + +struct _emu_qmesh { + int num_vert; + struct _emu_qmesh_vertex_pair paira; + struct _emu_qmesh_vertex_pair pairb; + struct _emu_qmesh_vertex_pair *first_pair; + struct _emu_qmesh_vertex_pair *second_pair; + float defer_color[3]; + float defer_normal[3]; +} * _emu_qmesh_GC; + + +#define COPY_THREE_WORDS(A,B) { \ + struct three_words { long a, b, c; }; \ + *(struct three_words *) (A) = *(struct three_words *) (B); \ +} + +#define COPY_FOUR_WORDS(A,B) { \ + struct four_words { long a, b, c, d; }; \ + *(struct four_words *) (A) = *(struct four_words *) (B); \ +} + +/* ================================================================= */ + +void _emu_qmesh_InitGC (struct _emu_qmesh * tmp) +{ + + tmp -> num_vert = 0; + tmp -> first_pair = & (tmp -> paira); + tmp -> second_pair = & (tmp -> pairb); + + tmp -> defer_color[0] = 0.0; + tmp -> defer_color[1] = 0.0; + tmp -> defer_color[2] = 0.0; + + tmp -> defer_normal[0] = 0.0; + tmp -> defer_normal[1] = 0.0; + tmp -> defer_normal[2] = 0.0; + +} + +/* ================================================================= */ + +struct _emu_qmesh * _emu_qmesh_CreateGC (void) +{ + struct _emu_qmesh * tmp; + + tmp = (struct _emu_qmesh *) malloc (sizeof (struct _emu_qmesh)); + _emu_qmesh_InitGC (tmp); + + return (tmp); +} + +/* ================================================================= */ + +void _emu_qmesh_DestroyGC (void) +{ + free (_emu_qmesh_GC); +} + +/* ================================================================= */ + +void _emu_qmesh_bgnqmesh (void) +{ + _emu_qmesh_GC = _emu_qmesh_CreateGC (); + bgnmode = QMESH; +} + +/* ================================================================= */ + +void _emu_qmesh_endqmesh (void) +{ + _emu_qmesh_DestroyGC (); + bgnmode = 0; +} + +/* ================================================================= */ + +void _emu_qmesh_c3f (float c[3]) +{ + if (bgnmode == QMESH) { + COPY_THREE_WORDS (_emu_qmesh_GC -> defer_color, c); + } else { + c3f (c); + } +} + +/* ================================================================= */ + +void _emu_qmesh_n3f (float n[3]) +{ + if (bgnmode == QMESH) { + COPY_THREE_WORDS (_emu_qmesh_GC -> defer_normal, n); + } else { + n3f (n); + } +} + +/* ================================================================= */ + +void _emu_qmesh_v3f (float v[3]) +{ + int nv, even_odd, fs; + struct _emu_qmesh_vertex_pair *tmp; + + if (bgnmode == QMESH) { + nv = _emu_qmesh_GC -> num_vert; + even_odd = nv %2; + fs = (nv %4) / 2; + + if (fs) { + if (even_odd) { + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.cb, + _emu_qmesh_GC -> defer_color); + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.nb, + _emu_qmesh_GC -> defer_normal); + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.vb, v); + _emu_qmesh_GC -> pairb.vb [3] = 1.0; + } else { + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.ca, + _emu_qmesh_GC -> defer_color); + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.na, + _emu_qmesh_GC -> defer_normal); + COPY_THREE_WORDS (_emu_qmesh_GC -> pairb.va, v); + _emu_qmesh_GC -> pairb.va [3] = 1.0; + } + } else { + if (even_odd) { + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.cb, + _emu_qmesh_GC -> defer_color); + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.nb, + _emu_qmesh_GC -> defer_normal); + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.vb, v); + _emu_qmesh_GC -> paira.vb [3] = 1.0; + } else { + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.ca, + _emu_qmesh_GC -> defer_color); + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.na, + _emu_qmesh_GC -> defer_normal); + COPY_THREE_WORDS (_emu_qmesh_GC -> paira.va, v); + _emu_qmesh_GC -> paira.va [3] = 1.0; + } + } + + if (even_odd && (nv >= 3)) { + bgnpolygon (); + c3f ( _emu_qmesh_GC -> first_pair -> ca); + n3f ( _emu_qmesh_GC -> first_pair -> na); + v4f ( _emu_qmesh_GC -> first_pair -> va); + c3f ( _emu_qmesh_GC -> first_pair -> cb); + n3f ( _emu_qmesh_GC -> first_pair -> nb); + v4f ( _emu_qmesh_GC -> first_pair -> vb); + c3f ( _emu_qmesh_GC -> second_pair -> cb); + n3f ( _emu_qmesh_GC -> second_pair -> nb); + v4f ( _emu_qmesh_GC -> second_pair -> vb); + c3f ( _emu_qmesh_GC -> second_pair -> ca); + n3f ( _emu_qmesh_GC -> second_pair -> na); + v4f ( _emu_qmesh_GC -> second_pair -> va); + endpolygon (); + + /* swap the data buffers */ + tmp = _emu_qmesh_GC -> first_pair; + _emu_qmesh_GC -> first_pair = _emu_qmesh_GC -> second_pair; + _emu_qmesh_GC -> second_pair = tmp; + } + + _emu_qmesh_GC -> num_vert ++; + + } else { + v3f (v); + } +} + +/* ================================================================= */ diff --git a/lib/glut-3.7.6/lib/gle/rot.h b/lib/glut-3.7.6/lib/gle/rot.h new file mode 100644 index 0000000000..f7588c1832 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/rot.h @@ -0,0 +1,98 @@ + +/* + * rot.h + * + * FUNCTION: + * rotation matrix utilities + * + * HISTORY: + * Linas Vepstas Aug 1990 + */ + +/* ========================================================== */ +/* + * The MACROS below generate and return more traditional rotation + * matrices -- matrices for rotations about principal axes. + */ +/* ========================================================== */ + +#define ROTX_CS(m,cosine,sine) \ +{ \ + /* rotation about the x-axis */ \ + \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = (cosine); \ + m[1][2] = (sine); \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = -(sine); \ + m[2][2] = (cosine); \ + 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; \ +} + +/* ========================================================== */ + +#define ROTY_CS(m,cosine,sine) \ +{ \ + /* rotation about the y-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = 0.0; \ + m[0][2] = -(sine); \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = (sine); \ + m[2][1] = 0.0; \ + m[2][2] = (cosine); \ + 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; \ +} + +/* ========================================================== */ + +#define ROTZ_CS(m,cosine,sine) \ +{ \ + /* rotation about the z-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = (sine); \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = -(sine); \ + m[1][1] = (cosine); \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + 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; \ +} + +/* ========================================================== */ diff --git a/lib/glut-3.7.6/lib/gle/rot_prince.c b/lib/glut-3.7.6/lib/gle/rot_prince.c new file mode 100644 index 0000000000..69cf042bd6 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/rot_prince.c @@ -0,0 +1,303 @@ + +#include +#include "rot.h" +#include "port.h" + +/* ========================================================== */ +/* + * The routines below generate and return more traditional rotation + * matrices -- matrices for rotations about principal axes. + */ +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void urotx_sc_d (double m[4][4], /* returned */ + double cosine, /* input */ + double sine) /* input */ +#else +void urotx_sc_f (float m[4][4], /* returned */ + float cosine, /* input */ + float sine) /* input */ +#endif +{ + /* create matrix that represents rotation about the x-axis */ + + ROTX_CS (m, cosine, sine); +} + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void rotx_cs_d (double cosine, /* input */ + double sine) /* input */ +{ + /* create and load matrix that represents rotation about the x-axis */ + double m[4][4]; + + (void) urotx_cs_d (m, cosine, sine); + MULTMATRIX_D (m); +} + +#else +void rotx_cs_f (float cosine, /* input */ + float sine) /* input */ +{ + /* create and load matrix that represents rotation about the x-axis */ + float m[4][4]; + + (void) urotx_cs_f (m, cosine, sine); + MULTMATRIX_F (m); +} +#endif +#endif + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void uroty_sc_d (double m[4][4], /* returned */ + double cosine, /* input */ + double sine) /* input */ +#else +void uroty_sc_f (float m[4][4], /* returned */ + float cosine, /* input */ + float sine) /* input */ +#endif +{ + /* create matriy that represents rotation about the y-ayis */ + + ROTX_CS (m, cosine, sine); +} + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void roty_cs_d (double cosine, /* input */ + double sine) /* input */ +{ + /* create and load matriy that represents rotation about the y-ayis */ + double m[4][4]; + + (void) uroty_cs_d (m, cosine, sine); + MULTMATRIX_D (m); +} + +#else +void roty_cs_f (float cosine, /* input */ + float sine) /* input */ +{ + /* create and load matriy that represents rotation about the y-ayis */ + float m[4][4]; + + (void) uroty_cs_f (m, cosine, sine); + MULTMATRIX_F (m); +} +#endif +#endif + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void urotz_sc_d (double m[4][4], /* returned */ + double cosine, /* input */ + double sine) /* input */ +#else +void urotz_sc_f (float m[4][4], /* returned */ + float cosine, /* input */ + float sine) /* input */ +#endif +{ + /* create matriz that represents rotation about the z-azis */ + + ROTX_CS (m, cosine, sine); +} + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void rotz_cs_d (double cosine, /* input */ + double sine) /* input */ +{ + /* create and load matriz that represents rotation about the z-azis */ + double m[4][4]; + + (void) urotz_cs_d (m, cosine, sine); + MULTMATRIX_D (m); +} + +#else +void rotz_cs_f (float cosine, /* input */ + float sine) /* input */ +{ + /* create and load matriz that represents rotation about the z-azis */ + float m[4][4]; + + (void) urotz_cs_f (m, cosine, sine); + MULTMATRIX_F (m); +} +#endif +#endif + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void urot_cs_d (double m[4][4], /* returned */ + double cosine, /* input */ + double sine, /* input */ + char axis) /* input */ +{ + /* create matrix that represents rotation about a principle axis */ + + switch (axis) { + case 'x': + case 'X': + urotx_cs_d (m, cosine, sine); + break; + case 'y': + case 'Y': + uroty_cs_d (m, cosine, sine); + break; + case 'z': + case 'Z': + urotz_cs_d (m, cosine, sine); + break; + default: + break; + } + +} + +#else +void urot_cs_f (float m[4][4], /* returned */ + float cosine, /* input */ + float sine, /* input */ + char axis) /* input */ +{ + /* create matrix that represents rotation about a principle axis */ + + switch (axis) { + case 'x': + case 'X': + urotx_cs_f (m, cosine, sine); + break; + case 'y': + case 'Y': + uroty_cs_f (m, cosine, sine); + break; + case 'z': + case 'Z': + urotz_cs_f (m, cosine, sine); + break; + default: + break; + } + +} +#endif +#endif + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void rot_cs_d (double cosine, /* input */ + double sine, /* input */ + char axis) /* input */ +{ + /* create and load matrix that represents rotation about the z-axis */ + double m[4][4]; + + (void) urot_cs_d (m, cosine, sine, axis); + MULTMATRIX_D (m); +} +#else +void rot_cs_f (float cosine, /* input */ + float sine, /* input */ + char axis) /* input */ +{ + /* create and load matrix that represents rotation about the z-axis */ + float m[4][4]; + + (void) urot_cs_f (m, cosine, sine, axis); + MULTMATRIX_F (m); +} +#endif +#endif + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void urot_prince_d (double m[4][4], /* returned */ + double theta, /* input */ + char axis) /* input */ +{ + /* + * generate rotation matrix for rotation around principal axis; + * note that angle is measured in radians (divide by 180, multiply by + * PI to convert from degrees). + */ + + (void) urot_cs_d (m, + cos (theta), + sin (theta), + axis); +} +#else +void urot_prince_f (float m[4][4], /* returned */ + float theta, /* input */ + char axis) /* input */ +{ + /* + * generate rotation matrix for rotation around principal axis; + * note that angle is measured in radians (divide by 180, multiply by + * PI to convert from degrees). + */ + + (void) urot_cs_f (m, + (float) cos ((double) theta), + (float) sin ((double) theta), + axis); +} +#endif +#endif + +/* ========================================================== */ + +#if 0 +#ifdef __GUTIL_DOUBLE +void rot_prince_d (double theta, /* input */ + char axis) /* input */ +{ + double m[4][4]; + /* + * generate rotation matrix for rotation around principal axis; + * note that angle is measured in radians (divide by 180, multiply by + * PI to convert from degrees). + */ + + (void) urot_prince_d (m, theta, axis); + MULTMATRIX_D (m); +} +#else + +void rot_prince_f (float theta, /* input */ + char axis) /* input */ +{ + float m[4][4]; + /* + * generate rotation matrix for rotation around principal axis; + * note that angle is measured in radians (divide by 180, multiply by + * PI to convert from degrees). + */ + + (void) urot_prince_f (m, theta, axis); + MULTMATRIX_F (m); +} +#endif +#endif + +/* ========================================================== */ diff --git a/lib/glut-3.7.6/lib/gle/rotate.c b/lib/glut-3.7.6/lib/gle/rotate.c new file mode 100644 index 0000000000..028b067ff1 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/rotate.c @@ -0,0 +1,134 @@ +/* + * MODULE NAME: rotate.c + * + * FUNCTION: + * This module contains three different routines that compute rotation + * matricies and load them into GL. + * Detailed description is provided below. + * + * DEPENDENCIES: + * The routines call GL matrix routines. + * + * HISTORY: + * Developed & written, Linas Vepstas, Septmeber 1991 + * Double precision port, March 1993 + * + * DETAILED DESCRIPTION: + * This module contains three routines: + * -------------------------------------------------------------------- + * + * void urot_about_axis (float m[4][4], --- returned + * float angle, --- input + * float axis[3]) --- input + * Computes a rotation matrix. + * The rotation is around the the direction specified by the argument + * argument axis[3]. User may specify vector which is not of unit + * length. The angle of rotation is specified in degrees, and is in the + * right-handed direction. + * + * void rot_about_axis (float angle, --- input + * float axis[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + * + * void urot_axis (float m[4][4], --- returned + * float omega, --- input + * float axis[3]) --- input + * Same as urot_about_axis(), but angle specified in radians. + * It is assumed that the argument axis[3] is a vector of unit length. + * If it is not of unit length, the returned matrix will not be correct. + * + * void rot_axis (float omega, --- input + * float axis[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + * + * void urot_omega (float m[4][4], --- returned + * float omega[3]) --- input + * same as urot_axis(), but the angle is taken as the length of the + * vector omega[3] + * + * void rot_omega (float omega[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + */ + +#include +#include "port.h" +#include "gutil.h" + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void rot_axis_d (double omega, /* input */ + double axis[3]) /* input */ +{ + double m[4][4]; + + (void) urot_axis_d (m, omega, axis); + MULTMATRIX_D (m); + +} +#else + +void rot_axis_f (float omega, /* input */ + float axis[3]) /* input */ +{ + float m[4][4]; + + (void) urot_axis_f (m, omega, axis); + MULTMATRIX_F (m); + +} +#endif + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void rot_about_axis_d (double angle, /* input */ + double axis[3]) /* input */ +{ + double m[4][4]; + + (void) urot_about_axis_d (m, angle, axis); + MULTMATRIX_D (m); +} + +#else +void rot_about_axis_f (float angle, /* input */ + float axis[3]) /* input */ +{ + float m[4][4]; + + (void) urot_about_axis_f (m, angle, axis); + MULTMATRIX_F (m); +} +#endif + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void rot_omega_d (double axis[3]) /* input */ +{ + double m[4][4]; + + (void) urot_omega_d (m, axis); + MULTMATRIX_D(m); +} +#else +void rot_omega_f (float axis[3]) /* input */ +{ + float m[4][4]; + + (void) urot_omega_f (m, axis); + MULTMATRIX_F(m); +} +#endif + +/* ========================================================== */ diff --git a/lib/glut-3.7.6/lib/gle/round_cap.c b/lib/glut-3.7.6/lib/gle/round_cap.c new file mode 100644 index 0000000000..4decd91582 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/round_cap.c @@ -0,0 +1,211 @@ +/* + * MODULE NAME: round_cap.c + * + * FUNCTION: + * This module contains code that draws the round end-cap for round + * join-style tubing. + * + * HISTORY: + * written by Linas Vepstas August/September 1991 + * split into multiple compile units, Linas, October 1991 + * added normal vectors Linas, October 1991 + */ + + +#include +#include +#include +#include /* for the memcpy() subroutine */ +#include +#include "port.h" +#include "gutil.h" +#include "vvector.h" +#include "extrude.h" +#include "tube_gc.h" +#include "intersect.h" +#include "segment.h" + + +/* ============================================================ */ +/* This routine does what it says: It draws the end-caps for the + * "round" join style. + */ + +/* HACK ALERT HACK ALERT HACK ALERT HACK ALERT */ +/* This #define should be replaced by some adaptive thingy. + * the adaptiveness needs to depend on relative angles and diameter of + * extrusion relative to screen size (in pixels). + */ + +#define __ROUND_TESS_PIECES 5 + +void draw_round_style_cap_callback (int ncp, + double cap[][3], + float face_color[3], + gleDouble cut[3], + gleDouble bi[3], + double norms[][3], + int frontwards) +{ + double axis[3]; + double xycut[3]; + double theta; + double *last_contour, *next_contour; + double *last_norm, *next_norm; + double *cap_z; + double *tmp; + char *malloced_area; + int i, j, k; + double m[4][4]; + + if (face_color != NULL) C3F (face_color); + + /* ------------ start setting up rotation matrix ------------- */ + /* if the cut vector is NULL (this should only occur in + * a degenerate case), then we can't draw anything. return. */ + if (cut == NULL) return; + + /* make sure that the cut vector points inwards */ + if (cut[2] > 0.0) { + VEC_SCALE (cut, -1.0, cut); + } + + /* make sure that the bi vector points outwards */ + if (bi[2] < 0.0) { + VEC_SCALE (bi, -1.0, bi); + } + + /* determine the axis we are to rotate about to get bi-contour. + * Note that the axis will always lie in the x-y plane */ + VEC_CROSS_PRODUCT (axis, cut, bi); + + /* reverse the cut vector for the back cap -- + * need to do this to get angle right */ + if (!frontwards) { + VEC_SCALE (cut, -1.0, cut); + } + + /* get angle to rotate by -- arccos of dot product of cut with cut + * projected into the x-y plane */ + xycut [0] = 0.0; + xycut [1] = 0.0; + xycut [2] = 1.0; + VEC_PERP (xycut, cut, xycut); + VEC_NORMALIZE (xycut); + VEC_DOT_PRODUCT (theta, xycut, cut); + + theta = acos (theta); + + /* we'll tesselate round joins into a number of teeny pieces */ + theta /= (double) __ROUND_TESS_PIECES; + + /* get the matrix */ + urot_axis_d (m, theta, axis); + + /* ------------ done setting up rotation matrix ------------- */ + + /* This malloc is a fancy version of: + * last_contour = (double *) malloc (3*ncp*sizeof(double); + * next_contour = (double *) malloc (3*ncp*sizeof(double); + */ + malloced_area = malloc ((4*3+1) *ncp*sizeof (double)); + last_contour = (double *) malloced_area; + next_contour = last_contour + 3*ncp; + cap_z = next_contour + 3*ncp; + last_norm = cap_z + ncp; + next_norm = last_norm + 3*ncp; + + /* make first copy of contour */ + if (frontwards) { + for (j=0; j +#include +#include +#include /* for the memcpy() subroutine */ +#include "GL/tube.h" +#include "port.h" +#include "extrude.h" +#include "tube_gc.h" +#include "segment.h" + + +/* ============================================================ */ + +void draw_segment_plain (int ncp, /* number of contour points */ + gleDouble front_contour[][3], + gleDouble back_contour[][3], + int inext, double len) +{ + int j; + + /* draw the tube segment */ + BGNTMESH (inext, len); + for (j=0; j +#include +#include +#include "port.h" +#include "tube_gc.h" + +/* ======================================================= */ + +gleGC *_gle_gc = 0x0; + +gleGC * gleCreateGC (void) { + gleGC * retval = (gleGC *) malloc (sizeof (gleGC)); + + retval -> bgn_gen_texture = 0x0; + retval -> n3f_gen_texture = 0x0; + retval -> n3d_gen_texture = 0x0; + retval -> v3f_gen_texture = 0x0; + retval -> v3d_gen_texture = 0x0; + retval -> end_gen_texture = 0x0; + + retval -> save_bgn_gen_texture = 0x0; + retval -> save_n3f_gen_texture = 0x0; + retval -> save_n3d_gen_texture = 0x0; + retval -> save_v3f_gen_texture = 0x0; + retval -> save_v3d_gen_texture = 0x0; + retval -> save_end_gen_texture = 0x0; + + retval -> join_style = TUBE_JN_ANGLE | TUBE_JN_CAP | TUBE_NORM_FACET; + retval -> ncp = 0; + retval -> npoints = 0; + + retval -> num_vert = 0; + retval -> segment_number = 0; + retval -> segment_length = 0.0; + retval -> accum_seg_len = 0.0; + retval -> prev_x = 0.0; + retval -> prev_y = 0.0; + + return retval; +} + +/* ======================================================= */ + +#define segment_number (_gle_gc -> segment_number) +#define segment_length (_gle_gc -> segment_length) +#define accum_seg_len (_gle_gc -> accum_seg_len) +#define num_vert (_gle_gc -> num_vert) +#define prev_x (_gle_gc -> prev_x) +#define prev_y (_gle_gc -> prev_y) + +/* ======================================================= */ + +static double save_nx = 0.0; +static double save_ny = 0.0; +static double save_nz = 0.0; + +static void save_normal (double *v) { + save_nx = v[0]; + save_ny = v[1]; + save_nz = v[2]; +} + +/* ======================================================= */ + +static void bgn_sphere_texgen (int inext, double len) { + segment_number = inext - 1; + segment_length = len; + num_vert = 0; +} + +/* ======================================================= */ +/* + * this routine assumes that the vertex passed in has been normalized + * (i.e. is of unit length) + */ +/* ARGSUSED3 */ +static void sphere_texgen (double x, double y, double z, + int jcnt, int which_end) +{ + double theta, phi; + + /* let phi and theta range fro 0 to 1 */ + phi = 0.5 * atan2 (x, y) / M_PI; + phi += 0.5; + + theta = 1.0 - acos (z) / M_PI; + + /* if first vertex, merely record the texture coords */ + if (num_vert == 0) { + prev_x = phi; + prev_y = theta; + num_vert ++; + } else { + + /* if texture coordinates changed radically, wrap them */ + if ((prev_y - theta) > 0.6) { + theta +=1.0; + } else if ((prev_y - theta) < -0.6) { + theta -=1.0; + } /* else no-op */ + prev_y = theta; + + + /* if texture coordinates changed radically, wrap them */ + if ((prev_x - phi) > 0.6) { + phi +=1.0; + } else if ((prev_x - phi) < -0.6) { + phi -=1.0; + } /* else no-op */ + prev_x = phi; + + } + + T2F_D (phi, theta); +} + +/* ======================================================= */ +/* mappers */ + +static void vertex_sphere_texgen_v (double *v, int jcnt, int which_end) { + double x = v[0]; double y = v[1]; double z = v[2]; + double r; + + r = 1.0 / sqrt (x*x + y*y + z*z); + x *= r; + y *= r; + z *= r; + sphere_texgen (x, y, z, jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_sphere_texgen_v (double *v, int jcnt, int which_end) { + sphere_texgen (save_nx, save_ny, save_nz, jcnt, which_end); +} + +static void vertex_sphere_model_v (double *v, int jcnt, int which_end) { + double x = _gle_gc->contour[jcnt][0]; + double y = _gle_gc->contour[jcnt][1]; + double z = v[2]; + double r; + + r = 1.0 / sqrt (x*x + y*y + z*z); + x *= r; + y *= r; + z *= r; + sphere_texgen (x, y, z, jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_sphere_model_v (double *v, int jcnt, int which_end) { + if (!(_gle_gc -> cont_normal)) return; + sphere_texgen (_gle_gc->cont_normal[jcnt][0], + _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); +} + +/* ======================================================= */ + +static void bgn_z_texgen (int inext, double len) { + + /* accumulate the previous length */ + accum_seg_len += segment_length; + + /* save current values */ + segment_number = inext - 1; + segment_length = len; + + /* reset counter on first segment */ + if (1 >= segment_number) accum_seg_len = 0.0; + + num_vert = 0; +} + +/* ======================================================= */ + +/* ARGSUSED2 */ +static void cylinder_texgen (double x, double y, double z, + int jcnt, int which_end) +{ + double phi; + + /* let phi and theta range fro 0 to 1 */ + phi = 0.5 * atan2 (x, y) / M_PI; + phi += 0.5; + + /* if first vertex, merely record the texture coords */ + if (num_vert == 0) { + prev_x = phi; + num_vert ++; + } else { + /* if texture coordinates changed radically, wrap them */ + if ((prev_x - phi) > 0.6) { + phi +=1.0; + } else if ((prev_x - phi) < -0.6) { + phi -=1.0; + } /* else no-op */ + prev_x = phi; + } + + if (FRONT == which_end) { + T2F_D (phi, accum_seg_len); + } + if (BACK == which_end) { + T2F_D (phi, accum_seg_len + segment_length); + } +} + +/* ======================================================= */ +/* mappers */ + +static void vertex_cylinder_texgen_v (double *v, int jcnt, int which_end) { + double x = v[0]; double y = v[1]; double z = v[2]; + double r; + + r = 1.0 / sqrt (x*x + y*y); + x *= r; + y *= r; + cylinder_texgen (x, y, z, jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_cylinder_texgen_v (double *v, int jcnt, int which_end) { + cylinder_texgen (save_nx, save_ny, save_nz, jcnt, which_end); +} + +static void vertex_cylinder_model_v (double *v, int jcnt, int which_end) { + double x = _gle_gc->contour[jcnt][0]; + double y = _gle_gc->contour[jcnt][1]; + double z = v[2]; + double r; + + r = 1.0 / sqrt (x*x + y*y); + x *= r; + y *= r; + cylinder_texgen (x, y, z, jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_cylinder_model_v (double *v, int jcnt, int which_end) { + if (!(_gle_gc -> cont_normal)) return; + cylinder_texgen (_gle_gc->cont_normal[jcnt][0], + _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); +} + +/* ======================================================= */ + +/* ARGSUSED1 */ +static void flat_texgen (double x, double y, double z, + int jcnt, int which_end) +{ + if (FRONT == which_end) { + T2F_D (x, accum_seg_len); + } + if (BACK == which_end) { + T2F_D (x, accum_seg_len + segment_length); + } +} + +/* ======================================================= */ + + +static void vertex_flat_texgen_v (double *v, int jcnt, int which_end) { + flat_texgen (v[0], v[1], v[2], jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_flat_texgen_v (double *v, int jcnt, int which_end) { + flat_texgen (save_nx, save_ny, save_nz, jcnt, which_end); +} + +static void vertex_flat_model_v (double *v, int jcnt, int which_end) { + flat_texgen (_gle_gc->contour[jcnt][0], + _gle_gc->contour[jcnt][1], v[2], jcnt, which_end); +} + +/* ARGSUSED */ +static void normal_flat_model_v (double *v, int jcnt, int which_end) { + if (!(_gle_gc -> cont_normal)) return; + flat_texgen (_gle_gc->cont_normal[jcnt][0], + _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end); +} + +/* ======================================================= */ + +void gleTextureMode (int mode) { + + INIT_GC(); + + /* enable textureing by restoring the mode */ + _gle_gc -> bgn_gen_texture = _gle_gc -> save_bgn_gen_texture; + _gle_gc -> n3f_gen_texture = _gle_gc -> save_n3f_gen_texture; + _gle_gc -> n3d_gen_texture = _gle_gc -> save_n3d_gen_texture; + _gle_gc -> v3f_gen_texture = _gle_gc -> save_v3f_gen_texture; + _gle_gc -> v3d_gen_texture = _gle_gc -> save_v3d_gen_texture; + _gle_gc -> end_gen_texture = _gle_gc -> save_end_gen_texture; + + switch (mode&GLE_TEXTURE_STYLE_MASK) { + + case GLE_TEXTURE_VERTEX_FLAT: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = vertex_flat_texgen_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_FLAT: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = normal_flat_texgen_v; + _gle_gc -> n3d_gen_texture = save_normal; + break; + + case GLE_TEXTURE_VERTEX_MODEL_FLAT: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = vertex_flat_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_MODEL_FLAT: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = normal_flat_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_VERTEX_CYL: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = vertex_cylinder_texgen_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_CYL: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = normal_cylinder_texgen_v; + _gle_gc -> n3d_gen_texture = save_normal; + break; + + case GLE_TEXTURE_VERTEX_MODEL_CYL: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = vertex_cylinder_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_MODEL_CYL: + _gle_gc -> bgn_gen_texture = bgn_z_texgen; + _gle_gc -> v3d_gen_texture = normal_cylinder_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_VERTEX_SPH: + _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; + _gle_gc -> v3d_gen_texture = vertex_sphere_texgen_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_SPH: + _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; + _gle_gc -> v3d_gen_texture = normal_sphere_texgen_v; + _gle_gc -> n3d_gen_texture = save_normal; + break; + + case GLE_TEXTURE_VERTEX_MODEL_SPH: + _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; + _gle_gc -> v3d_gen_texture = vertex_sphere_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + case GLE_TEXTURE_NORMAL_MODEL_SPH: + _gle_gc -> bgn_gen_texture = bgn_sphere_texgen; + _gle_gc -> v3d_gen_texture = normal_sphere_model_v; + _gle_gc -> n3d_gen_texture = 0x0; + break; + + default: + break; + } + + /* disable texturing, and save the mode */ + if (!(mode & GLE_TEXTURE_ENABLE)) { + _gle_gc -> save_bgn_gen_texture = _gle_gc -> bgn_gen_texture; + _gle_gc -> save_n3f_gen_texture = _gle_gc -> n3f_gen_texture; + _gle_gc -> save_n3d_gen_texture = _gle_gc -> n3d_gen_texture; + _gle_gc -> save_v3f_gen_texture = _gle_gc -> v3f_gen_texture; + _gle_gc -> save_v3d_gen_texture = _gle_gc -> v3d_gen_texture; + _gle_gc -> save_end_gen_texture = _gle_gc -> end_gen_texture; + + _gle_gc -> bgn_gen_texture = 0x0; + _gle_gc -> n3f_gen_texture = 0x0; + _gle_gc -> n3d_gen_texture = 0x0; + _gle_gc -> v3f_gen_texture = 0x0; + _gle_gc -> v3d_gen_texture = 0x0; + _gle_gc -> end_gen_texture = 0x0; + } +} + +/* ================== END OF FILE ========================= */ diff --git a/lib/glut-3.7.6/lib/gle/tube_gc.h b/lib/glut-3.7.6/lib/gle/tube_gc.h new file mode 100644 index 0000000000..a9fe3107f7 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/tube_gc.h @@ -0,0 +1,73 @@ +/* + * tube_gc.h + * + * FUNCTION: + * This file allows for easy changes to changes in the way the extrusion + * library handles state info (i.e. context). + * + * HISTORY: + * Linas Vepstas --- February 1993 + * Added auto texture coord generation hacks, Linas April 1994 + */ + +typedef float gleColor[3]; +typedef double gleTwoVec[2]; + +typedef struct { + + /* public methods */ + void (*bgn_gen_texture) (int, double); + void (*n3f_gen_texture) (float *); + void (*n3d_gen_texture) (double *); + void (*v3f_gen_texture) (float *, int, int); + void (*v3d_gen_texture) (double *, int, int); + void (*end_gen_texture) (void); + + /* protected members -- "general knowledge" stuff */ + int join_style; + + /* arguments passed into extrusion code */ + int ncp; /* number of contour points */ + gleTwoVec *contour; /* 2D contour */ + gleTwoVec *cont_normal; /* 2D contour normals */ + gleDouble *up; /* up vector */ + int npoints; /* number of points in polyline */ + gleVector *point_array; /* path */ + gleColor *color_array; /* path colors */ + gleAffine *xform_array; /* contour xforms */ + + /* private members, used by texturing code */ + int num_vert; + int segment_number; + double segment_length; + double accum_seg_len; + double prev_x; + double prev_y; + + void (*save_bgn_gen_texture) (int, double); + void (*save_n3f_gen_texture) (float *); + void (*save_n3d_gen_texture) (double *); + void (*save_v3f_gen_texture) (float *, int, int); + void (*save_v3d_gen_texture) (double *, int, int); + void (*save_end_gen_texture) (void); + +} gleGC; + +extern gleGC *_gle_gc; +extern gleGC * gleCreateGC (void); + +#define INIT_GC() {if (!_gle_gc) _gle_gc = gleCreateGC(); } +#define extrusion_join_style (_gle_gc->join_style) + +#define __TUBE_CLOSE_CONTOUR (extrusion_join_style & TUBE_CONTOUR_CLOSED) +#define __TUBE_DRAW_CAP (extrusion_join_style & TUBE_JN_CAP) +#define __TUBE_DRAW_FACET_NORMALS (extrusion_join_style & TUBE_NORM_FACET) +#define __TUBE_DRAW_PATH_EDGE_NORMALS (extrusion_join_style & TUBE_NORM_PATH_EDGE) + +#define __TUBE_STYLE (extrusion_join_style & TUBE_JN_MASK) +#define __TUBE_RAW_JOIN (extrusion_join_style & TUBE_JN_RAW) +#define __TUBE_CUT_JOIN (extrusion_join_style & TUBE_JN_CUT) +#define __TUBE_ANGLE_JOIN (extrusion_join_style & TUBE_JN_ANGLE) +#define __TUBE_ROUND_JOIN (extrusion_join_style & TUBE_JN_ROUND) + +/* ======================= END OF FILE ========================== */ diff --git a/lib/glut-3.7.6/lib/gle/urotate.c b/lib/glut-3.7.6/lib/gle/urotate.c new file mode 100644 index 0000000000..5ce9d9f058 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/urotate.c @@ -0,0 +1,217 @@ + +/* + * MODULE: urotate.c + * + * FUNCTION: + * This module contains three different routines that compute rotation + * matricies and return these to user. + * Detailed description is provided below. + * + * HISTORY: + * Developed & written, Linas Vepstas, Septmeber 1991 + * double precision port, March 1993 + * + * DETAILED DESCRIPTION: + * This module contains three routines: + * -------------------------------------------------------------------- + * + * void urot_about_axis (float m[4][4], --- returned + * float angle, --- input + * float axis[3]) --- input + * Computes a rotation matrix. + * The rotation is around the the direction specified by the argument + * argument axis[3]. User may specify vector which is not of unit + * length. The angle of rotation is specified in degrees, and is in the + * right-handed direction. + * + * void rot_about_axis (float angle, --- input + * float axis[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + * + * void urot_axis (float m[4][4], --- returned + * float omega, --- input + * float axis[3]) --- input + * Same as urot_about_axis(), but angle specified in radians. + * It is assumed that the argument axis[3] is a vector of unit length. + * If it is not of unit length, the returned matrix will not be correct. + * + * void rot_axis (float omega, --- input + * float axis[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + * + * void urot_omega (float m[4][4], --- returned + * float omega[3]) --- input + * same as urot_axis(), but the angle is taken as the length of the + * vector omega[3] + * + * void rot_omega (float omega[3]) --- input + * Same as above routine, except that the matrix is multiplied into the + * GL matrix stack. + * + * -------------------------------------------------------------------- + */ + +#include +#include "gutil.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void urot_axis_d (double m[4][4], /* returned */ + double omega, /* input */ + double axis[3]) /* input */ +#else +void urot_axis_f (float m[4][4], /* returned */ + float omega, /* input */ + float axis[3]) /* input */ +#endif +{ + double s, c, ssq, csq, cts; + double tmp; + + /* + * The formula coded up below can be derived by using the + * homomorphism between SU(2) and O(3), namely, that the + * 3x3 rotation matrix R is given by + * t.R.v = S(-1) t.v S + * where + * t are the Pauli matrices (similar to Quaternions, easier to use) + * v is an arbitrary 3-vector + * and S is a 2x2 hermitian matrix: + * S = exp ( i omega t.axis / 2 ) + * + * (Also, remember that computer graphics uses the transpose of R). + * + * The Pauli matrices are: + * + * tx = (0 1) ty = (0 -i) tz = (1 0) + * (1 0) (i 0) (0 -1) + * + * Note that no error checking is done -- if the axis vector is not + * of unit length, you'll get strange results. + */ + + tmp = (double) omega / 2.0; + s = sin (tmp); + c = cos (tmp); + + ssq = s*s; + csq = c*c; + + m[0][0] = m[1][1] = m[2][2] = csq - ssq; + + ssq *= 2.0; + + /* on-diagonal entries */ + m[0][0] += ssq * axis[0]*axis[0]; + m[1][1] += ssq * axis[1]*axis[1]; + m[2][2] += ssq * axis[2]*axis[2]; + + /* off-diagonal entries */ + m[0][1] = m[1][0] = axis[0] * axis[1] * ssq; + m[1][2] = m[2][1] = axis[1] * axis[2] * ssq; + m[2][0] = m[0][2] = axis[2] * axis[0] * ssq; + + cts = 2.0 * c * s; + + tmp = cts * axis[2]; + m[0][1] += tmp; + m[1][0] -= tmp; + + tmp = cts * axis[0]; + m[1][2] += tmp; + m[2][1] -= tmp; + + tmp = cts * axis[1]; + m[2][0] += tmp; + m[0][2] -= tmp; + + /* homogeneous entries */ + m[0][3] = m[1][3] = m[2][3] = m[3][2] = m[3][1] = m[3][0] = 0.0; + m[3][3] = 1.0; + + +} + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void urot_about_axis_d (double m[4][4], /* returned */ + double angle, /* input */ + double axis[3]) /* input */ +#else +void urot_about_axis_f (float m[4][4], /* returned */ + float angle, /* input */ + float axis[3]) /* input */ +#endif +{ + gutDouble len, ax[3]; + + angle *= M_PI/180.0; /* convert to radians */ + + /* renormalize axis vector, if needed */ + len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; + + /* we can save some machine instructions by normalizing only + * if needed. The compiler should be able to schedule in the + * if test "for free". */ + if (len != 1.0) { + len = (gutDouble) (1.0 / sqrt ((double) len)); + ax[0] = axis[0] * len; + ax[1] = axis[1] * len; + ax[2] = axis[2] * len; +#ifdef __GUTIL_DOUBLE + urot_axis_d (m, angle, ax); +#else + urot_axis_f (m, angle, ax); +#endif + } else { +#ifdef __GUTIL_DOUBLE + urot_axis_d (m, angle, axis); +#else + urot_axis_f (m, angle, axis); +#endif + } +} + +/* ========================================================== */ + +#ifdef __GUTIL_DOUBLE +void urot_omega_d (double m[4][4], /* returned */ + double axis[3]) /* input */ +#else +void urot_omega_f (float m[4][4], /* returned */ + float axis[3]) /* input */ +#endif +{ + gutDouble len, ax[3]; + + /* normalize axis vector */ + len = axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]; + + len = (gutDouble) (1.0 / sqrt ((double) len)); + ax[0] = axis[0] * len; + ax[1] = axis[1] * len; + ax[2] = axis[2] * len; + + /* the amount of rotation is equal to the length, in radians */ +#ifdef __GUTIL_DOUBLE + urot_axis_d (m, len, ax); +#else + urot_axis_f (m, len, ax); +#endif + +} + +/* ======================= END OF FILE ========================== */ diff --git a/lib/glut-3.7.6/lib/gle/view.c b/lib/glut-3.7.6/lib/gle/view.c new file mode 100644 index 0000000000..dcc34799f9 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/view.c @@ -0,0 +1,308 @@ + +/* + * MODULE Name: view.c + * + * FUNCTION: + * This module provides two different routines that compute and return + * viewing matrices. Both routines take a direction and an up vector, + * and return a matrix that transforms the direction to the z-axis, and + * the up-vector to the y-axis. + * + * HISTORY: + * written by Linas Vepstas August 1991 + * Added double precision interface, March 1993, Linas + */ + +#include +#include "rot.h" +#include "gutil.h" +#include "vvector.h" + +/* ============================================================ */ +/* + * The uviewdirection subroutine computes and returns a 4x4 rotation + * matrix that puts the negative z axis along the direction v21 and + * puts the y axis along the up vector. + * + * Note that this code is fairly tolerant of "weird" paramters. + * It normalizes when necessary, it does nothing when vectors are of + * zero length, or are co-linear. This code shouldn't croak, no matter + * what the user sends in as arguments. + */ +#ifdef __GUTIL_DOUBLE +void uview_direction_d (double m[4][4], /* returned */ + double v21[3], /* input */ + double up[3]) /* input */ +#else +void uview_direction_f (float m[4][4], /* returned */ + float v21[3], /* input */ + float up[3]) /* input */ +#endif +{ + double amat[4][4]; + double bmat[4][4]; + double cmat[4][4]; + double v_hat_21[3]; + double v_xy[3]; + double sine, cosine; + double len; + double up_proj[3]; + double tmp[3]; + + /* find the unit vector that points in the v21 direction */ + VEC_COPY (v_hat_21, v21); + VEC_LENGTH (len, v_hat_21); + if (len != 0.0) { + len = 1.0 / len; + VEC_SCALE (v_hat_21, len, v_hat_21); + + /* rotate z in the xz-plane until same latitude */ + sine = sqrt ( 1.0 - v_hat_21[2] * v_hat_21[2]); + ROTY_CS (amat, (-v_hat_21[2]), (-sine)); + + } else { + + /* error condition: zero length vecotr passed in -- do nothing */ + IDENTIFY_MATRIX_4X4 (amat); + } + + + /* project v21 onto the xy plane */ + v_xy[0] = v21[0]; + v_xy[1] = v21[1]; + v_xy[2] = 0.0; + VEC_LENGTH (len, v_xy); + + /* rotate in the x-y plane until v21 lies on z axis --- + * but of course, if its already there, do nothing */ + if (len != 0.0) { + + /* want xy projection to be unit vector, so that sines/cosines pop out */ + len = 1.0 / len; + VEC_SCALE (v_xy, len, v_xy); + + /* rotate the projection of v21 in the xy-plane over to the x axis */ + ROTZ_CS (bmat, v_xy[0], v_xy[1]); + + /* concatenate these together */ + MATRIX_PRODUCT_4X4 (cmat, amat, bmat); + + } else { + + /* no-op -- vector is already in correct position */ + COPY_MATRIX_4X4 (cmat, amat); + } + + /* up vector really should be perpendicular to the x-form direction -- + * Use up a couple of cycles, and make sure it is, + * just in case the user blew it. + */ + VEC_PERP (up_proj, up, v_hat_21); + VEC_LENGTH (len, up_proj); + if (len != 0.0) { + + /* normalize the vector */ + len = 1.0/len; + VEC_SCALE (up_proj, len, up_proj); + + /* compare the up-vector to the y-axis to get the cosine of the angle */ + tmp [0] = cmat [1][0]; + tmp [1] = cmat [1][1]; + tmp [2] = cmat [1][2]; + VEC_DOT_PRODUCT (cosine, tmp, up_proj); + + /* compare the up-vector to the x-axis to get the sine of the angle */ + tmp [0] = cmat [0][0]; + tmp [1] = cmat [0][1]; + tmp [2] = cmat [0][2]; + VEC_DOT_PRODUCT (sine, tmp, up_proj); + + /* rotate to align the up vector with the y-axis */ + ROTZ_CS (amat, cosine, -sine); + + /* This xform, although computed last, acts first */ + MATRIX_PRODUCT_4X4 (m, amat, cmat); + + } else { + + /* error condition: up vector is indeterminate (zero length) + * -- do nothing */ + COPY_MATRIX_4X4 (m, cmat); + } +} + +/* ============================================================ */ +#ifdef __STALE_CODE +/* + * The uview_dire subroutine computes and returns a 4x4 rotation + * matrix that puts the negative z axis along the direction v21 and + * puts the y axis along the up vector. + * + * It computes exactly the same matrix as the code above + * (uview_direction), but with an entirely different (and slower) + * algorithm. + * + * Note that the code below is slightly less robust than that above -- + * it may croak if the supplied vectors are of zero length, or are + * parallel to each other ... + */ +void uview_dire (float m[4][4], /* returned */ + float v21[3], /* input */ + float up[3]) /* input */ +{ + double theta; + float v_hat_21 [3]; + float z_hat [3]; + float v_cross_z [3]; + float u[3]; + float y_hat [3]; + float u_cross_y [3]; + double cosine; + float zmat [4][4]; + float upmat[4][4]; + float dot; + + /* perform rotation to z-axis only if not already + * pointing down z */ + if ((v21[0] != 0.0 ) || (v21[1] != 0.0)) { + + /* find the unit vector that points in the v21 direction */ + VEC_COPY (v_hat_21, v21); + VEC_NORMALIZE (v_hat_21); + + /* cosine theta equals v_hat dot z_hat */ + cosine = - v_hat_21 [2]; + theta = - acos (cosine); + + /* Take cros product with z -- we need this, because we will rotate + * about this axis */ + z_hat[0] = 0.0; + z_hat[1] = 0.0; + z_hat[2] = -1.0; + + VEC_CROSS_PRODUCT (v_cross_z, v_hat_21, z_hat); + VEC_NORMALIZE (v_cross_z); + + /* compute rotation matrix that takes -z axis to the v21 axis */ + urot_axis (zmat, (float) theta, v_cross_z); + + } else { + + IDENTIFY_MATRIX_4X4 (zmat); + if (v21[2] > 0.0) { + /* if its pointing down the positive z-axis, flip it, so that + * we point down negative z-axis. We flip x so that the partiy + * isn't destroyed (looks like a rotation) + */ + zmat[0][0] = -1.0; + zmat[2][2] = -1.0; + } + } + + /* --------------------- */ + /* OK, now compute the part that takes the y-axis to the up vector */ + + VEC_COPY (u, up); + /* the rotation blows up, if the up vector is not perpendicular to + * the v21 vector. Let us make sure that this is so. */ + VEC_PERP (u, u, v_hat_21); + + /* need to run the y axis through above x-form, to see where it went */ + y_hat[0] = zmat [1][0]; + y_hat[1] = zmat [1][1]; + y_hat[2] = zmat [1][2]; + + /* perform rotation to up-axis only if not already + * pointing along y axis */ + VEC_DOT_PRODUCT (dot, y_hat, u); + if ((-1.0 < dot) && (dot < 1.0)) { + + /* make sure that up really is a unit vector */ + VEC_NORMALIZE (u); + /* cosine phi equals y_hat dot up_vec */ + VEC_DOT_PRODUCT (cosine, u, y_hat); + theta = - acos (cosine); + + /* Take cross product with y */ + VEC_CROSS_PRODUCT (u_cross_y, u, y_hat); + VEC_NORMALIZE (u_cross_y); + + /* As a matter of fact, u_cross_y points either in the v21 direction, + * or in the minus v21 direction. In either case, we needed to compute + * it, because the the arccosine function returns values only for + * 0 to 180 degree, not 0 to 360, which is what we need. The + * cross-product helps us make up for this. + */ + /* rotate about the NEW z axis (i.e. v21) by the cosine */ + urot_axis (upmat, (float) theta, u_cross_y); + + } else { + + IDENTIFY_MATRIX_4X4 (upmat); + if (dot == -1.0) { + /* if its pointing along the negative y-axis, flip it, so that + * we point along the positive y-axis. We flip x so that the partiy + * isn't destroyed (looks like a rotation) + */ + upmat[0][0] = -1.0; + upmat[1][1] = -1.0; + } + } + + MATRIX_PRODUCT_4X4 (m, zmat, upmat); + +} +#endif /* __STALE_CODE */ + +/* ============================================================ */ +/* + * The uviewpoint subroutine computes and returns a 4x4 matrix that + * translates the origen to the point v1, puts the negative z axis + * along the direction v21==v2-v1, and puts the y axis along the up + * vector. + */ +#ifdef __GUTIL_DOUBLE +void uviewpoint_d (double m[4][4], /* returned */ + double v1[3], /* input */ + double v2[3], /* input */ + double up[3]) /* input */ +#else +void uviewpoint_f (float m[4][4], /* returned */ + float v1[3], /* input */ + float v2[3], /* input */ + float up[3]) /* input */ +#endif +{ +#ifdef __GUTIL_DOUBLE + double v_hat_21 [3]; + double trans_mat[4][4]; + double rot_mat[4][4]; +#else + float v_hat_21 [3]; + float trans_mat[4][4]; + float rot_mat[4][4]; +#endif + + /* find the vector that points in the v21 direction */ + VEC_DIFF (v_hat_21, v2, v1); + + /* compute rotation matrix that takes -z axis to the v21 axis, + * and y to the up dierction */ +#ifdef __GUTIL_DOUBLE + uview_direction_d (rot_mat, v_hat_21, up); +#else + uview_direction_f (rot_mat, v_hat_21, up); +#endif + + /* build matrix that translates the origin to v1 */ + IDENTIFY_MATRIX_4X4 (trans_mat); + trans_mat[3][0] = v1[0]; + trans_mat[3][1] = v1[1]; + trans_mat[3][2] = v1[2]; + + /* concatenate the matrices together */ + MATRIX_PRODUCT_4X4 (m, rot_mat, trans_mat); + +} + +/* ================== END OF FILE ============================ */ diff --git a/lib/glut-3.7.6/lib/gle/vvector.h b/lib/glut-3.7.6/lib/gle/vvector.h new file mode 100644 index 0000000000..266b36e1a4 --- /dev/null +++ b/lib/glut-3.7.6/lib/gle/vvector.h @@ -0,0 +1,1339 @@ + +/* + * vvector.h + * + * FUNCTION: + * This file contains a number of utilities useful for handling + * 3D vectors + * + * HISTORY: + * Written by Linas Vepstas, August 1991 + * Added 2D code, March 1993 + * Added Outer products, C++ proofed, Linas Vepstas October 1993 + */ + +#ifndef __GUTIL_VECTOR_H__ +#define __GUTIL_VECTOR_H__ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + + +#include +#include "port.h" + +/* ========================================================== */ +/* Zero out a 2D vector */ + +#define VEC_ZERO_2(a) \ +{ \ + (a)[0] = (a)[1] = 0.0; \ +} + +/* ========================================================== */ +/* Zero out a 3D vector */ + +#define VEC_ZERO(a) \ +{ \ + (a)[0] = (a)[1] = (a)[2] = 0.0; \ +} + +/* ========================================================== */ +/* Zero out a 4D vector */ + +#define VEC_ZERO_4(a) \ +{ \ + (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0; \ +} + +/* ========================================================== */ +/* Vector copy */ + +#define VEC_COPY_2(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ +} + +/* ========================================================== */ +/* Copy 3D vector */ + +#define VEC_COPY(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ +} + +/* ========================================================== */ +/* Copy 4D vector */ + +#define VEC_COPY_4(b,a) \ +{ \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ + (b)[3] = (a)[3]; \ +} + +/* ========================================================== */ +/* Vector difference */ + +#define VEC_DIFF_2(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ +} + +/* ========================================================== */ +/* Vector difference */ + +#define VEC_DIFF(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ +} + +/* ========================================================== */ +/* Vector difference */ + +#define VEC_DIFF_4(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ + (v21)[3] = (v2)[3] - (v1)[3]; \ +} + +/* ========================================================== */ +/* Vector sum */ + +#define VEC_SUM_2(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ +} + +/* ========================================================== */ +/* Vector sum */ + +#define VEC_SUM(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ +} + +/* ========================================================== */ +/* Vector sum */ + +#define VEC_SUM_4(v21,v2,v1) \ +{ \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ + (v21)[3] = (v2)[3] + (v1)[3]; \ +} + +/* ========================================================== */ +/* scalar times vector */ + +#define VEC_SCALE_2(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ +} + +/* ========================================================== */ +/* scalar times vector */ + +#define VEC_SCALE(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ + (c)[2] = (a)*(b)[2]; \ +} + +/* ========================================================== */ +/* scalar times vector */ + +#define VEC_SCALE_4(c,a,b) \ +{ \ + (c)[0] = (a)*(b)[0]; \ + (c)[1] = (a)*(b)[1]; \ + (c)[2] = (a)*(b)[2]; \ + (c)[3] = (a)*(b)[3]; \ +} + +/* ========================================================== */ +/* accumulate scaled vector */ + +#define VEC_ACCUM_2(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ +} + +/* ========================================================== */ +/* accumulate scaled vector */ + +#define VEC_ACCUM(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ + (c)[2] += (a)*(b)[2]; \ +} + +/* ========================================================== */ +/* accumulate scaled vector */ + +#define VEC_ACCUM_4(c,a,b) \ +{ \ + (c)[0] += (a)*(b)[0]; \ + (c)[1] += (a)*(b)[1]; \ + (c)[2] += (a)*(b)[2]; \ + (c)[3] += (a)*(b)[3]; \ +} + +/* ========================================================== */ +/* Vector dot product */ + +#define VEC_DOT_PRODUCT_2(c,a,b) \ +{ \ + c = (a)[0]*(b)[0] + (a)[1]*(b)[1]; \ +} + +/* ========================================================== */ +/* Vector dot product */ + +#define VEC_DOT_PRODUCT(c,a,b) \ +{ \ + c = (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]; \ +} + +/* ========================================================== */ +/* Vector dot product */ + +#define VEC_DOT_PRODUCT_4(c,a,b) \ +{ \ + c = (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3] ; \ +} + +/* ========================================================== */ +/* vector impact parameter (squared) */ + +#define VEC_IMPACT_SQ(bsq,direction,position) \ +{ \ + gleDouble len, llel; \ + VEC_DOT_PRODUCT (len, position, position); \ + VEC_DOT_PRODUCT (llel, direction, position); \ + bsq = len - llel*llel; \ +} + +/* ========================================================== */ +/* vector impact parameter */ + +#define VEC_IMPACT(bsq,direction,position) \ +{ \ + VEC_IMPACT_SQ(bsq,direction,position); \ + bsq = sqrt (bsq); \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_LENGTH_2(len,a) \ +{ \ + len = a[0]*a[0] + a[1]*a[1]; \ + len = sqrt (len); \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_LENGTH(len,a) \ +{ \ + len = (a)[0]*(a)[0] + (a)[1]*(a)[1]; \ + len += (a)[2]*(a)[2]; \ + len = sqrt (len); \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_LENGTH_4(len,a) \ +{ \ + len = (a)[0]*(a)[0] + (a)[1]*(a)[1]; \ + len += (a)[2]*(a)[2]; \ + len += (a)[3] * (a)[3]; \ + len = sqrt (len); \ +} + +/* ========================================================== */ +/* distance between two points */ + +#define VEC_DISTANCE(len,va,vb) \ +{ \ + gleDouble tmp[4]; \ + VEC_DIFF (tmp, vb, va); \ + VEC_LENGTH (len, tmp); \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_CONJUGATE_LENGTH(len,a) \ +{ \ + len = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\ + len = sqrt (len); \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_NORMALIZE(a) \ +{ \ + double len; \ + VEC_LENGTH (len,a); \ + if (len != 0.0) { \ + len = 1.0 / len; \ + a[0] *= len; \ + a[1] *= len; \ + a[2] *= len; \ + } \ +} + +/* ========================================================== */ +/* Vector length */ + +#define VEC_RENORMALIZE(a,newlen) \ +{ \ + double len; \ + VEC_LENGTH (len,a); \ + if (len != 0.0) { \ + len = newlen / len; \ + a[0] *= len; \ + a[1] *= len; \ + a[2] *= len; \ + } \ +} + +/* ========================================================== */ +/* 3D Vector cross product yeilding vector */ + +#define VEC_CROSS_PRODUCT(c,a,b) \ +{ \ + c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \ + c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \ + c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \ +} + +/* ========================================================== */ +/* Vector perp -- assumes that n is of unit length + * accepts vector v, subtracts out any component parallel to n */ + +#define VEC_PERP(vp,v,n) \ +{ \ + double dot; \ + \ + VEC_DOT_PRODUCT (dot, v, n); \ + vp[0] = (v)[0] - (dot) * (n)[0]; \ + vp[1] = (v)[1] - (dot) * (n)[1]; \ + vp[2] = (v)[2] - (dot) * (n)[2]; \ +} + +/* ========================================================== */ +/* Vector parallel -- assumes that n is of unit length + * accepts vector v, subtracts out any component perpendicular to n */ + +#define VEC_PARALLEL(vp,v,n) \ +{ \ + double dot; \ + \ + VEC_DOT_PRODUCT (dot, v, n); \ + vp[0] = (dot) * (n)[0]; \ + vp[1] = (dot) * (n)[1]; \ + vp[2] = (dot) * (n)[2]; \ +} + +/* ========================================================== */ +/* Vector reflection -- assumes n is of unit length */ +/* Takes vector v, reflects it against reflector n, and returns vr */ + +#define VEC_REFLECT(vr,v,n) \ +{ \ + double dot; \ + \ + VEC_DOT_PRODUCT (dot, v, n); \ + vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \ + vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \ + vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \ +} + +/* ========================================================== */ +/* Vector blending */ +/* Takes two vectors a, b, blends them together */ + +#define VEC_BLEND(vr,sa,a,sb,b) \ +{ \ + \ + vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \ + vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \ + vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \ +} + +/* ========================================================== */ +/* Vector print */ + +#define VEC_PRINT_2(a) \ +{ \ + double len; \ + VEC_LENGTH_2 (len, a); \ + printf (" a is %f %f length of a is %f \n", a[0], a[1], len); \ +} + +/* ========================================================== */ +/* Vector print */ + +#define VEC_PRINT(a) \ +{ \ + double len; \ + VEC_LENGTH (len, (a)); \ + printf (" a is %f %f %f length of a is %f \n", (a)[0], (a)[1], (a)[2], len); \ +} + +/* ========================================================== */ +/* Vector print */ + +#define VEC_PRINT_4(a) \ +{ \ + double len; \ + VEC_LENGTH_4 (len, (a)); \ + printf (" a is %f %f %f %f length of a is %f \n", \ + (a)[0], (a)[1], (a)[2], (a)[3], len); \ +} + +/* ========================================================== */ +/* print matrix */ + +#define MAT_PRINT_4X4(mmm) { \ + int i,j; \ + printf ("matrix mmm is \n"); \ + if (mmm == NULL) { \ + printf (" Null \n"); \ + } else { \ + for (i=0; i<4; i++) { \ + for (j=0; j<4; j++) { \ + printf ("%f ", mmm[i][j]); \ + } \ + printf (" \n"); \ + } \ + } \ +} + +/* ========================================================== */ +/* print matrix */ + +#define MAT_PRINT_3X3(mmm) { \ + int i,j; \ + printf ("matrix mmm is \n"); \ + if (mmm == NULL) { \ + printf (" Null \n"); \ + } else { \ + for (i=0; i<3; i++) { \ + for (j=0; j<3; j++) { \ + printf ("%f ", mmm[i][j]); \ + } \ + printf (" \n"); \ + } \ + } \ +} + +/* ========================================================== */ +/* print matrix */ + +#define MAT_PRINT_2X3(mmm) { \ + int i,j; \ + printf ("matrix mmm is \n"); \ + if (mmm == NULL) { \ + printf (" Null \n"); \ + } else { \ + for (i=0; i<2; i++) { \ + for (j=0; j<3; j++) { \ + printf ("%f ", mmm[i][j]); \ + } \ + printf (" \n"); \ + } \ + } \ +} + +/* ========================================================== */ +/* initialize matrix */ + +#define IDENTIFY_MATRIX_3X3(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ +} + +/* ========================================================== */ +/* initialize matrix */ + +#define IDENTIFY_MATRIX_4X4(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + 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; \ +} + +/* ========================================================== */ +/* matrix copy */ + +#define COPY_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + \ +} + +/* ========================================================== */ +/* matrix copy */ + +#define COPY_MATRIX_2X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ +} + +/* ========================================================== */ +/* matrix copy */ + +#define COPY_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ +} + +/* ========================================================== */ +/* matrix copy */ + +#define COPY_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + b[0][3] = a[0][3]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + b[1][3] = a[1][3]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[2][3]; \ + \ + b[3][0] = a[3][0]; \ + b[3][1] = a[3][1]; \ + b[3][2] = a[3][2]; \ + b[3][3] = a[3][3]; \ +} + +/* ========================================================== */ +/* matrix transpose */ + +#define TRANSPOSE_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ +} + +/* ========================================================== */ +/* matrix transpose */ + +#define TRANSPOSE_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ +} + +/* ========================================================== */ +/* matrix transpose */ + +#define TRANSPOSE_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + b[0][3] = a[3][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + b[1][3] = a[3][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[3][2]; \ + \ + b[3][0] = a[0][3]; \ + b[3][1] = a[1][3]; \ + b[3][2] = a[2][3]; \ + b[3][3] = a[3][3]; \ +} + +/* ========================================================== */ +/* multiply matrix by scalar */ + +#define SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ +} + +/* ========================================================== */ +/* multiply matrix by scalar */ + +#define SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ +} + +/* ========================================================== */ +/* multiply matrix by scalar */ + +#define SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + b[0][3] = (s) * a[0][3]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + b[1][3] = (s) * a[1][3]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ + b[2][3] = (s) * a[2][3]; \ + \ + b[3][0] = s * a[3][0]; \ + b[3][1] = s * a[3][1]; \ + b[3][2] = s * a[3][2]; \ + b[3][3] = s * a[3][3]; \ +} + +/* ========================================================== */ +/* multiply matrix by scalar */ + +#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ +} + +/* +========================================================== */ +/* multiply matrix by scalar */ + +#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ +} + +/* +========================================================== */ +/* multiply matrix by scalar */ + +#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + b[0][3] += (s) * a[0][3]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + b[1][3] += (s) * a[1][3]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ + b[2][3] += (s) * a[2][3]; \ + \ + b[3][0] += (s) * a[3][0]; \ + b[3][1] += (s) * a[3][1]; \ + b[3][2] += (s) * a[3][2]; \ + b[3][3] += (s) * a[3][3]; \ +} + +/* +========================================================== */ +/* matrix product */ +/* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ + +#define MATRIX_PRODUCT_2X2(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \ + \ +} + +/* ========================================================== */ +/* matrix product */ +/* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ + +#define MATRIX_PRODUCT_3X3(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \ +} + +/* ========================================================== */ +/* matrix product */ +/* c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ + +#define MATRIX_PRODUCT_4X4(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\ + c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\ + c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\ + c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\ + \ + c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\ + c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\ + c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\ + c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\ +} + +/* ========================================================== */ +/* matrix times vector */ + +#define MAT_DOT_VEC_2X2(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \ +} + +/* ========================================================== */ +/* matrix times vector */ + +#define MAT_DOT_VEC_3X3(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \ +} + +/* ========================================================== */ +/* matrix times vector */ + +#define MAT_DOT_VEC_4X4(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \ + p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \ +} + +/* ========================================================== */ +/* vector transpose times matrix */ +/* p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */ + +#define VEC_DOT_MAT_3X3(p,v,m) \ +{ \ + p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \ + p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \ + p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \ +} + +/* ========================================================== */ +/* affine matrix times vector */ +/* The matrix is assumed to be an affine matrix, with last two + * entries representing a translation */ + +#define MAT_DOT_VEC_2X3(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \ +} + +/* ========================================================== */ +/* inverse transpose of matrix times vector + * + * This macro computes inverse transpose of matrix m, + * and multiplies vector v into it, to yeild vector p + * + * DANGER !!! Do Not use this on normal vectors!!! + * It will leave normals the wrong length !!! + * See macro below for use on normals. + */ + +#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \ +{ \ + gleDouble det; \ + \ + det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \ + p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ + p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ + \ + /* if matrix not singular, and not orthonormal, then renormalize */ \ + if ((det!=1.0) && (det != 0.0)) { \ + det = 1.0 / det; \ + p[0] *= det; \ + p[1] *= det; \ + } \ +} + +/* ========================================================== */ +/* transform normal vector by inverse transpose of matrix + * and then renormalize the vector + * + * This macro computes inverse transpose of matrix m, + * and multiplies vector v into it, to yeild vector p + * Vector p is then normalized. + */ + + +#define NORM_XFORM_2X2(p,m,v) \ +{ \ + double len; \ + \ + /* do nothing if off-diagonals are zero and diagonals are \ + * equal */ \ + if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \ + p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ + p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ + \ + len = p[0]*p[0] + p[1]*p[1]; \ + len = 1.0 / sqrt (len); \ + p[0] *= len; \ + p[1] *= len; \ + } else { \ + VEC_COPY_2 (p, v); \ + } \ +} + +/* ========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define OUTER_PRODUCT_2X2(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ +} + +/* ========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define OUTER_PRODUCT_3X3(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ +} + +/* ========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define OUTER_PRODUCT_4X4(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + m[0][3] = v[0] * t[3]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + m[1][3] = v[1] * t[3]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ + m[2][3] = v[2] * t[3]; \ + \ + m[3][0] = v[3] * t[0]; \ + m[3][1] = v[3] * t[1]; \ + m[3][2] = v[3] * t[2]; \ + m[3][3] = v[3] * t[3]; \ +} + +/* +========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ +} + +/* +========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ +} + +/* +========================================================== */ +/* outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ + +#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \ +{ \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + m[0][3] += v[0] * t[3]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + m[1][3] += v[1] * t[3]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ + m[2][3] += v[2] * t[3]; \ + \ + m[3][0] += v[3] * t[0]; \ + m[3][1] += v[3] * t[1]; \ + m[3][2] += v[3] * t[2]; \ + m[3][3] += v[3] * t[3]; \ +} + +/* +========================================================== */ +/* determinant of matrix + * + * Computes determinant of matrix m, returning d + */ + +#define DETERMINANT_2X2(d,m) \ +{ \ + d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ +} + +/* ========================================================== */ +/* determinant of matrix + * + * Computes determinant of matrix m, returning d + */ + +#define DETERMINANT_3X3(d,m) \ +{ \ + d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \ + d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \ + d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \ +} + +/* ========================================================== */ +/* i,j,th cofactor of a 4x4 matrix + * + */ + +#define COFACTOR_4X4_IJ(fac,m,i,j) \ +{ \ + int ii[4], jj[4], k; \ + \ + /* compute which row, columnt to skip */ \ + for (k=0; k + +#include "../../Glut.cf" + +SRCS = smap_buildsmap.c smap_context.c smap_create.c smap_destroy.c \ + smap_drawmesh.c smap_flag.c smap_get.c smap_getfunc.c smap_gettexdim.c \ + smap_gettexobj.c smap_getvec.c smap_makemesh.c smap_nearfar.c \ + smap_origin.c smap_render.c smap_rvec2st.c smap_set.c smap_setfunc.c \ + smap_setvec.c smap_texdim.c smap_texobj.c + +OBJS = smap_buildsmap.o smap_context.o smap_create.o smap_destroy.o \ + smap_drawmesh.o smap_flag.o smap_get.o smap_getfunc.o smap_gettexdim.o \ + smap_gettexobj.o smap_getvec.o smap_makemesh.o smap_nearfar.o \ + smap_origin.o smap_render.o smap_rvec2st.o smap_set.o smap_setfunc.o \ + smap_setvec.o smap_texdim.o smap_texobj.o + +#ifdef LibraryObjectRule +LibraryObjectRule() +#else +/* XXX Very lame, you must be using pre-R5 config files! This + will probably do essentially what LibraryObjectRule does. */ +NormalLibraryObjectRule() +#endif + +NormalLibraryTarget(glsmap,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/lib/glsmap/ObjectType.mk b/lib/glut-3.7.6/lib/glsmap/ObjectType.mk new file mode 100644 index 0000000000..f94dc77f5f --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_32) +CSTYLE = $(CSTYLE_32) diff --git a/lib/glut-3.7.6/lib/glsmap/glsmap.dsp b/lib/glut-3.7.6/lib/glsmap/glsmap.dsp new file mode 100644 index 0000000000..7b6e9b2924 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/glsmap.dsp @@ -0,0 +1,172 @@ +# Microsoft Developer Studio Project File - Name="glsmap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=glsmap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "glsmap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "glsmap.mak" CFG="glsmap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "glsmap - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "glsmap - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "glsmap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "glsmap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "glsmap - Win32 Release" +# Name "glsmap - Win32 Debug" +# Begin Source File + +SOURCE=.\glsmapint.h +# End Source File +# Begin Source File + +SOURCE=.\smap_buildsmap.c +# End Source File +# Begin Source File + +SOURCE=.\smap_context.c +# End Source File +# Begin Source File + +SOURCE=.\smap_create.c +# End Source File +# Begin Source File + +SOURCE=.\smap_destroy.c +# End Source File +# Begin Source File + +SOURCE=.\smap_drawmesh.c +# End Source File +# Begin Source File + +SOURCE=.\smap_flag.c +# End Source File +# Begin Source File + +SOURCE=.\smap_get.c +# End Source File +# Begin Source File + +SOURCE=.\smap_getfunc.c +# End Source File +# Begin Source File + +SOURCE=.\smap_gettexdim.c +# End Source File +# Begin Source File + +SOURCE=.\smap_gettexobj.c +# End Source File +# Begin Source File + +SOURCE=.\smap_getvec.c +# End Source File +# Begin Source File + +SOURCE=.\smap_makemesh.c +# End Source File +# Begin Source File + +SOURCE=.\smap_nearfar.c +# End Source File +# Begin Source File + +SOURCE=.\smap_origin.c +# End Source File +# Begin Source File + +SOURCE=.\smap_render.c +# End Source File +# Begin Source File + +SOURCE=.\smap_rvec2st.c +# End Source File +# Begin Source File + +SOURCE=.\smap_set.c +# End Source File +# Begin Source File + +SOURCE=.\smap_setfunc.c +# End Source File +# Begin Source File + +SOURCE=.\smap_setvec.c +# End Source File +# Begin Source File + +SOURCE=.\smap_texdim.c +# End Source File +# Begin Source File + +SOURCE=.\smap_texobj.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/glsmap/glsmapint.h b/lib/glut-3.7.6/lib/glsmap/glsmapint.h new file mode 100644 index 0000000000..f91baea32b --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/glsmapint.h @@ -0,0 +1,102 @@ +#ifndef __glsmapint_h__ +#define __glsmapint_h__ + +/* Copyright (c) Mark J. Kilgard, 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 + +enum { X = 0, Y = 1, Z = 2 }; + +#define INITFACE(mesh) \ + int steps = mesh->steps; \ + int sqsteps = mesh->steps * mesh->steps + +#define FACE(side,y,x) \ + mesh->face[(side)*sqsteps + (y)*steps + (x)] + +#define FACExy(side,i,j) \ + (&FACE(side,i,j).x) + +#define FACEst(side,i,j) \ + (&FACE(side,i,j).s) + +#define INITBACK(mesh) \ + int allrings = mesh->rings + mesh->edgeExtend; \ + int ringedspokes = allrings * mesh->steps + +#define BACK(edge,ring,spoke) \ + mesh->back[(edge)*ringedspokes + (ring)*mesh->steps + (spoke)] + +#define BACKxy(edge,ring,spoke) \ + (&BACK(edge,ring,spoke).x) + +#define BACKst(edge,ring,spoke) \ + (&BACK(edge,ring,spoke).s) + +typedef struct _STXY { + GLfloat s, t; + GLfloat x, y; +} STXY; + +typedef struct _SphereMapMesh { + + int refcnt; + + int steps; + int rings; + int edgeExtend; + + STXY *face; + STXY *back; + +} SphereMapMesh; + +struct _SphereMap { + + /* Shared sphere map mesh vertex data. */ + SphereMapMesh *mesh; + + /* Texture object ids. */ + GLuint smapTexObj; + GLuint viewTexObjs[6]; + GLuint viewTexObj; + + /* Flags */ + SphereMapFlags flags; + + /* Texture dimensions must be a power of two. */ + int viewTexDim; /* view texture dimension */ + int smapTexDim; /* sphere map texture dimension */ + + /* Viewport origins for view and sphere map rendering. */ + int viewOrigin[2]; + int smapOrigin[2]; + + /* Viewing vectors. */ + GLfloat eye[3]; + GLfloat up[3]; + GLfloat obj[3]; + + /* Projection parameters. */ + GLfloat viewNear; + GLfloat viewFar; + + /* Rendering callbacks. */ + void (*positionLights)(int view, void *context); + void (*drawView)(int view, void *context); + + /* Application specified callback data. */ + void *context; + +}; + +/* Library internal routines. */ +extern void __smapDrawSphereMapMeshSide(SphereMapMesh *mesh, int side); +extern void __smapDrawSphereMapMeshBack(SphereMapMesh *mesh); +extern void __smapValidateSphereMapMesh(SphereMapMesh *mesh); + +#endif /* __glsmapint_h__ */ diff --git a/lib/glut-3.7.6/lib/glsmap/smap_buildsmap.c b/lib/glut-3.7.6/lib/glsmap/smap_buildsmap.c new file mode 100644 index 0000000000..53fa0e6cb0 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_buildsmap.c @@ -0,0 +1,227 @@ + +/* Copyright (c) Mark J. Kilgard, 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. */ + +/* smap_buildsmap.c - automatically builds sphere map */ + +#include +#include +#include +#include + +#include "glsmapint.h" + +#if defined(GL_EXT_texture_object) && !defined(GL_VERSION_1_1) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#endif +#if defined(GL_EXT_copy_texture) && !defined(GL_VERSION_1_1) +#define glCopyTexImage2D(A, B, C, D, E, F, G, H) glCopyTexImage2DEXT(A, B, C, D, E, F, G, H) +#endif + +static void +copyImageToTexture(SphereMap *smap, + GLuint texobj, int origin[2], int texdim) +{ + int isSmapTexObj = (texobj == smap->smapTexObj) ? 1 : 0; + int genMipmapsFlag = + isSmapTexObj ? SMAP_GENERATE_SMAP_MIPMAPS : SMAP_GENERATE_VIEW_MIPMAPS; + static GLubyte pixels[256][256][3]; /* XXX fix me. */ + + glBindTexture(GL_TEXTURE_2D, texobj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + if (smap->flags & genMipmapsFlag) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + /* Clamp to avoid artifacts from wrap around in texture. */ + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (smap->flags & genMipmapsFlag) { + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glReadPixels(origin[X], origin[Y], texdim, texdim, + GL_RGB, GL_UNSIGNED_BYTE, pixels); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texdim, texdim, + GL_RGB, GL_UNSIGNED_BYTE, pixels); + } else { + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + origin[X], origin[Y], texdim, texdim, 0); + } +} + +static struct { + GLfloat angle; + GLfloat x, y, z; +} faceInfo[6] = { + { 0.0, +1.0, 0.0, 0.0 }, /* front */ + { 90.0, -1.0, 0.0, 0.0 }, /* top */ + { 90.0, +1.0, 0.0, 0.0 }, /* bottom */ + { 90.0, 0.0, -1.0, 0.0 }, /* left */ + { 90.0, 0.0, +1.0, 0.0 }, /* right */ + { 180.0, -1.0, 0.0, 0.0 } /* back */ +}; + +static void +configFace(SphereMap *smap, int view) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glRotatef(faceInfo[view].angle, + faceInfo[view].x, faceInfo[view].y, faceInfo[view].z); + gluLookAt(smap->obj[X], smap->obj[Y], smap->obj[Z], /* "eye" at object */ + smap->eye[X], smap->eye[Y], smap->eye[Z], /* looking at eye */ + smap->up[X], smap->up[Y], smap->up[Z]); +} + +static void +initGenViewTex(SphereMap *smap) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0, 1.0, smap->viewNear, smap->viewFar); + glViewport(smap->viewOrigin[X], smap->viewOrigin[Y], + smap->viewTexDim, smap->viewTexDim); + glScissor(0, 0, smap->viewTexDim, smap->viewTexDim); + glEnable(GL_SCISSOR_TEST); + glEnable(GL_DEPTH_TEST); +} + +static void +genViewTex(SphereMap *smap, int view) +{ + configFace(smap, view); + assert(smap->positionLights); + smap->positionLights(view, smap->context); + assert(smap->drawView); + smap->drawView(view, smap->context); +} + +void +smapGenViewTex(SphereMap *smap, int view) +{ + initGenViewTex(smap); + genViewTex(smap, view); + copyImageToTexture(smap, smap->viewTexObjs[view], + smap->viewOrigin, smap->viewTexDim); +} + +void +smapGenViewTexs(SphereMap *smap) +{ + int view; + + initGenViewTex(smap); + + for (view=0; view<6; view++) { + genViewTex(smap, view); + copyImageToTexture(smap, smap->viewTexObjs[view], + smap->viewOrigin, smap->viewTexDim); + } +} + +void +drawSphereMapMesh(SphereMap *smap) +{ + int side; + + /* Calculate sphere map mesh if needed. */ + __smapValidateSphereMapMesh(smap->mesh); + + /* Five front and side faces. */ + for (side=0; side<5; side++) { + /* Bind to texture for given face of cube map. */ + glBindTexture(GL_TEXTURE_2D, smap->viewTexObjs[side]); + __smapDrawSphereMapMeshSide(smap->mesh, side); + } + + /* Bind to texture for back face of cube map. */ + glBindTexture(GL_TEXTURE_2D, smap->viewTexObjs[side]); + __smapDrawSphereMapMeshBack(smap->mesh); +} + +void +initDrawSphereMapMesh(SphereMap *smap) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, 1, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(smap->smapOrigin[X], smap->smapOrigin[Y], + smap->smapTexDim, smap->smapTexDim); + + if (smap->flags & SMAP_CLEAR_SMAP_TEXTURE) { + glClear(GL_COLOR_BUFFER_BIT); + } + + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glDisable(GL_CULL_FACE); +} + +void +smapGenSphereMapFromViewTexs(SphereMap *smap) +{ + initDrawSphereMapMesh(smap); + drawSphereMapMesh(smap); + + copyImageToTexture(smap, smap->smapTexObj, + smap->smapOrigin, smap->smapTexDim); +} + +void +smapGenSphereMap(SphereMap *smap) +{ + smapGenViewTexs(smap); + smapGenSphereMapFromViewTexs(smap); +} + +void +smapGenSphereMapWithOneViewTex(SphereMap *smap) +{ + int side; + + /* Make sure viewports are not obviously overlapping. */ + assert(smap->viewOrigin[X] != smap->smapOrigin[X]); + assert(smap->viewOrigin[Y] != smap->smapOrigin[Y]); + + /* Calculate sphere map mesh if needed. */ + __smapValidateSphereMapMesh(smap->mesh); + + /* Five front and side faces. */ + for (side=0; side<5; side++) { + initGenViewTex(smap); + genViewTex(smap, side); + copyImageToTexture(smap, smap->viewTexObj, + smap->viewOrigin, smap->viewTexDim); + + /* Preceeding copyImageToTexture does bind to smap->viewTexObj */ + + initDrawSphereMapMesh(smap); + __smapDrawSphereMapMeshSide(smap->mesh, side); + } + + initGenViewTex(smap); + genViewTex(smap, SMAP_BACK); + copyImageToTexture(smap, smap->viewTexObj, + smap->viewOrigin, smap->viewTexDim); + + /* Preceeding copyImageToTexture does bind to smap->viewTexObj */ + + initDrawSphereMapMesh(smap); + __smapDrawSphereMapMeshBack(smap->mesh); + + copyImageToTexture(smap, smap->smapTexObj, + smap->smapOrigin, smap->smapTexDim); +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_context.c b/lib/glut-3.7.6/lib/glsmap/smap_context.c new file mode 100644 index 0000000000..6557b0bb01 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_context.c @@ -0,0 +1,20 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetContextData(SphereMap *smap, void *context) +{ + smap->context = context; +} + +void +smapGetContextData(SphereMap *smap, void **context) +{ + *context = smap->context; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_create.c b/lib/glut-3.7.6/lib/glsmap/smap_create.c new file mode 100644 index 0000000000..47eba82cdd --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_create.c @@ -0,0 +1,98 @@ + +/* Copyright (c) Mark J. Kilgard, 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 + +#include "glsmapint.h" + +static SphereMapMesh * +createSphereMapMesh(void) +{ + SphereMapMesh *mesh; + + mesh = (SphereMapMesh*) malloc(sizeof(SphereMapMesh)); + + mesh->steps = 8; + mesh->rings = 3; + mesh->edgeExtend = 1; + + mesh->face = NULL; + mesh->back = NULL; + + mesh->refcnt = 0; + + return mesh; +} + +static void +refSphereMapMesh(SphereMapMesh *mesh) +{ + mesh->refcnt++; +} + +SphereMap * +smapCreateSphereMap(SphereMap *shareSmap) +{ + SphereMap *smap; + int i; + + smap = (SphereMap*) malloc(sizeof(SphereMap)); + + if (shareSmap) { + smap->mesh = shareSmap->mesh; + } else { + smap->mesh = createSphereMapMesh(); + } + refSphereMapMesh(smap->mesh); + + /* Default texture objects. */ + smap->smapTexObj = 1001; + for (i=0; i<6; i++) { + smap->viewTexObjs[i] = i+1002; + } + smap->viewTexObj = 1008; + + /* Default texture dimensions 64x64 */ + smap->viewTexDim = 64; + smap->smapTexDim = 64; + + /* Default origin at lower left. */ + smap->viewOrigin[X] = 0; + smap->viewOrigin[Y] = 0; + smap->smapOrigin[X] = 0; + smap->smapOrigin[Y] = 0; + + /* Flags. */ + smap->flags = (SphereMapFlags) 0; + + /* Default eye vector. */ + smap->eye[X] = 0.0; + smap->eye[Y] = 0.0; + smap->eye[Z] = -10.0; + + /* Default up vector. */ + smap->up[X] = 0.0; + smap->up[Y] = 0.1; + smap->up[Z] = 0.0; + + /* Default object location vector. */ + smap->obj[X] = 0.0; + smap->obj[Y] = 0.0; + smap->obj[Z] = 0.0; + + /* Default near and far clip planes. */ + smap->viewNear = 0.1; + smap->viewFar = 20.0; + + smap->positionLights = NULL; + smap->drawView = NULL; + + smap->context = NULL; + + return smap; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_destroy.c b/lib/glut-3.7.6/lib/glsmap/smap_destroy.c new file mode 100644 index 0000000000..a90fa7b274 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_destroy.c @@ -0,0 +1,34 @@ + +/* Copyright (c) Mark J. Kilgard, 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 /* SunOS multithreaded assert() needs . Lame. */ +#include +#include + +#include "glsmapint.h" + +static void +derefSphereMapMesh(SphereMapMesh *mesh) +{ + assert(mesh->refcnt > 0); + mesh->refcnt--; + if (mesh->refcnt == 0) { + if (mesh->face) { + assert(mesh->back == + &(mesh->face[5*mesh->steps*mesh->steps])); + free(mesh->face); + } + free(mesh); + } +} + +void +smapDestroySphereMap(SphereMap *smap) +{ + derefSphereMapMesh(smap->mesh); + free(smap); +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_drawmesh.c b/lib/glut-3.7.6/lib/glsmap/smap_drawmesh.c new file mode 100644 index 0000000000..ed526c377f --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_drawmesh.c @@ -0,0 +1,50 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +__smapDrawSphereMapMeshSide(SphereMapMesh *mesh, int side) +{ + INITFACE(mesh); + int i, j; + + for (i=0; isteps-1; i++) { + glBegin(GL_QUAD_STRIP); + for (j=0; jsteps; j++) { + glTexCoord2fv (FACEst(side,i,j)); + glVertex2fv (FACExy(side,i,j)); + glTexCoord2fv (FACEst(side,i+1,j)); + glVertex2fv (FACExy(side,i+1,j)); + } + glEnd(); + } +} + +/* Back face specially rendered for its singularity! */ +void +__smapDrawSphereMapMeshBack(SphereMapMesh *mesh) +{ + INITBACK(mesh); + int side, i, j; + + for (side=0; side<4; side++) { + for (j=0; jrings-1+mesh->edgeExtend; j++) { + glBegin(GL_QUAD_STRIP); + for (i=0; isteps; i++) { + glTexCoord2fv (BACKst(side,j,i)); + glVertex2fv (BACKxy(side,j,i)); + glTexCoord2fv (BACKst(side,j+1,i)); + glVertex2fv (BACKxy(side,j+1,i)); + } + glEnd(); + } + } +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_flag.c b/lib/glut-3.7.6/lib/glsmap/smap_flag.c new file mode 100644 index 0000000000..11278b351d --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_flag.c @@ -0,0 +1,20 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetFlags(SphereMap *smap, SphereMapFlags flags) +{ + smap->flags = flags; +} + +void +smapGetFlags(SphereMap *smap, SphereMapFlags *flags) +{ + *flags = smap->flags; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_get.c b/lib/glut-3.7.6/lib/glsmap/smap_get.c new file mode 100644 index 0000000000..d43155581e --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_get.c @@ -0,0 +1,32 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void smapGetEye(SphereMap *smap, + GLfloat *eyex, GLfloat *eyey, GLfloat *eyez) +{ + *eyex = smap->eye[X]; + *eyey = smap->eye[Y]; + *eyez = smap->eye[Z]; +} + +void smapGetUp(SphereMap *smap, + GLfloat *upx, GLfloat *upy, GLfloat *upz) +{ + *upx = smap->up[X]; + *upy = smap->up[Y]; + *upz = smap->up[Z]; +} + +void smapGetObject(SphereMap *smap, + GLfloat *objx, GLfloat *objy, GLfloat *objz) +{ + *objx = smap->obj[X]; + *objy = smap->obj[Y]; + *objz = smap->obj[Z]; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_getfunc.c b/lib/glut-3.7.6/lib/glsmap/smap_getfunc.c new file mode 100644 index 0000000000..9732addfd6 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_getfunc.c @@ -0,0 +1,20 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void smapGetPositionLightsFunc(SphereMap *smap, + void (**positionLights)(int view, void *context)) +{ + *positionLights = smap->positionLights; +} + +void smapGetDrawViewFunc(SphereMap *smap, + void (**drawView)(int view, void *context)) +{ + *drawView = smap->drawView; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_gettexdim.c b/lib/glut-3.7.6/lib/glsmap/smap_gettexdim.c new file mode 100644 index 0000000000..ef3d243572 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_gettexdim.c @@ -0,0 +1,21 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapGetSphereMapTexDim(SphereMap *smap, GLsizei *texdim) +{ + *texdim = smap->smapTexDim; +} + +void +smapGetViewTexDim(SphereMap *smap, GLsizei *texdim) +{ + *texdim = smap->viewTexDim; +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_gettexobj.c b/lib/glut-3.7.6/lib/glsmap/smap_gettexobj.c new file mode 100644 index 0000000000..eba9b64b0e --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_gettexobj.c @@ -0,0 +1,31 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapGetSphereMapTexObj(SphereMap *smap, GLuint *texobj) +{ + *texobj = smap->smapTexObj; +} + +void +smapGetViewTexObj(SphereMap *smap, GLuint *texobj) +{ + *texobj = smap->viewTexObj; +} + +void +smapGetViewTexObjs(SphereMap *smap, GLuint texobjs[6]) +{ + int i; + + for (i=0; i<6; i++) { + texobjs[i] = smap->viewTexObjs[i]; + } +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_getvec.c b/lib/glut-3.7.6/lib/glsmap/smap_getvec.c new file mode 100644 index 0000000000..a56d309821 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_getvec.c @@ -0,0 +1,33 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapGetEyeVector(SphereMap *smap, GLfloat *eye) +{ + eye[X] = smap->eye[X]; + eye[Y] = smap->eye[Y]; + eye[Z] = smap->eye[Z]; +} + +void +smapGetUpVector(SphereMap *smap, GLfloat *up) +{ + up[X] = smap->up[X]; + up[Y] = smap->up[Y]; + up[Z] = smap->up[Z]; +} + +void +smapGetObjectVector(SphereMap *smap, GLfloat *obj) +{ + obj[X] = smap->obj[X]; + obj[Y] = smap->obj[Y]; + obj[Z] = smap->obj[Z]; +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_makemesh.c b/lib/glut-3.7.6/lib/glsmap/smap_makemesh.c new file mode 100644 index 0000000000..cd5b411d6d --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_makemesh.c @@ -0,0 +1,253 @@ + +/* Copyright (c) Mark J. Kilgard, 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 /* SunOS multithreaded assert() needs . Lame. */ +#include +#include +#include +#include + +#include "glsmapint.h" + +static struct { + int xl; + int yl; + int zl; + int swap; /* swap final (s,t) */ + int flip; /* flip final s or t, ie. [0..1] --> [1..0] */ + float dir; +} faceInfo[5] = { + { 0, 1, 2, 0, 1.0, 1.0 }, /* front */ + { 0, 2, 1, 0, -1.0, 1.0 }, /* top */ + { 0, 2, 1, 0, 1.0, -1.0 }, /* bottom */ + { 1, 2, 0, 1, -1.0, 1.0 }, /* left */ + { 1, 2, 0, 1, 1.0, -1.0 }, /* right */ +}; + +static struct { + int xl; + int yl; + float dir; +} edgeInfo[4] = { + { 0, 1, -1.0 }, + { 0, 1, 1.0 }, + { 1, 0, -1.0 }, + { 1, 0, 1.0 } +}; + +void +__smapValidateSphereMapMesh(SphereMapMesh *mesh) +{ + /* setup some local variables for variable array size indexing */ + INITFACE(mesh); + INITBACK(mesh); + + float st[2]; /* (s,t) coordinate */ + /* range=[0..1,0..1] */ + float v[3]; /* (x,y,z) location on cube map */ + /* range=[-1..1,-1..1,-1..1] */ + float rv[3]; /* reflection vector, ie. cube map location */ + /* normalized onto unit sphere */ + float len; /* distance from v[3] to origin */ + /* for converting to rv[3] */ + int side; /* which of 5 faces (all but back face) */ + int i, j; + int xl, yl, zl; /* renamed X, Y, Z index */ + int swap; + int flip; + int edge; /* which edge of back face */ + float sc, tc; /* singularity (s,t) on back face circle */ + + if (mesh->face) { + assert(mesh->back == &(mesh->face[5*sqsteps])); + return; + } + assert(mesh->back == NULL); + + mesh->face = (STXY*) + malloc((5*sqsteps+4*ringedspokes) * sizeof(STXY)); + mesh->back = &(mesh->face[5*sqsteps]); + + /* for the front and four side faces */ + for (side=0; side<5; side++) { + /* use faceInfo to parameterize face construction */ + xl = faceInfo[side].xl; + yl = faceInfo[side].yl; + zl = faceInfo[side].zl; + swap = faceInfo[side].swap; + flip = faceInfo[side].flip; + /* cube map "Z" coordinate */ + v[zl] = faceInfo[side].dir; + + for (i=0; isteps; i++) { + /* cube map "Y" coordinate */ + v[yl] = 2.0/(mesh->steps-1) * i - 1.0; + for (j=0; jsteps; j++) { + /* cube map "X" coordinate */ + v[xl] = 2.0/(mesh->steps-1) * j - 1.0; + + /* normalize cube map location to construct */ + /* reflection vector */ + len = sqrt(1.0 + v[xl]*v[xl] + v[yl]*v[yl]); + rv[0] = v[0]/len; + rv[1] = v[1]/len; + rv[2] = v[2]/len; + + /* map reflection vector to sphere map (s,t) */ + /* NOTE: face[side][i][j] (x,y) gets updated */ + smapRvecToSt(rv, FACExy(side,i,j)); + + /* update texture coordinate, */ + /* normalize [-1..1,-1..1] to [0..1,0..1] */ + if (!swap) { + FACE(side,i,j).s = (-v[xl] + 1.0)/2.0; + FACE(side,i,j).t = (flip*v[yl] + 1.0)/2.0; + } else { + FACE(side,i,j).s = (flip*-v[yl] + 1.0)/2.0; + FACE(side,i,j).t = (v[xl] + 1.0)/2.0; + } + } + } + } + + + /* The back face must be specially handled. The center + point in the back face of a cube map becomes a + a singularity around the circular edge of a sphere map. */ + + /* Carefully work from each edge of the back face to center + of back face mapped to the outside of the sphere map. */ + + /* cube map "Z" coordinate, always -1 since backface */ + v[2] = -1; + + /* for each edge */ + /* [x=-1, y=-1..1, z=-1] */ + /* [x= 1, y=-1..1, z=-1] */ + /* [x=-1..1, y=-1, z=-1] */ + /* [x=-1..1, y= 1, z=-1] */ + for (edge=0; edge<4; edge++) { + /* cube map "X" coordinate */ + v[edgeInfo[edge].xl] = edgeInfo[edge].dir; + for (j=0; jsteps; j++) { + /* cube map "Y" coordinate */ + v[edgeInfo[edge].yl] = 2.0/(mesh->steps-1) * j - 1.0; + + /* normalize cube map location to construct */ + /* reflection vector */ + len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + rv[0] = v[0]/len; + rv[1] = v[1]/len; + rv[2] = v[2]/len; + + /* Map reflection vector to sphere map (s,t). */ + smapRvecToSt(rv, st); + + /* Determine distinance from the center of sphere */ + /* map (0.5,0.5) to (s,t) */ + len = sqrt((st[0]-0.5)*(st[0]-0.5) + (st[1]-0.5)*(st[1]-0.5)); + + /* Calculate (s,t) location extended to the singularity */ + /* at the center of the back face (ie, extend to */ + /* circle edge of the sphere map). */ + sc = (st[0]-0.5)/len * 0.5 + 0.5; + tc = (st[1]-0.5)/len * 0.5 + 0.5; + + /* (s,t) at back face edge. */ + BACK(edge,0,j).s = (-v[0] + 1.0)/2.0; + BACK(edge,0,j).t = (-v[1] + 1.0)/2.0; + BACK(edge,0,j).x = st[0]; + BACK(edge,0,j).y = st[1]; + + /* If just two rings, we just generate a back face edge + vertex and a center vertex (2 rings), but if there + are more rings, we carefully interpolate between the + edge and center vertices. Notice how smapStToRvec is used + to map the interpolated (s,t) into a reflection vector + that must then be extended to the back cube face (it is + not correct to just interpolate the texture + coordinates!). */ + if (mesh->rings > 2) { + float ist[2]; /* interpolated (s,t) */ + float ds, dt; /* delta s and delta t */ + + /* Start interpolating from the edge. */ + ist[0] = st[0]; + ist[1] = st[1]; + + /* Calculate delta s and delta t for interpolation. */ + ds = (sc - ist[0]) / (mesh->rings-1); + dt = (tc - ist[1]) / (mesh->rings-1); + + for (i=1; irings-1; i++) { + /* Incremental interpolation of (s,t). */ + ist[0] = ist[0] + ds; + ist[1] = ist[1] + dt; + + /* Calculate reflection vector from interpolated (s,t). */ + smapStToRvec(ist, rv); + /* Assert that z must be on the back cube face. */ + assert(rv[2] <= -sqrt(1.0/3.0)); + /* Extend reflection vector out of back cube face. */ + /* Note: z is negative value so negate z to avoid */ + /* inverting x and y! */ + rv[0] = rv[0] / -rv[2]; + rv[1] = rv[1] / -rv[2]; + + BACK(edge,i,j).s = (-rv[0] + 1.0)/2.0; + BACK(edge,i,j).t = (-rv[1] + 1.0)/2.0; + BACK(edge,i,j).x = ist[0]; + BACK(edge,i,j).y = ist[1]; + } + } + + /* (s,t) at circle edge of the sphere map is ALWAYS */ + /* at center of back cube map face */ + BACK(edge,mesh->rings-1,j).s = 0.5; + BACK(edge,mesh->rings-1,j).t = 0.5; + /* Location of singularity at the edge of the sphere map. */ + BACK(edge,mesh->rings-1,j).x = sc; + BACK(edge,mesh->rings-1,j).y = tc; + + if (mesh->edgeExtend) { + /* Add an extra ring to avoid seeing the */ + /* tessellation boundary of the sphere map's sphere. */ + BACK(edge,mesh->rings,j).s = 0.5; + BACK(edge,mesh->rings,j).t = 0.5; + /* 0.33 below is a fudge factor. */ + BACK(edge,mesh->rings,j).x = sc + 0.33*(sc - st[0]); + BACK(edge,mesh->rings,j).y = tc + 0.33*(tc - st[1]); + } + } + } + for (edge=0; edge<4; edge++) { + for (j=0; jsteps; j++) { + for (i=1; irings-1; i++) { + } + } + } +} + +void +smapConfigureSphereMapMesh(SphereMap *smap, + int steps, int rings, int edgeExtend) +{ + SphereMapMesh *mesh = smap->mesh; + + if (steps == mesh->steps && + rings == mesh->rings && + edgeExtend == mesh->edgeExtend) { + return; + } + + mesh->steps = steps; + mesh->rings = rings; + mesh->edgeExtend = edgeExtend; + + mesh->face = NULL; + mesh->back = NULL; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_nearfar.c b/lib/glut-3.7.6/lib/glsmap/smap_nearfar.c new file mode 100644 index 0000000000..45eb55d83c --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_nearfar.c @@ -0,0 +1,26 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetNearFar(SphereMap *smap, + GLfloat viewNear, GLfloat viewFar) +{ + /* Curse Intel for "near" and "far" keywords. */ + smap->viewNear = viewNear; + smap->viewFar = viewFar; +} + +void +smapGetNearFar(SphereMap *smap, + GLfloat *viewNear, GLfloat *viewFar) +{ + /* Curse Intel for "near" and "far" keywords. */ + *viewNear = smap->viewNear; + *viewFar = smap->viewFar; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_origin.c b/lib/glut-3.7.6/lib/glsmap/smap_origin.c new file mode 100644 index 0000000000..9b6af2146f --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_origin.c @@ -0,0 +1,34 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void smapSetViewOrigin(SphereMap *smap, GLint x, GLint y) +{ + smap->viewOrigin[0] = x; + smap->viewOrigin[1] = y; +} + +void smapSetSphereMapOrigin(SphereMap *smap, GLint x, GLint y) +{ + smap->smapOrigin[0] = x; + smap->smapOrigin[1] = y; +} + +void smapGetViewOrigin(SphereMap *smap, GLint *x, GLint *y) +{ + *x = smap->viewOrigin[0]; + *y = smap->viewOrigin[1]; +} + +void smapGetSphereMapOrigin(SphereMap *smap, GLint *x, GLint *y) +{ + *x = smap->smapOrigin[0]; + *y = smap->smapOrigin[1]; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_render.c b/lib/glut-3.7.6/lib/glsmap/smap_render.c new file mode 100644 index 0000000000..504458ae69 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_render.c @@ -0,0 +1,26 @@ + +/* Copyright (c) Mark J. Kilgard, 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 + +#include "glsmapint.h" + +#if defined(GL_EXT_texture_object) && !defined(GL_VERSION_1_1) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#endif + +void +smapRenderSphereMappedObj(SphereMap *smap) +{ + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, smap->smapTexObj); +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_rvec2st.c b/lib/glut-3.7.6/lib/glsmap/smap_rvec2st.c new file mode 100644 index 0000000000..23b5d8dc10 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_rvec2st.c @@ -0,0 +1,79 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +/* (x,y,z) reflection vector --> (s,t) sphere map coordinates */ +int +smapRvecToSt(float rvec[3], float st[2]) +{ + double m, recipm; + + /* In Section 2.10.4 ("Generating texture coordinates") + of the OpenGL 1.1 specification, you will find the + GL_SPHERE_MAP equations: + + n' = normal after transformation to eye coordinates + u = unit vector from origin to vertex in eye coordinates + + (rx, ry, rz) = u - 2 * n' * transpose(n') * u + + m = 2 * sqrt(rx^2 + ry^2 + (rz + 1)^2)) + + s = rx/m + 0.5 + t = ry/m + 0.5 + + The equation for calculating (rx, ry, rz) is the + equation for calculating the reflection vector for + a surface and observer. The explanation and + derivation for this equation is found in Roger's + "Procedural Elements for Computer Graphics" 2nd ed. + in Section 5-5 ("Determining the Reflection Vector"). + Note that Roger's convention has the Z axis in + the opposite direction from the OpenGL convention. */ + + m = 2 * sqrt(rvec[0]*rvec[0] + + rvec[1]*rvec[1] + + (rvec[2]+1)*(rvec[2]+1)); + if (m == 0.0) { + /* Some point on the sphere map perimeter. */ + st[0] = 0.0; + st[1] = 0.5; + return 0; + } + + recipm = 1.0/m; + + st[0] = rvec[0]*recipm + 0.5; + st[1] = rvec[1]*recipm + 0.5; + return 1; +} + +/* (s,t) sphere map coordinate --> reflection verctor (x,y,z) */ +void +smapStToRvec(float *st, float *rvec) +{ + double tmp1, tmp2; + + /* Using algebra to invert the sphere mapping equations + shown above in smapRvecToSt, you get: + + rx = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*s-1) + ry = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*t-1) + rz = -8*s^2 + 8*s - 8*t^2 + 8*t - 3 + + The C code below eliminates common subexpressions. */ + + tmp1 = st[0]*(1-st[0]) + st[1]*(1-st[1]); + tmp2 = 2 * sqrt(4*tmp1 - 1); + + rvec[0] = tmp2 * (2*st[0]-1); + rvec[1] = tmp2 * (2*st[1]-1); + rvec[2] = 8 * tmp1 - 3; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_set.c b/lib/glut-3.7.6/lib/glsmap/smap_set.c new file mode 100644 index 0000000000..32d4e08a53 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_set.c @@ -0,0 +1,32 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void smapSetEye(SphereMap *smap, + GLfloat eyex, GLfloat eyey, GLfloat eyez) +{ + smap->eye[X] = eyex; + smap->eye[Y] = eyey; + smap->eye[Z] = eyez; +} + +void smapSetUp(SphereMap *smap, + GLfloat upx, GLfloat upy, GLfloat upz) +{ + smap->up[X] = upx; + smap->up[Y] = upy; + smap->up[Z] = upz; +} + +void smapSetObject(SphereMap *smap, + GLfloat objx, GLfloat objy, GLfloat objz) +{ + smap->obj[X] = objx; + smap->obj[Y] = objy; + smap->obj[Z] = objz; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_setfunc.c b/lib/glut-3.7.6/lib/glsmap/smap_setfunc.c new file mode 100644 index 0000000000..359c9a6ff6 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_setfunc.c @@ -0,0 +1,20 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void smapSetPositionLightsFunc(SphereMap *smap, + void (*positionLights)(int view, void *context)) +{ + smap->positionLights = positionLights; +} + +void smapSetDrawViewFunc(SphereMap *smap, + void (*drawView)(int view, void *context)) +{ + smap->drawView = drawView; +} diff --git a/lib/glut-3.7.6/lib/glsmap/smap_setvec.c b/lib/glut-3.7.6/lib/glsmap/smap_setvec.c new file mode 100644 index 0000000000..353be86dc7 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_setvec.c @@ -0,0 +1,33 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetEyeVector(SphereMap *smap, GLfloat *eye) +{ + smap->eye[X] = eye[X]; + smap->eye[Y] = eye[Y]; + smap->eye[Z] = eye[Z]; +} + +void +smapSetUpVector(SphereMap *smap, GLfloat *up) +{ + smap->up[X] = up[X]; + smap->up[Y] = up[Y]; + smap->up[Z] = up[Z]; +} + +void +smapSetObjectVector(SphereMap *smap, GLfloat *obj) +{ + smap->obj[X] = obj[X]; + smap->obj[Y] = obj[Y]; + smap->obj[Z] = obj[Z]; +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_texdim.c b/lib/glut-3.7.6/lib/glsmap/smap_texdim.c new file mode 100644 index 0000000000..ebc4a58a57 --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_texdim.c @@ -0,0 +1,21 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetSphereMapTexDim(SphereMap *smap, GLsizei texdim) +{ + smap->smapTexDim = texdim; +} + +void +smapSetViewTexDim(SphereMap *smap, GLsizei texdim) +{ + smap->viewTexDim = texdim; +} + diff --git a/lib/glut-3.7.6/lib/glsmap/smap_texobj.c b/lib/glut-3.7.6/lib/glsmap/smap_texobj.c new file mode 100644 index 0000000000..b4c478d50c --- /dev/null +++ b/lib/glut-3.7.6/lib/glsmap/smap_texobj.c @@ -0,0 +1,31 @@ + +/* Copyright (c) Mark J. Kilgard, 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 "glsmapint.h" + +void +smapSetSphereMapTexObj(SphereMap *smap, GLuint texobj) +{ + smap->smapTexObj = texobj; +} + +void +smapSetViewTexObj(SphereMap *smap, GLuint texobj) +{ + smap->viewTexObj = texobj; +} + +void +smapSetViewTexObjs(SphereMap *smap, GLuint texobjs[6]) +{ + int i; + + for (i=0; i<6; i++) { + smap->viewTexObjs[i] = texobjs[i]; + } +} + diff --git a/lib/glut-3.7.6/lib/glut.n32/ObjectType.mk b/lib/glut-3.7.6/lib/glut.n32/ObjectType.mk new file mode 100644 index 0000000000..6116ff97eb --- /dev/null +++ b/lib/glut-3.7.6/lib/glut.n32/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_N32) +CSTYLE = $(CSTYLE_N32) diff --git a/lib/glut-3.7.6/lib/glut.n64/ObjectType.mk b/lib/glut-3.7.6/lib/glut.n64/ObjectType.mk new file mode 100644 index 0000000000..55d0f47555 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut.n64/ObjectType.mk @@ -0,0 +1,3 @@ +LDOPTS = $(LDOPTS_64) +#OPTIMIZER = -O0 +CSTYLE = $(CSTYLE_64) diff --git a/lib/glut-3.7.6/lib/glut/Imakefile b/lib/glut-3.7.6/lib/glut/Imakefile new file mode 100644 index 0000000000..e87a230bd2 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/Imakefile @@ -0,0 +1,174 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#define DoNormalLib YES + +#include + +#include "../../Glut.cf" + +HDRS = \ + glutint.h \ + glutstroke.h \ + layerutil.h + +SRCS = \ + glut_8x13.c \ + glut_9x15.c \ + glut_bitmap.c \ + glut_bwidth.c \ + glut_cindex.c \ + glut_cmap.c \ + glut_cursor.c \ + glut_dials.c \ + glut_dstr.c \ + glut_event.c \ + glut_ext.c \ + glut_fullscrn.c \ + glut_gamemode.c \ + glut_get.c \ + glut_glxext.c \ + glut_hel10.c \ + glut_hel12.c \ + glut_hel18.c \ + glut_init.c \ + glut_input.c \ + glut_joy.c \ + glut_key.c \ + glut_keyctrl.c \ + glut_keyup.c \ + glut_menu.c \ + glut_menu2.c \ + glut_mesa.c \ + glut_modifier.c \ + glut_mroman.c \ + glut_overlay.c \ + glut_roman.c \ + glut_shapes.c \ + glut_space.c \ + glut_stroke.c \ + glut_swap.c \ + glut_swidth.c \ + glut_tablet.c \ + glut_teapot.c \ + glut_tr10.c \ + glut_tr24.c \ + glut_util.c \ + glut_vidresize.c \ + glut_warp.c \ + glut_win.c \ + glut_winmisc.c \ + layerutil.c + +OBJS = \ + glut_8x13.o \ + glut_9x15.o \ + glut_bitmap.o \ + glut_bwidth.o \ + glut_cindex.o \ + glut_cmap.o \ + glut_cursor.o \ + glut_dials.o \ + glut_dstr.o \ + glut_event.o \ + glut_ext.o \ + glut_fullscrn.o \ + glut_gamemode.o \ + glut_get.o \ + glut_glxext.o \ + glut_hel10.o \ + glut_hel12.o \ + glut_hel18.o \ + glut_init.o \ + glut_input.o \ + glut_joy.o \ + glut_key.o \ + glut_keyctrl.o \ + glut_keyup.o \ + glut_menu.o \ + glut_menu2.o \ + glut_mesa.o \ + glut_modifier.o \ + glut_mroman.o \ + glut_overlay.o \ + glut_roman.o \ + glut_shapes.o \ + glut_space.o \ + glut_stroke.o \ + glut_swap.o \ + glut_swidth.o \ + glut_tablet.o \ + glut_teapot.o \ + glut_tr10.o \ + glut_tr24.o \ + glut_util.o \ + glut_vidresize.o \ + glut_warp.o \ + glut_win.o \ + glut_winmisc.o \ + layerutil.o + +#ifdef LibraryObjectRule +LibraryObjectRule() +#else +/* XXX Very lame, you must be using pre-R5 config files! This + will probably do essentially what LibraryObjectRule does. */ +NormalLibraryObjectRule() +#endif + +NormalLibraryTarget(glut,$(OBJS)) + +/* I've gotten too many complaints from people (mostly Linux users) + trying to build GLUT that have problems using lex and yacc to + build the stroke fonts for GLUT so I will simply supply the + generated C stroke fonts files. If you would like to build the + fonts, please uncomment the following define of BuildStrokeFontsWithLex + and regenerate the Makefile. */ + +/* #define BuildStrokeFontsWithLex */ + +#ifdef BuildStrokeFontsWithLex + +# for SGI's parallel make +.ORDER : strokegen.h strokegen.c + +strokegen.h strokegen.c : strokegen.y + $(YACC) -d strokegen.y + $(MV) y.tab.c strokegen.c + $(MV) y.tab.h strokegen.h + +/* XXX Attempt to make up for the lack of lex support in pre-R6 imake + config files. */ +#ifndef LexCmd +#define LexCmd lex +LEX = LexCmd +#endif +#ifndef LexLib +#define LexLib -ll +LEXLIB = LexLib +#endif + +strokelex.c : strokelex.l + $(LEX) strokelex.l + $(MV) lex.yy.c strokelex.c + +strokegen : strokegen.o strokelex.o + $(CC) -o $@ $(CFLAGS) strokegen.o strokelex.o $(LEXLIB) + +glut_roman.c : Roman.stroke strokegen + ./strokegen -s glutStrokeRoman < Roman.stroke > $@ + +glut_mroman.c : MonoRoman.stroke strokegen + ./strokegen -s glutStrokeMonoRoman < MonoRoman.stroke > $@ + +GEN_STROKES = glut_roman.c glut_mroman.c + +depend:: glut_roman.c glut_mroman.c + +#endif /* BuildStrokeFontsWithLex */ + +clean:: + $(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c + $(RM) strokelex.c strokegen.c $(GEN_STROKES) strokegen capturexfont + +DependTarget() diff --git a/lib/glut-3.7.6/lib/glut/MonoRoman.stroke b/lib/glut-3.7.6/lib/glut/MonoRoman.stroke new file mode 100644 index 0000000000..8371044391 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/MonoRoman.stroke @@ -0,0 +1,503 @@ +## +# $XConsortium: Roman_M.src,v 5.2 91/07/21 16:42:40 rws Exp $ +## +## Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. +## +## 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 names of Sun Microsystems, +## the X Consortium, and MIT not be used in advertising or publicity +## pertaining to distribution of the software without specific, written +## prior permission. +## +## SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +## INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +## EVENT SHALL SUN MICROSYSTEMS 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. + +# Mono-spaced version of Roman Simplex font. + + FONTNAME Roman + TOP 119.0476 + BOTTOM -33.3333 + NUM_CH 128 + PROPERTIES 3 + + (CHARSET_REGISTRY ISO8859) + (CHARSET_ENCODING "1") + (SPACING M) + +INDEX 32 STROKE 0 CENTER 52.3810 RIGHT 104.7619 +INDEX 33 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 100.0000) (52.3810 33.3333) + OPEN 5 (52.3810 9.5238) (47.6191 4.7619) (52.3810 0.0000) + (57.1429 4.7619) (52.3810 9.5238) +INDEX 34 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (33.3334 100.0000) (33.3334 66.6667) + OPEN 2 (71.4286 100.0000) (71.4286 66.6667) +INDEX 35 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (54.7619 119.0476) (21.4286 -33.3333) + OPEN 2 (83.3334 119.0476) (50.0000 -33.3333) + OPEN 2 (21.4286 57.1429) (88.0952 57.1429) + OPEN 2 (16.6667 28.5714) (83.3334 28.5714) +INDEX 36 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (42.8571 119.0476) (42.8571 -19.0476) + OPEN 2 (61.9047 119.0476) (61.9047 -19.0476) + OPEN 20 (85.7143 85.7143) (76.1905 95.2381) (61.9047 100.0000) + (42.8571 100.0000) (28.5714 95.2381) (19.0476 85.7143) (19.0476 76.1905) + (23.8095 66.6667) (28.5714 61.9048) (38.0952 57.1429) (66.6666 47.6190) + (76.1905 42.8571) (80.9524 38.0952) (85.7143 28.5714) (85.7143 14.2857) + (76.1905 4.7619) (61.9047 0.0000) (42.8571 0.0000) (28.5714 4.7619) + (19.0476 14.2857) +INDEX 37 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (95.2381 100.0000) (9.5238 0.0000) + OPEN 16 (33.3333 100.0000) (42.8571 90.4762) (42.8571 80.9524) + (38.0952 71.4286) (28.5714 66.6667) (19.0476 66.6667) (9.5238 76.1905) + (9.5238 85.7143) (14.2857 95.2381) (23.8095 100.0000) (33.3333 100.0000) + (42.8571 95.2381) (57.1428 90.4762) (71.4286 90.4762) (85.7143 95.2381) + (95.2381 100.0000) + OPEN 11 (76.1905 33.3333) (66.6667 28.5714) (61.9048 19.0476) + (61.9048 9.5238) (71.4286 0.0000) (80.9524 0.0000) (90.4762 4.7619) + (95.2381 14.2857) (95.2381 23.8095) (85.7143 33.3333) (76.1905 33.3333) +INDEX 38 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 34 (100.0000 57.1429) (100.0000 61.9048) (95.2381 66.6667) + (90.4762 66.6667) (85.7143 61.9048) (80.9524 52.3810) (71.4286 28.5714) + (61.9048 14.2857) (52.3809 4.7619) (42.8571 0.0000) (23.8095 0.0000) + (14.2857 4.7619) (9.5238 9.5238) (4.7619 19.0476) (4.7619 28.5714) + (9.5238 38.0952) (14.2857 42.8571) (47.6190 61.9048) (52.3809 66.6667) + (57.1429 76.1905) (57.1429 85.7143) (52.3809 95.2381) (42.8571 100.0000) + (33.3333 95.2381) (28.5714 85.7143) (28.5714 76.1905) (33.3333 61.9048) + (42.8571 47.6190) (66.6667 14.2857) (76.1905 4.7619) (85.7143 0.0000) + (95.2381 0.0000) (100.0000 4.7619) (100.0000 9.5238) +INDEX 39 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 100.0000) (52.3810 66.6667) +INDEX 40 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (69.0476 119.0476) (59.5238 109.5238) (50.0000 95.2381) + (40.4762 76.1905) (35.7143 52.3810) (35.7143 33.3333) (40.4762 9.5238) + (50.0000 -9.5238) (59.5238 -23.8095) (69.0476 -33.3333) +INDEX 41 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (35.7143 119.0476) (45.2381 109.5238) (54.7619 95.2381) + (64.2857 76.1905) (69.0476 52.3810) (69.0476 33.3333) (64.2857 9.5238) + (54.7619 -9.5238) (45.2381 -23.8095) (35.7143 -33.3333) +INDEX 42 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 71.4286) (52.3810 14.2857) + OPEN 2 (28.5715 57.1429) (76.1905 28.5714) + OPEN 2 (76.1905 57.1429) (28.5715 28.5714) +INDEX 43 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3809 85.7143) (52.3809 0.0000) + OPEN 2 (9.5238 42.8571) (95.2381 42.8571) +INDEX 44 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 8 (57.1429 4.7619) (52.3810 0.0000) (47.6191 4.7619) + (52.3810 9.5238) (57.1429 4.7619) (57.1429 -4.7619) (52.3810 -14.2857) + (47.6191 -19.0476) +INDEX 45 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (9.5238 42.8571) (95.2381 42.8571) +INDEX 46 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (52.3810 9.5238) (47.6191 4.7619) (52.3810 0.0000) + (57.1429 4.7619) (52.3810 9.5238) +INDEX 47 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 -14.2857) (85.7143 100.0000) +INDEX 48 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 17 (47.6190 100.0000) (33.3333 95.2381) (23.8095 80.9524) + (19.0476 57.1429) (19.0476 42.8571) (23.8095 19.0476) (33.3333 4.7619) + (47.6190 0.0000) (57.1428 0.0000) (71.4286 4.7619) (80.9524 19.0476) + (85.7143 42.8571) (85.7143 57.1429) (80.9524 80.9524) (71.4286 95.2381) + (57.1428 100.0000) (47.6190 100.0000) +INDEX 49 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 4 (40.4762 80.9524) (50.0000 85.7143) (64.2857 100.0000) + (64.2857 0.0000) +INDEX 50 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 14 (23.8095 76.1905) (23.8095 80.9524) (28.5714 90.4762) + (33.3333 95.2381) (42.8571 100.0000) (61.9047 100.0000) (71.4286 95.2381) + (76.1905 90.4762) (80.9524 80.9524) (80.9524 71.4286) (76.1905 61.9048) + (66.6666 47.6190) (19.0476 0.0000) (85.7143 0.0000) +INDEX 51 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 15 (28.5714 100.0000) (80.9524 100.0000) (52.3809 61.9048) + (66.6666 61.9048) (76.1905 57.1429) (80.9524 52.3810) (85.7143 38.0952) + (85.7143 28.5714) (80.9524 14.2857) (71.4286 4.7619) (57.1428 0.0000) + (42.8571 0.0000) (28.5714 4.7619) (23.8095 9.5238) (19.0476 19.0476) +INDEX 52 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 3 (64.2857 100.0000) (16.6667 33.3333) (88.0952 33.3333) + OPEN 2 (64.2857 100.0000) (64.2857 0.0000) +INDEX 53 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 17 (76.1905 100.0000) (28.5714 100.0000) (23.8095 57.1429) + (28.5714 61.9048) (42.8571 66.6667) (57.1428 66.6667) (71.4286 61.9048) + (80.9524 52.3810) (85.7143 38.0952) (85.7143 28.5714) (80.9524 14.2857) + (71.4286 4.7619) (57.1428 0.0000) (42.8571 0.0000) (28.5714 4.7619) + (23.8095 9.5238) (19.0476 19.0476) +INDEX 54 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 23 (78.5714 85.7143) (73.8096 95.2381) (59.5238 100.0000) + (50.0000 100.0000) (35.7143 95.2381) (26.1905 80.9524) (21.4286 57.1429) + (21.4286 33.3333) (26.1905 14.2857) (35.7143 4.7619) (50.0000 0.0000) + (54.7619 0.0000) (69.0476 4.7619) (78.5714 14.2857) (83.3334 28.5714) + (83.3334 33.3333) (78.5714 47.6190) (69.0476 57.1429) (54.7619 61.9048) + (50.0000 61.9048) (35.7143 57.1429) (26.1905 47.6190) (21.4286 33.3333) +INDEX 55 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (85.7143 100.0000) (38.0952 0.0000) + OPEN 2 (19.0476 100.0000) (85.7143 100.0000) +INDEX 56 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 29 (42.8571 100.0000) (28.5714 95.2381) (23.8095 85.7143) + (23.8095 76.1905) (28.5714 66.6667) (38.0952 61.9048) (57.1428 57.1429) + (71.4286 52.3810) (80.9524 42.8571) (85.7143 33.3333) (85.7143 19.0476) + (80.9524 9.5238) (76.1905 4.7619) (61.9047 0.0000) (42.8571 0.0000) + (28.5714 4.7619) (23.8095 9.5238) (19.0476 19.0476) (19.0476 33.3333) + (23.8095 42.8571) (33.3333 52.3810) (47.6190 57.1429) (66.6666 61.9048) + (76.1905 66.6667) (80.9524 76.1905) (80.9524 85.7143) (76.1905 95.2381) + (61.9047 100.0000) (42.8571 100.0000) +INDEX 57 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 23 (83.3334 66.6667) (78.5714 52.3810) (69.0476 42.8571) + (54.7619 38.0952) (50.0000 38.0952) (35.7143 42.8571) (26.1905 52.3810) + (21.4286 66.6667) (21.4286 71.4286) (26.1905 85.7143) (35.7143 95.2381) + (50.0000 100.0000) (54.7619 100.0000) (69.0476 95.2381) (78.5714 85.7143) + (83.3334 66.6667) (83.3334 42.8571) (78.5714 19.0476) (69.0476 4.7619) + (54.7619 0.0000) (45.2381 0.0000) (30.9524 4.7619) (26.1905 14.2857) +INDEX 58 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (52.3810 66.6667) (47.6191 61.9048) (52.3810 57.1429) + (57.1429 61.9048) (52.3810 66.6667) + OPEN 5 (52.3810 9.5238) (47.6191 4.7619) (52.3810 0.0000) + (57.1429 4.7619) (52.3810 9.5238) +INDEX 59 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (52.3810 66.6667) (47.6191 61.9048) (52.3810 57.1429) + (57.1429 61.9048) (52.3810 66.6667) + OPEN 8 (57.1429 4.7619) (52.3810 0.0000) (47.6191 4.7619) + (52.3810 9.5238) (57.1429 4.7619) (57.1429 -4.7619) (52.3810 -14.2857) + (47.6191 -19.0476) +INDEX 60 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 3 (90.4762 85.7143) (14.2857 42.8571) (90.4762 0.0000) +INDEX 61 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (9.5238 57.1429) (95.2381 57.1429) + OPEN 2 (9.5238 28.5714) (95.2381 28.5714) +INDEX 62 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 3 (14.2857 85.7143) (90.4762 42.8571) (14.2857 0.0000) +INDEX 63 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 14 (23.8095 76.1905) (23.8095 80.9524) (28.5714 90.4762) + (33.3333 95.2381) (42.8571 100.0000) (61.9047 100.0000) (71.4285 95.2381) + (76.1905 90.4762) (80.9524 80.9524) (80.9524 71.4286) (76.1905 61.9048) + (71.4285 57.1429) (52.3809 47.6190) (52.3809 33.3333) + OPEN 5 (52.3809 9.5238) (47.6190 4.7619) (52.3809 0.0000) + (57.1428 4.7619) (52.3809 9.5238) +INDEX 64 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 8 (64.2857 52.3810) (54.7619 57.1429) (45.2381 57.1429) + (40.4762 47.6190) (40.4762 42.8571) (45.2381 33.3333) (54.7619 33.3333) + (64.2857 38.0952) + OPEN 19 (64.2857 57.1429) (64.2857 38.0952) (69.0476 33.3333) + (78.5714 33.3333) (83.3334 42.8571) (83.3334 47.6190) (78.5714 61.9048) + (69.0476 71.4286) (54.7619 76.1905) (50.0000 76.1905) (35.7143 71.4286) + (26.1905 61.9048) (21.4286 47.6190) (21.4286 42.8571) (26.1905 28.5714) + (35.7143 19.0476) (50.0000 14.2857) (54.7619 14.2857) (69.0476 19.0476) +INDEX 65 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3809 100.0000) (14.2857 0.0000) + OPEN 2 (52.3809 100.0000) (90.4762 0.0000) + OPEN 2 (28.5714 33.3333) (76.1905 33.3333) +INDEX 66 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 9 (19.0476 100.0000) (61.9047 100.0000) (76.1905 95.2381) + (80.9524 90.4762) (85.7143 80.9524) (85.7143 71.4286) (80.9524 61.9048) + (76.1905 57.1429) (61.9047 52.3810) + OPEN 10 (19.0476 52.3810) (61.9047 52.3810) (76.1905 47.6190) + (80.9524 42.8571) (85.7143 33.3333) (85.7143 19.0476) (80.9524 9.5238) + (76.1905 4.7619) (61.9047 0.0000) (19.0476 0.0000) +INDEX 67 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 18 (88.0952 76.1905) (83.3334 85.7143) (73.8096 95.2381) + (64.2857 100.0000) (45.2381 100.0000) (35.7143 95.2381) (26.1905 85.7143) + (21.4286 76.1905) (16.6667 61.9048) (16.6667 38.0952) (21.4286 23.8095) + (26.1905 14.2857) (35.7143 4.7619) (45.2381 0.0000) (64.2857 0.0000) + (73.8096 4.7619) (83.3334 14.2857) (88.0952 23.8095) +INDEX 68 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 12 (19.0476 100.0000) (52.3809 100.0000) (66.6666 95.2381) + (76.1905 85.7143) (80.9524 76.1905) (85.7143 61.9048) (85.7143 38.0952) + (80.9524 23.8095) (76.1905 14.2857) (66.6666 4.7619) (52.3809 0.0000) + (19.0476 0.0000) +INDEX 69 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (21.4286 100.0000) (21.4286 0.0000) + OPEN 2 (21.4286 100.0000) (83.3334 100.0000) + OPEN 2 (21.4286 52.3810) (59.5238 52.3810) + OPEN 2 (21.4286 0.0000) (83.3334 0.0000) +INDEX 70 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (21.4286 100.0000) (21.4286 0.0000) + OPEN 2 (21.4286 100.0000) (83.3334 100.0000) + OPEN 2 (21.4286 52.3810) (59.5238 52.3810) +INDEX 71 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 19 (88.0952 76.1905) (83.3334 85.7143) (73.8096 95.2381) + (64.2857 100.0000) (45.2381 100.0000) (35.7143 95.2381) (26.1905 85.7143) + (21.4286 76.1905) (16.6667 61.9048) (16.6667 38.0952) (21.4286 23.8095) + (26.1905 14.2857) (35.7143 4.7619) (45.2381 0.0000) (64.2857 0.0000) + (73.8096 4.7619) (83.3334 14.2857) (88.0952 23.8095) (88.0952 38.0952) + OPEN 2 (64.2857 38.0952) (88.0952 38.0952) +INDEX 72 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 2 (85.7143 100.0000) (85.7143 0.0000) + OPEN 2 (19.0476 52.3810) (85.7143 52.3810) +INDEX 73 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 100.0000) (52.3810 0.0000) +INDEX 74 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (76.1905 100.0000) (76.1905 23.8095) (71.4286 9.5238) + (66.6667 4.7619) (57.1429 0.0000) (47.6191 0.0000) (38.0953 4.7619) + (33.3334 9.5238) (28.5715 23.8095) (28.5715 33.3333) +INDEX 75 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 2 (85.7143 100.0000) (19.0476 33.3333) + OPEN 2 (42.8571 57.1429) (85.7143 0.0000) +INDEX 76 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (23.8095 100.0000) (23.8095 0.0000) + OPEN 2 (23.8095 0.0000) (80.9524 0.0000) +INDEX 77 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (14.2857 100.0000) (14.2857 0.0000) + OPEN 2 (14.2857 100.0000) (52.3809 0.0000) + OPEN 2 (90.4762 100.0000) (52.3809 0.0000) + OPEN 2 (90.4762 100.0000) (90.4762 0.0000) +INDEX 78 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 2 (19.0476 100.0000) (85.7143 0.0000) + OPEN 2 (85.7143 100.0000) (85.7143 0.0000) +INDEX 79 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 21 (42.8571 100.0000) (33.3333 95.2381) (23.8095 85.7143) + (19.0476 76.1905) (14.2857 61.9048) (14.2857 38.0952) (19.0476 23.8095) + (23.8095 14.2857) (33.3333 4.7619) (42.8571 0.0000) (61.9047 0.0000) + (71.4286 4.7619) (80.9524 14.2857) (85.7143 23.8095) (90.4762 38.0952) + (90.4762 61.9048) (85.7143 76.1905) (80.9524 85.7143) (71.4286 95.2381) + (61.9047 100.0000) (42.8571 100.0000) +INDEX 80 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 10 (19.0476 100.0000) (61.9047 100.0000) (76.1905 95.2381) + (80.9524 90.4762) (85.7143 80.9524) (85.7143 66.6667) (80.9524 57.1429) + (76.1905 52.3810) (61.9047 47.6190) (19.0476 47.6190) +INDEX 81 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 21 (42.8571 100.0000) (33.3333 95.2381) (23.8095 85.7143) + (19.0476 76.1905) (14.2857 61.9048) (14.2857 38.0952) (19.0476 23.8095) + (23.8095 14.2857) (33.3333 4.7619) (42.8571 0.0000) (61.9047 0.0000) + (71.4286 4.7619) (80.9524 14.2857) (85.7143 23.8095) (90.4762 38.0952) + (90.4762 61.9048) (85.7143 76.1905) (80.9524 85.7143) (71.4286 95.2381) + (61.9047 100.0000) (42.8571 100.0000) + OPEN 2 (57.1428 19.0476) (85.7143 -9.5238) +INDEX 82 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (19.0476 0.0000) + OPEN 10 (19.0476 100.0000) (61.9047 100.0000) (76.1905 95.2381) + (80.9524 90.4762) (85.7143 80.9524) (85.7143 71.4286) (80.9524 61.9048) + (76.1905 57.1429) (61.9047 52.3810) (19.0476 52.3810) + OPEN 2 (52.3809 52.3810) (85.7143 0.0000) +INDEX 83 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 20 (85.7143 85.7143) (76.1905 95.2381) (61.9047 100.0000) + (42.8571 100.0000) (28.5714 95.2381) (19.0476 85.7143) (19.0476 76.1905) + (23.8095 66.6667) (28.5714 61.9048) (38.0952 57.1429) (66.6666 47.6190) + (76.1905 42.8571) (80.9524 38.0952) (85.7143 28.5714) (85.7143 14.2857) + (76.1905 4.7619) (61.9047 0.0000) (42.8571 0.0000) (28.5714 4.7619) + (19.0476 14.2857) +INDEX 84 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3809 100.0000) (52.3809 0.0000) + OPEN 2 (19.0476 100.0000) (85.7143 100.0000) +INDEX 85 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (19.0476 100.0000) (19.0476 28.5714) (23.8095 14.2857) + (33.3333 4.7619) (47.6190 0.0000) (57.1428 0.0000) (71.4286 4.7619) + (80.9524 14.2857) (85.7143 28.5714) (85.7143 100.0000) +INDEX 86 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (14.2857 100.0000) (52.3809 0.0000) + OPEN 2 (90.4762 100.0000) (52.3809 0.0000) +INDEX 87 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (4.7619 100.0000) (28.5714 0.0000) + OPEN 2 (52.3809 100.0000) (28.5714 0.0000) + OPEN 2 (52.3809 100.0000) (76.1905 0.0000) + OPEN 2 (100.0000 100.0000) (76.1905 0.0000) +INDEX 88 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (85.7143 0.0000) + OPEN 2 (85.7143 100.0000) (19.0476 0.0000) +INDEX 89 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 3 (14.2857 100.0000) (52.3809 52.3810) (52.3809 0.0000) + OPEN 2 (90.4762 100.0000) (52.3809 52.3810) +INDEX 90 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (85.7143 100.0000) (19.0476 0.0000) + OPEN 2 (19.0476 100.0000) (85.7143 100.0000) + OPEN 2 (19.0476 0.0000) (85.7143 0.0000) +INDEX 91 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (35.7143 119.0476) (35.7143 -33.3333) + OPEN 2 (40.4762 119.0476) (40.4762 -33.3333) + OPEN 2 (35.7143 119.0476) (69.0476 119.0476) + OPEN 2 (35.7143 -33.3333) (69.0476 -33.3333) +INDEX 92 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (19.0476 100.0000) (85.7143 -14.2857) +INDEX 93 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (64.2857 119.0476) (64.2857 -33.3333) + OPEN 2 (69.0476 119.0476) (69.0476 -33.3333) + OPEN 2 (35.7143 119.0476) (69.0476 119.0476) + OPEN 2 (35.7143 -33.3333) (69.0476 -33.3333) +INDEX 94 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3809 109.5238) (14.2857 42.8571) + OPEN 2 (52.3809 109.5238) (90.4762 42.8571) +INDEX 95 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (0.0000 -33.3333) (104.7619 -33.3333) (104.7619 -28.5714) + (0.0000 -28.5714) (0.0000 -33.3333) +INDEX 96 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (42.8572 100.0000) (66.6667 71.4286) + OPEN 3 (42.8572 100.0000) (38.0953 95.2381) (66.6667 71.4286) +INDEX 97 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (80.9524 66.6667) (80.9524 0.0000) + OPEN 14 (80.9524 52.3810) (71.4285 61.9048) (61.9047 66.6667) + (47.6190 66.6667) (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) + (23.8095 28.5714) (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) + (61.9047 0.0000) (71.4285 4.7619) (80.9524 14.2857) +INDEX 98 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (23.8095 100.0000) (23.8095 0.0000) + OPEN 14 (23.8095 52.3810) (33.3333 61.9048) (42.8571 66.6667) + (57.1428 66.6667) (66.6666 61.9048) (76.1905 52.3810) (80.9524 38.0952) + (80.9524 28.5714) (76.1905 14.2857) (66.6666 4.7619) (57.1428 0.0000) + (42.8571 0.0000) (33.3333 4.7619) (23.8095 14.2857) +INDEX 99 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 14 (80.9524 52.3810) (71.4285 61.9048) (61.9047 66.6667) + (47.6190 66.6667) (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) + (23.8095 28.5714) (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) + (61.9047 0.0000) (71.4285 4.7619) (80.9524 14.2857) +INDEX 100 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (80.9524 100.0000) (80.9524 0.0000) + OPEN 14 (80.9524 52.3810) (71.4285 61.9048) (61.9047 66.6667) + (47.6190 66.6667) (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) + (23.8095 28.5714) (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) + (61.9047 0.0000) (71.4285 4.7619) (80.9524 14.2857) +INDEX 101 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 17 (23.8095 38.0952) (80.9524 38.0952) (80.9524 47.6190) + (76.1905 57.1429) (71.4285 61.9048) (61.9047 66.6667) (47.6190 66.6667) + (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) (23.8095 28.5714) + (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) (61.9047 0.0000) + (71.4285 4.7619) (80.9524 14.2857) +INDEX 102 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (71.4286 100.0000) (61.9048 100.0000) (52.3810 95.2381) + (47.6191 80.9524) (47.6191 0.0000) + OPEN 2 (33.3334 66.6667) (66.6667 66.6667) +INDEX 103 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 7 (80.9524 66.6667) (80.9524 -9.5238) (76.1905 -23.8095) + (71.4285 -28.5714) (61.9047 -33.3333) (47.6190 -33.3333) (38.0952 -28.5714) + OPEN 14 (80.9524 52.3810) (71.4285 61.9048) (61.9047 66.6667) + (47.6190 66.6667) (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) + (23.8095 28.5714) (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) + (61.9047 0.0000) (71.4285 4.7619) (80.9524 14.2857) +INDEX 104 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (26.1905 100.0000) (26.1905 0.0000) + OPEN 7 (26.1905 47.6190) (40.4762 61.9048) (50.0000 66.6667) + (64.2857 66.6667) (73.8095 61.9048) (78.5715 47.6190) (78.5715 0.0000) +INDEX 105 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (47.6191 100.0000) (52.3810 95.2381) (57.1429 100.0000) + (52.3810 104.7619) (47.6191 100.0000) + OPEN 2 (52.3810 66.6667) (52.3810 0.0000) +INDEX 106 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (57.1429 100.0000) (61.9048 95.2381) (66.6667 100.0000) + (61.9048 104.7619) (57.1429 100.0000) + OPEN 5 (61.9048 66.6667) (61.9048 -14.2857) (57.1429 -28.5714) + (47.6191 -33.3333) (38.0953 -33.3333) +INDEX 107 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (26.1905 100.0000) (26.1905 0.0000) + OPEN 2 (73.8095 66.6667) (26.1905 19.0476) + OPEN 2 (45.2381 38.0952) (78.5715 0.0000) +INDEX 108 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 100.0000) (52.3810 0.0000) +INDEX 109 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) + OPEN 7 (52.3810 47.6190) (66.6667 61.9048) (76.1905 66.6667) + (90.4762 66.6667) (100.0000 61.9048) (104.7619 47.6190) (104.7619 0.0000) +INDEX 110 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (26.1905 66.6667) (26.1905 0.0000) + OPEN 7 (26.1905 47.6190) (40.4762 61.9048) (50.0000 66.6667) + (64.2857 66.6667) (73.8095 61.9048) (78.5715 47.6190) (78.5715 0.0000) +INDEX 111 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 17 (45.2381 66.6667) (35.7143 61.9048) (26.1905 52.3810) + (21.4286 38.0952) (21.4286 28.5714) (26.1905 14.2857) (35.7143 4.7619) + (45.2381 0.0000) (59.5238 0.0000) (69.0476 4.7619) (78.5714 14.2857) + (83.3334 28.5714) (83.3334 38.0952) (78.5714 52.3810) (69.0476 61.9048) + (59.5238 66.6667) (45.2381 66.6667) +INDEX 112 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (23.8095 66.6667) (23.8095 -33.3333) + OPEN 14 (23.8095 52.3810) (33.3333 61.9048) (42.8571 66.6667) + (57.1428 66.6667) (66.6666 61.9048) (76.1905 52.3810) (80.9524 38.0952) + (80.9524 28.5714) (76.1905 14.2857) (66.6666 4.7619) (57.1428 0.0000) + (42.8571 0.0000) (33.3333 4.7619) (23.8095 14.2857) +INDEX 113 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (80.9524 66.6667) (80.9524 -33.3333) + OPEN 14 (80.9524 52.3810) (71.4285 61.9048) (61.9047 66.6667) + (47.6190 66.6667) (38.0952 61.9048) (28.5714 52.3810) (23.8095 38.0952) + (23.8095 28.5714) (28.5714 14.2857) (38.0952 4.7619) (47.6190 0.0000) + (61.9047 0.0000) (71.4285 4.7619) (80.9524 14.2857) +INDEX 114 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (33.3334 66.6667) (33.3334 0.0000) + OPEN 5 (33.3334 38.0952) (38.0953 52.3810) (47.6191 61.9048) + (57.1429 66.6667) (71.4286 66.6667) +INDEX 115 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 17 (78.5715 52.3810) (73.8095 61.9048) (59.5238 66.6667) + (45.2381 66.6667) (30.9524 61.9048) (26.1905 52.3810) (30.9524 42.8571) + (40.4762 38.0952) (64.2857 33.3333) (73.8095 28.5714) (78.5715 19.0476) + (78.5715 14.2857) (73.8095 4.7619) (59.5238 0.0000) (45.2381 0.0000) + (30.9524 4.7619) (26.1905 14.2857) +INDEX 116 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (47.6191 100.0000) (47.6191 19.0476) (52.3810 4.7619) + (61.9048 0.0000) (71.4286 0.0000) + OPEN 2 (33.3334 66.6667) (66.6667 66.6667) +INDEX 117 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 7 (26.1905 66.6667) (26.1905 19.0476) (30.9524 4.7619) + (40.4762 0.0000) (54.7619 0.0000) (64.2857 4.7619) (78.5715 19.0476) + OPEN 2 (78.5715 66.6667) (78.5715 0.0000) +INDEX 118 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (23.8095 66.6667) (52.3809 0.0000) + OPEN 2 (80.9524 66.6667) (52.3809 0.0000) +INDEX 119 STROKE 4 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (14.2857 66.6667) (33.3333 0.0000) + OPEN 2 (52.3809 66.6667) (33.3333 0.0000) + OPEN 2 (52.3809 66.6667) (71.4286 0.0000) + OPEN 2 (90.4762 66.6667) (71.4286 0.0000) +INDEX 120 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (26.1905 66.6667) (78.5715 0.0000) + OPEN 2 (78.5715 66.6667) (26.1905 0.0000) +INDEX 121 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (26.1905 66.6667) (54.7619 0.0000) + OPEN 6 (83.3334 66.6667) (54.7619 0.0000) (45.2381 -19.0476) + (35.7143 -28.5714) (26.1905 -33.3333) (21.4286 -33.3333) +INDEX 122 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (78.5715 66.6667) (26.1905 0.0000) + OPEN 2 (26.1905 66.6667) (78.5715 66.6667) + OPEN 2 (26.1905 0.0000) (78.5715 0.0000) +INDEX 123 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (64.2857 119.0476) (54.7619 114.2857) (50.0000 109.5238) + (45.2381 100.0000) (45.2381 90.4762) (50.0000 80.9524) (54.7619 76.1905) + (59.5238 66.6667) (59.5238 57.1429) (50.0000 47.6190) + OPEN 17 (54.7619 114.2857) (50.0000 104.7619) (50.0000 95.2381) + (54.7619 85.7143) (59.5238 80.9524) (64.2857 71.4286) (64.2857 61.9048) + (59.5238 52.3810) (40.4762 42.8571) (59.5238 33.3333) (64.2857 23.8095) + (64.2857 14.2857) (59.5238 4.7619) (54.7619 0.0000) (50.0000 -9.5238) + (50.0000 -19.0476) (54.7619 -28.5714) + OPEN 10 (50.0000 38.0952) (59.5238 28.5714) (59.5238 19.0476) + (54.7619 9.5238) (50.0000 4.7619) (45.2381 -4.7619) (45.2381 -14.2857) + (50.0000 -23.8095) (54.7619 -28.5714) (64.2857 -33.3333) +INDEX 124 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (52.3810 119.0476) (52.3810 -33.3333) +INDEX 125 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 10 (40.4762 119.0476) (50.0000 114.2857) (54.7619 109.5238) + (59.5238 100.0000) (59.5238 90.4762) (54.7619 80.9524) (50.0000 76.1905) + (45.2381 66.6667) (45.2381 57.1429) (54.7619 47.6190) + OPEN 17 (50.0000 114.2857) (54.7619 104.7619) (54.7619 95.2381) + (50.0000 85.7143) (45.2381 80.9524) (40.4762 71.4286) (40.4762 61.9048) + (45.2381 52.3810) (64.2857 42.8571) (45.2381 33.3333) (40.4762 23.8095) + (40.4762 14.2857) (45.2381 4.7619) (50.0000 0.0000) (54.7619 -9.5238) + (54.7619 -19.0476) (50.0000 -28.5714) + OPEN 10 (54.7619 38.0952) (45.2381 28.5714) (45.2381 19.0476) + (50.0000 9.5238) (54.7619 4.7619) (59.5238 -4.7619) (59.5238 -14.2857) + (54.7619 -23.8095) (50.0000 -28.5714) (40.4762 -33.3333) +INDEX 126 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 11 (9.5238 28.5714) (9.5238 38.0952) (14.2857 52.3810) + (23.8095 57.1429) (33.3333 57.1429) (42.8571 52.3810) (61.9048 38.0952) + (71.4286 33.3333) (80.9524 33.3333) (90.4762 38.0952) (95.2381 47.6190) + OPEN 11 (9.5238 38.0952) (14.2857 47.6190) (23.8095 52.3810) + (33.3333 52.3810) (42.8571 47.6190) (61.9048 33.3333) (71.4286 28.5714) + (80.9524 28.5714) (90.4762 33.3333) (95.2381 47.6190) (95.2381 57.1429) +INDEX 127 STROKE 2 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (71.4286 100.0000) (33.3333 -33.3333) + OPEN 17 (47.6190 66.6667) (33.3333 61.9048) (23.8095 52.3810) + (19.0476 38.0952) (19.0476 23.8095) (23.8095 14.2857) (33.3333 4.7619) + (47.6190 0.0000) (57.1428 0.0000) (71.4286 4.7619) (80.9524 14.2857) + (85.7143 28.5714) (85.7143 42.8571) (80.9524 52.3810) (71.4286 61.9048) + (57.1428 66.6667) (47.6190 66.6667) diff --git a/lib/glut-3.7.6/lib/glut/ObjectType.mk b/lib/glut-3.7.6/lib/glut/ObjectType.mk new file mode 100644 index 0000000000..f94dc77f5f --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_32) +CSTYLE = $(CSTYLE_32) diff --git a/lib/glut-3.7.6/lib/glut/Roman.stroke b/lib/glut-3.7.6/lib/glut/Roman.stroke new file mode 100644 index 0000000000..6defa76ac2 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/Roman.stroke @@ -0,0 +1,604 @@ +## +# $XConsortium: Roman.src,v 5.2 91/07/21 16:42:23 rws Exp $ +## +## Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. +## +## 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 names of Sun Microsystems, +## the X Consortium, and MIT not be used in advertising or publicity +## pertaining to distribution of the software without specific, written +## prior permission. +## +## SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +## INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +## EVENT SHALL SUN MICROSYSTEMS 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. + +# Roman Simplex font. + + FONTNAME Roman + TOP 119.0476 + BOTTOM -33.3333 + NUM_CH 128 + PROPERTIES 3 + + (CHARSET_REGISTRY ISO8859) + (CHARSET_ENCODING "1") + (SPACING P) + +INDEX 32 STROKE 0 CENTER 52.3810 RIGHT 104.7619 +INDEX 33 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 2 (4.7619 100.0000) (4.7619 33.3333) + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 34 STROKE 2 CENTER 19.0476 RIGHT 38.0952 + OPEN 2 (0.0000 100.0000) (0.0000 66.6667) + OPEN 2 (38.0952 100.0000) (38.0952 66.6667) +INDEX 35 STROKE 4 CENTER 33.3333 RIGHT 71.4286 + OPEN 2 (38.0952 119.0476) (4.7619 -33.3333) + OPEN 2 (66.6667 119.0476) (33.3333 -33.3333) + OPEN 2 (4.7619 57.1429) (71.4286 57.1429) + OPEN 2 (0.0000 28.5714) (66.6667 28.5714) +INDEX 36 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (23.8095 119.0476) (23.8095 -19.0476) + OPEN 2 (42.8571 119.0476) (42.8571 -19.0476) + OPEN 20 (66.6667 85.7143) (57.1429 95.2381) (42.8571 100.0000) + (23.8095 100.0000) (9.5238 95.2381) (0.0000 85.7143) (0.0000 76.1905) + (4.7619 66.6667) (9.5238 61.9048) (19.0476 57.1429) (47.6190 47.6190) + (57.1429 42.8571) (61.9048 38.0952) (66.6667 28.5714) (66.6667 14.2857) + (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (0.0000 14.2857) +INDEX 37 STROKE 3 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (85.7143 100.0000) (0.0000 0.0000) + OPEN 16 (23.8095 100.0000) (33.3333 90.4762) (33.3333 80.9524) + (28.5714 71.4286) (19.0476 66.6667) (9.5238 66.6667) (0.0000 76.1905) + (0.0000 85.7143) (4.7619 95.2381) (14.2857 100.0000) (23.8095 100.0000) + (33.3333 95.2381) (47.6190 90.4762) (61.9048 90.4762) (76.1905 95.2381) + (85.7143 100.0000) + OPEN 11 (66.6667 33.3333) (57.1429 28.5714) (52.3810 19.0476) + (52.3810 9.5238) (61.9048 0.0000) (71.4286 0.0000) (80.9524 4.7619) + (85.7143 14.2857) (85.7143 23.8095) (76.1905 33.3333) (66.6667 33.3333) +INDEX 38 STROKE 1 CENTER 47.6190 RIGHT 95.2381 + OPEN 34 (95.2381 57.1429) (95.2381 61.9048) (90.4762 66.6667) + (85.7143 66.6667) (80.9524 61.9048) (76.1905 52.3810) (66.6667 28.5714) + (57.1429 14.2857) (47.6190 4.7619) (38.0952 0.0000) (19.0476 0.0000) + (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) (0.0000 28.5714) + (4.7619 38.0952) (9.5238 42.8571) (42.8571 61.9048) (47.6190 66.6667) + (52.3810 76.1905) (52.3810 85.7143) (47.6190 95.2381) (38.0952 100.0000) + (28.5714 95.2381) (23.8095 85.7143) (23.8095 76.1905) (28.5714 61.9048) + (38.0952 47.6190) (61.9048 14.2857) (71.4286 4.7619) (80.9524 0.0000) + (90.4762 0.0000) (95.2381 4.7619) (95.2381 9.5238) +INDEX 39 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 66.6667) +INDEX 40 STROKE 1 CENTER 14.2857 RIGHT 33.3333 + OPEN 10 (33.3333 119.0476) (23.8095 109.5238) (14.2857 95.2381) + (4.7619 76.1905) (0.0000 52.3810) (0.0000 33.3333) (4.7619 9.5238) + (14.2857 -9.5238) (23.8095 -23.8095) (33.3333 -33.3333) +INDEX 41 STROKE 1 CENTER 19.0476 RIGHT 33.3333 + OPEN 10 (0.0000 119.0476) (9.5238 109.5238) (19.0476 95.2381) + (28.5714 76.1905) (33.3333 52.3810) (33.3333 33.3333) (28.5714 9.5238) + (19.0476 -9.5238) (9.5238 -23.8095) (0.0000 -33.3333) +INDEX 42 STROKE 3 CENTER 23.8095 RIGHT 47.6190 + OPEN 2 (23.8095 71.4286) (23.8095 14.2857) + OPEN 2 (0.0000 57.1429) (47.6190 28.5714) + OPEN 2 (47.6190 57.1429) (0.0000 28.5714) +INDEX 43 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (42.8571 85.7143) (42.8571 0.0000) + OPEN 2 (0.0000 42.8571) (85.7143 42.8571) +INDEX 44 STROKE 1 CENTER 4.7619 RIGHT 9.5238 + OPEN 8 (9.5238 4.7619) (4.7619 0.0000) (0.0000 4.7619) + (4.7619 9.5238) (9.5238 4.7619) (9.5238 -4.7619) (4.7619 -14.2857) + (0.0000 -19.0476) +INDEX 45 STROKE 1 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (0.0000 42.8571) (85.7143 42.8571) +INDEX 46 STROKE 1 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 47 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 -14.2857) (66.6667 100.0000) +INDEX 48 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 17 (28.5714 100.0000) (14.2857 95.2381) (4.7619 80.9524) + (0.0000 57.1429) (0.0000 42.8571) (4.7619 19.0476) (14.2857 4.7619) + (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) (61.9048 19.0476) + (66.6667 42.8571) (66.6667 57.1429) (61.9048 80.9524) (52.3810 95.2381) + (38.0952 100.0000) (28.5714 100.0000) +INDEX 49 STROKE 1 CENTER 19.0476 RIGHT 23.8095 + OPEN 4 (0.0000 80.9524) (9.5238 85.7143) (23.8095 100.0000) + (23.8095 0.0000) +INDEX 50 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 14 (4.7619 76.1905) (4.7619 80.9524) (9.5238 90.4762) + (14.2857 95.2381) (23.8095 100.0000) (42.8571 100.0000) (52.3810 95.2381) + (57.1429 90.4762) (61.9048 80.9524) (61.9048 71.4286) (57.1429 61.9048) + (47.6190 47.6190) (0.0000 0.0000) (66.6667 0.0000) +INDEX 51 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 15 (9.5238 100.0000) (61.9048 100.0000) (33.3333 61.9048) + (47.6190 61.9048) (57.1429 57.1429) (61.9048 52.3810) (66.6667 38.0952) + (66.6667 28.5714) (61.9048 14.2857) (52.3810 4.7619) (38.0952 0.0000) + (23.8095 0.0000) (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) +INDEX 52 STROKE 2 CENTER 33.3333 RIGHT 71.4286 + OPEN 3 (47.6190 100.0000) (0.0000 33.3333) (71.4286 33.3333) + OPEN 2 (47.6190 100.0000) (47.6190 0.0000) +INDEX 53 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 17 (57.1429 100.0000) (9.5238 100.0000) (4.7619 57.1429) + (9.5238 61.9048) (23.8095 66.6667) (38.0952 66.6667) (52.3810 61.9048) + (61.9048 52.3810) (66.6667 38.0952) (66.6667 28.5714) (61.9048 14.2857) + (52.3810 4.7619) (38.0952 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (4.7619 9.5238) (0.0000 19.0476) +INDEX 54 STROKE 1 CENTER 28.5714 RIGHT 61.9048 + OPEN 23 (57.1429 85.7143) (52.3810 95.2381) (38.0952 100.0000) + (28.5714 100.0000) (14.2857 95.2381) (4.7619 80.9524) (0.0000 57.1429) + (0.0000 33.3333) (4.7619 14.2857) (14.2857 4.7619) (28.5714 0.0000) + (33.3333 0.0000) (47.6190 4.7619) (57.1429 14.2857) (61.9048 28.5714) + (61.9048 33.3333) (57.1429 47.6190) (47.6190 57.1429) (33.3333 61.9048) + (28.5714 61.9048) (14.2857 57.1429) (4.7619 47.6190) (0.0000 33.3333) +INDEX 55 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (66.6667 100.0000) (19.0476 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) +INDEX 56 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 29 (23.8095 100.0000) (9.5238 95.2381) (4.7619 85.7143) + (4.7619 76.1905) (9.5238 66.6667) (19.0476 61.9048) (38.0952 57.1429) + (52.3810 52.3810) (61.9048 42.8571) (66.6667 33.3333) (66.6667 19.0476) + (61.9048 9.5238) (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) + (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) (0.0000 33.3333) + (4.7619 42.8571) (14.2857 52.3810) (28.5714 57.1429) (47.6190 61.9048) + (57.1429 66.6667) (61.9048 76.1905) (61.9048 85.7143) (57.1429 95.2381) + (42.8571 100.0000) (23.8095 100.0000) +INDEX 57 STROKE 1 CENTER 33.3333 RIGHT 61.9048 + OPEN 23 (61.9048 66.6667) (57.1429 52.3810) (47.6190 42.8571) + (33.3333 38.0952) (28.5714 38.0952) (14.2857 42.8571) (4.7619 52.3810) + (0.0000 66.6667) (0.0000 71.4286) (4.7619 85.7143) (14.2857 95.2381) + (28.5714 100.0000) (33.3333 100.0000) (47.6190 95.2381) (57.1429 85.7143) + (61.9048 66.6667) (61.9048 42.8571) (57.1429 19.0476) (47.6190 4.7619) + (33.3333 0.0000) (23.8095 0.0000) (9.5238 4.7619) (4.7619 14.2857) +INDEX 58 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 66.6667) (0.0000 61.9048) (4.7619 57.1429) + (9.5238 61.9048) (4.7619 66.6667) + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 59 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 66.6667) (0.0000 61.9048) (4.7619 57.1429) + (9.5238 61.9048) (4.7619 66.6667) + OPEN 8 (9.5238 4.7619) (4.7619 0.0000) (0.0000 4.7619) + (4.7619 9.5238) (9.5238 4.7619) (9.5238 -4.7619) (4.7619 -14.2857) + (0.0000 -19.0476) +INDEX 60 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (76.1905 85.7143) (0.0000 42.8571) (76.1905 0.0000) +INDEX 61 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (0.0000 57.1429) (85.7143 57.1429) + OPEN 2 (0.0000 28.5714) (85.7143 28.5714) +INDEX 62 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (0.0000 85.7143) (76.1905 42.8571) (0.0000 0.0000) +INDEX 63 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 14 (0.0000 76.1905) (0.0000 80.9524) (4.7619 90.4762) + (9.5238 95.2381) (19.0476 100.0000) (38.0952 100.0000) (47.6190 95.2381) + (52.3810 90.4762) (57.1429 80.9524) (57.1429 71.4286) (52.3810 61.9048) + (47.6190 57.1429) (28.5714 47.6190) (28.5714 33.3333) + OPEN 5 (28.5714 9.5238) (23.8095 4.7619) (28.5714 0.0000) + (33.3333 4.7619) (28.5714 9.5238) +INDEX 64 STROKE 2 CENTER 28.5714 RIGHT 61.9048 + OPEN 8 (42.8571 52.3810) (33.3333 57.1429) (23.8095 57.1429) + (19.0476 47.6190) (19.0476 42.8571) (23.8095 33.3333) (33.3333 33.3333) + (42.8571 38.0952) + OPEN 19 (42.8571 57.1429) (42.8571 38.0952) (47.6190 33.3333) + (57.1429 33.3333) (61.9048 42.8571) (61.9048 47.6190) (57.1429 61.9048) + (47.6190 71.4286) (33.3333 76.1905) (28.5714 76.1905) (14.2857 71.4286) + (4.7619 61.9048) (0.0000 47.6190) (0.0000 42.8571) (4.7619 28.5714) + (14.2857 19.0476) (28.5714 14.2857) (33.3333 14.2857) (47.6190 19.0476) +INDEX 65 STROKE 3 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (38.0952 100.0000) (0.0000 0.0000) + OPEN 2 (38.0952 100.0000) (76.1905 0.0000) + OPEN 2 (14.2857 33.3333) (61.9048 33.3333) +INDEX 66 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 9 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 71.4286) (61.9048 61.9048) + (57.1429 57.1429) (42.8571 52.3810) + OPEN 10 (0.0000 52.3810) (42.8571 52.3810) (57.1429 47.6190) + (61.9048 42.8571) (66.6667 33.3333) (66.6667 19.0476) (61.9048 9.5238) + (57.1429 4.7619) (42.8571 0.0000) (0.0000 0.0000) +INDEX 67 STROKE 1 CENTER 33.3333 RIGHT 71.4286 + OPEN 18 (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) +INDEX 68 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 12 (0.0000 100.0000) (33.3333 100.0000) (47.6190 95.2381) + (57.1429 85.7143) (61.9048 76.1905) (66.6667 61.9048) (66.6667 38.0952) + (61.9048 23.8095) (57.1429 14.2857) (47.6190 4.7619) (33.3333 0.0000) + (0.0000 0.0000) +INDEX 69 STROKE 4 CENTER 28.5714 RIGHT 61.9048 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (61.9048 100.0000) + OPEN 2 (0.0000 52.3810) (38.0952 52.3810) + OPEN 2 (0.0000 0.0000) (61.9048 0.0000) +INDEX 70 STROKE 3 CENTER 28.5714 RIGHT 61.9048 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (61.9048 100.0000) + OPEN 2 (0.0000 52.3810) (38.0952 52.3810) +INDEX 71 STROKE 2 CENTER 33.3333 RIGHT 71.4286 + OPEN 19 (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (71.4286 38.0952) + OPEN 2 (47.6190 38.0952) (71.4286 38.0952) +INDEX 72 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (66.6667 100.0000) (66.6667 0.0000) + OPEN 2 (0.0000 52.3810) (66.6667 52.3810) +INDEX 73 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) +INDEX 74 STROKE 1 CENTER 28.5714 RIGHT 47.6190 + OPEN 10 (47.6190 100.0000) (47.6190 23.8095) (42.8571 9.5238) + (38.0952 4.7619) (28.5714 0.0000) (19.0476 0.0000) (9.5238 4.7619) + (4.7619 9.5238) (0.0000 23.8095) (0.0000 33.3333) +INDEX 75 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (66.6667 100.0000) (0.0000 33.3333) + OPEN 2 (23.8095 57.1429) (66.6667 0.0000) +INDEX 76 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 0.0000) (57.1429 0.0000) +INDEX 77 STROKE 4 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (76.1905 0.0000) +INDEX 78 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 0.0000) + OPEN 2 (66.6667 100.0000) (66.6667 0.0000) +INDEX 79 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 21 (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (76.1905 38.0952) + (76.1905 61.9048) (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) +INDEX 80 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 10 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 66.6667) (61.9048 57.1429) + (57.1429 52.3810) (42.8571 47.6190) (0.0000 47.6190) +INDEX 81 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 21 (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (76.1905 38.0952) + (76.1905 61.9048) (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) + OPEN 2 (42.8571 19.0476) (71.4286 -9.5238) +INDEX 82 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 10 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 71.4286) (61.9048 61.9048) + (57.1429 57.1429) (42.8571 52.3810) (0.0000 52.3810) + OPEN 2 (33.3333 52.3810) (66.6667 0.0000) +INDEX 83 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 20 (66.6667 85.7143) (57.1429 95.2381) (42.8571 100.0000) + (23.8095 100.0000) (9.5238 95.2381) (0.0000 85.7143) (0.0000 76.1905) + (4.7619 66.6667) (9.5238 61.9048) (19.0476 57.1429) (47.6190 47.6190) + (57.1429 42.8571) (61.9048 38.0952) (66.6667 28.5714) (66.6667 14.2857) + (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (0.0000 14.2857) +INDEX 84 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (33.3333 100.0000) (33.3333 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) +INDEX 85 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 10 (0.0000 100.0000) (0.0000 28.5714) (4.7619 14.2857) + (14.2857 4.7619) (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) + (61.9048 14.2857) (66.6667 28.5714) (66.6667 100.0000) +INDEX 86 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 0.0000) +INDEX 87 STROKE 4 CENTER 47.6190 RIGHT 95.2381 + OPEN 2 (0.0000 100.0000) (23.8095 0.0000) + OPEN 2 (47.6190 100.0000) (23.8095 0.0000) + OPEN 2 (47.6190 100.0000) (71.4286 0.0000) + OPEN 2 (95.2381 100.0000) (71.4286 0.0000) +INDEX 88 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (66.6667 0.0000) + OPEN 2 (66.6667 100.0000) (0.0000 0.0000) +INDEX 89 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (0.0000 100.0000) (38.0952 52.3810) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 52.3810) +INDEX 90 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (66.6667 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) + OPEN 2 (0.0000 0.0000) (66.6667 0.0000) +INDEX 91 STROKE 4 CENTER 14.2857 RIGHT 33.3333 + OPEN 2 (0.0000 119.0476) (0.0000 -33.3333) + OPEN 2 (4.7619 119.0476) (4.7619 -33.3333) + OPEN 2 (0.0000 119.0476) (33.3333 119.0476) + OPEN 2 (0.0000 -33.3333) (33.3333 -33.3333) +INDEX 92 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (66.6667 -14.2857) +INDEX 93 STROKE 4 CENTER 19.0476 RIGHT 33.3333 + OPEN 2 (28.5714 119.0476) (28.5714 -33.3333) + OPEN 2 (33.3333 119.0476) (33.3333 -33.3333) + OPEN 2 (0.0000 119.0476) (33.3333 119.0476) + OPEN 2 (0.0000 -33.3333) (33.3333 -33.3333) +INDEX 94 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (38.0952 109.5238) (0.0000 42.8571) + OPEN 2 (38.0952 109.5238) (76.1905 42.8571) +INDEX 95 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (0.0000 -33.3333) (104.7619 -33.3333) (104.7619 -28.5714) + (0.0000 -28.5714) (0.0000 -33.3333) +INDEX 96 STROKE 2 CENTER 14.2857 RIGHT 28.5714 + OPEN 2 (4.7619 100.0000) (28.5714 71.4286) + OPEN 3 (4.7619 100.0000) (0.0000 95.2381) (28.5714 71.4286) +INDEX 97 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 66.6667) (57.1429 0.0000) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 98 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 14 (0.0000 52.3810) (9.5238 61.9048) (19.0476 66.6667) + (33.3333 66.6667) (42.8571 61.9048) (52.3810 52.3810) (57.1429 38.0952) + (57.1429 28.5714) (52.3810 14.2857) (42.8571 4.7619) (33.3333 0.0000) + (19.0476 0.0000) (9.5238 4.7619) (0.0000 14.2857) +INDEX 99 STROKE 1 CENTER 28.5714 RIGHT 57.1429 + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 100 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 100.0000) (57.1429 0.0000) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 101 STROKE 1 CENTER 28.5714 RIGHT 57.1429 + OPEN 17 (0.0000 38.0952) (57.1429 38.0952) (57.1429 47.6190) + (52.3810 57.1429) (47.6190 61.9048) (38.0952 66.6667) (23.8095 66.6667) + (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) (0.0000 28.5714) + (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) (38.0952 0.0000) + (47.6190 4.7619) (57.1429 14.2857) +INDEX 102 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 5 (38.0952 100.0000) (28.5714 100.0000) (19.0476 95.2381) + (14.2857 80.9524) (14.2857 0.0000) + OPEN 2 (0.0000 66.6667) (33.3333 66.6667) +INDEX 103 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 7 (57.1429 66.6667) (57.1429 -9.5238) (52.3810 -23.8095) + (47.6190 -28.5714) (38.0952 -33.3333) (23.8095 -33.3333) (14.2857 -28.5714) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 104 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) +INDEX 105 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (0.0000 100.0000) (4.7619 95.2381) (9.5238 100.0000) + (4.7619 104.7619) (0.0000 100.0000) + OPEN 2 (4.7619 66.6667) (4.7619 0.0000) +INDEX 106 STROKE 2 CENTER 19.0476 RIGHT 28.5714 + OPEN 5 (19.0476 100.0000) (23.8095 95.2381) (28.5714 100.0000) + (23.8095 104.7619) (19.0476 100.0000) + OPEN 5 (23.8095 66.6667) (23.8095 -14.2857) (19.0476 -28.5714) + (9.5238 -33.3333) (0.0000 -33.3333) +INDEX 107 STROKE 3 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (47.6190 66.6667) (0.0000 19.0476) + OPEN 2 (19.0476 38.0952) (52.3810 0.0000) +INDEX 108 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) +INDEX 109 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) + OPEN 7 (52.3810 47.6190) (66.6667 61.9048) (76.1905 66.6667) + (90.4762 66.6667) (100.0000 61.9048) (104.7619 47.6190) (104.7619 0.0000) +INDEX 110 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) +INDEX 111 STROKE 1 CENTER 28.5714 RIGHT 61.9048 + OPEN 17 (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) + (0.0000 38.0952) (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) + (23.8095 0.0000) (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) + (61.9048 28.5714) (61.9048 38.0952) (57.1429 52.3810) (47.6190 61.9048) + (38.0952 66.6667) (23.8095 66.6667) +INDEX 112 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 66.6667) (0.0000 -33.3333) + OPEN 14 (0.0000 52.3810) (9.5238 61.9048) (19.0476 66.6667) + (33.3333 66.6667) (42.8571 61.9048) (52.3810 52.3810) (57.1429 38.0952) + (57.1429 28.5714) (52.3810 14.2857) (42.8571 4.7619) (33.3333 0.0000) + (19.0476 0.0000) (9.5238 4.7619) (0.0000 14.2857) +INDEX 113 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 66.6667) (57.1429 -33.3333) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 114 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 5 (0.0000 38.0952) (4.7619 52.3810) (14.2857 61.9048) + (23.8095 66.6667) (38.0952 66.6667) +INDEX 115 STROKE 1 CENTER 23.8095 RIGHT 52.3810 + OPEN 17 (52.3810 52.3810) (47.6190 61.9048) (33.3333 66.6667) + (19.0476 66.6667) (4.7619 61.9048) (0.0000 52.3810) (4.7619 42.8571) + (14.2857 38.0952) (38.0952 33.3333) (47.6190 28.5714) (52.3810 19.0476) + (52.3810 14.2857) (47.6190 4.7619) (33.3333 0.0000) (19.0476 0.0000) + (4.7619 4.7619) (0.0000 14.2857) +INDEX 116 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 5 (14.2857 100.0000) (14.2857 19.0476) (19.0476 4.7619) + (28.5714 0.0000) (38.0952 0.0000) + OPEN 2 (0.0000 66.6667) (33.3333 66.6667) +INDEX 117 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 7 (0.0000 66.6667) (0.0000 19.0476) (4.7619 4.7619) + (14.2857 0.0000) (28.5714 0.0000) (38.0952 4.7619) (52.3810 19.0476) + OPEN 2 (52.3810 66.6667) (52.3810 0.0000) +INDEX 118 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 66.6667) (28.5714 0.0000) + OPEN 2 (57.1429 66.6667) (28.5714 0.0000) +INDEX 119 STROKE 4 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 66.6667) (19.0476 0.0000) + OPEN 2 (38.0952 66.6667) (19.0476 0.0000) + OPEN 2 (38.0952 66.6667) (57.1429 0.0000) + OPEN 2 (76.1905 66.6667) (57.1429 0.0000) +INDEX 120 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 66.6667) (52.3810 0.0000) + OPEN 2 (52.3810 66.6667) (0.0000 0.0000) +INDEX 121 STROKE 2 CENTER 33.3333 RIGHT 61.9048 + OPEN 2 (4.7619 66.6667) (33.3333 0.0000) + OPEN 6 (61.9048 66.6667) (33.3333 0.0000) (23.8095 -19.0476) + (14.2857 -28.5714) (4.7619 -33.3333) (0.0000 -33.3333) +INDEX 122 STROKE 3 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (52.3810 66.6667) (0.0000 0.0000) + OPEN 2 (0.0000 66.6667) (52.3810 66.6667) + OPEN 2 (0.0000 0.0000) (52.3810 0.0000) +INDEX 123 STROKE 3 CENTER 14.2857 RIGHT 23.8095 + OPEN 10 (23.8095 119.0476) (14.2857 114.2857) (9.5238 109.5238) + (4.7619 100.0000) (4.7619 90.4762) (9.5238 80.9524) (14.2857 76.1905) + (19.0476 66.6667) (19.0476 57.1429) (9.5238 47.6190) + OPEN 17 (14.2857 114.2857) (9.5238 104.7619) (9.5238 95.2381) + (14.2857 85.7143) (19.0476 80.9524) (23.8095 71.4286) (23.8095 61.9048) + (19.0476 52.3810) (0.0000 42.8571) (19.0476 33.3333) (23.8095 23.8095) + (23.8095 14.2857) (19.0476 4.7619) (14.2857 0.0000) (9.5238 -9.5238) + (9.5238 -19.0476) (14.2857 -28.5714) + OPEN 10 (9.5238 38.0952) (19.0476 28.5714) (19.0476 19.0476) + (14.2857 9.5238) (9.5238 4.7619) (4.7619 -4.7619) (4.7619 -14.2857) + (9.5238 -23.8095) (14.2857 -28.5714) (23.8095 -33.3333) +INDEX 124 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 119.0476) (0.0000 -33.3333) +INDEX 125 STROKE 3 CENTER 9.5238 RIGHT 23.8095 + OPEN 10 (0.0000 119.0476) (9.5238 114.2857) (14.2857 109.5238) + (19.0476 100.0000) (19.0476 90.4762) (14.2857 80.9524) (9.5238 76.1905) + (4.7619 66.6667) (4.7619 57.1429) (14.2857 47.6190) + OPEN 17 (9.5238 114.2857) (14.2857 104.7619) (14.2857 95.2381) + (9.5238 85.7143) (4.7619 80.9524) (0.0000 71.4286) (0.0000 61.9048) + (4.7619 52.3810) (23.8095 42.8571) (4.7619 33.3333) (0.0000 23.8095) + (0.0000 14.2857) (4.7619 4.7619) (9.5238 0.0000) (14.2857 -9.5238) + (14.2857 -19.0476) (9.5238 -28.5714) + OPEN 10 (14.2857 38.0952) (4.7619 28.5714) (4.7619 19.0476) + (9.5238 9.5238) (14.2857 4.7619) (19.0476 -4.7619) (19.0476 -14.2857) + (14.2857 -23.8095) (9.5238 -28.5714) (0.0000 -33.3333) +INDEX 126 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 11 (0.0000 28.5714) (0.0000 38.0952) (4.7619 52.3810) + (14.2857 57.1429) (23.8095 57.1429) (33.3333 52.3810) (52.3810 38.0952) + (61.9048 33.3333) (71.4286 33.3333) (80.9524 38.0952) (85.7143 47.6190) + OPEN 11 (0.0000 38.0952) (4.7619 47.6190) (14.2857 52.3810) + (23.8095 52.3810) (33.3333 47.6190) (52.3810 33.3333) (61.9048 28.5714) + (71.4286 28.5714) (80.9524 33.3333) (85.7143 47.6190) (85.7143 57.1429) +INDEX 127 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (52.3810 100.0000) (14.2857 -33.3333) + OPEN 17 (28.5714 66.6667) (14.2857 61.9048) (4.7619 52.3810) + (0.0000 38.0952) (0.0000 23.8095) (4.7619 14.2857) (14.2857 4.7619) + (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) (61.9048 14.2857) + (66.6667 28.5714) (66.6667 42.8571) (61.9048 52.3810) (52.3810 61.9048) + (38.0952 66.6667) (28.5714 66.6667) + + + +#/* NCGA GRAFNET:SANS-SERIF NORMAL*/ + +BEARING 32 L_SPACE 0.0 WIDTH 20.0 R_SPACE 0.0 +BEARING 33 L_SPACE 8.62 WIDTH 13.64 R_SPACE 8.48 +BEARING 34 L_SPACE 4.02 WIDTH 32.86 R_SPACE 9.32 +BEARING 35 L_SPACE 3.2 WIDTH 68.94 R_SPACE 4.86 +BEARING 36 L_SPACE 4.82 WIDTH 67.44 R_SPACE 4.72 +BEARING 37 L_SPACE 6.36 WIDTH 112.38 R_SPACE 4.5 +BEARING 38 L_SPACE 5.98 WIDTH 82.02 R_SPACE 0.54 +BEARING 39 L_SPACE 4.44 WIDTH 13.36 R_SPACE 9.18 +BEARING 40 L_SPACE 7.58 WIDTH 24.72 R_SPACE 6.26 +BEARING 41 L_SPACE 5.28 WIDTH 24.34 R_SPACE 8.92 +BEARING 42 L_SPACE 6.96 WIDTH 42.06 R_SPACE 4.86 +BEARING 43 L_SPACE 5.98 WIDTH 96.36 R_SPACE 5.56 +BEARING 44 L_SPACE 8.76 WIDTH 14.2 R_SPACE 7.78 +BEARING 45 L_SPACE 7.38 WIDTH 38.84 R_SPACE 7.66 +BEARING 46 L_SPACE 8.34 WIDTH 13.78 R_SPACE 8.62 +BEARING 47 L_SPACE 7.24 WIDTH 38.44 R_SPACE 8.2 +BEARING 48 L_SPACE 4.98 WIDTH 66.58 R_SPACE 5.42 +BEARING 49 L_SPACE 11.82 WIDTH 34.26 R_SPACE 30.9 +BEARING 50 L_SPACE 5.42 WIDTH 66.0 R_SPACE 5.56 +BEARING 51 L_SPACE 5.0 WIDTH 66.62 R_SPACE 5.38 +BEARING 52 L_SPACE 3.88 WIDTH 68.24 R_SPACE 4.86 +BEARING 53 L_SPACE 4.86 WIDTH 65.96 R_SPACE 6.16 +BEARING 54 L_SPACE 5.58 WIDTH 65.08 R_SPACE 6.32 +BEARING 55 L_SPACE 5.56 WIDTH 66.42 R_SPACE 5.0 +BEARING 56 L_SPACE 5.6 WIDTH 65.98 R_SPACE 5.4 +BEARING 57 L_SPACE 6.6 WIDTH 64.82 R_SPACE 5.56 +BEARING 58 L_SPACE 9.32 WIDTH 14.06 R_SPACE 7.38 +BEARING 59 L_SPACE 8.2 WIDTH 13.96 R_SPACE 8.58 +BEARING 60 L_SPACE 3.06 WIDTH 102.5 R_SPACE 2.36 +BEARING 61 L_SPACE 5.7 WIDTH 96.36 R_SPACE 5.84 +BEARING 62 L_SPACE 2.78 WIDTH 102.5 R_SPACE 2.64 +BEARING 63 L_SPACE 8.42 WIDTH 60.22 R_SPACE 8.34 +BEARING 64 L_SPACE 6.36 WIDTH 126.24 R_SPACE 6.1 +BEARING 65 L_SPACE 2.5 WIDTH 88.16 R_SPACE 1.8 +BEARING 66 L_SPACE 11.42 WIDTH 75.5 R_SPACE 5.54 +BEARING 67 L_SPACE 6.66 WIDTH 87.06 R_SPACE 6.4 +BEARING 68 L_SPACE 11.96 WIDTH 81.48 R_SPACE 6.66 +BEARING 69 L_SPACE 11.42 WIDTH 72.28 R_SPACE 4.86 +BEARING 70 L_SPACE 11.42 WIDTH 67.96 R_SPACE 5.42 +BEARING 71 L_SPACE 7.06 WIDTH 89.56 R_SPACE 11.28 +BEARING 72 L_SPACE 11.42 WIDTH 77.7 R_SPACE 11.0 +BEARING 73 L_SPACE 10.86 WIDTH 13.36 R_SPACE 10.44 +BEARING 74 L_SPACE 2.5 WIDTH 56.96 R_SPACE 9.88 +BEARING 75 L_SPACE 11.28 WIDTH 79.8 R_SPACE 1.38 +BEARING 76 L_SPACE 11.68 WIDTH 62.8 R_SPACE 2.5 +BEARING 77 L_SPACE 10.86 WIDTH 94.56 R_SPACE 10.16 +BEARING 78 L_SPACE 11.14 WIDTH 77.98 R_SPACE 11.0 +BEARING 79 L_SPACE 6.24 WIDTH 95.28 R_SPACE 6.4 +BEARING 80 L_SPACE 12.1 WIDTH 73.44 R_SPACE 6.9 +BEARING 81 L_SPACE 5.3 WIDTH 96.0 R_SPACE 6.6 +BEARING 82 L_SPACE 11.68 WIDTH 80.64 R_SPACE 4.02 +BEARING 83 L_SPACE 8.0 WIDTH 78.28 R_SPACE 6.16 +BEARING 84 L_SPACE 2.36 WIDTH 79.52 R_SPACE 2.92 +BEARING 85 L_SPACE 11.54 WIDTH 77.28 R_SPACE 11.28 +BEARING 86 L_SPACE 2.36 WIDTH 87.04 R_SPACE 3.06 +BEARING 87 L_SPACE 2.22 WIDTH 125.76 R_SPACE 3.06 +BEARING 88 L_SPACE 2.5 WIDTH 86.76 R_SPACE 3.2 +BEARING 89 L_SPACE 1.52 WIDTH 88.98 R_SPACE 1.94 +BEARING 90 L_SPACE 2.5 WIDTH 77.7 R_SPACE 4.58 +BEARING 91 L_SPACE 7.78 WIDTH 25.76 R_SPACE 5.0 +BEARING 92 L_SPACE 5.84 WIDTH 73.24 R_SPACE 5.7 +BEARING 93 L_SPACE 4.44 WIDTH 25.48 R_SPACE 8.62 +BEARING 94 L_SPACE 5.98 WIDTH 55.28 R_SPACE 8.06 +BEARING 95 L_SPACE -1.1 WIDTH 70.04 R_SPACE 0.4 +BEARING 96 L_SPACE 28.26 WIDTH 25.9 R_SPACE 26.74 +BEARING 97 L_SPACE 6.68 WIDTH 67.54 R_SPACE 2.78 +BEARING 98 L_SPACE 8.76 WIDTH 63.66 R_SPACE 4.56 +BEARING 99 L_SPACE 5.52 WIDTH 61.46 R_SPACE 6.26 +BEARING 100 L_SPACE 4.64 WIDTH 63.88 R_SPACE 8.48 +BEARING 101 L_SPACE 5.72 WIDTH 65.62 R_SPACE 5.66 +BEARING 102 L_SPACE 0.68 WIDTH 34.12 R_SPACE -0.12 +BEARING 103 L_SPACE 5.36 WIDTH 63.16 R_SPACE 8.48 +BEARING 104 L_SPACE 9.6 WIDTH 58.34 R_SPACE 9.04 +BEARING 105 L_SPACE 10.02 WIDTH 11.42 R_SPACE 9.32 +BEARING 106 L_SPACE -1.66 WIDTH 23.1 R_SPACE 9.32 +BEARING 107 L_SPACE 9.6 WIDTH 59.18 R_SPACE 0.54 +BEARING 108 L_SPACE 10.02 WIDTH 11.42 R_SPACE 9.32 +BEARING 109 L_SPACE 9.6 WIDTH 96.36 R_SPACE 9.6 +BEARING 110 L_SPACE 9.18 WIDTH 58.48 R_SPACE 9.32 +BEARING 111 L_SPACE 4.98 WIDTH 67.14 R_SPACE 4.86 +BEARING 112 L_SPACE 9.46 WIDTH 63.34 R_SPACE 4.2 +BEARING 113 L_SPACE 4.84 WIDTH 63.38 R_SPACE 8.76 +BEARING 114 L_SPACE 9.46 WIDTH 34.8 R_SPACE 1.94 +BEARING 115 L_SPACE 4.7 WIDTH 59.4 R_SPACE 5.24 +BEARING 116 L_SPACE 0.54 WIDTH 33.42 R_SPACE 0.68 +BEARING 117 L_SPACE 9.46 WIDTH 58.2 R_SPACE 9.32 +BEARING 118 L_SPACE 1.8 WIDTH 65.86 R_SPACE 1.66 +BEARING 119 L_SPACE 2.5 WIDTH 95.82 R_SPACE 1.8 +BEARING 120 L_SPACE 1.66 WIDTH 65.32 R_SPACE 2.36 +BEARING 121 L_SPACE 1.8 WIDTH 65.18 R_SPACE 2.36 +BEARING 122 L_SPACE 4.44 WIDTH 59.88 R_SPACE 5.0 +BEARING 123 L_SPACE 7.38 WIDTH 36.06 R_SPACE 10.44 +BEARING 124 L_SPACE 11.54 WIDTH 6.96 R_SPACE 12.24 +BEARING 125 L_SPACE 9.18 WIDTH 36.2 R_SPACE 8.48 +BEARING 126 L_SPACE 2.92 WIDTH 102.36 R_SPACE 2.64 + diff --git a/lib/glut-3.7.6/lib/glut/capturexfont.c b/lib/glut-3.7.6/lib/glut/capturexfont.c new file mode 100644 index 0000000000..491d62f3c8 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/capturexfont.c @@ -0,0 +1,352 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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. */ + +/* capturexfont.c connects to an X server and downloads a + bitmap font from which a C source file is generated, + encoding the font for GLUT's use. Example usage: + capturexfont.c 9x15 glutBitmap9By15 > glut_9x15.c */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_GLYPHS_PER_GRAB 512 /* This is big enough for 2^9 + glyph character sets */ + +static void +outputChar(int num, int width, int height, + int xoff, int yoff, int advance, int data) +{ + if (width == 0 || height == 0) { + printf("#ifdef _WIN32\n"); + printf("/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with\n"); + printf(" a height or width of zero does not advance the raster position\n"); + printf(" as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */\n"); + printf("static const GLubyte ch%ddata[] = { 0x0 };\n", num); + printf("static const BitmapCharRec ch%d = {", num); + printf("%d,", 0); + printf("%d,", 0); + printf("%d,", xoff); + printf("%d,", yoff); + printf("%d,", advance); + printf("ch%ddata", num); + printf("};\n"); + printf("#else\n"); + } + printf("static const BitmapCharRec ch%d = {", num); + printf("%d,", width); + printf("%d,", height); + printf("%d,", xoff); + printf("%d,", yoff); + printf("%d,", advance); + if (data) { + printf("ch%ddata", num); + } else { + printf("0"); + } + printf("};\n"); + if (width == 0 || height == 0) { + printf("#endif\n"); + } + printf("\n"); +} + +/* Can't just use isprint because it only works for the range + of ASCII characters (ie, TRUE for isascii) and capturexfont + might be run on 16-bit fonts. */ +#define PRINTABLE(ch) (isascii(ch) ? isprint(ch) : 0) + +void +captureXFont(Display * dpy, Font font, char *xfont, char *name) +{ + int first, last, count; + int cnt, len; + Pixmap offscreen; + Window drawable; + XFontStruct *fontinfo; + XImage *image; + GC xgc; + XGCValues values; + int width, height; + int i, j, k; + XCharStruct *charinfo; + XChar2b character; + GLubyte *bitmapData; + int x, y; + int spanLength; + int charWidth, charHeight, maxSpanLength, pixwidth; + int grabList[MAX_GLYPHS_PER_GRAB]; + int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; + int numToGrab; + int rows, pages, byte1, byte2, index; + int nullBitmap; + + drawable = RootWindow(dpy, DefaultScreen(dpy)); + + fontinfo = XQueryFont(dpy, font); + pages = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1; + first = (fontinfo->min_byte1 << 8) + fontinfo->min_char_or_byte2; + last = (fontinfo->max_byte1 << 8) + fontinfo->max_char_or_byte2; + count = last - first + 1; + + width = fontinfo->max_bounds.rbearing - + fontinfo->min_bounds.lbearing; + height = fontinfo->max_bounds.ascent + + fontinfo->max_bounds.descent; + /* 16-bit fonts have more than one row; indexing into + per_char is trickier. */ + rows = fontinfo->max_byte1 - fontinfo->min_byte1 + 1; + + maxSpanLength = (width + 7) / 8; + /* For portability reasons we don't use alloca for + bitmapData, but we could. */ + bitmapData = malloc(height * maxSpanLength); + /* Be careful determining the width of the pixmap; the X + protocol allows pixmaps of width 2^16-1 (unsigned short + size) but drawing coordinates max out at 2^15-1 (signed + short size). If the width is too large, we need to limit + the glyphs per grab. */ + if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) { + glyphsPerGrab = (1 << 15) / (8 * maxSpanLength); + } + pixwidth = glyphsPerGrab * 8 * maxSpanLength; + offscreen = XCreatePixmap(dpy, drawable, pixwidth, height, 1); + + values.font = font; + values.background = 0; + values.foreground = 0; + xgc = XCreateGC(dpy, offscreen, + GCFont | GCBackground | GCForeground, &values); + XFillRectangle(dpy, offscreen, xgc, 0, 0, + 8 * maxSpanLength * glyphsPerGrab, height); + XSetForeground(dpy, xgc, 1); + + numToGrab = 0; + if (fontinfo->per_char == NULL) { + charinfo = &(fontinfo->min_bounds); + charWidth = charinfo->rbearing - charinfo->lbearing; + charHeight = charinfo->ascent + charinfo->descent; + spanLength = (charWidth + 7) / 8; + } + printf("\n/* GENERATED FILE -- DO NOT MODIFY */\n\n"); + printf("#include \"glutbitmap.h\"\n\n"); + for (i = first; count; i++, count--) { + int undefined; + if (rows == 1) { + undefined = (fontinfo->min_char_or_byte2 > i || + fontinfo->max_char_or_byte2 < i); + } else { + byte2 = i & 0xff; + byte1 = i >> 8; + undefined = (fontinfo->min_char_or_byte2 > byte2 || + fontinfo->max_char_or_byte2 < byte2 || + fontinfo->min_byte1 > byte1 || + fontinfo->max_byte1 < byte1); + + } + if (undefined) { + goto PossiblyDoGrab; + } + if (fontinfo->per_char != NULL) { + if (rows == 1) { + index = i - fontinfo->min_char_or_byte2; + } else { + byte2 = i & 0xff; + byte1 = i >> 8; + index = + (byte1 - fontinfo->min_byte1) * pages + + (byte2 - fontinfo->min_char_or_byte2); + } + charinfo = &(fontinfo->per_char[index]); + charWidth = charinfo->rbearing - charinfo->lbearing; + charHeight = charinfo->ascent + charinfo->descent; + if (charWidth == 0 || charHeight == 0) { + if (charinfo->width != 0) { + /* Still must move raster pos even if empty character + + */ + outputChar(i, 0, 0, 0, 0, charinfo->width, 0); + } + goto PossiblyDoGrab; + } + } + grabList[numToGrab] = i; + character.byte2 = i & 255; + character.byte1 = i >> 8; + + /* XXX We could use XDrawImageString16 which would also + paint the backing rectangle but X server bugs in some + scalable font rasterizers makes it more effective to do + XFillRectangles to clear the pixmap and then + XDrawImage16 for the text. */ + XDrawString16(dpy, offscreen, xgc, + -charinfo->lbearing + 8 * maxSpanLength * numToGrab, + charinfo->ascent, &character, 1); + + numToGrab++; + + PossiblyDoGrab: + + if (numToGrab >= glyphsPerGrab || count == 1) { + image = XGetImage(dpy, offscreen, + 0, 0, pixwidth, height, 1, XYPixmap); + for (j = numToGrab - 1; j >= 0; j--) { + if (fontinfo->per_char != NULL) { + byte2 = grabList[j] & 0xff; + byte1 = grabList[j] >> 8; + index = + (byte1 - fontinfo->min_byte1) * pages + + (byte2 - fontinfo->min_char_or_byte2); + charinfo = &(fontinfo->per_char[index]); + charWidth = charinfo->rbearing - charinfo->lbearing; + charHeight = charinfo->ascent + charinfo->descent; + spanLength = (charWidth + 7) / 8; + } + memset(bitmapData, 0, height * spanLength); + for (y = 0; y < charHeight; y++) { + for (x = 0; x < charWidth; x++) { + if (XGetPixel(image, j * maxSpanLength * 8 + x, + charHeight - 1 - y)) { + /* Little endian machines (such as DEC Alpha) + could benefit from reversing the bit order + here and changing the GL_UNPACK_LSB_FIRST + parameter in glutBitmapCharacter to GL_TRUE. */ + bitmapData[y * spanLength + x / 8] |= + (1 << (7 - (x & 7))); + } + } + } + if (PRINTABLE(grabList[j])) { + printf("/* char: 0x%x '%c' */\n\n", + grabList[j], grabList[j]); + } else { + printf("/* char: 0x%x */\n\n", grabList[j]); + } + + /* Determine if the bitmap is null. */ + nullBitmap = 1; + len = (charinfo->ascent + charinfo->descent) * + ((charinfo->rbearing - charinfo->lbearing + 7) / 8); + cnt = 0; + while (cnt < len) { + for (k = 0; k < 16 && cnt < len; k++, cnt++) { + if (bitmapData[cnt] != 0) { + nullBitmap = 0; + } + } + } + + if (!nullBitmap) { + printf("static const GLubyte ch%ddata[] = {\n", grabList[j]); + len = (charinfo->ascent + charinfo->descent) * + ((charinfo->rbearing - charinfo->lbearing + 7) / 8); + cnt = 0; + while (cnt < len) { + for (k = 0; k < 16 && cnt < len; k++, cnt++) { + printf("0x%x,", bitmapData[cnt]); + } + printf("\n"); + } + printf("};\n\n"); + } else { + charWidth = 0; + charHeight = 0; + } + + outputChar(grabList[j], charWidth, charHeight, + -charinfo->lbearing, charinfo->descent, + charinfo->width, !nullBitmap); + } + XDestroyImage(image); + numToGrab = 0; + if (count > 0) { + XSetForeground(dpy, xgc, 0); + XFillRectangle(dpy, offscreen, xgc, 0, 0, + 8 * maxSpanLength * glyphsPerGrab, height); + XSetForeground(dpy, xgc, 1); + } + } + } + XFreeGC(dpy, xgc); + XFreePixmap(dpy, offscreen); + /* For portability reasons we don't use alloca for + bitmapData, but we could. */ + free(bitmapData); + + printf("static const BitmapCharRec * const chars[] = {\n"); + for (i = first; i <= last; i++) { + int undefined; + byte2 = i & 0xff; + byte1 = i >> 8; + undefined = (fontinfo->min_char_or_byte2 > byte2 || + fontinfo->max_char_or_byte2 < byte2 || + fontinfo->min_byte1 > byte1 || + fontinfo->max_byte1 < byte1); + if (undefined) { + printf("0,\n"); + } else { + if (fontinfo->per_char != NULL) { + if (rows == 1) { + index = i - fontinfo->min_char_or_byte2; + } else { + byte2 = i & 0xff; + byte1 = i >> 8; + index = + (byte1 - fontinfo->min_byte1) * pages + + (byte2 - fontinfo->min_char_or_byte2); + } + charinfo = &(fontinfo->per_char[index]); + charWidth = charinfo->rbearing - charinfo->lbearing; + charHeight = charinfo->ascent + charinfo->descent; + if (charWidth == 0 || charHeight == 0) { + if (charinfo->width == 0) { + printf("0,\n"); + continue; + } + } + } + printf("&ch%d,\n", i); + } + } + printf("};\n\n"); + printf("const BitmapFontRec %s = {\n", name); + printf("\"%s\",\n", xfont); + printf("%d,\n", last - first + 1); + printf("%d,\n", first); + printf("chars\n"); + printf("};\n\n"); + XFreeFont(dpy, fontinfo); +} + +int +main(int argc, char **argv) +{ + Display *dpy; + Font font; + + if (argc != 3) { + fprintf(stderr, "usage: capturexfont XFONT NAME\n"); + exit(1); + } + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + fprintf(stderr, "capturexfont: could not open X display\n"); + exit(1); + } + font = XLoadFont(dpy, argv[1]); + if (font == None) { + fprintf(stderr, "capturexfont: bad font\n"); + exit(1); + } + captureXFont(dpy, font, argv[1], argv[2]); + XCloseDisplay(dpy); + return 0; +} diff --git a/lib/glut-3.7.6/lib/glut/glut.def b/lib/glut-3.7.6/lib/glut/glut.def new file mode 100644 index 0000000000..94da6ab852 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut.def @@ -0,0 +1,126 @@ +DESCRIPTION 'OpenGL Utility Toolkit for Win32' + +VERSION 3.7 + +EXPORTS + + glutAddMenuEntry + glutAddSubMenu + glutAttachMenu + glutBitmapCharacter + glutBitmapLength + glutBitmapWidth + glutButtonBoxFunc + glutChangeToMenuEntry + glutChangeToSubMenu + glutCopyColormap + glutCreateMenu + __glutCreateMenuWithExit + glutCreateSubWindow + glutCreateWindow + __glutCreateWindowWithExit + glutDestroyMenu + glutDestroyWindow + glutDetachMenu + glutDeviceGet + glutDialsFunc + glutDisplayFunc + glutEnterGameMode + glutEntryFunc + glutEstablishOverlay + glutExtensionSupported + glutForceJoystickFunc + glutFullScreen + glutGameModeGet + glutGameModeString + glutGet + glutGetColor + glutGetMenu + glutGetModifiers + glutGetWindow + glutHideOverlay + glutHideWindow + glutIconifyWindow + glutIdleFunc + glutIgnoreKeyRepeat + glutInit + __glutInitWithExit + glutInitDisplayMode + glutInitDisplayString + glutInitWindowPosition + glutInitWindowSize + glutJoystickFunc + glutKeyboardFunc + glutKeyboardUpFunc + glutLayerGet + glutLeaveGameMode + glutMainLoop + glutMenuStateFunc + glutMenuStatusFunc + glutMotionFunc + glutMouseFunc + glutOverlayDisplayFunc + glutPassiveMotionFunc + glutPopWindow + glutPositionWindow + glutPostOverlayRedisplay + glutPostRedisplay + glutPostWindowOverlayRedisplay + glutPostWindowRedisplay + glutPushWindow + glutRemoveMenuItem + glutRemoveOverlay + glutReportErrors + glutReshapeFunc + glutReshapeWindow + glutSetColor + glutSetCursor + glutSetIconTitle + glutSetKeyRepeat + glutSetMenu + glutSetWindow + glutSetWindowTitle + glutSetupVideoResizing + glutShowOverlay + glutShowWindow + glutSolidCone + glutSolidCube + glutSolidDodecahedron + glutSolidIcosahedron + glutSolidOctahedron + glutSolidSphere + glutSolidTeapot + glutSolidTetrahedron + glutSolidTorus + glutSpaceballButtonFunc + glutSpaceballMotionFunc + glutSpaceballRotateFunc + glutSpecialFunc + glutSpecialUpFunc + glutStopVideoResizing + glutStrokeCharacter + glutStrokeLength + glutStrokeWidth + glutSwapBuffers + glutTabletButtonFunc + glutTabletMotionFunc + glutTimerFunc + glutUseLayer + glutVideoPan + glutVideoResize + glutVideoResizeGet + glutVisibilityFunc + glutWarpPointer + glutWindowStatusFunc + glutWireCone + glutWireCube + glutWireDodecahedron + glutWireIcosahedron + glutWireOctahedron + glutWireSphere + glutWireTeapot + glutWireTetrahedron + glutWireTorus +; __glutSetFCB +; __glutGetFCB + diff --git a/lib/glut-3.7.6/lib/glut/glut.ico b/lib/glut-3.7.6/lib/glut/glut.ico new file mode 100644 index 0000000000000000000000000000000000000000..ffe391db4538225a3a6ddb6508d2854d2f57bbf1 GIT binary patch literal 3638 zcmZQzU}Ruo5D;JhgA7&%1~mo-1_cE$mth4514ADx1A_(w0|Q72NSKj<10u-?p)kn? z28IR(28M<6dwR4IYwk|DZSURPeVd*YRE$hbjWl&Fzy|P}sf!8;iO8Ek zc<3Z)t_Kxqh_LwopJ4$5!$}qh#% zCp$4zXFD;p6gx5W6gx4@sdi#m+5!^uVrVJ$Vwh6x#W1JEi(zSx7ejG&5JNQx7Y8x4 z6bCW%R0lCkX$fMO(-Oo`oE^o`Qys-Hr6r1?r8=3RrzM$T3JCWkGtB8pX4pC>nW3c` zQV(pMlg-dlUChwaQp_-CN-@LMImHZnmliWj>8S?S3v1_8GwfYj&2VgOHN%vi7KS-f zS|D}BoECsp4rAiQ@i!?C@f zx&>0lTsyax;oiBm4A;(WWw>{4E5os4kUHnsv11J9K=|A-hUfQ=F`PRGs(a2cJiiB` zuQA+%)RHdY(G&QyICkhA(3T5VqM2lpISa~|> z1r`xYAuq*i-M1!zM2q9G_C9Kp|D ztS6Lw#v-#fPlEnVic3%(&RISOFAdlAOG{Ao literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/lib/glut/glut.rc b/lib/glut-3.7.6/lib/glut/glut.rc new file mode 100644 index 0000000000..774918e3b9 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut.rc @@ -0,0 +1 @@ +GLUT_ICON ICON DISCARDABLE "glut.ico" diff --git a/lib/glut-3.7.6/lib/glut/glut32.dsp b/lib/glut-3.7.6/lib/glut/glut32.dsp new file mode 100644 index 0000000000..305d0b272d --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut32.dsp @@ -0,0 +1,351 @@ +# Microsoft Developer Studio Project File - Name="glut32" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=glut32 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "glut32.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "glut32.mak" CFG="glut32 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "glut32 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "glut32 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "glut32 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT32_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT32_EXPORTS" /U "GLUT_USE_SGI_OPENGL" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib glu32.lib opengl32.lib /nologo /dll /machine:I386 /nodefaultlib:"glut32.lib" +# Begin Special Build Tool +TargetDir=.\Release +SOURCE="$(InputPath)" +PostBuild_Desc=Copying libraries, headers & dll's... +PostBuild_Cmds=copy $(TARGETDIR)\glut32.dll %WINDIR%\SYSTEM copy $(TARGETDIR)\glut32.lib "$(MSDevDir)\..\..\VC98\lib" copy ..\..\include\GL\glut.h "$(MSDevDir)\..\..\VC98\include\GL" +# End Special Build Tool + +!ELSEIF "$(CFG)" == "glut32 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT32_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT32_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib glu32.lib opengl32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"glut32.lib" /pdbtype:sept +# Begin Special Build Tool +TargetDir=.\Debug +SOURCE="$(InputPath)" +PostBuild_Desc=Copying libraries, headers & dll's... +PostBuild_Cmds=copy $(TARGETDIR)\glut32.dll %WINDIR%\SYSTEM32 copy $(TARGETDIR)\glut32.lib "$(MSDevDir)\..\..\VC98\lib" copy ..\..\include\GL\glut.h "$(MSDevDir)\..\..\VC98\include\GL" +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "glut32 - Win32 Release" +# Name "glut32 - Win32 Debug" +# Begin Source File + +SOURCE=.\glut.def +# End Source File +# Begin Source File + +SOURCE=..\..\include\Gl\glut.h +# End Source File +# Begin Source File + +SOURCE=.\glut.ico +# End Source File +# Begin Source File + +SOURCE=.\glut.rc +# End Source File +# Begin Source File + +SOURCE=.\glut_8x13.c +# End Source File +# Begin Source File + +SOURCE=.\glut_9x15.c +# End Source File +# Begin Source File + +SOURCE=.\glut_bitmap.c +# End Source File +# Begin Source File + +SOURCE=.\glut_bwidth.c +# End Source File +# Begin Source File + +SOURCE=.\glut_cindex.c +# End Source File +# Begin Source File + +SOURCE=.\glut_cmap.c +# End Source File +# Begin Source File + +SOURCE=.\glut_cursor.c +# End Source File +# Begin Source File + +SOURCE=.\glut_dials.c +# End Source File +# Begin Source File + +SOURCE=.\glut_dstr.c +# End Source File +# Begin Source File + +SOURCE=.\glut_event.c +# End Source File +# Begin Source File + +SOURCE=.\glut_ext.c +# End Source File +# Begin Source File + +SOURCE=.\glut_fcb.c +# End Source File +# Begin Source File + +SOURCE=.\glut_fullscrn.c +# End Source File +# Begin Source File + +SOURCE=.\glut_gamemode.c +# End Source File +# Begin Source File + +SOURCE=.\glut_get.c +# End Source File +# Begin Source File + +SOURCE=.\glut_glxext.c +# End Source File +# Begin Source File + +SOURCE=.\glut_hel10.c +# End Source File +# Begin Source File + +SOURCE=.\glut_hel12.c +# End Source File +# Begin Source File + +SOURCE=.\glut_hel18.c +# End Source File +# Begin Source File + +SOURCE=.\glut_init.c +# End Source File +# Begin Source File + +SOURCE=.\glut_input.c +# End Source File +# Begin Source File + +SOURCE=.\glut_joy.c +# End Source File +# Begin Source File + +SOURCE=.\glut_key.c +# End Source File +# Begin Source File + +SOURCE=.\glut_keyctrl.c +# End Source File +# Begin Source File + +SOURCE=.\glut_keyup.c +# End Source File +# Begin Source File + +SOURCE=.\glut_mesa.c +# End Source File +# Begin Source File + +SOURCE=.\glut_modifier.c +# End Source File +# Begin Source File + +SOURCE=.\glut_mroman.c +# End Source File +# Begin Source File + +SOURCE=.\glut_overlay.c +# End Source File +# Begin Source File + +SOURCE=.\glut_roman.c +# End Source File +# Begin Source File + +SOURCE=.\glut_shapes.c +# End Source File +# Begin Source File + +SOURCE=.\glut_space.c +# End Source File +# Begin Source File + +SOURCE=.\glut_stroke.c +# End Source File +# Begin Source File + +SOURCE=.\glut_swap.c +# End Source File +# Begin Source File + +SOURCE=.\glut_swidth.c +# End Source File +# Begin Source File + +SOURCE=.\glut_tablet.c +# End Source File +# Begin Source File + +SOURCE=.\glut_teapot.c +# End Source File +# Begin Source File + +SOURCE=.\glut_tr10.c +# End Source File +# Begin Source File + +SOURCE=.\glut_tr24.c +# End Source File +# Begin Source File + +SOURCE=.\glut_util.c +# End Source File +# Begin Source File + +SOURCE=.\glut_vidresize.c +# End Source File +# Begin Source File + +SOURCE=.\glut_warp.c +# End Source File +# Begin Source File + +SOURCE=.\glut_win.c +# End Source File +# Begin Source File + +SOURCE=.\glut_winmisc.c +# End Source File +# Begin Source File + +SOURCE=.\glutbitmap.h +# End Source File +# Begin Source File + +SOURCE=.\include\Gl\glutf90.h +# End Source File +# Begin Source File + +SOURCE=.\glutint.h +# End Source File +# Begin Source File + +SOURCE=.\glutstroke.h +# End Source File +# Begin Source File + +SOURCE=.\glutwin32.h +# End Source File +# Begin Source File + +SOURCE="..\..\README-win32.txt" +# End Source File +# Begin Source File + +SOURCE=.\stroke.h +# End Source File +# Begin Source File + +SOURCE=.\win32_glx.c +# End Source File +# Begin Source File + +SOURCE=.\win32_glx.h +# End Source File +# Begin Source File + +SOURCE=.\win32_menu.c +# End Source File +# Begin Source File + +SOURCE=.\win32_util.c +# End Source File +# Begin Source File + +SOURCE=.\win32_winproc.c +# End Source File +# Begin Source File + +SOURCE=.\win32_x11.c +# End Source File +# Begin Source File + +SOURCE=.\win32_x11.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/glut/glut_8x13.c b/lib/glut-3.7.6/lib/glut/glut_8x13.c new file mode 100644 index 0000000000..c88c66591d --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_8x13.c @@ -0,0 +1,2073 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmap8By13 XXX +#include "glutbitmap.h" +#undef glutBitmap8By13 + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch0data[] = { 0x0 }; +static const BitmapCharRec ch0 = {1,1,0,0,8,ch0data}; +#else +static const BitmapCharRec ch0 = {0,0,0,0,8,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,8,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,8,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch127data[] = { 0x0 }; +static const BitmapCharRec ch127 = {1,1,0,0,8,ch127data}; +#else +static const BitmapCharRec ch127 = {0,0,0,0,8,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,8,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,8,0}; +#endif + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x0,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch255 = {6,12,-1,2,8,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0x80,0x80,0xb8,0xc4,0x84,0x84,0xc4,0xb8,0x80,0x80, +}; + +static const BitmapCharRec ch254 = {6,10,-1,2,8,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch253 = {6,12,-1,2,8,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x74,0x88,0x88,0x88,0x88,0x88,0x0,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch252 = {6,10,-1,0,8,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x74,0x88,0x88,0x88,0x88,0x88,0x0,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch251 = {6,10,-1,0,8,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x74,0x88,0x88,0x88,0x88,0x88,0x0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch250 = {6,10,-1,0,8,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x74,0x88,0x88,0x88,0x88,0x88,0x0,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch249 = {6,10,-1,0,8,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0x80,0x78,0xc4,0xa4,0x94,0x8c,0x78,0x4, +}; + +static const BitmapCharRec ch248 = {6,8,-1,1,8,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x20,0x20,0x0,0xf8,0x0,0x20,0x20, +}; + +static const BitmapCharRec ch247 = {5,7,-1,-1,8,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch246 = {6,10,-1,0,8,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch245 = {6,10,-1,0,8,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch244 = {6,10,-1,0,8,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch243 = {6,10,-1,0,8,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch242 = {6,10,-1,0,8,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0x84,0x84,0x84,0x84,0xc4,0xb8,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch241 = {6,10,-1,0,8,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x78,0x84,0x84,0x84,0x84,0x78,0x8,0x50,0x30,0x48, +}; + +static const BitmapCharRec ch240 = {6,10,-1,0,8,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0xf8,0x20,0x20,0x20,0x20,0x60,0x0,0x0,0x50,0x50, +}; + +static const BitmapCharRec ch239 = {5,10,-1,0,8,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0xf8,0x20,0x20,0x20,0x20,0x60,0x0,0x0,0x90,0x60, +}; + +static const BitmapCharRec ch238 = {5,10,-1,0,8,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0xf8,0x20,0x20,0x20,0x20,0x60,0x0,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch237 = {5,10,-1,0,8,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0xf8,0x20,0x20,0x20,0x20,0x60,0x0,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch236 = {5,10,-1,0,8,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x78,0x84,0x80,0xfc,0x84,0x78,0x0,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch235 = {6,10,-1,0,8,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x78,0x84,0x80,0xfc,0x84,0x78,0x0,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch234 = {6,10,-1,0,8,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x78,0x84,0x80,0xfc,0x84,0x78,0x0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch233 = {6,10,-1,0,8,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x78,0x84,0x80,0xfc,0x84,0x78,0x0,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch232 = {6,10,-1,0,8,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x20,0x10,0x78,0x84,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch231 = {6,8,-1,2,8,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x6c,0x92,0x90,0x7c,0x12,0x6c, +}; + +static const BitmapCharRec ch230 = {7,6,0,0,8,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x30,0x48,0x30, +}; + +static const BitmapCharRec ch229 = {6,10,-1,0,8,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch228 = {6,10,-1,0,8,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch227 = {6,10,-1,0,8,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch226 = {6,10,-1,0,8,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch225 = {6,10,-1,0,8,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78,0x0,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch224 = {6,10,-1,0,8,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0x80,0xb8,0xc4,0x84,0x84,0xf8,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch223 = {6,9,-1,1,8,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0x80,0x80,0x80,0xf8,0x84,0x84,0x84,0xf8,0x80, +}; + +static const BitmapCharRec ch222 = {6,9,-1,0,8,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x20,0x20,0x20,0x20,0x50,0x88,0x88,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch221 = {5,10,-1,0,8,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch220 = {6,10,-1,0,8,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch219 = {6,10,-1,0,8,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch218 = {6,10,-1,0,8,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch217 = {6,10,-1,0,8,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x80,0x78,0xc4,0xa4,0xa4,0xa4,0x94,0x94,0x8c,0x78,0x4, +}; + +static const BitmapCharRec ch216 = {6,11,-1,1,8,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x84,0x48,0x30,0x30,0x48,0x84, +}; + +static const BitmapCharRec ch215 = {6,6,-1,-1,8,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch214 = {7,10,0,0,8,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch213 = {7,10,0,0,8,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x24,0x18, +}; + +static const BitmapCharRec ch212 = {7,10,0,0,8,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch211 = {7,10,0,0,8,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x8,0x10, +}; + +static const BitmapCharRec ch210 = {7,10,0,0,8,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0x82,0x86,0x8a,0x92,0xa2,0xc2,0x82,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch209 = {7,10,0,0,8,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0xfc,0x42,0x42,0x42,0xe2,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch208 = {7,9,0,0,8,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x50,0x50, +}; + +static const BitmapCharRec ch207 = {5,10,-1,0,8,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch206 = {5,10,-1,0,8,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch205 = {5,10,-1,0,8,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch204 = {5,10,-1,0,8,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xfc,0x80,0x80,0xf0,0x80,0x80,0xfc,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch203 = {6,10,-1,0,8,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xfc,0x80,0x80,0xf0,0x80,0x80,0xfc,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch202 = {6,10,-1,0,8,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xfc,0x80,0x80,0xf0,0x80,0x80,0xfc,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch201 = {6,10,-1,0,8,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xfc,0x80,0x80,0xf0,0x80,0x80,0xfc,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch200 = {6,10,-1,0,8,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x20,0x10,0x78,0x84,0x80,0x80,0x80,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch199 = {6,11,-1,2,8,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0x9e,0x90,0x90,0xf0,0x9c,0x90,0x90,0x90,0x6e, +}; + +static const BitmapCharRec ch198 = {7,9,0,0,8,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x30,0x48,0x30, +}; + +static const BitmapCharRec ch197 = {6,10,-1,0,8,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x0,0x48,0x48, +}; + +static const BitmapCharRec ch196 = {6,10,-1,0,8,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch195 = {6,10,-1,0,8,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x0,0x48,0x30, +}; + +static const BitmapCharRec ch194 = {6,10,-1,0,8,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch193 = {6,10,-1,0,8,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0x84,0x84,0xfc,0x84,0x84,0x48,0x30,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch192 = {6,10,-1,0,8,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x78,0x84,0x84,0x80,0x40,0x20,0x20,0x0,0x20, +}; + +static const BitmapCharRec ch191 = {6,9,-1,0,8,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x6,0x1a,0x12,0xa,0x66,0x92,0x10,0x20,0x90,0x60, +}; + +static const BitmapCharRec ch190 = {7,10,0,0,8,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x1e,0x10,0xc,0x2,0xf2,0x4c,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch189 = {7,10,0,0,8,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x6,0x1a,0x12,0xa,0xe6,0x42,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch188 = {7,10,0,0,8,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0x90,0x48,0x24,0x12,0x24,0x48,0x90, +}; + +static const BitmapCharRec ch187 = {7,7,0,-1,8,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xf0,0x0,0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch186 = {4,6,-1,-3,8,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch185 = {3,6,-1,-4,8,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0xc0,0x40, +}; + +static const BitmapCharRec ch184 = {2,2,-3,2,8,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0xc0, +}; + +static const BitmapCharRec ch183 = {2,1,-3,-4,8,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x28,0x28,0x28,0x28,0x68,0xe8,0xe8,0xe8,0x7c, +}; + +static const BitmapCharRec ch182 = {6,9,-1,0,8,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x80,0xb4,0xcc,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch181 = {6,7,-1,1,8,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0x80,0x40, +}; + +static const BitmapCharRec ch180 = {2,2,-3,-8,8,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0x60,0x90,0x10,0x20,0x90,0x60, +}; + +static const BitmapCharRec ch179 = {4,6,-1,-4,8,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xf0,0x80,0x60,0x10,0x90,0x60, +}; + +static const BitmapCharRec ch178 = {4,6,-1,-4,8,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xf8,0x0,0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch177 = {5,7,-1,-1,8,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch176 = {4,4,-2,-5,8,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xfc, +}; + +static const BitmapCharRec ch175 = {6,1,-1,-8,8,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x38,0x44,0xaa,0xb2,0xaa,0xaa,0x92,0x44,0x38, +}; + +static const BitmapCharRec ch174 = {7,9,0,-1,8,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xfc, +}; + +static const BitmapCharRec ch173 = {6,1,-1,-4,8,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x4,0x4,0x4,0xfc, +}; + +static const BitmapCharRec ch172 = {6,4,-1,-1,8,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x12,0x24,0x48,0x90,0x48,0x24,0x12, +}; + +static const BitmapCharRec ch171 = {7,7,0,-1,8,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xf8,0x0,0x78,0x88,0x78,0x8,0x70, +}; + +static const BitmapCharRec ch170 = {5,7,-1,-2,8,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x38,0x44,0x92,0xaa,0xa2,0xaa,0x92,0x44,0x38, +}; + +static const BitmapCharRec ch169 = {7,9,0,-1,8,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xd8, +}; + +static const BitmapCharRec ch168 = {5,1,-1,-8,8,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x60,0x90,0x10,0x60,0x90,0x90,0x60,0x80,0x90,0x60, +}; + +static const BitmapCharRec ch167 = {4,10,-2,0,8,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0x80,0x80,0x80,0x80,0x0,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch166 = {1,9,-3,0,8,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x10,0x10,0x7c,0x10,0x7c,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch165 = {7,9,0,0,8,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0x84,0x78,0x48,0x48,0x78,0x84, +}; + +static const BitmapCharRec ch164 = {6,6,-1,-1,8,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xdc,0x62,0x20,0x20,0x20,0x70,0x20,0x22,0x1c, +}; + +static const BitmapCharRec ch163 = {7,9,0,0,8,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x20,0x70,0xa8,0xa0,0xa0,0xa8,0x70,0x20, +}; + +static const BitmapCharRec ch162 = {5,8,-1,-1,8,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch161 = {1,9,-3,0,8,ch161data}; + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x90,0xa8,0x48, +}; + +static const BitmapCharRec ch126 = {5,3,-1,-6,8,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0xe0,0x10,0x10,0x20,0x18,0x20,0x10,0x10,0xe0, +}; + +static const BitmapCharRec ch125 = {5,9,-1,0,8,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch124 = {1,9,-3,0,8,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x38,0x40,0x40,0x20,0xc0,0x20,0x40,0x40,0x38, +}; + +static const BitmapCharRec ch123 = {5,9,-2,0,8,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xfc,0x40,0x20,0x10,0x8,0xfc, +}; + +static const BitmapCharRec ch122 = {6,6,-1,0,8,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch121 = {6,8,-1,2,8,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0x84,0x48,0x30,0x30,0x48,0x84, +}; + +static const BitmapCharRec ch120 = {6,6,-1,0,8,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x44,0xaa,0x92,0x92,0x82,0x82, +}; + +static const BitmapCharRec ch119 = {7,6,0,0,8,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x20,0x50,0x50,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch118 = {5,6,-1,0,8,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x74,0x88,0x88,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch117 = {6,6,-1,0,8,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x38,0x44,0x40,0x40,0x40,0xf8,0x40,0x40, +}; + +static const BitmapCharRec ch116 = {6,8,-1,0,8,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0x78,0x84,0x18,0x60,0x84,0x78, +}; + +static const BitmapCharRec ch115 = {6,6,-1,0,8,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0x40,0x40,0x40,0x40,0x44,0xb8, +}; + +static const BitmapCharRec ch114 = {6,6,-1,0,8,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x4,0x4,0x4,0x74,0x8c,0x84,0x8c,0x74, +}; + +static const BitmapCharRec ch113 = {6,8,-1,2,8,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0x80,0x80,0x80,0xb8,0xc4,0x84,0xc4,0xb8, +}; + +static const BitmapCharRec ch112 = {6,8,-1,2,8,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x78,0x84,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch111 = {6,6,-1,0,8,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0x84,0x84,0x84,0x84,0xc4,0xb8, +}; + +static const BitmapCharRec ch110 = {6,6,-1,0,8,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0x82,0x92,0x92,0x92,0x92,0xec, +}; + +static const BitmapCharRec ch109 = {7,6,0,0,8,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, +}; + +static const BitmapCharRec ch108 = {5,9,-1,0,8,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0x84,0x88,0x90,0xe0,0x90,0x88,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch107 = {6,9,-1,0,8,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0x70,0x88,0x88,0x8,0x8,0x8,0x8,0x18,0x0,0x8, +}; + +static const BitmapCharRec ch106 = {5,10,-1,2,8,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0xf8,0x20,0x20,0x20,0x20,0x60,0x0,0x20, +}; + +static const BitmapCharRec ch105 = {5,8,-1,0,8,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0x84,0x84,0x84,0x84,0xc4,0xb8,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch104 = {6,9,-1,0,8,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x78,0x84,0x78,0x80,0x70,0x88,0x88,0x74, +}; + +static const BitmapCharRec ch103 = {6,8,-1,2,8,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x40,0x40,0x40,0x40,0xf8,0x40,0x40,0x44,0x38, +}; + +static const BitmapCharRec ch102 = {6,9,-1,0,8,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x78,0x84,0x80,0xfc,0x84,0x78, +}; + +static const BitmapCharRec ch101 = {6,6,-1,0,8,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x74,0x8c,0x84,0x84,0x8c,0x74,0x4,0x4,0x4, +}; + +static const BitmapCharRec ch100 = {6,9,-1,0,8,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x78,0x84,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch99 = {6,6,-1,0,8,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xb8,0xc4,0x84,0x84,0xc4,0xb8,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch98 = {6,9,-1,0,8,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x74,0x8c,0x84,0x7c,0x4,0x78, +}; + +static const BitmapCharRec ch97 = {6,6,-1,0,8,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0x10,0x60,0xe0, +}; + +static const BitmapCharRec ch96 = {4,3,-2,-6,8,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xfe, +}; + +static const BitmapCharRec ch95 = {7,1,0,1,8,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x88,0x50,0x20, +}; + +static const BitmapCharRec ch94 = {5,3,-1,-6,8,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf0, +}; + +static const BitmapCharRec ch93 = {4,9,-1,0,8,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x2,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x80, +}; + +static const BitmapCharRec ch92 = {7,9,0,0,8,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xf0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf0, +}; + +static const BitmapCharRec ch91 = {4,9,-2,0,8,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xfc,0x80,0x80,0x40,0x20,0x10,0x8,0x4,0xfc, +}; + +static const BitmapCharRec ch90 = {6,9,-1,0,8,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x10,0x10,0x10,0x10,0x10,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch89 = {7,9,0,0,8,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0x82,0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch88 = {7,9,0,0,8,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x44,0xaa,0x92,0x92,0x92,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch87 = {7,9,0,0,8,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x10,0x28,0x28,0x28,0x44,0x44,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch86 = {7,9,0,0,8,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch85 = {6,9,-1,0,8,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xfe, +}; + +static const BitmapCharRec ch84 = {7,9,0,0,8,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x78,0x84,0x4,0x4,0x78,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch83 = {6,9,-1,0,8,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0x84,0x88,0x90,0xa0,0xf8,0x84,0x84,0x84,0xf8, +}; + +static const BitmapCharRec ch82 = {6,9,-1,0,8,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x4,0x78,0x94,0xa4,0x84,0x84,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch81 = {6,10,-1,1,8,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0x80,0x80,0x80,0x80,0xf8,0x84,0x84,0x84,0xf8, +}; + +static const BitmapCharRec ch80 = {6,9,-1,0,8,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch79 = {6,9,-1,0,8,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0x84,0x84,0x84,0x8c,0x94,0xa4,0xc4,0x84,0x84, +}; + +static const BitmapCharRec ch78 = {6,9,-1,0,8,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0x82,0x82,0x82,0x92,0x92,0xaa,0xc6,0x82,0x82, +}; + +static const BitmapCharRec ch77 = {7,9,0,0,8,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xfc,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch76 = {6,9,-1,0,8,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0x84,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x84, +}; + +static const BitmapCharRec ch75 = {6,9,-1,0,8,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x70,0x88,0x8,0x8,0x8,0x8,0x8,0x8,0x3c, +}; + +static const BitmapCharRec ch74 = {6,9,-1,0,8,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xf8, +}; + +static const BitmapCharRec ch73 = {5,9,-1,0,8,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0x84,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch72 = {6,9,-1,0,8,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x74,0x8c,0x84,0x9c,0x80,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch71 = {6,9,-1,0,8,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0x80,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xfc, +}; + +static const BitmapCharRec ch70 = {6,9,-1,0,8,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xfc,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xfc, +}; + +static const BitmapCharRec ch69 = {6,9,-1,0,8,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xfc,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch68 = {7,9,0,0,8,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x78,0x84,0x80,0x80,0x80,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch67 = {6,9,-1,0,8,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xfc,0x42,0x42,0x42,0x7c,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch66 = {7,9,0,0,8,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0x48,0x30, +}; + +static const BitmapCharRec ch65 = {6,9,-1,0,8,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x78,0x80,0x94,0xac,0xa4,0x9c,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch64 = {6,9,-1,0,8,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x10,0x0,0x10,0x10,0x8,0x4,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch63 = {6,9,-1,0,8,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0x80,0x40,0x20,0x10,0x8,0x10,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch62 = {5,9,-1,0,8,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xfc,0x0,0x0,0xfc, +}; + +static const BitmapCharRec ch61 = {6,4,-1,-2,8,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x8,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x8, +}; + +static const BitmapCharRec ch60 = {5,9,-2,0,8,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x60,0x70,0x0,0x0,0x20,0x70,0x20, +}; + +static const BitmapCharRec ch59 = {4,8,-1,1,8,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0x40,0xe0,0x40,0x0,0x0,0x40,0xe0,0x40, +}; + +static const BitmapCharRec ch58 = {3,8,-2,1,8,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0x70,0x8,0x4,0x4,0x74,0x8c,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch57 = {6,9,-1,0,8,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x78,0x84,0x84,0x84,0x78,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch56 = {6,9,-1,0,8,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x40,0x40,0x20,0x20,0x10,0x10,0x8,0x4,0xfc, +}; + +static const BitmapCharRec ch55 = {6,9,-1,0,8,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x78,0x84,0x84,0xc4,0xb8,0x80,0x80,0x40,0x38, +}; + +static const BitmapCharRec ch54 = {6,9,-1,0,8,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x78,0x84,0x4,0x4,0xc4,0xb8,0x80,0x80,0xfc, +}; + +static const BitmapCharRec ch53 = {6,9,-1,0,8,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x8,0x8,0xfc,0x88,0x88,0x48,0x28,0x18,0x8, +}; + +static const BitmapCharRec ch52 = {6,9,-1,0,8,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x78,0x84,0x4,0x4,0x38,0x10,0x8,0x4,0xfc, +}; + +static const BitmapCharRec ch51 = {6,9,-1,0,8,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xfc,0x80,0x40,0x30,0x8,0x4,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch50 = {6,9,-1,0,8,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xa0,0x60,0x20, +}; + +static const BitmapCharRec ch49 = {5,9,-1,0,8,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x30,0x48,0x84,0x84,0x84,0x84,0x84,0x48,0x30, +}; + +static const BitmapCharRec ch48 = {6,9,-1,0,8,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0x80,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x2, +}; + +static const BitmapCharRec ch47 = {7,9,0,0,8,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0x40,0xe0,0x40, +}; + +static const BitmapCharRec ch46 = {3,3,-2,1,8,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xfc, +}; + +static const BitmapCharRec ch45 = {6,1,-1,-4,8,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x60,0x70, +}; + +static const BitmapCharRec ch44 = {4,3,-1,1,8,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch43 = {5,5,-1,-2,8,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0x48,0x30,0xfc,0x30,0x48, +}; + +static const BitmapCharRec ch42 = {6,5,-1,-2,8,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x40,0x20,0x20,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {3,9,-2,0,8,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x20,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch40 = {3,9,-3,0,8,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x80,0x60,0x70, +}; + +static const BitmapCharRec ch39 = {4,3,-1,-6,8,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x74,0x88,0x94,0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch38 = {6,7,-1,0,8,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x88,0x54,0x48,0x20,0x10,0x10,0x48,0xa4,0x44, +}; + +static const BitmapCharRec ch37 = {6,9,-1,0,8,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x20,0xf0,0x28,0x70,0xa0,0x78,0x20, +}; + +static const BitmapCharRec ch36 = {5,7,-1,-1,8,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x48,0x48,0xfc,0x48,0xfc,0x48,0x48, +}; + +static const BitmapCharRec ch35 = {6,7,-1,-1,8,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0x90,0x90,0x90, +}; + +static const BitmapCharRec ch34 = {4,3,-2,-6,8,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0x80,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch33 = {1,9,-3,0,8,ch33data}; + +/* char: 0x1f */ + +static const GLubyte ch31data[] = { +0x80, +}; + +static const BitmapCharRec ch31 = {1,1,-3,-3,8,ch31data}; + +/* char: 0x1e */ + +static const GLubyte ch30data[] = { +0xdc,0x62,0x20,0x20,0x20,0x70,0x20,0x22,0x1c, +}; + +static const BitmapCharRec ch30 = {7,9,0,0,8,ch30data}; + +/* char: 0x1d */ + +static const GLubyte ch29data[] = { +0x80,0x40,0xfe,0x10,0xfe,0x4,0x2, +}; + +static const BitmapCharRec ch29 = {7,7,0,0,8,ch29data}; + +/* char: 0x1c */ + +static const GLubyte ch28data[] = { +0x88,0x48,0x48,0x48,0x48,0xfc, +}; + +static const BitmapCharRec ch28 = {6,6,-1,0,8,ch28data}; + +/* char: 0x1b */ + +static const GLubyte ch27data[] = { +0xfe,0x80,0x20,0x8,0x2,0x8,0x20,0x80, +}; + +static const BitmapCharRec ch27 = {7,8,0,0,8,ch27data}; + +/* char: 0x1a */ + +static const GLubyte ch26data[] = { +0xfe,0x2,0x8,0x20,0x80,0x20,0x8,0x2, +}; + +static const BitmapCharRec ch26 = {7,8,0,0,8,ch26data}; + +/* char: 0x19 */ + +static const GLubyte ch25data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch25 = {1,13,-3,2,8,ch25data}; + +/* char: 0x18 */ + +static const GLubyte ch24data[] = { +0x10,0x10,0x10,0x10,0x10,0xff, +}; + +static const BitmapCharRec ch24 = {8,6,0,2,8,ch24data}; + +/* char: 0x17 */ + +static const GLubyte ch23data[] = { +0xff,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch23 = {8,8,0,-3,8,ch23data}; + +/* char: 0x16 */ + +static const GLubyte ch22data[] = { +0x10,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch22 = {4,13,0,2,8,ch22data}; + +/* char: 0x15 */ + +static const GLubyte ch21data[] = { +0x80,0x80,0x80,0x80,0x80,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch21 = {5,13,-3,2,8,ch21data}; + +/* char: 0x14 */ + +static const GLubyte ch20data[] = { +0xff, +}; + +static const BitmapCharRec ch20 = {8,1,0,1,8,ch20data}; + +/* char: 0x13 */ + +static const GLubyte ch19data[] = { +0xff, +}; + +static const BitmapCharRec ch19 = {8,1,0,-1,8,ch19data}; + +/* char: 0x12 */ + +static const GLubyte ch18data[] = { +0xff, +}; + +static const BitmapCharRec ch18 = {8,1,0,-3,8,ch18data}; + +/* char: 0x11 */ + +static const GLubyte ch17data[] = { +0xff, +}; + +static const BitmapCharRec ch17 = {8,1,0,-5,8,ch17data}; + +/* char: 0x10 */ + +static const GLubyte ch16data[] = { +0xff, +}; + +static const BitmapCharRec ch16 = {8,1,0,-7,8,ch16data}; + +/* char: 0xf */ + +static const GLubyte ch15data[] = { +0x10,0x10,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch15 = {8,13,0,2,8,ch15data}; + +/* char: 0xe */ + +static const GLubyte ch14data[] = { +0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch14 = {5,8,-3,-3,8,ch14data}; + +/* char: 0xd */ + +static const GLubyte ch13data[] = { +0x80,0x80,0x80,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch13 = {5,6,-3,2,8,ch13data}; + +/* char: 0xc */ + +static const GLubyte ch12data[] = { +0x10,0x10,0x10,0x10,0x10,0xf0, +}; + +static const BitmapCharRec ch12 = {4,6,0,2,8,ch12data}; + +/* char: 0xb */ + +static const GLubyte ch11data[] = { +0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch11 = {4,8,0,-3,8,ch11data}; + +/* char: 0xa */ + +static const GLubyte ch10data[] = { +0x8,0x8,0x8,0x8,0x3e,0x20,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch10 = {7,9,0,2,8,ch10data}; + +/* char: 0x9 */ + +static const GLubyte ch9data[] = { +0x3e,0x20,0x20,0x20,0x88,0x98,0xa8,0xc8,0x88, +}; + +static const BitmapCharRec ch9 = {7,9,0,2,8,ch9data}; + +/* char: 0x8 */ + +static const GLubyte ch8data[] = { +0xfe,0x10,0x10,0xfe,0x10,0x10, +}; + +static const BitmapCharRec ch8 = {7,6,0,0,8,ch8data}; + +/* char: 0x7 */ + +static const GLubyte ch7data[] = { +0x70,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch7 = {5,4,-1,-5,8,ch7data}; + +/* char: 0x6 */ + +static const GLubyte ch6data[] = { +0x20,0x20,0x3c,0x20,0x3e,0xf8,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch6 = {7,9,0,2,8,ch6data}; + +/* char: 0x5 */ + +static const GLubyte ch5data[] = { +0x22,0x22,0x3c,0x22,0x3c,0x78,0x80,0x80,0x78, +}; + +static const BitmapCharRec ch5 = {7,9,0,2,8,ch5data}; + +/* char: 0x4 */ + +static const GLubyte ch4data[] = { +0x10,0x10,0x1c,0x10,0x9e,0x80,0xe0,0x80,0xf0, +}; + +static const BitmapCharRec ch4 = {7,9,0,2,8,ch4data}; + +/* char: 0x3 */ + +static const GLubyte ch3data[] = { +0x8,0x8,0x8,0x3e,0x88,0x88,0xf8,0x88,0x88, +}; + +static const BitmapCharRec ch3 = {7,9,0,2,8,ch3data}; + +/* char: 0x2 */ + +static const GLubyte ch2data[] = { +0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, +}; + +static const BitmapCharRec ch2 = {8,12,0,2,8,ch2data}; + +/* char: 0x1 */ + +static const GLubyte ch1data[] = { +0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10, +}; + +static const BitmapCharRec ch1 = {7,7,0,-1,8,ch1data}; + +static const BitmapCharRec * const chars[] = { +&ch0, +&ch1, +&ch2, +&ch3, +&ch4, +&ch5, +&ch6, +&ch7, +&ch8, +&ch9, +&ch10, +&ch11, +&ch12, +&ch13, +&ch14, +&ch15, +&ch16, +&ch17, +&ch18, +&ch19, +&ch20, +&ch21, +&ch22, +&ch23, +&ch24, +&ch25, +&ch26, +&ch27, +&ch28, +&ch29, +&ch30, +&ch31, +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +&ch127, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmap8By13 = { +"-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", +256, +0, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_9x15.c b/lib/glut-3.7.6/lib/glut/glut_9x15.c new file mode 100644 index 0000000000..04df3dcde2 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_9x15.c @@ -0,0 +1,2075 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmap9By15 XXX +#include "glutbitmap.h" +#undef glutBitmap9By15 + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch0data[] = { 0x0 }; +static const BitmapCharRec ch0 = {1,1,0,0,9,ch0data}; +#else +static const BitmapCharRec ch0 = {0,0,0,0,9,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,9,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,9,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch127data[] = { 0x0 }; +static const BitmapCharRec ch127 = {1,1,0,0,9,ch127data}; +#else +static const BitmapCharRec ch127 = {0,0,0,0,9,0}; +#endif + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,9,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,9,0}; +#endif + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch255 = {6,14,-1,3,9,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0x80,0x80,0x80,0xbc,0xc2,0x82,0x82,0x82,0xc2,0xbc,0x80,0x80, +}; + +static const BitmapCharRec ch254 = {7,12,-1,3,9,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch253 = {6,14,-1,3,9,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x7a,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch252 = {7,11,-1,0,9,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x7a,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch251 = {7,11,-1,0,9,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x7a,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch250 = {7,11,-1,0,9,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x7a,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch249 = {7,11,-1,0,9,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0x80,0x7c,0xa2,0xa2,0x92,0x8a,0x8a,0x7c,0x2, +}; + +static const BitmapCharRec ch248 = {7,9,-1,1,9,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x10,0x38,0x10,0x0,0xfe,0x0,0x10,0x38,0x10, +}; + +static const BitmapCharRec ch247 = {7,9,-1,0,9,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch246 = {7,11,-1,0,9,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch245 = {7,11,-1,0,9,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch244 = {7,11,-1,0,9,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch243 = {7,11,-1,0,9,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch242 = {7,11,-1,0,9,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0x82,0x82,0x82,0x82,0x82,0xc2,0xbc,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch241 = {7,11,-1,0,9,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c,0x8,0x50,0x30,0x48, +}; + +static const BitmapCharRec ch240 = {7,11,-1,0,9,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x50,0x50, +}; + +static const BitmapCharRec ch239 = {5,11,-2,0,9,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x90,0x60, +}; + +static const BitmapCharRec ch238 = {5,11,-2,0,9,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x60,0x10, +}; + +static const BitmapCharRec ch237 = {5,11,-2,0,9,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x30,0x40, +}; + +static const BitmapCharRec ch236 = {5,11,-2,0,9,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x7c,0x80,0x80,0xfe,0x82,0x82,0x7c,0x0,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch235 = {7,11,-1,0,9,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x7c,0x80,0x80,0xfe,0x82,0x82,0x7c,0x0,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch234 = {7,11,-1,0,9,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x7c,0x80,0x80,0xfe,0x82,0x82,0x7c,0x0,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch233 = {7,11,-1,0,9,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x7c,0x80,0x80,0xfe,0x82,0x82,0x7c,0x0,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch232 = {7,11,-1,0,9,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x30,0x48,0x18,0x7c,0x82,0x80,0x80,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch231 = {7,10,-1,3,9,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x6e,0x92,0x90,0x7c,0x12,0x92,0x6c, +}; + +static const BitmapCharRec ch230 = {7,7,-1,0,9,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x18,0x24,0x18, +}; + +static const BitmapCharRec ch229 = {7,11,-1,0,9,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch228 = {7,11,-1,0,9,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch227 = {7,11,-1,0,9,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch226 = {7,11,-1,0,9,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch225 = {7,11,-1,0,9,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c,0x0,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch224 = {7,11,-1,0,9,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0x80,0xbc,0xc2,0x82,0x82,0xfc,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch223 = {7,9,-1,1,9,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0x80,0x80,0x80,0xfc,0x82,0x82,0x82,0xfc,0x80,0x80, +}; + +static const BitmapCharRec ch222 = {7,10,-1,0,9,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x10,0x10,0x10,0x10,0x28,0x44,0x82,0x82,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch221 = {7,11,-1,0,9,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch220 = {7,11,-1,0,9,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch219 = {7,11,-1,0,9,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch218 = {7,11,-1,0,9,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch217 = {7,11,-1,0,9,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x80,0x7c,0xc2,0xa2,0xa2,0x92,0x92,0x8a,0x8a,0x86,0x7c,0x2, +}; + +static const BitmapCharRec ch216 = {7,12,-1,1,9,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x82,0x44,0x28,0x10,0x28,0x44,0x82, +}; + +static const BitmapCharRec ch215 = {7,7,-1,-1,9,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch214 = {7,11,-1,0,9,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch213 = {7,11,-1,0,9,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch212 = {7,11,-1,0,9,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch211 = {7,11,-1,0,9,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch210 = {7,11,-1,0,9,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0x82,0x86,0x8a,0x92,0x92,0xa2,0xc2,0x82,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch209 = {7,11,-1,0,9,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0xfc,0x42,0x42,0x42,0x42,0xf2,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch208 = {7,10,-1,0,9,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x50,0x50, +}; + +static const BitmapCharRec ch207 = {5,11,-2,0,9,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x88,0x70, +}; + +static const BitmapCharRec ch206 = {5,11,-2,0,9,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x60,0x10, +}; + +static const BitmapCharRec ch205 = {5,11,-2,0,9,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0xf8,0x0,0x30,0x40, +}; + +static const BitmapCharRec ch204 = {5,11,-2,0,9,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xfe,0x40,0x40,0x40,0x78,0x40,0x40,0xfe,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch203 = {7,11,-1,0,9,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xfe,0x40,0x40,0x40,0x78,0x40,0x40,0xfe,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch202 = {7,11,-1,0,9,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xfe,0x40,0x40,0x40,0x78,0x40,0x40,0xfe,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch201 = {7,11,-1,0,9,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xfe,0x40,0x40,0x40,0x78,0x40,0x40,0xfe,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch200 = {7,11,-1,0,9,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x30,0x48,0x18,0x7c,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch199 = {7,13,-1,3,9,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0x9e,0x90,0x90,0x90,0xfc,0x90,0x90,0x90,0x90,0x6e, +}; + +static const BitmapCharRec ch198 = {7,10,-1,0,9,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x10,0x28,0x10, +}; + +static const BitmapCharRec ch197 = {7,11,-1,0,9,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x0,0x28,0x28, +}; + +static const BitmapCharRec ch196 = {7,11,-1,0,9,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch195 = {7,11,-1,0,9,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x0,0x44,0x38, +}; + +static const BitmapCharRec ch194 = {7,11,-1,0,9,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x0,0x30,0x8, +}; + +static const BitmapCharRec ch193 = {7,11,-1,0,9,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x44,0x38,0x0,0x18,0x20, +}; + +static const BitmapCharRec ch192 = {7,11,-1,0,9,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x7c,0x82,0x82,0x80,0x40,0x20,0x10,0x10,0x0,0x10, +}; + +static const BitmapCharRec ch191 = {7,10,-1,0,9,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x6,0x1a,0x12,0xa,0x66,0x92,0x10,0x20,0x90,0x60, +}; + +static const BitmapCharRec ch190 = {7,10,-1,0,9,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x1e,0x10,0xc,0x2,0xf2,0x4c,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch189 = {7,10,-1,0,9,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x6,0x1a,0x12,0xa,0xe6,0x42,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch188 = {7,10,-1,0,9,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0x90,0x48,0x24,0x12,0x12,0x24,0x48,0x90, +}; + +static const BitmapCharRec ch187 = {7,8,-1,-1,9,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xf8,0x0,0x70,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch186 = {5,6,-1,-5,9,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch185 = {3,6,-1,-4,9,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0x60,0x90,0x30, +}; + +static const BitmapCharRec ch184 = {4,3,-2,3,9,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch183 = {2,2,-4,-4,9,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0xa,0xa,0xa,0xa,0xa,0x7a,0x8a,0x8a,0x8a,0x7e, +}; + +static const BitmapCharRec ch182 = {7,10,-1,0,9,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x80,0x80,0xba,0xc6,0x82,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch181 = {7,9,-1,2,9,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0xc0,0x20, +}; + +static const BitmapCharRec ch180 = {3,2,-3,-9,9,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0x60,0x90,0x10,0x20,0x90,0x60, +}; + +static const BitmapCharRec ch179 = {4,6,-1,-4,9,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xf0,0x80,0x60,0x10,0x90,0x60, +}; + +static const BitmapCharRec ch178 = {4,6,-1,-4,9,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xfe,0x0,0x10,0x10,0x10,0xfe,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch177 = {7,9,-1,-1,9,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch176 = {4,4,-3,-6,9,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xfc, +}; + +static const BitmapCharRec ch175 = {6,1,-1,-9,9,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x3c,0x42,0xa5,0xa9,0xbd,0xa5,0xb9,0x42,0x3c, +}; + +static const BitmapCharRec ch174 = {8,9,0,-1,9,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xfc, +}; + +static const BitmapCharRec ch173 = {6,1,-1,-4,9,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x4,0x4,0x4,0xfc, +}; + +static const BitmapCharRec ch172 = {6,4,-1,-2,9,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x12,0x24,0x48,0x90,0x90,0x48,0x24,0x12, +}; + +static const BitmapCharRec ch171 = {7,8,-1,-1,9,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xf8,0x0,0x78,0x90,0x70,0x90,0x60, +}; + +static const BitmapCharRec ch170 = {5,7,-3,-3,9,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x3c,0x42,0x99,0xa5,0xa1,0xa5,0x99,0x42,0x3c, +}; + +static const BitmapCharRec ch169 = {8,9,0,-1,9,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xa0,0xa0, +}; + +static const BitmapCharRec ch168 = {3,2,-3,-9,9,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x70,0x88,0x8,0x70,0x88,0x88,0x88,0x70,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch167 = {5,11,-2,1,9,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch166 = {1,11,-4,1,9,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x10,0x10,0x10,0x7c,0x10,0x7c,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch165 = {7,10,-1,0,9,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0x82,0x7c,0x44,0x44,0x7c,0x82, +}; + +static const BitmapCharRec ch164 = {7,6,-1,-3,9,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0x5c,0xa2,0x60,0x20,0x20,0xf8,0x20,0x20,0x22,0x1c, +}; + +static const BitmapCharRec ch163 = {7,10,-1,0,9,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x40,0x78,0xa4,0xa0,0x90,0x94,0x78,0x8, +}; + +static const BitmapCharRec ch162 = {6,8,-1,0,9,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x80,0x80, +}; + +static const BitmapCharRec ch161 = {1,11,-4,0,9,ch161data}; + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x8c,0x92,0x62, +}; + +static const BitmapCharRec ch126 = {7,3,-1,-7,9,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0xe0,0x10,0x10,0x10,0x20,0x18,0x18,0x20,0x10,0x10,0x10,0xe0, +}; + +static const BitmapCharRec ch125 = {5,12,-1,1,9,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch124 = {1,12,-4,1,9,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x38,0x40,0x40,0x40,0x20,0xc0,0xc0,0x20,0x40,0x40,0x40,0x38, +}; + +static const BitmapCharRec ch123 = {5,12,-3,1,9,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xfe,0x40,0x20,0x10,0x8,0x4,0xfe, +}; + +static const BitmapCharRec ch122 = {7,7,-1,0,9,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x78,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch121 = {6,10,-1,3,9,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0x82,0x44,0x28,0x10,0x28,0x44,0x82, +}; + +static const BitmapCharRec ch120 = {7,7,-1,0,9,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x44,0xaa,0x92,0x92,0x92,0x82,0x82, +}; + +static const BitmapCharRec ch119 = {7,7,-1,0,9,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x10,0x28,0x28,0x44,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch118 = {7,7,-1,0,9,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x7a,0x84,0x84,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch117 = {7,7,-1,0,9,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x1c,0x22,0x20,0x20,0x20,0x20,0xfc,0x20,0x20, +}; + +static const BitmapCharRec ch116 = {7,9,-1,0,9,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0x7c,0x82,0x2,0x7c,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch115 = {7,7,-1,0,9,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0x40,0x40,0x40,0x40,0x42,0x62,0x9c, +}; + +static const BitmapCharRec ch114 = {7,7,-1,0,9,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x2,0x2,0x2,0x7a,0x86,0x82,0x82,0x82,0x86,0x7a, +}; + +static const BitmapCharRec ch113 = {7,10,-1,3,9,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0x80,0x80,0x80,0xbc,0xc2,0x82,0x82,0x82,0xc2,0xbc, +}; + +static const BitmapCharRec ch112 = {7,10,-1,3,9,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch111 = {7,7,-1,0,9,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0x82,0x82,0x82,0x82,0x82,0xc2,0xbc, +}; + +static const BitmapCharRec ch110 = {7,7,-1,0,9,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0x82,0x92,0x92,0x92,0x92,0x92,0xec, +}; + +static const BitmapCharRec ch109 = {7,7,-1,0,9,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xe0, +}; + +static const BitmapCharRec ch108 = {5,10,-2,0,9,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0x82,0x8c,0xb0,0xc0,0xb0,0x8c,0x82,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch107 = {7,10,-1,0,9,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0x78,0x84,0x84,0x84,0x4,0x4,0x4,0x4,0x4,0x1c,0x0,0x0,0xc, +}; + +static const BitmapCharRec ch106 = {6,13,-1,3,9,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x60, +}; + +static const BitmapCharRec ch105 = {5,10,-2,0,9,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0x82,0x82,0x82,0x82,0x82,0xc2,0xbc,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch104 = {7,10,-1,0,9,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x7c,0x82,0x82,0x7c,0x80,0x78,0x84,0x84,0x84,0x7a, +}; + +static const BitmapCharRec ch103 = {7,10,-1,3,9,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x20,0x20,0x20,0x20,0xf8,0x20,0x20,0x22,0x22,0x1c, +}; + +static const BitmapCharRec ch102 = {7,10,-1,0,9,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x7c,0x80,0x80,0xfe,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch101 = {7,7,-1,0,9,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x7a,0x86,0x82,0x82,0x82,0x86,0x7a,0x2,0x2,0x2, +}; + +static const BitmapCharRec ch100 = {7,10,-1,0,9,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x7c,0x82,0x80,0x80,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch99 = {7,7,-1,0,9,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xbc,0xc2,0x82,0x82,0x82,0xc2,0xbc,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch98 = {7,10,-1,0,9,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x7a,0x86,0x82,0x7e,0x2,0x2,0x7c, +}; + +static const BitmapCharRec ch97 = {7,7,-1,0,9,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0x10,0x20,0x40,0xc0, +}; + +static const BitmapCharRec ch96 = {4,4,-3,-6,9,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xff, +}; + +static const BitmapCharRec ch95 = {8,1,0,1,9,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x82,0x44,0x28,0x10, +}; + +static const BitmapCharRec ch94 = {7,4,-1,-6,9,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf0, +}; + +static const BitmapCharRec ch93 = {4,12,-2,1,9,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x2,0x4,0x4,0x8,0x10,0x10,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch92 = {7,10,-1,0,9,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xf0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf0, +}; + +static const BitmapCharRec ch91 = {4,12,-3,1,9,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xfe,0x80,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0xfe, +}; + +static const BitmapCharRec ch90 = {7,10,-1,0,9,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch89 = {7,10,-1,0,9,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0x82,0x82,0x44,0x28,0x10,0x10,0x28,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch88 = {7,10,-1,0,9,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x44,0xaa,0x92,0x92,0x92,0x92,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch87 = {7,10,-1,0,9,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x10,0x28,0x28,0x28,0x44,0x44,0x44,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch86 = {7,10,-1,0,9,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch85 = {7,10,-1,0,9,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xfe, +}; + +static const BitmapCharRec ch84 = {7,10,-1,0,9,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x7c,0x82,0x82,0x2,0xc,0x70,0x80,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch83 = {7,10,-1,0,9,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0x82,0x82,0x84,0x88,0x90,0xfc,0x82,0x82,0x82,0xfc, +}; + +static const BitmapCharRec ch82 = {7,10,-1,0,9,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x6,0x8,0x7c,0x92,0xa2,0x82,0x82,0x82,0x82,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch81 = {7,12,-1,2,9,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0x80,0x80,0x80,0x80,0x80,0xfc,0x82,0x82,0x82,0xfc, +}; + +static const BitmapCharRec ch80 = {7,10,-1,0,9,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch79 = {7,10,-1,0,9,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0x82,0x82,0x82,0x86,0x8a,0x92,0xa2,0xc2,0x82,0x82, +}; + +static const BitmapCharRec ch78 = {7,10,-1,0,9,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0x82,0x82,0x82,0x92,0x92,0xaa,0xaa,0xc6,0x82,0x82, +}; + +static const BitmapCharRec ch77 = {7,10,-1,0,9,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch76 = {7,10,-1,0,9,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0x82,0x84,0x88,0x90,0xa0,0xe0,0x90,0x88,0x84,0x82, +}; + +static const BitmapCharRec ch75 = {7,10,-1,0,9,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x78,0x84,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x1e, +}; + +static const BitmapCharRec ch74 = {7,10,-1,0,9,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xf8, +}; + +static const BitmapCharRec ch73 = {5,10,-2,0,9,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0x82,0x82,0x82,0x82,0x82,0xfe,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch72 = {7,10,-1,0,9,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x7c,0x82,0x82,0x82,0x8e,0x80,0x80,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch71 = {7,10,-1,0,9,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0x40,0x40,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0xfe, +}; + +static const BitmapCharRec ch70 = {7,10,-1,0,9,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xfe,0x40,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0xfe, +}; + +static const BitmapCharRec ch69 = {7,10,-1,0,9,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xfc,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch68 = {7,10,-1,0,9,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x7c,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x7c, +}; + +static const BitmapCharRec ch67 = {7,10,-1,0,9,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xfc,0x42,0x42,0x42,0x42,0x7c,0x42,0x42,0x42,0xfc, +}; + +static const BitmapCharRec ch66 = {7,10,-1,0,9,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0x82,0x82,0x82,0xfe,0x82,0x82,0x82,0x44,0x28,0x10, +}; + +static const BitmapCharRec ch65 = {7,10,-1,0,9,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x7c,0x80,0x80,0x9a,0xa6,0xa2,0x9e,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch64 = {7,10,-1,0,9,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x10,0x0,0x10,0x10,0x8,0x4,0x2,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch63 = {7,10,-1,0,9,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0x80,0x40,0x20,0x10,0x8,0x8,0x10,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch62 = {5,10,-2,0,9,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xfe,0x0,0x0,0xfe, +}; + +static const BitmapCharRec ch61 = {7,4,-1,-2,9,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x8,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x8, +}; + +static const BitmapCharRec ch60 = {5,10,-2,0,9,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x40,0x40,0xc0,0xc0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch59 = {2,10,-4,3,9,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0xc0,0xc0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch58 = {2,7,-4,0,9,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0x78,0x4,0x2,0x2,0x7a,0x86,0x82,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch57 = {7,10,-1,0,9,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x38,0x44,0x82,0x82,0x44,0x38,0x44,0x82,0x44,0x38, +}; + +static const BitmapCharRec ch56 = {7,10,-1,0,9,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x40,0x40,0x20,0x20,0x10,0x8,0x4,0x2,0x2,0xfe, +}; + +static const BitmapCharRec ch55 = {7,10,-1,0,9,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x7c,0x82,0x82,0x82,0xc2,0xbc,0x80,0x80,0x40,0x3c, +}; + +static const BitmapCharRec ch54 = {7,10,-1,0,9,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x7c,0x82,0x2,0x2,0x2,0xc2,0xbc,0x80,0x80,0xfe, +}; + +static const BitmapCharRec ch53 = {7,10,-1,0,9,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x4,0x4,0x4,0xfe,0x84,0x44,0x24,0x14,0xc,0x4, +}; + +static const BitmapCharRec ch52 = {7,10,-1,0,9,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x7c,0x82,0x2,0x2,0x2,0x1c,0x8,0x4,0x2,0xfe, +}; + +static const BitmapCharRec ch51 = {7,10,-1,0,9,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xfe,0x80,0x40,0x30,0x8,0x4,0x2,0x82,0x82,0x7c, +}; + +static const BitmapCharRec ch50 = {7,10,-1,0,9,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0xfe,0x10,0x10,0x10,0x10,0x10,0x90,0x50,0x30,0x10, +}; + +static const BitmapCharRec ch49 = {7,10,-1,0,9,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38, +}; + +static const BitmapCharRec ch48 = {7,10,-1,0,9,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0x80,0x40,0x40,0x20,0x10,0x10,0x8,0x4,0x4,0x2, +}; + +static const BitmapCharRec ch47 = {7,10,-1,0,9,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch46 = {2,2,-4,0,9,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xfe, +}; + +static const BitmapCharRec ch45 = {7,1,-1,-4,9,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x40,0x40,0xc0,0xc0, +}; + +static const BitmapCharRec ch44 = {2,5,-4,3,9,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x10,0x10,0x10,0xfe,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch43 = {7,7,-1,-1,9,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0x10,0x92,0x54,0x38,0x54,0x92,0x10, +}; + +static const BitmapCharRec ch42 = {7,7,-1,-1,9,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {3,12,-3,1,9,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x20,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch40 = {3,12,-3,1,9,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x80,0x40,0x20,0x30, +}; + +static const BitmapCharRec ch39 = {4,4,-3,-6,9,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x62,0x94,0x88,0x94,0x62,0x60,0x90,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch38 = {7,10,-1,0,9,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x84,0x4a,0x4a,0x24,0x10,0x10,0x48,0xa4,0xa4,0x42, +}; + +static const BitmapCharRec ch37 = {7,10,-1,0,9,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x10,0x7c,0x92,0x12,0x12,0x14,0x38,0x50,0x90,0x92,0x7c,0x10, +}; + +static const BitmapCharRec ch36 = {7,12,-1,1,9,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48, +}; + +static const BitmapCharRec ch35 = {6,8,-1,-1,9,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0x90,0x90,0x90, +}; + +static const BitmapCharRec ch34 = {4,3,-3,-7,9,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0x80,0x80,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch33 = {1,11,-4,0,9,ch33data}; + +/* char: 0x1f */ + +static const GLubyte ch31data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch31 = {2,2,-4,-2,9,ch31data}; + +/* char: 0x1e */ + +static const GLubyte ch30data[] = { +0x5c,0xa2,0x60,0x20,0x20,0xf8,0x20,0x20,0x22,0x1c, +}; + +static const BitmapCharRec ch30 = {7,10,-1,0,9,ch30data}; + +/* char: 0x1d */ + +static const GLubyte ch29data[] = { +0x80,0x40,0xfe,0x10,0xfe,0x4,0x2, +}; + +static const BitmapCharRec ch29 = {7,7,-1,0,9,ch29data}; + +/* char: 0x1c */ + +static const GLubyte ch28data[] = { +0x44,0x24,0x24,0x24,0x24,0x24,0xfe, +}; + +static const BitmapCharRec ch28 = {7,7,-1,0,9,ch28data}; + +/* char: 0x1b */ + +static const GLubyte ch27data[] = { +0xfe,0x0,0x80,0x40,0x20,0x10,0x8,0x8,0x10,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch27 = {7,12,-1,2,9,ch27data}; + +/* char: 0x1a */ + +static const GLubyte ch26data[] = { +0xfc,0x0,0x4,0x8,0x10,0x20,0x40,0x40,0x20,0x10,0x8,0x4, +}; + +static const BitmapCharRec ch26 = {6,12,-2,2,9,ch26data}; + +/* char: 0x19 */ + +static const GLubyte ch25data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch25 = {1,15,-4,3,9,ch25data}; + +/* char: 0x18 */ + +static const GLubyte ch24data[] = { +0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0xff,0x80, +}; + +static const BitmapCharRec ch24 = {9,7,0,3,9,ch24data}; + +/* char: 0x17 */ + +static const GLubyte ch23data[] = { +0xff,0x80,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0, +0x8,0x0, +}; + +static const BitmapCharRec ch23 = {9,9,0,-3,9,ch23data}; + +/* char: 0x16 */ + +static const GLubyte ch22data[] = { +0x8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, +}; + +static const BitmapCharRec ch22 = {5,15,0,3,9,ch22data}; + +/* char: 0x15 */ + +static const GLubyte ch21data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch21 = {5,15,-4,3,9,ch21data}; + +/* char: 0x14 */ + +static const GLubyte ch20data[] = { +0xff,0x80, +}; + +static const BitmapCharRec ch20 = {9,1,0,1,9,ch20data}; + +/* char: 0x13 */ + +static const GLubyte ch19data[] = { +0xff,0x80, +}; + +static const BitmapCharRec ch19 = {9,1,0,-1,9,ch19data}; + +/* char: 0x12 */ + +static const GLubyte ch18data[] = { +0xff,0x80, +}; + +static const BitmapCharRec ch18 = {9,1,0,-3,9,ch18data}; + +/* char: 0x11 */ + +static const GLubyte ch17data[] = { +0xff,0x80, +}; + +static const BitmapCharRec ch17 = {9,1,0,-5,9,ch17data}; + +/* char: 0x10 */ + +static const GLubyte ch16data[] = { +0xff,0x80, +}; + +static const BitmapCharRec ch16 = {9,1,0,-7,9,ch16data}; + +/* char: 0xf */ + +static const GLubyte ch15data[] = { +0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0xff,0x80,0x8,0x0, +0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0,0x8,0x0, +}; + +static const BitmapCharRec ch15 = {9,15,0,3,9,ch15data}; + +/* char: 0xe */ + +static const GLubyte ch14data[] = { +0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch14 = {5,9,-4,-3,9,ch14data}; + +/* char: 0xd */ + +static const GLubyte ch13data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch13 = {5,7,-4,3,9,ch13data}; + +/* char: 0xc */ + +static const GLubyte ch12data[] = { +0x8,0x8,0x8,0x8,0x8,0x8,0xf8, +}; + +static const BitmapCharRec ch12 = {5,7,0,3,9,ch12data}; + +/* char: 0xb */ + +static const GLubyte ch11data[] = { +0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, +}; + +static const BitmapCharRec ch11 = {5,9,0,-3,9,ch11data}; + +/* char: 0xa */ + +static const GLubyte ch10data[] = { +0x8,0x8,0x8,0x8,0x3e,0x0,0x20,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch10 = {7,10,-1,2,9,ch10data}; + +/* char: 0x9 */ + +static const GLubyte ch9data[] = { +0x3e,0x20,0x20,0x20,0x20,0x88,0x98,0xa8,0xc8,0x88, +}; + +static const BitmapCharRec ch9 = {7,10,-1,2,9,ch9data}; + +/* char: 0x8 */ + +static const GLubyte ch8data[] = { +0xfe,0x10,0x10,0xfe,0x10,0x10, +}; + +static const BitmapCharRec ch8 = {7,6,-1,0,9,ch8data}; + +/* char: 0x7 */ + +static const GLubyte ch7data[] = { +0x70,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch7 = {5,4,-2,-6,9,ch7data}; + +/* char: 0x6 */ + +static const GLubyte ch6data[] = { +0x20,0x20,0x3c,0x20,0x3e,0x0,0xf8,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch6 = {7,10,-1,2,9,ch6data}; + +/* char: 0x5 */ + +static const GLubyte ch5data[] = { +0x22,0x22,0x3c,0x22,0x3c,0x0,0x78,0x80,0x80,0x78, +}; + +static const BitmapCharRec ch5 = {7,10,-1,2,9,ch5data}; + +/* char: 0x4 */ + +static const GLubyte ch4data[] = { +0x10,0x10,0x1c,0x10,0x1e,0x80,0x80,0xe0,0x80,0xf0, +}; + +static const BitmapCharRec ch4 = {7,10,-1,2,9,ch4data}; + +/* char: 0x3 */ + +static const GLubyte ch3data[] = { +0x8,0x8,0x8,0x3e,0x0,0x88,0x88,0xf8,0x88,0x88, +}; + +static const BitmapCharRec ch3 = {7,10,-1,2,9,ch3data}; + +/* char: 0x2 */ + +static const GLubyte ch2data[] = { +0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, +}; + +static const BitmapCharRec ch2 = {8,14,0,3,9,ch2data}; + +/* char: 0x1 */ + +static const GLubyte ch1data[] = { +0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10, +}; + +static const BitmapCharRec ch1 = {7,7,-1,0,9,ch1data}; + +static const BitmapCharRec * const chars[] = { +&ch0, +&ch1, +&ch2, +&ch3, +&ch4, +&ch5, +&ch6, +&ch7, +&ch8, +&ch9, +&ch10, +&ch11, +&ch12, +&ch13, +&ch14, +&ch15, +&ch16, +&ch17, +&ch18, +&ch19, +&ch20, +&ch21, +&ch22, +&ch23, +&ch24, +&ch25, +&ch26, +&ch27, +&ch28, +&ch29, +&ch30, +&ch31, +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +&ch127, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmap9By15 = { +"-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1", +256, +0, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_bitmap.c b/lib/glut-3.7.6/lib/glut/glut_bitmap.c new file mode 100644 index 0000000000..2a74054f60 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_bitmap.c @@ -0,0 +1,57 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" +#include "glutbitmap.h" + +void APIENTRY +glutBitmapCharacter(GLUTbitmapFont font, int c) +{ + const BitmapCharRec *ch; + BitmapFontPtr fontinfo; + GLint swapbytes, lsbfirst, rowlength; + GLint skiprows, skippixels, alignment; + +#if defined(_WIN32) + fontinfo = (BitmapFontPtr) __glutFont(font); +#else + fontinfo = (BitmapFontPtr) font; +#endif + + if (c < fontinfo->first || + c >= fontinfo->first + fontinfo->num_chars) + return; + ch = fontinfo->ch[c - fontinfo->first]; + if (ch) { + /* Save current modes. */ + 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); + /* Little endian machines (DEC Alpha for example) could + benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE + instead of GL_FALSE, but this would require changing the + generated bitmaps too. */ + 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); + glBitmap(ch->width, ch->height, ch->xorig, ch->yorig, + ch->advance, 0, ch->bitmap); + /* Restore saved 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); + } +} diff --git a/lib/glut-3.7.6/lib/glut/glut_bwidth.c b/lib/glut-3.7.6/lib/glut/glut_bwidth.c new file mode 100644 index 0000000000..117cecf0b8 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_bwidth.c @@ -0,0 +1,58 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" +#include "glutbitmap.h" + +/* CENTRY */ +int APIENTRY +glutBitmapWidth(GLUTbitmapFont font, int c) +{ + BitmapFontPtr fontinfo; + const BitmapCharRec *ch; + +#ifdef _WIN32 + fontinfo = (BitmapFontPtr) __glutFont(font); +#else + fontinfo = (BitmapFontPtr) font; +#endif + + if (c < fontinfo->first || c >= fontinfo->first + fontinfo->num_chars) + return 0; + ch = fontinfo->ch[c - fontinfo->first]; + if (ch) + return ch->advance; + else + return 0; +} + +int APIENTRY +glutBitmapLength(GLUTbitmapFont font, const unsigned char *string) +{ + int c, length; + BitmapFontPtr fontinfo; + const BitmapCharRec *ch; + +#ifdef _WIN32 + fontinfo = (BitmapFontPtr) __glutFont(font); +#else + fontinfo = (BitmapFontPtr) font; +#endif + + length = 0; + for (; *string != '\0'; string++) { + c = *string; + if (c >= fontinfo->first && c < fontinfo->first + fontinfo->num_chars) { + ch = fontinfo->ch[c - fontinfo->first]; + if (ch) + length += ch->advance; + } + } + return length; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_cindex.c b/lib/glut-3.7.6/lib/glut/glut_cindex.c new file mode 100644 index 0000000000..a74d8b6bce --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_cindex.c @@ -0,0 +1,252 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996, 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. */ + +#include +#include "glutint.h" + +#define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i))) + +/* CENTRY */ +void APIENTRY +glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue) +{ + GLUTcolormap *cmap, *newcmap; + XVisualInfo *vis; + XColor color; + int i; + + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + cmap = __glutCurrentWindow->colormap; + vis = __glutCurrentWindow->vis; + } else { + cmap = __glutCurrentWindow->overlay->colormap; + vis = __glutCurrentWindow->overlay->vis; + if (ndx == __glutCurrentWindow->overlay->transparentPixel) { + __glutWarning( + "glutSetColor: cannot set color of overlay transparent index %d\n", + ndx); + return; + } + } + + if (!cmap) { + __glutWarning("glutSetColor: current window is RGBA"); + return; + } +#if defined(_WIN32) + if (ndx >= 256 || /* always assume 256 colors on Win32 */ +#else + if (ndx >= vis->visual->map_entries || +#endif + ndx < 0) { + __glutWarning("glutSetColor: index %d out of range", ndx); + return; + } + if (cmap->refcnt > 1) { + newcmap = __glutAssociateNewColormap(vis); + cmap->refcnt--; + /* Wouldn't it be nice if XCopyColormapAndFree could be + told not to free the old colormap's entries! */ + for (i = cmap->size - 1; i >= 0; i--) { + if (i == ndx) { + /* We are going to set this cell shortly! */ + continue; + } + if (cmap->cells[i].component[GLUT_RED] >= 0.0) { + color.pixel = i; + newcmap->cells[i].component[GLUT_RED] = + cmap->cells[i].component[GLUT_RED]; + color.red = (GLfloat) 0xffff * + cmap->cells[i].component[GLUT_RED]; + newcmap->cells[i].component[GLUT_GREEN] = + cmap->cells[i].component[GLUT_GREEN]; + color.green = (GLfloat) 0xffff * + cmap->cells[i].component[GLUT_GREEN]; + newcmap->cells[i].component[GLUT_BLUE] = + cmap->cells[i].component[GLUT_BLUE]; + color.blue = (GLfloat) 0xffff * + cmap->cells[i].component[GLUT_BLUE]; + color.flags = DoRed | DoGreen | DoBlue; +#if defined(_WIN32) + if (IsWindowVisible(__glutCurrentWindow->win)) { + XHDC = __glutCurrentWindow->hdc; + } else { + XHDC = 0; + } +#endif + XStoreColor(__glutDisplay, newcmap->cmap, &color); + } else { + /* Leave unallocated entries unallocated. */ + } + } + cmap = newcmap; + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + __glutCurrentWindow->colormap = cmap; + __glutCurrentWindow->cmap = cmap->cmap; + } else { + __glutCurrentWindow->overlay->colormap = cmap; + __glutCurrentWindow->overlay->cmap = cmap->cmap; + } + XSetWindowColormap(__glutDisplay, + __glutCurrentWindow->renderWin, cmap->cmap); + +#if !defined(_WIN32) + { + GLUTwindow *toplevel; + + toplevel = __glutToplevelOf(__glutCurrentWindow); + if (toplevel->cmap != cmap->cmap) { + __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK); + } + } +#endif + } + color.pixel = ndx; + red = CLAMP(red); + cmap->cells[ndx].component[GLUT_RED] = red; + color.red = (GLfloat) 0xffff *red; + green = CLAMP(green); + cmap->cells[ndx].component[GLUT_GREEN] = green; + color.green = (GLfloat) 0xffff *green; + blue = CLAMP(blue); + cmap->cells[ndx].component[GLUT_BLUE] = blue; + color.blue = (GLfloat) 0xffff *blue; + color.flags = DoRed | DoGreen | DoBlue; +#if defined(_WIN32) + if (IsWindowVisible(__glutCurrentWindow->win)) { + XHDC = __glutCurrentWindow->hdc; + } else { + XHDC = 0; + } +#endif + XStoreColor(__glutDisplay, cmap->cmap, &color); +} + +GLfloat APIENTRY +glutGetColor(int ndx, int comp) +{ + GLUTcolormap *colormap; + XVisualInfo *vis; + + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + colormap = __glutCurrentWindow->colormap; + vis = __glutCurrentWindow->vis; + } else { + colormap = __glutCurrentWindow->overlay->colormap; + vis = __glutCurrentWindow->overlay->vis; + if (ndx == __glutCurrentWindow->overlay->transparentPixel) { + __glutWarning("glutGetColor: requesting overlay transparent index %d\n", + ndx); + return -1.0; + } + } + + if (!colormap) { + __glutWarning("glutGetColor: current window is RGBA"); + return -1.0; + } +#if defined(_WIN32) +#define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0) +#else +#define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0) +#endif + if (OUT_OF_RANGE_NDX(ndx)) { + __glutWarning("glutGetColor: index %d out of range", ndx); + return -1.0; + } + return colormap->cells[ndx].component[comp]; +} + +void APIENTRY +glutCopyColormap(int winnum) +{ + GLUTwindow *window = __glutWindowList[winnum - 1]; + GLUTcolormap *oldcmap, *newcmap; + XVisualInfo *dstvis; + + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + oldcmap = __glutCurrentWindow->colormap; + dstvis = __glutCurrentWindow->vis; + newcmap = window->colormap; + } else { + oldcmap = __glutCurrentWindow->overlay->colormap; + dstvis = __glutCurrentWindow->overlay->vis; + if (!window->overlay) { + __glutWarning("glutCopyColormap: window %d has no overlay", winnum); + return; + } + newcmap = window->overlay->colormap; + } + + if (!oldcmap) { + __glutWarning("glutCopyColormap: destination colormap must be color index"); + return; + } + if (!newcmap) { + __glutWarning( + "glutCopyColormap: source colormap of window %d must be color index", + winnum); + return; + } + if (newcmap == oldcmap) { + /* Source and destination are the same; now copy needed. */ + return; + } +#if !defined(_WIN32) + /* Play safe: compare visual IDs, not Visual*'s. */ + if (newcmap->visual->visualid == oldcmap->visual->visualid) { +#endif + /* Visuals match! "Copy" by reference... */ + __glutFreeColormap(oldcmap); + newcmap->refcnt++; + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + __glutCurrentWindow->colormap = newcmap; + __glutCurrentWindow->cmap = newcmap->cmap; + } else { + __glutCurrentWindow->overlay->colormap = newcmap; + __glutCurrentWindow->overlay->cmap = newcmap->cmap; + } + XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin, + newcmap->cmap); +#if !defined(_WIN32) + __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK); + } else { + GLUTcolormap *copycmap; + XColor color; + int i, last; + + /* Visuals different - need a distinct X colormap! */ + copycmap = __glutAssociateNewColormap(dstvis); + /* Wouldn't it be nice if XCopyColormapAndFree could be + told not to free the old colormap's entries! */ + last = newcmap->size; + if (last > copycmap->size) { + last = copycmap->size; + } + for (i = last - 1; i >= 0; i--) { + if (newcmap->cells[i].component[GLUT_RED] >= 0.0) { + color.pixel = i; + copycmap->cells[i].component[GLUT_RED] = + newcmap->cells[i].component[GLUT_RED]; + color.red = (GLfloat) 0xffff * + newcmap->cells[i].component[GLUT_RED]; + copycmap->cells[i].component[GLUT_GREEN] = + newcmap->cells[i].component[GLUT_GREEN]; + color.green = (GLfloat) 0xffff * + newcmap->cells[i].component[GLUT_GREEN]; + copycmap->cells[i].component[GLUT_BLUE] = + newcmap->cells[i].component[GLUT_BLUE]; + color.blue = (GLfloat) 0xffff * + newcmap->cells[i].component[GLUT_BLUE]; + color.flags = DoRed | DoGreen | DoBlue; + XStoreColor(__glutDisplay, copycmap->cmap, &color); + } + } + } +#endif +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_cmap.c b/lib/glut-3.7.6/lib/glut/glut_cmap.c new file mode 100644 index 0000000000..e3bbbf8354 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_cmap.c @@ -0,0 +1,395 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1996, 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. */ + +#include +#include +#include /* SunOS multithreaded assert() needs . Lame. */ +#include +#if !defined(_WIN32) +#include +#include +#include /* for XA_RGB_DEFAULT_MAP atom */ +#if defined(__vms) +#include /* for XmuLookupStandardColormap */ +#else +#include /* for XmuLookupStandardColormap */ +#endif +#endif + +/* SGI optimization introduced in IRIX 6.3 to avoid X server + round trips for interning common X atoms. */ +#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) +#include +#else +#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) +#endif + +#include "glutint.h" +#include "layerutil.h" + +GLUTcolormap *__glutColormapList = NULL; + +GLUTcolormap * +__glutAssociateNewColormap(XVisualInfo * vis) +{ + GLUTcolormap *cmap; + int transparentPixel, i; + unsigned long pixels[255]; + + cmap = (GLUTcolormap *) malloc(sizeof(GLUTcolormap)); + if (!cmap) + __glutFatalError("out of memory."); +#if defined(_WIN32) + pixels[0] = 0; /* avoid compilation warnings on win32 */ + cmap->visual = 0; + cmap->size = 256; /* always assume 256 on Win32 */ +#else + cmap->visual = vis->visual; + cmap->size = vis->visual->map_entries; +#endif + cmap->refcnt = 1; + cmap->cells = (GLUTcolorcell *) + malloc(sizeof(GLUTcolorcell) * cmap->size); + if (!cmap->cells) + __glutFatalError("out of memory."); + /* make all color cell entries be invalid */ + for (i = cmap->size - 1; i >= 0; i--) { + cmap->cells[i].component[GLUT_RED] = -1.0; + cmap->cells[i].component[GLUT_GREEN] = -1.0; + cmap->cells[i].component[GLUT_BLUE] = -1.0; + } + transparentPixel = __glutGetTransparentPixel(__glutDisplay, vis); + if (transparentPixel == -1 || transparentPixel >= cmap->size) { + + /* If there is no transparent pixel or if the transparent + pixel is outside the range of valid colormap cells (HP + can implement their overlays this smart way since their + transparent pixel is 255), we can AllocAll the colormap. + See note below. */ + + cmap->cmap = XCreateColormap(__glutDisplay, + __glutRoot, cmap->visual, AllocAll); + } else { + + /* On machines where zero (or some other value in the range + of 0 through map_entries-1), BadAlloc may be generated + when an AllocAll overlay colormap is allocated since the + transparent pixel precludes all the cells in the colormap + being allocated (the transparent pixel is pre-allocated). + So in this case, use XAllocColorCells to allocate + map_entries-1 pixels (that is, all but the transparent + pixel. */ + +#if defined(_WIN32) + cmap->cmap = XCreateColormap(__glutDisplay, + __glutRoot, 0, AllocNone); +#else + cmap->cmap = XCreateColormap(__glutDisplay, + __glutRoot, vis->visual, AllocNone); + XAllocColorCells(__glutDisplay, cmap->cmap, False, 0, 0, + pixels, cmap->size - 1); +#endif + } + cmap->next = __glutColormapList; + __glutColormapList = cmap; + return cmap; +} + +static GLUTcolormap * +associateColormap(XVisualInfo * vis) +{ +#if !defined(_WIN32) + GLUTcolormap *cmap = __glutColormapList; + + while (cmap != NULL) { + /* Play safe: compare visual IDs, not Visual*'s. */ + if (cmap->visual->visualid == vis->visual->visualid) { + /* Already have created colormap for the visual. */ + cmap->refcnt++; + return cmap; + } + cmap = cmap->next; + } +#endif + return __glutAssociateNewColormap(vis); +} + +void +__glutSetupColormap(XVisualInfo * vi, GLUTcolormap ** colormap, Colormap * cmap) +{ +#if defined(_WIN32) + if (vi->dwFlags & PFD_NEED_PALETTE || vi->iPixelType == PFD_TYPE_COLORINDEX) { + *colormap = associateColormap(vi); + *cmap = (*colormap)->cmap; + } else { + *colormap = NULL; + *cmap = 0; + } +#else + Status status; + XStandardColormap *standardCmaps; + int i, numCmaps; + static Atom hpColorRecoveryAtom = -1; + int isRGB, visualClass, rc; + +#if defined(__cplusplus) || defined(c_plusplus) + visualClass = vi->c_class; +#else + visualClass = vi->class; +#endif + switch (visualClass) { + case PseudoColor: + /* Mesa might return a PseudoColor visual for RGB mode. */ + rc = glXGetConfig(__glutDisplay, vi, GLX_RGBA, &isRGB); + if (rc == 0 && isRGB) { + /* Must be Mesa. */ + *colormap = NULL; + if (MaxCmapsOfScreen(DefaultScreenOfDisplay(__glutDisplay)) == 1 + && vi->visual == DefaultVisual(__glutDisplay, __glutScreen)) { + char *privateCmap = getenv("MESA_PRIVATE_CMAP"); + + if (privateCmap) { + /* User doesn't want to share colormaps. */ + *cmap = XCreateColormap(__glutDisplay, __glutRoot, + vi->visual, AllocNone); + } else { + /* Share the root colormap. */ + *cmap = DefaultColormap(__glutDisplay, __glutScreen); + } + } else { + /* Get our own PseudoColor colormap. */ + *cmap = XCreateColormap(__glutDisplay, __glutRoot, + vi->visual, AllocNone); + } + } else { + /* CI mode, real GLX never returns a PseudoColor visual + for RGB mode. */ + *colormap = associateColormap(vi); + *cmap = (*colormap)->cmap; + } + break; + case TrueColor: + case DirectColor: + *colormap = NULL; /* NULL if RGBA */ + + /* Hewlett-Packard supports a feature called "HP Color + Recovery". Mesa has code to use HP Color Recovery. For + Mesa to use this feature, the atom + _HP_RGB_SMOOTH_MAP_LIST must be defined on the root + window AND the colormap obtainable by XGetRGBColormaps + for that atom must be set on the window. If that + colormap is not set, the output will look stripy. */ + + if (hpColorRecoveryAtom == -1) { + char *xvendor; + +#define VENDOR_HP "Hewlett-Packard" + + /* Only makes sense to make XInternAtom round-trip if we + know that we are connected to an HP X server. */ + xvendor = ServerVendor(__glutDisplay); + if (!strncmp(xvendor, VENDOR_HP, sizeof(VENDOR_HP) - 1)) { + hpColorRecoveryAtom = XInternAtom(__glutDisplay, "_HP_RGB_SMOOTH_MAP_LIST", True); + } else { + hpColorRecoveryAtom = None; + } + } + if (hpColorRecoveryAtom != None) { + status = XGetRGBColormaps(__glutDisplay, __glutRoot, + &standardCmaps, &numCmaps, hpColorRecoveryAtom); + if (status == 1) { + for (i = 0; i < numCmaps; i++) { + if (standardCmaps[i].visualid == vi->visualid) { + *cmap = standardCmaps[i].colormap; + XFree(standardCmaps); + return; + } + } + XFree(standardCmaps); + } + } +#ifndef SOLARIS_2_4_BUG + /* Solaris 2.4 and 2.5 have a bug in their + XmuLookupStandardColormap implementations. Please + compile your Solaris 2.4 or 2.5 version of GLUT with + -DSOLARIS_2_4_BUG to work around this bug. The symptom + of the bug is that programs will get a BadMatch error + from X_CreateWindow when creating a GLUT window because + Solaris 2.4 and 2.5 create a corrupted RGB_DEFAULT_MAP + property. Note that this workaround prevents Colormap + sharing between applications, perhaps leading + unnecessary colormap installations or colormap flashing. + Sun fixed this bug in Solaris 2.6. */ + status = XmuLookupStandardColormap(__glutDisplay, + vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, + /* replace */ False, /* retain */ True); + if (status == 1) { + status = XGetRGBColormaps(__glutDisplay, __glutRoot, + &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP); + if (status == 1) { + for (i = 0; i < numCmaps; i++) { + if (standardCmaps[i].visualid == vi->visualid) { + *cmap = standardCmaps[i].colormap; + XFree(standardCmaps); + return; + } + } + XFree(standardCmaps); + } + } +#endif + /* If no standard colormap but TrueColor, just make a + private one. */ + /* XXX Should do a better job of internal sharing for + privately allocated TrueColor colormaps. */ + /* XXX DirectColor probably needs ramps hand initialized! */ + *cmap = XCreateColormap(__glutDisplay, __glutRoot, + vi->visual, AllocNone); + break; + case StaticColor: + case StaticGray: + case GrayScale: + /* Mesa supports these visuals */ + *colormap = NULL; + *cmap = XCreateColormap(__glutDisplay, __glutRoot, + vi->visual, AllocNone); + break; + default: + __glutFatalError( + "could not allocate colormap for visual type: %d.", + visualClass); + } + return; +#endif +} + +#if !defined(_WIN32) +static int +findColormaps(GLUTwindow * window, + Window * winlist, Colormap * cmaplist, int num, int max) +{ + GLUTwindow *child; + int i; + + /* Do not allow more entries that maximum number of + colormaps! */ + if (num >= max) + return num; + /* Is cmap for this window already on the list? */ + for (i = 0; i < num; i++) { + if (cmaplist[i] == window->cmap) + goto normalColormapAlreadyListed; + } + /* Not found on the list; add colormap and window. */ + winlist[num] = window->win; + cmaplist[num] = window->cmap; + num++; + +normalColormapAlreadyListed: + + /* Repeat above but for the overlay colormap if there one. */ + if (window->overlay) { + if (num >= max) + return num; + for (i = 0; i < num; i++) { + if (cmaplist[i] == window->overlay->cmap) + goto overlayColormapAlreadyListed; + } + winlist[num] = window->overlay->win; + cmaplist[num] = window->overlay->cmap; + num++; + } +overlayColormapAlreadyListed: + + /* Recursively search children. */ + child = window->children; + while (child) { + num = findColormaps(child, winlist, cmaplist, num, max); + child = child->siblings; + } + return num; +} + +void +__glutEstablishColormapsProperty(GLUTwindow * window) +{ + /* this routine is strictly X. Win32 doesn't need to do + anything of this sort (but has to do other wacky stuff + later). */ + static Atom wmColormapWindows = None; + Window *winlist; + Colormap *cmaplist; + Status status; + int maxcmaps, num; + + assert(!window->parent); + maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay, + __glutScreen)); + /* For portability reasons we don't use alloca for winlist + and cmaplist, but we could. */ + winlist = (Window *) malloc(maxcmaps * sizeof(Window)); + cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap)); + num = findColormaps(window, winlist, cmaplist, 0, maxcmaps); + if (num < 2) { + /* Property no longer needed; remove it. */ + wmColormapWindows = XSGIFastInternAtom(__glutDisplay, + "WM_COLORMAP_WINDOWS", SGI_XA_WM_COLORMAP_WINDOWS, False); + if (wmColormapWindows == None) { + __glutWarning("Could not intern X atom for WM_COLORMAP_WINDOWS."); + return; + } + XDeleteProperty(__glutDisplay, window->win, wmColormapWindows); + } else { + status = XSetWMColormapWindows(__glutDisplay, window->win, + winlist, num); + /* XSetWMColormapWindows should always work unless the + WM_COLORMAP_WINDOWS property cannot be intern'ed. We + check to be safe. */ + if (status == False) + __glutFatalError("XSetWMColormapWindows returned False."); + } + /* For portability reasons we don't use alloca for winlist + and cmaplist, but we could. */ + free(winlist); + free(cmaplist); +} + +GLUTwindow * +__glutToplevelOf(GLUTwindow * window) +{ + while (window->parent) { + window = window->parent; + } + return window; +} +#endif + +void +__glutFreeColormap(GLUTcolormap * cmap) +{ + GLUTcolormap *cur, **prev; + + cmap->refcnt--; + if (cmap->refcnt == 0) { + /* remove from colormap list */ + cur = __glutColormapList; + prev = &__glutColormapList; + while (cur) { + if (cur == cmap) { + *prev = cmap->next; + break; + } + prev = &(cur->next); + cur = cur->next; + } + /* actually free colormap */ + XFreeColormap(__glutDisplay, cmap->cmap); + free(cmap->cells); + free(cmap); + } +} + diff --git a/lib/glut-3.7.6/lib/glut/glut_cursor.c b/lib/glut-3.7.6/lib/glut/glut_cursor.c new file mode 100644 index 0000000000..7601a6d36c --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_cursor.c @@ -0,0 +1,201 @@ + +/* Copyright (c) Mark J. Kilgard, 1995, 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 "glutint.h" + +#if !defined(_WIN32) +#include /* For XA_CURSOR */ +#include +#endif + +typedef struct _CursorTable { +#if defined(_WIN32) + char* glyph; +#else + int glyph; +#endif + Cursor cursor; +} CursorTable; +/* *INDENT-OFF* */ + +static CursorTable cursorTable[] = { + {XC_arrow, None}, /* GLUT_CURSOR_RIGHT_ARROW */ + {XC_top_left_arrow, None}, /* GLUT_CURSOR_LEFT_ARROW */ + {XC_hand1, None}, /* GLUT_CURSOR_INFO */ + {XC_pirate, None}, /* GLUT_CURSOR_DESTROY */ + {XC_question_arrow, None}, /* GLUT_CURSOR_HELP */ + {XC_exchange, None}, /* GLUT_CURSOR_CYCLE */ + {XC_spraycan, None}, /* GLUT_CURSOR_SPRAY */ + {XC_watch, None}, /* GLUT_CURSOR_WAIT */ + {XC_xterm, None}, /* GLUT_CURSOR_TEXT */ + {XC_crosshair, None}, /* GLUT_CURSOR_CROSSHAIR */ + {XC_sb_v_double_arrow, None}, /* GLUT_CURSOR_UP_DOWN */ + {XC_sb_h_double_arrow, None}, /* GLUT_CURSOR_LEFT_RIGHT */ + {XC_top_side, None}, /* GLUT_CURSOR_TOP_SIDE */ + {XC_bottom_side, None}, /* GLUT_CURSOR_BOTTOM_SIDE */ + {XC_left_side, None}, /* GLUT_CURSOR_LEFT_SIDE */ + {XC_right_side, None}, /* GLUT_CURSOR_RIGHT_SIDE */ + {XC_top_left_corner, None}, /* GLUT_CURSOR_TOP_LEFT_CORNER */ + {XC_top_right_corner, None}, /* GLUT_CURSOR_TOP_RIGHT_CORNER */ + {XC_bottom_right_corner, None}, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */ + {XC_bottom_left_corner, None}, /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */ +}; +/* *INDENT-ON* */ + +#if !defined(_WIN32) +static Cursor blankCursor = None; +static Cursor fullCrosshairCusor = None; + +/* SGI X server's support a special property called the + _SGI_CROSSHAIR_CURSOR that when installed as a window's + cursor, becomes a full screen crosshair cursor. SGI + has special cursor generation hardware for this case. */ +static Cursor +getFullCrosshairCursor(void) +{ + Cursor cursor; + Atom crosshairAtom, actualType; + int rc, actualFormat; + unsigned long n, left; + unsigned long *value; + + if (fullCrosshairCusor == None) { + crosshairAtom = XInternAtom(__glutDisplay, + "_SGI_CROSSHAIR_CURSOR", True); + if (crosshairAtom != None) { + value = 0; /* Make compiler happy. */ + rc = XGetWindowProperty(__glutDisplay, __glutRoot, + crosshairAtom, 0, 1, False, XA_CURSOR, &actualType, + &actualFormat, &n, &left, (unsigned char **) &value); + if (rc == Success && actualFormat == 32 && n >= 1) { + cursor = value[0]; + XFree(value); + return cursor; + } + } + } + return XCreateFontCursor(__glutDisplay, XC_crosshair); +} + +/* X11 forces you to create a blank cursor if you want + to disable the cursor. */ +static Cursor +makeBlankCursor(void) +{ + static char data[1] = + {0}; + Cursor cursor; + Pixmap blank; + XColor dummy; + + blank = XCreateBitmapFromData(__glutDisplay, __glutRoot, + data, 1, 1); + if (blank == None) + __glutFatalError("out of memory."); + cursor = XCreatePixmapCursor(__glutDisplay, blank, blank, + &dummy, &dummy, 0, 0); + XFreePixmap(__glutDisplay, blank); + + return cursor; +} +#endif /* !_WIN32 */ + +/* Win32 and X11 use this same function to accomplish + fairly different tasks. X11 lets you just define the + cursor for a window and the window system takes care + of making sure that the window's cursor is installed + when the mouse is in the window. Win32 requires the + application to handle a WM_SETCURSOR message to install + the right cursor when windows are entered. Think of + the Win32 __glutSetCursor (called from __glutWindowProc) + as "install cursor". Think of the X11 __glutSetCursor + (called from glutSetCursor) as "define cursor". */ +void +__glutSetCursor(GLUTwindow *window) +{ + int cursor = window->cursor; + Cursor xcursor; + + if (cursor >= 0 && + cursor < sizeof(cursorTable) / sizeof(cursorTable[0])) { + if (cursorTable[cursor].cursor == None) { + cursorTable[cursor].cursor = XCreateFontCursor(__glutDisplay, + cursorTable[cursor].glyph); + } + xcursor = cursorTable[cursor].cursor; + } else { + /* Special cases. */ + switch (cursor) { + case GLUT_CURSOR_INHERIT: +#if defined(_WIN32) + while (window->parent) { + window = window->parent; + if (window->cursor != GLUT_CURSOR_INHERIT) { + __glutSetCursor(window); + return; + } + } + /* XXX Default to an arrow cursor. Is this + right or should we be letting the default + window proc be installing some system cursor? */ + xcursor = cursorTable[0].cursor; + if (xcursor == NULL) { + xcursor = + cursorTable[0].cursor = + LoadCursor(NULL, cursorTable[0].glyph); + } +#else + xcursor = None; +#endif + break; + case GLUT_CURSOR_NONE: +#if defined(_WIN32) + xcursor = NULL; +#else + if (blankCursor == None) { + blankCursor = makeBlankCursor(); + } + xcursor = blankCursor; +#endif + break; + case GLUT_CURSOR_FULL_CROSSHAIR: +#if defined(_WIN32) + xcursor = LoadCursor(NULL, IDC_CROSS); +#else + if (fullCrosshairCusor == None) { + fullCrosshairCusor = getFullCrosshairCursor(); + } + xcursor = fullCrosshairCusor; +#endif + break; + } + } + XDefineCursor(__glutDisplay, + window->win, xcursor); + XFlush(__glutDisplay); +} + +/* CENTRY */ +void APIENTRY +glutSetCursor(int cursor) +{ +#ifdef _WIN32 + POINT point; + + __glutCurrentWindow->cursor = cursor; + /* Are we in the window right now? If so, + install the cursor. */ + GetCursorPos(&point); + if (__glutCurrentWindow->win == WindowFromPoint(point)) { + __glutSetCursor(__glutCurrentWindow); + } +#else + __glutCurrentWindow->cursor = cursor; + __glutSetCursor(__glutCurrentWindow); +#endif +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_dials.c b/lib/glut-3.7.6/lib/glut/glut_dials.c new file mode 100644 index 0000000000..b34e8430e2 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_dials.c @@ -0,0 +1,26 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" + +void APIENTRY +glutButtonBoxFunc(GLUTbuttonBoxCB buttonBoxFunc) +{ + __glutCurrentWindow->buttonBox = buttonBoxFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} + +void APIENTRY +glutDialsFunc(GLUTdialsCB dialsFunc) +{ + __glutCurrentWindow->dials = dialsFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} diff --git a/lib/glut-3.7.6/lib/glut/glut_dstr.c b/lib/glut-3.7.6/lib/glut/glut_dstr.c new file mode 100644 index 0000000000..6084e87dd8 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_dstr.c @@ -0,0 +1,1637 @@ + +/* 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. */ + +#include +#include +#include +#include +#include "glutint.h" + +/* glxcaps matches the criteria macros listed in glutint.h, but + only list the first set (those that correspond to GLX visual + attributes). */ +static int glxcap[NUM_GLXCAPS] = +{ + GLX_RGBA, + GLX_BUFFER_SIZE, + GLX_DOUBLEBUFFER, + GLX_STEREO, + GLX_AUX_BUFFERS, + GLX_RED_SIZE, + GLX_GREEN_SIZE, + GLX_BLUE_SIZE, + GLX_ALPHA_SIZE, + GLX_DEPTH_SIZE, + GLX_STENCIL_SIZE, + GLX_ACCUM_RED_SIZE, + GLX_ACCUM_GREEN_SIZE, + GLX_ACCUM_BLUE_SIZE, + GLX_ACCUM_ALPHA_SIZE, + GLX_LEVEL, +}; + +#ifdef TEST + +#if !defined(_WIN32) +char *__glutProgramName = "dstr"; +Display *__glutDisplay; +int __glutScreen; +XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle, + Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc) = NULL; +char *__glutDisplayString = NULL; +#endif +static int verbose = 0; + +static char *compstr[] = +{ + "none", "=", "!=", "<=", ">=", ">", "<", "~" +}; +static char *capstr[] = +{ + "rgba", "bufsize", "double", "stereo", "auxbufs", "red", "green", "blue", "alpha", + "depth", "stencil", "acred", "acgreen", "acblue", "acalpha", "level", "xvisual", + "transparent", "samples", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor", + "xtruecolor", "xdirectcolor", "slow", "conformant", "num" +}; + +static void +printCriteria(Criterion * criteria, int ncriteria) +{ + int i; + printf("Criteria: %d\n", ncriteria); + for (i = 0; i < ncriteria; i++) { + printf(" %s %s %d\n", + capstr[criteria[i].capability], + compstr[criteria[i].comparison], + criteria[i].value); + } +} + +#endif /* TEST */ + +static int isMesaGLX = -1; + +static int +determineMesaGLX(void) +{ +#ifdef GLX_VERSION_1_1 + const char *vendor, *version, *ch; + + vendor = glXGetClientString(__glutDisplay, GLX_VENDOR); + if (!strcmp(vendor, "Brian Paul")) { + version = glXGetClientString(__glutDisplay, GLX_VERSION); + for (ch = version; *ch != ' ' && *ch != '\0'; ch++); + for (; *ch == ' ' && *ch != '\0'; ch++); + +#define MESA_NAME "Mesa " /* Trailing space is intentional. */ + + if (!strncmp(MESA_NAME, ch, sizeof(MESA_NAME) - 1)) { + return 1; + } + } +#else + /* Recent versions for Mesa should support GLX 1.1 and + therefore glXGetClientString. If we get into this case, + we would be compiling against a true OpenGL not supporting + GLX 1.1, and the resulting compiled library won't work well + with Mesa then. */ +#endif + return 0; +} + +static XVisualInfo ** +getMesaVisualList(int *n) +{ + XVisualInfo **vlist, *vinfo; + int attribs[23]; + int i, x, cnt; + + vlist = (XVisualInfo **) malloc((32 + 16) * sizeof(XVisualInfo *)); + if (!vlist) + __glutFatalError("out of memory."); + + cnt = 0; + for (i = 0; i < 32; i++) { + x = 0; + attribs[x] = GLX_RGBA; + x++; + attribs[x] = GLX_RED_SIZE; + x++; + attribs[x] = 1; + x++; + attribs[x] = GLX_GREEN_SIZE; + x++; + attribs[x] = 1; + x++; + attribs[x] = GLX_BLUE_SIZE; + x++; + attribs[x] = 1; + x++; + if (i & 1) { + attribs[x] = GLX_DEPTH_SIZE; + x++; + attribs[x] = 1; + x++; + } + if (i & 2) { + attribs[x] = GLX_STENCIL_SIZE; + x++; + attribs[x] = 1; + x++; + } + if (i & 4) { + attribs[x] = GLX_ACCUM_RED_SIZE; + x++; + attribs[x] = 1; + x++; + attribs[x] = GLX_ACCUM_GREEN_SIZE; + x++; + attribs[x] = 1; + x++; + attribs[x] = GLX_ACCUM_BLUE_SIZE; + x++; + attribs[x] = 1; + x++; + } + if (i & 8) { + attribs[x] = GLX_ALPHA_SIZE; + x++; + attribs[x] = 1; + x++; + if (i & 4) { + attribs[x] = GLX_ACCUM_ALPHA_SIZE; + x++; + attribs[x] = 1; + x++; + } + } + if (i & 16) { + attribs[x] = GLX_DOUBLEBUFFER; + x++; + } + attribs[x] = None; + x++; + assert(x <= sizeof(attribs) / sizeof(attribs[0])); + vinfo = glXChooseVisual(__glutDisplay, __glutScreen, attribs); + if (vinfo) { + vlist[cnt] = vinfo; + cnt++; + } + } + for (i = 0; i < 16; i++) { + x = 0; + if (i & 1) { + attribs[x] = GLX_DEPTH_SIZE; + x++; + attribs[x] = 1; + x++; + } + if (i & 2) { + attribs[x] = GLX_STENCIL_SIZE; + x++; + attribs[x] = 1; + x++; + } + if (i & 4) { + attribs[x] = GLX_DOUBLEBUFFER; + x++; + } + if (i & 8) { + attribs[x] = GLX_LEVEL; + x++; + attribs[x] = 1; + x++; +#if defined(GLX_TRANSPARENT_TYPE_EXT) && defined(GLX_TRANSPARENT_INDEX_EXT) + attribs[x] = GLX_TRANSPARENT_TYPE_EXT; + x++; + attribs[x] = GLX_TRANSPARENT_INDEX_EXT; + x++; +#endif + } + attribs[x] = None; + x++; + assert(x <= sizeof(attribs) / sizeof(attribs[0])); + vinfo = glXChooseVisual(__glutDisplay, __glutScreen, attribs); + if (vinfo) { + vlist[cnt] = vinfo; + cnt++; + } + } + + *n = cnt; + return vlist; +} + +static FrameBufferMode * +loadVisuals(int *nitems_return) +{ + XVisualInfo *vinfo, **vlist, template; + FrameBufferMode *fbmodes, *mode; + int n, i, j, rc, glcapable; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + int multisample; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + int visual_info; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) + int visual_rating; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + int fbconfig; +#endif + + isMesaGLX = determineMesaGLX(); + if (isMesaGLX) { + vlist = getMesaVisualList(&n); + } else { +#if !defined(_WIN32) + template.screen = __glutScreen; + vinfo = XGetVisualInfo(__glutDisplay, VisualScreenMask, &template, &n); +#else + vinfo = XGetVisualInfo(__glutDisplay, 0, &template, &n); +#endif + if (vinfo == NULL) { + *nitems_return = 0; + return NULL; + } + assert(n > 0); + + /* Make an array of XVisualInfo* pointers to help the Mesa + case because each glXChooseVisual call returns a + distinct XVisualInfo*, not a handy array like + XGetVisualInfo. (Mesa expects us to return the _exact_ + pointer returned by glXChooseVisual so we could not just + copy the returned structure.) */ + vlist = (XVisualInfo **) malloc(n * sizeof(XVisualInfo *)); + if (!vlist) + __glutFatalError("out of memory."); + for (i = 0; i < n; i++) { + vlist[i] = &vinfo[i]; + } + } + +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + multisample = __glutIsSupportedByGLX("GLX_SGIS_multisample"); +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + visual_info = __glutIsSupportedByGLX("GLX_EXT_visual_info"); +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) + visual_rating = __glutIsSupportedByGLX("GLX_EXT_visual_rating"); +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + fbconfig = __glutIsSupportedByGLX("GLX_SGIX_fbconfig"); +#endif + + fbmodes = (FrameBufferMode *) malloc(n * sizeof(FrameBufferMode)); + if (fbmodes == NULL) { + *nitems_return = -1; + return NULL; + } + for (i = 0; i < n; i++) { + mode = &fbmodes[i]; + mode->vi = vlist[i]; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + mode->fbc = NULL; +#endif + rc = glXGetConfig(__glutDisplay, vlist[i], GLX_USE_GL, &glcapable); + if (rc == 0 && glcapable) { + mode->valid = 1; /* Assume the best until proven + otherwise. */ + for (j = 0; j < NUM_GLXCAPS; j++) { + rc = glXGetConfig(__glutDisplay, vlist[i], glxcap[j], &mode->cap[j]); + if (rc != 0) { + mode->valid = 0; + } + } +#if defined(_WIN32) + mode->cap[XVISUAL] = ChoosePixelFormat(XHDC, vlist[i]); +#else + mode->cap[XVISUAL] = (int) vlist[i]->visualid; +#endif + mode->cap[XSTATICGRAY] = 0; + mode->cap[XGRAYSCALE] = 0; + mode->cap[XSTATICCOLOR] = 0; + mode->cap[XPSEUDOCOLOR] = 0; + mode->cap[XTRUECOLOR] = 0; + mode->cap[XDIRECTCOLOR] = 0; +#if !defined(_WIN32) +#if defined(__cplusplus) || defined(c_plusplus) + switch (vlist[i]->c_class) { +#else + switch (vlist[i]->class) { +#endif + case StaticGray: + mode->cap[XSTATICGRAY] = 1; + break; + case GrayScale: + mode->cap[XGRAYSCALE] = 1; + break; + case StaticColor: + mode->cap[XSTATICCOLOR] = 1; + break; + case PseudoColor: + mode->cap[XPSEUDOCOLOR] = 1; + break; + case TrueColor: + mode->cap[XTRUECOLOR] = 1; + break; + case DirectColor: + mode->cap[XDIRECTCOLOR] = 1; + break; + } +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) + if (visual_rating) { + int rating; + +/* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0 + 564 for Alpha did not properly define GLX_VISUAL_CAVEAT_EXT + in despite claiming to support + GLX_EXT_visual_rating. */ +#ifndef GLX_VISUAL_CAVEAT_EXT +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#endif + + rc = glXGetConfig(__glutDisplay, + vlist[i], GLX_VISUAL_CAVEAT_EXT, &rating); + if (rc != 0) { + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; + } else { + switch (rating) { + case GLX_SLOW_VISUAL_EXT: + mode->cap[SLOW] = 1; + mode->cap[CONFORMANT] = 1; + break; + +/* IRIX 5.3 for the R10K Indigo2 may have shipped without this + properly defined in /usr/include/GL/glxtokens.h */ +#ifndef GLX_NON_CONFORMANT_VISUAL_EXT +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#endif + + case GLX_NON_CONFORMANT_VISUAL_EXT: + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 0; + break; + case GLX_NONE_EXT: + default: /* XXX Hopefully this is a good default + assumption. */ + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; + break; + } + } + } else { + mode->cap[TRANSPARENT] = 0; + } +#else + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + if (visual_info) { + int transparent; + +/* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0 + 564 for Alpha did not properly define + GLX_TRANSPARENT_TYPE_EXT in despite claiming to + support GLX_EXT_visual_info. */ +#ifndef GLX_TRANSPARENT_TYPE_EXT +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#endif + + rc = glXGetConfig(__glutDisplay, + vlist[i], GLX_TRANSPARENT_TYPE_EXT, &transparent); + if (rc != 0) { + mode->cap[TRANSPARENT] = 0; + } else { + mode->cap[TRANSPARENT] = (transparent != GLX_NONE_EXT); + } + } else { + mode->cap[TRANSPARENT] = 0; + } +#else + mode->cap[TRANSPARENT] = 0; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (multisample) { + rc = glXGetConfig(__glutDisplay, + vlist[i], GLX_SAMPLES_SGIS, &mode->cap[SAMPLES]); + if (rc != 0) { + mode->cap[SAMPLES] = 0; + } + } else { + mode->cap[SAMPLES] = 0; + } +#else + mode->cap[SAMPLES] = 0; +#endif + } else { +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + if (fbconfig) { + GLXFBConfigSGIX fbc; + int fbconfigID, drawType, renderType; + + fbc = glXGetFBConfigFromVisualSGIX(__glutDisplay, vlist[i]); + if (fbc) { + rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc, + GLX_FBCONFIG_ID_SGIX, &fbconfigID); + if ((rc == 0) && (fbconfigID != None)) { + rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc, + GLX_DRAWABLE_TYPE_SGIX, &drawType); + if ((rc == 0) && (drawType & GLX_WINDOW_BIT_SGIX)) { + rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc, + GLX_RENDER_TYPE_SGIX, &renderType); + if ((rc == 0) && (renderType & GLX_RGBA_BIT_SGIX)) { + mode->fbc = fbc; + mode->valid = 1; /* Assume the best until + proven otherwise. */ + + assert(glxcap[0] == GLX_RGBA); + mode->cap[0] = 1; + + /* Start with "j = 1" to skip the GLX_RGBA attribute. */ + for (j = 1; j < NUM_GLXCAPS; j++) { + rc = glXGetFBConfigAttribSGIX(__glutDisplay, + fbc, glxcap[j], &mode->cap[j]); + if (rc != 0) { + mode->valid = 0; + } + } + + mode->cap[XVISUAL] = (int) vlist[i]->visualid; + mode->cap[XSTATICGRAY] = 0; + mode->cap[XGRAYSCALE] = 0; + mode->cap[XSTATICCOLOR] = 0; + mode->cap[XPSEUDOCOLOR] = 0; + mode->cap[XTRUECOLOR] = 0; + mode->cap[XDIRECTCOLOR] = 0; +#if defined(__cplusplus) || defined(c_plusplus) + switch (vlist[i]->c_class) { +#else + switch (vlist[i]->class) { +#endif + case StaticGray: + mode->cap[XSTATICGRAY] = 1; + break; + case GrayScale: + mode->cap[XGRAYSCALE] = 1; + break; + case StaticColor: + mode->cap[XSTATICCOLOR] = 1; + break; + case PseudoColor: + mode->cap[XPSEUDOCOLOR] = 1; + break; + case TrueColor: + mode->cap[XTRUECOLOR] = 1; + break; + case DirectColor: + mode->cap[XDIRECTCOLOR] = 1; + break; + } +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) + if (visual_rating) { + int rating; + +/* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0 + 564 for Alpha did not properly define GLX_VISUAL_CAVEAT_EXT + in despite claiming to support + GLX_EXT_visual_rating. */ +#ifndef GLX_VISUAL_CAVEAT_EXT +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#endif + + rc = glXGetFBConfigAttribSGIX(__glutDisplay, + fbc, GLX_VISUAL_CAVEAT_EXT, &rating); + if (rc != 0) { + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; + } else { + switch (rating) { + case GLX_SLOW_VISUAL_EXT: + mode->cap[SLOW] = 1; + mode->cap[CONFORMANT] = 1; + break; + +/* IRIX 5.3 for the R10K Indigo2 may have shipped without this + properly defined in /usr/include/GL/glxtokens.h */ +#ifndef GLX_NON_CONFORMANT_VISUAL_EXT +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#endif + + case GLX_NON_CONFORMANT_VISUAL_EXT: + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 0; + break; + case GLX_NONE_EXT: + default: /* XXX Hopefully this is a good + default assumption. */ + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; + break; + } + } + } else { + mode->cap[TRANSPARENT] = 0; + } +#else + mode->cap[SLOW] = 0; + mode->cap[CONFORMANT] = 1; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + if (visual_info) { + int transparent; + +/* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0 + 564 for Alpha did not properly define + GLX_TRANSPARENT_TYPE_EXT in despite claiming to + support GLX_EXT_visual_info. */ +#ifndef GLX_TRANSPARENT_TYPE_EXT +#define GLX_TRANSPARENT_TYPE_EXT 0x23 +#endif + + rc = glXGetFBConfigAttribSGIX(__glutDisplay, + fbc, GLX_TRANSPARENT_TYPE_EXT, &transparent); + if (rc != 0) { + mode->cap[TRANSPARENT] = 0; + } else { + mode->cap[TRANSPARENT] = (transparent != GLX_NONE_EXT); + } + } else { + mode->cap[TRANSPARENT] = 0; + } +#else + mode->cap[TRANSPARENT] = 0; +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (multisample) { + rc = glXGetFBConfigAttribSGIX(__glutDisplay, + fbc, GLX_SAMPLES_SGIS, &mode->cap[SAMPLES]); + if (rc != 0) { + mode->cap[SAMPLES] = 0; + } + } else { + mode->cap[SAMPLES] = 0; + } +#else + mode->cap[SAMPLES] = 0; +#endif + + } else { + /* Fbconfig is not RGBA; GLUT only uses RGBA + FBconfigs. */ + /* XXX Code could be exteneded to handle color + index FBconfigs, but seems a color index + window-renderable FBconfig would also be + advertised as an X visual. */ + mode->valid = 0; + } + } else { + /* Fbconfig does not support window rendering; + not a valid FBconfig for GLUT windows. */ + mode->valid = 0; + } + } else { + /* FBconfig ID is None (zero); not a valid + FBconfig. */ + mode->valid = 0; + } + } else { + /* FBconfig ID is None (zero); not a valid FBconfig. */ + mode->valid = 0; + } + } else { + /* No SGIX_fbconfig GLX sever implementation support. */ + mode->valid = 0; + } +#else + /* No SGIX_fbconfig GLX extension API support. */ + mode->valid = 0; +#endif + } + } + + free(vlist); + *nitems_return = n; + return fbmodes; +} + +static XVisualInfo * +findMatch(FrameBufferMode * fbmodes, int nfbmodes, + Criterion * criteria, int ncriteria, void **fbc) +{ + FrameBufferMode *found; + int *bestScore, *thisScore; + int i, j, numok, result, worse, better; + + found = NULL; + numok = 1; /* "num" capability is indexed from 1, + not 0. */ + + /* XXX alloca canidate. */ + bestScore = (int *) malloc(ncriteria * sizeof(int)); + if (!bestScore) + __glutFatalError("out of memory."); + for (j = 0; j < ncriteria; j++) { + /* Very negative number. */ + bestScore[j] = -32768; + } + + /* XXX alloca canidate. */ + thisScore = (int *) malloc(ncriteria * sizeof(int)); + if (!thisScore) + __glutFatalError("out of memory."); + + for (i = 0; i < nfbmodes; i++) { + if (fbmodes[i].valid) { +#ifdef TEST +#if !defined(_WIN32) + if (verbose) + printf("Visual 0x%x\n", fbmodes[i].vi->visualid); +#endif +#endif + + worse = 0; + better = 0; + + for (j = 0; j < ncriteria; j++) { + int cap, cvalue, fbvalue; + + cap = criteria[j].capability; + cvalue = criteria[j].value; + if (cap == NUM) { + fbvalue = numok; + } else { + fbvalue = fbmodes[i].cap[cap]; + } +#ifdef TEST + if (verbose) + printf(" %s %s %d to %d\n", + capstr[cap], compstr[criteria[j].comparison], cvalue, fbvalue); +#endif + switch (criteria[j].comparison) { + case EQ: + result = cvalue == fbvalue; + thisScore[j] = 1; + break; + case NEQ: + result = cvalue != fbvalue; + thisScore[j] = 1; + break; + case LT: + result = fbvalue < cvalue; + thisScore[j] = fbvalue - cvalue; + break; + case GT: + result = fbvalue > cvalue; + thisScore[j] = fbvalue - cvalue; + break; + case LTE: + result = fbvalue <= cvalue; + thisScore[j] = fbvalue - cvalue; + break; + case GTE: + result = (fbvalue >= cvalue); + thisScore[j] = fbvalue - cvalue; + break; + case MIN: + result = fbvalue >= cvalue; + thisScore[j] = cvalue - fbvalue; + break; + } + +#ifdef TEST + if (verbose) + printf(" result=%d score=%d bestScore=%d\n", result, thisScore[j], bestScore[j]); +#endif + + if (result) { + if (better || thisScore[j] > bestScore[j]) { + better = 1; + } else if (thisScore[j] == bestScore[j]) { + /* Keep looking. */ + } else { + goto nextFBM; + } + } else { + if (cap == NUM) { + worse = 1; + } else { + goto nextFBM; + } + } + + } + + if (better && !worse) { + found = &fbmodes[i]; + for (j = 0; j < ncriteria; j++) { + bestScore[j] = thisScore[j]; + } + } + numok++; + + nextFBM:; + + } + } + free(bestScore); + free(thisScore); + if (found) { +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + *fbc = found->fbc; +#endif + return found->vi; + } else { + return NULL; + } +} + +static int +parseCriteria(char *word, Criterion * criterion, int *mask, + Bool * allowDoubleAsSingle) +{ + char *cstr, *vstr, *response; + int comparator, value; + int rgb, rgba, acc, acca, count, i; + + cstr = strpbrk(word, "=>': + if (cstr[1] == '=') { + comparator = GTE; + vstr = &cstr[2]; + } else { + comparator = GT; + vstr = &cstr[1]; + } + break; + case '<': + if (cstr[1] == '=') { + comparator = LTE; + vstr = &cstr[2]; + } else { + comparator = LT; + vstr = &cstr[1]; + } + break; + case '!': + if (cstr[1] == '=') { + comparator = NEQ; + vstr = &cstr[2]; + } else { + return -1; + } + break; + default: + return -1; + } + value = (int) strtol(vstr, &response, 0); + if (response == vstr) { + /* Not a valid number. */ + return -1; + } + *cstr = '\0'; + } else { + comparator = NONE; + } + switch (word[0]) { + case 'a': + if (!strcmp(word, "alpha")) { + criterion[0].capability = ALPHA_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << RGBA); + *mask |= (1 << ALPHA_SIZE); + *mask |= (1 << RGBA_MODE); + return 1; + } + acca = !strcmp(word, "acca"); + acc = !strcmp(word, "acc"); + if (acc || acca) { + criterion[0].capability = ACCUM_RED_SIZE; + criterion[1].capability = ACCUM_GREEN_SIZE; + criterion[2].capability = ACCUM_BLUE_SIZE; + criterion[3].capability = ACCUM_ALPHA_SIZE; + if (acca) { + count = 4; + } else { + count = 3; + criterion[3].comparison = MIN; + criterion[3].value = 0; + } + if (comparator == NONE) { + comparator = GTE; + value = 8; + } + for (i = 0; i < count; i++) { + criterion[i].comparison = comparator; + criterion[i].value = value; + } + *mask |= (1 << ACCUM_RED_SIZE); + return 4; + } + if (!strcmp(word, "auxbufs")) { + criterion[0].capability = AUX_BUFFERS; + if (comparator == NONE) { + criterion[0].comparison = MIN; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << AUX_BUFFERS); + return 1; + } + return -1; + case 'b': + if (!strcmp(word, "blue")) { + criterion[0].capability = BLUE_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << RGBA); + *mask |= (1 << RGBA_MODE); + return 1; + } + if (!strcmp(word, "buffer")) { + criterion[0].capability = BUFFER_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + return 1; + } + return -1; + case 'c': + if (!strcmp(word, "conformant")) { + criterion[0].capability = CONFORMANT; + if (comparator == NONE) { + criterion[0].comparison = EQ; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << CONFORMANT); + return 1; + } + return -1; + case 'd': + if (!strcmp(word, "depth")) { + criterion[0].capability = DEPTH_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 12; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << DEPTH_SIZE); + return 1; + } + if (!strcmp(word, "double")) { + criterion[0].capability = DOUBLEBUFFER; + if (comparator == NONE) { + criterion[0].comparison = EQ; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << DOUBLEBUFFER); + return 1; + } + return -1; + case 'g': + if (!strcmp(word, "green")) { + criterion[0].capability = GREEN_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << RGBA); + *mask |= (1 << RGBA_MODE); + return 1; + } + return -1; + case 'i': + if (!strcmp(word, "index")) { + criterion[0].capability = RGBA; + criterion[0].comparison = EQ; + criterion[0].value = 0; + *mask |= (1 << RGBA); + *mask |= (1 << CI_MODE); + criterion[1].capability = BUFFER_SIZE; + if (comparator == NONE) { + criterion[1].comparison = GTE; + criterion[1].value = 1; + } else { + criterion[1].comparison = comparator; + criterion[1].value = value; + } + return 2; + } + return -1; + case 'l': + if (!strcmp(word, "luminance")) { + criterion[0].capability = RGBA; + criterion[0].comparison = EQ; + criterion[0].value = 1; + + criterion[1].capability = RED_SIZE; + if (comparator == NONE) { + criterion[1].comparison = GTE; + criterion[1].value = 1; + } else { + criterion[1].comparison = comparator; + criterion[1].value = value; + } + + criterion[2].capability = GREEN_SIZE; + criterion[2].comparison = EQ; + criterion[2].value = 0; + + criterion[3].capability = BLUE_SIZE; + criterion[3].comparison = EQ; + criterion[3].value = 0; + + *mask |= (1 << RGBA); + *mask |= (1 << RGBA_MODE); + *mask |= (1 << LUMINANCE_MODE); + return 4; + } + return -1; + case 'n': + if (!strcmp(word, "num")) { + criterion[0].capability = NUM; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; + case 'r': + if (!strcmp(word, "red")) { + criterion[0].capability = RED_SIZE; + if (comparator == NONE) { + criterion[0].comparison = GTE; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << RGBA); + *mask |= (1 << RGBA_MODE); + return 1; + } + rgba = !strcmp(word, "rgba"); + rgb = !strcmp(word, "rgb"); + if (rgb || rgba) { + criterion[0].capability = RGBA; + criterion[0].comparison = EQ; + criterion[0].value = 1; + + criterion[1].capability = RED_SIZE; + criterion[2].capability = GREEN_SIZE; + criterion[3].capability = BLUE_SIZE; + criterion[4].capability = ALPHA_SIZE; + if (rgba) { + count = 5; + } else { + count = 4; + criterion[4].comparison = MIN; + criterion[4].value = 0; + } + if (comparator == NONE) { + comparator = GTE; + value = 1; + } + for (i = 1; i < count; i++) { + criterion[i].comparison = comparator; + criterion[i].value = value; + } + *mask |= (1 << RGBA); + *mask |= (1 << RGBA_MODE); + return 5; + } + return -1; + case 's': + if (!strcmp(word, "stencil")) { + criterion[0].capability = STENCIL_SIZE; + if (comparator == NONE) { + criterion[0].comparison = MIN; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << STENCIL_SIZE); + return 1; + } + if (!strcmp(word, "single")) { + criterion[0].capability = DOUBLEBUFFER; + if (comparator == NONE) { + criterion[0].comparison = EQ; + criterion[0].value = 0; + *allowDoubleAsSingle = True; + *mask |= (1 << DOUBLEBUFFER); + return 1; + } else { + return -1; + } + } + if (!strcmp(word, "stereo")) { + criterion[0].capability = STEREO; + if (comparator == NONE) { + criterion[0].comparison = EQ; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << STEREO); + return 1; + } + if (!strcmp(word, "samples")) { + criterion[0].capability = SAMPLES; + if (comparator == NONE) { + criterion[0].comparison = LTE; + criterion[0].value = 4; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << SAMPLES); + return 1; + } + if (!strcmp(word, "slow")) { + criterion[0].capability = SLOW; + if (comparator == NONE) { + /* Just "slow" means permit fast visuals, but accept + slow ones in preference. Presumably the slow ones + must be higher quality or something else desirable. */ + criterion[0].comparison = GTE; + criterion[0].value = 0; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + *mask |= (1 << SLOW); + return 1; + } + return -1; +#if defined(_WIN32) + case 'w': + if (!strcmp(word, "win32pfd")) { + criterion[0].capability = XVISUAL; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; +#endif +#if !defined(_WIN32) + case 'x': + if (!strcmp(word, "xvisual")) { + if (comparator == NONE) { + return -1; + } else { + criterion[0].capability = XVISUAL; + criterion[0].comparison = comparator; + criterion[0].value = value; + /* Set everything in "mask" so that no default criteria + get used. Assume the program really wants the + xvisual specified. */ + *mask |= ~0; + return 1; + } + } + /* Be a little over-eager to fill in the comparison and + value so we won't have to replicate the code after each + string match. */ + if (comparator == NONE) { + criterion[0].comparison = EQ; + criterion[0].value = 1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + } + + if (!strcmp(word, "xstaticgray")) { + criterion[0].capability = XSTATICGRAY; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + if (!strcmp(word, "xgrayscale")) { + criterion[0].capability = XGRAYSCALE; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + if (!strcmp(word, "xstaticcolor")) { + criterion[0].capability = XSTATICCOLOR; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + if (!strcmp(word, "xpseudocolor")) { + criterion[0].capability = XPSEUDOCOLOR; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + if (!strcmp(word, "xtruecolor")) { + criterion[0].capability = XTRUECOLOR; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + if (!strcmp(word, "xdirectcolor")) { + criterion[0].capability = XDIRECTCOLOR; + *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual + class selected. */ + return 1; + } + return -1; +#endif + default: + return -1; + } +} + +static Criterion * +parseModeString(char *mode, int *ncriteria, Bool * allowDoubleAsSingle, + Criterion * requiredCriteria, int nRequired, int requiredMask) +{ + Criterion *criteria = NULL; + int n, mask, parsed, i; + char *copy, *word; + + *allowDoubleAsSingle = False; + copy = __glutStrdup(mode); + /* Attempt to estimate how many criteria entries should be + needed. */ + n = 0; + word = strtok(copy, " \t"); + while (word) { + n++; + word = strtok(NULL, " \t"); + } + /* Overestimate by 4 times ("rgba" might add four criteria + entries) plus add in possible defaults plus space for + required criteria. */ + criteria = (Criterion *) malloc((4 * n + 30 + nRequired) * sizeof(Criterion)); + if (!criteria) { + __glutFatalError("out of memory."); + } + + /* Re-copy the copy of the mode string. */ + strcpy(copy, mode); + + /* First add the required criteria (these match at the + highest priority). Typically these will be used to force a + specific level (layer), transparency, and/or visual type. */ + mask = requiredMask; + for (i = 0; i < nRequired; i++) { + criteria[i] = requiredCriteria[i]; + } + n = nRequired; + + word = strtok(copy, " \t"); + while (word) { + parsed = parseCriteria(word, &criteria[n], &mask, allowDoubleAsSingle); + if (parsed >= 0) { + n += parsed; + } else { + __glutWarning("Unrecognized display string word: %s (ignoring)\n", word); + } + word = strtok(NULL, " \t"); + } + +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) { + if (!(mask & (1 << SAMPLES))) { + criteria[n].capability = SAMPLES; + criteria[n].comparison = EQ; + criteria[n].value = 0; + n++; + } else { + /* Multisample visuals are marked nonconformant. If + multisampling was requeste and no conformant + preference was set, assume that we will settle for a + non-conformant visual to get multisampling. */ + if (!(mask & (1 << CONFORMANT))) { + criteria[n].capability = CONFORMANT; + criteria[n].comparison = MIN; + criteria[n].value = 0; + n++; + mask |= (1 << CONFORMANT); + } + } + } +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + if (__glutIsSupportedByGLX("GLX_EXT_visual_info")) { + if (!(mask & (1 << TRANSPARENT))) { + criteria[n].capability = TRANSPARENT; + criteria[n].comparison = EQ; + criteria[n].value = 0; + n++; + } + } +#endif +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) + if (__glutIsSupportedByGLX("GLX_EXT_visual_rating")) { + if (!(mask & (1 << SLOW))) { + criteria[n].capability = SLOW; + criteria[n].comparison = EQ; + criteria[n].value = 0; + n++; + } + if (!(mask & (1 << CONFORMANT))) { + criteria[n].capability = CONFORMANT; + criteria[n].comparison = EQ; + criteria[n].value = 1; + n++; + } + } +#endif + if (!(mask & (1 << ACCUM_RED_SIZE))) { + criteria[n].capability = ACCUM_RED_SIZE; + criteria[n].comparison = MIN; + criteria[n].value = 0; + criteria[n + 1].capability = ACCUM_GREEN_SIZE; + criteria[n + 1].comparison = MIN; + criteria[n + 1].value = 0; + criteria[n + 2].capability = ACCUM_BLUE_SIZE; + criteria[n + 2].comparison = MIN; + criteria[n + 2].value = 0; + criteria[n + 3].capability = ACCUM_ALPHA_SIZE; + criteria[n + 3].comparison = MIN; + criteria[n + 3].value = 0; + n += 4; + } + if (!(mask & (1 << AUX_BUFFERS))) { + criteria[n].capability = AUX_BUFFERS; + criteria[n].comparison = MIN; + criteria[n].value = 0; + n++; + } + if (!(mask & (1 << RGBA))) { + criteria[n].capability = RGBA; + criteria[n].comparison = EQ; + criteria[n].value = 1; + criteria[n + 1].capability = RED_SIZE; + criteria[n + 1].comparison = GTE; + criteria[n + 1].value = 1; + criteria[n + 2].capability = GREEN_SIZE; + criteria[n + 2].comparison = GTE; + criteria[n + 2].value = 1; + criteria[n + 3].capability = BLUE_SIZE; + criteria[n + 3].comparison = GTE; + criteria[n + 3].value = 1; + criteria[n + 4].capability = ALPHA_SIZE; + criteria[n + 4].comparison = MIN; + criteria[n + 4].value = 0; + n += 5; + mask |= (1 << RGBA_MODE); + } +#if !defined(_WIN32) + if (!(mask & (1 << XSTATICGRAY))) { + assert(isMesaGLX != -1); + if ((mask & (1 << RGBA_MODE)) && !isMesaGLX) { + /* Normally, request an RGBA mode visual be TrueColor, + except in the case of Mesa where we trust Mesa (and + other code in GLUT) to handle any type of RGBA visual + reasonably. */ + if (mask & (1 << LUMINANCE_MODE)) { + /* If RGBA luminance was requested, actually go for + a StaticGray visual. */ + criteria[n].capability = XSTATICGRAY; + } else { + criteria[n].capability = XTRUECOLOR; + } + criteria[n].value = 1; + criteria[n].comparison = EQ; + + n++; + } + if (mask & (1 << CI_MODE)) { + criteria[n].capability = XPSEUDOCOLOR; + criteria[n].value = 1; + criteria[n].comparison = EQ; + n++; + } + } +#endif + if (!(mask & (1 << STEREO))) { + criteria[n].capability = STEREO; + criteria[n].comparison = EQ; + criteria[n].value = 0; + n++; + } + if (!(mask & (1 << DOUBLEBUFFER))) { + criteria[n].capability = DOUBLEBUFFER; + criteria[n].comparison = EQ; + criteria[n].value = 0; + *allowDoubleAsSingle = True; + n++; + } + if (!(mask & (1 << DEPTH_SIZE))) { + criteria[n].capability = DEPTH_SIZE; + criteria[n].comparison = MIN; + criteria[n].value = 0; + n++; + } + if (!(mask & (1 << STENCIL_SIZE))) { + criteria[n].capability = STENCIL_SIZE; + criteria[n].comparison = MIN; + criteria[n].value = 0; + n++; + } + if (!(mask & (1 << LEVEL))) { + criteria[n].capability = LEVEL; + criteria[n].comparison = EQ; + criteria[n].value = 0; + n++; + } + if (n) { + /* Since over-estimated the size needed; squeeze it down to + reality. */ + criteria = (Criterion *) realloc(criteria, n * sizeof(Criterion)); + if (!criteria) { + /* Should never happen since should be shrinking down! */ + __glutFatalError("out of memory."); + } + } else { + /* For portability, avoid "realloc(ptr,0)" call. */ + free(criteria); + criteria = NULL; + } + + free(copy); + *ncriteria = n; + return criteria; +} + +static FrameBufferMode *fbmodes = NULL; +static int nfbmodes = 0; + +static XVisualInfo * +getVisualInfoFromString(char *string, Bool * treatAsSingle, + Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc) +{ + Criterion *criteria; + XVisualInfo *visinfo; + Bool allowDoubleAsSingle; + int ncriteria, i; + + /* In WIN32, after changing display settings, the visuals might change. + (e.g. if entering game mode with a different bitdepth!) + Therefore, reload the visuals each time they are queried. */ +#ifdef WIN32 + if (fbmodes) { + free(fbmodes); + fbmodes = NULL; + nfbmodes = 0; + } +#endif + if (!fbmodes) { + fbmodes = loadVisuals(&nfbmodes); + } + criteria = parseModeString(string, &ncriteria, + &allowDoubleAsSingle, requiredCriteria, nRequired, requiredMask); + if (criteria == NULL) { + __glutWarning("failed to parse mode string"); + return NULL; + } +#ifdef TEST + printCriteria(criteria, ncriteria); +#endif + visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc); + if (visinfo) { + *treatAsSingle = 0; + } else { + if (allowDoubleAsSingle) { + /* Rewrite criteria so that we now look for a double + buffered visual which will then get treated as a + single buffered visual. */ + for (i = 0; i < ncriteria; i++) { + if (criteria[i].capability == DOUBLEBUFFER + && criteria[i].comparison == EQ + && criteria[i].value == 0) { + criteria[i].value = 1; + } + } + visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc); + if (visinfo) { + *treatAsSingle = 1; + } + } + } + free(criteria); + + if (visinfo) { +#if defined(_WIN32) + /* We could have a valid pixel format for drawing to a + bitmap. However, we don't want to draw into a bitmap, we + need one that can be used with a window, so make sure + that this is true. */ + if (!(visinfo->dwFlags & PFD_DRAW_TO_WINDOW)) + return NULL; +#endif + return visinfo; + } else { + return NULL; + } +} + +/* CENTRY */ +void APIENTRY +glutInitDisplayString(const char *string) +{ +#ifdef _WIN32 + XHDC = GetDC(GetDesktopWindow()); +#endif + + __glutDetermineVisualFromString = getVisualInfoFromString; + if (__glutDisplayString) { + free(__glutDisplayString); + } + if (string) { + __glutDisplayString = __glutStrdup(string); + if (!__glutDisplayString) + __glutFatalError("out of memory."); + } else { + __glutDisplayString = NULL; + } +} +/* ENDCENTRY */ + +#ifdef TEST + +Criterion requiredWindowCriteria[] = +{ + {LEVEL, EQ, 0}, + {TRANSPARENT, EQ, 0} +}; +int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion); +int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT); + +Criterion requiredOverlayCriteria[] = +{ + {LEVEL, EQ, 1}, + {TRANSPARENT, EQ, 1}, + {XPSEUDOCOLOR, EQ, 1}, + {RGBA, EQ, 0}, + {BUFFER_SIZE, GTE, 1} +}; +int numRequiredOverlayCriteria = sizeof(requiredOverlayCriteria) / sizeof(Criterion); +int requiredOverlayCriteriaMask = +(1 << LEVEL) | (1 << TRANSPARENT) | (1 << XSTATICGRAY) | (1 << RGBA) | (1 << CI_MODE); + +int +main(int argc, char **argv) +{ + Display *dpy; + XVisualInfo *vinfo; + Bool treatAsSingle; + char *str, buffer[1024]; + int tty = isatty(fileno(stdin)); + int overlay = 0, showconfig = 0; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + GLXFBConfigSGIX fbc; +#else + void *fbc; +#endif + +#if !defined(_WIN32) + dpy = XOpenDisplay(NULL); + if (dpy == NULL) { + printf("Could not connect to X server\n"); + exit(1); + } + __glutDisplay = dpy; + __glutScreen = DefaultScreen(__glutDisplay); +#endif + while (!feof(stdin)) { + if (tty) + printf("dstr> "); + str = gets(buffer); + if (str) { + printf("\n"); + if (!strcmp("v", str)) { + verbose = 1 - verbose; + printf("verbose = %d\n\n", verbose); + } else if (!strcmp("s", str)) { + showconfig = 1 - showconfig; + printf("showconfig = %d\n\n", showconfig); + } else if (!strcmp("o", str)) { + overlay = 1 - overlay; + printf("overlay = %d\n\n", overlay); + } else { + if (overlay) { + vinfo = getVisualInfoFromString(str, &treatAsSingle, + requiredOverlayCriteria, numRequiredOverlayCriteria, requiredOverlayCriteriaMask, (void**) &fbc); + } else { + vinfo = getVisualInfoFromString(str, &treatAsSingle, + requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, (void**) &fbc); + } + if (vinfo) { + printf("\n"); + if (!tty) + printf("Display string: %s", str); +#ifdef _WIN32 + printf("Visual = 0x%x\n", 0); +#else + printf("Visual = 0x%x%s\n", vinfo->visualid, fbc ? " (needs FBC)" : ""); +#endif + if (treatAsSingle) { + printf("Treat as SINGLE.\n"); + } + if (showconfig) { + int glxCapable, bufferSize, level, renderType, doubleBuffer, + stereo, auxBuffers, redSize, greenSize, blueSize, + alphaSize, depthSize, stencilSize, acRedSize, acGreenSize, + acBlueSize, acAlphaSize; + + glXGetConfig(dpy, vinfo, GLX_BUFFER_SIZE, &bufferSize); + glXGetConfig(dpy, vinfo, GLX_LEVEL, &level); + glXGetConfig(dpy, vinfo, GLX_RGBA, &renderType); + glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &doubleBuffer); + glXGetConfig(dpy, vinfo, GLX_STEREO, &stereo); + glXGetConfig(dpy, vinfo, GLX_AUX_BUFFERS, &auxBuffers); + glXGetConfig(dpy, vinfo, GLX_RED_SIZE, &redSize); + glXGetConfig(dpy, vinfo, GLX_GREEN_SIZE, &greenSize); + glXGetConfig(dpy, vinfo, GLX_BLUE_SIZE, &blueSize); + glXGetConfig(dpy, vinfo, GLX_ALPHA_SIZE, &alphaSize); + glXGetConfig(dpy, vinfo, GLX_DEPTH_SIZE, &depthSize); + glXGetConfig(dpy, vinfo, GLX_STENCIL_SIZE, &stencilSize); + glXGetConfig(dpy, vinfo, GLX_ACCUM_RED_SIZE, &acRedSize); + glXGetConfig(dpy, vinfo, GLX_ACCUM_GREEN_SIZE, &acGreenSize); + glXGetConfig(dpy, vinfo, GLX_ACCUM_BLUE_SIZE, &acBlueSize); + glXGetConfig(dpy, vinfo, GLX_ACCUM_ALPHA_SIZE, &acAlphaSize); + printf("RGBA = (%d, %d, %d, %d)\n", redSize, greenSize, blueSize, alphaSize); + printf("acc = (%d, %d, %d, %d)\n", acRedSize, acGreenSize, acBlueSize, acAlphaSize); + printf("db = %d\n", doubleBuffer); + printf("str = %d\n", stereo); + printf("aux = %d\n", auxBuffers); + printf("lvl = %d\n", level); + printf("buf = %d\n", bufferSize); + printf("rgba = %d\n", renderType); + printf("z = %d\n", depthSize); + printf("s = %d\n", stencilSize); + } + } else { + printf("\n"); + printf("No match.\n"); + } + printf("\n"); + } + } + } + printf("\n"); + return 0; +} +#endif diff --git a/lib/glut-3.7.6/lib/glut/glut_event.c b/lib/glut-3.7.6/lib/glut/glut_event.c new file mode 100644 index 0000000000..ca71b04782 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_event.c @@ -0,0 +1,1386 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1997, 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 +#include +#include +#include /* Some FD_ZERO macros use memset without + prototyping memset. */ + +/* Much of the following #ifdef logic to include the proper + prototypes for the select system call is based on logic + from the X11R6.3 version of . */ + +#if !defined(_WIN32) +# ifdef __sgi +# include /* prototype for bzero used by FD_ZERO */ +# endif +# if (defined(SVR4) || defined(CRAY) || defined(AIXV3)) && !defined(FD_SETSIZE) +# include /* select system call interface */ +# ifdef luna +# include +# endif +# endif + /* AIX 4.2 fubar-ed , so go to heroic measures to get it */ +# if defined(AIXV4) && !defined(NFDBITS) +# include +# endif +#endif /* !_WIN32 */ + +#include + +#if !defined(_WIN32) +# if defined(__vms) && ( __VMS_VER < 70000000 ) +# include +# else +# ifndef __vms +# include +# endif +# endif +# include +# include +# include +#else +# ifdef __CYGWIN32__ +# include +# else +# include +# endif +# ifdef __hpux + /* XXX Bert Gijsbers reports that HP-UX + needs different keysyms for the End, Insert, and Delete keys + to work on an HP 715. It would be better if HP generated + standard keysyms for standard keys. */ +# include +# endif +#endif /* !_WIN32 */ + +#if defined(__vms) && ( __VMS_VER < 70000000 ) +#include +#include +extern int SYS$CLREF(int efn); +extern int SYS$SETIMR(unsigned int efn, struct timeval *timeout, void *ast, + unsigned int request_id, unsigned int flags); +extern int SYS$WFLOR(unsigned int efn, unsigned int mask); +extern int SYS$CANTIM(unsigned int request_id, unsigned int mode); +#endif /* __vms, VMs 6.2 or earlier */ + +#include "glutint.h" + +static GLUTtimer *freeTimerList = NULL; + +GLUTidleCB __glutIdleFunc = NULL; +GLUTtimer *__glutTimerList = NULL; +#ifdef SUPPORT_FORTRAN +GLUTtimer *__glutNewTimer; +#endif +GLUTwindow *__glutWindowWorkList = NULL; +GLUTmenu *__glutMappedMenu; +GLUTmenu *__glutCurrentMenu = NULL; + +void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *); +#if !defined(_WIN32) +void (*__glutMenuItemEnterOrLeave)(GLUTmenuItem * item, int num, int type) = NULL; +void (*__glutFinishMenu)(Window win, int x, int y); +void (*__glutPaintMenu)(GLUTmenu * menu); +void (*__glutStartMenu)(GLUTmenu * menu, GLUTwindow * window, int x, int y, int x_win, int y_win); +GLUTmenu * (*__glutGetMenuByNum)(int menunum); +GLUTmenuItem * (*__glutGetMenuItem)(GLUTmenu * menu, Window win, int *which); +GLUTmenu * (*__glutGetMenu)(Window win); +#endif + +Atom __glutMotifHints = None; +/* Modifier mask of ~0 implies not in core input callback. */ +unsigned int __glutModifierMask = (unsigned int) ~0; +int __glutWindowDamaged = 0; + +void APIENTRY +glutIdleFunc(GLUTidleCB idleFunc) +{ + __glutIdleFunc = idleFunc; +} + +void APIENTRY +glutTimerFunc(unsigned int interval, GLUTtimerCB timerFunc, int value) +{ + GLUTtimer *timer, *other; + GLUTtimer **prevptr; + struct timeval now; + + if (!timerFunc) + return; + + if (freeTimerList) { + timer = freeTimerList; + freeTimerList = timer->next; + } else { + timer = (GLUTtimer *) malloc(sizeof(GLUTtimer)); + if (!timer) + __glutFatalError("out of memory."); + } + + timer->func = timerFunc; +#if defined(__vms) && ( __VMS_VER < 70000000 ) + /* VMS time is expressed in units of 100 ns */ + timer->timeout.val = interval * TICKS_PER_MILLISECOND; +#else + timer->timeout.tv_sec = (int) interval / 1000; + timer->timeout.tv_usec = (int) (interval % 1000) * 1000; +#endif + timer->value = value; + timer->next = NULL; + GETTIMEOFDAY(&now); + ADD_TIME(timer->timeout, timer->timeout, now); + prevptr = &__glutTimerList; + other = *prevptr; + while (other && IS_AFTER(other->timeout, timer->timeout)) { + prevptr = &other->next; + other = *prevptr; + } + timer->next = other; +#ifdef SUPPORT_FORTRAN + __glutNewTimer = timer; /* for Fortran binding! */ +#endif + *prevptr = timer; +} + +void +handleTimeouts(void) +{ + struct timeval now; + GLUTtimer *timer; + + /* Assumption is that __glutTimerList is already determined + to be non-NULL. */ + GETTIMEOFDAY(&now); + while (IS_AT_OR_AFTER(__glutTimerList->timeout, now)) { + timer = __glutTimerList; + timer->func(timer->value); + __glutTimerList = timer->next; + timer->next = freeTimerList; + freeTimerList = timer; + if (!__glutTimerList) + break; + } +} + +void +__glutPutOnWorkList(GLUTwindow * window, int workMask) +{ + if (window->workMask) { + /* Already on list; just OR in new workMask. */ + window->workMask |= workMask; + } else { + /* Update work mask and add to window work list. */ + window->workMask = workMask; + /* Assert that if the window does not have a + workMask already, the window should definitely + not be the head of the work list. */ + assert(window != __glutWindowWorkList); + window->prevWorkWin = __glutWindowWorkList; + __glutWindowWorkList = window; + } +} + +void +__glutPostRedisplay(GLUTwindow * window, int layerMask) +{ + int shown = (layerMask & (GLUT_REDISPLAY_WORK | GLUT_REPAIR_WORK)) ? + window->shownState : window->overlay->shownState; + + /* Post a redisplay if the window is visible (or the + visibility of the window is unknown, ie. window->visState + == -1) _and_ the layer is known to be shown. */ + if (window->visState != GLUT_HIDDEN + && window->visState != GLUT_FULLY_COVERED && shown) { + __glutPutOnWorkList(window, layerMask); + } +} + +/* CENTRY */ +void APIENTRY +glutPostRedisplay(void) +{ + __glutPostRedisplay(__glutCurrentWindow, GLUT_REDISPLAY_WORK); +} + +/* The advantage of this routine is that it saves the cost of a + glutSetWindow call (entailing an expensive OpenGL context switch), + particularly useful when multiple windows need redisplays posted at + the same times. See also glutPostWindowOverlayRedisplay. */ +void APIENTRY +glutPostWindowRedisplay(int win) +{ + __glutPostRedisplay(__glutWindowList[win - 1], GLUT_REDISPLAY_WORK); +} + +/* ENDCENTRY */ +static GLUTeventParser *eventParserList = NULL; + +/* __glutRegisterEventParser allows another module to register + to intercept X events types not otherwise acted on by the + GLUT processEventsAndTimeouts routine. The X Input + extension support code uses an event parser for handling X + Input extension events. */ + +void +__glutRegisterEventParser(GLUTeventParser * parser) +{ + parser->next = eventParserList; + eventParserList = parser; +} + +static void +markWindowHidden(GLUTwindow * window) +{ + if (GLUT_HIDDEN != window->visState) { + GLUTwindow *child; + + if (window->windowStatus) { + window->visState = GLUT_HIDDEN; + __glutSetWindow(window); + window->windowStatus(GLUT_HIDDEN); + } + /* An unmap is only reported on a single window; its + descendents need to know they are no longer visible. */ + child = window->children; + while (child) { + markWindowHidden(child); + child = child->siblings; + } + } +} + +#if !defined(_WIN32) + +static void +purgeStaleWindow(Window win) +{ + GLUTstale **pEntry = &__glutStaleWindowList; + GLUTstale *entry = __glutStaleWindowList; + + /* Tranverse singly-linked stale window list look for the + window ID. */ + while (entry) { + if (entry->win == win) { + /* Found it; delete it. */ + *pEntry = entry->next; + free(entry); + return; + } else { + pEntry = &entry->next; + entry = *pEntry; + } + } +} + +/* Unlike XNextEvent, if a signal arrives, + interruptibleXNextEvent will return (with a zero return + value). This helps GLUT drop out of XNextEvent if a signal + is delivered. The intent is so that a GLUT program can call + glutIdleFunc in a signal handler to register an idle func + and then immediately get dropped into the idle func (after + returning from the signal handler). The idea is to make + GLUT's main loop reliably interruptible by signals. */ +static int +interruptibleXNextEvent(Display * dpy, XEvent * event) +{ + fd_set fds; + int rc; + + /* Flush X protocol since XPending does not do this + implicitly. */ + XFlush(__glutDisplay); + for (;;) { + if (XPending(__glutDisplay)) { + XNextEvent(dpy, event); + return 1; + } + FD_ZERO(&fds); + FD_SET(__glutConnectionFD, &fds); + rc = select(__glutConnectionFD + 1, &fds, + NULL, NULL, NULL); + if (rc < 0) { + if (errno == EINTR) { + return 0; + } else { + __glutFatalError("select error."); + } + } + } +} + +#endif + +static void +processEventsAndTimeouts(void) +{ +#if defined ( _WIN32 ) + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + if ( msg.message == WM_QUIT ) { + exit( 0 ); + } + } + if (__glutTimerList) { + handleTimeouts(); + } +#else /* _WIN32 */ + + do { + static int mappedMenuButton; + GLUTeventParser *parser; + XEvent event, ahead; + GLUTwindow *window; + GLUTkeyboardCB keyboard; + GLUTspecialCB special; + int gotEvent, width, height; + + gotEvent = interruptibleXNextEvent(__glutDisplay, &event); + if (gotEvent) { + switch (event.type) { + case MappingNotify: + XRefreshKeyboardMapping((XMappingEvent *) & event); + break; + case ConfigureNotify: + window = __glutGetWindow(event.xconfigure.window); + if (window) { + if (window->win != event.xconfigure.window) { + /* Ignore ConfigureNotify sent to the overlay + planes. GLUT could get here because overlays + select for StructureNotify events to receive + DestroyNotify. */ + break; + } + width = event.xconfigure.width; + height = event.xconfigure.height; + if (width != window->width || height != window->height) { + if (window->overlay) { + XResizeWindow(__glutDisplay, window->overlay->win, width, height); + } + window->width = width; + window->height = height; + __glutSetWindow(window); + /* Do not execute OpenGL out of sequence with + respect to the XResizeWindow request! */ + glXWaitX(); + window->reshape(width, height); + window->forceReshape = False; + /* A reshape should be considered like posting a + repair; this is necessary for the "Mesa + glXSwapBuffers to repair damage" hack to operate + correctly. Without it, there's not an initial + back buffer render from which to blit from when + damage happens to the window. */ + __glutPostRedisplay(window, GLUT_REPAIR_WORK); + } + } + break; + case Expose: + /* compress expose events */ + while (XEventsQueued(__glutDisplay, QueuedAfterReading) + > 0) { + XPeekEvent(__glutDisplay, &ahead); + if (ahead.type != Expose || + ahead.xexpose.window != event.xexpose.window) { + break; + } + XNextEvent(__glutDisplay, &event); + } + if (event.xexpose.count == 0) { + GLUTmenu *menu; + + if (__glutMappedMenu && + (menu = __glutGetMenu(event.xexpose.window))) { + __glutPaintMenu(menu); + } else { + window = __glutGetWindow(event.xexpose.window); + if (window) { + if (window->win == event.xexpose.window) { + __glutPostRedisplay(window, GLUT_REPAIR_WORK); + } else if (window->overlay && window->overlay->win == event.xexpose.window) { + __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK); + } + } + } + } else { + /* there are more exposes to read; wait to redisplay */ + } + break; + case ButtonPress: + case ButtonRelease: + if (__glutMappedMenu && event.type == ButtonRelease + && mappedMenuButton == event.xbutton.button) { + /* Menu is currently popped up and its button is + released. */ + __glutFinishMenu(event.xbutton.window, event.xbutton.x, event.xbutton.y); + } else { + window = __glutGetWindow(event.xbutton.window); + if (window) { + GLUTmenu *menu; + int menuNum; + + menuNum = window->menu[event.xbutton.button - 1]; + /* Make sure that __glutGetMenuByNum is only called if there + really is a menu present. */ + if ((menuNum > 0) && (menu = __glutGetMenuByNum(menuNum))) { + if (event.type == ButtonPress && !__glutMappedMenu) { + __glutStartMenu(menu, window, + event.xbutton.x_root, event.xbutton.y_root, + event.xbutton.x, event.xbutton.y); + mappedMenuButton = event.xbutton.button; + } else { + /* Ignore a release of a button with a menu + attatched to it when no menu is popped up, + or ignore a press when another menu is + already popped up. */ + } + } else if (window->mouse) { + __glutSetWindow(window); + __glutModifierMask = event.xbutton.state; + window->mouse(event.xbutton.button - 1, + event.type == ButtonRelease ? + GLUT_UP : GLUT_DOWN, + event.xbutton.x, event.xbutton.y); + __glutModifierMask = ~0; + } else { + /* Stray mouse events. Ignore. */ + } + } else { + /* Window might have been destroyed and all the + events for the window may not yet be received. */ + } + } + break; + case MotionNotify: + if (!__glutMappedMenu) { + window = __glutGetWindow(event.xmotion.window); + if (window) { + /* If motion function registered _and_ buttons held + * down, call motion function... */ + if (window->motion && event.xmotion.state & + (Button1Mask | Button2Mask | Button3Mask)) { + __glutSetWindow(window); + window->motion(event.xmotion.x, event.xmotion.y); + } + /* If passive motion function registered _and_ + buttons not held down, call passive motion + function... */ + else if (window->passive && + ((event.xmotion.state & + (Button1Mask | Button2Mask | Button3Mask)) == + 0)) { + __glutSetWindow(window); + window->passive(event.xmotion.x, + event.xmotion.y); + } + } + } else { + /* Motion events are thrown away when a pop up menu + is active. */ + } + break; + case KeyPress: + case KeyRelease: + window = __glutGetWindow(event.xkey.window); + if (!window) { + break; + } + if (event.type == KeyPress) { + keyboard = window->keyboard; + } else { + + /* If we are ignoring auto repeated keys for this window, + check if the next event in the X event queue is a KeyPress + for the exact same key (and at the exact same time) as the + key being released. The X11 protocol will send auto + repeated keys as such KeyRelease/KeyPress pairs. */ + + if (window->ignoreKeyRepeat) { + if (XEventsQueued(__glutDisplay, QueuedAfterReading)) { + XPeekEvent(__glutDisplay, &ahead); + if (ahead.type == KeyPress + && ahead.xkey.window == event.xkey.window + && ahead.xkey.keycode == event.xkey.keycode + && ahead.xkey.time == event.xkey.time) { + /* Pop off the repeated KeyPress and ignore + the auto repeated KeyRelease/KeyPress pair. */ + XNextEvent(__glutDisplay, &event); + break; + } + } + } + keyboard = window->keyboardUp; + } + if (keyboard) { + char tmp[1]; + int rc; + + rc = XLookupString(&event.xkey, tmp, sizeof(tmp), + NULL, NULL); + if (rc) { + __glutSetWindow(window); + __glutModifierMask = event.xkey.state; + keyboard(tmp[0], + event.xkey.x, event.xkey.y); + __glutModifierMask = ~0; + break; + } + } + if (event.type == KeyPress) { + special = window->special; + } else { + special = window->specialUp; + } + if (special) { + KeySym ks; + int key; + +/* Introduced in X11R6: (Partial list of) Keypad Functions. Define + in place in case compiling against an older pre-X11R6 + X11/keysymdef.h file. */ +#ifndef XK_KP_Home +#define XK_KP_Home 0xFF95 +#endif +#ifndef XK_KP_Left +#define XK_KP_Left 0xFF96 +#endif +#ifndef XK_KP_Up +#define XK_KP_Up 0xFF97 +#endif +#ifndef XK_KP_Right +#define XK_KP_Right 0xFF98 +#endif +#ifndef XK_KP_Down +#define XK_KP_Down 0xFF99 +#endif +#ifndef XK_KP_Prior +#define XK_KP_Prior 0xFF9A +#endif +#ifndef XK_KP_Next +#define XK_KP_Next 0xFF9B +#endif +#ifndef XK_KP_End +#define XK_KP_End 0xFF9C +#endif +#ifndef XK_KP_Insert +#define XK_KP_Insert 0xFF9E +#endif +#ifndef XK_KP_Delete +#define XK_KP_Delete 0xFF9F +#endif + + ks = XLookupKeysym((XKeyEvent *) & event, 0); + /* XXX Verbose, but makes no assumptions about keysym + layout. */ + switch (ks) { +/* *INDENT-OFF* */ + /* function keys */ + case XK_F1: key = GLUT_KEY_F1; break; + case XK_F2: key = GLUT_KEY_F2; break; + case XK_F3: key = GLUT_KEY_F3; break; + case XK_F4: key = GLUT_KEY_F4; break; + case XK_F5: key = GLUT_KEY_F5; break; + case XK_F6: key = GLUT_KEY_F6; break; + case XK_F7: key = GLUT_KEY_F7; break; + case XK_F8: key = GLUT_KEY_F8; break; + case XK_F9: key = GLUT_KEY_F9; break; + case XK_F10: key = GLUT_KEY_F10; break; + case XK_F11: key = GLUT_KEY_F11; break; + case XK_F12: key = GLUT_KEY_F12; break; + /* directional keys */ + case XK_KP_Left: + case XK_Left: key = GLUT_KEY_LEFT; break; + case XK_KP_Up: /* Introduced in X11R6. */ + case XK_Up: key = GLUT_KEY_UP; break; + case XK_KP_Right: /* Introduced in X11R6. */ + case XK_Right: key = GLUT_KEY_RIGHT; break; + case XK_KP_Down: /* Introduced in X11R6. */ + case XK_Down: key = GLUT_KEY_DOWN; break; +/* *INDENT-ON* */ + + case XK_KP_Prior: /* Introduced in X11R6. */ + case XK_Prior: + /* XK_Prior same as X11R6's XK_Page_Up */ + key = GLUT_KEY_PAGE_UP; + break; + case XK_KP_Next: /* Introduced in X11R6. */ + case XK_Next: + /* XK_Next same as X11R6's XK_Page_Down */ + key = GLUT_KEY_PAGE_DOWN; + break; + case XK_KP_Home: /* Introduced in X11R6. */ + case XK_Home: + key = GLUT_KEY_HOME; + break; +#ifdef __hpux + case XK_Select: +#endif + case XK_KP_End: /* Introduced in X11R6. */ + case XK_End: + key = GLUT_KEY_END; + break; +#ifdef __hpux + case XK_InsertChar: +#endif + case XK_KP_Insert: /* Introduced in X11R6. */ + case XK_Insert: + key = GLUT_KEY_INSERT; + break; +#ifdef __hpux + case XK_DeleteChar: +#endif + case XK_KP_Delete: /* Introduced in X11R6. */ + /* The Delete character is really an ASCII key. */ + __glutSetWindow(window); + keyboard(127, /* ASCII Delete character. */ + event.xkey.x, event.xkey.y); + goto skip; + default: + goto skip; + } + __glutSetWindow(window); + __glutModifierMask = event.xkey.state; + special(key, event.xkey.x, event.xkey.y); + __glutModifierMask = ~0; + skip:; + } + break; + case EnterNotify: + case LeaveNotify: + if (event.xcrossing.mode != NotifyNormal || + event.xcrossing.detail == NotifyNonlinearVirtual || + event.xcrossing.detail == NotifyVirtual) { + + /* Careful to ignore Enter/LeaveNotify events that + come from the pop-up menu pointer grab and ungrab. + Also, ignore "virtual" Enter/LeaveNotify events + since they represent the pointer passing through + the window hierarchy without actually entering or + leaving the actual real estate of a window. */ + + break; + } + if (__glutMappedMenu) { + GLUTmenuItem *item; + int num; + + item = __glutGetMenuItem(__glutMappedMenu, + event.xcrossing.window, &num); + if (item) { + __glutMenuItemEnterOrLeave(item, num, event.type); + break; + } + } + window = __glutGetWindow(event.xcrossing.window); + if (window) { + if (window->entry) { + if (event.type == EnterNotify) { + + /* With overlays established, X can report two + enter events for both the overlay and normal + plane window. Do not generate a second enter + callback if we reported one without an + intervening leave. */ + + if (window->entryState != EnterNotify) { + int num = window->num; + Window xid = window->win; + + window->entryState = EnterNotify; + __glutSetWindow(window); + window->entry(GLUT_ENTERED); + + if (__glutMappedMenu) { + + /* Do not generate any passive motion events + when menus are in use. */ + + } else { + + /* An EnterNotify event can result in a + "compound" callback if a passive motion + callback is also registered. In this case, + be a little paranoid about the possibility + the window could have been destroyed in the + entry callback. */ + + window = __glutWindowList[num]; + if (window && window->passive && window->win == xid) { + __glutSetWindow(window); + window->passive(event.xcrossing.x, event.xcrossing.y); + } + } + } + } else { + if (window->entryState != LeaveNotify) { + + /* When an overlay is established for a window + already mapped and with the pointer in it, + the X server will generate a leave/enter + event pair as the pointer leaves (without + moving) from the normal plane X window to + the newly mapped overlay X window (or vice + versa). This enter/leave pair should not be + reported to the GLUT program since the pair + is a consequence of creating (or destroying) + the overlay, not an actual leave from the + GLUT window. */ + + if (XEventsQueued(__glutDisplay, QueuedAfterReading)) { + XPeekEvent(__glutDisplay, &ahead); + if (ahead.type == EnterNotify && + __glutGetWindow(ahead.xcrossing.window) == window) { + XNextEvent(__glutDisplay, &event); + break; + } + } + window->entryState = LeaveNotify; + __glutSetWindow(window); + window->entry(GLUT_LEFT); + } + } + } else if (window->passive) { + __glutSetWindow(window); + window->passive(event.xcrossing.x, event.xcrossing.y); + } + } + break; + case UnmapNotify: + /* MapNotify events are not needed to maintain + visibility state since VisibilityNotify events will + be delivered when a window becomes visible from + mapping. However, VisibilityNotify events are not + delivered when a window is unmapped (for the window + or its children). */ + window = __glutGetWindow(event.xunmap.window); + if (window) { + if (window->win != event.xconfigure.window) { + /* Ignore UnmapNotify sent to the overlay planes. + GLUT could get here because overlays select for + StructureNotify events to receive DestroyNotify. + */ + break; + } + markWindowHidden(window); + } + break; + case VisibilityNotify: + window = __glutGetWindow(event.xvisibility.window); + if (window) { + /* VisibilityUnobscured+1 = GLUT_FULLY_RETAINED, + VisibilityPartiallyObscured+1 = + GLUT_PARTIALLY_RETAINED, VisibilityFullyObscured+1 + = GLUT_FULLY_COVERED. */ + int visState = event.xvisibility.state + 1; + + if (visState != window->visState) { + if (window->windowStatus) { + window->visState = visState; + __glutSetWindow(window); + window->windowStatus(visState); + } + } + } + break; + case ClientMessage: + if (event.xclient.data.l[0] == __glutWMDeleteWindow) + exit(0); + break; + case DestroyNotify: + purgeStaleWindow(event.xdestroywindow.window); + break; + case CirculateNotify: + case CreateNotify: + case GravityNotify: + case ReparentNotify: + /* Uninteresting to GLUT (but possible for GLUT to + receive). */ + break; + default: + /* Pass events not directly handled by the GLUT main + event loop to any event parsers that have been + registered. In this way, X Input extension events + are passed to the correct handler without forcing + all GLUT programs to support X Input event handling. + */ + parser = eventParserList; + while (parser) { + if (parser->func(&event)) + break; + parser = parser->next; + } + break; + } + } + if (__glutTimerList) { + handleTimeouts(); + } + } + while (XPending(__glutDisplay)); +#endif /* _WIN32 */ +} + +static void +waitForSomething(void) +{ +#if defined(__vms) && ( __VMS_VER < 70000000 ) + static struct timeval zerotime = + {0}; + unsigned int timer_efn; +#define timer_id 'glut' /* random :-) number */ + unsigned int wait_mask; +#else + static struct timeval zerotime = + {0, 0}; +#if !defined(_WIN32) + fd_set fds; +#endif +#endif + struct timeval now, timeout, waittime; +#if !defined(_WIN32) + int rc; +#endif + + /* Flush X protocol since XPending does not do this + implicitly. */ + XFlush(__glutDisplay); + if (XPending(__glutDisplay)) { + /* It is possible (but quite rare) that XFlush may have + needed to wait for a writable X connection file + descriptor, and in the process, may have had to read off + X protocol from the file descriptor. If XPending is true, + this case occured and we should avoid waiting in select + since X protocol buffered within Xlib is due to be + processed and potentially no more X protocol is on the + file descriptor, so we would risk waiting improperly in + select. */ + goto immediatelyHandleXinput; + } +#if defined(__vms) && ( __VMS_VER < 70000000 ) + timeout = __glutTimerList->timeout; + GETTIMEOFDAY(&now); + wait_mask = 1 << (__glutConnectionFD & 31); + if (IS_AFTER(now, timeout)) { + /* We need an event flag for the timer. */ + /* XXX The `right' way to do this is to use LIB$GET_EF, but + since it needs to be in the same cluster as the EFN for + the display, we will have hack it. */ + timer_efn = __glutConnectionFD - 1; + if ((timer_efn / 32) != (__glutConnectionFD / 32)) { + timer_efn = __glutConnectionFD + 1; + } + rc = SYS$CLREF(timer_efn); + rc = SYS$SETIMR(timer_efn, &timeout, NULL, timer_id, 0); + wait_mask |= 1 << (timer_efn & 31); + } else { + timer_efn = 0; + } + rc = SYS$WFLOR(__glutConnectionFD, wait_mask); + if (timer_efn != 0 && SYS$CLREF(timer_efn) == SS$_WASCLR) { + rc = SYS$CANTIM(timer_id, PSL$C_USER); + } + /* XXX There does not seem to be checking of "rc" in the code + above. Can any of the SYS$ routines above fail? */ +#else /* not vms6.2 or lower */ +#if !defined(_WIN32) + FD_ZERO(&fds); + FD_SET(__glutConnectionFD, &fds); +#endif + timeout = __glutTimerList->timeout; + GETTIMEOFDAY(&now); + if (IS_AFTER(now, timeout)) { + TIMEDELTA(waittime, timeout, now); + } else { + waittime = zerotime; + } +#if !defined(_WIN32) + rc = select(__glutConnectionFD + 1, &fds, + NULL, NULL, &waittime); + if (rc < 0 && errno != EINTR) + __glutFatalError("select error."); +#else + MsgWaitForMultipleObjects(0, NULL, FALSE, waittime.tv_sec*1000 + waittime.tv_usec/1000, QS_ALLEVENTS); +#endif +#endif /* not vms6.2 or lower */ + /* Without considering the cause of select unblocking, check + for pending X events and handle any timeouts (by calling + processEventsAndTimeouts). We always look for X events + even if select returned with 0 (indicating a timeout); + otherwise we risk starving X event processing by continous + timeouts. */ + if (XPending(__glutDisplay)) { + immediatelyHandleXinput: + processEventsAndTimeouts(); + } else { + if (__glutTimerList) + handleTimeouts(); + } +} + +static void +idleWait(void) +{ + if (XPending(__glutDisplay)) { + processEventsAndTimeouts(); + } else { + if (__glutTimerList) { + handleTimeouts(); + } + } + /* Make sure idle func still exists! */ + if (__glutIdleFunc) { + __glutIdleFunc(); + } +} + +static GLUTwindow **beforeEnd; + +static GLUTwindow * +processWindowWorkList(GLUTwindow * window) +{ + int workMask; + + if (window->prevWorkWin) { + window->prevWorkWin = processWindowWorkList(window->prevWorkWin); + if (beforeEnd == 0) + beforeEnd = &window->prevWorkWin; + } else { + beforeEnd = &window->prevWorkWin; + } + + /* Capture work mask for work that needs to be done to this + window, then clear the window's work mask (excepting the + dummy work bit, see below). Then, process the captured + work mask. This allows callbacks in the processing the + captured work mask to set the window's work mask for + subsequent processing. */ + + workMask = window->workMask; + assert((workMask & GLUT_DUMMY_WORK) == 0); + + /* Set the dummy work bit, clearing all other bits, to + indicate that the window is currently on the window work + list _and_ that the window's work mask is currently being + processed. This convinces __glutPutOnWorkList that this + window is on the work list still. */ + window->workMask = GLUT_DUMMY_WORK; + + /* Optimization: most of the time, the work to do is a + redisplay and not these other types of work. Check for + the following cases as a group to before checking each one + individually one by one. This saves about 25 MIPS + instructions in the common redisplay only case. */ + if (workMask & (GLUT_EVENT_MASK_WORK | GLUT_DEVICE_MASK_WORK | + GLUT_CONFIGURE_WORK | GLUT_COLORMAP_WORK | GLUT_MAP_WORK)) { +#if !defined(_WIN32) + /* Be sure to set event mask BEFORE map window is done. */ + if (workMask & GLUT_EVENT_MASK_WORK) { + long eventMask; + + /* Make sure children are not propogating events this + window is selecting for. Be sure to do this before + enabling events on the children's parent. */ + if (window->children) { + GLUTwindow *child = window->children; + unsigned long attribMask = CWDontPropagate; + XSetWindowAttributes wa; + + wa.do_not_propagate_mask = window->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; + if (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) { + wa.event_mask = child->eventMask | (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK); + attribMask |= CWEventMask; + } + do { + XChangeWindowAttributes(__glutDisplay, child->win, + attribMask, &wa); + child = child->siblings; + } while (child); + } + eventMask = window->eventMask; + if (window->parent && window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) + eventMask |= (window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK); + XSelectInput(__glutDisplay, window->win, eventMask); + if (window->overlay) + XSelectInput(__glutDisplay, window->overlay->win, + window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK); + } +#endif /* !_WIN32 */ + /* Be sure to set device mask BEFORE map window is done. */ + if (workMask & GLUT_DEVICE_MASK_WORK) { + __glutUpdateInputDeviceMaskFunc(window); + } + /* Be sure to configure window BEFORE map window is done. */ + if (workMask & GLUT_CONFIGURE_WORK) { +#if defined(_WIN32) + if ( workMask & GLUT_FULL_SCREEN_WORK ) { + DWORD s; + RECT r; + + GetWindowRect(GetDesktopWindow(), &r); + s = GetWindowLong(window->win, GWL_STYLE); + s &= ~WS_OVERLAPPEDWINDOW; + s |= WS_POPUP; + SetWindowLong(window->win, GWL_STYLE, s); + SetWindowPos(window->win, + HWND_TOP, /* safer - a lot of people use windows atop a fullscreen GLUT window. */ + //HWND_TOPMOST, /* is better, but no windows atop it */ + r.left, r.top, + r.right-r.left, r.bottom-r.top, + SWP_FRAMECHANGED); + + /* This hack causes the window to go back to the right position + when it is taken out of fullscreen mode. */ + { + POINT p; + + p.x = 0; + p.y = 0; + ClientToScreen(window->win, &p); + window->desiredConfMask |= CWX | CWY; + window->desiredX = p.x; + window->desiredY = p.y; + } + } else { + RECT changes; + POINT point; + UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER; + DWORD style; + + GetClientRect(window->win, &changes); + style = GetWindowLong(window->win, GWL_STYLE); + + /* Get rid of fullscreen mode, if it exists */ + if ( style & WS_POPUP ) { + style &= ~WS_POPUP; + style |= WS_OVERLAPPEDWINDOW; + SetWindowLong(window->win, GWL_STYLE, style); + flags |= SWP_FRAMECHANGED; + } + + /* If this window is a toplevel window, translate the 0,0 client + coordinate into a screen coordinate for proper placement. */ + if (!window->parent) { + point.x = 0; + point.y = 0; + ClientToScreen(window->win, &point); + changes.left = point.x; + changes.top = point.y; + } + if (window->desiredConfMask & (CWX | CWY)) { + changes.left = window->desiredX; + changes.top = window->desiredY; + flags &= ~SWP_NOMOVE; + } + if (window->desiredConfMask & (CWWidth | CWHeight)) { + changes.right = changes.left + window->desiredWidth; + changes.bottom = changes.top + window->desiredHeight; + flags &= ~SWP_NOSIZE; + /* XXX If overlay exists, resize the overlay here, ie. + if (window->overlay) ... */ + } + if (window->desiredConfMask & CWStackMode) { + flags &= ~SWP_NOZORDER; + /* XXX Overlay support might require something special here. */ + } + + /* Adjust the window rectangle because Win32 thinks that the x, y, + width & height are the WHOLE window (including decorations), + whereas GLUT treats the x, y, width & height as only the CLIENT + area of the window. Only do this to top level windows + that are not in game mode (since game mode windows do + not have any decorations). */ + if (!window->parent && window != __glutGameModeWindow) { + AdjustWindowRect(&changes, style, FALSE); + } + + /* Do the repositioning, moving, and push/pop. */ + SetWindowPos(window->win, + window->desiredStack == Above ? HWND_TOP : HWND_BOTTOM, + changes.left, changes.top, + changes.right - changes.left, changes.bottom - changes.top, + flags); + + /* Zero out the mask. */ + window->desiredConfMask = 0; + } +#else /* !_WIN32 */ + XWindowChanges changes; + + changes.x = window->desiredX; + changes.y = window->desiredY; + if (window->desiredConfMask & (CWWidth | CWHeight)) { + changes.width = window->desiredWidth; + changes.height = window->desiredHeight; + if (window->overlay) + XResizeWindow(__glutDisplay, window->overlay->win, + window->desiredWidth, window->desiredHeight); + if (__glutMotifHints != None) { + if (workMask & GLUT_FULL_SCREEN_WORK) { + MotifWmHints hints; + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = 0; /* Absolutely no + decorations. */ + XChangeProperty(__glutDisplay, window->win, + __glutMotifHints, __glutMotifHints, 32, + PropModeReplace, (unsigned char *) &hints, 4); + if (workMask & GLUT_MAP_WORK) { + /* Handle case where glutFullScreen is called + before the first time that the window is + mapped. Some window managers will randomly or + interactively position the window the first + time it is mapped if the window's + WM_NORMAL_HINTS property does not request an + explicit position. We don't want any such + window manager interaction when going + fullscreen. Overwrite the WM_NORMAL_HINTS + property installed by glutCreateWindow's + XSetWMProperties property with one explicitly + requesting a fullscreen window. */ + XSizeHints hints; + + hints.flags = USPosition | USSize; + hints.x = 0; + hints.y = 0; + hints.width = window->desiredWidth; + hints.height = window->desiredHeight; + XSetWMNormalHints(__glutDisplay, window->win, &hints); + } + } else { + XDeleteProperty(__glutDisplay, window->win, __glutMotifHints); + } + } + } + if (window->desiredConfMask & CWStackMode) { + changes.stack_mode = window->desiredStack; + /* Do not let glutPushWindow push window beneath the + underlay. */ + if (window->parent && window->parent->overlay + && window->desiredStack == Below) { + changes.stack_mode = Above; + changes.sibling = window->parent->overlay->win; + window->desiredConfMask |= CWSibling; + } + } + XConfigureWindow(__glutDisplay, window->win, + window->desiredConfMask, &changes); + window->desiredConfMask = 0; +#endif + } +#if !defined(_WIN32) + /* Be sure to establish the colormaps BEFORE map window is + done. */ + if (workMask & GLUT_COLORMAP_WORK) { + __glutEstablishColormapsProperty(window); + } +#endif + if (workMask & GLUT_MAP_WORK) { + switch (window->desiredMapState) { + case WithdrawnState: + if (window->parent) { + XUnmapWindow(__glutDisplay, window->win); + } else { + XWithdrawWindow(__glutDisplay, window->win, + __glutScreen); + } + window->shownState = 0; + break; + case NormalState: + XMapWindow(__glutDisplay, window->win); + window->shownState = 1; + break; +#ifdef _WIN32 + case GameModeState: /* Not an Xlib value. */ + ShowWindow(window->win, SW_SHOW); + window->shownState = 1; + break; +#endif + case IconicState: + XIconifyWindow(__glutDisplay, window->win, __glutScreen); + window->shownState = 0; + break; + } + } + } + if (workMask & (GLUT_REDISPLAY_WORK | GLUT_OVERLAY_REDISPLAY_WORK | GLUT_REPAIR_WORK | GLUT_OVERLAY_REPAIR_WORK)) { + if (window->forceReshape) { + /* Guarantee that before a display callback is generated + for a window, a reshape callback must be generated. */ + __glutSetWindow(window); + window->reshape(window->width, window->height); + window->forceReshape = False; + + /* Setting the redisplay bit on the first reshape is + necessary to make the "Mesa glXSwapBuffers to repair + damage" hack operate correctly. Without indicating a + redisplay is necessary, there's not an initial back + buffer render from which to blit from when damage + happens to the window. */ + workMask |= GLUT_REDISPLAY_WORK; + } + /* The code below is more involved than otherwise necessary + because it is paranoid about the overlay or entire window + being removed or destroyed in the course of the callbacks. + Notice how the global __glutWindowDamaged is used to record + the layers' damage status. See the code in glutLayerGet for + how __glutWindowDamaged is used. The point is to not have to + update the "damaged" field after the callback since the + window (or overlay) may be destroyed (or removed) when the + callback returns. */ + + if (window->overlay && window->overlay->display) { + int num = window->num; + Window xid = window->overlay ? window->overlay->win : None; + + /* If an overlay display callback is registered, we + differentiate between a redisplay needed for the + overlay and/or normal plane. If there is no overlay + display callback registered, we simply use the + standard display callback. */ + + if (workMask & (GLUT_REDISPLAY_WORK | GLUT_REPAIR_WORK)) { + if (__glutMesaSwapHackSupport) { + if (window->usedSwapBuffers) { + if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) { + SWAP_BUFFERS_WINDOW(window); + goto skippedDisplayCallback1; + } + } + } + /* Render to normal plane. */ +#ifdef _WIN32 + window->renderDc = window->hdc; +#endif + window->renderWin = window->win; + window->renderCtx = window->ctx; + __glutWindowDamaged = (workMask & GLUT_REPAIR_WORK); + __glutSetWindow(window); + window->usedSwapBuffers = 0; + window->display(); + __glutWindowDamaged = 0; + + skippedDisplayCallback1:; + } + if (workMask & (GLUT_OVERLAY_REDISPLAY_WORK | GLUT_OVERLAY_REPAIR_WORK)) { + window = __glutWindowList[num]; + if (window && window->overlay && + window->overlay->win == xid && window->overlay->display) { + + /* Render to overlay. */ +#ifdef _WIN32 + window->renderDc = window->overlay->hdc; +#endif + window->renderWin = window->overlay->win; + window->renderCtx = window->overlay->ctx; + __glutWindowDamaged = (workMask & GLUT_OVERLAY_REPAIR_WORK); + __glutSetWindow(window); + window->overlay->display(); + __glutWindowDamaged = 0; + } else { + /* Overlay may have since been destroyed or the + overlay callback may have been disabled during + normal display callback. */ + } + } + } else { + if (__glutMesaSwapHackSupport) { + if (!window->overlay && window->usedSwapBuffers) { + if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) { + SWAP_BUFFERS_WINDOW(window); + goto skippedDisplayCallback2; + } + } + } + /* Render to normal plane (and possibly overlay). */ + __glutWindowDamaged = (workMask & (GLUT_OVERLAY_REPAIR_WORK | GLUT_REPAIR_WORK)); + __glutSetWindow(window); + window->usedSwapBuffers = 0; + window->display(); + __glutWindowDamaged = 0; + + skippedDisplayCallback2:; + } + } + /* Combine workMask with window->workMask to determine what + finish and debug work there is. */ + workMask |= window->workMask; + + if (workMask & GLUT_FINISH_WORK) { + /* Finish work makes sure a glFinish gets done to indirect + rendering contexts. Indirect contexts tend to have much + longer latency because lots of OpenGL extension requests + can queue up in the X protocol stream. __glutSetWindow + is where the finish works gets queued for indirect + contexts. */ + __glutSetWindow(window); + glFinish(); + } + if (workMask & GLUT_DEBUG_WORK) { + __glutSetWindow(window); + glutReportErrors(); + } + /* Strip out dummy, finish, and debug work bits. */ + window->workMask &= ~(GLUT_DUMMY_WORK | GLUT_FINISH_WORK | GLUT_DEBUG_WORK); + if (window->workMask) { + /* Leave on work list. */ + return window; + } else { + if (beforeEnd == &window->prevWorkWin) + beforeEnd = 0; + /* Remove current window from work list. */ + return window->prevWorkWin; + } +} + +/* CENTRY */ +void APIENTRY +glutMainLoop(void) +{ +#if !defined(_WIN32) + if (!__glutDisplay) + __glutFatalUsage("main loop entered with out proper initialization."); +#endif + if (!__glutWindowListSize) + __glutFatalUsage( + "main loop entered with no windows created."); + for (;;) { + if (__glutWindowWorkList) { + GLUTwindow *remainder, *work; + + work = __glutWindowWorkList; + __glutWindowWorkList = NULL; + if (work) { + remainder = processWindowWorkList(work); + if (remainder) { + *beforeEnd = __glutWindowWorkList; + __glutWindowWorkList = remainder; + } + } + } + if (__glutIdleFunc || __glutWindowWorkList) { + idleWait(); + } else { + if (__glutTimerList) { + waitForSomething(); + } else { + processEventsAndTimeouts(); + } +#if defined(_WIN32) + // If there is no idle function, go to sleep for a millisecond (we + // still need to possibly service timers) or until there is some + // event in our queue. + MsgWaitForMultipleObjects(0, NULL, FALSE, 1, QS_ALLEVENTS); +#endif + } + } +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_ext.c b/lib/glut-3.7.6/lib/glut/glut_ext.c new file mode 100644 index 0000000000..b6fe404188 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_ext.c @@ -0,0 +1,53 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +#include +#include + +#include "glutint.h" + +/* CENTRY */ +int APIENTRY +glutExtensionSupported(const char *extension) +{ + static const GLubyte *extensions = NULL; + const GLubyte *start; + GLubyte *where, *terminator; + + /* Extension names should not have spaces. */ + where = (GLubyte *) strchr(extension, ' '); + if (where || *extension == '\0') + return 0; + + if (!extensions) { + extensions = glGetString(GL_EXTENSIONS); + } + /* It takes a bit of care to be fool-proof about parsing the + OpenGL extensions string. Don't be fooled by sub-strings, + etc. */ + start = extensions; + for (;;) { + /* If your application crashes in the strstr routine below, + you are probably calling glutExtensionSupported without + having a current window. Calling glGetString without + a current OpenGL context has unpredictable results. + Please fix your program. */ + where = (GLubyte *) strstr((const char *) start, extension); + if (!where) + break; + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { + return 1; + } + } + start = terminator; + } + return 0; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_fcb.c b/lib/glut-3.7.6/lib/glut/glut_fcb.c new file mode 100644 index 0000000000..73d1d27ae7 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_fcb.c @@ -0,0 +1,164 @@ + +/* Copyright (c) Mark J. Kilgard, 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. */ + +/* 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 "glutint.h" + +/* FCB stands for Fortran CallBack. */ + +/* There is only one idleFunc, menuStateFunc, and menuStatusFunc, so they + can be saved in the wrappers for Fortran rather than the C structures. */ + +/* Set a Fortran callback function. */ + +void APIENTRY +__glutSetFCB(int which, void *func) +{ +#ifdef SUPPORT_FORTRAN + switch (which) { + case GLUT_FCB_DISPLAY: + __glutCurrentWindow->fdisplay = (GLUTdisplayFCB) func; + break; + case GLUT_FCB_RESHAPE: + __glutCurrentWindow->freshape = (GLUTreshapeFCB) func; + break; + case GLUT_FCB_MOUSE: + __glutCurrentWindow->fmouse = (GLUTmouseFCB) func; + break; + case GLUT_FCB_MOTION: + __glutCurrentWindow->fmotion = (GLUTmotionFCB) func; + break; + case GLUT_FCB_PASSIVE: + __glutCurrentWindow->fpassive = (GLUTpassiveFCB) func; + break; + case GLUT_FCB_ENTRY: + __glutCurrentWindow->fentry = (GLUTentryFCB) func; + break; + case GLUT_FCB_KEYBOARD: + __glutCurrentWindow->fkeyboard = (GLUTkeyboardFCB) func; + break; + case GLUT_FCB_KEYBOARD_UP: + __glutCurrentWindow->fkeyboardUp = (GLUTkeyboardFCB) func; + break; + case GLUT_FCB_WINDOW_STATUS: + __glutCurrentWindow->fwindowStatus = (GLUTwindowStatusFCB) func; + break; + case GLUT_FCB_VISIBILITY: + __glutCurrentWindow->fvisibility = (GLUTvisibilityFCB) func; + break; + case GLUT_FCB_SPECIAL: + __glutCurrentWindow->fspecial = (GLUTspecialFCB) func; + break; + case GLUT_FCB_SPECIAL_UP: + __glutCurrentWindow->fspecialUp = (GLUTspecialFCB) func; + break; + case GLUT_FCB_BUTTON_BOX: + __glutCurrentWindow->fbuttonBox = (GLUTbuttonBoxFCB) func; + break; + case GLUT_FCB_DIALS: + __glutCurrentWindow->fdials = (GLUTdialsFCB) func; + break; + case GLUT_FCB_SPACE_MOTION: + __glutCurrentWindow->fspaceMotion = (GLUTspaceMotionFCB) func; + break; + case GLUT_FCB_SPACE_ROTATE: + __glutCurrentWindow->fspaceRotate = (GLUTspaceRotateFCB) func; + break; + case GLUT_FCB_SPACE_BUTTON: + __glutCurrentWindow->fspaceButton = (GLUTspaceButtonFCB) func; + break; + case GLUT_FCB_TABLET_MOTION: + __glutCurrentWindow->ftabletMotion = (GLUTtabletMotionFCB) func; + break; + case GLUT_FCB_TABLET_BUTTON: + __glutCurrentWindow->ftabletButton = (GLUTtabletButtonFCB) func; + break; +#ifdef _WIN32 + case GLUT_FCB_JOYSTICK: + __glutCurrentWindow->fjoystick = (GLUTjoystickFCB) func; + break; +#endif + case GLUT_FCB_OVERLAY_DISPLAY: + __glutCurrentWindow->overlay->fdisplay = (GLUTdisplayFCB) func; + break; + case GLUT_FCB_SELECT: + __glutCurrentMenu->fselect = (GLUTselectFCB) func; + break; + case GLUT_FCB_TIMER: + __glutNewTimer->ffunc = (GLUTtimerFCB) func; + break; + } +#endif +} + +/* Get a Fortran callback function. */ + +void* APIENTRY +__glutGetFCB(int which) +{ +#ifdef SUPPORT_FORTRAN + switch (which) { + case GLUT_FCB_DISPLAY: + return (void *) __glutCurrentWindow->fdisplay; + case GLUT_FCB_RESHAPE: + return (void *) __glutCurrentWindow->freshape; + case GLUT_FCB_MOUSE: + return (void *) __glutCurrentWindow->fmouse; + case GLUT_FCB_MOTION: + return (void *) __glutCurrentWindow->fmotion; + case GLUT_FCB_PASSIVE: + return (void *) __glutCurrentWindow->fpassive; + case GLUT_FCB_ENTRY: + return (void *) __glutCurrentWindow->fentry; + case GLUT_FCB_KEYBOARD: + return (void *) __glutCurrentWindow->fkeyboard; + case GLUT_FCB_KEYBOARD_UP: + return (void *) __glutCurrentWindow->fkeyboardUp; + case GLUT_FCB_WINDOW_STATUS: + return (void *) __glutCurrentWindow->fwindowStatus; + case GLUT_FCB_VISIBILITY: + return (void *) __glutCurrentWindow->fvisibility; + case GLUT_FCB_SPECIAL: + return (void *) __glutCurrentWindow->fspecial; + case GLUT_FCB_SPECIAL_UP: + return (void *) __glutCurrentWindow->fspecialUp; + case GLUT_FCB_BUTTON_BOX: + return (void *) __glutCurrentWindow->fbuttonBox; + case GLUT_FCB_DIALS: + return (void *) __glutCurrentWindow->fdials; + case GLUT_FCB_SPACE_MOTION: + return (void *) __glutCurrentWindow->fspaceMotion; + case GLUT_FCB_SPACE_ROTATE: + return (void *) __glutCurrentWindow->fspaceRotate; + case GLUT_FCB_SPACE_BUTTON: + return (void *) __glutCurrentWindow->fspaceButton; + case GLUT_FCB_TABLET_MOTION: + return (void *) __glutCurrentWindow->ftabletMotion; + case GLUT_FCB_TABLET_BUTTON: + return (void *) __glutCurrentWindow->ftabletButton; + case GLUT_FCB_JOYSTICK: +#ifdef _WIN32 + return (void *) __glutCurrentWindow->fjoystick; +#else + return NULL; +#endif + case GLUT_FCB_OVERLAY_DISPLAY: + return (void *) __glutCurrentWindow->overlay->fdisplay; + case GLUT_FCB_SELECT: + return (void *) __glutCurrentMenu->fselect; + case GLUT_FCB_TIMER: + return (void *) __glutTimerList->ffunc; + default: + return NULL; + } +#else + return NULL; +#endif +} diff --git a/lib/glut-3.7.6/lib/glut/glut_fullscrn.c b/lib/glut-3.7.6/lib/glut/glut_fullscrn.c new file mode 100644 index 0000000000..892a06c61a --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_fullscrn.c @@ -0,0 +1,52 @@ + +/* Copyright (c) Mark J. Kilgard, 1995, 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 /* SunOS multithreaded assert() needs . Lame. */ +#include + +#if !defined(_WIN32) +#include +#include +#endif + +/* SGI optimization introduced in IRIX 6.3 to avoid X server + round trips for interning common X atoms. */ +#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) +#include +#else +#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) +#endif + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutFullScreen(void) +{ + assert(!__glutCurrentWindow->parent); + IGNORE_IN_GAME_MODE(); +#if !defined(_WIN32) + if (__glutMotifHints == None) { + __glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS", + SGI_XA__MOTIF_WM_HINTS, 0); + if (__glutMotifHints == None) { + __glutWarning("Could not intern X atom for _MOTIF_WM_HINTS."); + } + } +#endif + + __glutCurrentWindow->desiredX = 0; + __glutCurrentWindow->desiredY = 0; + __glutCurrentWindow->desiredWidth = __glutScreenWidth; + __glutCurrentWindow->desiredHeight = __glutScreenHeight; + __glutCurrentWindow->desiredConfMask |= CWX | CWY | CWWidth | CWHeight; + + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK); +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_gamemode.c b/lib/glut-3.7.6/lib/glut/glut_gamemode.c new file mode 100644 index 0000000000..b660df24a1 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_gamemode.c @@ -0,0 +1,674 @@ + +/* Copyright (c) Mark J. Kilgard, 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 +#include +#include + +#include "glutint.h" + +#ifndef _WIN32 +#include +#include + +/* SGI optimization introduced in IRIX 6.3 to avoid X server + round trips for interning common X atoms. */ +#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) +#include +#else +#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) +#endif +#endif /* not _WIN32 */ + +int __glutDisplaySettingsChanged = 0; +static DisplayMode *dmodes, *currentDm = NULL; +static int ndmodes = -1; +GLUTwindow *__glutGameModeWindow = NULL; + +#ifdef TEST +static char *compstr[] = +{ + "none", "=", "!=", "<=", ">=", ">", "<", "~" +}; +static char *capstr[] = +{ + "width", "height", "bpp", "hertz", "num" +}; +#endif + +void +__glutCloseDownGameMode(void) +{ + if (__glutDisplaySettingsChanged) { +#ifdef _WIN32 + /* Assumes that display settings have been changed, that + is __glutDisplaySettingsChanged is true. */ + ChangeDisplaySettings(NULL, 0); +#endif + __glutDisplaySettingsChanged = 0; + } + __glutGameModeWindow = NULL; +} + +void APIENTRY +glutLeaveGameMode(void) +{ + if (__glutGameModeWindow == NULL) { + __glutWarning("not in game mode so cannot leave game mode"); + return; + } + __glutDestroyWindow(__glutGameModeWindow, + __glutGameModeWindow); + XFlush(__glutDisplay); + __glutGameModeWindow = NULL; +} + +#ifdef _WIN32 + +/* Same values as from MSDN's SetDisp.c example. */ +#define MIN_WIDTH 400 +#define MIN_FREQUENCY 60 + +static void +initGameModeSupport(void) +{ + DEVMODE dm; + DWORD mode; + int i; + + if (ndmodes >= 0) { + /* ndmodes is initially -1 to indicate no + dmodes allocated yet. */ + return; + } + + /* Determine how many display modes there are. */ + ndmodes = 0; + mode = 0; + while (EnumDisplaySettings(NULL, mode, &dm)) { + if (dm.dmPelsWidth >= MIN_WIDTH && + (dm.dmDisplayFrequency == 0 || + dm.dmDisplayFrequency >= MIN_FREQUENCY)) { + ndmodes++; + } + mode++; + } + + /* Allocate memory for a list of all the display modes. */ + dmodes = (DisplayMode*) + malloc(ndmodes * sizeof(DisplayMode)); + + /* Now that we know how many display modes to expect, + enumerate them again and save the information in + the list we allocated above. */ + i = 0; + mode = 0; + while (EnumDisplaySettings(NULL, mode, &dm)) { + /* Try to reject any display settings that seem unplausible. */ + if (dm.dmPelsWidth >= MIN_WIDTH && + (dm.dmDisplayFrequency == 0 || + dm.dmDisplayFrequency >= MIN_FREQUENCY)) { + dmodes[i].devmode = dm; + dmodes[i].valid = 1; /* XXX Not used for now. */ + dmodes[i].cap[DM_WIDTH] = dm.dmPelsWidth; + dmodes[i].cap[DM_HEIGHT] = dm.dmPelsHeight; + dmodes[i].cap[DM_PIXEL_DEPTH] = dm.dmBitsPerPel; + if (dm.dmDisplayFrequency == 0) { + /* Guess a reasonable guess. */ + /* Lame Windows 95 version of EnumDisplaySettings. */ + dmodes[i].cap[DM_HERTZ] = 60; + } else { + dmodes[i].cap[DM_HERTZ] = dm.dmDisplayFrequency; + } + i++; + } + mode++; + } + + assert(i == ndmodes); +} + +#else + +/* X Windows version of initGameModeSupport. */ +static void +initGameModeSupport(void) +{ + if (ndmodes >= 0) { + /* ndmodes is initially -1 to indicate no + dmodes allocated yet. */ + return; + } + + /* Determine how many display modes there are. */ + ndmodes = 0; +} + +#endif + +/* This routine is based on similiar code in glut_dstr.c */ +static DisplayMode * +findMatch(DisplayMode * dmodes, int ndmodes, + Criterion * criteria, int ncriteria) +{ + DisplayMode *found; + int *bestScore, *thisScore; + int i, j, numok, result, worse, better; + + found = NULL; + numok = 1; /* "num" capability is indexed from 1, + not 0. */ + + /* XXX alloca canidate. */ + bestScore = (int *) malloc(ncriteria * sizeof(int)); + if (!bestScore) { + __glutFatalError("out of memory."); + } + for (j = 0; j < ncriteria; j++) { + /* Very negative number. */ + bestScore[j] = -32768; + } + + /* XXX alloca canidate. */ + thisScore = (int *) malloc(ncriteria * sizeof(int)); + if (!thisScore) { + __glutFatalError("out of memory."); + } + + for (i = 0; i < ndmodes; i++) { + if (dmodes[i].valid) { + worse = 0; + better = 0; + + for (j = 0; j < ncriteria; j++) { + int cap, cvalue, dvalue; + + cap = criteria[j].capability; + cvalue = criteria[j].value; + if (cap == NUM) { + dvalue = numok; + } else { + dvalue = dmodes[i].cap[cap]; + } +#ifdef TEST + if (verbose) + printf(" %s %s %d to %d\n", + capstr[cap], compstr[criteria[j].comparison], cvalue, dvalue); +#endif + switch (criteria[j].comparison) { + case EQ: + result = cvalue == dvalue; + thisScore[j] = 1; + break; + case NEQ: + result = cvalue != dvalue; + thisScore[j] = 1; + break; + case LT: + result = dvalue < cvalue; + thisScore[j] = dvalue - cvalue; + break; + case GT: + result = dvalue > cvalue; + thisScore[j] = dvalue - cvalue; + break; + case LTE: + result = dvalue <= cvalue; + thisScore[j] = dvalue - cvalue; + break; + case GTE: + result = (dvalue >= cvalue); + thisScore[j] = dvalue - cvalue; + break; + case MIN: + result = dvalue >= cvalue; + thisScore[j] = cvalue - dvalue; + break; + } + +#ifdef TEST + if (verbose) + printf(" result=%d score=%d bestScore=%d\n", result, thisScore[j], bestScore[j]); +#endif + + if (result) { + if (better || thisScore[j] > bestScore[j]) { + better = 1; + } else if (thisScore[j] == bestScore[j]) { + /* Keep looking. */ + } else { + goto nextDM; + } + } else { + if (cap == NUM) { + worse = 1; + } else { + goto nextDM; + } + } + + } + + if (better && !worse) { + found = &dmodes[i]; + for (j = 0; j < ncriteria; j++) { + bestScore[j] = thisScore[j]; + } + } + numok++; + + nextDM:; + + } + } + free(bestScore); + free(thisScore); + return found; +} + +/** + * Parses strings in the form of: + * 800x600 + * 800x600:16 + * 800x600@60 + * 800x600:16@60 + * @60 + * :16 + * :16@60 + * NOTE that @ before : is not parsed. + */ +static int +specialCaseParse(char *word, Criterion * criterion, int mask) +{ + char *xstr, *response; + int got; + int width, height, bpp, hertz; + + switch(word[0]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* The WWWxHHH case. */ + if (mask & (1 << DM_WIDTH)) { + return -1; + } + xstr = strpbrk(&word[1], "x"); + if (xstr) { + width = (int) strtol(word, &response, 0); + if (response == word || response[0] != 'x') { + /* Not a valid number OR needs to be followed by 'x'. */ + return -1; + } + height = (int) strtol(&xstr[1], &response, 0); + if (response == &xstr[1]) { + /* Not a valid number. */ + return -1; + } + criterion[0].capability = DM_WIDTH; + criterion[0].comparison = EQ; + criterion[0].value = width; + criterion[1].capability = DM_HEIGHT; + criterion[1].comparison = EQ; + criterion[1].value = height; + got = specialCaseParse(response, + &criterion[2], 1 << DM_WIDTH); + if (got >= 0) { + return got + 2; + } else { + return -1; + } + } + return -1; + case ':': + /* The :BPP case. */ + if (mask & (1 << DM_PIXEL_DEPTH)) { + return -1; + } + bpp = (int) strtol(&word[1], &response, 0); + if (response == &word[1]) { + /* Not a valid number. */ + return -1; + } + criterion[0].capability = DM_PIXEL_DEPTH; + criterion[0].comparison = EQ; + criterion[0].value = bpp; + got = specialCaseParse(response, + &criterion[1], (1 << DM_WIDTH) | (1 << DM_PIXEL_DEPTH)); + if (got >= 0) { + return got + 1; + } else { + return -1; + } + case '@': + /* The @HZ case. */ + if (mask & (1 << DM_HERTZ)) { + return -1; + } + hertz = (int) strtol(&word[1], &response, 0); + if (response == &word[1]) { + /* Not a valid number. */ + return -1; + } + criterion[0].capability = DM_HERTZ; + criterion[0].comparison = EQ; + criterion[0].value = hertz; + got = specialCaseParse(response, + &criterion[1], ~DM_HERTZ); + if (got >= 0) { + return got + 1; + } else { + return -1; + } + case '\0': + return 0; + } + return -1; +} + +/* This routine is based on similiar code in glut_dstr.c */ +static int +parseCriteria(char *word, Criterion * criterion) +{ + char *cstr, *vstr, *response; + int comparator, value; + + cstr = strpbrk(word, "=>': + if (cstr[1] == '=') { + comparator = GTE; + vstr = &cstr[2]; + } else { + comparator = GT; + vstr = &cstr[1]; + } + break; + case '<': + if (cstr[1] == '=') { + comparator = LTE; + vstr = &cstr[2]; + } else { + comparator = LT; + vstr = &cstr[1]; + } + break; + case '!': + if (cstr[1] == '=') { + comparator = NEQ; + vstr = &cstr[2]; + } else { + return -1; + } + break; + default: + return -1; + } + value = (int) strtol(vstr, &response, 0); + if (response == vstr) { + /* Not a valid number. */ + return -1; + } + *cstr = '\0'; + } else { + comparator = NONE; + } + switch (word[0]) { + case 'b': + if (!strcmp(word, "bpp")) { + criterion[0].capability = DM_PIXEL_DEPTH; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; + case 'h': + if (!strcmp(word, "height")) { + criterion[0].capability = DM_HEIGHT; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + if (!strcmp(word, "hertz")) { + criterion[0].capability = DM_HERTZ; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; + case 'n': + if (!strcmp(word, "num")) { + criterion[0].capability = DM_NUM; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; + case 'w': + if (!strcmp(word, "width")) { + criterion[0].capability = DM_WIDTH; + if (comparator == NONE) { + return -1; + } else { + criterion[0].comparison = comparator; + criterion[0].value = value; + return 1; + } + } + return -1; + } + if (comparator == NONE) { + return specialCaseParse(word, criterion, 0); + } + return -1; +} + +/* This routine is based on similiar code in glut_dstr.c */ +static Criterion * +parseDisplayString(const char *display, int *ncriteria) +{ + Criterion *criteria = NULL; + int n, parsed; + char *copy, *word; + + copy = __glutStrdup(display); + /* Attempt to estimate how many criteria entries should be + needed. */ + n = 0; + word = strtok(copy, " \t"); + while (word) { + n++; + word = strtok(NULL, " \t"); + } + /* Allocate number of words of criteria. A word + could contain as many as four criteria in the + worst case. Example: 800x600:16@60 */ + criteria = (Criterion *) malloc(4 * n * sizeof(Criterion)); + if (!criteria) { + __glutFatalError("out of memory."); + } + + /* Re-copy the copy of the display string. */ + strcpy(copy, display); + + n = 0; + word = strtok(copy, " \t"); + while (word) { + parsed = parseCriteria(word, &criteria[n]); + if (parsed >= 0) { + n += parsed; + } else { + __glutWarning("Unrecognized game mode string word: %s (ignoring)\n", word); + } + word = strtok(NULL, " \t"); + } + + free(copy); + *ncriteria = n; + return criteria; +} + +void APIENTRY +glutGameModeString(const char *string) +{ + Criterion *criteria; + int ncriteria; + + initGameModeSupport(); + criteria = parseDisplayString(string, &ncriteria); + currentDm = findMatch(dmodes, ndmodes, criteria, ncriteria); + free(criteria); +} + +int APIENTRY +glutEnterGameMode(void) +{ + GLUTwindow *window; + int width, height; + Window win; + + if (__glutMappedMenu) { + __glutFatalUsage("entering game mode not allowed while menus in use"); + } + if (__glutGameModeWindow) { + /* Already in game mode, so blow away game mode + window so apps can change resolutions. */ + window = __glutGameModeWindow; + /* Setting the game mode window to NULL tricks + the window destroy code into not undoing the + screen display change since we plan on immediately + doing another mode change. */ + __glutGameModeWindow = NULL; + __glutDestroyWindow(window, window); + } + + /* Assume default screen size until we find out if we + can actually change the display settings. */ + width = __glutScreenWidth; + height = __glutScreenHeight; + + if (currentDm) { +#ifdef _WIN32 + LONG status; + static int registered = 0; + + status = ChangeDisplaySettings(¤tDm->devmode, + CDS_FULLSCREEN); + if (status == DISP_CHANGE_SUCCESSFUL) { + __glutDisplaySettingsChanged = 1; + width = currentDm->cap[DM_WIDTH]; + height = currentDm->cap[DM_HEIGHT]; + if (!registered) { + atexit(__glutCloseDownGameMode); + registered = 1; + } + } else { + /* Switch back to default resolution. */ + ChangeDisplaySettings(NULL, 0); + } +#endif + } + + window = __glutCreateWindow(NULL, 0, 0, + width, height, /* game mode */ 1); + win = window->win; + +#if !defined(_WIN32) + if (__glutMotifHints == None) { + __glutMotifHints = XSGIFastInternAtom(__glutDisplay, "_MOTIF_WM_HINTS", + SGI_XA__MOTIF_WM_HINTS, 0); + if (__glutMotifHints == None) { + __glutWarning("Could not intern X atom for _MOTIF_WM_HINTS."); + } + } + + /* Game mode window is a toplevel window. */ + XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1); +#endif + + /* Schedule the fullscreen property to be added and to + make sure the window is configured right. Win32 + doesn't need this. */ + window->desiredX = 0; + window->desiredY = 0; + window->desiredWidth = width; + window->desiredHeight = height; + window->desiredConfMask |= CWX | CWY | CWWidth | CWHeight; +#ifdef _WIN32 + /* Win32 does not want to use GLUT_FULL_SCREEN_WORK + for game mode because we need to be maximizing + the window in game mode, not just sizing it to + take up the full screen. The Win32-ness of game + mode happens when you pass 1 in the gameMode parameter + to __glutCreateWindow above. A gameMode of creates + a WS_POPUP window, not a standard WS_OVERLAPPEDWINDOW + window. WS_POPUP ensures the taskbar is hidden. */ + __glutPutOnWorkList(window, + GLUT_CONFIGURE_WORK); +#else + __glutPutOnWorkList(window, + GLUT_CONFIGURE_WORK | GLUT_FULL_SCREEN_WORK); +#endif + + __glutGameModeWindow = window; + return window->num + 1; +} + +int APIENTRY +glutGameModeGet(GLenum mode) +{ + switch (mode) { + case GLUT_GAME_MODE_ACTIVE: + return __glutGameModeWindow != NULL; + case GLUT_GAME_MODE_POSSIBLE: + return currentDm != NULL; + case GLUT_GAME_MODE_WIDTH: + return currentDm ? currentDm->cap[DM_WIDTH] : -1; + case GLUT_GAME_MODE_HEIGHT: + return currentDm ? currentDm->cap[DM_HEIGHT] : -1; + case GLUT_GAME_MODE_PIXEL_DEPTH: + return currentDm ? currentDm->cap[DM_PIXEL_DEPTH] : -1; + case GLUT_GAME_MODE_REFRESH_RATE: + return currentDm ? currentDm->cap[DM_HERTZ] : -1; + case GLUT_GAME_MODE_DISPLAY_CHANGED: + return __glutDisplaySettingsChanged; + default: + return -1; + } +} diff --git a/lib/glut-3.7.6/lib/glut/glut_get.c b/lib/glut-3.7.6/lib/glut/glut_get.c new file mode 100644 index 0000000000..b01671efbf --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_get.c @@ -0,0 +1,216 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 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 /* SunOS 4 needs NULL defined for GETTIMEOFDAY macro. */ +#include "glutint.h" + +/* CENTRY */ +int APIENTRY +glutGet(GLenum param) +{ + Window win, root; + int x, y, value; + unsigned int width, height, border, depth; + + switch (param) { + case GLUT_INIT_WINDOW_X: + return __glutInitX; + case GLUT_INIT_WINDOW_Y: + return __glutInitY; + case GLUT_INIT_WINDOW_WIDTH: + return __glutInitWidth; + case GLUT_INIT_WINDOW_HEIGHT: + return __glutInitHeight; + case GLUT_INIT_DISPLAY_MODE: + return __glutDisplayMode; + case GLUT_WINDOW_X: + XTranslateCoordinates(__glutDisplay, __glutCurrentWindow->win, + __glutRoot, 0, 0, &x, &y, &win); + return x; + case GLUT_WINDOW_Y: + XTranslateCoordinates(__glutDisplay, __glutCurrentWindow->win, + __glutRoot, 0, 0, &x, &y, &win); + return y; + case GLUT_WINDOW_WIDTH: + if (!__glutCurrentWindow->reshape) { + XGetGeometry(__glutDisplay, __glutCurrentWindow->win, + &root, &x, &y, + &width, &height, &border, &depth); + return width; + } + return __glutCurrentWindow->width; + case GLUT_WINDOW_HEIGHT: + if (!__glutCurrentWindow->reshape) { + XGetGeometry(__glutDisplay, __glutCurrentWindow->win, + &root, &x, &y, + &width, &height, &border, &depth); + return height; + } + return __glutCurrentWindow->height; + +#define GET_CONFIG(attrib) { \ + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { \ + glXGetConfig(__glutDisplay, __glutCurrentWindow->vis, \ + attrib, &value); \ + } else { \ + glXGetConfig(__glutDisplay, __glutCurrentWindow->overlay->vis, \ + attrib, &value); \ + } \ +} + + case GLUT_WINDOW_BUFFER_SIZE: + GET_CONFIG(GLX_BUFFER_SIZE); + return value; + case GLUT_WINDOW_STENCIL_SIZE: + GET_CONFIG(GLX_STENCIL_SIZE); + return value; + case GLUT_WINDOW_DEPTH_SIZE: + GET_CONFIG(GLX_DEPTH_SIZE); + return value; + case GLUT_WINDOW_RED_SIZE: + GET_CONFIG(GLX_RED_SIZE); + return value; + case GLUT_WINDOW_GREEN_SIZE: + GET_CONFIG(GLX_GREEN_SIZE); + return value; + case GLUT_WINDOW_BLUE_SIZE: + GET_CONFIG(GLX_BLUE_SIZE); + return value; + case GLUT_WINDOW_ALPHA_SIZE: + GET_CONFIG(GLX_ALPHA_SIZE); + return value; + case GLUT_WINDOW_ACCUM_RED_SIZE: + GET_CONFIG(GLX_ACCUM_RED_SIZE); + return value; + case GLUT_WINDOW_ACCUM_GREEN_SIZE: + GET_CONFIG(GLX_ACCUM_GREEN_SIZE); + return value; + case GLUT_WINDOW_ACCUM_BLUE_SIZE: + GET_CONFIG(GLX_ACCUM_BLUE_SIZE); + return value; + case GLUT_WINDOW_ACCUM_ALPHA_SIZE: + GET_CONFIG(GLX_ACCUM_ALPHA_SIZE); + return value; + case GLUT_WINDOW_DOUBLEBUFFER: + GET_CONFIG(GLX_DOUBLEBUFFER); + return value; + case GLUT_WINDOW_RGBA: + GET_CONFIG(GLX_RGBA); + return value; + case GLUT_WINDOW_COLORMAP_SIZE: + GET_CONFIG(GLX_RGBA); + if (value) { + return 0; + } else { +#if defined(_WIN32) + /* KLUDGE: we always assume 256 colors in CI mode on + Win32 */ + return 256; +#else + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + return __glutCurrentWindow->vis->visual->map_entries; + } else { + return __glutCurrentWindow->overlay->vis->visual->map_entries; + } +#endif /* _WIN32 */ + } + case GLUT_WINDOW_PARENT: + return __glutCurrentWindow->parent ? + __glutCurrentWindow->parent->num + 1 : 0; + case GLUT_WINDOW_NUM_CHILDREN: + { + int num = 0; + GLUTwindow *children = __glutCurrentWindow->children; + + while (children) { + num++; + children = children->siblings; + } + return num; + } + case GLUT_WINDOW_NUM_SAMPLES: +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) { + GET_CONFIG(GLX_SAMPLES_SGIS); + return value; + } else { + return 0; + } +#else + /* Independent of GLX server support, multisampling not + supported by GLX client-side. */ + return 0; +#endif + case GLUT_WINDOW_STEREO: + GET_CONFIG(GLX_STEREO); + return value; + case GLUT_WINDOW_CURSOR: + return __glutCurrentWindow->cursor; + case GLUT_SCREEN_WIDTH: + return DisplayWidth(__glutDisplay, __glutScreen); + case GLUT_SCREEN_HEIGHT: + return DisplayHeight(__glutDisplay, __glutScreen); + case GLUT_SCREEN_WIDTH_MM: + return DisplayWidthMM(__glutDisplay, __glutScreen); + case GLUT_SCREEN_HEIGHT_MM: + return DisplayHeightMM(__glutDisplay, __glutScreen); + case GLUT_MENU_NUM_ITEMS: + return __glutCurrentMenu->num; + case GLUT_DISPLAY_MODE_POSSIBLE: + { + XVisualInfo *vi; + Bool dummy, visAlloced; + void *fbc; + +#if defined(_WIN32) + /* Our fake glXChooseVisual (which is called by + __glutDetermineVisual) needs an HDC to work with, so grab one + from the "root" window. */ + XHDC = GetDC(GetDesktopWindow()); +#endif + vi = __glutDetermineWindowVisual(&dummy, &visAlloced, &fbc); +#if defined(_WIN32) + ReleaseDC(GetDesktopWindow(), XHDC); +#endif + if (vi) { + if (visAlloced) + XFree(vi); + return 1; + } + return 0; + } + case GLUT_ELAPSED_TIME: + { + struct timeval elapsed, beginning, now; + + __glutInitTime(&beginning); + GETTIMEOFDAY(&now); + TIMEDELTA(elapsed, now, beginning); + /* Return elapsed milliseconds. */ +#if defined(__vms) && ( __VMS_VER < 70000000 ) + return (int) (elapsed.val / TICKS_PER_MILLISECOND); +#else + return (int) ((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000)); +#endif + } + case GLUT_WINDOW_FORMAT_ID: +#if defined(_WIN32) + return GetPixelFormat(__glutCurrentWindow->hdc); +#else + if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) { + return (int) __glutCurrentWindow->vis->visualid; + } else { + return (int) __glutCurrentWindow->overlay->vis->visualid; + } +#endif + default: + __glutWarning("invalid glutGet parameter: %d", param); + return -1; + } +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_glxext.c b/lib/glut-3.7.6/lib/glut/glut_glxext.c new file mode 100644 index 0000000000..a481617f58 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_glxext.c @@ -0,0 +1,48 @@ + +/* 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. */ + +#include +#include +#include "glutint.h" + +#if defined(GLX_VERSION_1_1) +int +__glutIsSupportedByGLX(char *extension) +{ + static const char *extensions = NULL; + const char *start; + char *where, *terminator; + int major, minor; + + glXQueryVersion(__glutDisplay, &major, &minor); + /* Be careful not to call glXQueryExtensionsString if it + looks like the server doesn't support GLX 1.1. + Unfortunately, the original GLX 1.0 didn't have the notion + of GLX extensions. */ + if ((major == 1 && minor >= 1) || (major > 1)) { + if (!extensions) + extensions = glXQueryExtensionsString(__glutDisplay, __glutScreen); + /* It takes a bit of care to be fool-proof about parsing + the GLX extensions string. Don't be fooled by + sub-strings, etc. */ + start = extensions; + for (;;) { + where = strstr(start, extension); + if (!where) + return 0; + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { + return 1; + } + } + start = terminator; + } + } + return 0; +} +#endif diff --git a/lib/glut-3.7.6/lib/glut/glut_hel10.c b/lib/glut-3.7.6/lib/glut/glut_hel10.c new file mode 100644 index 0000000000..7d948297a3 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_hel10.c @@ -0,0 +1,1778 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmapHelvetica10 XXX +#include "glutbitmap.h" +#undef glutBitmapHelvetica10 + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0x80,0x40,0x40,0x60,0xa0,0xa0,0x90,0x90,0x0,0x50, +}; + +static const BitmapCharRec ch255 = {4,10,0,2,5,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0x80,0x80,0xb0,0xc8,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch254 = {5,10,0,2,6,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x80,0x40,0x40,0x60,0xa0,0xa0,0x90,0x90,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch253 = {4,11,0,2,5,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x70,0x90,0x90,0x90,0x90,0x90,0x0,0x50, +}; + +static const BitmapCharRec ch252 = {4,8,0,0,5,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x70,0x90,0x90,0x90,0x90,0x90,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch251 = {4,9,0,0,5,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x70,0x90,0x90,0x90,0x90,0x90,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch250 = {4,9,0,0,5,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x70,0x90,0x90,0x90,0x90,0x90,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch249 = {4,9,0,0,5,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0x70,0x88,0xc8,0xa8,0x98,0x74, +}; + +static const BitmapCharRec ch248 = {6,6,0,0,6,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x20,0x0,0xf8,0x0,0x20, +}; + +static const BitmapCharRec ch247 = {5,5,0,-1,6,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x0,0x50, +}; + +static const BitmapCharRec ch246 = {5,8,0,0,6,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch245 = {5,9,0,0,6,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch244 = {5,9,0,0,6,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch243 = {5,9,0,0,6,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch242 = {5,9,0,0,6,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0x90,0x90,0x90,0x90,0x90,0xe0,0x0,0xa0,0x50, +}; + +static const BitmapCharRec ch241 = {4,9,0,0,5,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x70,0x88,0x88,0x88,0x88,0x78,0x90,0x60,0x50, +}; + +static const BitmapCharRec ch240 = {5,9,0,0,6,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0, +}; + +static const BitmapCharRec ch239 = {3,8,0,0,2,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch238 = {3,9,1,0,2,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x40, +}; + +static const BitmapCharRec ch237 = {2,9,0,0,2,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch236 = {2,9,1,0,2,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x60,0x90,0x80,0xf0,0x90,0x60,0x0,0x50, +}; + +static const BitmapCharRec ch235 = {4,8,0,0,5,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x60,0x90,0x80,0xf0,0x90,0x60,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch234 = {4,9,0,0,5,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x60,0x90,0x80,0xf0,0x90,0x60,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch233 = {4,9,0,0,5,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x60,0x90,0x80,0xf0,0x90,0x60,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch232 = {4,9,0,0,5,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x60,0x20,0x60,0x90,0x80,0x80,0x90,0x60, +}; + +static const BitmapCharRec ch231 = {4,8,0,2,5,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x6c,0x92,0x90,0x7e,0x12,0xec, +}; + +static const BitmapCharRec ch230 = {7,6,0,0,8,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x20,0x50,0x20, +}; + +static const BitmapCharRec ch229 = {5,9,0,0,5,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x0,0x50, +}; + +static const BitmapCharRec ch228 = {5,8,0,0,5,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x0,0xa0,0x50, +}; + +static const BitmapCharRec ch227 = {5,9,0,0,5,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch226 = {5,9,0,0,5,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch225 = {5,9,0,0,5,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch224 = {5,9,0,0,5,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0xa0,0x90,0x90,0x90,0xa0,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch223 = {4,8,0,0,5,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0x80,0x80,0xf0,0x88,0x88,0xf0,0x80,0x80, +}; + +static const BitmapCharRec ch222 = {5,8,-1,0,7,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x10,0x10,0x10,0x28,0x28,0x44,0x44,0x82,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch221 = {7,11,0,0,7,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x48, +}; + +static const BitmapCharRec ch220 = {6,10,-1,0,8,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch219 = {6,11,-1,0,8,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch218 = {6,11,-1,0,8,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch217 = {6,11,-1,0,8,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x80,0x78,0xc4,0xa4,0xa4,0x94,0x94,0x8c,0x78,0x4, +}; + +static const BitmapCharRec ch216 = {6,10,-1,1,8,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x88,0x50,0x20,0x50,0x88, +}; + +static const BitmapCharRec ch215 = {5,5,0,-1,6,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x48, +}; + +static const BitmapCharRec ch214 = {6,10,-1,0,8,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch213 = {6,11,-1,0,8,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch212 = {6,11,-1,0,8,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch211 = {6,11,-1,0,8,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch210 = {6,11,-1,0,8,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0x8c,0x8c,0x94,0x94,0xa4,0xa4,0xc4,0xc4,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch209 = {6,11,-1,0,8,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0x78,0x44,0x42,0x42,0xf2,0x42,0x44,0x78, +}; + +static const BitmapCharRec ch208 = {7,8,0,0,8,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0, +}; + +static const BitmapCharRec ch207 = {3,10,0,0,3,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch206 = {3,11,0,0,3,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x40, +}; + +static const BitmapCharRec ch205 = {2,11,-1,0,3,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch204 = {2,11,0,0,3,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xf8,0x80,0x80,0x80,0xf8,0x80,0x80,0xf8,0x0,0x50, +}; + +static const BitmapCharRec ch203 = {5,10,-1,0,7,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xf8,0x80,0x80,0xf8,0x80,0x80,0x80,0xf8,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch202 = {5,11,-1,0,7,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xf8,0x80,0x80,0x80,0xf8,0x80,0x80,0xf8,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch201 = {5,11,-1,0,7,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xf8,0x80,0x80,0x80,0xf8,0x80,0x80,0xf8,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch200 = {5,11,-1,0,7,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x30,0x10,0x78,0x84,0x80,0x80,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch199 = {6,10,-1,2,8,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0x8f,0x80,0x88,0x0,0x78,0x0,0x48,0x0,0x2f,0x80,0x28,0x0,0x18,0x0,0x1f,0x80, +}; + +static const BitmapCharRec ch198 = {9,8,0,0,10,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x10,0x28,0x10, +}; + +static const BitmapCharRec ch197 = {7,11,0,0,7,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x0,0x28, +}; + +static const BitmapCharRec ch196 = {7,10,0,0,7,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch195 = {7,11,0,0,7,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch194 = {7,11,0,0,7,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch193 = {7,11,0,0,7,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch192 = {7,11,0,0,7,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x60,0x90,0x80,0x40,0x20,0x20,0x0,0x20, +}; + +static const BitmapCharRec ch191 = {4,8,-1,2,6,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x21,0x0,0x17,0x80,0x13,0x0,0x9,0x0,0xc8,0x0,0x24,0x0,0x44,0x0,0xe2,0x0, +}; + +static const BitmapCharRec ch190 = {9,8,0,0,9,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x27,0x12,0x15,0xb,0x48,0x44,0xc4,0x42, +}; + +static const BitmapCharRec ch189 = {8,8,0,0,9,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x21,0x0,0x17,0x80,0x13,0x0,0x9,0x0,0x48,0x0,0x44,0x0,0xc4,0x0,0x42,0x0, +}; + +static const BitmapCharRec ch188 = {9,8,0,0,9,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0xa0,0x50,0x28,0x50,0xa0, +}; + +static const BitmapCharRec ch187 = {5,5,0,0,6,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xe0,0x0,0xe0,0xa0,0xe0, +}; + +static const BitmapCharRec ch186 = {3,5,0,-3,4,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch185 = {2,4,0,-3,3,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0xc0,0x40, +}; + +static const BitmapCharRec ch184 = {2,2,0,2,3,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0xc0, +}; + +static const BitmapCharRec ch183 = {2,1,0,-3,3,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x28,0x28,0x28,0x28,0x28,0x68,0xe8,0xe8,0xe8,0x7c, +}; + +static const BitmapCharRec ch182 = {6,10,0,2,6,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x80,0x80,0xf0,0x90,0x90,0x90,0x90,0x90, +}; + +static const BitmapCharRec ch181 = {4,8,0,2,5,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0x80,0x40, +}; + +static const BitmapCharRec ch180 = {2,2,0,-6,3,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0xc0,0x20,0x40,0xe0, +}; + +static const BitmapCharRec ch179 = {3,4,0,-3,3,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xe0,0x40,0xa0,0x60, +}; + +static const BitmapCharRec ch178 = {3,4,0,-3,3,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xf8,0x0,0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch177 = {5,7,0,0,6,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch176 = {4,4,0,-3,4,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xe0, +}; + +static const BitmapCharRec ch175 = {3,1,0,-7,3,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x38,0x44,0xaa,0xb2,0xba,0x44,0x38, +}; + +static const BitmapCharRec ch174 = {7,7,-1,0,9,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xe0, +}; + +static const BitmapCharRec ch173 = {3,1,0,-3,4,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x8,0x8,0xf8, +}; + +static const BitmapCharRec ch172 = {5,3,-1,-2,7,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x28,0x50,0xa0,0x50,0x28, +}; + +static const BitmapCharRec ch171 = {5,5,0,0,6,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xe0,0x0,0xa0,0x20,0xe0, +}; + +static const BitmapCharRec ch170 = {3,5,0,-3,4,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x38,0x44,0x9a,0xa2,0x9a,0x44,0x38, +}; + +static const BitmapCharRec ch169 = {7,7,-1,0,9,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xa0, +}; + +static const BitmapCharRec ch168 = {3,1,0,-7,3,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x70,0x88,0x18,0x70,0xc8,0x98,0x70,0xc0,0x88,0x70, +}; + +static const BitmapCharRec ch167 = {5,10,0,2,6,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0x80,0x80,0x80,0x80,0x0,0x0,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch166 = {1,10,-1,2,3,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x20,0xf8,0x20,0xf8,0x50,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch165 = {5,8,0,0,6,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0x90,0x60,0x90,0x90,0x60,0x90, +}; + +static const BitmapCharRec ch164 = {4,6,0,-1,5,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xb0,0x48,0x40,0x40,0xe0,0x40,0x48,0x30, +}; + +static const BitmapCharRec ch163 = {5,8,0,0,6,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x40,0x70,0xa8,0xa0,0xa0,0xa8,0x70,0x10, +}; + +static const BitmapCharRec ch162 = {5,8,0,1,6,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch161 = {1,8,-1,2,3,ch161data}; + +/* char: 0xa0 */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,3,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,3,0}; +#endif + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x98,0x64, +}; + +static const BitmapCharRec ch126 = {6,2,0,-3,7,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0x80,0x40,0x40,0x40,0x40,0x20,0x40,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch125 = {3,10,0,2,3,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch124 = {1,10,-1,2,3,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x20,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch123 = {3,10,0,2,3,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xf0,0x80,0x40,0x20,0x10,0xf0, +}; + +static const BitmapCharRec ch122 = {4,6,0,0,5,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x80,0x40,0x40,0x60,0xa0,0xa0,0x90,0x90, +}; + +static const BitmapCharRec ch121 = {4,8,0,2,5,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0x88,0x88,0x50,0x20,0x50,0x88, +}; + +static const BitmapCharRec ch120 = {5,6,0,0,6,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x28,0x28,0x54,0x54,0x92,0x92, +}; + +static const BitmapCharRec ch119 = {7,6,0,0,8,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x20,0x20,0x50,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch118 = {5,6,0,0,6,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x70,0x90,0x90,0x90,0x90,0x90, +}; + +static const BitmapCharRec ch117 = {4,6,0,0,5,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x60,0x40,0x40,0x40,0x40,0xe0,0x40,0x40, +}; + +static const BitmapCharRec ch116 = {3,8,0,0,4,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0x60,0x90,0x10,0x60,0x90,0x60, +}; + +static const BitmapCharRec ch115 = {4,6,0,0,5,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0x80,0x80,0x80,0x80,0xc0,0xa0, +}; + +static const BitmapCharRec ch114 = {3,6,0,0,4,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x8,0x8,0x68,0x98,0x88,0x88,0x98,0x68, +}; + +static const BitmapCharRec ch113 = {5,8,0,2,6,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0x80,0x80,0xb0,0xc8,0x88,0x88,0xc8,0xb0, +}; + +static const BitmapCharRec ch112 = {5,8,0,2,6,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x70,0x88,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch111 = {5,6,0,0,6,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0x88,0x88,0x88,0x88,0xc8,0xb0, +}; + +static const BitmapCharRec ch110 = {5,6,0,0,6,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0x92,0x92,0x92,0x92,0x92,0xec, +}; + +static const BitmapCharRec ch109 = {7,6,0,0,8,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch108 = {1,8,0,0,2,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0x90,0x90,0xa0,0xc0,0xa0,0x90,0x80,0x80, +}; + +static const BitmapCharRec ch107 = {4,8,0,0,5,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch106 = {1,9,0,1,2,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch105 = {1,8,0,0,2,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0x88,0x88,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch104 = {5,8,0,0,6,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x70,0x8,0x68,0x98,0x88,0x88,0x98,0x68, +}; + +static const BitmapCharRec ch103 = {5,8,0,2,6,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x40,0x40,0x40,0x40,0x40,0xe0,0x40,0x30, +}; + +static const BitmapCharRec ch102 = {4,8,0,0,4,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x60,0x90,0x80,0xf0,0x90,0x60, +}; + +static const BitmapCharRec ch101 = {4,6,0,0,5,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x68,0x98,0x88,0x88,0x98,0x68,0x8,0x8, +}; + +static const BitmapCharRec ch100 = {5,8,0,0,6,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x60,0x90,0x80,0x80,0x90,0x60, +}; + +static const BitmapCharRec ch99 = {4,6,0,0,5,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xb0,0xc8,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch98 = {5,8,0,0,6,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x68,0x90,0x90,0x70,0x10,0xe0, +}; + +static const BitmapCharRec ch97 = {5,6,0,0,5,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0x80,0x80,0x40, +}; + +static const BitmapCharRec ch96 = {2,3,0,-5,3,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xfc, +}; + +static const BitmapCharRec ch95 = {6,1,0,2,6,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x88,0x50,0x50,0x20,0x20, +}; + +static const BitmapCharRec ch94 = {5,5,0,-3,6,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, +}; + +static const BitmapCharRec ch93 = {2,10,0,2,3,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x20,0x20,0x40,0x40,0x40,0x40,0x80,0x80, +}; + +static const BitmapCharRec ch92 = {3,8,0,0,3,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, +}; + +static const BitmapCharRec ch91 = {2,10,-1,2,3,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xf8,0x80,0x40,0x20,0x20,0x10,0x8,0xf8, +}; + +static const BitmapCharRec ch90 = {5,8,-1,0,7,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x10,0x10,0x10,0x28,0x28,0x44,0x44,0x82, +}; + +static const BitmapCharRec ch89 = {7,8,0,0,7,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0x88,0x88,0x50,0x50,0x20,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch88 = {5,8,-1,0,7,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x22,0x0,0x22,0x0,0x22,0x0,0x55,0x0,0x49,0x0,0x49,0x0,0x88,0x80,0x88,0x80, +}; + +static const BitmapCharRec ch87 = {9,8,0,0,9,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x10,0x28,0x28,0x44,0x44,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch86 = {7,8,0,0,7,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch85 = {6,8,-1,0,8,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xf8, +}; + +static const BitmapCharRec ch84 = {5,8,0,0,5,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x70,0x88,0x88,0x8,0x70,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch83 = {5,8,-1,0,7,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0x88,0x88,0x88,0x88,0xf0,0x88,0x88,0xf0, +}; + +static const BitmapCharRec ch82 = {5,8,-1,0,7,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x2,0x7c,0x8c,0x94,0x84,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch81 = {7,9,-1,1,8,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0x80,0x80,0x80,0x80,0xf0,0x88,0x88,0xf0, +}; + +static const BitmapCharRec ch80 = {5,8,-1,0,7,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x78, +}; + +static const BitmapCharRec ch79 = {6,8,-1,0,8,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0x8c,0x8c,0x94,0x94,0xa4,0xa4,0xc4,0xc4, +}; + +static const BitmapCharRec ch78 = {6,8,-1,0,8,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0x92,0x92,0x92,0xaa,0xaa,0xc6,0xc6,0x82, +}; + +static const BitmapCharRec ch77 = {7,8,-1,0,9,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xf0,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch76 = {4,8,-1,0,6,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0x88,0x88,0x90,0x90,0xe0,0xa0,0x90,0x88, +}; + +static const BitmapCharRec ch75 = {5,8,-1,0,7,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x60,0x90,0x10,0x10,0x10,0x10,0x10,0x10, +}; + +static const BitmapCharRec ch74 = {4,8,0,0,5,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch73 = {1,8,-1,0,3,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0x84,0x84,0x84,0x84,0xfc,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch72 = {6,8,-1,0,8,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x74,0x8c,0x84,0x8c,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch71 = {6,8,-1,0,8,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0x80,0x80,0x80,0x80,0xf0,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch70 = {5,8,-1,0,6,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xf8,0x80,0x80,0x80,0xf8,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch69 = {5,8,-1,0,7,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xf0,0x88,0x84,0x84,0x84,0x84,0x88,0xf0, +}; + +static const BitmapCharRec ch68 = {6,8,-1,0,8,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x78,0x84,0x80,0x80,0x80,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch67 = {6,8,-1,0,8,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xf0,0x88,0x88,0x88,0xf0,0x88,0x88,0xf0, +}; + +static const BitmapCharRec ch66 = {5,8,-1,0,7,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10, +}; + +static const BitmapCharRec ch65 = {7,8,0,0,7,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x3e,0x0,0x40,0x0,0x9b,0x0,0xa4,0x80,0xa4,0x80,0xa2,0x40,0x92,0x40,0x4d,0x40, +0x20,0x80,0x1f,0x0, +}; + +static const BitmapCharRec ch64 = {10,10,0,2,11,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x40,0x0,0x40,0x40,0x20,0x10,0x90,0x60, +}; + +static const BitmapCharRec ch63 = {4,8,-1,0,6,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0x80,0x40,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch62 = {3,5,-1,-1,6,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xf0,0x0,0xf0, +}; + +static const BitmapCharRec ch61 = {4,3,0,-2,5,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x20,0x40,0x80,0x40,0x20, +}; + +static const BitmapCharRec ch60 = {3,5,-1,-1,6,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x40,0x40,0x0,0x0,0x0,0x0,0x40, +}; + +static const BitmapCharRec ch59 = {2,8,0,2,3,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0x80,0x0,0x0,0x0,0x0,0x80, +}; + +static const BitmapCharRec ch58 = {1,6,-1,0,3,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0x70,0x88,0x8,0x68,0x98,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch57 = {5,8,0,0,6,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch56 = {5,8,0,0,6,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x40,0x40,0x20,0x20,0x10,0x10,0x8,0xf8, +}; + +static const BitmapCharRec ch55 = {5,8,0,0,6,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x70,0x88,0x88,0xc8,0xb0,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch54 = {5,8,0,0,6,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x70,0x88,0x8,0x8,0xf0,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch53 = {5,8,0,0,6,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x10,0x10,0xf8,0x90,0x50,0x50,0x30,0x10, +}; + +static const BitmapCharRec ch52 = {5,8,0,0,6,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x70,0x88,0x8,0x8,0x30,0x8,0x88,0x70, +}; + +static const BitmapCharRec ch51 = {5,8,0,0,6,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xf8,0x80,0x40,0x30,0x8,0x8,0x88,0x70, +}; + +static const BitmapCharRec ch50 = {5,8,0,0,6,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch49 = {2,8,-1,0,6,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch48 = {5,8,0,0,6,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0x80,0x80,0x40,0x40,0x40,0x40,0x20,0x20, +}; + +static const BitmapCharRec ch47 = {3,8,0,0,3,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0x80, +}; + +static const BitmapCharRec ch46 = {1,1,-1,0,3,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xf8, +}; + +static const BitmapCharRec ch45 = {5,1,-1,-3,7,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x40,0x40, +}; + +static const BitmapCharRec ch44 = {2,3,0,2,3,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch43 = {5,5,0,-1,6,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0xa0,0x40,0xa0, +}; + +static const BitmapCharRec ch42 = {3,3,0,-5,4,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {3,10,-1,2,4,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x20,0x40,0x40,0x80,0x80,0x80,0x80,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch40 = {3,10,0,2,4,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x80,0x40,0x40, +}; + +static const BitmapCharRec ch39 = {2,3,-1,-5,3,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x64,0x98,0x98,0xa4,0x60,0x50,0x50,0x20, +}; + +static const BitmapCharRec ch38 = {6,8,-1,0,8,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x26,0x29,0x16,0x10,0x8,0x68,0x94,0x64, +}; + +static const BitmapCharRec ch37 = {8,8,0,0,9,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x20,0x70,0xa8,0x28,0x70,0xa0,0xa8,0x70,0x20, +}; + +static const BitmapCharRec ch36 = {5,9,0,1,6,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x50,0x50,0xf8,0x28,0x7c,0x28,0x28, +}; + +static const BitmapCharRec ch35 = {6,7,0,0,6,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0xa0,0xa0, +}; + +static const BitmapCharRec ch34 = {3,2,-1,-6,4,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0x80,0x0,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch33 = {1,8,-1,0,3,ch33data}; + +/* char: 0x20 ' ' */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {0,0,0,0,3,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,3,0}; +#endif + +static const BitmapCharRec * const chars[] = { +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmapHelvetica10 = { +"-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", +224, +32, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_hel12.c b/lib/glut-3.7.6/lib/glut/glut_hel12.c new file mode 100644 index 0000000000..1760c5b115 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_hel12.c @@ -0,0 +1,1788 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmapHelvetica12 XXX +#include "glutbitmap.h" +#undef glutBitmapHelvetica12 + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0xc0,0x20,0x20,0x20,0x30,0x50,0x50,0x48,0x88,0x88,0x0,0x50, +}; + +static const BitmapCharRec ch255 = {5,12,-1,3,7,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0x80,0x80,0x80,0xb0,0xc8,0x88,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch254 = {5,12,-1,3,7,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x80,0x40,0x20,0x20,0x50,0x50,0x90,0x88,0x88,0x88,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch253 = {5,13,-1,3,7,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x68,0x98,0x88,0x88,0x88,0x88,0x88,0x0,0x50, +}; + +static const BitmapCharRec ch252 = {5,9,-1,0,7,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x68,0x98,0x88,0x88,0x88,0x88,0x88,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch251 = {5,10,-1,0,7,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x68,0x98,0x88,0x88,0x88,0x88,0x88,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch250 = {5,10,-1,0,7,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x68,0x98,0x88,0x88,0x88,0x88,0x88,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch249 = {5,10,-1,0,7,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0xb8,0x44,0x64,0x54,0x4c,0x44,0x3a, +}; + +static const BitmapCharRec ch248 = {7,7,0,0,7,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x20,0x0,0xf8,0x0,0x20, +}; + +static const BitmapCharRec ch247 = {5,5,-1,-1,7,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0,0x50, +}; + +static const BitmapCharRec ch246 = {5,9,-1,0,7,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch245 = {5,10,-1,0,7,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch244 = {5,10,-1,0,7,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch243 = {5,10,-1,0,7,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch242 = {5,10,-1,0,7,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0x88,0x88,0x88,0x88,0x88,0xc8,0xb0,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch241 = {5,10,-1,0,7,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x70,0x88,0x88,0x88,0x88,0x78,0x8,0x50,0x30,0x68, +}; + +static const BitmapCharRec ch240 = {5,10,-1,0,7,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0, +}; + +static const BitmapCharRec ch239 = {3,9,0,0,3,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch238 = {3,10,0,0,3,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x40, +}; + +static const BitmapCharRec ch237 = {2,10,-1,0,3,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch236 = {2,10,0,0,3,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x70,0x88,0x80,0xf8,0x88,0x88,0x70,0x0,0x50, +}; + +static const BitmapCharRec ch235 = {5,9,-1,0,7,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x70,0x88,0x80,0xf8,0x88,0x88,0x70,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch234 = {5,10,-1,0,7,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x70,0x88,0x80,0xf8,0x88,0x88,0x70,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch233 = {5,10,-1,0,7,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x70,0x88,0x80,0xf8,0x88,0x88,0x70,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch232 = {5,10,-1,0,7,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x60,0x10,0x20,0x70,0x88,0x80,0x80,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch231 = {5,10,-1,3,7,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x77,0x0,0x88,0x80,0x88,0x0,0x7f,0x80,0x8,0x80,0x88,0x80,0x77,0x0, +}; + +static const BitmapCharRec ch230 = {9,7,-1,0,11,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x30,0x48,0x30, +}; + +static const BitmapCharRec ch229 = {6,10,-1,0,7,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x0,0x50, +}; + +static const BitmapCharRec ch228 = {6,9,-1,0,7,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch227 = {6,10,-1,0,7,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch226 = {6,10,-1,0,7,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch225 = {6,10,-1,0,7,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch224 = {6,10,-1,0,7,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0xb0,0x88,0x88,0x88,0xb0,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch223 = {5,9,-1,0,7,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0x80,0x80,0xf8,0x84,0x84,0x84,0xf8,0x80,0x80, +}; + +static const BitmapCharRec ch222 = {6,9,-1,0,8,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x10,0x10,0x10,0x10,0x28,0x44,0x44,0x82,0x82,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch221 = {7,12,-1,0,9,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x48, +}; + +static const BitmapCharRec ch220 = {6,11,-1,0,8,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch219 = {6,12,-1,0,8,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch218 = {6,12,-1,0,8,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch217 = {6,12,-1,0,8,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x80,0x0,0x5e,0x0,0x21,0x0,0x50,0x80,0x48,0x80,0x44,0x80,0x44,0x80,0x42,0x80, +0x21,0x0,0x1e,0x80,0x0,0x40, +}; + +static const BitmapCharRec ch216 = {10,11,0,1,10,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x88,0x50,0x20,0x50,0x88, +}; + +static const BitmapCharRec ch215 = {5,5,-1,-1,7,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c,0x0,0x24, +}; + +static const BitmapCharRec ch214 = {8,11,-1,0,10,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch213 = {8,12,-1,0,10,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c,0x0,0x14,0x8, +}; + +static const BitmapCharRec ch212 = {8,12,-1,0,10,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c,0x0,0x8,0x4, +}; + +static const BitmapCharRec ch211 = {8,12,-1,0,10,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c,0x0,0x8,0x10, +}; + +static const BitmapCharRec ch210 = {8,12,-1,0,10,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0x82,0x86,0x8a,0x8a,0x92,0xa2,0xa2,0xc2,0x82,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch209 = {7,12,-1,0,9,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0x7c,0x42,0x41,0x41,0xf1,0x41,0x41,0x42,0x7c, +}; + +static const BitmapCharRec ch208 = {8,9,0,0,9,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0, +}; + +static const BitmapCharRec ch207 = {3,11,0,0,3,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch206 = {3,12,0,0,3,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x40, +}; + +static const BitmapCharRec ch205 = {2,12,-1,0,3,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch204 = {2,12,0,0,3,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xfc,0x80,0x80,0x80,0xfc,0x80,0x80,0x80,0xfc,0x0,0x28, +}; + +static const BitmapCharRec ch203 = {6,11,-1,0,8,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xfc,0x80,0x80,0x80,0xfc,0x80,0x80,0x80,0xfc,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch202 = {6,12,-1,0,8,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xfc,0x80,0x80,0x80,0xfc,0x80,0x80,0x80,0xfc,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch201 = {6,12,-1,0,8,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xfc,0x80,0x80,0x80,0xfc,0x80,0x80,0x80,0xfc,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch200 = {6,12,-1,0,8,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x30,0x8,0x8,0x3c,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x3c, +}; + +static const BitmapCharRec ch199 = {7,12,-1,3,9,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0x8f,0x80,0x88,0x0,0x88,0x0,0x78,0x0,0x4f,0x80,0x48,0x0,0x28,0x0,0x28,0x0, +0x1f,0x80, +}; + +static const BitmapCharRec ch198 = {9,9,-1,0,11,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x10,0x28,0x10, +}; + +static const BitmapCharRec ch197 = {7,12,-1,0,9,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x0,0x28, +}; + +static const BitmapCharRec ch196 = {7,11,-1,0,9,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch195 = {7,12,-1,0,9,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch194 = {7,12,-1,0,9,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch193 = {7,12,-1,0,9,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x10,0x10,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch192 = {7,12,-1,0,9,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x70,0x88,0x88,0x40,0x40,0x20,0x20,0x0,0x20, +}; + +static const BitmapCharRec ch191 = {5,9,-1,3,7,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x21,0x0,0x17,0x80,0x15,0x0,0xb,0x0,0xc9,0x0,0x24,0x0,0x44,0x0,0x22,0x0, +0xe1,0x0, +}; + +static const BitmapCharRec ch190 = {9,9,0,0,10,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x47,0x80,0x22,0x0,0x11,0x0,0x14,0x80,0x4b,0x0,0x48,0x0,0x44,0x0,0xc2,0x0, +0x41,0x0, +}; + +static const BitmapCharRec ch189 = {9,9,0,0,10,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x41,0x0,0x27,0x80,0x15,0x0,0x13,0x0,0x49,0x0,0x44,0x0,0x44,0x0,0xc2,0x0, +0x41,0x0, +}; + +static const BitmapCharRec ch188 = {9,9,0,0,10,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0xa0,0x50,0x28,0x50,0xa0, +}; + +static const BitmapCharRec ch187 = {5,5,-1,-1,7,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xe0,0x0,0xe0,0xa0,0xe0, +}; + +static const BitmapCharRec ch186 = {3,5,-1,-4,5,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0x40,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch185 = {2,5,-1,-3,4,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0xc0,0x20,0x20,0x40, +}; + +static const BitmapCharRec ch184 = {3,4,0,3,3,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0x80, +}; + +static const BitmapCharRec ch183 = {1,1,-1,-3,3,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x28,0x28,0x28,0x28,0x28,0x28,0x68,0xe8,0xe8,0xe8,0x68,0x3c, +}; + +static const BitmapCharRec ch182 = {6,12,0,3,7,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x80,0x80,0x80,0xe8,0x98,0x88,0x88,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch181 = {5,10,-1,3,7,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0x80,0x40, +}; + +static const BitmapCharRec ch180 = {2,2,0,-8,2,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0xc0,0x20,0x40,0x20,0xe0, +}; + +static const BitmapCharRec ch179 = {3,5,0,-3,4,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xf0,0x40,0x20,0x90,0x60, +}; + +static const BitmapCharRec ch178 = {4,5,0,-3,4,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xf8,0x0,0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch177 = {5,7,-1,0,7,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch176 = {4,4,0,-4,5,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xf0, +}; + +static const BitmapCharRec ch175 = {4,1,0,-8,4,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x3e,0x0,0x41,0x0,0x94,0x80,0x94,0x80,0x98,0x80,0x94,0x80,0x9c,0x80,0x41,0x0, +0x3e,0x0, +}; + +static const BitmapCharRec ch174 = {9,9,-1,0,11,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xf0, +}; + +static const BitmapCharRec ch173 = {4,1,0,-3,5,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x4,0x4,0x4,0xfc, +}; + +static const BitmapCharRec ch172 = {6,4,-1,-2,8,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x28,0x50,0xa0,0x50,0x28, +}; + +static const BitmapCharRec ch171 = {5,5,-1,-1,7,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xe0,0x0,0xa0,0x20,0xe0, +}; + +static const BitmapCharRec ch170 = {3,5,-1,-4,5,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x3e,0x0,0x41,0x0,0x9c,0x80,0xa2,0x80,0xa0,0x80,0xa2,0x80,0x9c,0x80,0x41,0x0, +0x3e,0x0, +}; + +static const BitmapCharRec ch169 = {9,9,-1,0,11,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xa0, +}; + +static const BitmapCharRec ch168 = {3,1,0,-8,3,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x70,0x88,0x8,0x30,0x48,0x88,0x88,0x90,0x60,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch167 = {5,12,0,3,6,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch166 = {1,11,-1,2,3,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x20,0x20,0xf8,0x20,0xf8,0x20,0x50,0x88,0x88, +}; + +static const BitmapCharRec ch165 = {5,9,-1,0,7,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0x84,0x78,0x48,0x48,0x78,0x84, +}; + +static const BitmapCharRec ch164 = {6,6,0,-1,7,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xb0,0x48,0x20,0x20,0xf0,0x40,0x40,0x48,0x30, +}; + +static const BitmapCharRec ch163 = {5,9,-1,0,7,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x40,0x70,0xc8,0xa0,0xa0,0xa0,0xa8,0x70,0x10, +}; + +static const BitmapCharRec ch162 = {5,9,-1,1,7,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch161 = {1,10,-1,3,3,ch161data}; + +/* char: 0xa0 */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,4,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,4,0}; +#endif + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x98,0x64, +}; + +static const BitmapCharRec ch126 = {6,2,0,-3,7,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0xc0,0x20,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xc0, +}; + +static const BitmapCharRec ch125 = {4,12,0,3,4,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch124 = {1,12,-1,3,3,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x30,0x40,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, +}; + +static const BitmapCharRec ch123 = {4,12,0,3,4,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xf0,0x80,0x40,0x40,0x20,0x10,0xf0, +}; + +static const BitmapCharRec ch122 = {4,7,-1,0,6,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x80,0x40,0x20,0x20,0x50,0x50,0x90,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch121 = {5,10,-1,3,7,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0x84,0x84,0x48,0x30,0x30,0x48,0x84, +}; + +static const BitmapCharRec ch120 = {6,7,0,0,6,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x22,0x0,0x22,0x0,0x55,0x0,0x49,0x0,0x49,0x0,0x88,0x80,0x88,0x80, +}; + +static const BitmapCharRec ch119 = {9,7,0,0,9,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x20,0x20,0x50,0x50,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch118 = {5,7,-1,0,7,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x68,0x98,0x88,0x88,0x88,0x88,0x88, +}; + +static const BitmapCharRec ch117 = {5,7,-1,0,7,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x60,0x40,0x40,0x40,0x40,0x40,0xe0,0x40,0x40, +}; + +static const BitmapCharRec ch116 = {3,9,0,0,3,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0x60,0x90,0x10,0x60,0x80,0x90,0x60, +}; + +static const BitmapCharRec ch115 = {4,7,-1,0,6,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0x80,0x80,0x80,0x80,0x80,0xc0,0xa0, +}; + +static const BitmapCharRec ch114 = {3,7,-1,0,4,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x8,0x8,0x8,0x68,0x98,0x88,0x88,0x88,0x98,0x68, +}; + +static const BitmapCharRec ch113 = {5,10,-1,3,7,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0x80,0x80,0x80,0xb0,0xc8,0x88,0x88,0x88,0xc8,0xb0, +}; + +static const BitmapCharRec ch112 = {5,10,-1,3,7,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch111 = {5,7,-1,0,7,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0x88,0x88,0x88,0x88,0x88,0xc8,0xb0, +}; + +static const BitmapCharRec ch110 = {5,7,-1,0,7,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0x92,0x92,0x92,0x92,0x92,0xda,0xa4, +}; + +static const BitmapCharRec ch109 = {7,7,-1,0,9,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch108 = {1,9,-1,0,3,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0x88,0x90,0xa0,0xc0,0xc0,0xa0,0x90,0x80,0x80, +}; + +static const BitmapCharRec ch107 = {5,9,-1,0,6,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x0,0x40, +}; + +static const BitmapCharRec ch106 = {2,12,0,3,3,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch105 = {1,9,-1,0,3,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0x88,0x88,0x88,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch104 = {5,9,-1,0,7,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x70,0x88,0x8,0x68,0x98,0x88,0x88,0x88,0x98,0x68, +}; + +static const BitmapCharRec ch103 = {5,10,-1,3,7,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x40,0x40,0x40,0x40,0x40,0x40,0xe0,0x40,0x30, +}; + +static const BitmapCharRec ch102 = {4,9,0,0,3,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x70,0x88,0x80,0xf8,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch101 = {5,7,-1,0,7,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x68,0x98,0x88,0x88,0x88,0x98,0x68,0x8,0x8, +}; + +static const BitmapCharRec ch100 = {5,9,-1,0,7,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x70,0x88,0x80,0x80,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch99 = {5,7,-1,0,7,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xb0,0xc8,0x88,0x88,0x88,0xc8,0xb0,0x80,0x80, +}; + +static const BitmapCharRec ch98 = {5,9,-1,0,7,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x74,0x88,0x88,0x78,0x8,0x88,0x70, +}; + +static const BitmapCharRec ch97 = {6,7,-1,0,7,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0xc0,0x80,0x40, +}; + +static const BitmapCharRec ch96 = {2,3,0,-6,3,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xfe, +}; + +static const BitmapCharRec ch95 = {7,1,0,2,7,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x88,0x50,0x20, +}; + +static const BitmapCharRec ch94 = {5,3,0,-5,6,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, +}; + +static const BitmapCharRec ch93 = {2,12,0,3,3,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x80, +}; + +static const BitmapCharRec ch92 = {4,9,0,0,4,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, +}; + +static const BitmapCharRec ch91 = {2,12,-1,3,3,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xfe,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0xfe, +}; + +static const BitmapCharRec ch90 = {7,9,-1,0,9,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x10,0x10,0x10,0x10,0x28,0x44,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch89 = {7,9,-1,0,9,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0x82,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x82, +}; + +static const BitmapCharRec ch88 = {7,9,-1,0,9,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x22,0x0,0x22,0x0,0x22,0x0,0x55,0x0,0x55,0x0,0x49,0x0,0x88,0x80,0x88,0x80, +0x88,0x80, +}; + +static const BitmapCharRec ch87 = {9,9,-1,0,11,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x10,0x10,0x28,0x28,0x44,0x44,0x44,0x82,0x82, +}; + +static const BitmapCharRec ch86 = {7,9,-1,0,9,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +}; + +static const BitmapCharRec ch85 = {6,9,-1,0,8,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xfe, +}; + +static const BitmapCharRec ch84 = {7,9,0,0,7,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x78,0x84,0x84,0x4,0x18,0x60,0x80,0x84,0x78, +}; + +static const BitmapCharRec ch83 = {6,9,-1,0,8,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0x84,0x84,0x84,0x88,0xf8,0x84,0x84,0x84,0xf8, +}; + +static const BitmapCharRec ch82 = {6,9,-1,0,8,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x3d,0x42,0x85,0x89,0x81,0x81,0x81,0x42,0x3c, +}; + +static const BitmapCharRec ch81 = {8,9,-1,0,10,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0x80,0x80,0x80,0x80,0xf8,0x84,0x84,0x84,0xf8, +}; + +static const BitmapCharRec ch80 = {6,9,-1,0,8,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x3c,0x42,0x81,0x81,0x81,0x81,0x81,0x42,0x3c, +}; + +static const BitmapCharRec ch79 = {8,9,-1,0,10,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0x82,0x86,0x8a,0x8a,0x92,0xa2,0xa2,0xc2,0x82, +}; + +static const BitmapCharRec ch78 = {7,9,-1,0,9,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0x88,0x80,0x88,0x80,0x94,0x80,0x94,0x80,0xa2,0x80,0xa2,0x80,0xc1,0x80,0xc1,0x80, +0x80,0x80, +}; + +static const BitmapCharRec ch77 = {9,9,-1,0,11,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xf8,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch76 = {5,9,-1,0,7,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0x82,0x84,0x88,0x90,0xe0,0xa0,0x90,0x88,0x84, +}; + +static const BitmapCharRec ch75 = {7,9,-1,0,8,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x70,0x88,0x88,0x8,0x8,0x8,0x8,0x8,0x8, +}; + +static const BitmapCharRec ch74 = {5,9,-1,0,7,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch73 = {1,9,-1,0,3,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0x82,0x82,0x82,0x82,0xfe,0x82,0x82,0x82,0x82, +}; + +static const BitmapCharRec ch72 = {7,9,-1,0,9,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x3a,0x46,0x82,0x82,0x8e,0x80,0x80,0x42,0x3c, +}; + +static const BitmapCharRec ch71 = {7,9,-1,0,9,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0x80,0x80,0x80,0x80,0xf8,0x80,0x80,0x80,0xfc, +}; + +static const BitmapCharRec ch70 = {6,9,-1,0,8,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xfc,0x80,0x80,0x80,0xfc,0x80,0x80,0x80,0xfc, +}; + +static const BitmapCharRec ch69 = {6,9,-1,0,8,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xf8,0x84,0x82,0x82,0x82,0x82,0x82,0x84,0xf8, +}; + +static const BitmapCharRec ch68 = {7,9,-1,0,9,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x3c,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x3c, +}; + +static const BitmapCharRec ch67 = {7,9,-1,0,9,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xf8,0x84,0x84,0x84,0xf8,0x84,0x84,0x84,0xf8, +}; + +static const BitmapCharRec ch66 = {6,9,-1,0,8,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0x82,0x82,0x82,0x7c,0x44,0x44,0x28,0x28,0x10, +}; + +static const BitmapCharRec ch65 = {7,9,-1,0,9,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x3e,0x0,0x40,0x0,0x9b,0x0,0xa6,0x80,0xa2,0x40,0xa2,0x40,0x92,0x40,0x4d,0x40, +0x60,0x80,0x1f,0x0, +}; + +static const BitmapCharRec ch64 = {10,10,-1,1,12,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x20,0x0,0x20,0x20,0x10,0x10,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch63 = {5,9,-1,0,7,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0xc0,0x30,0xc,0x30,0xc0, +}; + +static const BitmapCharRec ch62 = {6,5,-1,-1,7,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xf8,0x0,0xf8, +}; + +static const BitmapCharRec ch61 = {5,3,-1,-2,7,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0xc,0x30,0xc0,0x30,0xc, +}; + +static const BitmapCharRec ch60 = {6,5,0,-1,7,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x40,0x40,0x0,0x0,0x0,0x0,0x40, +}; + +static const BitmapCharRec ch59 = {2,8,0,2,3,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0x80,0x0,0x0,0x0,0x0,0x80, +}; + +static const BitmapCharRec ch58 = {1,6,-1,0,3,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0x70,0x88,0x8,0x8,0x78,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch57 = {5,9,-1,0,7,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x70,0x88,0x88,0x88,0x88,0x70,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch56 = {5,9,-1,0,7,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x40,0x40,0x20,0x20,0x20,0x10,0x10,0x8,0xf8, +}; + +static const BitmapCharRec ch55 = {5,9,-1,0,7,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x70,0x88,0x88,0x88,0xc8,0xb0,0x80,0x88,0x70, +}; + +static const BitmapCharRec ch54 = {5,9,-1,0,7,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x70,0x88,0x88,0x8,0x8,0xf0,0x80,0x80,0xf8, +}; + +static const BitmapCharRec ch53 = {5,9,-1,0,7,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x8,0x8,0xfc,0x88,0x48,0x28,0x28,0x18,0x8, +}; + +static const BitmapCharRec ch52 = {6,9,0,0,7,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x70,0x88,0x88,0x8,0x8,0x30,0x8,0x88,0x70, +}; + +static const BitmapCharRec ch51 = {5,9,-1,0,7,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xf8,0x80,0x80,0x40,0x20,0x10,0x8,0x88,0x70, +}; + +static const BitmapCharRec ch50 = {5,9,-1,0,7,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x20, +}; + +static const BitmapCharRec ch49 = {3,9,-1,0,7,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70, +}; + +static const BitmapCharRec ch48 = {5,9,-1,0,7,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10, +}; + +static const BitmapCharRec ch47 = {4,9,0,0,4,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0x80, +}; + +static const BitmapCharRec ch46 = {1,1,-1,0,3,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xf8, +}; + +static const BitmapCharRec ch45 = {5,1,-1,-3,8,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x40,0x40, +}; + +static const BitmapCharRec ch44 = {2,3,-1,2,4,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch43 = {5,5,-1,-1,7,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0xa0,0x40,0xa0, +}; + +static const BitmapCharRec ch42 = {3,3,-1,-6,5,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {3,12,0,3,4,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x20,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch40 = {3,12,-1,3,4,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x80,0x40,0xc0, +}; + +static const BitmapCharRec ch39 = {2,3,-1,-6,3,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x72,0x8c,0x84,0x8a,0x50,0x30,0x48,0x48,0x30, +}; + +static const BitmapCharRec ch38 = {7,9,-1,0,9,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x23,0x0,0x14,0x80,0x14,0x80,0x13,0x0,0x8,0x0,0x68,0x0,0x94,0x0,0x94,0x0, +0x62,0x0, +}; + +static const BitmapCharRec ch37 = {9,9,-1,0,11,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x20,0x70,0xa8,0xa8,0x28,0x70,0xa0,0xa8,0x70,0x20, +}; + +static const BitmapCharRec ch36 = {5,10,-1,1,7,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x50,0x50,0x50,0xfc,0x28,0xfc,0x28,0x28, +}; + +static const BitmapCharRec ch35 = {6,8,0,0,7,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0xa0,0xa0,0xa0, +}; + +static const BitmapCharRec ch34 = {3,3,-1,-6,5,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0x80,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch33 = {1,9,-1,0,3,ch33data}; + +/* char: 0x20 ' ' */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,4,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,4,0}; +#endif + +static const BitmapCharRec * const chars[] = { +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmapHelvetica12 = { +"-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", +224, +32, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_hel18.c b/lib/glut-3.7.6/lib/glut/glut_hel18.c new file mode 100644 index 0000000000..c0af0c7032 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_hel18.c @@ -0,0 +1,1897 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmapHelvetica18 XXX +#include "glutbitmap.h" +#undef glutBitmapHelvetica18 + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0x70,0x70,0x18,0x18,0x18,0x18,0x3c,0x24,0x66,0x66,0x66,0xc3,0xc3,0xc3,0x0,0x66, +0x66, +}; + +static const BitmapCharRec ch255 = {8,17,-1,4,10,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xde,0x0,0xff,0x0,0xe3,0x0,0xc1,0x80, +0xc1,0x80,0xc1,0x80,0xc1,0x80,0xe3,0x0,0xff,0x0,0xde,0x0,0xc0,0x0,0xc0,0x0, +0xc0,0x0,0xc0,0x0, +}; + +static const BitmapCharRec ch254 = {9,18,-1,4,11,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x70,0x70,0x18,0x18,0x18,0x18,0x3c,0x24,0x66,0x66,0x66,0xc3,0xc3,0xc3,0x0,0x18, +0xc,0x6, +}; + +static const BitmapCharRec ch253 = {8,18,-1,4,10,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x73,0xfb,0xc7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x0,0x66,0x66, +}; + +static const BitmapCharRec ch252 = {8,13,-1,0,10,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x73,0xfb,0xc7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x0,0x66,0x3c,0x18, +}; + +static const BitmapCharRec ch251 = {8,14,-1,0,10,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x73,0xfb,0xc7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x0,0x18,0xc,0x6, +}; + +static const BitmapCharRec ch250 = {8,14,-1,0,10,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x73,0xfb,0xc7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x0,0xc,0x18,0x30, +}; + +static const BitmapCharRec ch249 = {8,14,-1,0,10,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0xce,0x0,0x7f,0x80,0x31,0x80,0x78,0xc0,0x6c,0xc0,0x66,0xc0,0x63,0xc0,0x31,0x80, +0x3f,0xc0,0xe,0x60, +}; + +static const BitmapCharRec ch248 = {11,10,0,0,11,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x18,0x18,0x0,0xff,0xff,0x0,0x18,0x18, +}; + +static const BitmapCharRec ch247 = {8,8,-1,-1,10,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x0,0x0,0x36,0x0,0x36,0x0, +}; + +static const BitmapCharRec ch246 = {9,13,-1,0,11,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x0,0x0,0x26,0x0,0x2d,0x0,0x19,0x0, +}; + +static const BitmapCharRec ch245 = {9,14,-1,0,11,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x0,0x0,0x33,0x0,0x1e,0x0,0xc,0x0, +}; + +static const BitmapCharRec ch244 = {9,14,-1,0,11,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x0,0x0,0x18,0x0,0xc,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch243 = {9,14,-1,0,11,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x0,0x0,0xc,0x0,0x18,0x0,0x30,0x0, +}; + +static const BitmapCharRec ch242 = {9,14,-1,0,11,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xe3,0xdf,0xce,0x0,0x4c,0x5a,0x32, +}; + +static const BitmapCharRec ch241 = {8,14,-1,0,10,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0,0x4c,0x0,0x38,0x0,0x36,0x0,0x60,0x0, +}; + +static const BitmapCharRec ch240 = {9,14,-1,0,11,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x0,0xd8,0xd8, +}; + +static const BitmapCharRec ch239 = {5,13,0,0,4,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x0,0xcc,0x78,0x30, +}; + +static const BitmapCharRec ch238 = {6,14,1,0,4,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x0,0xc0,0x60,0x30, +}; + +static const BitmapCharRec ch237 = {4,14,0,0,4,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x0,0x30,0x60,0xc0, +}; + +static const BitmapCharRec ch236 = {4,14,0,0,4,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x3c,0x7f,0xe3,0xc0,0xc0,0xff,0xc3,0xc3,0x7e,0x3c,0x0,0x36,0x36, +}; + +static const BitmapCharRec ch235 = {8,13,-1,0,10,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x3c,0x7f,0xe3,0xc0,0xc0,0xff,0xc3,0xc3,0x7e,0x3c,0x0,0x66,0x3c,0x18, +}; + +static const BitmapCharRec ch234 = {8,14,-1,0,10,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x3c,0x7f,0xe3,0xc0,0xc0,0xff,0xc3,0xc3,0x7e,0x3c,0x0,0x18,0xc,0x6, +}; + +static const BitmapCharRec ch233 = {8,14,-1,0,10,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x3c,0x7f,0xe3,0xc0,0xc0,0xff,0xc3,0xc3,0x7e,0x3c,0x0,0x18,0x30,0x60, +}; + +static const BitmapCharRec ch232 = {8,14,-1,0,10,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x78,0x6c,0xc,0x38,0x3e,0x7f,0x63,0xc0,0xc0,0xc0,0xc0,0x63,0x7f,0x3e, +}; + +static const BitmapCharRec ch231 = {8,14,-1,4,10,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x75,0xe0,0xef,0xf8,0xc7,0x18,0xc6,0x0,0xe6,0x0,0x7f,0xf8,0xe,0x18,0xc6,0x18, +0xef,0xf0,0x7d,0xe0, +}; + +static const BitmapCharRec ch230 = {13,10,-1,0,15,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x38,0x6c,0x6c,0x38, +}; + +static const BitmapCharRec ch229 = {7,14,-1,0,9,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x0,0x6c,0x6c, +}; + +static const BitmapCharRec ch228 = {7,13,-1,0,9,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x0,0x4c,0x5a,0x32, +}; + +static const BitmapCharRec ch227 = {7,14,-1,0,9,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x0,0x66,0x3c,0x18, +}; + +static const BitmapCharRec ch226 = {7,14,-1,0,9,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x0,0x30,0x18,0xc, +}; + +static const BitmapCharRec ch225 = {7,14,-1,0,9,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c,0x0,0x18,0x30,0x60, +}; + +static const BitmapCharRec ch224 = {7,14,-1,0,9,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0xdc,0xde,0xc6,0xc6,0xc6,0xc6,0xdc,0xdc,0xc6,0xc6,0xc6,0xc6,0x7c,0x38, +}; + +static const BitmapCharRec ch223 = {7,14,-1,0,9,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x80,0xc1,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc1,0xc0,0xff,0x80,0xff,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +}; + +static const BitmapCharRec ch222 = {10,14,-1,0,12,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0xf,0x0,0x19,0x80, +0x30,0xc0,0x30,0xc0,0x60,0x60,0x60,0x60,0xc0,0x30,0xc0,0x30,0x0,0x0,0x6,0x0, +0x3,0x0,0x1,0x80, +}; + +static const BitmapCharRec ch221 = {12,18,-1,0,14,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x1f,0x0,0x7f,0xc0,0x60,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0x0,0x0,0x19,0x80, +0x19,0x80, +}; + +static const BitmapCharRec ch220 = {11,17,-1,0,13,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x1f,0x0,0x7f,0xc0,0x60,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0x0,0x0,0x19,0x80, +0xf,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch219 = {11,18,-1,0,13,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x1f,0x0,0x7f,0xc0,0x60,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0x0,0x0,0xc,0x0, +0x6,0x0,0x3,0x0, +}; + +static const BitmapCharRec ch218 = {11,18,-1,0,13,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x1f,0x0,0x7f,0xc0,0x60,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0x0,0x0,0x6,0x0, +0xc,0x0,0x18,0x0, +}; + +static const BitmapCharRec ch217 = {11,18,-1,0,13,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0xc7,0xc0,0xff,0xf0,0x78,0x38,0x38,0x18,0x6c,0x1c,0x6e,0xc,0x67,0xc,0x63,0x8c, +0x61,0xcc,0x70,0xdc,0x30,0x78,0x38,0x38,0x1f,0xfc,0x7,0xcc, +}; + +static const BitmapCharRec ch216 = {14,14,0,0,15,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0xc0,0xc0,0x61,0x80,0x33,0x0,0x1e,0x0,0xc,0x0,0x1e,0x0,0x33,0x0,0x61,0x80, +0xc0,0xc0, +}; + +static const BitmapCharRec ch215 = {10,9,0,0,10,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80,0x0,0x0,0xd,0x80, +0xd,0x80, +}; + +static const BitmapCharRec ch214 = {13,17,-1,0,15,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80,0x0,0x0,0x9,0x80, +0xb,0x40,0x6,0x40, +}; + +static const BitmapCharRec ch213 = {13,18,-1,0,15,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80,0x0,0x0,0xc,0xc0, +0x7,0x80,0x3,0x0, +}; + +static const BitmapCharRec ch212 = {13,18,-1,0,15,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80,0x0,0x0,0x3,0x0, +0x1,0x80,0x0,0xc0, +}; + +static const BitmapCharRec ch211 = {13,18,-1,0,15,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80,0x0,0x0,0x3,0x0, +0x6,0x0,0xc,0x0, +}; + +static const BitmapCharRec ch210 = {13,18,-1,0,15,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0xc0,0x60,0xc0,0xe0,0xc1,0xe0,0xc1,0xe0,0xc3,0x60,0xc6,0x60,0xc6,0x60,0xcc,0x60, +0xcc,0x60,0xd8,0x60,0xd8,0x60,0xf0,0x60,0xe0,0x60,0xe0,0x60,0x0,0x0,0x13,0x0, +0x16,0x80,0xc,0x80, +}; + +static const BitmapCharRec ch209 = {11,18,-1,0,13,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0x7f,0x80,0x7f,0xc0,0x60,0xe0,0x60,0x60,0x60,0x30,0x60,0x30,0xfc,0x30,0xfc,0x30, +0x60,0x30,0x60,0x30,0x60,0x60,0x60,0xe0,0x7f,0xc0,0x7f,0x80, +}; + +static const BitmapCharRec ch208 = {12,14,0,0,13,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x0,0xcc, +0xcc, +}; + +static const BitmapCharRec ch207 = {6,17,0,0,6,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x0,0xcc, +0x78,0x30, +}; + +static const BitmapCharRec ch206 = {6,18,0,0,6,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0xc0, +0x60,0x30, +}; + +static const BitmapCharRec ch205 = {4,18,-2,0,6,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x0,0x30, +0x60,0xc0, +}; + +static const BitmapCharRec ch204 = {4,18,0,0,6,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xff,0x80,0xff,0x80,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80,0x0,0x0,0x33,0x0, +0x33,0x0, +}; + +static const BitmapCharRec ch203 = {9,17,-1,0,11,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xff,0x80,0xff,0x80,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80,0x0,0x0,0x33,0x0, +0x1e,0x0,0xc,0x0, +}; + +static const BitmapCharRec ch202 = {9,18,-1,0,11,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xff,0x80,0xff,0x80,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80,0x0,0x0,0xc,0x0, +0x6,0x0,0x3,0x0, +}; + +static const BitmapCharRec ch201 = {9,18,-1,0,11,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xff,0x80,0xff,0x80,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80,0x0,0x0,0xc,0x0, +0x18,0x0,0x30,0x0, +}; + +static const BitmapCharRec ch200 = {9,18,-1,0,11,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x1e,0x0,0x1b,0x0,0x3,0x0,0xe,0x0,0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30, +0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xe0,0x0,0x60,0x30,0x70,0x70, +0x3f,0xe0,0xf,0x80, +}; + +static const BitmapCharRec ch199 = {12,18,-1,4,14,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0xc1,0xff,0xc1,0xff,0x61,0x80,0x61,0x80,0x7f,0x80,0x3f,0x80,0x31,0xfe,0x31,0xfe, +0x19,0x80,0x19,0x80,0xd,0x80,0xd,0x80,0x7,0xff,0x7,0xff, +}; + +static const BitmapCharRec ch198 = {16,14,-1,0,18,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0xf,0x0,0x19,0x80, +0x19,0x80,0xf,0x0, +}; + +static const BitmapCharRec ch197 = {12,18,0,0,12,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x19,0x80, +0x19,0x80, +}; + +static const BitmapCharRec ch196 = {12,17,0,0,12,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x13,0x0, +0x16,0x80,0xc,0x80, +}; + +static const BitmapCharRec ch195 = {12,18,0,0,12,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x19,0x80, +0xf,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch194 = {12,18,0,0,12,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x6,0x0, +0x3,0x0,0x1,0x80, +}; + +static const BitmapCharRec ch193 = {12,18,0,0,12,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x6,0x0, +0xc,0x0,0x18,0x0, +}; + +static const BitmapCharRec ch192 = {12,18,0,0,12,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x7c,0xfe,0xc6,0xc6,0xe0,0x70,0x38,0x18,0x18,0x18,0x0,0x0,0x18,0x18, +}; + +static const BitmapCharRec ch191 = {7,14,-1,4,10,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x18,0x18,0x18,0x18,0xc,0xfc,0x6,0xd8,0x6,0x78,0x73,0x38,0xf9,0x18,0x99,0x88, +0x30,0xc0,0x30,0xc0,0x98,0x60,0xf8,0x30,0x70,0x30, +}; + +static const BitmapCharRec ch190 = {14,13,0,0,15,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x30,0xf8,0x30,0xf8,0x18,0x60,0xc,0x30,0xc,0x18,0x66,0x98,0x62,0xf8,0x63,0x70, +0x61,0x80,0x61,0x80,0xe0,0xc0,0xe0,0x60,0x60,0x60, +}; + +static const BitmapCharRec ch189 = {13,13,-1,0,15,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x30,0x30,0x30,0x30,0x19,0xf8,0xd,0xb0,0xc,0xf0,0x66,0x70,0x62,0x30,0x63,0x10, +0x61,0x80,0x61,0x80,0xe0,0xc0,0xe0,0x60,0x60,0x60, +}; + +static const BitmapCharRec ch188 = {13,13,-1,0,15,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0x90,0xd8,0x6c,0x36,0x36,0x6c,0xd8,0x90, +}; + +static const BitmapCharRec ch187 = {7,8,-1,-1,9,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xf8,0x0,0x70,0xd8,0x88,0x88,0xd8,0x70, +}; + +static const BitmapCharRec ch186 = {5,8,-1,-6,7,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0x60,0x60,0x60,0x60,0x60,0xe0,0xe0,0x60, +}; + +static const BitmapCharRec ch185 = {3,8,-1,-5,6,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0xf0,0xd8,0x18,0x70,0x60, +}; + +static const BitmapCharRec ch184 = {5,5,0,4,5,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch183 = {2,2,-1,-4,4,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x32,0x72,0xf2,0xf2,0xf2,0xf2, +0x72,0x3f, +}; + +static const BitmapCharRec ch182 = {8,18,-1,4,10,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0xc0,0xc0,0xc0,0xc0,0xdb,0xff,0xe7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3, +}; + +static const BitmapCharRec ch181 = {8,14,-1,4,10,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0xc0,0x60,0x30, +}; + +static const BitmapCharRec ch180 = {4,3,0,-11,4,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0x70,0xf8,0x98,0x30,0x30,0x98,0xf8,0x70, +}; + +static const BitmapCharRec ch179 = {5,8,0,-5,6,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xf8,0xf8,0x60,0x30,0x18,0x98,0xf8,0x70, +}; + +static const BitmapCharRec ch178 = {5,8,0,-5,6,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xff,0xff,0x0,0x18,0x18,0x18,0xff,0xff,0x18,0x18,0x18, +}; + +static const BitmapCharRec ch177 = {8,11,-1,0,10,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x70,0xd8,0x88,0xd8,0x70, +}; + +static const BitmapCharRec ch176 = {5,5,-1,-8,7,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xf8, +}; + +static const BitmapCharRec ch175 = {5,1,0,-12,5,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0xf,0x80,0x30,0x60,0x40,0x10,0x48,0x50,0x88,0x88,0x89,0x8,0x8f,0x88,0x88,0x48, +0x88,0x48,0x4f,0x90,0x40,0x10,0x30,0x60,0xf,0x80, +}; + +static const BitmapCharRec ch174 = {13,13,-1,0,14,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xf8,0xf8, +}; + +static const BitmapCharRec ch173 = {5,2,-1,-4,7,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x1,0x80,0x1,0x80,0x1,0x80,0xff,0x80,0xff,0x80, +}; + +static const BitmapCharRec ch172 = {9,5,-1,-3,11,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x12,0x36,0x6c,0xd8,0xd8,0x6c,0x36,0x12, +}; + +static const BitmapCharRec ch171 = {7,8,-1,-1,9,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xf8,0x0,0x68,0xd8,0x48,0x38,0xc8,0x70, +}; + +static const BitmapCharRec ch170 = {5,8,-1,-6,7,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0xf,0x80,0x30,0x60,0x40,0x10,0x47,0x10,0x88,0x88,0x90,0x8,0x90,0x8,0x90,0x8, +0x88,0x88,0x47,0x10,0x40,0x10,0x30,0x60,0xf,0x80, +}; + +static const BitmapCharRec ch169 = {13,13,-1,0,15,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xd8,0xd8, +}; + +static const BitmapCharRec ch168 = {5,2,0,-11,6,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x3c,0x7e,0xc3,0xc3,0x7,0xe,0x3e,0x73,0xe3,0xc3,0xc7,0x6e,0x7c,0xf0,0xc3,0xc3, +0x7e,0x3c, +}; + +static const BitmapCharRec ch167 = {8,18,-1,4,10,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0x0,0x0,0x0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0, +}; + +static const BitmapCharRec ch166 = {2,17,-1,3,4,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x3c,0x66,0x66,0x66,0xc3,0xc3, +}; + +static const BitmapCharRec ch165 = {8,13,-1,0,10,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0xc3,0xff,0x66,0x66,0x66,0xff,0xc3, +}; + +static const BitmapCharRec ch164 = {8,7,-1,-3,10,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xdf,0x0,0xff,0x80,0x60,0x80,0x30,0x0,0x18,0x0,0x18,0x0,0x7e,0x0,0x30,0x0, +0x60,0x0,0x61,0x80,0x61,0x80,0x3f,0x0,0x1e,0x0, +}; + +static const BitmapCharRec ch163 = {9,13,0,0,10,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x10,0x10,0x3e,0x7f,0x6b,0xc8,0xc8,0xc8,0xc8,0x6b,0x7f,0x3e,0x4,0x4, +}; + +static const BitmapCharRec ch162 = {8,14,-1,2,10,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x40,0x40,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch161 = {2,14,-2,4,6,ch161data}; + +/* char: 0xa0 */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,5,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,5,0}; +#endif + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0xcc,0x7e,0x33, +}; + +static const BitmapCharRec ch126 = {8,3,-1,-4,10,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0xc0,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0xc,0x18,0x30,0x30,0x30,0x30,0x30, +0x60,0xc0, +}; + +static const BitmapCharRec ch125 = {6,18,0,4,6,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0, +}; + +static const BitmapCharRec ch124 = {2,18,-1,4,4,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0xc,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0xc0,0x60,0x30,0x30,0x30,0x30,0x30, +0x18,0xc, +}; + +static const BitmapCharRec ch123 = {6,18,0,4,6,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xfe,0xfe,0xc0,0x60,0x30,0x18,0xc,0x6,0xfe,0xfe, +}; + +static const BitmapCharRec ch122 = {7,10,-1,0,9,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x70,0x70,0x18,0x18,0x18,0x18,0x3c,0x24,0x66,0x66,0x66,0xc3,0xc3,0xc3, +}; + +static const BitmapCharRec ch121 = {8,14,-1,4,10,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0xc3,0xe7,0x66,0x3c,0x18,0x18,0x3c,0x66,0xe7,0xc3, +}; + +static const BitmapCharRec ch120 = {8,10,-1,0,10,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x19,0x80,0x19,0x80,0x39,0xc0,0x29,0x40,0x69,0x60,0x66,0x60,0x66,0x60,0xc6,0x30, +0xc6,0x30,0xc6,0x30, +}; + +static const BitmapCharRec ch119 = {12,10,-1,0,14,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x18,0x18,0x3c,0x24,0x66,0x66,0x66,0xc3,0xc3,0xc3, +}; + +static const BitmapCharRec ch118 = {8,10,-1,0,10,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x73,0xfb,0xc7,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3, +}; + +static const BitmapCharRec ch117 = {8,10,-1,0,10,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x18,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0xfc,0xfc,0x30,0x30,0x30, +}; + +static const BitmapCharRec ch116 = {6,13,0,0,6,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0x78,0xfc,0xc6,0x6,0x3e,0xfc,0xc0,0xc6,0x7e,0x3c, +}; + +static const BitmapCharRec ch115 = {7,10,-1,0,9,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xe0,0xd8,0xd8, +}; + +static const BitmapCharRec ch114 = {5,10,-1,0,6,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x3d,0x80,0x7f,0x80,0x63,0x80,0xc1,0x80, +0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x80,0x7f,0x80,0x3d,0x80, +}; + +static const BitmapCharRec ch113 = {9,14,-1,4,11,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xde,0x0,0xff,0x0,0xe3,0x0,0xc1,0x80, +0xc1,0x80,0xc1,0x80,0xc1,0x80,0xe3,0x0,0xff,0x0,0xde,0x0, +}; + +static const BitmapCharRec ch112 = {9,14,-1,4,11,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x3e,0x0,0x7f,0x0,0x63,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x0, +0x7f,0x0,0x3e,0x0, +}; + +static const BitmapCharRec ch111 = {9,10,-1,0,11,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xe3,0xdf,0xce, +}; + +static const BitmapCharRec ch110 = {8,10,-1,0,10,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0xc6,0x30,0xc6,0x30,0xc6,0x30,0xc6,0x30,0xc6,0x30,0xc6,0x30,0xc6,0x30,0xe7,0x30, +0xde,0xf0,0xcc,0x60, +}; + +static const BitmapCharRec ch109 = {12,10,-1,0,14,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch108 = {2,14,-1,0,4,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0xc7,0xc6,0xce,0xcc,0xd8,0xf8,0xf0,0xd8,0xcc,0xc6,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch107 = {8,14,-1,0,9,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0xe0,0xf0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x0,0x0, +0x30,0x30, +}; + +static const BitmapCharRec ch106 = {4,18,1,4,4,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch105 = {2,14,-1,0,4,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xe3,0xdf,0xce,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch104 = {8,14,-1,0,10,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x1c,0x0,0x7f,0x0,0x63,0x0,0x1,0x80,0x3d,0x80,0x7f,0x80,0x63,0x80,0xc1,0x80, +0xc1,0x80,0xc1,0x80,0xc1,0x80,0x61,0x80,0x7f,0x80,0x3d,0x80, +}; + +static const BitmapCharRec ch103 = {9,14,-1,4,11,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xfc,0xfc,0x30,0x30,0x3c,0x1c, +}; + +static const BitmapCharRec ch102 = {6,14,0,0,6,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x3c,0x7f,0xe3,0xc0,0xc0,0xff,0xc3,0xc3,0x7e,0x3c, +}; + +static const BitmapCharRec ch101 = {8,10,-1,0,10,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x3d,0x80,0x7f,0x80,0x63,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x63,0x80, +0x7f,0x80,0x3d,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80, +}; + +static const BitmapCharRec ch100 = {9,14,-1,0,11,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x3e,0x7f,0x63,0xc0,0xc0,0xc0,0xc0,0x63,0x7f,0x3e, +}; + +static const BitmapCharRec ch99 = {8,10,-1,0,10,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xde,0x0,0xff,0x0,0xe3,0x0,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xe3,0x0, +0xff,0x0,0xde,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +}; + +static const BitmapCharRec ch98 = {9,14,-1,0,11,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x76,0xee,0xc6,0xc6,0xe6,0x7e,0xe,0xc6,0xee,0x7c, +}; + +static const BitmapCharRec ch97 = {7,10,-1,0,9,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0xc0,0xc0,0x80,0x80,0x40, +}; + +static const BitmapCharRec ch96 = {2,5,-1,-9,4,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xff,0xc0,0xff,0xc0, +}; + +static const BitmapCharRec ch95 = {10,2,0,4,10,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x82,0xc6,0x6c,0x38,0x10, +}; + +static const BitmapCharRec ch94 = {7,5,-1,-8,9,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xf0,0xf0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0xf0,0xf0, +}; + +static const BitmapCharRec ch93 = {4,18,0,4,5,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x18,0x18,0x10,0x10,0x30,0x30,0x20,0x20,0x60,0x60,0x40,0x40,0xc0,0xc0, +}; + +static const BitmapCharRec ch92 = {5,14,0,0,5,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xf0,0xf0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xf0,0xf0, +}; + +static const BitmapCharRec ch91 = {4,18,-1,4,5,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xff,0xc0,0xff,0xc0,0xc0,0x0,0x60,0x0,0x30,0x0,0x18,0x0,0x1c,0x0,0xc,0x0, +0x6,0x0,0x3,0x0,0x1,0x80,0x0,0xc0,0xff,0xc0,0xff,0xc0, +}; + +static const BitmapCharRec ch90 = {10,14,-1,0,12,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0xf,0x0,0x19,0x80, +0x30,0xc0,0x30,0xc0,0x60,0x60,0x60,0x60,0xc0,0x30,0xc0,0x30, +}; + +static const BitmapCharRec ch89 = {12,14,-1,0,14,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0xc0,0x60,0xe0,0xe0,0x60,0xc0,0x71,0xc0,0x31,0x80,0x1b,0x0,0xe,0x0,0xe,0x0, +0x1b,0x0,0x31,0x80,0x71,0xc0,0x60,0xc0,0xe0,0xe0,0xc0,0x60, +}; + +static const BitmapCharRec ch88 = {11,14,-1,0,13,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x18,0x18,0x18,0x18,0x1c,0x38,0x34,0x2c,0x36,0x6c,0x36,0x6c,0x66,0x66,0x66,0x66, +0x62,0x46,0x63,0xc6,0xc3,0xc3,0xc1,0x83,0xc1,0x83,0xc1,0x83, +}; + +static const BitmapCharRec ch87 = {16,14,-1,0,18,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x6,0x0,0xf,0x0,0xf,0x0,0x19,0x80,0x19,0x80,0x19,0x80,0x30,0xc0,0x30,0xc0, +0x30,0xc0,0x60,0x60,0x60,0x60,0x60,0x60,0xc0,0x30,0xc0,0x30, +}; + +static const BitmapCharRec ch86 = {12,14,-1,0,14,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x1f,0x0,0x7f,0xc0,0x60,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +}; + +static const BitmapCharRec ch85 = {11,14,-1,0,13,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0, +0xc,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0xff,0xc0,0xff,0xc0, +}; + +static const BitmapCharRec ch84 = {10,14,-1,0,12,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x3f,0x0,0x7f,0xc0,0xe0,0xe0,0xc0,0x60,0x0,0x60,0x0,0xe0,0x3,0xc0,0x1f,0x0, +0x7c,0x0,0xe0,0x0,0xc0,0x60,0xe0,0xe0,0x7f,0xc0,0x1f,0x0, +}; + +static const BitmapCharRec ch83 = {11,14,-1,0,13,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0x80,0xc1,0x80,0xff,0x0,0xff,0x80, +0xc1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0xff,0x80,0xff,0x0, +}; + +static const BitmapCharRec ch82 = {10,14,-1,0,12,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x0,0x30,0xf,0xb0,0x3f,0xe0,0x70,0xf0,0x61,0xb0,0xe1,0xb8,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80, +}; + +static const BitmapCharRec ch81 = {13,15,-1,1,15,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x80, +0xc1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0xff,0x80,0xff,0x0, +}; + +static const BitmapCharRec ch80 = {10,14,-1,0,12,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x38,0xc0,0x18,0xc0,0x18,0xc0,0x18, +0xc0,0x18,0xe0,0x38,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80, +}; + +static const BitmapCharRec ch79 = {13,14,-1,0,15,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0xc0,0x60,0xc0,0xe0,0xc1,0xe0,0xc1,0xe0,0xc3,0x60,0xc6,0x60,0xc6,0x60,0xcc,0x60, +0xcc,0x60,0xd8,0x60,0xf0,0x60,0xf0,0x60,0xe0,0x60,0xc0,0x60, +}; + +static const BitmapCharRec ch78 = {11,14,-1,0,13,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0xc3,0xc,0xc3,0xc,0xc7,0x8c,0xc4,0x8c,0xcc,0xcc,0xcc,0xcc,0xd8,0x6c,0xd8,0x6c, +0xf0,0x3c,0xf0,0x3c,0xe0,0x1c,0xe0,0x1c,0xc0,0xc,0xc0,0xc, +}; + +static const BitmapCharRec ch77 = {14,14,-1,0,16,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch76 = {8,14,-1,0,10,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0xc0,0x70,0xc0,0xe0,0xc1,0xc0,0xc3,0x80,0xc7,0x0,0xce,0x0,0xfc,0x0,0xf8,0x0, +0xdc,0x0,0xce,0x0,0xc7,0x0,0xc3,0x80,0xc1,0xc0,0xc0,0xe0, +}; + +static const BitmapCharRec ch75 = {12,14,-1,0,13,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x3c,0x7e,0xe7,0xc3,0xc3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3, +}; + +static const BitmapCharRec ch74 = {8,14,-1,0,10,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch73 = {2,14,-2,0,6,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xff,0xe0,0xff,0xe0, +0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +}; + +static const BitmapCharRec ch72 = {11,14,-1,0,13,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0xf,0xb0,0x3f,0xf0,0x70,0x70,0x60,0x30,0xe0,0x30,0xc1,0xf0,0xc1,0xf0,0xc0,0x0, +0xc0,0x0,0xe0,0x30,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80, +}; + +static const BitmapCharRec ch71 = {12,14,-1,0,14,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80, +}; + +static const BitmapCharRec ch70 = {9,14,-1,0,11,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xff,0x80,0xff,0x80,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x0,0xff,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80,0xff,0x80, +}; + +static const BitmapCharRec ch69 = {9,14,-1,0,11,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xff,0x0,0xff,0x80,0xc1,0xc0,0xc0,0xc0,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60, +0xc0,0x60,0xc0,0x60,0xc0,0xc0,0xc1,0xc0,0xff,0x80,0xff,0x0, +}; + +static const BitmapCharRec ch68 = {11,14,-1,0,13,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0xf,0x80,0x3f,0xe0,0x70,0x70,0x60,0x30,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +0xc0,0x0,0xe0,0x0,0x60,0x30,0x70,0x70,0x3f,0xe0,0xf,0x80, +}; + +static const BitmapCharRec ch67 = {12,14,-1,0,14,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xff,0x80,0xff,0xc0,0xc0,0xe0,0xc0,0x60,0xc0,0x60,0xc0,0xe0,0xff,0xc0,0xff,0x80, +0xc1,0x80,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0xff,0x80,0xff,0x0, +}; + +static const BitmapCharRec ch66 = {11,14,-1,0,13,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0xc0,0x30,0xc0,0x30,0x60,0x60,0x60,0x60,0x7f,0xe0,0x3f,0xc0,0x30,0xc0,0x30,0xc0, +0x19,0x80,0x19,0x80,0xf,0x0,0xf,0x0,0x6,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch65 = {12,14,0,0,12,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x7,0xe0,0x1f,0xf0,0x38,0x0,0x70,0x0,0x67,0x70,0xcf,0xf8,0xcc,0xcc,0xcc,0x66, +0xcc,0x66,0xcc,0x63,0xc6,0x33,0x67,0x73,0x63,0xb3,0x30,0x6,0x1c,0xe,0xf,0xfc, +0x3,0xf0, +}; + +static const BitmapCharRec ch64 = {16,17,-1,3,18,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x30,0x30,0x0,0x0,0x30,0x30,0x30,0x38,0x1c,0xe,0xc6,0xc6,0xfe,0x7c, +}; + +static const BitmapCharRec ch63 = {7,14,-1,0,10,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0xc0,0xf0,0x3c,0xe,0x3,0xe,0x3c,0xf0,0xc0, +}; + +static const BitmapCharRec ch62 = {8,9,-1,0,10,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xfe,0xfe,0x0,0x0,0xfe,0xfe, +}; + +static const BitmapCharRec ch61 = {7,6,-2,-2,11,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x3,0xf,0x3c,0x70,0xc0,0x70,0x3c,0xf,0x3, +}; + +static const BitmapCharRec ch60 = {8,9,-1,0,10,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x40,0x40,0xc0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch59 = {2,13,-1,3,5,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0xc0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch58 = {2,10,-1,0,5,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0x7c,0xfe,0xc6,0x3,0x3,0x3b,0x7f,0xc3,0xc3,0xc3,0xc7,0x7e,0x3c, +}; + +static const BitmapCharRec ch57 = {8,13,-1,0,10,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x3c,0x7e,0xe7,0xc3,0xc3,0x66,0x7e,0x66,0xc3,0xc3,0xe7,0x7e,0x3c, +}; + +static const BitmapCharRec ch56 = {8,13,-1,0,10,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x60,0x60,0x30,0x30,0x30,0x18,0x18,0xc,0xc,0x6,0x3,0xff,0xff, +}; + +static const BitmapCharRec ch55 = {8,13,-1,0,10,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x3c,0x7e,0xe3,0xc3,0xc3,0xc3,0xfe,0xdc,0xc0,0xc0,0x63,0x7f,0x3c, +}; + +static const BitmapCharRec ch54 = {8,13,-1,0,10,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x7c,0xfe,0xc7,0xc3,0x3,0x3,0xc7,0xfe,0xfc,0xc0,0xc0,0xfe,0xfe, +}; + +static const BitmapCharRec ch53 = {8,13,-1,0,10,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x3,0x0,0x3,0x0,0x3,0x0,0xff,0x80,0xff,0x80,0xc3,0x0,0x63,0x0,0x33,0x0, +0x33,0x0,0x1b,0x0,0xf,0x0,0x7,0x0,0x3,0x0, +}; + +static const BitmapCharRec ch52 = {9,13,-1,0,10,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x3c,0x7e,0xc7,0xc3,0x3,0x7,0x1e,0x1c,0x6,0xc3,0xc3,0x7e,0x3c, +}; + +static const BitmapCharRec ch51 = {8,13,-1,0,10,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xff,0xff,0xc0,0xe0,0x70,0x38,0x1c,0xe,0x7,0x3,0xc3,0xfe,0x3c, +}; + +static const BitmapCharRec ch50 = {8,13,-1,0,10,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0xf8,0x18, +}; + +static const BitmapCharRec ch49 = {5,13,-2,0,10,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x3c,0x7e,0x66,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x7e,0x3c, +}; + +static const BitmapCharRec ch48 = {8,13,-1,0,10,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0xc0,0xc0,0x40,0x40,0x60,0x60,0x20,0x20,0x30,0x30,0x10,0x10,0x18,0x18, +}; + +static const BitmapCharRec ch47 = {5,14,0,0,5,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch46 = {2,2,-1,0,5,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xff,0xff, +}; + +static const BitmapCharRec ch45 = {8,2,-1,-4,11,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x40,0x40,0xc0,0xc0, +}; + +static const BitmapCharRec ch44 = {2,5,-1,3,5,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x18,0x18,0x18,0x18,0xff,0xff,0x18,0x18,0x18,0x18, +}; + +static const BitmapCharRec ch43 = {8,10,-1,0,10,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0x88,0x70,0x70,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch42 = {5,6,-1,-8,7,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0xc0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0x60, +0xc0,0x80, +}; + +static const BitmapCharRec ch41 = {4,18,-1,4,6,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x10,0x30,0x60,0x60,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x60,0x60, +0x30,0x10, +}; + +static const BitmapCharRec ch40 = {4,18,-1,4,6,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x80,0x40,0x40,0xc0,0xc0, +}; + +static const BitmapCharRec ch39 = {2,5,-1,-9,4,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x3c,0x70,0x7e,0xe0,0xe7,0xc0,0xc3,0x80,0xc3,0xc0,0xc6,0xc0,0xee,0xc0,0x7c,0x0, +0x3c,0x0,0x66,0x0,0x66,0x0,0x7e,0x0,0x3c,0x0, +}; + +static const BitmapCharRec ch38 = {12,13,-1,0,13,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x18,0x78,0x18,0xfc,0xc,0xcc,0xc,0xcc,0x6,0xfc,0x6,0x78,0x3,0x0,0x7b,0x0, +0xfd,0x80,0xcd,0x80,0xcc,0xc0,0xfc,0xc0,0x78,0x60, +}; + +static const BitmapCharRec ch37 = {14,13,-1,0,16,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x8,0x0,0x8,0x0,0x3e,0x0,0x7f,0x0,0xeb,0x80,0xc9,0x80,0x9,0x80,0xf,0x0, +0x3e,0x0,0x78,0x0,0xe8,0x0,0xc8,0x0,0xcb,0x0,0x7f,0x0,0x3e,0x0,0x8,0x0, +}; + +static const BitmapCharRec ch36 = {9,16,-1,2,10,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x24,0x0,0x24,0x0,0x24,0x0,0xff,0x80,0xff,0x80,0x12,0x0,0x12,0x0,0x12,0x0, +0x7f,0xc0,0x7f,0xc0,0x9,0x0,0x9,0x0,0x9,0x0, +}; + +static const BitmapCharRec ch35 = {10,13,0,0,10,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0x90,0x90,0xd8,0xd8,0xd8, +}; + +static const BitmapCharRec ch34 = {5,5,0,-9,5,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0xc0,0xc0,0x0,0x0,0x80,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +}; + +static const BitmapCharRec ch33 = {2,14,-2,0,6,ch33data}; + +/* char: 0x20 ' ' */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,5,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,5,0}; +#endif + +static const BitmapCharRec * const chars[] = { +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmapHelvetica18 = { +"-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", +224, +32, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_init.c b/lib/glut-3.7.6/lib/glut/glut_init.c new file mode 100644 index 0000000000..f91b5c1ed3 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_init.c @@ -0,0 +1,370 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +#include +#include +#include + +#if !defined(_WIN32) +#include +#include +#endif + +/* SGI optimization introduced in IRIX 6.3 to avoid X server + round trips for interning common X atoms. */ +#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) +#include +#else +#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) +#endif + +#include "glutint.h" + +/* GLUT inter-file variables */ +/* *INDENT-OFF* */ +char *__glutProgramName = NULL; +int __glutArgc = 0; +char **__glutArgv = NULL; +char *__glutGeometry = NULL; +Display *__glutDisplay = NULL; +int __glutScreen; +Window __glutRoot; +int __glutScreenHeight; +int __glutScreenWidth; +GLboolean __glutIconic = GL_FALSE; +GLboolean __glutDebug = GL_FALSE; +unsigned int __glutDisplayMode = + GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH; +char *__glutDisplayString = NULL; +int __glutConnectionFD; +XSizeHints __glutSizeHints = {0}; +int __glutInitWidth = 300, __glutInitHeight = 300; +int __glutInitX = -1, __glutInitY = -1; +GLboolean __glutForceDirect = GL_FALSE, + __glutTryDirect = GL_TRUE; +Atom __glutWMDeleteWindow; +/* *INDENT-ON* */ + +#ifdef _WIN32 +void (__cdecl *__glutExitFunc)(int retval) = NULL; +#endif + +static Bool synchronize = False; + +#if defined(_WIN32) + +#ifdef __BORLANDC__ +#include /* For masking floating point exceptions. */ +#endif + +void +__glutOpenWin32Connection(char* display) +{ + static char *classname; + WNDCLASS wc; + HINSTANCE hInstance = GetModuleHandle(NULL); + + /* Make sure we register the window only once. */ + if(classname) + return; + +#ifdef __BORLANDC__ + /* Under certain conditions (e.g. while rendering solid surfaces with + lighting enabled) Microsoft OpenGL libraries cause some illegal + operations like floating point overflow or division by zero. The + default behaviour of Microsoft compilers is to mask (ignore) + floating point exceptions, while Borland compilers do not. The + following function of Borland RTL allows to mask exceptions. + Advice from Pier Giorgio Esposito (mc2172@mclink.it). */ + _control87(MCW_EM,MCW_EM); +#endif + + classname = "GLUT"; + + /* Clear (important!) and then fill in the window class structure. */ + memset(&wc, 0, sizeof(WNDCLASS)); + wc.style = CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)__glutWindowProc; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, "GLUT_ICON"); + wc.hCursor = LoadCursor(hInstance, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = classname; + + if(wc.hIcon == NULL) { + HINSTANCE hDLLInstance = LoadLibrary("glut32.dll"); + if (hDLLInstance == NULL) { + /* Fill in a default icon if one isn't specified as a resource. */ + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + } else { + wc.hIcon = LoadIcon(hDLLInstance, "GLUT_ICON"); + } + } + + if(!RegisterClass(&wc)) { + __glutFatalError("RegisterClass() failed:" + "Cannot register GLUT window class."); + } + + __glutScreenWidth = GetSystemMetrics(SM_CXSCREEN); + __glutScreenHeight = GetSystemMetrics(SM_CYSCREEN); + + /* Set the root window to NULL because windows creates a top-level + window when the parent is NULL. X creates a top-level window + when the parent is the root window. */ + __glutRoot = NULL; + + /* Set the display to 1 -- we shouldn't be using this anywhere + (except as an argument to X calls). */ + __glutDisplay = (Display*)1; + + /* There isn't any concept of multiple screens in Win32, therefore, + we don't need to keep track of the screen we're on... it's always + the same one. */ + __glutScreen = 0; +} +#else /* !_WIN32 */ +void +__glutOpenXConnection(char *display) +{ + int errorBase, eventBase; + + __glutDisplay = XOpenDisplay(display); + if (!__glutDisplay) + __glutFatalError("could not open display: %s", + XDisplayName(display)); + if (synchronize) + XSynchronize(__glutDisplay, True); + if (!glXQueryExtension(__glutDisplay, &errorBase, &eventBase)) + __glutFatalError( + "OpenGL GLX extension not supported by display: %s", + XDisplayName(display)); + __glutScreen = DefaultScreen(__glutDisplay); + __glutRoot = RootWindow(__glutDisplay, __glutScreen); + __glutScreenWidth = DisplayWidth(__glutDisplay, __glutScreen); + __glutScreenHeight = DisplayHeight(__glutDisplay, + __glutScreen); + __glutConnectionFD = ConnectionNumber(__glutDisplay); + __glutWMDeleteWindow = XSGIFastInternAtom(__glutDisplay, + "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False); +} +#endif /* _WIN32 */ + +void +__glutInitTime(struct timeval *beginning) +{ + static int beenhere = 0; + static struct timeval genesis; + + if (!beenhere) { + GETTIMEOFDAY(&genesis); + beenhere = 1; + } + *beginning = genesis; +} + +static void +removeArgs(int *argcp, char **argv, int numToRemove) +{ + int i, j; + + for (i = 0, j = numToRemove; argv[j]; i++, j++) { + argv[i] = argv[j]; + } + argv[i] = NULL; + *argcp -= numToRemove; +} + +void APIENTRY +glutInit(int *argcp, char **argv) +{ + char *display = NULL; + char *str, *geometry = NULL; + struct timeval unused; + int i; + + if (__glutDisplay) { + __glutWarning("glutInit being called a second time."); + return; + } + /* Determine temporary program name. */ + str = strrchr(argv[0], '/'); + if (str == NULL) { + __glutProgramName = argv[0]; + } else { + __glutProgramName = str + 1; + } + + /* Make private copy of command line arguments. */ + __glutArgc = *argcp; + __glutArgv = (char **) malloc(__glutArgc * sizeof(char *)); + if (!__glutArgv) + __glutFatalError("out of memory."); + for (i = 0; i < __glutArgc; i++) { + __glutArgv[i] = __glutStrdup(argv[i]); + if (!__glutArgv[i]) + __glutFatalError("out of memory."); + } + + /* determine permanent program name */ + str = strrchr(__glutArgv[0], '/'); + if (str == NULL) { + __glutProgramName = __glutArgv[0]; + } else { + __glutProgramName = str + 1; + } + + /* parse arguments for standard options */ + for (i = 1; i < __glutArgc; i++) { + if (!strcmp(__glutArgv[i], "-display")) { +#if defined(_WIN32) + __glutWarning("-display option not supported by Win32 GLUT."); +#endif + if (++i >= __glutArgc) { + __glutFatalError( + "follow -display option with X display name."); + } + display = __glutArgv[i]; + removeArgs(argcp, &argv[1], 2); + } else if (!strcmp(__glutArgv[i], "-geometry")) { + if (++i >= __glutArgc) { + __glutFatalError( + "follow -geometry option with geometry parameter."); + } + geometry = __glutArgv[i]; + removeArgs(argcp, &argv[1], 2); + } else if (!strcmp(__glutArgv[i], "-direct")) { +#if defined(_WIN32) + __glutWarning("-direct option not supported by Win32 GLUT."); +#endif + if (!__glutTryDirect) + __glutFatalError( + "cannot force both direct and indirect rendering."); + __glutForceDirect = GL_TRUE; + removeArgs(argcp, &argv[1], 1); + } else if (!strcmp(__glutArgv[i], "-indirect")) { +#if defined(_WIN32) + __glutWarning("-indirect option not supported by Win32 GLUT."); +#endif + if (__glutForceDirect) + __glutFatalError( + "cannot force both direct and indirect rendering."); + __glutTryDirect = GL_FALSE; + removeArgs(argcp, &argv[1], 1); + } else if (!strcmp(__glutArgv[i], "-iconic")) { + __glutIconic = GL_TRUE; + removeArgs(argcp, &argv[1], 1); + } else if (!strcmp(__glutArgv[i], "-gldebug")) { + __glutDebug = GL_TRUE; + removeArgs(argcp, &argv[1], 1); + } else if (!strcmp(__glutArgv[i], "-sync")) { +#if defined(_WIN32) + __glutWarning("-sync option not supported by Win32 GLUT."); +#endif + synchronize = GL_TRUE; + removeArgs(argcp, &argv[1], 1); + } else { + /* Once unknown option encountered, stop command line + processing. */ + break; + } + } +#if defined(_WIN32) + __glutOpenWin32Connection(display); +#else + __glutOpenXConnection(display); +#endif + if (geometry) { + int flags, x, y, width, height; + + /* Fix bogus "{width|height} may be used before set" + warning */ + width = 0; + height = 0; + + flags = XParseGeometry(geometry, &x, &y, + (unsigned int *) &width, (unsigned int *) &height); + if (WidthValue & flags) { + /* Careful because X does not allow zero or negative + width windows */ + if (width > 0) + __glutInitWidth = width; + } + if (HeightValue & flags) { + /* Careful because X does not allow zero or negative + height windows */ + if (height > 0) + __glutInitHeight = height; + } + glutInitWindowSize(__glutInitWidth, __glutInitHeight); + if (XValue & flags) { + if (XNegative & flags) + x = DisplayWidth(__glutDisplay, __glutScreen) + + x - __glutSizeHints.width; + /* Play safe: reject negative X locations */ + if (x >= 0) + __glutInitX = x; + } + if (YValue & flags) { + if (YNegative & flags) + y = DisplayHeight(__glutDisplay, __glutScreen) + + y - __glutSizeHints.height; + /* Play safe: reject negative Y locations */ + if (y >= 0) + __glutInitY = y; + } + glutInitWindowPosition(__glutInitX, __glutInitY); + } + __glutInitTime(&unused); +} + +#ifdef _WIN32 +void APIENTRY +__glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)) +{ + __glutExitFunc = exitfunc; + glutInit(argcp, argv); +} +#endif + +/* CENTRY */ +void APIENTRY +glutInitWindowPosition(int x, int y) +{ + __glutInitX = x; + __glutInitY = y; + if (x >= 0 && y >= 0) { + __glutSizeHints.x = x; + __glutSizeHints.y = y; + __glutSizeHints.flags |= USPosition; + } else { + __glutSizeHints.flags &= ~USPosition; + } +} + +void APIENTRY +glutInitWindowSize(int width, int height) +{ + __glutInitWidth = width; + __glutInitHeight = height; + if (width > 0 && height > 0) { + __glutSizeHints.width = width; + __glutSizeHints.height = height; + __glutSizeHints.flags |= USSize; + } else { + __glutSizeHints.flags &= ~USSize; + } +} + +void APIENTRY +glutInitDisplayMode(unsigned int mask) +{ + __glutDisplayMode = mask; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_input.c b/lib/glut-3.7.6/lib/glut/glut_input.c new file mode 100644 index 0000000000..5c62dfbf62 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_input.c @@ -0,0 +1,645 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 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 +#include +#include + +#if !defined(_WIN32) +#include +#if defined(__vms) +#include +#else +#include +#endif +#include +#else +#include +#include /* Win32 Multimedia API header. */ +#endif /* !_WIN32 */ + +#include "glutint.h" + +int __glutNumDials = 0; +int __glutNumSpaceballButtons = 0; +int __glutNumButtonBoxButtons = 0; +int __glutNumTabletButtons = 0; +int __glutNumMouseButtons = 3; /* Good guess. */ +XDevice *__glutTablet = NULL; +XDevice *__glutDials = NULL; +XDevice *__glutSpaceball = NULL; + +int __glutHasJoystick = 0; +int __glutNumJoystickButtons = 0; +int __glutNumJoystickAxes = 0; + +#if !defined(_WIN32) +typedef struct _Range { + int min; + int range; +} Range; + +#define NUM_SPACEBALL_AXIS 6 +#define NUM_TABLET_AXIS 2 +#define NUM_DIALS_AXIS 8 + +Range __glutSpaceballRange[NUM_SPACEBALL_AXIS]; +Range __glutTabletRange[NUM_TABLET_AXIS]; +int *__glutDialsResolution; + +/* Safely assumes 0 is an illegal event type for X Input + extension events. */ +int __glutDeviceMotionNotify = 0; +int __glutDeviceButtonPress = 0; +int __glutDeviceButtonPressGrab = 0; +int __glutDeviceButtonRelease = 0; +int __glutDeviceStateNotify = 0; + +static int +normalizeTabletPos(int axis, int rawValue) +{ + assert(rawValue >= __glutTabletRange[axis].min); + assert(rawValue <= __glutTabletRange[axis].min + + __glutTabletRange[axis].range); + /* Normalize rawValue to between 0 and 4000. */ + return ((rawValue - __glutTabletRange[axis].min) * 4000) / + __glutTabletRange[axis].range; +} + +static int +normalizeDialAngle(int axis, int rawValue) +{ + /* XXX Assumption made that the resolution of the device is + number of clicks for one complete dial revolution. This + is true for SGI's dial & button box. */ + return (rawValue * 360.0) / __glutDialsResolution[axis]; +} + +static int +normalizeSpaceballAngle(int axis, int rawValue) +{ + assert(rawValue >= __glutSpaceballRange[axis].min); + assert(rawValue <= __glutSpaceballRange[axis].min + + __glutSpaceballRange[axis].range); + /* Normalize rawValue to between -1800 and 1800. */ + return ((rawValue - __glutSpaceballRange[axis].min) * 3600) / + __glutSpaceballRange[axis].range - 1800; +} + +static int +normalizeSpaceballDelta(int axis, int rawValue) +{ + assert(rawValue >= __glutSpaceballRange[axis].min); + assert(rawValue <= __glutSpaceballRange[axis].min + + __glutSpaceballRange[axis].range); + /* Normalize rawValue to between -1000 and 1000. */ + return ((rawValue - __glutSpaceballRange[axis].min) * 2000) / + __glutSpaceballRange[axis].range - 1000; +} + +static void +queryTabletPos(GLUTwindow * window) +{ + XDeviceState *state; + XInputClass *any; + XValuatorState *v; + int i; + + state = XQueryDeviceState(__glutDisplay, __glutTablet); + any = state->data; + for (i = 0; i < state->num_classes; i++) { +#if defined(__cplusplus) || defined(c_plusplus) + switch (any->c_class) { +#else + switch (any->class) { +#endif + case ValuatorClass: + v = (XValuatorState *) any; + if (v->num_valuators < 2) + goto end; + if (window->tabletPos[0] == -1) + window->tabletPos[0] = normalizeTabletPos(0, v->valuators[0]); + if (window->tabletPos[1] == -1) + window->tabletPos[1] = normalizeTabletPos(1, v->valuators[1]); + } + any = (XInputClass *) ((char *) any + any->length); + } +end: + XFreeDeviceState(state); +} + +static void +tabletPosChange(GLUTwindow * window, int first, int count, int *data) +{ + int i, value, genEvent = 0; + + for (i = first; i < first + count; i++) { + switch (i) { + case 0: /* X axis */ + case 1: /* Y axis */ + value = normalizeTabletPos(i, data[i - first]); + if (value != window->tabletPos[i]) { + window->tabletPos[i] = value; + genEvent = 1; + } + break; + } + } + if (window->tabletPos[0] == -1 || window->tabletPos[1] == -1) + queryTabletPos(window); + if (genEvent) + window->tabletMotion(window->tabletPos[0], window->tabletPos[1]); +} +#endif /* !_WIN32 */ + +int +__glutProcessDeviceEvents(XEvent * event) +{ +#if !defined(_WIN32) + GLUTwindow *window; + + /* XXX Ugly code fan out. */ + + /* Can't use switch/case since X Input event types are + dynamic. */ + + if (__glutDeviceMotionNotify && event->type == __glutDeviceMotionNotify) { + XDeviceMotionEvent *devmot = (XDeviceMotionEvent *) event; + + window = __glutGetWindow(devmot->window); + if (window) { + if (__glutTablet + && devmot->deviceid == __glutTablet->device_id + && window->tabletMotion) { + tabletPosChange(window, devmot->first_axis, devmot->axes_count, + devmot->axis_data); + } else if (__glutDials + && devmot->deviceid == __glutDials->device_id + && window->dials) { + int i, first = devmot->first_axis, count = devmot->axes_count; + + for (i = first; i < first + count; i++) + window->dials(i + 1, + normalizeDialAngle(i, devmot->axis_data[i - first])); + } else if (__glutSpaceball + && devmot->deviceid == __glutSpaceball->device_id) { + /* XXX Assume that space ball motion events come in as + all the first 6 axes. Assume first 3 axes are XYZ + translations; second 3 axes are XYZ rotations. */ + if (devmot->first_axis == 0 && devmot->axes_count == 6) { + if (window->spaceMotion) + window->spaceMotion( + normalizeSpaceballDelta(0, devmot->axis_data[0]), + normalizeSpaceballDelta(1, devmot->axis_data[1]), + normalizeSpaceballDelta(2, devmot->axis_data[2])); + if (window->spaceRotate) + window->spaceRotate( + normalizeSpaceballAngle(3, devmot->axis_data[3]), + normalizeSpaceballAngle(4, devmot->axis_data[4]), + normalizeSpaceballAngle(5, devmot->axis_data[5])); + } + } + return 1; + } + } else if (__glutDeviceButtonPress + && event->type == __glutDeviceButtonPress) { + XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event; + + window = __glutGetWindow(devbtn->window); + if (window) { + if (__glutTablet + && devbtn->deviceid == __glutTablet->device_id + && window->tabletButton + && devbtn->first_axis == 0 + && devbtn->axes_count == 2) { + tabletPosChange(window, devbtn->first_axis, devbtn->axes_count, + devbtn->axis_data); + window->tabletButton(devbtn->button, GLUT_DOWN, + window->tabletPos[0], window->tabletPos[1]); + } else if (__glutDials + && devbtn->deviceid == __glutDials->device_id + && window->buttonBox) { + window->buttonBox(devbtn->button, GLUT_DOWN); + } else if (__glutSpaceball + && devbtn->deviceid == __glutSpaceball->device_id + && window->spaceButton) { + window->spaceButton(devbtn->button, GLUT_DOWN); + } + return 1; + } + } else if (__glutDeviceButtonRelease + && event->type == __glutDeviceButtonRelease) { + XDeviceButtonEvent *devbtn = (XDeviceButtonEvent *) event; + + window = __glutGetWindow(devbtn->window); + if (window) { + if (__glutTablet + && devbtn->deviceid == __glutTablet->device_id + && window->tabletButton + && devbtn->first_axis == 0 + && devbtn->axes_count == 2) { + tabletPosChange(window, devbtn->first_axis, devbtn->axes_count, + devbtn->axis_data); + window->tabletButton(devbtn->button, GLUT_UP, + window->tabletPos[0], window->tabletPos[1]); + } else if (__glutDials + && devbtn->deviceid == __glutDials->device_id + && window->buttonBox) { + window->buttonBox(devbtn->button, GLUT_UP); + } else if (__glutSpaceball + && devbtn->deviceid == __glutSpaceball->device_id + && window->spaceButton) { + window->spaceButton(devbtn->button, GLUT_UP); + } + return 1; + } + } +#else + { + JOYINFOEX info; + JOYCAPS joyCaps; + + if (joyGetPosEx(JOYSTICKID1,&info) != JOYERR_NOERROR) { + __glutHasJoystick = 1; + joyGetDevCaps(JOYSTICKID1, &joyCaps, sizeof(joyCaps)); + __glutNumJoystickButtons = joyCaps.wNumButtons; + __glutNumJoystickAxes = joyCaps.wNumAxes; + } else { + __glutHasJoystick = 0; + __glutNumJoystickButtons = 0; + __glutNumJoystickAxes = 0; + } +#if 0 + JOYINFOEX info; + int njoyId = 0; + int nConnected = 0; + MMRESULT result; + + /* Loop through all possible joystick IDs until we get the error + JOYERR_PARMS. Count the number of times we get JOYERR_NOERROR + indicating an installed joystick driver with a joystick currently + attached to the port. */ + while ((result = joyGetPosEx(njoyId++,&info)) != JOYERR_PARMS) { + if (result == JOYERR_NOERROR) { + ++nConnected; /* The count of connected joysticks. */ + } + } +#endif + } +#endif /* !_WIN32 */ + return 0; +} + +static GLUTeventParser eventParser = +{__glutProcessDeviceEvents, NULL}; + +static void +addDeviceEventParser(void) +{ + static Bool been_here = False; + + if (been_here) + return; + been_here = True; + __glutRegisterEventParser(&eventParser); +} + +static int +probeDevices(void) +{ + static Bool been_here = False; + static int support; +#if !defined(_WIN32) + XExtensionVersion *version; + XDeviceInfoPtr device_info, device; + XAnyClassPtr any; + XButtonInfoPtr b; + XValuatorInfoPtr v; + XAxisInfoPtr a; + int num_dev, btns, dials; + int i, j, k; +#endif /* !_WIN32 */ + + if (been_here) { + return support; + } + been_here = True; + +#if !defined(_WIN32) + version = XGetExtensionVersion(__glutDisplay, "XInputExtension"); + /* Ugh. XInput extension API forces annoying cast of a pointer + to a long so it can be compared with the NoSuchExtension + value (#defined to 1). */ + if (version == NULL || ((long) version) == NoSuchExtension) { + support = 0; + return support; + } + XFree(version); + device_info = XListInputDevices(__glutDisplay, &num_dev); + if (device_info) { + for (i = 0; i < num_dev; i++) { + /* XXX These are SGI names for these devices; + unfortunately, no good standard exists for standard + types of X input extension devices. */ + + device = &device_info[i]; + any = (XAnyClassPtr) device->inputclassinfo; + + if (!__glutSpaceball && !strcmp(device->name, "spaceball")) { + v = NULL; + b = NULL; + for (j = 0; j < device->num_classes; j++) { +#if defined(__cplusplus) || defined(c_plusplus) + switch (any->c_class) { +#else + switch (any->class) { +#endif + case ButtonClass: + b = (XButtonInfoPtr) any; + btns = b->num_buttons; + break; + case ValuatorClass: + v = (XValuatorInfoPtr) any; + /* Sanity check: at least 6 valuators? */ + if (v->num_axes < NUM_SPACEBALL_AXIS) + goto skip_device; + a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo)); + for (k = 0; k < NUM_SPACEBALL_AXIS; k++, a++) { + __glutSpaceballRange[k].min = a->min_value; + __glutSpaceballRange[k].range = a->max_value - a->min_value; + } + break; + } + any = (XAnyClassPtr) ((char *) any + any->length); + } + if (v) { + __glutSpaceball = XOpenDevice(__glutDisplay, device->id); + if (__glutSpaceball) { + __glutNumSpaceballButtons = btns; + addDeviceEventParser(); + } + } + } else if (!__glutDials && !strcmp(device->name, "dial+buttons")) { + v = NULL; + b = NULL; + for (j = 0; j < device->num_classes; j++) { +#if defined(__cplusplus) || defined(c_plusplus) + switch (any->c_class) { +#else + switch (any->class) { +#endif + case ButtonClass: + b = (XButtonInfoPtr) any; + btns = b->num_buttons; + break; + case ValuatorClass: + v = (XValuatorInfoPtr) any; + /* Sanity check: at least 8 valuators? */ + if (v->num_axes < NUM_DIALS_AXIS) + goto skip_device; + dials = v->num_axes; + __glutDialsResolution = (int *) malloc(sizeof(int) * dials); + a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo)); + for (k = 0; k < dials; k++, a++) { + __glutDialsResolution[k] = a->resolution; + } + break; + } + any = (XAnyClassPtr) ((char *) any + any->length); + } + if (v) { + __glutDials = XOpenDevice(__glutDisplay, device->id); + if (__glutDials) { + __glutNumButtonBoxButtons = btns; + __glutNumDials = dials; + addDeviceEventParser(); + } + } + } else if (!__glutTablet && !strcmp(device->name, "tablet")) { + v = NULL; + b = NULL; + for (j = 0; j < device->num_classes; j++) { +#if defined(__cplusplus) || defined(c_plusplus) + switch (any->c_class) { +#else + switch (any->class) { +#endif + case ButtonClass: + b = (XButtonInfoPtr) any; + btns = b->num_buttons; + break; + case ValuatorClass: + v = (XValuatorInfoPtr) any; + /* Sanity check: exactly 2 valuators? */ + if (v->num_axes != NUM_TABLET_AXIS) + goto skip_device; + a = (XAxisInfoPtr) ((char *) v + sizeof(XValuatorInfo)); + for (k = 0; k < NUM_TABLET_AXIS; k++, a++) { + __glutTabletRange[k].min = a->min_value; + __glutTabletRange[k].range = a->max_value - a->min_value; + } + break; + } + any = (XAnyClassPtr) ((char *) any + any->length); + } + if (v) { + __glutTablet = XOpenDevice(__glutDisplay, device->id); + if (__glutTablet) { + __glutNumTabletButtons = btns; + addDeviceEventParser(); + } + } + } else if (!strcmp(device->name, "mouse")) { + for (j = 0; j < device->num_classes; j++) { +#if defined(__cplusplus) || defined(c_plusplus) + if (any->c_class == ButtonClass) { +#else + if (any->class == ButtonClass) { +#endif + b = (XButtonInfoPtr) any; + __glutNumMouseButtons = b->num_buttons; + } + any = (XAnyClassPtr) ((char *) any + any->length); + } + } + skip_device:; + } + XFreeDeviceList(device_info); + } +#else /* _WIN32 */ + __glutNumMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); +#endif /* !_WIN32 */ + /* X Input extension might be supported, but only if there is + a tablet, dials, or spaceball do we claim devices are + supported. */ + support = __glutTablet || __glutDials || __glutSpaceball; + return support; +} + +void +__glutUpdateInputDeviceMask(GLUTwindow * window) +{ +#if !defined(_WIN32) + /* 5 (dial and buttons) + 5 (tablet locator and buttons) + 5 + (Spaceball buttons and axis) = 15 */ + XEventClass eventList[15]; + int rc, numEvents; + + rc = probeDevices(); + if (rc) { + numEvents = 0; + if (__glutTablet) { + if (window->tabletMotion) { + DeviceMotionNotify(__glutTablet, __glutDeviceMotionNotify, + eventList[numEvents]); + numEvents++; + } + if (window->tabletButton) { + DeviceButtonPress(__glutTablet, __glutDeviceButtonPress, + eventList[numEvents]); + numEvents++; + DeviceButtonPressGrab(__glutTablet, __glutDeviceButtonPressGrab, + eventList[numEvents]); + numEvents++; + DeviceButtonRelease(__glutTablet, __glutDeviceButtonRelease, + eventList[numEvents]); + numEvents++; + } + if (window->tabletMotion || window->tabletButton) { + DeviceStateNotify(__glutTablet, __glutDeviceStateNotify, + eventList[numEvents]); + numEvents++; + } + } + if (__glutDials) { + if (window->dials) { + DeviceMotionNotify(__glutDials, __glutDeviceMotionNotify, + eventList[numEvents]); + numEvents++; + } + if (window->buttonBox) { + DeviceButtonPress(__glutDials, __glutDeviceButtonPress, + eventList[numEvents]); + numEvents++; + DeviceButtonPressGrab(__glutDials, __glutDeviceButtonPressGrab, + eventList[numEvents]); + numEvents++; + DeviceButtonRelease(__glutDials, __glutDeviceButtonRelease, + eventList[numEvents]); + numEvents++; + } + if (window->dials || window->buttonBox) { + DeviceStateNotify(__glutDials, __glutDeviceStateNotify, + eventList[numEvents]); + numEvents++; + } + } + if (__glutSpaceball) { + if (window->spaceMotion || window->spaceRotate) { + DeviceMotionNotify(__glutSpaceball, __glutDeviceMotionNotify, + eventList[numEvents]); + numEvents++; + } + if (window->spaceButton) { + DeviceButtonPress(__glutSpaceball, __glutDeviceButtonPress, + eventList[numEvents]); + numEvents++; + DeviceButtonPressGrab(__glutSpaceball, __glutDeviceButtonPressGrab, + eventList[numEvents]); + numEvents++; + DeviceButtonRelease(__glutSpaceball, __glutDeviceButtonRelease, + eventList[numEvents]); + numEvents++; + } + if (window->spaceMotion || window->spaceRotate || window->spaceButton) { + DeviceStateNotify(__glutSpaceball, __glutDeviceStateNotify, + eventList[numEvents]); + numEvents++; + } + } +#if 0 + if (window->children) { + GLUTwindow *child = window->children; + + do { + XChangeDeviceDontPropagateList(__glutDisplay, child->win, + numEvents, eventList, AddToList); + child = child->siblings; + } while (child); + } +#endif + XSelectExtensionEvent(__glutDisplay, window->win, + eventList, numEvents); + if (window->overlay) { + XSelectExtensionEvent(__glutDisplay, window->overlay->win, + eventList, numEvents); + } + } else { + /* X Input extension not supported; no chance for exotic + input devices. */ + } +#endif /* !_WIN32 */ +} + +/* CENTRY */ +int APIENTRY +glutDeviceGet(GLenum param) +{ + probeDevices(); + switch (param) { + case GLUT_HAS_KEYBOARD: + case GLUT_HAS_MOUSE: + /* Assume window system always has mouse and keyboard. */ + return 1; + case GLUT_HAS_SPACEBALL: + return __glutSpaceball != NULL; + case GLUT_HAS_DIAL_AND_BUTTON_BOX: + return __glutDials != NULL; + case GLUT_HAS_TABLET: + return __glutTablet != NULL; + case GLUT_NUM_MOUSE_BUTTONS: + return __glutNumMouseButtons; + case GLUT_NUM_SPACEBALL_BUTTONS: + return __glutNumSpaceballButtons; + case GLUT_NUM_BUTTON_BOX_BUTTONS: + return __glutNumButtonBoxButtons; + case GLUT_NUM_DIALS: + return __glutNumDials; + case GLUT_NUM_TABLET_BUTTONS: + return __glutNumTabletButtons; + case GLUT_DEVICE_IGNORE_KEY_REPEAT: + return __glutCurrentWindow->ignoreKeyRepeat; +#ifndef _WIN32 + case GLUT_DEVICE_KEY_REPEAT: + { + XKeyboardState state; + + XGetKeyboardControl(__glutDisplay, &state); + return state.global_auto_repeat; + } + case GLUT_JOYSTICK_POLL_RATE: + return 0; +#else + case GLUT_DEVICE_KEY_REPEAT: + /* Win32 cannot globally disable key repeat. */ + return GLUT_KEY_REPEAT_ON; + case GLUT_JOYSTICK_POLL_RATE: + return __glutCurrentWindow->joyPollInterval; +#endif + case GLUT_HAS_JOYSTICK: + return __glutHasJoystick; + case GLUT_JOYSTICK_BUTTONS: + return __glutNumJoystickButtons; + case GLUT_JOYSTICK_AXES: + return __glutNumJoystickAxes; + default: + __glutWarning("invalid glutDeviceGet parameter: %d", param); + return -1; + } +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_joy.c b/lib/glut-3.7.6/lib/glut/glut_joy.c new file mode 100644 index 0000000000..1d67df0594 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_joy.c @@ -0,0 +1,80 @@ + +/* Copyright (c) Mark J. Kilgard, 1997, 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. */ + +#ifdef _WIN32 +#include +#include /* Win32 Multimedia API header. */ +#endif + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutJoystickFunc(GLUTjoystickCB joystickFunc, int pollInterval) +{ +#ifdef _WIN32 + if (joystickFunc && (pollInterval > 0)) { + if (__glutCurrentWindow->entryState == WM_SETFOCUS) { + MMRESULT result; + + /* Capture joystick focus if current window has + focus now. */ + result = joySetCapture(__glutCurrentWindow->win, + JOYSTICKID1, 0, TRUE); + if (result == JOYERR_NOERROR) { + (void) joySetThreshold(JOYSTICKID1, pollInterval); + } + } + __glutCurrentWindow->joyPollInterval = pollInterval; + } else { + /* Release joystick focus if current window has + focus now. */ + if (__glutCurrentWindow->joystick + && (__glutCurrentWindow->joyPollInterval > 0) + && (__glutCurrentWindow->entryState == WM_SETFOCUS)) { + (void) joyReleaseCapture(JOYSTICKID1); + } + __glutCurrentWindow->joyPollInterval = 0; + } + __glutCurrentWindow->joystick = joystickFunc; +#else + /* XXX No support currently for X11 joysticks. */ +#endif +} + +void APIENTRY +glutForceJoystickFunc(void) +{ +#ifdef _WIN32 + if (__glutCurrentWindow->joystick) { + JOYINFOEX jix; + MMRESULT res; + int x, y, z; + + /* Poll the joystick. */ + jix.dwSize = sizeof(jix); + jix.dwFlags = JOY_RETURNALL; + res = joyGetPosEx(JOYSTICKID1,&jix); + if (res == JOYERR_NOERROR) { + + /* Convert to int for scaling. */ + x = jix.dwXpos; + y = jix.dwYpos; + z = jix.dwZpos; + +#define SCALE(v) ((int) ((v - 32767)/32.768)) + + __glutCurrentWindow->joystick(jix.dwButtons, + SCALE(x), SCALE(y), SCALE(z)); + } + } +#else + /* XXX No support currently for X11 joysticks. */ +#endif +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_key.c b/lib/glut-3.7.6/lib/glut/glut_key.c new file mode 100644 index 0000000000..b608e3825e --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_key.c @@ -0,0 +1,29 @@ + +/* 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. */ + +#include + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutKeyboardFunc(GLUTkeyboardCB keyboardFunc) +{ + __glutChangeWindowEventMask(KeyPressMask, + keyboardFunc != NULL || __glutCurrentWindow->special != NULL); + __glutCurrentWindow->keyboard = keyboardFunc; +} + +void APIENTRY +glutSpecialFunc(GLUTspecialCB specialFunc) +{ + __glutChangeWindowEventMask(KeyPressMask, + specialFunc != NULL || __glutCurrentWindow->keyboard != NULL); + __glutCurrentWindow->special = specialFunc; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_keyctrl.c b/lib/glut-3.7.6/lib/glut/glut_keyctrl.c new file mode 100644 index 0000000000..af61b78c75 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_keyctrl.c @@ -0,0 +1,29 @@ + +/* Copyright (c) Mark J. Kilgard, 1996, 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. */ + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutIgnoreKeyRepeat(int ignore) +{ + __glutCurrentWindow->ignoreKeyRepeat = ignore; +} + +void APIENTRY +glutSetKeyRepeat(int repeatMode) +{ +#if !defined(_WIN32) + XKeyboardControl values; + + /* GLUT's repeatMode #define's match the Xlib API values. */ + values.auto_repeat_mode = repeatMode; + XChangeKeyboardControl(__glutDisplay, KBAutoRepeatMode, &values); +#endif +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_keyup.c b/lib/glut-3.7.6/lib/glut/glut_keyup.c new file mode 100644 index 0000000000..c081a26f92 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_keyup.c @@ -0,0 +1,29 @@ + +/* 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. */ + +#include + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutKeyboardUpFunc(GLUTkeyboardCB keyboardUpFunc) +{ + __glutChangeWindowEventMask(KeyReleaseMask, + keyboardUpFunc != NULL || __glutCurrentWindow->specialUp != NULL); + __glutCurrentWindow->keyboardUp = keyboardUpFunc; +} + +void APIENTRY +glutSpecialUpFunc(GLUTspecialCB specialUpFunc) +{ + __glutChangeWindowEventMask(KeyReleaseMask, + specialUpFunc != NULL || __glutCurrentWindow->keyboardUp != NULL); + __glutCurrentWindow->specialUp = specialUpFunc; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_menu.c b/lib/glut-3.7.6/lib/glut/glut_menu.c new file mode 100644 index 0000000000..5b5a65959d --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_menu.c @@ -0,0 +1,1010 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +/* The Win32 GLUT file win32_menu.c completely re-implements all + the menuing functionality implemented. This file is used only by + the X Window System version of GLUT. */ + +#include +#include +#include +#include +#include + +#include +#include +#include /* for XC_arrow */ + +#include "glutint.h" +#include "layerutil.h" + +void (CDECL *__glutMenuStatusFunc) (int, int, int); +GLUTmenuItem *__glutItemSelected; +GLUTmenu **__glutMenuList = NULL; + +static int menuListSize = 0; +static XFontStruct *menuFont = NULL; +static Cursor menuCursor; +static Colormap menuColormap; +static Visual *menuVisual; +static int menuDepth; +static int fontHeight; +static GC blackGC, grayGC, whiteGC; +static unsigned long menuBlack, menuWhite, menuGray; +static unsigned long useSaveUnders; + +/* A replacement for XAllocColor (originally by Brian Paul). + This function should never fail to allocate a color. When + XAllocColor fails, we return the nearest matching color. If + we have to allocate many colors this function isn't a great + solution; the XQueryColors() could be done just once. */ +static void +noFaultXAllocColor(Display * dpy, Colormap cmap, int cmapSize, + XColor * color) +{ + XColor *ctable, subColor; + int i, bestmatch; + double mindist; /* 3*2^16^2 exceeds 32-bit long int + precision. */ + + for (;;) { + /* First try just using XAllocColor. */ + if (XAllocColor(dpy, cmap, color)) { + return; + } + + /* Retrieve color table entries. */ + /* XXX alloca canidate. */ + ctable = (XColor *) malloc(cmapSize * sizeof(XColor)); + for (i = 0; i < cmapSize; i++) + ctable[i].pixel = i; + XQueryColors(dpy, cmap, ctable, cmapSize); + + /* Find best match. */ + bestmatch = -1; + mindist = 0.0; + for (i = 0; i < cmapSize; i++) { + double dr = (double) color->red - (double) ctable[i].red; + double dg = (double) color->green - (double) ctable[i].green; + double db = (double) color->blue - (double) ctable[i].blue; + double dist = dr * dr + dg * dg + db * db; + if (bestmatch < 0 || dist < mindist) { + bestmatch = i; + mindist = dist; + } + } + + /* Return result. */ + subColor.red = ctable[bestmatch].red; + subColor.green = ctable[bestmatch].green; + subColor.blue = ctable[bestmatch].blue; + free(ctable); + if (XAllocColor(dpy, cmap, &subColor)) { + *color = subColor; + return; + } + /* Extremely unlikely, but possibly color was deallocated + and reallocated by someone else before we could + XAllocColor the color cell we located. If so, loop + again... */ + } +} + +static int +ifSunCreator(void) +{ + char *xvendor, *glvendor, *renderer; + int isSunCreator = 0; /* Until proven that it is. */ + int savedDisplayMode; + char *savedDisplayString; + GLUTwindow *window; + +#define VENDOR_SUN "Sun Microsystems" +#define RENDERER_CREATOR "Creator" + + /* Check the X vendor string first. It is easier to check + than the OpenGL vendor and renderer strings since it + doesn't require a valid OpenGL rendering context. Bail + early if not connected to a Sun. */ + xvendor = ServerVendor(__glutDisplay); + if (!strncmp(xvendor, VENDOR_SUN, sizeof(VENDOR_SUN) - 1)) { + + /* We need a valid current OpenGL rendering context to be + able to call glGetString successfully. If there is not + a current window, set up a temporary one just to call + glGetString with (gag, expensive). */ + if (__glutCurrentWindow) { + window = NULL; + } else { + savedDisplayMode = __glutDisplayMode; + savedDisplayString = __glutDisplayString; + __glutDisplayMode = GLUT_RGB | GLUT_SINGLE; + __glutDisplayString = NULL; + window = __glutCreateWindow(NULL, 0, 0, 1, 1, 0); + } + + glvendor = (char *) glGetString(GL_VENDOR); + if (!strncmp(glvendor, VENDOR_SUN, sizeof(VENDOR_SUN) - 1)) { + renderer = (char *) glGetString(GL_RENDERER); + if (!strncmp(renderer, RENDERER_CREATOR, sizeof(RENDERER_CREATOR) - 1)) { + isSunCreator = 1; + } + } + /* Destroy the temporary window for glGetString if one + needed to be created. */ + if (window) { + __glutDestroyWindow(window, window); + __glutDisplayMode = savedDisplayMode; + __glutDisplayString = savedDisplayString; + } + } + return isSunCreator; +} + +static void +menuVisualSetup(void) +{ + XLayerVisualInfo template, *visual, *overlayVisuals; + XColor color; + Status status; + Bool presumablyMesa; + int layer, nVisuals, i, dummy; + unsigned long *placeHolders = NULL; + int numPlaceHolders; + Bool allocateHigh; + + allocateHigh = ifSunCreator(); + + /* Start with the highest overlay layer and work down. I + don't think any hardware has more than 3 overlay layers. */ + for (layer = 3; layer > 0; layer--) { + template.layer = layer; + template.vinfo.screen = __glutScreen; + overlayVisuals = __glutXGetLayerVisualInfo(__glutDisplay, + VisualScreenMask | VisualLayerMask, &template, &nVisuals); + if (overlayVisuals) { + /* First, check if the default visual is in this layer. + If the default visual is in this layer, we try to use + it since it has pre-defined black and white pixels and + + using the default visual will probably minimize + colormap flashing problems. Suggested by Thomas Roell + (thomas@xig.com). */ + for (i = 0; i < nVisuals; i++) { + visual = &overlayVisuals[i]; + if (visual->vinfo.colormap_size >= 3) { + /* Compare visual IDs just to be safe. */ + if (visual->vinfo.visual->visualid == DefaultVisual(__glutDisplay, __glutScreen)->visualid) { + /* Settle for default visual. */ + menuVisual = DefaultVisual(__glutDisplay, __glutScreen); + menuDepth = DefaultDepth(__glutDisplay, __glutScreen); + menuColormap = DefaultColormap(__glutDisplay, __glutScreen); + menuBlack = BlackPixel(__glutDisplay, __glutScreen); + menuWhite = WhitePixel(__glutDisplay, __glutScreen); + color.red = color.green = color.blue = 0xaa00; + noFaultXAllocColor(__glutDisplay, menuColormap, + menuVisual->map_entries, &color); + menuGray = color.pixel; + useSaveUnders = 0; + XFree(overlayVisuals); + return; + } + } + } + for (i = 0; i < nVisuals; i++) { + visual = &overlayVisuals[i]; + if (visual->vinfo.colormap_size >= 3) { + if (allocateHigh) { + /* For Sun's Creator graphics, try to force the + read-only colors to the high end of the colormap + by first allocating read-write place-holder cells + for all but the last three cells. This helps + avoid colormap flashing problems. */ + numPlaceHolders = visual->vinfo.colormap_size - 3; + if (numPlaceHolders > 0) { + placeHolders = (unsigned long *) + malloc(numPlaceHolders * sizeof(unsigned long)); + /* A malloc failure would be harmless. */ + } + } + menuColormap = XCreateColormap(__glutDisplay, __glutRoot, + visual->vinfo.visual, AllocNone); + if (placeHolders) { + /* Again for Sun's Creator graphics, do the actual + read-write place-holder cell allocation. */ + status = XAllocColorCells(__glutDisplay, menuColormap, False, 0, 0, + placeHolders, numPlaceHolders); + if (!status) { + XFreeColormap(__glutDisplay, menuColormap); + free(placeHolders); + continue; + } + } + /* Allocate overlay colormap cells in defined order: + gray, black, white to match the IRIS GL allocation + scheme. Increases likelihood of less overlay + colormap flashing. */ + /* XXX Nice if these 3 AllocColor's could be done in + one protocol round-trip. */ + color.red = color.green = color.blue = 0xaa00; + status = XAllocColor(__glutDisplay, + menuColormap, &color); + if (!status) { + XFreeColormap(__glutDisplay, menuColormap); + if (placeHolders) { + free(placeHolders); + } + continue; + } + menuGray = color.pixel; + color.red = color.green = color.blue = 0x0000; + status = XAllocColor(__glutDisplay, + menuColormap, &color); + if (!status) { + XFreeColormap(__glutDisplay, menuColormap); + if (placeHolders) { + free(placeHolders); + } + continue; + } + menuBlack = color.pixel; + color.red = color.green = color.blue = 0xffff; + status = XAllocColor(__glutDisplay, + menuColormap, &color); + if (!status) { + XFreeColormap(__glutDisplay, menuColormap); + if (placeHolders) { + free(placeHolders); + } + continue; + } + if (placeHolders) { + /* Now free the placeholder cells. */ + XFreeColors(__glutDisplay, menuColormap, + placeHolders, numPlaceHolders, 0); + free(placeHolders); + } + menuWhite = color.pixel; + menuVisual = visual->vinfo.visual; + menuDepth = visual->vinfo.depth; + /* If using overlays, do not request "save unders". */ + useSaveUnders = 0; + XFree(overlayVisuals); + return; + } + } + XFree(overlayVisuals); + } + } + /* Settle for default visual. */ + menuVisual = DefaultVisual(__glutDisplay, __glutScreen); + menuDepth = DefaultDepth(__glutDisplay, __glutScreen); + menuColormap = DefaultColormap(__glutDisplay, __glutScreen); + menuBlack = BlackPixel(__glutDisplay, __glutScreen); + menuWhite = WhitePixel(__glutDisplay, __glutScreen); + color.red = color.green = color.blue = 0xaa00; + noFaultXAllocColor(__glutDisplay, menuColormap, + menuVisual->map_entries, &color); + menuGray = color.pixel; + + /* When no overlays are supported, we would like to use X + "save unders" to avoid exposes to windows obscured by + pop-up menus. However, OpenGL's direct rendering support + means OpenGL interacts poorly with X backing store and + save unders. X servers do not (in implementation + practice) redirect OpenGL rendering destined to obscured + window regions into backing store. + + Implementation solutions exist for this problem, but they + are expensive and high-end OpenGL implementations + typically provide fast rendering and/or overlays to + obviate the problem associated of user interfaces (pop-up + menus) forcing redraws of complex normal plane scenes. + (See support for overlays pop-up menus above.) + + Mesa 3D, however, does not support direct rendering. + Overlays are often unavailable to Mesa, and Mesa is also + relatively slow. For these reasons, Mesa-rendering GLUT + programs can and should use X save unders. + + Look for the GLX extension. If _not_ supported, we are + presumably using Mesa so enable save unders. */ + + presumablyMesa = !XQueryExtension(__glutDisplay, "GLX", + &dummy, &dummy, &dummy); + + if (presumablyMesa) { + useSaveUnders = CWSaveUnder; + } else { + useSaveUnders = 0; + } +} + +static void +menuSetup(void) +{ + if (menuFont) { + /* MenuFont overload to indicate menu initalization. */ + return; + } + menuFont = XLoadQueryFont(__glutDisplay, + "-*-helvetica-bold-o-normal--14-*-*-*-p-*-iso8859-1"); + if (!menuFont) { + /* Try back up font. */ + menuFont = XLoadQueryFont(__glutDisplay, "fixed"); + } + if (!menuFont) { + __glutFatalError("could not load font."); + } + menuVisualSetup(); + fontHeight = menuFont->ascent + menuFont->descent; + menuCursor = XCreateFontCursor(__glutDisplay, XC_arrow); +} + +static void +menuGraphicsContextSetup(Window win) +{ + XGCValues gcvals; + + if (blackGC != None) { + return; + } + gcvals.font = menuFont->fid; + gcvals.foreground = menuBlack; + blackGC = XCreateGC(__glutDisplay, win, + GCFont | GCForeground, &gcvals); + gcvals.foreground = menuGray; + grayGC = XCreateGC(__glutDisplay, win, GCForeground, &gcvals); + gcvals.foreground = menuWhite; + whiteGC = XCreateGC(__glutDisplay, win, GCForeground, &gcvals); +} + +void +__glutSetMenu(GLUTmenu * menu) +{ + __glutCurrentMenu = menu; +} + +static void +unmapMenu(GLUTmenu * menu) +{ + if (menu->cascade) { + unmapMenu(menu->cascade); + menu->cascade = NULL; + } + menu->anchor = NULL; + menu->highlighted = NULL; + XUnmapWindow(__glutDisplay, menu->win); +} + +static void +finishMenu(Window win, int x, int y) +{ + Window dummy; + int rc; + + unmapMenu(__glutMappedMenu); + XUngrabPointer(__glutDisplay, CurrentTime); + + /* Popping up an overlay popup menu will install its own + colormap. If the window associated with the menu has an + overlay, install that window's overlay colormap so the + overlay isn't left using the popup menu's colormap. */ + if (__glutMenuWindow->overlay) { + XInstallColormap(__glutDisplay, + __glutMenuWindow->overlay->colormap->cmap); + } + + /* This XFlush is needed to to make sure the pointer is + really ungrabbed when the application's menu callback is + called. Otherwise, a deadlock might happen because the + application may try to read from an terminal window, but + yet the ungrab hasn't really happened since it hasn't been + flushed out. */ + XFlush(__glutDisplay); + + if (__glutMenuStatusFunc) { + if (win != __glutMenuWindow->win) { + /* The button release may have occurred in a window other + than the window requesting the pop-up menu (for + example, one of the submenu windows). In this case, we + need to translate the coordinates into the coordinate + system of the window associated with the window. */ + rc = XTranslateCoordinates(__glutDisplay, win, __glutMenuWindow->win, + x, y, &x, &y, &dummy); + assert(rc != False); /* Will always be on same screen. */ + } + __glutSetWindow(__glutMenuWindow); + __glutSetMenu(__glutMappedMenu); + + /* Setting __glutMappedMenu to NULL permits operations that + change menus or destroy the menu window again. */ + __glutMappedMenu = NULL; + + __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y); + } + /* Setting __glutMappedMenu to NULL permits operations that + change menus or destroy the menu window again. */ + __glutMappedMenu = NULL; + + /* If an item is selected and it is not a submenu trigger, + generate menu callback. */ + if (__glutItemSelected && !__glutItemSelected->isTrigger) { + __glutSetWindow(__glutMenuWindow); + /* When menu callback is triggered, current menu should be + set to the callback menu. */ + __glutSetMenu(__glutItemSelected->menu); + __glutItemSelected->menu->select( + __glutItemSelected->value); + } + __glutMenuWindow = NULL; +} + +#define MENU_BORDER 1 +#define MENU_GAP 2 +#define MENU_ARROW_GAP 6 +#define MENU_ARROW_WIDTH 8 + +static void +mapMenu(GLUTmenu * menu, int x, int y) +{ + XWindowChanges changes; + unsigned int mask; + int subMenuExtension, num; + + /* If there are submenus, we need to provide extra space for + the submenu pull arrow. */ + if (menu->submenus > 0) { + subMenuExtension = MENU_ARROW_GAP + MENU_ARROW_WIDTH; + } else { + subMenuExtension = 0; + } + + changes.stack_mode = Above; + mask = CWStackMode | CWX | CWY; + /* If the menu isn't managed (ie, validated so all the + InputOnly subwindows are the right size), do so. */ + if (!menu->managed) { + GLUTmenuItem *item; + + item = menu->list; + num = menu->num; + while (item) { + XWindowChanges itemupdate; + + itemupdate.y = (num - 1) * fontHeight + MENU_GAP; + itemupdate.width = menu->pixwidth; + itemupdate.width += subMenuExtension; + XConfigureWindow(__glutDisplay, item->win, + CWWidth | CWY, &itemupdate); + item = item->next; + num--; + } + menu->pixheight = MENU_GAP + + fontHeight * menu->num + MENU_GAP; + changes.height = menu->pixheight; + changes.width = MENU_GAP + + menu->pixwidth + subMenuExtension + MENU_GAP; + mask |= CWWidth | CWHeight; + menu->managed = True; + } + /* Make sure menu appears fully on screen. */ + if (y + menu->pixheight >= __glutScreenHeight) { + changes.y = __glutScreenHeight - menu->pixheight; + } else { + changes.y = y; + } + if (x + menu->pixwidth + subMenuExtension >= + __glutScreenWidth) { + changes.x = __glutScreenWidth - + menu->pixwidth + subMenuExtension; + } else { + changes.x = x; + } + + /* Rember where the menu is placed so submenus can be + properly placed relative to it. */ + menu->x = changes.x; + menu->y = changes.y; + + XConfigureWindow(__glutDisplay, menu->win, mask, &changes); + XInstallColormap(__glutDisplay, menuColormap); + /* XXX The XRaiseWindow below should not be necessary because + the XConfigureWindow requests an Above stack mode (same as + XRaiseWindow), but some Sun users complained this was still + necessary. Probably some window manager or X server bug on + these machines?? */ + XRaiseWindow(__glutDisplay, menu->win); + XMapWindow(__glutDisplay, menu->win); +} + +static void +startMenu(GLUTmenu * menu, GLUTwindow * window, + int x, int y, int x_win, int y_win) +{ + int grab; + + assert(__glutMappedMenu == NULL); + grab = XGrabPointer(__glutDisplay, __glutRoot, True, + ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + __glutRoot, menuCursor, CurrentTime); + if (grab != GrabSuccess) { + /* Somebody else has pointer grabbed, ignore menu + activation. */ + return; + } + __glutMappedMenu = menu; + __glutMenuWindow = window; + __glutItemSelected = NULL; + if (__glutMenuStatusFunc) { + __glutSetMenu(menu); + __glutSetWindow(window); + __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win); + } + mapMenu(menu, x, y); +} + +static void +paintSubMenuArrow(Window win, int x, int y) +{ + XPoint p[5]; + + p[0].x = p[4].x = x; + p[0].y = p[4].y = y - menuFont->ascent + 1; + p[1].x = p[0].x + MENU_ARROW_WIDTH - 1; + p[1].y = p[0].y + (menuFont->ascent / 2) - 1; + p[2].x = p[1].x; + p[2].y = p[1].y + 1; + p[3].x = p[0].x; + p[3].y = p[0].y + menuFont->ascent - 2; + XFillPolygon(__glutDisplay, win, + whiteGC, p, 4, Convex, CoordModeOrigin); + XDrawLines(__glutDisplay, win, blackGC, p, 5, CoordModeOrigin); +} + +static void +paintMenuItem(GLUTmenuItem * item, int num) +{ + Window win = item->menu->win; + GC gc; + int y; + int subMenuExtension; + + if (item->menu->submenus > 0) { + subMenuExtension = MENU_ARROW_GAP + MENU_ARROW_WIDTH; + } else { + subMenuExtension = 0; + } + if (item->menu->highlighted == item) { + gc = whiteGC; + } else { + gc = grayGC; + } + y = MENU_GAP + fontHeight * num - menuFont->descent; + XFillRectangle(__glutDisplay, win, gc, + MENU_GAP, y - fontHeight + menuFont->descent, + item->menu->pixwidth + subMenuExtension, fontHeight); + XDrawString(__glutDisplay, win, blackGC, + MENU_GAP, y, item->label, item->len); + if (item->isTrigger) { + paintSubMenuArrow(win, + item->menu->pixwidth + MENU_ARROW_GAP + 1, y); + } +} + +static void +paintMenu(GLUTmenu * menu) +{ + GLUTmenuItem *item; + int i = menu->num; + int y = MENU_GAP + fontHeight * i - menuFont->descent; + + item = menu->list; + while (item) { + if (item->menu->highlighted == item) { + paintMenuItem(item, i); + } else { + /* Quick render of the menu item; assume background + already cleared to gray. */ + XDrawString(__glutDisplay, menu->win, blackGC, + 2, y, item->label, item->len); + if (item->isTrigger) { + paintSubMenuArrow(menu->win, + menu->pixwidth + MENU_ARROW_GAP + 1, y); + } + } + i--; + y -= fontHeight; + item = item->next; + } +} + +static GLUTmenuItem * +getMenuItem(GLUTmenu * menu, Window win, int *which) +{ + GLUTmenuItem *item; + int i; + + if (menu->searched) { + __glutFatalError("submenu infinite loop detected"); + } + menu->searched = True; + i = menu->num; + item = menu->list; + while (item) { + if (item->win == win) { + *which = i; + menu->searched = False; + return item; + } + if (item->isTrigger) { + GLUTmenuItem *subitem; + + subitem = __glutGetMenuItem(__glutMenuList[item->value], + win, which); + if (subitem) { + menu->searched = False; + return subitem; + } + } + i--; + item = item->next; + } + menu->searched = False; + return NULL; +} + +static int +getMenuItemIndex(GLUTmenuItem * item) +{ + int count = 0; + + while (item) { + count++; + item = item->next; + } + return count; +} + +static GLUTmenu * +getMenu(Window win) +{ + GLUTmenu *menu; + + menu = __glutMappedMenu; + while (menu) { + if (win == menu->win) { + return menu; + } + menu = menu->cascade; + } + return NULL; +} + +static GLUTmenu * +getMenuByNum(int menunum) +{ + if (menunum < 1 || menunum > menuListSize) { + return NULL; + } + return __glutMenuList[menunum - 1]; +} + +static int +getUnusedMenuSlot(void) +{ + int i; + + /* Look for allocated, unused slot. */ + for (i = 0; i < menuListSize; i++) { + if (!__glutMenuList[i]) { + return i; + } + } + /* Allocate a new slot. */ + menuListSize++; + if (__glutMenuList) { + __glutMenuList = (GLUTmenu **) + realloc(__glutMenuList, menuListSize * sizeof(GLUTmenu *)); + } else { + /* XXX Some realloc's do not correctly perform a malloc + when asked to perform a realloc on a NULL pointer, + though the ANSI C library spec requires this. */ + __glutMenuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *)); + } + if (!__glutMenuList) { + __glutFatalError("out of memory."); + } + __glutMenuList[menuListSize - 1] = NULL; + return menuListSize - 1; +} + +void +__glutMenuModificationError(void) +{ + /* XXX Remove the warning after GLUT 3.0. */ + __glutWarning("The following is a new check for GLUT 3.0; update your code."); + __glutFatalError("menu manipulation not allowed while menus in use."); +} + + +static void +menuItemEnterOrLeave(GLUTmenuItem * item, + int num, int type) +{ + int alreadyUp = 0; + + if (type == EnterNotify) { + GLUTmenuItem *prevItem = item->menu->highlighted; + + if (prevItem && prevItem != item) { + /* If there's an already higlighted item in this menu + that is different from this one (we could be + re-entering an item with an already cascaded + submenu!), unhighlight the previous item. */ + item->menu->highlighted = NULL; + paintMenuItem(prevItem, getMenuItemIndex(prevItem)); + } + item->menu->highlighted = item; + __glutItemSelected = item; + if (item->menu->cascade) { + if (!item->isTrigger) { + /* Entered a menu item that is not a submenu trigger, + so pop down the current submenu cascade of this + menu. */ + unmapMenu(item->menu->cascade); + item->menu->cascade = NULL; + } else { + GLUTmenu *submenu = __glutMenuList[item->value]; + + if (submenu->anchor == item) { + /* We entered the submenu trigger for the submenu + that is already up, so don't take down the + submenu. */ + alreadyUp = 1; + } else { + /* Submenu already popped up for some other submenu + item of this menu; need to pop down that other + submenu cascade. */ + unmapMenu(item->menu->cascade); + item->menu->cascade = NULL; + } + } + } + if (!alreadyUp) { + /* Make sure the menu item gets painted with + highlighting. */ + paintMenuItem(item, num); + } else { + /* If already up, should already be highlighted. */ + } + } else { + /* LeaveNotify: Handle leaving a menu item... */ + if (item->menu->cascade && + item->menu->cascade->anchor == item) { + /* If there is a submenu casacaded from this item, do not + change the highlighting on this item upon leaving. */ + } else { + /* Unhighlight this menu item. */ + item->menu->highlighted = NULL; + paintMenuItem(item, num); + } + __glutItemSelected = NULL; + } + if (item->isTrigger) { + if (type == EnterNotify && !alreadyUp) { + GLUTmenu *submenu = __glutMenuList[item->value]; + + mapMenu(submenu, + item->menu->x + item->menu->pixwidth + + MENU_ARROW_GAP + MENU_ARROW_WIDTH + + MENU_GAP + MENU_BORDER, + item->menu->y + fontHeight * (num - 1) + MENU_GAP); + item->menu->cascade = submenu; + submenu->anchor = item; + } + } +} + +/* Installs callback functions for use by glut_event.c The point + of this is so that GLUT's menu code only gets linked into + GLUT binaries (assuming a static library) if the GLUT menu + API is used. */ +static void +installMenuCallbacks(void) +{ + __glutMenuItemEnterOrLeave = menuItemEnterOrLeave; + __glutFinishMenu = finishMenu; + __glutPaintMenu = paintMenu; + __glutStartMenu = startMenu; + __glutGetMenuByNum = getMenuByNum; + __glutGetMenu = getMenu; + __glutGetMenuItem = getMenuItem; +} + +int APIENTRY +glutCreateMenu(GLUTselectCB selectFunc) +{ + XSetWindowAttributes wa; + GLUTmenu *menu; + int menuid; + + if (__glutMappedMenu) { + __glutMenuModificationError(); + } + if (!__glutDisplay) { + __glutOpenXConnection(NULL); + } + + installMenuCallbacks(); + + menuid = getUnusedMenuSlot(); + menu = (GLUTmenu *) malloc(sizeof(GLUTmenu)); + if (!menu) { + __glutFatalError("out of memory."); + } + menu->id = menuid; + menu->num = 0; + menu->submenus = 0; + menu->managed = False; + menu->searched = False; + menu->pixwidth = 0; + menu->select = selectFunc; + menu->list = NULL; + menu->cascade = NULL; + menu->highlighted = NULL; + menu->anchor = NULL; + menuSetup(); + wa.override_redirect = True; + wa.background_pixel = menuGray; + wa.border_pixel = menuBlack; + wa.colormap = menuColormap; + wa.event_mask = StructureNotifyMask | ExposureMask | + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask; + /* Save unders really only enabled if useSaveUnders is set to + CWSaveUnder, ie. using Mesa 3D. See earlier comments. */ + wa.save_under = True; + menu->win = XCreateWindow(__glutDisplay, __glutRoot, + /* Real position determined when mapped. */ + 0, 0, + /* Real size will be determined when menu is manged. */ + 1, 1, + MENU_BORDER, menuDepth, InputOutput, menuVisual, + CWOverrideRedirect | CWBackPixel | CWBorderPixel | + CWEventMask | CWColormap | useSaveUnders, + &wa); + menuGraphicsContextSetup(menu->win); + __glutMenuList[menuid] = menu; + __glutSetMenu(menu); + return menuid + 1; +} + +/* CENTRY */ +int APIENTRY +glutGetMenu(void) +{ + if (__glutCurrentMenu) { + return __glutCurrentMenu->id + 1; + } else { + return 0; + } +} + +void APIENTRY +glutSetMenu(int menuid) +{ + GLUTmenu *menu; + + if (menuid < 1 || menuid > menuListSize) { + __glutWarning("glutSetMenu attempted on bogus menu."); + return; + } + menu = __glutMenuList[menuid - 1]; + if (!menu) { + __glutWarning("glutSetMenu attempted on bogus menu."); + return; + } + __glutSetMenu(menu); +} +/* ENDCENTRY */ + +void +__glutSetMenuItem(GLUTmenuItem * item, const char *label, + int value, Bool isTrigger) +{ + GLUTmenu *menu; + + menu = item->menu; + item->label = __glutStrdup(label); + if (!item->label) { + __glutFatalError("out of memory."); + } + item->isTrigger = isTrigger; + item->len = (int) strlen(label); + item->value = value; + item->pixwidth = XTextWidth(menuFont, label, item->len) + 4; + if (item->pixwidth > menu->pixwidth) { + menu->pixwidth = item->pixwidth; + } + menu->managed = False; +} + +/* CENTRY */ +void APIENTRY +glutAddMenuEntry(const char *label, int value) +{ + XSetWindowAttributes wa; + GLUTmenuItem *entry; + + if (__glutMappedMenu) { + __glutMenuModificationError(); + } + entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem)); + if (!entry) { + __glutFatalError("out of memory."); + } + entry->menu = __glutCurrentMenu; + __glutSetMenuItem(entry, label, value, False); + wa.event_mask = EnterWindowMask | LeaveWindowMask; + entry->win = XCreateWindow(__glutDisplay, + __glutCurrentMenu->win, MENU_GAP, + __glutCurrentMenu->num * fontHeight + MENU_GAP, /* x & y */ + entry->pixwidth, fontHeight, /* width & height */ + 0, CopyFromParent, InputOnly, CopyFromParent, + CWEventMask, &wa); + XMapWindow(__glutDisplay, entry->win); + __glutCurrentMenu->num++; + entry->next = __glutCurrentMenu->list; + __glutCurrentMenu->list = entry; +} + +void APIENTRY +glutAddSubMenu(const char *label, int menu) +{ + XSetWindowAttributes wa; + GLUTmenuItem *submenu; + + if (__glutMappedMenu) { + __glutMenuModificationError(); + } + submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem)); + if (!submenu) { + __glutFatalError("out of memory."); + } + __glutCurrentMenu->submenus++; + submenu->menu = __glutCurrentMenu; + __glutSetMenuItem(submenu, label, /* base 0 */ menu - 1, True); + wa.event_mask = EnterWindowMask | LeaveWindowMask; + submenu->win = XCreateWindow(__glutDisplay, + __glutCurrentMenu->win, MENU_GAP, + __glutCurrentMenu->num * fontHeight + MENU_GAP, /* x & y */ + submenu->pixwidth, fontHeight, /* width & height */ + 0, CopyFromParent, InputOnly, CopyFromParent, + CWEventMask, &wa); + XMapWindow(__glutDisplay, submenu->win); + __glutCurrentMenu->num++; + submenu->next = __glutCurrentMenu->list; + __glutCurrentMenu->list = submenu; +} + +void APIENTRY +glutAttachMenu(int button) +{ + if (__glutMappedMenu) { + __glutMenuModificationError(); + } + installMenuCallbacks(); + if (__glutCurrentWindow->menu[button] < 1) { + __glutCurrentWindow->buttonUses++; + } + __glutChangeWindowEventMask( + ButtonPressMask | ButtonReleaseMask, True); + __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1; +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_menu2.c b/lib/glut-3.7.6/lib/glut/glut_menu2.c new file mode 100644 index 0000000000..3046f91f1b --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_menu2.c @@ -0,0 +1,185 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +/* glut_menu2.c implements the little used GLUT menu calls in + a distinct file from glut_menu.c for slim static linking. */ + +/* The Win32 GLUT file win32_menu.c completely re-implements all + the menuing functionality implemented. This file is used only by + the X Window System version of GLUT. */ + +#include +#include +#include +#include +#include + +#include + +#include "glutint.h" +#include "layerutil.h" + +/* CENTRY */ +/* DEPRICATED, use glutMenuStatusFunc instead. */ +void APIENTRY +glutMenuStateFunc(GLUTmenuStateCB menuStateFunc) +{ + __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc; +} + +void APIENTRY +glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc) +{ + __glutMenuStatusFunc = menuStatusFunc; +} + +void APIENTRY +glutDestroyMenu(int menunum) +{ + GLUTmenu *menu = __glutGetMenuByNum(menunum); + GLUTmenuItem *item, *next; + + if (__glutMappedMenu) + __glutMenuModificationError(); + assert(menu->id == menunum - 1); + XDestroySubwindows(__glutDisplay, menu->win); + XDestroyWindow(__glutDisplay, menu->win); + __glutMenuList[menunum - 1] = NULL; + /* free all menu entries */ + item = menu->list; + while (item) { + assert(item->menu == menu); + next = item->next; + free(item->label); + free(item); + item = next; + } + if (__glutCurrentMenu == menu) { + __glutCurrentMenu = NULL; + } + free(menu); +} + +void APIENTRY +glutChangeToMenuEntry(int num, const char *label, int value) +{ + GLUTmenuItem *item; + int i; + + if (__glutMappedMenu) + __glutMenuModificationError(); + i = __glutCurrentMenu->num; + item = __glutCurrentMenu->list; + while (item) { + if (i == num) { + if (item->isTrigger) { + /* If changing a submenu trigger to a menu entry, we + need to account for submenus. */ + item->menu->submenus--; + } + free(item->label); + __glutSetMenuItem(item, label, value, False); + return; + } + i--; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutChangeToSubMenu(int num, const char *label, int menu) +{ + GLUTmenuItem *item; + int i; + + if (__glutMappedMenu) + __glutMenuModificationError(); + i = __glutCurrentMenu->num; + item = __glutCurrentMenu->list; + while (item) { + if (i == num) { + if (!item->isTrigger) { + /* If changing a menu entry to as submenu trigger, we + need to account for submenus. */ + item->menu->submenus++; + } + free(item->label); + __glutSetMenuItem(item, label, /* base 0 */ menu - 1, True); + return; + } + i--; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutRemoveMenuItem(int num) +{ + GLUTmenuItem *item, **prev, *remaining; + int pixwidth, i; + + if (__glutMappedMenu) + __glutMenuModificationError(); + i = __glutCurrentMenu->num; + prev = &__glutCurrentMenu->list; + item = __glutCurrentMenu->list; + /* If menu item is removed, the menu's pixwidth may need to + be recomputed. */ + pixwidth = 1; + while (item) { + if (i == num) { + /* If this menu item's pixwidth is as wide as the menu's + pixwidth, removing this menu item will necessitate + shrinking the menu's pixwidth. */ + if (item->pixwidth >= __glutCurrentMenu->pixwidth) { + /* Continue recalculating menu pixwidth, first skipping + the removed item. */ + remaining = item->next; + while (remaining) { + if (remaining->pixwidth > pixwidth) { + pixwidth = remaining->pixwidth; + } + remaining = remaining->next; + } + __glutCurrentMenu->pixwidth = pixwidth; + } + __glutCurrentMenu->num--; + __glutCurrentMenu->managed = False; + + /* Patch up menu's item list. */ + *prev = item->next; + + free(item->label); + free(item); + return; + } + if (item->pixwidth > pixwidth) { + pixwidth = item->pixwidth; + } + i--; + prev = &item->next; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutDetachMenu(int button) +{ + if (__glutMappedMenu) + __glutMenuModificationError(); + if (__glutCurrentWindow->menu[button] > 0) { + __glutCurrentWindow->buttonUses--; + __glutChangeWindowEventMask(ButtonPressMask | ButtonReleaseMask, + __glutCurrentWindow->buttonUses > 0); + __glutCurrentWindow->menu[button] = 0; + } +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_mesa.c b/lib/glut-3.7.6/lib/glut/glut_mesa.c new file mode 100644 index 0000000000..73682a5067 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_mesa.c @@ -0,0 +1,57 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 +#include "glutint.h" + +int __glutMesaSwapHackSupport = 0; /* Not supported until + proven otherwise. */ + +/* Use the "Mesa swap hack" if reasonable if and only if + MESA_SWAP_HACK is set to something whose first character is + not "N" or "n" AND "Brian Paul" is the vendor string AND + "Mesa X11"* (or "Mesa" for backward compatibility) is the + renderer string. + + Anyone who modifies Mesa so that glXSwapBuffers does not + simply blit the previously rendered back buffer should + change either their vendor or renderer string to avoid + confusing GLUT. */ + +void +__glutDetermineMesaSwapHackSupport(void) +{ + static int doneAlready = 0; + char *env, *vendor, *renderer; + + if (doneAlready) + return; + env = getenv("MESA_SWAP_HACK"); + if (env) { + if ((env[0] != 'n') && (env[0] != 'N')) { + vendor = (char *) glGetString(GL_VENDOR); + renderer = (char *) glGetString(GL_RENDERER); + + /* Old versions of X11 Mesa uses the renderer string + "Mesa"; Brian plans to start using "Mesa X11" to + distinguish the X version of Mesa from other flavor + such as Windows or 3Dfx. */ + +#define MESA_X11 "Mesa X11" + + /* XXX At some point in the future, eliminate the + backward compatibility for the old "Mesa" renderer + string. */ + + if (!strcmp(vendor, "Brian Paul") && (!strcmp(renderer, "Mesa") || + !strncmp(renderer, MESA_X11, sizeof(MESA_X11) - 1))) + __glutMesaSwapHackSupport = 1; + } + } + doneAlready = 1; +} diff --git a/lib/glut-3.7.6/lib/glut/glut_modifier.c b/lib/glut-3.7.6/lib/glut/glut_modifier.c new file mode 100644 index 0000000000..deb9a04484 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_modifier.c @@ -0,0 +1,31 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" + +/* CENTRY */ +int APIENTRY +glutGetModifiers(void) +{ + int modifiers; + + if(__glutModifierMask == (unsigned int) ~0) { + __glutWarning( + "glutCurrentModifiers: do not call outside core input callback."); + return 0; + } + modifiers = 0; + if(__glutModifierMask & (ShiftMask|LockMask)) + modifiers |= GLUT_ACTIVE_SHIFT; + if(__glutModifierMask & ControlMask) + modifiers |= GLUT_ACTIVE_CTRL; + if(__glutModifierMask & Mod1Mask) + modifiers |= GLUT_ACTIVE_ALT; + return modifiers; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_mroman.c b/lib/glut-3.7.6/lib/glut/glut_mroman.c new file mode 100644 index 0000000000..de93a9c341 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_mroman.c @@ -0,0 +1,2451 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#include "glutstroke.h" + +/* char: 33 '!' */ + +static const CoordRec char33_stroke0[] = { + { 52.381, 100 }, + { 52.381, 33.3333 }, +}; + +static const CoordRec char33_stroke1[] = { + { 52.381, 9.5238 }, + { 47.6191, 4.7619 }, + { 52.381, 0 }, + { 57.1429, 4.7619 }, + { 52.381, 9.5238 }, +}; + +static const StrokeRec char33[] = { + { 2, char33_stroke0 }, + { 5, char33_stroke1 }, +}; + +/* char: 34 '"' */ + +static const CoordRec char34_stroke0[] = { + { 33.3334, 100 }, + { 33.3334, 66.6667 }, +}; + +static const CoordRec char34_stroke1[] = { + { 71.4286, 100 }, + { 71.4286, 66.6667 }, +}; + +static const StrokeRec char34[] = { + { 2, char34_stroke0 }, + { 2, char34_stroke1 }, +}; + +/* char: 35 '#' */ + +static const CoordRec char35_stroke0[] = { + { 54.7619, 119.048 }, + { 21.4286, -33.3333 }, +}; + +static const CoordRec char35_stroke1[] = { + { 83.3334, 119.048 }, + { 50, -33.3333 }, +}; + +static const CoordRec char35_stroke2[] = { + { 21.4286, 57.1429 }, + { 88.0952, 57.1429 }, +}; + +static const CoordRec char35_stroke3[] = { + { 16.6667, 28.5714 }, + { 83.3334, 28.5714 }, +}; + +static const StrokeRec char35[] = { + { 2, char35_stroke0 }, + { 2, char35_stroke1 }, + { 2, char35_stroke2 }, + { 2, char35_stroke3 }, +}; + +/* char: 36 '$' */ + +static const CoordRec char36_stroke0[] = { + { 42.8571, 119.048 }, + { 42.8571, -19.0476 }, +}; + +static const CoordRec char36_stroke1[] = { + { 61.9047, 119.048 }, + { 61.9047, -19.0476 }, +}; + +static const CoordRec char36_stroke2[] = { + { 85.7143, 85.7143 }, + { 76.1905, 95.2381 }, + { 61.9047, 100 }, + { 42.8571, 100 }, + { 28.5714, 95.2381 }, + { 19.0476, 85.7143 }, + { 19.0476, 76.1905 }, + { 23.8095, 66.6667 }, + { 28.5714, 61.9048 }, + { 38.0952, 57.1429 }, + { 66.6666, 47.619 }, + { 76.1905, 42.8571 }, + { 80.9524, 38.0952 }, + { 85.7143, 28.5714 }, + { 85.7143, 14.2857 }, + { 76.1905, 4.7619 }, + { 61.9047, 0 }, + { 42.8571, 0 }, + { 28.5714, 4.7619 }, + { 19.0476, 14.2857 }, +}; + +static const StrokeRec char36[] = { + { 2, char36_stroke0 }, + { 2, char36_stroke1 }, + { 20, char36_stroke2 }, +}; + +/* char: 37 '%' */ + +static const CoordRec char37_stroke0[] = { + { 95.2381, 100 }, + { 9.5238, 0 }, +}; + +static const CoordRec char37_stroke1[] = { + { 33.3333, 100 }, + { 42.8571, 90.4762 }, + { 42.8571, 80.9524 }, + { 38.0952, 71.4286 }, + { 28.5714, 66.6667 }, + { 19.0476, 66.6667 }, + { 9.5238, 76.1905 }, + { 9.5238, 85.7143 }, + { 14.2857, 95.2381 }, + { 23.8095, 100 }, + { 33.3333, 100 }, + { 42.8571, 95.2381 }, + { 57.1428, 90.4762 }, + { 71.4286, 90.4762 }, + { 85.7143, 95.2381 }, + { 95.2381, 100 }, +}; + +static const CoordRec char37_stroke2[] = { + { 76.1905, 33.3333 }, + { 66.6667, 28.5714 }, + { 61.9048, 19.0476 }, + { 61.9048, 9.5238 }, + { 71.4286, 0 }, + { 80.9524, 0 }, + { 90.4762, 4.7619 }, + { 95.2381, 14.2857 }, + { 95.2381, 23.8095 }, + { 85.7143, 33.3333 }, + { 76.1905, 33.3333 }, +}; + +static const StrokeRec char37[] = { + { 2, char37_stroke0 }, + { 16, char37_stroke1 }, + { 11, char37_stroke2 }, +}; + +/* char: 38 '&' */ + +static const CoordRec char38_stroke0[] = { + { 100, 57.1429 }, + { 100, 61.9048 }, + { 95.2381, 66.6667 }, + { 90.4762, 66.6667 }, + { 85.7143, 61.9048 }, + { 80.9524, 52.381 }, + { 71.4286, 28.5714 }, + { 61.9048, 14.2857 }, + { 52.3809, 4.7619 }, + { 42.8571, 0 }, + { 23.8095, 0 }, + { 14.2857, 4.7619 }, + { 9.5238, 9.5238 }, + { 4.7619, 19.0476 }, + { 4.7619, 28.5714 }, + { 9.5238, 38.0952 }, + { 14.2857, 42.8571 }, + { 47.619, 61.9048 }, + { 52.3809, 66.6667 }, + { 57.1429, 76.1905 }, + { 57.1429, 85.7143 }, + { 52.3809, 95.2381 }, + { 42.8571, 100 }, + { 33.3333, 95.2381 }, + { 28.5714, 85.7143 }, + { 28.5714, 76.1905 }, + { 33.3333, 61.9048 }, + { 42.8571, 47.619 }, + { 66.6667, 14.2857 }, + { 76.1905, 4.7619 }, + { 85.7143, 0 }, + { 95.2381, 0 }, + { 100, 4.7619 }, + { 100, 9.5238 }, +}; + +static const StrokeRec char38[] = { + { 34, char38_stroke0 }, +}; + +/* char: 39 ''' */ + +static const CoordRec char39_stroke0[] = { + { 52.381, 100 }, + { 52.381, 66.6667 }, +}; + +static const StrokeRec char39[] = { + { 2, char39_stroke0 }, +}; + +/* char: 40 '(' */ + +static const CoordRec char40_stroke0[] = { + { 69.0476, 119.048 }, + { 59.5238, 109.524 }, + { 50, 95.2381 }, + { 40.4762, 76.1905 }, + { 35.7143, 52.381 }, + { 35.7143, 33.3333 }, + { 40.4762, 9.5238 }, + { 50, -9.5238 }, + { 59.5238, -23.8095 }, + { 69.0476, -33.3333 }, +}; + +static const StrokeRec char40[] = { + { 10, char40_stroke0 }, +}; + +/* char: 41 ')' */ + +static const CoordRec char41_stroke0[] = { + { 35.7143, 119.048 }, + { 45.2381, 109.524 }, + { 54.7619, 95.2381 }, + { 64.2857, 76.1905 }, + { 69.0476, 52.381 }, + { 69.0476, 33.3333 }, + { 64.2857, 9.5238 }, + { 54.7619, -9.5238 }, + { 45.2381, -23.8095 }, + { 35.7143, -33.3333 }, +}; + +static const StrokeRec char41[] = { + { 10, char41_stroke0 }, +}; + +/* char: 42 '*' */ + +static const CoordRec char42_stroke0[] = { + { 52.381, 71.4286 }, + { 52.381, 14.2857 }, +}; + +static const CoordRec char42_stroke1[] = { + { 28.5715, 57.1429 }, + { 76.1905, 28.5714 }, +}; + +static const CoordRec char42_stroke2[] = { + { 76.1905, 57.1429 }, + { 28.5715, 28.5714 }, +}; + +static const StrokeRec char42[] = { + { 2, char42_stroke0 }, + { 2, char42_stroke1 }, + { 2, char42_stroke2 }, +}; + +/* char: 43 '+' */ + +static const CoordRec char43_stroke0[] = { + { 52.3809, 85.7143 }, + { 52.3809, 0 }, +}; + +static const CoordRec char43_stroke1[] = { + { 9.5238, 42.8571 }, + { 95.2381, 42.8571 }, +}; + +static const StrokeRec char43[] = { + { 2, char43_stroke0 }, + { 2, char43_stroke1 }, +}; + +/* char: 44 ',' */ + +static const CoordRec char44_stroke0[] = { + { 57.1429, 4.7619 }, + { 52.381, 0 }, + { 47.6191, 4.7619 }, + { 52.381, 9.5238 }, + { 57.1429, 4.7619 }, + { 57.1429, -4.7619 }, + { 52.381, -14.2857 }, + { 47.6191, -19.0476 }, +}; + +static const StrokeRec char44[] = { + { 8, char44_stroke0 }, +}; + +/* char: 45 '-' */ + +static const CoordRec char45_stroke0[] = { + { 9.5238, 42.8571 }, + { 95.2381, 42.8571 }, +}; + +static const StrokeRec char45[] = { + { 2, char45_stroke0 }, +}; + +/* char: 46 '.' */ + +static const CoordRec char46_stroke0[] = { + { 52.381, 9.5238 }, + { 47.6191, 4.7619 }, + { 52.381, 0 }, + { 57.1429, 4.7619 }, + { 52.381, 9.5238 }, +}; + +static const StrokeRec char46[] = { + { 5, char46_stroke0 }, +}; + +/* char: 47 '/' */ + +static const CoordRec char47_stroke0[] = { + { 19.0476, -14.2857 }, + { 85.7143, 100 }, +}; + +static const StrokeRec char47[] = { + { 2, char47_stroke0 }, +}; + +/* char: 48 '0' */ + +static const CoordRec char48_stroke0[] = { + { 47.619, 100 }, + { 33.3333, 95.2381 }, + { 23.8095, 80.9524 }, + { 19.0476, 57.1429 }, + { 19.0476, 42.8571 }, + { 23.8095, 19.0476 }, + { 33.3333, 4.7619 }, + { 47.619, 0 }, + { 57.1428, 0 }, + { 71.4286, 4.7619 }, + { 80.9524, 19.0476 }, + { 85.7143, 42.8571 }, + { 85.7143, 57.1429 }, + { 80.9524, 80.9524 }, + { 71.4286, 95.2381 }, + { 57.1428, 100 }, + { 47.619, 100 }, +}; + +static const StrokeRec char48[] = { + { 17, char48_stroke0 }, +}; + +/* char: 49 '1' */ + +static const CoordRec char49_stroke0[] = { + { 40.4762, 80.9524 }, + { 50, 85.7143 }, + { 64.2857, 100 }, + { 64.2857, 0 }, +}; + +static const StrokeRec char49[] = { + { 4, char49_stroke0 }, +}; + +/* char: 50 '2' */ + +static const CoordRec char50_stroke0[] = { + { 23.8095, 76.1905 }, + { 23.8095, 80.9524 }, + { 28.5714, 90.4762 }, + { 33.3333, 95.2381 }, + { 42.8571, 100 }, + { 61.9047, 100 }, + { 71.4286, 95.2381 }, + { 76.1905, 90.4762 }, + { 80.9524, 80.9524 }, + { 80.9524, 71.4286 }, + { 76.1905, 61.9048 }, + { 66.6666, 47.619 }, + { 19.0476, 0 }, + { 85.7143, 0 }, +}; + +static const StrokeRec char50[] = { + { 14, char50_stroke0 }, +}; + +/* char: 51 '3' */ + +static const CoordRec char51_stroke0[] = { + { 28.5714, 100 }, + { 80.9524, 100 }, + { 52.3809, 61.9048 }, + { 66.6666, 61.9048 }, + { 76.1905, 57.1429 }, + { 80.9524, 52.381 }, + { 85.7143, 38.0952 }, + { 85.7143, 28.5714 }, + { 80.9524, 14.2857 }, + { 71.4286, 4.7619 }, + { 57.1428, 0 }, + { 42.8571, 0 }, + { 28.5714, 4.7619 }, + { 23.8095, 9.5238 }, + { 19.0476, 19.0476 }, +}; + +static const StrokeRec char51[] = { + { 15, char51_stroke0 }, +}; + +/* char: 52 '4' */ + +static const CoordRec char52_stroke0[] = { + { 64.2857, 100 }, + { 16.6667, 33.3333 }, + { 88.0952, 33.3333 }, +}; + +static const CoordRec char52_stroke1[] = { + { 64.2857, 100 }, + { 64.2857, 0 }, +}; + +static const StrokeRec char52[] = { + { 3, char52_stroke0 }, + { 2, char52_stroke1 }, +}; + +/* char: 53 '5' */ + +static const CoordRec char53_stroke0[] = { + { 76.1905, 100 }, + { 28.5714, 100 }, + { 23.8095, 57.1429 }, + { 28.5714, 61.9048 }, + { 42.8571, 66.6667 }, + { 57.1428, 66.6667 }, + { 71.4286, 61.9048 }, + { 80.9524, 52.381 }, + { 85.7143, 38.0952 }, + { 85.7143, 28.5714 }, + { 80.9524, 14.2857 }, + { 71.4286, 4.7619 }, + { 57.1428, 0 }, + { 42.8571, 0 }, + { 28.5714, 4.7619 }, + { 23.8095, 9.5238 }, + { 19.0476, 19.0476 }, +}; + +static const StrokeRec char53[] = { + { 17, char53_stroke0 }, +}; + +/* char: 54 '6' */ + +static const CoordRec char54_stroke0[] = { + { 78.5714, 85.7143 }, + { 73.8096, 95.2381 }, + { 59.5238, 100 }, + { 50, 100 }, + { 35.7143, 95.2381 }, + { 26.1905, 80.9524 }, + { 21.4286, 57.1429 }, + { 21.4286, 33.3333 }, + { 26.1905, 14.2857 }, + { 35.7143, 4.7619 }, + { 50, 0 }, + { 54.7619, 0 }, + { 69.0476, 4.7619 }, + { 78.5714, 14.2857 }, + { 83.3334, 28.5714 }, + { 83.3334, 33.3333 }, + { 78.5714, 47.619 }, + { 69.0476, 57.1429 }, + { 54.7619, 61.9048 }, + { 50, 61.9048 }, + { 35.7143, 57.1429 }, + { 26.1905, 47.619 }, + { 21.4286, 33.3333 }, +}; + +static const StrokeRec char54[] = { + { 23, char54_stroke0 }, +}; + +/* char: 55 '7' */ + +static const CoordRec char55_stroke0[] = { + { 85.7143, 100 }, + { 38.0952, 0 }, +}; + +static const CoordRec char55_stroke1[] = { + { 19.0476, 100 }, + { 85.7143, 100 }, +}; + +static const StrokeRec char55[] = { + { 2, char55_stroke0 }, + { 2, char55_stroke1 }, +}; + +/* char: 56 '8' */ + +static const CoordRec char56_stroke0[] = { + { 42.8571, 100 }, + { 28.5714, 95.2381 }, + { 23.8095, 85.7143 }, + { 23.8095, 76.1905 }, + { 28.5714, 66.6667 }, + { 38.0952, 61.9048 }, + { 57.1428, 57.1429 }, + { 71.4286, 52.381 }, + { 80.9524, 42.8571 }, + { 85.7143, 33.3333 }, + { 85.7143, 19.0476 }, + { 80.9524, 9.5238 }, + { 76.1905, 4.7619 }, + { 61.9047, 0 }, + { 42.8571, 0 }, + { 28.5714, 4.7619 }, + { 23.8095, 9.5238 }, + { 19.0476, 19.0476 }, + { 19.0476, 33.3333 }, + { 23.8095, 42.8571 }, + { 33.3333, 52.381 }, + { 47.619, 57.1429 }, + { 66.6666, 61.9048 }, + { 76.1905, 66.6667 }, + { 80.9524, 76.1905 }, + { 80.9524, 85.7143 }, + { 76.1905, 95.2381 }, + { 61.9047, 100 }, + { 42.8571, 100 }, +}; + +static const StrokeRec char56[] = { + { 29, char56_stroke0 }, +}; + +/* char: 57 '9' */ + +static const CoordRec char57_stroke0[] = { + { 83.3334, 66.6667 }, + { 78.5714, 52.381 }, + { 69.0476, 42.8571 }, + { 54.7619, 38.0952 }, + { 50, 38.0952 }, + { 35.7143, 42.8571 }, + { 26.1905, 52.381 }, + { 21.4286, 66.6667 }, + { 21.4286, 71.4286 }, + { 26.1905, 85.7143 }, + { 35.7143, 95.2381 }, + { 50, 100 }, + { 54.7619, 100 }, + { 69.0476, 95.2381 }, + { 78.5714, 85.7143 }, + { 83.3334, 66.6667 }, + { 83.3334, 42.8571 }, + { 78.5714, 19.0476 }, + { 69.0476, 4.7619 }, + { 54.7619, 0 }, + { 45.2381, 0 }, + { 30.9524, 4.7619 }, + { 26.1905, 14.2857 }, +}; + +static const StrokeRec char57[] = { + { 23, char57_stroke0 }, +}; + +/* char: 58 ':' */ + +static const CoordRec char58_stroke0[] = { + { 52.381, 66.6667 }, + { 47.6191, 61.9048 }, + { 52.381, 57.1429 }, + { 57.1429, 61.9048 }, + { 52.381, 66.6667 }, +}; + +static const CoordRec char58_stroke1[] = { + { 52.381, 9.5238 }, + { 47.6191, 4.7619 }, + { 52.381, 0 }, + { 57.1429, 4.7619 }, + { 52.381, 9.5238 }, +}; + +static const StrokeRec char58[] = { + { 5, char58_stroke0 }, + { 5, char58_stroke1 }, +}; + +/* char: 59 ';' */ + +static const CoordRec char59_stroke0[] = { + { 52.381, 66.6667 }, + { 47.6191, 61.9048 }, + { 52.381, 57.1429 }, + { 57.1429, 61.9048 }, + { 52.381, 66.6667 }, +}; + +static const CoordRec char59_stroke1[] = { + { 57.1429, 4.7619 }, + { 52.381, 0 }, + { 47.6191, 4.7619 }, + { 52.381, 9.5238 }, + { 57.1429, 4.7619 }, + { 57.1429, -4.7619 }, + { 52.381, -14.2857 }, + { 47.6191, -19.0476 }, +}; + +static const StrokeRec char59[] = { + { 5, char59_stroke0 }, + { 8, char59_stroke1 }, +}; + +/* char: 60 '<' */ + +static const CoordRec char60_stroke0[] = { + { 90.4762, 85.7143 }, + { 14.2857, 42.8571 }, + { 90.4762, 0 }, +}; + +static const StrokeRec char60[] = { + { 3, char60_stroke0 }, +}; + +/* char: 61 '=' */ + +static const CoordRec char61_stroke0[] = { + { 9.5238, 57.1429 }, + { 95.2381, 57.1429 }, +}; + +static const CoordRec char61_stroke1[] = { + { 9.5238, 28.5714 }, + { 95.2381, 28.5714 }, +}; + +static const StrokeRec char61[] = { + { 2, char61_stroke0 }, + { 2, char61_stroke1 }, +}; + +/* char: 62 '>' */ + +static const CoordRec char62_stroke0[] = { + { 14.2857, 85.7143 }, + { 90.4762, 42.8571 }, + { 14.2857, 0 }, +}; + +static const StrokeRec char62[] = { + { 3, char62_stroke0 }, +}; + +/* char: 63 '?' */ + +static const CoordRec char63_stroke0[] = { + { 23.8095, 76.1905 }, + { 23.8095, 80.9524 }, + { 28.5714, 90.4762 }, + { 33.3333, 95.2381 }, + { 42.8571, 100 }, + { 61.9047, 100 }, + { 71.4285, 95.2381 }, + { 76.1905, 90.4762 }, + { 80.9524, 80.9524 }, + { 80.9524, 71.4286 }, + { 76.1905, 61.9048 }, + { 71.4285, 57.1429 }, + { 52.3809, 47.619 }, + { 52.3809, 33.3333 }, +}; + +static const CoordRec char63_stroke1[] = { + { 52.3809, 9.5238 }, + { 47.619, 4.7619 }, + { 52.3809, 0 }, + { 57.1428, 4.7619 }, + { 52.3809, 9.5238 }, +}; + +static const StrokeRec char63[] = { + { 14, char63_stroke0 }, + { 5, char63_stroke1 }, +}; + +/* char: 64 '@' */ + +static const CoordRec char64_stroke0[] = { + { 64.2857, 52.381 }, + { 54.7619, 57.1429 }, + { 45.2381, 57.1429 }, + { 40.4762, 47.619 }, + { 40.4762, 42.8571 }, + { 45.2381, 33.3333 }, + { 54.7619, 33.3333 }, + { 64.2857, 38.0952 }, +}; + +static const CoordRec char64_stroke1[] = { + { 64.2857, 57.1429 }, + { 64.2857, 38.0952 }, + { 69.0476, 33.3333 }, + { 78.5714, 33.3333 }, + { 83.3334, 42.8571 }, + { 83.3334, 47.619 }, + { 78.5714, 61.9048 }, + { 69.0476, 71.4286 }, + { 54.7619, 76.1905 }, + { 50, 76.1905 }, + { 35.7143, 71.4286 }, + { 26.1905, 61.9048 }, + { 21.4286, 47.619 }, + { 21.4286, 42.8571 }, + { 26.1905, 28.5714 }, + { 35.7143, 19.0476 }, + { 50, 14.2857 }, + { 54.7619, 14.2857 }, + { 69.0476, 19.0476 }, +}; + +static const StrokeRec char64[] = { + { 8, char64_stroke0 }, + { 19, char64_stroke1 }, +}; + +/* char: 65 'A' */ + +static const CoordRec char65_stroke0[] = { + { 52.3809, 100 }, + { 14.2857, 0 }, +}; + +static const CoordRec char65_stroke1[] = { + { 52.3809, 100 }, + { 90.4762, 0 }, +}; + +static const CoordRec char65_stroke2[] = { + { 28.5714, 33.3333 }, + { 76.1905, 33.3333 }, +}; + +static const StrokeRec char65[] = { + { 2, char65_stroke0 }, + { 2, char65_stroke1 }, + { 2, char65_stroke2 }, +}; + +/* char: 66 'B' */ + +static const CoordRec char66_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char66_stroke1[] = { + { 19.0476, 100 }, + { 61.9047, 100 }, + { 76.1905, 95.2381 }, + { 80.9524, 90.4762 }, + { 85.7143, 80.9524 }, + { 85.7143, 71.4286 }, + { 80.9524, 61.9048 }, + { 76.1905, 57.1429 }, + { 61.9047, 52.381 }, +}; + +static const CoordRec char66_stroke2[] = { + { 19.0476, 52.381 }, + { 61.9047, 52.381 }, + { 76.1905, 47.619 }, + { 80.9524, 42.8571 }, + { 85.7143, 33.3333 }, + { 85.7143, 19.0476 }, + { 80.9524, 9.5238 }, + { 76.1905, 4.7619 }, + { 61.9047, 0 }, + { 19.0476, 0 }, +}; + +static const StrokeRec char66[] = { + { 2, char66_stroke0 }, + { 9, char66_stroke1 }, + { 10, char66_stroke2 }, +}; + +/* char: 67 'C' */ + +static const CoordRec char67_stroke0[] = { + { 88.0952, 76.1905 }, + { 83.3334, 85.7143 }, + { 73.8096, 95.2381 }, + { 64.2857, 100 }, + { 45.2381, 100 }, + { 35.7143, 95.2381 }, + { 26.1905, 85.7143 }, + { 21.4286, 76.1905 }, + { 16.6667, 61.9048 }, + { 16.6667, 38.0952 }, + { 21.4286, 23.8095 }, + { 26.1905, 14.2857 }, + { 35.7143, 4.7619 }, + { 45.2381, 0 }, + { 64.2857, 0 }, + { 73.8096, 4.7619 }, + { 83.3334, 14.2857 }, + { 88.0952, 23.8095 }, +}; + +static const StrokeRec char67[] = { + { 18, char67_stroke0 }, +}; + +/* char: 68 'D' */ + +static const CoordRec char68_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char68_stroke1[] = { + { 19.0476, 100 }, + { 52.3809, 100 }, + { 66.6666, 95.2381 }, + { 76.1905, 85.7143 }, + { 80.9524, 76.1905 }, + { 85.7143, 61.9048 }, + { 85.7143, 38.0952 }, + { 80.9524, 23.8095 }, + { 76.1905, 14.2857 }, + { 66.6666, 4.7619 }, + { 52.3809, 0 }, + { 19.0476, 0 }, +}; + +static const StrokeRec char68[] = { + { 2, char68_stroke0 }, + { 12, char68_stroke1 }, +}; + +/* char: 69 'E' */ + +static const CoordRec char69_stroke0[] = { + { 21.4286, 100 }, + { 21.4286, 0 }, +}; + +static const CoordRec char69_stroke1[] = { + { 21.4286, 100 }, + { 83.3334, 100 }, +}; + +static const CoordRec char69_stroke2[] = { + { 21.4286, 52.381 }, + { 59.5238, 52.381 }, +}; + +static const CoordRec char69_stroke3[] = { + { 21.4286, 0 }, + { 83.3334, 0 }, +}; + +static const StrokeRec char69[] = { + { 2, char69_stroke0 }, + { 2, char69_stroke1 }, + { 2, char69_stroke2 }, + { 2, char69_stroke3 }, +}; + +/* char: 70 'F' */ + +static const CoordRec char70_stroke0[] = { + { 21.4286, 100 }, + { 21.4286, 0 }, +}; + +static const CoordRec char70_stroke1[] = { + { 21.4286, 100 }, + { 83.3334, 100 }, +}; + +static const CoordRec char70_stroke2[] = { + { 21.4286, 52.381 }, + { 59.5238, 52.381 }, +}; + +static const StrokeRec char70[] = { + { 2, char70_stroke0 }, + { 2, char70_stroke1 }, + { 2, char70_stroke2 }, +}; + +/* char: 71 'G' */ + +static const CoordRec char71_stroke0[] = { + { 88.0952, 76.1905 }, + { 83.3334, 85.7143 }, + { 73.8096, 95.2381 }, + { 64.2857, 100 }, + { 45.2381, 100 }, + { 35.7143, 95.2381 }, + { 26.1905, 85.7143 }, + { 21.4286, 76.1905 }, + { 16.6667, 61.9048 }, + { 16.6667, 38.0952 }, + { 21.4286, 23.8095 }, + { 26.1905, 14.2857 }, + { 35.7143, 4.7619 }, + { 45.2381, 0 }, + { 64.2857, 0 }, + { 73.8096, 4.7619 }, + { 83.3334, 14.2857 }, + { 88.0952, 23.8095 }, + { 88.0952, 38.0952 }, +}; + +static const CoordRec char71_stroke1[] = { + { 64.2857, 38.0952 }, + { 88.0952, 38.0952 }, +}; + +static const StrokeRec char71[] = { + { 19, char71_stroke0 }, + { 2, char71_stroke1 }, +}; + +/* char: 72 'H' */ + +static const CoordRec char72_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char72_stroke1[] = { + { 85.7143, 100 }, + { 85.7143, 0 }, +}; + +static const CoordRec char72_stroke2[] = { + { 19.0476, 52.381 }, + { 85.7143, 52.381 }, +}; + +static const StrokeRec char72[] = { + { 2, char72_stroke0 }, + { 2, char72_stroke1 }, + { 2, char72_stroke2 }, +}; + +/* char: 73 'I' */ + +static const CoordRec char73_stroke0[] = { + { 52.381, 100 }, + { 52.381, 0 }, +}; + +static const StrokeRec char73[] = { + { 2, char73_stroke0 }, +}; + +/* char: 74 'J' */ + +static const CoordRec char74_stroke0[] = { + { 76.1905, 100 }, + { 76.1905, 23.8095 }, + { 71.4286, 9.5238 }, + { 66.6667, 4.7619 }, + { 57.1429, 0 }, + { 47.6191, 0 }, + { 38.0953, 4.7619 }, + { 33.3334, 9.5238 }, + { 28.5715, 23.8095 }, + { 28.5715, 33.3333 }, +}; + +static const StrokeRec char74[] = { + { 10, char74_stroke0 }, +}; + +/* char: 75 'K' */ + +static const CoordRec char75_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char75_stroke1[] = { + { 85.7143, 100 }, + { 19.0476, 33.3333 }, +}; + +static const CoordRec char75_stroke2[] = { + { 42.8571, 57.1429 }, + { 85.7143, 0 }, +}; + +static const StrokeRec char75[] = { + { 2, char75_stroke0 }, + { 2, char75_stroke1 }, + { 2, char75_stroke2 }, +}; + +/* char: 76 'L' */ + +static const CoordRec char76_stroke0[] = { + { 23.8095, 100 }, + { 23.8095, 0 }, +}; + +static const CoordRec char76_stroke1[] = { + { 23.8095, 0 }, + { 80.9524, 0 }, +}; + +static const StrokeRec char76[] = { + { 2, char76_stroke0 }, + { 2, char76_stroke1 }, +}; + +/* char: 77 'M' */ + +static const CoordRec char77_stroke0[] = { + { 14.2857, 100 }, + { 14.2857, 0 }, +}; + +static const CoordRec char77_stroke1[] = { + { 14.2857, 100 }, + { 52.3809, 0 }, +}; + +static const CoordRec char77_stroke2[] = { + { 90.4762, 100 }, + { 52.3809, 0 }, +}; + +static const CoordRec char77_stroke3[] = { + { 90.4762, 100 }, + { 90.4762, 0 }, +}; + +static const StrokeRec char77[] = { + { 2, char77_stroke0 }, + { 2, char77_stroke1 }, + { 2, char77_stroke2 }, + { 2, char77_stroke3 }, +}; + +/* char: 78 'N' */ + +static const CoordRec char78_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char78_stroke1[] = { + { 19.0476, 100 }, + { 85.7143, 0 }, +}; + +static const CoordRec char78_stroke2[] = { + { 85.7143, 100 }, + { 85.7143, 0 }, +}; + +static const StrokeRec char78[] = { + { 2, char78_stroke0 }, + { 2, char78_stroke1 }, + { 2, char78_stroke2 }, +}; + +/* char: 79 'O' */ + +static const CoordRec char79_stroke0[] = { + { 42.8571, 100 }, + { 33.3333, 95.2381 }, + { 23.8095, 85.7143 }, + { 19.0476, 76.1905 }, + { 14.2857, 61.9048 }, + { 14.2857, 38.0952 }, + { 19.0476, 23.8095 }, + { 23.8095, 14.2857 }, + { 33.3333, 4.7619 }, + { 42.8571, 0 }, + { 61.9047, 0 }, + { 71.4286, 4.7619 }, + { 80.9524, 14.2857 }, + { 85.7143, 23.8095 }, + { 90.4762, 38.0952 }, + { 90.4762, 61.9048 }, + { 85.7143, 76.1905 }, + { 80.9524, 85.7143 }, + { 71.4286, 95.2381 }, + { 61.9047, 100 }, + { 42.8571, 100 }, +}; + +static const StrokeRec char79[] = { + { 21, char79_stroke0 }, +}; + +/* char: 80 'P' */ + +static const CoordRec char80_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char80_stroke1[] = { + { 19.0476, 100 }, + { 61.9047, 100 }, + { 76.1905, 95.2381 }, + { 80.9524, 90.4762 }, + { 85.7143, 80.9524 }, + { 85.7143, 66.6667 }, + { 80.9524, 57.1429 }, + { 76.1905, 52.381 }, + { 61.9047, 47.619 }, + { 19.0476, 47.619 }, +}; + +static const StrokeRec char80[] = { + { 2, char80_stroke0 }, + { 10, char80_stroke1 }, +}; + +/* char: 81 'Q' */ + +static const CoordRec char81_stroke0[] = { + { 42.8571, 100 }, + { 33.3333, 95.2381 }, + { 23.8095, 85.7143 }, + { 19.0476, 76.1905 }, + { 14.2857, 61.9048 }, + { 14.2857, 38.0952 }, + { 19.0476, 23.8095 }, + { 23.8095, 14.2857 }, + { 33.3333, 4.7619 }, + { 42.8571, 0 }, + { 61.9047, 0 }, + { 71.4286, 4.7619 }, + { 80.9524, 14.2857 }, + { 85.7143, 23.8095 }, + { 90.4762, 38.0952 }, + { 90.4762, 61.9048 }, + { 85.7143, 76.1905 }, + { 80.9524, 85.7143 }, + { 71.4286, 95.2381 }, + { 61.9047, 100 }, + { 42.8571, 100 }, +}; + +static const CoordRec char81_stroke1[] = { + { 57.1428, 19.0476 }, + { 85.7143, -9.5238 }, +}; + +static const StrokeRec char81[] = { + { 21, char81_stroke0 }, + { 2, char81_stroke1 }, +}; + +/* char: 82 'R' */ + +static const CoordRec char82_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char82_stroke1[] = { + { 19.0476, 100 }, + { 61.9047, 100 }, + { 76.1905, 95.2381 }, + { 80.9524, 90.4762 }, + { 85.7143, 80.9524 }, + { 85.7143, 71.4286 }, + { 80.9524, 61.9048 }, + { 76.1905, 57.1429 }, + { 61.9047, 52.381 }, + { 19.0476, 52.381 }, +}; + +static const CoordRec char82_stroke2[] = { + { 52.3809, 52.381 }, + { 85.7143, 0 }, +}; + +static const StrokeRec char82[] = { + { 2, char82_stroke0 }, + { 10, char82_stroke1 }, + { 2, char82_stroke2 }, +}; + +/* char: 83 'S' */ + +static const CoordRec char83_stroke0[] = { + { 85.7143, 85.7143 }, + { 76.1905, 95.2381 }, + { 61.9047, 100 }, + { 42.8571, 100 }, + { 28.5714, 95.2381 }, + { 19.0476, 85.7143 }, + { 19.0476, 76.1905 }, + { 23.8095, 66.6667 }, + { 28.5714, 61.9048 }, + { 38.0952, 57.1429 }, + { 66.6666, 47.619 }, + { 76.1905, 42.8571 }, + { 80.9524, 38.0952 }, + { 85.7143, 28.5714 }, + { 85.7143, 14.2857 }, + { 76.1905, 4.7619 }, + { 61.9047, 0 }, + { 42.8571, 0 }, + { 28.5714, 4.7619 }, + { 19.0476, 14.2857 }, +}; + +static const StrokeRec char83[] = { + { 20, char83_stroke0 }, +}; + +/* char: 84 'T' */ + +static const CoordRec char84_stroke0[] = { + { 52.3809, 100 }, + { 52.3809, 0 }, +}; + +static const CoordRec char84_stroke1[] = { + { 19.0476, 100 }, + { 85.7143, 100 }, +}; + +static const StrokeRec char84[] = { + { 2, char84_stroke0 }, + { 2, char84_stroke1 }, +}; + +/* char: 85 'U' */ + +static const CoordRec char85_stroke0[] = { + { 19.0476, 100 }, + { 19.0476, 28.5714 }, + { 23.8095, 14.2857 }, + { 33.3333, 4.7619 }, + { 47.619, 0 }, + { 57.1428, 0 }, + { 71.4286, 4.7619 }, + { 80.9524, 14.2857 }, + { 85.7143, 28.5714 }, + { 85.7143, 100 }, +}; + +static const StrokeRec char85[] = { + { 10, char85_stroke0 }, +}; + +/* char: 86 'V' */ + +static const CoordRec char86_stroke0[] = { + { 14.2857, 100 }, + { 52.3809, 0 }, +}; + +static const CoordRec char86_stroke1[] = { + { 90.4762, 100 }, + { 52.3809, 0 }, +}; + +static const StrokeRec char86[] = { + { 2, char86_stroke0 }, + { 2, char86_stroke1 }, +}; + +/* char: 87 'W' */ + +static const CoordRec char87_stroke0[] = { + { 4.7619, 100 }, + { 28.5714, 0 }, +}; + +static const CoordRec char87_stroke1[] = { + { 52.3809, 100 }, + { 28.5714, 0 }, +}; + +static const CoordRec char87_stroke2[] = { + { 52.3809, 100 }, + { 76.1905, 0 }, +}; + +static const CoordRec char87_stroke3[] = { + { 100, 100 }, + { 76.1905, 0 }, +}; + +static const StrokeRec char87[] = { + { 2, char87_stroke0 }, + { 2, char87_stroke1 }, + { 2, char87_stroke2 }, + { 2, char87_stroke3 }, +}; + +/* char: 88 'X' */ + +static const CoordRec char88_stroke0[] = { + { 19.0476, 100 }, + { 85.7143, 0 }, +}; + +static const CoordRec char88_stroke1[] = { + { 85.7143, 100 }, + { 19.0476, 0 }, +}; + +static const StrokeRec char88[] = { + { 2, char88_stroke0 }, + { 2, char88_stroke1 }, +}; + +/* char: 89 'Y' */ + +static const CoordRec char89_stroke0[] = { + { 14.2857, 100 }, + { 52.3809, 52.381 }, + { 52.3809, 0 }, +}; + +static const CoordRec char89_stroke1[] = { + { 90.4762, 100 }, + { 52.3809, 52.381 }, +}; + +static const StrokeRec char89[] = { + { 3, char89_stroke0 }, + { 2, char89_stroke1 }, +}; + +/* char: 90 'Z' */ + +static const CoordRec char90_stroke0[] = { + { 85.7143, 100 }, + { 19.0476, 0 }, +}; + +static const CoordRec char90_stroke1[] = { + { 19.0476, 100 }, + { 85.7143, 100 }, +}; + +static const CoordRec char90_stroke2[] = { + { 19.0476, 0 }, + { 85.7143, 0 }, +}; + +static const StrokeRec char90[] = { + { 2, char90_stroke0 }, + { 2, char90_stroke1 }, + { 2, char90_stroke2 }, +}; + +/* char: 91 '[' */ + +static const CoordRec char91_stroke0[] = { + { 35.7143, 119.048 }, + { 35.7143, -33.3333 }, +}; + +static const CoordRec char91_stroke1[] = { + { 40.4762, 119.048 }, + { 40.4762, -33.3333 }, +}; + +static const CoordRec char91_stroke2[] = { + { 35.7143, 119.048 }, + { 69.0476, 119.048 }, +}; + +static const CoordRec char91_stroke3[] = { + { 35.7143, -33.3333 }, + { 69.0476, -33.3333 }, +}; + +static const StrokeRec char91[] = { + { 2, char91_stroke0 }, + { 2, char91_stroke1 }, + { 2, char91_stroke2 }, + { 2, char91_stroke3 }, +}; + +/* char: 92 '\' */ + +static const CoordRec char92_stroke0[] = { + { 19.0476, 100 }, + { 85.7143, -14.2857 }, +}; + +static const StrokeRec char92[] = { + { 2, char92_stroke0 }, +}; + +/* char: 93 ']' */ + +static const CoordRec char93_stroke0[] = { + { 64.2857, 119.048 }, + { 64.2857, -33.3333 }, +}; + +static const CoordRec char93_stroke1[] = { + { 69.0476, 119.048 }, + { 69.0476, -33.3333 }, +}; + +static const CoordRec char93_stroke2[] = { + { 35.7143, 119.048 }, + { 69.0476, 119.048 }, +}; + +static const CoordRec char93_stroke3[] = { + { 35.7143, -33.3333 }, + { 69.0476, -33.3333 }, +}; + +static const StrokeRec char93[] = { + { 2, char93_stroke0 }, + { 2, char93_stroke1 }, + { 2, char93_stroke2 }, + { 2, char93_stroke3 }, +}; + +/* char: 94 '^' */ + +static const CoordRec char94_stroke0[] = { + { 52.3809, 109.524 }, + { 14.2857, 42.8571 }, +}; + +static const CoordRec char94_stroke1[] = { + { 52.3809, 109.524 }, + { 90.4762, 42.8571 }, +}; + +static const StrokeRec char94[] = { + { 2, char94_stroke0 }, + { 2, char94_stroke1 }, +}; + +/* char: 95 '_' */ + +static const CoordRec char95_stroke0[] = { + { 0, -33.3333 }, + { 104.762, -33.3333 }, + { 104.762, -28.5714 }, + { 0, -28.5714 }, + { 0, -33.3333 }, +}; + +static const StrokeRec char95[] = { + { 5, char95_stroke0 }, +}; + +/* char: 96 '`' */ + +static const CoordRec char96_stroke0[] = { + { 42.8572, 100 }, + { 66.6667, 71.4286 }, +}; + +static const CoordRec char96_stroke1[] = { + { 42.8572, 100 }, + { 38.0953, 95.2381 }, + { 66.6667, 71.4286 }, +}; + +static const StrokeRec char96[] = { + { 2, char96_stroke0 }, + { 3, char96_stroke1 }, +}; + +/* char: 97 'a' */ + +static const CoordRec char97_stroke0[] = { + { 80.9524, 66.6667 }, + { 80.9524, 0 }, +}; + +static const CoordRec char97_stroke1[] = { + { 80.9524, 52.381 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char97[] = { + { 2, char97_stroke0 }, + { 14, char97_stroke1 }, +}; + +/* char: 98 'b' */ + +static const CoordRec char98_stroke0[] = { + { 23.8095, 100 }, + { 23.8095, 0 }, +}; + +static const CoordRec char98_stroke1[] = { + { 23.8095, 52.381 }, + { 33.3333, 61.9048 }, + { 42.8571, 66.6667 }, + { 57.1428, 66.6667 }, + { 66.6666, 61.9048 }, + { 76.1905, 52.381 }, + { 80.9524, 38.0952 }, + { 80.9524, 28.5714 }, + { 76.1905, 14.2857 }, + { 66.6666, 4.7619 }, + { 57.1428, 0 }, + { 42.8571, 0 }, + { 33.3333, 4.7619 }, + { 23.8095, 14.2857 }, +}; + +static const StrokeRec char98[] = { + { 2, char98_stroke0 }, + { 14, char98_stroke1 }, +}; + +/* char: 99 'c' */ + +static const CoordRec char99_stroke0[] = { + { 80.9524, 52.381 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char99[] = { + { 14, char99_stroke0 }, +}; + +/* char: 100 'd' */ + +static const CoordRec char100_stroke0[] = { + { 80.9524, 100 }, + { 80.9524, 0 }, +}; + +static const CoordRec char100_stroke1[] = { + { 80.9524, 52.381 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char100[] = { + { 2, char100_stroke0 }, + { 14, char100_stroke1 }, +}; + +/* char: 101 'e' */ + +static const CoordRec char101_stroke0[] = { + { 23.8095, 38.0952 }, + { 80.9524, 38.0952 }, + { 80.9524, 47.619 }, + { 76.1905, 57.1429 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char101[] = { + { 17, char101_stroke0 }, +}; + +/* char: 102 'f' */ + +static const CoordRec char102_stroke0[] = { + { 71.4286, 100 }, + { 61.9048, 100 }, + { 52.381, 95.2381 }, + { 47.6191, 80.9524 }, + { 47.6191, 0 }, +}; + +static const CoordRec char102_stroke1[] = { + { 33.3334, 66.6667 }, + { 66.6667, 66.6667 }, +}; + +static const StrokeRec char102[] = { + { 5, char102_stroke0 }, + { 2, char102_stroke1 }, +}; + +/* char: 103 'g' */ + +static const CoordRec char103_stroke0[] = { + { 80.9524, 66.6667 }, + { 80.9524, -9.5238 }, + { 76.1905, -23.8095 }, + { 71.4285, -28.5714 }, + { 61.9047, -33.3333 }, + { 47.619, -33.3333 }, + { 38.0952, -28.5714 }, +}; + +static const CoordRec char103_stroke1[] = { + { 80.9524, 52.381 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char103[] = { + { 7, char103_stroke0 }, + { 14, char103_stroke1 }, +}; + +/* char: 104 'h' */ + +static const CoordRec char104_stroke0[] = { + { 26.1905, 100 }, + { 26.1905, 0 }, +}; + +static const CoordRec char104_stroke1[] = { + { 26.1905, 47.619 }, + { 40.4762, 61.9048 }, + { 50, 66.6667 }, + { 64.2857, 66.6667 }, + { 73.8095, 61.9048 }, + { 78.5715, 47.619 }, + { 78.5715, 0 }, +}; + +static const StrokeRec char104[] = { + { 2, char104_stroke0 }, + { 7, char104_stroke1 }, +}; + +/* char: 105 'i' */ + +static const CoordRec char105_stroke0[] = { + { 47.6191, 100 }, + { 52.381, 95.2381 }, + { 57.1429, 100 }, + { 52.381, 104.762 }, + { 47.6191, 100 }, +}; + +static const CoordRec char105_stroke1[] = { + { 52.381, 66.6667 }, + { 52.381, 0 }, +}; + +static const StrokeRec char105[] = { + { 5, char105_stroke0 }, + { 2, char105_stroke1 }, +}; + +/* char: 106 'j' */ + +static const CoordRec char106_stroke0[] = { + { 57.1429, 100 }, + { 61.9048, 95.2381 }, + { 66.6667, 100 }, + { 61.9048, 104.762 }, + { 57.1429, 100 }, +}; + +static const CoordRec char106_stroke1[] = { + { 61.9048, 66.6667 }, + { 61.9048, -14.2857 }, + { 57.1429, -28.5714 }, + { 47.6191, -33.3333 }, + { 38.0953, -33.3333 }, +}; + +static const StrokeRec char106[] = { + { 5, char106_stroke0 }, + { 5, char106_stroke1 }, +}; + +/* char: 107 'k' */ + +static const CoordRec char107_stroke0[] = { + { 26.1905, 100 }, + { 26.1905, 0 }, +}; + +static const CoordRec char107_stroke1[] = { + { 73.8095, 66.6667 }, + { 26.1905, 19.0476 }, +}; + +static const CoordRec char107_stroke2[] = { + { 45.2381, 38.0952 }, + { 78.5715, 0 }, +}; + +static const StrokeRec char107[] = { + { 2, char107_stroke0 }, + { 2, char107_stroke1 }, + { 2, char107_stroke2 }, +}; + +/* char: 108 'l' */ + +static const CoordRec char108_stroke0[] = { + { 52.381, 100 }, + { 52.381, 0 }, +}; + +static const StrokeRec char108[] = { + { 2, char108_stroke0 }, +}; + +/* char: 109 'm' */ + +static const CoordRec char109_stroke0[] = { + { 0, 66.6667 }, + { 0, 0 }, +}; + +static const CoordRec char109_stroke1[] = { + { 0, 47.619 }, + { 14.2857, 61.9048 }, + { 23.8095, 66.6667 }, + { 38.0952, 66.6667 }, + { 47.619, 61.9048 }, + { 52.381, 47.619 }, + { 52.381, 0 }, +}; + +static const CoordRec char109_stroke2[] = { + { 52.381, 47.619 }, + { 66.6667, 61.9048 }, + { 76.1905, 66.6667 }, + { 90.4762, 66.6667 }, + { 100, 61.9048 }, + { 104.762, 47.619 }, + { 104.762, 0 }, +}; + +static const StrokeRec char109[] = { + { 2, char109_stroke0 }, + { 7, char109_stroke1 }, + { 7, char109_stroke2 }, +}; + +/* char: 110 'n' */ + +static const CoordRec char110_stroke0[] = { + { 26.1905, 66.6667 }, + { 26.1905, 0 }, +}; + +static const CoordRec char110_stroke1[] = { + { 26.1905, 47.619 }, + { 40.4762, 61.9048 }, + { 50, 66.6667 }, + { 64.2857, 66.6667 }, + { 73.8095, 61.9048 }, + { 78.5715, 47.619 }, + { 78.5715, 0 }, +}; + +static const StrokeRec char110[] = { + { 2, char110_stroke0 }, + { 7, char110_stroke1 }, +}; + +/* char: 111 'o' */ + +static const CoordRec char111_stroke0[] = { + { 45.2381, 66.6667 }, + { 35.7143, 61.9048 }, + { 26.1905, 52.381 }, + { 21.4286, 38.0952 }, + { 21.4286, 28.5714 }, + { 26.1905, 14.2857 }, + { 35.7143, 4.7619 }, + { 45.2381, 0 }, + { 59.5238, 0 }, + { 69.0476, 4.7619 }, + { 78.5714, 14.2857 }, + { 83.3334, 28.5714 }, + { 83.3334, 38.0952 }, + { 78.5714, 52.381 }, + { 69.0476, 61.9048 }, + { 59.5238, 66.6667 }, + { 45.2381, 66.6667 }, +}; + +static const StrokeRec char111[] = { + { 17, char111_stroke0 }, +}; + +/* char: 112 'p' */ + +static const CoordRec char112_stroke0[] = { + { 23.8095, 66.6667 }, + { 23.8095, -33.3333 }, +}; + +static const CoordRec char112_stroke1[] = { + { 23.8095, 52.381 }, + { 33.3333, 61.9048 }, + { 42.8571, 66.6667 }, + { 57.1428, 66.6667 }, + { 66.6666, 61.9048 }, + { 76.1905, 52.381 }, + { 80.9524, 38.0952 }, + { 80.9524, 28.5714 }, + { 76.1905, 14.2857 }, + { 66.6666, 4.7619 }, + { 57.1428, 0 }, + { 42.8571, 0 }, + { 33.3333, 4.7619 }, + { 23.8095, 14.2857 }, +}; + +static const StrokeRec char112[] = { + { 2, char112_stroke0 }, + { 14, char112_stroke1 }, +}; + +/* char: 113 'q' */ + +static const CoordRec char113_stroke0[] = { + { 80.9524, 66.6667 }, + { 80.9524, -33.3333 }, +}; + +static const CoordRec char113_stroke1[] = { + { 80.9524, 52.381 }, + { 71.4285, 61.9048 }, + { 61.9047, 66.6667 }, + { 47.619, 66.6667 }, + { 38.0952, 61.9048 }, + { 28.5714, 52.381 }, + { 23.8095, 38.0952 }, + { 23.8095, 28.5714 }, + { 28.5714, 14.2857 }, + { 38.0952, 4.7619 }, + { 47.619, 0 }, + { 61.9047, 0 }, + { 71.4285, 4.7619 }, + { 80.9524, 14.2857 }, +}; + +static const StrokeRec char113[] = { + { 2, char113_stroke0 }, + { 14, char113_stroke1 }, +}; + +/* char: 114 'r' */ + +static const CoordRec char114_stroke0[] = { + { 33.3334, 66.6667 }, + { 33.3334, 0 }, +}; + +static const CoordRec char114_stroke1[] = { + { 33.3334, 38.0952 }, + { 38.0953, 52.381 }, + { 47.6191, 61.9048 }, + { 57.1429, 66.6667 }, + { 71.4286, 66.6667 }, +}; + +static const StrokeRec char114[] = { + { 2, char114_stroke0 }, + { 5, char114_stroke1 }, +}; + +/* char: 115 's' */ + +static const CoordRec char115_stroke0[] = { + { 78.5715, 52.381 }, + { 73.8095, 61.9048 }, + { 59.5238, 66.6667 }, + { 45.2381, 66.6667 }, + { 30.9524, 61.9048 }, + { 26.1905, 52.381 }, + { 30.9524, 42.8571 }, + { 40.4762, 38.0952 }, + { 64.2857, 33.3333 }, + { 73.8095, 28.5714 }, + { 78.5715, 19.0476 }, + { 78.5715, 14.2857 }, + { 73.8095, 4.7619 }, + { 59.5238, 0 }, + { 45.2381, 0 }, + { 30.9524, 4.7619 }, + { 26.1905, 14.2857 }, +}; + +static const StrokeRec char115[] = { + { 17, char115_stroke0 }, +}; + +/* char: 116 't' */ + +static const CoordRec char116_stroke0[] = { + { 47.6191, 100 }, + { 47.6191, 19.0476 }, + { 52.381, 4.7619 }, + { 61.9048, 0 }, + { 71.4286, 0 }, +}; + +static const CoordRec char116_stroke1[] = { + { 33.3334, 66.6667 }, + { 66.6667, 66.6667 }, +}; + +static const StrokeRec char116[] = { + { 5, char116_stroke0 }, + { 2, char116_stroke1 }, +}; + +/* char: 117 'u' */ + +static const CoordRec char117_stroke0[] = { + { 26.1905, 66.6667 }, + { 26.1905, 19.0476 }, + { 30.9524, 4.7619 }, + { 40.4762, 0 }, + { 54.7619, 0 }, + { 64.2857, 4.7619 }, + { 78.5715, 19.0476 }, +}; + +static const CoordRec char117_stroke1[] = { + { 78.5715, 66.6667 }, + { 78.5715, 0 }, +}; + +static const StrokeRec char117[] = { + { 7, char117_stroke0 }, + { 2, char117_stroke1 }, +}; + +/* char: 118 'v' */ + +static const CoordRec char118_stroke0[] = { + { 23.8095, 66.6667 }, + { 52.3809, 0 }, +}; + +static const CoordRec char118_stroke1[] = { + { 80.9524, 66.6667 }, + { 52.3809, 0 }, +}; + +static const StrokeRec char118[] = { + { 2, char118_stroke0 }, + { 2, char118_stroke1 }, +}; + +/* char: 119 'w' */ + +static const CoordRec char119_stroke0[] = { + { 14.2857, 66.6667 }, + { 33.3333, 0 }, +}; + +static const CoordRec char119_stroke1[] = { + { 52.3809, 66.6667 }, + { 33.3333, 0 }, +}; + +static const CoordRec char119_stroke2[] = { + { 52.3809, 66.6667 }, + { 71.4286, 0 }, +}; + +static const CoordRec char119_stroke3[] = { + { 90.4762, 66.6667 }, + { 71.4286, 0 }, +}; + +static const StrokeRec char119[] = { + { 2, char119_stroke0 }, + { 2, char119_stroke1 }, + { 2, char119_stroke2 }, + { 2, char119_stroke3 }, +}; + +/* char: 120 'x' */ + +static const CoordRec char120_stroke0[] = { + { 26.1905, 66.6667 }, + { 78.5715, 0 }, +}; + +static const CoordRec char120_stroke1[] = { + { 78.5715, 66.6667 }, + { 26.1905, 0 }, +}; + +static const StrokeRec char120[] = { + { 2, char120_stroke0 }, + { 2, char120_stroke1 }, +}; + +/* char: 121 'y' */ + +static const CoordRec char121_stroke0[] = { + { 26.1905, 66.6667 }, + { 54.7619, 0 }, +}; + +static const CoordRec char121_stroke1[] = { + { 83.3334, 66.6667 }, + { 54.7619, 0 }, + { 45.2381, -19.0476 }, + { 35.7143, -28.5714 }, + { 26.1905, -33.3333 }, + { 21.4286, -33.3333 }, +}; + +static const StrokeRec char121[] = { + { 2, char121_stroke0 }, + { 6, char121_stroke1 }, +}; + +/* char: 122 'z' */ + +static const CoordRec char122_stroke0[] = { + { 78.5715, 66.6667 }, + { 26.1905, 0 }, +}; + +static const CoordRec char122_stroke1[] = { + { 26.1905, 66.6667 }, + { 78.5715, 66.6667 }, +}; + +static const CoordRec char122_stroke2[] = { + { 26.1905, 0 }, + { 78.5715, 0 }, +}; + +static const StrokeRec char122[] = { + { 2, char122_stroke0 }, + { 2, char122_stroke1 }, + { 2, char122_stroke2 }, +}; + +/* char: 123 '{' */ + +static const CoordRec char123_stroke0[] = { + { 64.2857, 119.048 }, + { 54.7619, 114.286 }, + { 50, 109.524 }, + { 45.2381, 100 }, + { 45.2381, 90.4762 }, + { 50, 80.9524 }, + { 54.7619, 76.1905 }, + { 59.5238, 66.6667 }, + { 59.5238, 57.1429 }, + { 50, 47.619 }, +}; + +static const CoordRec char123_stroke1[] = { + { 54.7619, 114.286 }, + { 50, 104.762 }, + { 50, 95.2381 }, + { 54.7619, 85.7143 }, + { 59.5238, 80.9524 }, + { 64.2857, 71.4286 }, + { 64.2857, 61.9048 }, + { 59.5238, 52.381 }, + { 40.4762, 42.8571 }, + { 59.5238, 33.3333 }, + { 64.2857, 23.8095 }, + { 64.2857, 14.2857 }, + { 59.5238, 4.7619 }, + { 54.7619, 0 }, + { 50, -9.5238 }, + { 50, -19.0476 }, + { 54.7619, -28.5714 }, +}; + +static const CoordRec char123_stroke2[] = { + { 50, 38.0952 }, + { 59.5238, 28.5714 }, + { 59.5238, 19.0476 }, + { 54.7619, 9.5238 }, + { 50, 4.7619 }, + { 45.2381, -4.7619 }, + { 45.2381, -14.2857 }, + { 50, -23.8095 }, + { 54.7619, -28.5714 }, + { 64.2857, -33.3333 }, +}; + +static const StrokeRec char123[] = { + { 10, char123_stroke0 }, + { 17, char123_stroke1 }, + { 10, char123_stroke2 }, +}; + +/* char: 124 '|' */ + +static const CoordRec char124_stroke0[] = { + { 52.381, 119.048 }, + { 52.381, -33.3333 }, +}; + +static const StrokeRec char124[] = { + { 2, char124_stroke0 }, +}; + +/* char: 125 '}' */ + +static const CoordRec char125_stroke0[] = { + { 40.4762, 119.048 }, + { 50, 114.286 }, + { 54.7619, 109.524 }, + { 59.5238, 100 }, + { 59.5238, 90.4762 }, + { 54.7619, 80.9524 }, + { 50, 76.1905 }, + { 45.2381, 66.6667 }, + { 45.2381, 57.1429 }, + { 54.7619, 47.619 }, +}; + +static const CoordRec char125_stroke1[] = { + { 50, 114.286 }, + { 54.7619, 104.762 }, + { 54.7619, 95.2381 }, + { 50, 85.7143 }, + { 45.2381, 80.9524 }, + { 40.4762, 71.4286 }, + { 40.4762, 61.9048 }, + { 45.2381, 52.381 }, + { 64.2857, 42.8571 }, + { 45.2381, 33.3333 }, + { 40.4762, 23.8095 }, + { 40.4762, 14.2857 }, + { 45.2381, 4.7619 }, + { 50, 0 }, + { 54.7619, -9.5238 }, + { 54.7619, -19.0476 }, + { 50, -28.5714 }, +}; + +static const CoordRec char125_stroke2[] = { + { 54.7619, 38.0952 }, + { 45.2381, 28.5714 }, + { 45.2381, 19.0476 }, + { 50, 9.5238 }, + { 54.7619, 4.7619 }, + { 59.5238, -4.7619 }, + { 59.5238, -14.2857 }, + { 54.7619, -23.8095 }, + { 50, -28.5714 }, + { 40.4762, -33.3333 }, +}; + +static const StrokeRec char125[] = { + { 10, char125_stroke0 }, + { 17, char125_stroke1 }, + { 10, char125_stroke2 }, +}; + +/* char: 126 '~' */ + +static const CoordRec char126_stroke0[] = { + { 9.5238, 28.5714 }, + { 9.5238, 38.0952 }, + { 14.2857, 52.381 }, + { 23.8095, 57.1429 }, + { 33.3333, 57.1429 }, + { 42.8571, 52.381 }, + { 61.9048, 38.0952 }, + { 71.4286, 33.3333 }, + { 80.9524, 33.3333 }, + { 90.4762, 38.0952 }, + { 95.2381, 47.619 }, +}; + +static const CoordRec char126_stroke1[] = { + { 9.5238, 38.0952 }, + { 14.2857, 47.619 }, + { 23.8095, 52.381 }, + { 33.3333, 52.381 }, + { 42.8571, 47.619 }, + { 61.9048, 33.3333 }, + { 71.4286, 28.5714 }, + { 80.9524, 28.5714 }, + { 90.4762, 33.3333 }, + { 95.2381, 47.619 }, + { 95.2381, 57.1429 }, +}; + +static const StrokeRec char126[] = { + { 11, char126_stroke0 }, + { 11, char126_stroke1 }, +}; + +/* char: 127 */ + +static const CoordRec char127_stroke0[] = { + { 71.4286, 100 }, + { 33.3333, -33.3333 }, +}; + +static const CoordRec char127_stroke1[] = { + { 47.619, 66.6667 }, + { 33.3333, 61.9048 }, + { 23.8095, 52.381 }, + { 19.0476, 38.0952 }, + { 19.0476, 23.8095 }, + { 23.8095, 14.2857 }, + { 33.3333, 4.7619 }, + { 47.619, 0 }, + { 57.1428, 0 }, + { 71.4286, 4.7619 }, + { 80.9524, 14.2857 }, + { 85.7143, 28.5714 }, + { 85.7143, 42.8571 }, + { 80.9524, 52.381 }, + { 71.4286, 61.9048 }, + { 57.1428, 66.6667 }, + { 47.619, 66.6667 }, +}; + +static const StrokeRec char127[] = { + { 2, char127_stroke0 }, + { 17, char127_stroke1 }, +}; + +static const StrokeCharRec chars[] = { + { 0, /* char0 */ 0, 0, 0 }, + { 0, /* char1 */ 0, 0, 0 }, + { 0, /* char2 */ 0, 0, 0 }, + { 0, /* char3 */ 0, 0, 0 }, + { 0, /* char4 */ 0, 0, 0 }, + { 0, /* char5 */ 0, 0, 0 }, + { 0, /* char6 */ 0, 0, 0 }, + { 0, /* char7 */ 0, 0, 0 }, + { 0, /* char8 */ 0, 0, 0 }, + { 0, /* char9 */ 0, 0, 0 }, + { 0, /* char10 */ 0, 0, 0 }, + { 0, /* char11 */ 0, 0, 0 }, + { 0, /* char12 */ 0, 0, 0 }, + { 0, /* char13 */ 0, 0, 0 }, + { 0, /* char14 */ 0, 0, 0 }, + { 0, /* char15 */ 0, 0, 0 }, + { 0, /* char16 */ 0, 0, 0 }, + { 0, /* char17 */ 0, 0, 0 }, + { 0, /* char18 */ 0, 0, 0 }, + { 0, /* char19 */ 0, 0, 0 }, + { 0, /* char20 */ 0, 0, 0 }, + { 0, /* char21 */ 0, 0, 0 }, + { 0, /* char22 */ 0, 0, 0 }, + { 0, /* char23 */ 0, 0, 0 }, + { 0, /* char24 */ 0, 0, 0 }, + { 0, /* char25 */ 0, 0, 0 }, + { 0, /* char26 */ 0, 0, 0 }, + { 0, /* char27 */ 0, 0, 0 }, + { 0, /* char28 */ 0, 0, 0 }, + { 0, /* char29 */ 0, 0, 0 }, + { 0, /* char30 */ 0, 0, 0 }, + { 0, /* char31 */ 0, 0, 0 }, + { 0, /* char32 */ 0, 52.381, 104.762 }, + { 2, char33, 52.381, 104.762 }, + { 2, char34, 52.381, 104.762 }, + { 4, char35, 52.381, 104.762 }, + { 3, char36, 52.381, 104.762 }, + { 3, char37, 52.381, 104.762 }, + { 1, char38, 52.381, 104.762 }, + { 1, char39, 52.381, 104.762 }, + { 1, char40, 52.381, 104.762 }, + { 1, char41, 52.381, 104.762 }, + { 3, char42, 52.381, 104.762 }, + { 2, char43, 52.381, 104.762 }, + { 1, char44, 52.381, 104.762 }, + { 1, char45, 52.381, 104.762 }, + { 1, char46, 52.381, 104.762 }, + { 1, char47, 52.381, 104.762 }, + { 1, char48, 52.381, 104.762 }, + { 1, char49, 52.381, 104.762 }, + { 1, char50, 52.381, 104.762 }, + { 1, char51, 52.381, 104.762 }, + { 2, char52, 52.381, 104.762 }, + { 1, char53, 52.381, 104.762 }, + { 1, char54, 52.381, 104.762 }, + { 2, char55, 52.381, 104.762 }, + { 1, char56, 52.381, 104.762 }, + { 1, char57, 52.381, 104.762 }, + { 2, char58, 52.381, 104.762 }, + { 2, char59, 52.381, 104.762 }, + { 1, char60, 52.381, 104.762 }, + { 2, char61, 52.381, 104.762 }, + { 1, char62, 52.381, 104.762 }, + { 2, char63, 52.381, 104.762 }, + { 2, char64, 52.381, 104.762 }, + { 3, char65, 52.381, 104.762 }, + { 3, char66, 52.381, 104.762 }, + { 1, char67, 52.381, 104.762 }, + { 2, char68, 52.381, 104.762 }, + { 4, char69, 52.381, 104.762 }, + { 3, char70, 52.381, 104.762 }, + { 2, char71, 52.381, 104.762 }, + { 3, char72, 52.381, 104.762 }, + { 1, char73, 52.381, 104.762 }, + { 1, char74, 52.381, 104.762 }, + { 3, char75, 52.381, 104.762 }, + { 2, char76, 52.381, 104.762 }, + { 4, char77, 52.381, 104.762 }, + { 3, char78, 52.381, 104.762 }, + { 1, char79, 52.381, 104.762 }, + { 2, char80, 52.381, 104.762 }, + { 2, char81, 52.381, 104.762 }, + { 3, char82, 52.381, 104.762 }, + { 1, char83, 52.381, 104.762 }, + { 2, char84, 52.381, 104.762 }, + { 1, char85, 52.381, 104.762 }, + { 2, char86, 52.381, 104.762 }, + { 4, char87, 52.381, 104.762 }, + { 2, char88, 52.381, 104.762 }, + { 2, char89, 52.381, 104.762 }, + { 3, char90, 52.381, 104.762 }, + { 4, char91, 52.381, 104.762 }, + { 1, char92, 52.381, 104.762 }, + { 4, char93, 52.381, 104.762 }, + { 2, char94, 52.381, 104.762 }, + { 1, char95, 52.381, 104.762 }, + { 2, char96, 52.381, 104.762 }, + { 2, char97, 52.381, 104.762 }, + { 2, char98, 52.381, 104.762 }, + { 1, char99, 52.381, 104.762 }, + { 2, char100, 52.381, 104.762 }, + { 1, char101, 52.381, 104.762 }, + { 2, char102, 52.381, 104.762 }, + { 2, char103, 52.381, 104.762 }, + { 2, char104, 52.381, 104.762 }, + { 2, char105, 52.381, 104.762 }, + { 2, char106, 52.381, 104.762 }, + { 3, char107, 52.381, 104.762 }, + { 1, char108, 52.381, 104.762 }, + { 3, char109, 52.381, 104.762 }, + { 2, char110, 52.381, 104.762 }, + { 1, char111, 52.381, 104.762 }, + { 2, char112, 52.381, 104.762 }, + { 2, char113, 52.381, 104.762 }, + { 2, char114, 52.381, 104.762 }, + { 1, char115, 52.381, 104.762 }, + { 2, char116, 52.381, 104.762 }, + { 2, char117, 52.381, 104.762 }, + { 2, char118, 52.381, 104.762 }, + { 4, char119, 52.381, 104.762 }, + { 2, char120, 52.381, 104.762 }, + { 2, char121, 52.381, 104.762 }, + { 3, char122, 52.381, 104.762 }, + { 3, char123, 52.381, 104.762 }, + { 1, char124, 52.381, 104.762 }, + { 3, char125, 52.381, 104.762 }, + { 2, char126, 52.381, 104.762 }, + { 2, char127, 52.381, 104.762 }, +}; + +StrokeFontRec glutStrokeMonoRoman = { "Roman", 128, chars, 119.048, -33.3333 }; + diff --git a/lib/glut-3.7.6/lib/glut/glut_overlay.c b/lib/glut-3.7.6/lib/glut/glut_overlay.c new file mode 100644 index 0000000000..0d4d45707a --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_overlay.c @@ -0,0 +1,607 @@ + +/* Copyright (c) Mark J. Kilgard, 1996, 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. */ + +#include +#include +#include +#include + +#if !defined(_WIN32) +#include +#include +#include /* for XA_RGB_DEFAULT_MAP atom */ +#if defined (__vms) +#include /* for XmuLookupStandardColormap */ +#else +#include /* for XmuLookupStandardColormap */ +#endif +#endif /* !_WIN32 */ + +#include "glutint.h" +#include "layerutil.h" + +static Criterion requiredOverlayCriteria[] = +{ + {LEVEL, EQ, 1}, /* This entry gets poked in + determineOverlayVisual. */ + {TRANSPARENT, EQ, 1}, + {XPSEUDOCOLOR, EQ, 1}, + {RGBA, EQ, 0}, + {BUFFER_SIZE, GTE, 1} +}; +static int numRequiredOverlayCriteria = sizeof(requiredOverlayCriteria) / sizeof(Criterion); +static int requiredOverlayCriteriaMask = +(1 << LEVEL) | (1 << TRANSPARENT) | (1 << XSTATICGRAY) | (1 << RGBA) | (1 << CI_MODE); + +#if !defined(_WIN32) +static int +checkOverlayAcceptability(XVisualInfo * vi, unsigned int mode) +{ + int value; + + /* Must support OpenGL. */ + glXGetConfig(__glutDisplay, vi, GLX_USE_GL, &value); + if (!value) + return 1; + + /* Must be color index. */ + glXGetConfig(__glutDisplay, vi, GLX_RGBA, &value); + if (value) + return 1; + + /* Must match single/double buffering request. */ + glXGetConfig(__glutDisplay, vi, GLX_DOUBLEBUFFER, &value); + if (GLUT_WIND_IS_DOUBLE(mode) != (value != 0)) + return 1; + + /* Must match mono/stereo request. */ + glXGetConfig(__glutDisplay, vi, GLX_STEREO, &value); + if (GLUT_WIND_IS_STEREO(mode) != (value != 0)) + return 1; + + /* Alpha and accumulation buffers incompatible with color + index. */ + if (GLUT_WIND_HAS_ALPHA(mode) || GLUT_WIND_HAS_ACCUM(mode)) + return 1; + + /* Look for depth buffer if requested. */ + glXGetConfig(__glutDisplay, vi, GLX_DEPTH_SIZE, &value); + if (GLUT_WIND_HAS_DEPTH(mode) && (value <= 0)) + return 1; + + /* Look for stencil buffer if requested. */ + glXGetConfig(__glutDisplay, vi, GLX_STENCIL_SIZE, &value); + if (GLUT_WIND_HAS_STENCIL(mode) && (value <= 0)) + return 1; + +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + /* XXX Multisampled overlay color index?? Pretty unlikely. */ + /* Look for multisampling if requested. */ + if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) + glXGetConfig(__glutDisplay, vi, GLX_SAMPLES_SGIS, &value); + else + value = 0; + if (GLUT_WIND_IS_MULTISAMPLE(mode) && (value <= 0)) + return 1; +#endif + + return 0; +} +#endif + +static XVisualInfo * +getOverlayVisualInfoCI(unsigned int mode) +{ +#if !defined(_WIN32) + XLayerVisualInfo *vi; + XLayerVisualInfo template; + XVisualInfo *goodVisual, *returnVisual; + int nitems, i, j, bad; + + /* The GLX 1.0 glXChooseVisual is does not permit queries + based on pixel transparency (and GLX_BUFFER_SIZE uses + "smallest that meets" its requirement instead of "largest + that meets" that GLUT wants. So, GLUT implements its own + visual selection routine for color index overlays. */ + + /* Try three overlay layers. */ + for (i = 1; i <= 3; i++) { + template.vinfo.screen = __glutScreen; + template.vinfo.class = PseudoColor; + template.layer = i; + template.type = TransparentPixel; + vi = __glutXGetLayerVisualInfo(__glutDisplay, + VisualTransparentType | VisualScreenMask | VisualClassMask | VisualLayerMask, + &template, &nitems); + if (vi) { + /* Check list for acceptable visual meeting requirements + of requested display mode. */ + for (j = 0; j < nitems; j++) { + bad = checkOverlayAcceptability(&vi[j].vinfo, mode); + if (bad) { + /* Set vi[j].vinfo.visual to mark it unacceptable. */ + vi[j].vinfo.visual = NULL; + } + } + + /* Look through list to find deepest acceptable visual. */ + goodVisual = NULL; + for (j = 0; j < nitems; j++) { + if (vi[j].vinfo.visual) { + if (goodVisual == NULL) { + goodVisual = &vi[j].vinfo; + } else { + if (goodVisual->depth < vi[j].vinfo.depth) { + goodVisual = &vi[j].vinfo; + } + } + } + } + + /* If a visual is found, clean up and return the visual. */ + if (goodVisual) { + returnVisual = (XVisualInfo *) malloc(sizeof(XVisualInfo)); + if (returnVisual) { + *returnVisual = *goodVisual; + } + XFree(vi); + return returnVisual; + } + XFree(vi); + } + } +#endif /* !_WIN32 */ + return NULL; +} + +/* ARGSUSED */ +static XVisualInfo * +getOverlayVisualInfoRGB(unsigned int mode) +{ + + /* XXX For now, transparent RGBA overlays are not supported + by GLUT. RGBA overlays raise difficult questions about + what the transparent pixel (really color) value should be. + + Color index overlay transparency is "easy" because the + transparent pixel value does not affect displayable colors + (except for stealing one color cell) since colors are + determined by indirection through a colormap, and because + it is uncommon for arbitrary pixel values in color index to + be "calculated" (as can occur with a host of RGBA operations + like lighting, blending, etc) so it is easy to avoid the + transparent pixel value. + + Since it is typically easy to avoid the transparent pixel + value in color index mode, if GLUT tells the programmer what + pixel is transparent, then most program can easily avoid + generating that pixel value except when they intend + transparency. GLUT returns whatever transparent pixel value + is provided by the system through glutGet( + GLUT_TRANSPARENT_INDEX). + + Theory versus practice for RGBA overlay transparency: In + theory, the reasonable thing is enabling overlay transparency + when an overlay pixel's destination alpha is 0 because this + allows overlay transparency to be controlled via alpha and all + visibile colors are permited, but no hardware I am aware of + supports this practice (and it requires destination alpha which + is typically optional and quite uncommon for overlay windows!). + + In practice, the choice of transparent pixel value is typically + "hardwired" into most graphics hardware to a single pixel value. + SGI hardware uses true black (0,0,0) without regard for the + destination alpha. This is far from ideal because true black (a + common color that is easy to accidently generate) can not be + generated in an RGBA overlay. I am not sure what other vendors + do. + + Pragmatically, most of the typical things you want to do in the + overlays can be done in color index (rubber banding, pop-up + menus, etc.). One solution for GLUT would be to simply + "advertise" what RGB triple (or possibly RGBA quadruple or simply + A alone) generates transparency. The problem with this approach + is that it forces programmers to avoid whatever arbitrary color + various systems decide is transparent. This is a difficult + burden to place on programmers that want to portably make use of + overlays. + + To actually support transparent RGBA overlays, there are really + two reaonsable options. ONE: Simply mandate that true black is + the RGBA overlay transparent color (what IRIS GL did). This is + nice for programmers since only one option, nice for existing SGI + hardware, bad for anyone (including SGI) who wants to improve + upon "true black" RGB transparency. + + Or TWO: Provide a set of queriable "transparency types" (like + "true black" or "alpha == 0" or "true white" or even a queriable + transparent color). This is harder for programmers, OK for + existing SGI hardware, and it leaves open the issue of what other + modes are reasonable. + + Option TWO seems the more general approach, but since hardware + designers will likely only implement a single mode (this is a + scan out issue where bandwidth is pressing issue), codifying + multiple speculative approaches nobody may ever implement seems + silly. And option ONE fiats a suboptimal solution. + + Therefore, I defer any decision of how GLUT should support RGBA + overlay transparency and leave support for it unimplemented. + Nobody has been pressing me for RGBA overlay transparency (though + people have requested color index overlay transparency + repeatedly). Geez, if you read this far you are either really + bored or maybe actually interested in this topic. Anyway, if + you have ideas (particularly if you plan on implementing a + hardware scheme for RGBA overlay transparency), I'd be + interested. + + For the record, SGI's expiremental Framebufer Configuration + experimental GLX extension uses option TWO. Transparency modes + for "none" and "RGB" are defined (others could be defined later). + What RGB value is the transparent one must be queried. + + I was hoping GLUT could have something that required less work + from the programmer to use portably. -mjk */ + + __glutWarning("RGBA overlays are not supported by GLUT (for now)."); + return NULL; +} + +static XVisualInfo * +getOverlayVisualInfo(unsigned int mode) +{ + /* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */ + if (GLUT_WIND_IS_LUMINANCE(mode)) + return NULL; + + if (GLUT_WIND_IS_RGB(mode)) + return getOverlayVisualInfoRGB(mode); + else + return getOverlayVisualInfoCI(mode); +} + +#if !defined(_WIN32) + +/* The GLUT overlay can come and go, and the overlay window has + a distinct X window ID. Logically though, GLUT treats the + normal and overlay windows as a unified window. In + particular, X input events typically go to the overlay window + since it is "on top of" the normal window. When an overlay + window ID is destroyed (due to glutRemoveOverlay or a call to + glutEstablishOverlay when an overlay already exists), we + still keep track of the overlay window ID until we get back a + DestroyNotify event for the overlay window. Otherwise, we + could lose track of X input events sent to a destroyed + overlay. To avoid this, we keep the destroyed overlay window + ID on a "stale window" list. This lets us properly route X + input events generated on destroyed overlay windows to the + proper GLUT window. */ +static void +addStaleWindow(GLUTwindow * window, Window win) +{ + GLUTstale *entry; + + entry = (GLUTstale *) malloc(sizeof(GLUTstale)); + if (!entry) + __glutFatalError("out of memory"); + entry->window = window; + entry->win = win; + entry->next = __glutStaleWindowList; + __glutStaleWindowList = entry; +} + +#endif + +void +__glutFreeOverlay(GLUToverlay * overlay) +{ + if (overlay->visAlloced) + XFree(overlay->vis); + XDestroyWindow(__glutDisplay, overlay->win); + glXDestroyContext(__glutDisplay, overlay->ctx); + if (overlay->colormap) { + /* Only color index overlays have colormap data structure. */ + __glutFreeColormap(overlay->colormap); + } + free(overlay); +} + +static XVisualInfo * +determineOverlayVisual(int *treatAsSingle, Bool * visAlloced, void **fbc) +{ + if (__glutDisplayString) { + XVisualInfo *vi; + int i; + + /* __glutDisplayString should be NULL except if + glutInitDisplayString has been called to register a + different display string. Calling glutInitDisplayString + means using a string instead of an integer mask determine + + the visual to use. Using the function pointer variable + __glutDetermineVisualFromString below avoids linking in + the code for implementing glutInitDisplayString (ie, + glut_dstr.o) unless glutInitDisplayString gets called by + the application. */ + + assert(__glutDetermineVisualFromString); + + /* Try three overlay layers. */ + *visAlloced = False; + *fbc = NULL; + for (i = 1; i <= 3; i++) { + requiredOverlayCriteria[0].value = i; + vi = __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle, + requiredOverlayCriteria, numRequiredOverlayCriteria, + requiredOverlayCriteriaMask, fbc); + if (vi) { + return vi; + } + } + return NULL; + } else { + *visAlloced = True; + *fbc = NULL; + return __glutDetermineVisual(__glutDisplayMode, + treatAsSingle, getOverlayVisualInfo); + } +} + +/* CENTRY */ +void APIENTRY +glutEstablishOverlay(void) +{ + GLUToverlay *overlay; + GLUTwindow *window; + XSetWindowAttributes wa; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + GLXFBConfigSGIX fbc; +#else + void *fbc; +#endif + + /* Register a routine to free an overlay with glut_win.c; + this keeps glut_win.c from pulling in all of + glut_overlay.c when no overlay functionality is used by + the application. */ + __glutFreeOverlayFunc = __glutFreeOverlay; + + window = __glutCurrentWindow; + + /* Allow for an existant overlay to be re-established perhaps + if you wanted a different display mode. */ + if (window->overlay) { +#if !defined(_WIN32) + addStaleWindow(window, window->overlay->win); +#endif + __glutFreeOverlay(window->overlay); + } + overlay = (GLUToverlay *) malloc(sizeof(GLUToverlay)); + if (!overlay) + __glutFatalError("out of memory."); + + overlay->vis = determineOverlayVisual(&overlay->treatAsSingle, + &overlay->visAlloced, (void **) &fbc); + if (!overlay->vis) { + __glutFatalError("lacks overlay support."); + } +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + if (fbc) { + window->ctx = glXCreateContextWithConfigSGIX(__glutDisplay, fbc, + GLX_RGBA_TYPE_SGIX, None, __glutTryDirect); + } else +#endif + { + overlay->ctx = glXCreateContext(__glutDisplay, overlay->vis, + None, __glutTryDirect); + } + if (!overlay->ctx) { + __glutFatalError( + "failed to create overlay OpenGL rendering context."); + } +#if !defined(_WIN32) + overlay->isDirect = glXIsDirect(__glutDisplay, overlay->ctx); + if (__glutForceDirect) { + if (!overlay->isDirect) { + __glutFatalError("direct rendering not possible."); + } + } +#endif + __glutSetupColormap(overlay->vis, &overlay->colormap, &overlay->cmap); + overlay->transparentPixel = __glutGetTransparentPixel(__glutDisplay, + overlay->vis); + wa.colormap = overlay->cmap; + wa.background_pixel = overlay->transparentPixel; + wa.event_mask = window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK; + wa.border_pixel = 0; +#if defined(_WIN32) + /* XXX Overlays not supported in Win32 yet. */ +#else + overlay->win = XCreateWindow(__glutDisplay, + window->win, + 0, 0, window->width, window->height, 0, + overlay->vis->depth, InputOutput, overlay->vis->visual, + CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, + &wa); +#endif + if (window->children) { + /* Overlay window must be lowered below any GLUT + subwindows. */ + XLowerWindow(__glutDisplay, overlay->win); + } + XMapWindow(__glutDisplay, overlay->win); + overlay->shownState = 1; + + overlay->display = NULL; + + /* Make sure a reshape gets delivered. */ + window->forceReshape = True; + +#if !defined(_WIN32) + __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK); +#endif + + window->overlay = overlay; + glutUseLayer(GLUT_OVERLAY); + + if (overlay->treatAsSingle) { + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } +} + +void APIENTRY +glutRemoveOverlay(void) +{ + GLUTwindow *window = __glutCurrentWindow; + GLUToverlay *overlay = __glutCurrentWindow->overlay; + + if (!window->overlay) + return; + + /* If using overlay, switch to the normal layer. */ + if (window->renderWin == overlay->win) { + glutUseLayer(GLUT_NORMAL); + } +#if !defined(_WIN32) + addStaleWindow(window, overlay->win); +#endif + __glutFreeOverlay(overlay); + window->overlay = NULL; +#if !defined(_WIN32) + __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK); +#endif +} + +void APIENTRY +glutUseLayer(GLenum layer) +{ + GLUTwindow *window = __glutCurrentWindow; + + switch (layer) { + case GLUT_NORMAL: +#ifdef _WIN32 + window->renderDc = window->hdc; +#endif + window->renderWin = window->win; + window->renderCtx = window->ctx; + break; + case GLUT_OVERLAY: + /* Did you crash here? Calling glutUseLayer(GLUT_OVERLAY) + without an overlay established is erroneous. Fix your + code. */ +#ifdef _WIN32 + window->renderDc = window->overlay->hdc; +#endif + window->renderWin = window->overlay->win; + window->renderCtx = window->overlay->ctx; + break; + default: + __glutWarning("glutUseLayer: unknown layer, %d.", layer); + break; + } + __glutSetWindow(window); +} + +void APIENTRY +glutPostOverlayRedisplay(void) +{ + __glutPostRedisplay(__glutCurrentWindow, GLUT_OVERLAY_REDISPLAY_WORK); +} + +/* The advantage of this routine is that it saves the cost of a + glutSetWindow call (entailing an expensive OpenGL context + switch), particularly useful when multiple windows need + redisplays posted at the same times. */ +void APIENTRY +glutPostWindowOverlayRedisplay(int win) +{ + __glutPostRedisplay(__glutWindowList[win - 1], GLUT_OVERLAY_REDISPLAY_WORK); +} + +void APIENTRY +glutOverlayDisplayFunc(GLUTdisplayCB displayFunc) +{ + if (!__glutCurrentWindow->overlay) { + __glutWarning("glutOverlayDisplayFunc: window has no overlay established"); + return; + } + __glutCurrentWindow->overlay->display = displayFunc; +} + +void APIENTRY +glutHideOverlay(void) +{ + if (!__glutCurrentWindow->overlay) { + __glutWarning("glutHideOverlay: window has no overlay established"); + return; + } + XUnmapWindow(__glutDisplay, __glutCurrentWindow->overlay->win); + __glutCurrentWindow->overlay->shownState = 0; +} + +void APIENTRY +glutShowOverlay(void) +{ + if (!__glutCurrentWindow->overlay) { + __glutWarning("glutShowOverlay: window has no overlay established"); + return; + } + XMapWindow(__glutDisplay, __glutCurrentWindow->overlay->win); + __glutCurrentWindow->overlay->shownState = 1; +} + +int APIENTRY +glutLayerGet(GLenum param) +{ + switch (param) { + case GLUT_OVERLAY_POSSIBLE: + { + XVisualInfo *vi; + Bool dummy, visAlloced; + void *fbc; + + vi = determineOverlayVisual(&dummy, &visAlloced, &fbc); + if (vi) { + if (visAlloced) + XFree(vi); + return 1; + } + return 0; + } + case GLUT_LAYER_IN_USE: + return __glutCurrentWindow->renderWin != __glutCurrentWindow->win; + case GLUT_HAS_OVERLAY: + return __glutCurrentWindow->overlay != NULL; + case GLUT_TRANSPARENT_INDEX: + if (__glutCurrentWindow->overlay) { + return __glutCurrentWindow->overlay->transparentPixel; + } else { + return -1; + } + case GLUT_NORMAL_DAMAGED: + /* __glutWindowDamaged is used so the damage state within + the window (or overlay belwo) can be cleared before + calling a display callback so on return, the state does + not have to be cleared (since upon return from the + callback the window could be destroyed (or layer + removed). */ + return (__glutCurrentWindow->workMask & GLUT_REPAIR_WORK) + || __glutWindowDamaged; + case GLUT_OVERLAY_DAMAGED: + if (__glutCurrentWindow->overlay) { + return (__glutCurrentWindow->workMask & GLUT_OVERLAY_REPAIR_WORK) + || __glutWindowDamaged; + } else { + return -1; + } + default: + __glutWarning("invalid glutLayerGet param: %d", param); + return -1; + } +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_roman.c b/lib/glut-3.7.6/lib/glut/glut_roman.c new file mode 100644 index 0000000000..8e25de8ac1 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_roman.c @@ -0,0 +1,2451 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#include "glutstroke.h" + +/* char: 33 '!' */ + +static const CoordRec char33_stroke0[] = { + { 13.3819, 100 }, + { 13.3819, 33.3333 }, +}; + +static const CoordRec char33_stroke1[] = { + { 13.3819, 9.5238 }, + { 8.62, 4.7619 }, + { 13.3819, 0 }, + { 18.1438, 4.7619 }, + { 13.3819, 9.5238 }, +}; + +static const StrokeRec char33[] = { + { 2, char33_stroke0 }, + { 5, char33_stroke1 }, +}; + +/* char: 34 '"' */ + +static const CoordRec char34_stroke0[] = { + { 4.02, 100 }, + { 4.02, 66.6667 }, +}; + +static const CoordRec char34_stroke1[] = { + { 42.1152, 100 }, + { 42.1152, 66.6667 }, +}; + +static const StrokeRec char34[] = { + { 2, char34_stroke0 }, + { 2, char34_stroke1 }, +}; + +/* char: 35 '#' */ + +static const CoordRec char35_stroke0[] = { + { 41.2952, 119.048 }, + { 7.9619, -33.3333 }, +}; + +static const CoordRec char35_stroke1[] = { + { 69.8667, 119.048 }, + { 36.5333, -33.3333 }, +}; + +static const CoordRec char35_stroke2[] = { + { 7.9619, 57.1429 }, + { 74.6286, 57.1429 }, +}; + +static const CoordRec char35_stroke3[] = { + { 3.2, 28.5714 }, + { 69.8667, 28.5714 }, +}; + +static const StrokeRec char35[] = { + { 2, char35_stroke0 }, + { 2, char35_stroke1 }, + { 2, char35_stroke2 }, + { 2, char35_stroke3 }, +}; + +/* char: 36 '$' */ + +static const CoordRec char36_stroke0[] = { + { 28.6295, 119.048 }, + { 28.6295, -19.0476 }, +}; + +static const CoordRec char36_stroke1[] = { + { 47.6771, 119.048 }, + { 47.6771, -19.0476 }, +}; + +static const CoordRec char36_stroke2[] = { + { 71.4867, 85.7143 }, + { 61.9629, 95.2381 }, + { 47.6771, 100 }, + { 28.6295, 100 }, + { 14.3438, 95.2381 }, + { 4.82, 85.7143 }, + { 4.82, 76.1905 }, + { 9.5819, 66.6667 }, + { 14.3438, 61.9048 }, + { 23.8676, 57.1429 }, + { 52.439, 47.619 }, + { 61.9629, 42.8571 }, + { 66.7248, 38.0952 }, + { 71.4867, 28.5714 }, + { 71.4867, 14.2857 }, + { 61.9629, 4.7619 }, + { 47.6771, 0 }, + { 28.6295, 0 }, + { 14.3438, 4.7619 }, + { 4.82, 14.2857 }, +}; + +static const StrokeRec char36[] = { + { 2, char36_stroke0 }, + { 2, char36_stroke1 }, + { 20, char36_stroke2 }, +}; + +/* char: 37 '%' */ + +static const CoordRec char37_stroke0[] = { + { 92.0743, 100 }, + { 6.36, 0 }, +}; + +static const CoordRec char37_stroke1[] = { + { 30.1695, 100 }, + { 39.6933, 90.4762 }, + { 39.6933, 80.9524 }, + { 34.9314, 71.4286 }, + { 25.4076, 66.6667 }, + { 15.8838, 66.6667 }, + { 6.36, 76.1905 }, + { 6.36, 85.7143 }, + { 11.1219, 95.2381 }, + { 20.6457, 100 }, + { 30.1695, 100 }, + { 39.6933, 95.2381 }, + { 53.979, 90.4762 }, + { 68.2648, 90.4762 }, + { 82.5505, 95.2381 }, + { 92.0743, 100 }, +}; + +static const CoordRec char37_stroke2[] = { + { 73.0267, 33.3333 }, + { 63.5029, 28.5714 }, + { 58.741, 19.0476 }, + { 58.741, 9.5238 }, + { 68.2648, 0 }, + { 77.7886, 0 }, + { 87.3124, 4.7619 }, + { 92.0743, 14.2857 }, + { 92.0743, 23.8095 }, + { 82.5505, 33.3333 }, + { 73.0267, 33.3333 }, +}; + +static const StrokeRec char37[] = { + { 2, char37_stroke0 }, + { 16, char37_stroke1 }, + { 11, char37_stroke2 }, +}; + +/* char: 38 '&' */ + +static const CoordRec char38_stroke0[] = { + { 101.218, 57.1429 }, + { 101.218, 61.9048 }, + { 96.4562, 66.6667 }, + { 91.6943, 66.6667 }, + { 86.9324, 61.9048 }, + { 82.1705, 52.381 }, + { 72.6467, 28.5714 }, + { 63.1229, 14.2857 }, + { 53.599, 4.7619 }, + { 44.0752, 0 }, + { 25.0276, 0 }, + { 15.5038, 4.7619 }, + { 10.7419, 9.5238 }, + { 5.98, 19.0476 }, + { 5.98, 28.5714 }, + { 10.7419, 38.0952 }, + { 15.5038, 42.8571 }, + { 48.8371, 61.9048 }, + { 53.599, 66.6667 }, + { 58.361, 76.1905 }, + { 58.361, 85.7143 }, + { 53.599, 95.2381 }, + { 44.0752, 100 }, + { 34.5514, 95.2381 }, + { 29.7895, 85.7143 }, + { 29.7895, 76.1905 }, + { 34.5514, 61.9048 }, + { 44.0752, 47.619 }, + { 67.8848, 14.2857 }, + { 77.4086, 4.7619 }, + { 86.9324, 0 }, + { 96.4562, 0 }, + { 101.218, 4.7619 }, + { 101.218, 9.5238 }, +}; + +static const StrokeRec char38[] = { + { 34, char38_stroke0 }, +}; + +/* char: 39 ''' */ + +static const CoordRec char39_stroke0[] = { + { 4.44, 100 }, + { 4.44, 66.6667 }, +}; + +static const StrokeRec char39[] = { + { 2, char39_stroke0 }, +}; + +/* char: 40 '(' */ + +static const CoordRec char40_stroke0[] = { + { 40.9133, 119.048 }, + { 31.3895, 109.524 }, + { 21.8657, 95.2381 }, + { 12.3419, 76.1905 }, + { 7.58, 52.381 }, + { 7.58, 33.3333 }, + { 12.3419, 9.5238 }, + { 21.8657, -9.5238 }, + { 31.3895, -23.8095 }, + { 40.9133, -33.3333 }, +}; + +static const StrokeRec char40[] = { + { 10, char40_stroke0 }, +}; + +/* char: 41 ')' */ + +static const CoordRec char41_stroke0[] = { + { 5.28, 119.048 }, + { 14.8038, 109.524 }, + { 24.3276, 95.2381 }, + { 33.8514, 76.1905 }, + { 38.6133, 52.381 }, + { 38.6133, 33.3333 }, + { 33.8514, 9.5238 }, + { 24.3276, -9.5238 }, + { 14.8038, -23.8095 }, + { 5.28, -33.3333 }, +}; + +static const StrokeRec char41[] = { + { 10, char41_stroke0 }, +}; + +/* char: 42 '*' */ + +static const CoordRec char42_stroke0[] = { + { 30.7695, 71.4286 }, + { 30.7695, 14.2857 }, +}; + +static const CoordRec char42_stroke1[] = { + { 6.96, 57.1429 }, + { 54.579, 28.5714 }, +}; + +static const CoordRec char42_stroke2[] = { + { 54.579, 57.1429 }, + { 6.96, 28.5714 }, +}; + +static const StrokeRec char42[] = { + { 2, char42_stroke0 }, + { 2, char42_stroke1 }, + { 2, char42_stroke2 }, +}; + +/* char: 43 '+' */ + +static const CoordRec char43_stroke0[] = { + { 48.8371, 85.7143 }, + { 48.8371, 0 }, +}; + +static const CoordRec char43_stroke1[] = { + { 5.98, 42.8571 }, + { 91.6943, 42.8571 }, +}; + +static const StrokeRec char43[] = { + { 2, char43_stroke0 }, + { 2, char43_stroke1 }, +}; + +/* char: 44 ',' */ + +static const CoordRec char44_stroke0[] = { + { 18.2838, 4.7619 }, + { 13.5219, 0 }, + { 8.76, 4.7619 }, + { 13.5219, 9.5238 }, + { 18.2838, 4.7619 }, + { 18.2838, -4.7619 }, + { 13.5219, -14.2857 }, + { 8.76, -19.0476 }, +}; + +static const StrokeRec char44[] = { + { 8, char44_stroke0 }, +}; + +/* char: 45 '-' */ + +static const CoordRec char45_stroke0[] = { + { 7.38, 42.8571 }, + { 93.0943, 42.8571 }, +}; + +static const StrokeRec char45[] = { + { 2, char45_stroke0 }, +}; + +/* char: 46 '.' */ + +static const CoordRec char46_stroke0[] = { + { 13.1019, 9.5238 }, + { 8.34, 4.7619 }, + { 13.1019, 0 }, + { 17.8638, 4.7619 }, + { 13.1019, 9.5238 }, +}; + +static const StrokeRec char46[] = { + { 5, char46_stroke0 }, +}; + +/* char: 47 '/' */ + +static const CoordRec char47_stroke0[] = { + { 7.24, -14.2857 }, + { 73.9067, 100 }, +}; + +static const StrokeRec char47[] = { + { 2, char47_stroke0 }, +}; + +/* char: 48 '0' */ + +static const CoordRec char48_stroke0[] = { + { 33.5514, 100 }, + { 19.2657, 95.2381 }, + { 9.7419, 80.9524 }, + { 4.98, 57.1429 }, + { 4.98, 42.8571 }, + { 9.7419, 19.0476 }, + { 19.2657, 4.7619 }, + { 33.5514, 0 }, + { 43.0752, 0 }, + { 57.361, 4.7619 }, + { 66.8848, 19.0476 }, + { 71.6467, 42.8571 }, + { 71.6467, 57.1429 }, + { 66.8848, 80.9524 }, + { 57.361, 95.2381 }, + { 43.0752, 100 }, + { 33.5514, 100 }, +}; + +static const StrokeRec char48[] = { + { 17, char48_stroke0 }, +}; + +/* char: 49 '1' */ + +static const CoordRec char49_stroke0[] = { + { 11.82, 80.9524 }, + { 21.3438, 85.7143 }, + { 35.6295, 100 }, + { 35.6295, 0 }, +}; + +static const StrokeRec char49[] = { + { 4, char49_stroke0 }, +}; + +/* char: 50 '2' */ + +static const CoordRec char50_stroke0[] = { + { 10.1819, 76.1905 }, + { 10.1819, 80.9524 }, + { 14.9438, 90.4762 }, + { 19.7057, 95.2381 }, + { 29.2295, 100 }, + { 48.2771, 100 }, + { 57.801, 95.2381 }, + { 62.5629, 90.4762 }, + { 67.3248, 80.9524 }, + { 67.3248, 71.4286 }, + { 62.5629, 61.9048 }, + { 53.039, 47.619 }, + { 5.42, 0 }, + { 72.0867, 0 }, +}; + +static const StrokeRec char50[] = { + { 14, char50_stroke0 }, +}; + +/* char: 51 '3' */ + +static const CoordRec char51_stroke0[] = { + { 14.5238, 100 }, + { 66.9048, 100 }, + { 38.3333, 61.9048 }, + { 52.619, 61.9048 }, + { 62.1429, 57.1429 }, + { 66.9048, 52.381 }, + { 71.6667, 38.0952 }, + { 71.6667, 28.5714 }, + { 66.9048, 14.2857 }, + { 57.381, 4.7619 }, + { 43.0952, 0 }, + { 28.8095, 0 }, + { 14.5238, 4.7619 }, + { 9.7619, 9.5238 }, + { 5, 19.0476 }, +}; + +static const StrokeRec char51[] = { + { 15, char51_stroke0 }, +}; + +/* char: 52 '4' */ + +static const CoordRec char52_stroke0[] = { + { 51.499, 100 }, + { 3.88, 33.3333 }, + { 75.3086, 33.3333 }, +}; + +static const CoordRec char52_stroke1[] = { + { 51.499, 100 }, + { 51.499, 0 }, +}; + +static const StrokeRec char52[] = { + { 3, char52_stroke0 }, + { 2, char52_stroke1 }, +}; + +/* char: 53 '5' */ + +static const CoordRec char53_stroke0[] = { + { 62.0029, 100 }, + { 14.3838, 100 }, + { 9.6219, 57.1429 }, + { 14.3838, 61.9048 }, + { 28.6695, 66.6667 }, + { 42.9552, 66.6667 }, + { 57.241, 61.9048 }, + { 66.7648, 52.381 }, + { 71.5267, 38.0952 }, + { 71.5267, 28.5714 }, + { 66.7648, 14.2857 }, + { 57.241, 4.7619 }, + { 42.9552, 0 }, + { 28.6695, 0 }, + { 14.3838, 4.7619 }, + { 9.6219, 9.5238 }, + { 4.86, 19.0476 }, +}; + +static const StrokeRec char53[] = { + { 17, char53_stroke0 }, +}; + +/* char: 54 '6' */ + +static const CoordRec char54_stroke0[] = { + { 62.7229, 85.7143 }, + { 57.961, 95.2381 }, + { 43.6752, 100 }, + { 34.1514, 100 }, + { 19.8657, 95.2381 }, + { 10.3419, 80.9524 }, + { 5.58, 57.1429 }, + { 5.58, 33.3333 }, + { 10.3419, 14.2857 }, + { 19.8657, 4.7619 }, + { 34.1514, 0 }, + { 38.9133, 0 }, + { 53.199, 4.7619 }, + { 62.7229, 14.2857 }, + { 67.4848, 28.5714 }, + { 67.4848, 33.3333 }, + { 62.7229, 47.619 }, + { 53.199, 57.1429 }, + { 38.9133, 61.9048 }, + { 34.1514, 61.9048 }, + { 19.8657, 57.1429 }, + { 10.3419, 47.619 }, + { 5.58, 33.3333 }, +}; + +static const StrokeRec char54[] = { + { 23, char54_stroke0 }, +}; + +/* char: 55 '7' */ + +static const CoordRec char55_stroke0[] = { + { 72.2267, 100 }, + { 24.6076, 0 }, +}; + +static const CoordRec char55_stroke1[] = { + { 5.56, 100 }, + { 72.2267, 100 }, +}; + +static const StrokeRec char55[] = { + { 2, char55_stroke0 }, + { 2, char55_stroke1 }, +}; + +/* char: 56 '8' */ + +static const CoordRec char56_stroke0[] = { + { 29.4095, 100 }, + { 15.1238, 95.2381 }, + { 10.3619, 85.7143 }, + { 10.3619, 76.1905 }, + { 15.1238, 66.6667 }, + { 24.6476, 61.9048 }, + { 43.6952, 57.1429 }, + { 57.981, 52.381 }, + { 67.5048, 42.8571 }, + { 72.2667, 33.3333 }, + { 72.2667, 19.0476 }, + { 67.5048, 9.5238 }, + { 62.7429, 4.7619 }, + { 48.4571, 0 }, + { 29.4095, 0 }, + { 15.1238, 4.7619 }, + { 10.3619, 9.5238 }, + { 5.6, 19.0476 }, + { 5.6, 33.3333 }, + { 10.3619, 42.8571 }, + { 19.8857, 52.381 }, + { 34.1714, 57.1429 }, + { 53.219, 61.9048 }, + { 62.7429, 66.6667 }, + { 67.5048, 76.1905 }, + { 67.5048, 85.7143 }, + { 62.7429, 95.2381 }, + { 48.4571, 100 }, + { 29.4095, 100 }, +}; + +static const StrokeRec char56[] = { + { 29, char56_stroke0 }, +}; + +/* char: 57 '9' */ + +static const CoordRec char57_stroke0[] = { + { 68.5048, 66.6667 }, + { 63.7429, 52.381 }, + { 54.219, 42.8571 }, + { 39.9333, 38.0952 }, + { 35.1714, 38.0952 }, + { 20.8857, 42.8571 }, + { 11.3619, 52.381 }, + { 6.6, 66.6667 }, + { 6.6, 71.4286 }, + { 11.3619, 85.7143 }, + { 20.8857, 95.2381 }, + { 35.1714, 100 }, + { 39.9333, 100 }, + { 54.219, 95.2381 }, + { 63.7429, 85.7143 }, + { 68.5048, 66.6667 }, + { 68.5048, 42.8571 }, + { 63.7429, 19.0476 }, + { 54.219, 4.7619 }, + { 39.9333, 0 }, + { 30.4095, 0 }, + { 16.1238, 4.7619 }, + { 11.3619, 14.2857 }, +}; + +static const StrokeRec char57[] = { + { 23, char57_stroke0 }, +}; + +/* char: 58 ':' */ + +static const CoordRec char58_stroke0[] = { + { 14.0819, 66.6667 }, + { 9.32, 61.9048 }, + { 14.0819, 57.1429 }, + { 18.8438, 61.9048 }, + { 14.0819, 66.6667 }, +}; + +static const CoordRec char58_stroke1[] = { + { 14.0819, 9.5238 }, + { 9.32, 4.7619 }, + { 14.0819, 0 }, + { 18.8438, 4.7619 }, + { 14.0819, 9.5238 }, +}; + +static const StrokeRec char58[] = { + { 5, char58_stroke0 }, + { 5, char58_stroke1 }, +}; + +/* char: 59 ';' */ + +static const CoordRec char59_stroke0[] = { + { 12.9619, 66.6667 }, + { 8.2, 61.9048 }, + { 12.9619, 57.1429 }, + { 17.7238, 61.9048 }, + { 12.9619, 66.6667 }, +}; + +static const CoordRec char59_stroke1[] = { + { 17.7238, 4.7619 }, + { 12.9619, 0 }, + { 8.2, 4.7619 }, + { 12.9619, 9.5238 }, + { 17.7238, 4.7619 }, + { 17.7238, -4.7619 }, + { 12.9619, -14.2857 }, + { 8.2, -19.0476 }, +}; + +static const StrokeRec char59[] = { + { 5, char59_stroke0 }, + { 8, char59_stroke1 }, +}; + +/* char: 60 '<' */ + +static const CoordRec char60_stroke0[] = { + { 79.2505, 85.7143 }, + { 3.06, 42.8571 }, + { 79.2505, 0 }, +}; + +static const StrokeRec char60[] = { + { 3, char60_stroke0 }, +}; + +/* char: 61 '=' */ + +static const CoordRec char61_stroke0[] = { + { 5.7, 57.1429 }, + { 91.4143, 57.1429 }, +}; + +static const CoordRec char61_stroke1[] = { + { 5.7, 28.5714 }, + { 91.4143, 28.5714 }, +}; + +static const StrokeRec char61[] = { + { 2, char61_stroke0 }, + { 2, char61_stroke1 }, +}; + +/* char: 62 '>' */ + +static const CoordRec char62_stroke0[] = { + { 2.78, 85.7143 }, + { 78.9705, 42.8571 }, + { 2.78, 0 }, +}; + +static const StrokeRec char62[] = { + { 3, char62_stroke0 }, +}; + +/* char: 63 '?' */ + +static const CoordRec char63_stroke0[] = { + { 8.42, 76.1905 }, + { 8.42, 80.9524 }, + { 13.1819, 90.4762 }, + { 17.9438, 95.2381 }, + { 27.4676, 100 }, + { 46.5152, 100 }, + { 56.039, 95.2381 }, + { 60.801, 90.4762 }, + { 65.5629, 80.9524 }, + { 65.5629, 71.4286 }, + { 60.801, 61.9048 }, + { 56.039, 57.1429 }, + { 36.9914, 47.619 }, + { 36.9914, 33.3333 }, +}; + +static const CoordRec char63_stroke1[] = { + { 36.9914, 9.5238 }, + { 32.2295, 4.7619 }, + { 36.9914, 0 }, + { 41.7533, 4.7619 }, + { 36.9914, 9.5238 }, +}; + +static const StrokeRec char63[] = { + { 14, char63_stroke0 }, + { 5, char63_stroke1 }, +}; + +/* char: 64 '@' */ + +static const CoordRec char64_stroke0[] = { + { 49.2171, 52.381 }, + { 39.6933, 57.1429 }, + { 30.1695, 57.1429 }, + { 25.4076, 47.619 }, + { 25.4076, 42.8571 }, + { 30.1695, 33.3333 }, + { 39.6933, 33.3333 }, + { 49.2171, 38.0952 }, +}; + +static const CoordRec char64_stroke1[] = { + { 49.2171, 57.1429 }, + { 49.2171, 38.0952 }, + { 53.979, 33.3333 }, + { 63.5029, 33.3333 }, + { 68.2648, 42.8571 }, + { 68.2648, 47.619 }, + { 63.5029, 61.9048 }, + { 53.979, 71.4286 }, + { 39.6933, 76.1905 }, + { 34.9314, 76.1905 }, + { 20.6457, 71.4286 }, + { 11.1219, 61.9048 }, + { 6.36, 47.619 }, + { 6.36, 42.8571 }, + { 11.1219, 28.5714 }, + { 20.6457, 19.0476 }, + { 34.9314, 14.2857 }, + { 39.6933, 14.2857 }, + { 53.979, 19.0476 }, +}; + +static const StrokeRec char64[] = { + { 8, char64_stroke0 }, + { 19, char64_stroke1 }, +}; + +/* char: 65 'A' */ + +static const CoordRec char65_stroke0[] = { + { 40.5952, 100 }, + { 2.5, 0 }, +}; + +static const CoordRec char65_stroke1[] = { + { 40.5952, 100 }, + { 78.6905, 0 }, +}; + +static const CoordRec char65_stroke2[] = { + { 16.7857, 33.3333 }, + { 64.4048, 33.3333 }, +}; + +static const StrokeRec char65[] = { + { 2, char65_stroke0 }, + { 2, char65_stroke1 }, + { 2, char65_stroke2 }, +}; + +/* char: 66 'B' */ + +static const CoordRec char66_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char66_stroke1[] = { + { 11.42, 100 }, + { 54.2771, 100 }, + { 68.5629, 95.2381 }, + { 73.3248, 90.4762 }, + { 78.0867, 80.9524 }, + { 78.0867, 71.4286 }, + { 73.3248, 61.9048 }, + { 68.5629, 57.1429 }, + { 54.2771, 52.381 }, +}; + +static const CoordRec char66_stroke2[] = { + { 11.42, 52.381 }, + { 54.2771, 52.381 }, + { 68.5629, 47.619 }, + { 73.3248, 42.8571 }, + { 78.0867, 33.3333 }, + { 78.0867, 19.0476 }, + { 73.3248, 9.5238 }, + { 68.5629, 4.7619 }, + { 54.2771, 0 }, + { 11.42, 0 }, +}; + +static const StrokeRec char66[] = { + { 2, char66_stroke0 }, + { 9, char66_stroke1 }, + { 10, char66_stroke2 }, +}; + +/* char: 67 'C' */ + +static const CoordRec char67_stroke0[] = { + { 78.0886, 76.1905 }, + { 73.3267, 85.7143 }, + { 63.8029, 95.2381 }, + { 54.279, 100 }, + { 35.2314, 100 }, + { 25.7076, 95.2381 }, + { 16.1838, 85.7143 }, + { 11.4219, 76.1905 }, + { 6.66, 61.9048 }, + { 6.66, 38.0952 }, + { 11.4219, 23.8095 }, + { 16.1838, 14.2857 }, + { 25.7076, 4.7619 }, + { 35.2314, 0 }, + { 54.279, 0 }, + { 63.8029, 4.7619 }, + { 73.3267, 14.2857 }, + { 78.0886, 23.8095 }, +}; + +static const StrokeRec char67[] = { + { 18, char67_stroke0 }, +}; + +/* char: 68 'D' */ + +static const CoordRec char68_stroke0[] = { + { 11.96, 100 }, + { 11.96, 0 }, +}; + +static const CoordRec char68_stroke1[] = { + { 11.96, 100 }, + { 45.2933, 100 }, + { 59.579, 95.2381 }, + { 69.1029, 85.7143 }, + { 73.8648, 76.1905 }, + { 78.6267, 61.9048 }, + { 78.6267, 38.0952 }, + { 73.8648, 23.8095 }, + { 69.1029, 14.2857 }, + { 59.579, 4.7619 }, + { 45.2933, 0 }, + { 11.96, 0 }, +}; + +static const StrokeRec char68[] = { + { 2, char68_stroke0 }, + { 12, char68_stroke1 }, +}; + +/* char: 69 'E' */ + +static const CoordRec char69_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char69_stroke1[] = { + { 11.42, 100 }, + { 73.3248, 100 }, +}; + +static const CoordRec char69_stroke2[] = { + { 11.42, 52.381 }, + { 49.5152, 52.381 }, +}; + +static const CoordRec char69_stroke3[] = { + { 11.42, 0 }, + { 73.3248, 0 }, +}; + +static const StrokeRec char69[] = { + { 2, char69_stroke0 }, + { 2, char69_stroke1 }, + { 2, char69_stroke2 }, + { 2, char69_stroke3 }, +}; + +/* char: 70 'F' */ + +static const CoordRec char70_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char70_stroke1[] = { + { 11.42, 100 }, + { 73.3248, 100 }, +}; + +static const CoordRec char70_stroke2[] = { + { 11.42, 52.381 }, + { 49.5152, 52.381 }, +}; + +static const StrokeRec char70[] = { + { 2, char70_stroke0 }, + { 2, char70_stroke1 }, + { 2, char70_stroke2 }, +}; + +/* char: 71 'G' */ + +static const CoordRec char71_stroke0[] = { + { 78.4886, 76.1905 }, + { 73.7267, 85.7143 }, + { 64.2029, 95.2381 }, + { 54.679, 100 }, + { 35.6314, 100 }, + { 26.1076, 95.2381 }, + { 16.5838, 85.7143 }, + { 11.8219, 76.1905 }, + { 7.06, 61.9048 }, + { 7.06, 38.0952 }, + { 11.8219, 23.8095 }, + { 16.5838, 14.2857 }, + { 26.1076, 4.7619 }, + { 35.6314, 0 }, + { 54.679, 0 }, + { 64.2029, 4.7619 }, + { 73.7267, 14.2857 }, + { 78.4886, 23.8095 }, + { 78.4886, 38.0952 }, +}; + +static const CoordRec char71_stroke1[] = { + { 54.679, 38.0952 }, + { 78.4886, 38.0952 }, +}; + +static const StrokeRec char71[] = { + { 19, char71_stroke0 }, + { 2, char71_stroke1 }, +}; + +/* char: 72 'H' */ + +static const CoordRec char72_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char72_stroke1[] = { + { 78.0867, 100 }, + { 78.0867, 0 }, +}; + +static const CoordRec char72_stroke2[] = { + { 11.42, 52.381 }, + { 78.0867, 52.381 }, +}; + +static const StrokeRec char72[] = { + { 2, char72_stroke0 }, + { 2, char72_stroke1 }, + { 2, char72_stroke2 }, +}; + +/* char: 73 'I' */ + +static const CoordRec char73_stroke0[] = { + { 10.86, 100 }, + { 10.86, 0 }, +}; + +static const StrokeRec char73[] = { + { 2, char73_stroke0 }, +}; + +/* char: 74 'J' */ + +static const CoordRec char74_stroke0[] = { + { 50.119, 100 }, + { 50.119, 23.8095 }, + { 45.3571, 9.5238 }, + { 40.5952, 4.7619 }, + { 31.0714, 0 }, + { 21.5476, 0 }, + { 12.0238, 4.7619 }, + { 7.2619, 9.5238 }, + { 2.5, 23.8095 }, + { 2.5, 33.3333 }, +}; + +static const StrokeRec char74[] = { + { 10, char74_stroke0 }, +}; + +/* char: 75 'K' */ + +static const CoordRec char75_stroke0[] = { + { 11.28, 100 }, + { 11.28, 0 }, +}; + +static const CoordRec char75_stroke1[] = { + { 77.9467, 100 }, + { 11.28, 33.3333 }, +}; + +static const CoordRec char75_stroke2[] = { + { 35.0895, 57.1429 }, + { 77.9467, 0 }, +}; + +static const StrokeRec char75[] = { + { 2, char75_stroke0 }, + { 2, char75_stroke1 }, + { 2, char75_stroke2 }, +}; + +/* char: 76 'L' */ + +static const CoordRec char76_stroke0[] = { + { 11.68, 100 }, + { 11.68, 0 }, +}; + +static const CoordRec char76_stroke1[] = { + { 11.68, 0 }, + { 68.8229, 0 }, +}; + +static const StrokeRec char76[] = { + { 2, char76_stroke0 }, + { 2, char76_stroke1 }, +}; + +/* char: 77 'M' */ + +static const CoordRec char77_stroke0[] = { + { 10.86, 100 }, + { 10.86, 0 }, +}; + +static const CoordRec char77_stroke1[] = { + { 10.86, 100 }, + { 48.9552, 0 }, +}; + +static const CoordRec char77_stroke2[] = { + { 87.0505, 100 }, + { 48.9552, 0 }, +}; + +static const CoordRec char77_stroke3[] = { + { 87.0505, 100 }, + { 87.0505, 0 }, +}; + +static const StrokeRec char77[] = { + { 2, char77_stroke0 }, + { 2, char77_stroke1 }, + { 2, char77_stroke2 }, + { 2, char77_stroke3 }, +}; + +/* char: 78 'N' */ + +static const CoordRec char78_stroke0[] = { + { 11.14, 100 }, + { 11.14, 0 }, +}; + +static const CoordRec char78_stroke1[] = { + { 11.14, 100 }, + { 77.8067, 0 }, +}; + +static const CoordRec char78_stroke2[] = { + { 77.8067, 100 }, + { 77.8067, 0 }, +}; + +static const StrokeRec char78[] = { + { 2, char78_stroke0 }, + { 2, char78_stroke1 }, + { 2, char78_stroke2 }, +}; + +/* char: 79 'O' */ + +static const CoordRec char79_stroke0[] = { + { 34.8114, 100 }, + { 25.2876, 95.2381 }, + { 15.7638, 85.7143 }, + { 11.0019, 76.1905 }, + { 6.24, 61.9048 }, + { 6.24, 38.0952 }, + { 11.0019, 23.8095 }, + { 15.7638, 14.2857 }, + { 25.2876, 4.7619 }, + { 34.8114, 0 }, + { 53.859, 0 }, + { 63.3829, 4.7619 }, + { 72.9067, 14.2857 }, + { 77.6686, 23.8095 }, + { 82.4305, 38.0952 }, + { 82.4305, 61.9048 }, + { 77.6686, 76.1905 }, + { 72.9067, 85.7143 }, + { 63.3829, 95.2381 }, + { 53.859, 100 }, + { 34.8114, 100 }, +}; + +static const StrokeRec char79[] = { + { 21, char79_stroke0 }, +}; + +/* char: 80 'P' */ + +static const CoordRec char80_stroke0[] = { + { 12.1, 100 }, + { 12.1, 0 }, +}; + +static const CoordRec char80_stroke1[] = { + { 12.1, 100 }, + { 54.9571, 100 }, + { 69.2429, 95.2381 }, + { 74.0048, 90.4762 }, + { 78.7667, 80.9524 }, + { 78.7667, 66.6667 }, + { 74.0048, 57.1429 }, + { 69.2429, 52.381 }, + { 54.9571, 47.619 }, + { 12.1, 47.619 }, +}; + +static const StrokeRec char80[] = { + { 2, char80_stroke0 }, + { 10, char80_stroke1 }, +}; + +/* char: 81 'Q' */ + +static const CoordRec char81_stroke0[] = { + { 33.8714, 100 }, + { 24.3476, 95.2381 }, + { 14.8238, 85.7143 }, + { 10.0619, 76.1905 }, + { 5.3, 61.9048 }, + { 5.3, 38.0952 }, + { 10.0619, 23.8095 }, + { 14.8238, 14.2857 }, + { 24.3476, 4.7619 }, + { 33.8714, 0 }, + { 52.919, 0 }, + { 62.4429, 4.7619 }, + { 71.9667, 14.2857 }, + { 76.7286, 23.8095 }, + { 81.4905, 38.0952 }, + { 81.4905, 61.9048 }, + { 76.7286, 76.1905 }, + { 71.9667, 85.7143 }, + { 62.4429, 95.2381 }, + { 52.919, 100 }, + { 33.8714, 100 }, +}; + +static const CoordRec char81_stroke1[] = { + { 48.1571, 19.0476 }, + { 76.7286, -9.5238 }, +}; + +static const StrokeRec char81[] = { + { 21, char81_stroke0 }, + { 2, char81_stroke1 }, +}; + +/* char: 82 'R' */ + +static const CoordRec char82_stroke0[] = { + { 11.68, 100 }, + { 11.68, 0 }, +}; + +static const CoordRec char82_stroke1[] = { + { 11.68, 100 }, + { 54.5371, 100 }, + { 68.8229, 95.2381 }, + { 73.5848, 90.4762 }, + { 78.3467, 80.9524 }, + { 78.3467, 71.4286 }, + { 73.5848, 61.9048 }, + { 68.8229, 57.1429 }, + { 54.5371, 52.381 }, + { 11.68, 52.381 }, +}; + +static const CoordRec char82_stroke2[] = { + { 45.0133, 52.381 }, + { 78.3467, 0 }, +}; + +static const StrokeRec char82[] = { + { 2, char82_stroke0 }, + { 10, char82_stroke1 }, + { 2, char82_stroke2 }, +}; + +/* char: 83 'S' */ + +static const CoordRec char83_stroke0[] = { + { 74.6667, 85.7143 }, + { 65.1429, 95.2381 }, + { 50.8571, 100 }, + { 31.8095, 100 }, + { 17.5238, 95.2381 }, + { 8, 85.7143 }, + { 8, 76.1905 }, + { 12.7619, 66.6667 }, + { 17.5238, 61.9048 }, + { 27.0476, 57.1429 }, + { 55.619, 47.619 }, + { 65.1429, 42.8571 }, + { 69.9048, 38.0952 }, + { 74.6667, 28.5714 }, + { 74.6667, 14.2857 }, + { 65.1429, 4.7619 }, + { 50.8571, 0 }, + { 31.8095, 0 }, + { 17.5238, 4.7619 }, + { 8, 14.2857 }, +}; + +static const StrokeRec char83[] = { + { 20, char83_stroke0 }, +}; + +/* char: 84 'T' */ + +static const CoordRec char84_stroke0[] = { + { 35.6933, 100 }, + { 35.6933, 0 }, +}; + +static const CoordRec char84_stroke1[] = { + { 2.36, 100 }, + { 69.0267, 100 }, +}; + +static const StrokeRec char84[] = { + { 2, char84_stroke0 }, + { 2, char84_stroke1 }, +}; + +/* char: 85 'U' */ + +static const CoordRec char85_stroke0[] = { + { 11.54, 100 }, + { 11.54, 28.5714 }, + { 16.3019, 14.2857 }, + { 25.8257, 4.7619 }, + { 40.1114, 0 }, + { 49.6352, 0 }, + { 63.921, 4.7619 }, + { 73.4448, 14.2857 }, + { 78.2067, 28.5714 }, + { 78.2067, 100 }, +}; + +static const StrokeRec char85[] = { + { 10, char85_stroke0 }, +}; + +/* char: 86 'V' */ + +static const CoordRec char86_stroke0[] = { + { 2.36, 100 }, + { 40.4552, 0 }, +}; + +static const CoordRec char86_stroke1[] = { + { 78.5505, 100 }, + { 40.4552, 0 }, +}; + +static const StrokeRec char86[] = { + { 2, char86_stroke0 }, + { 2, char86_stroke1 }, +}; + +/* char: 87 'W' */ + +static const CoordRec char87_stroke0[] = { + { 2.22, 100 }, + { 26.0295, 0 }, +}; + +static const CoordRec char87_stroke1[] = { + { 49.839, 100 }, + { 26.0295, 0 }, +}; + +static const CoordRec char87_stroke2[] = { + { 49.839, 100 }, + { 73.6486, 0 }, +}; + +static const CoordRec char87_stroke3[] = { + { 97.4581, 100 }, + { 73.6486, 0 }, +}; + +static const StrokeRec char87[] = { + { 2, char87_stroke0 }, + { 2, char87_stroke1 }, + { 2, char87_stroke2 }, + { 2, char87_stroke3 }, +}; + +/* char: 88 'X' */ + +static const CoordRec char88_stroke0[] = { + { 2.5, 100 }, + { 69.1667, 0 }, +}; + +static const CoordRec char88_stroke1[] = { + { 69.1667, 100 }, + { 2.5, 0 }, +}; + +static const StrokeRec char88[] = { + { 2, char88_stroke0 }, + { 2, char88_stroke1 }, +}; + +/* char: 89 'Y' */ + +static const CoordRec char89_stroke0[] = { + { 1.52, 100 }, + { 39.6152, 52.381 }, + { 39.6152, 0 }, +}; + +static const CoordRec char89_stroke1[] = { + { 77.7105, 100 }, + { 39.6152, 52.381 }, +}; + +static const StrokeRec char89[] = { + { 3, char89_stroke0 }, + { 2, char89_stroke1 }, +}; + +/* char: 90 'Z' */ + +static const CoordRec char90_stroke0[] = { + { 69.1667, 100 }, + { 2.5, 0 }, +}; + +static const CoordRec char90_stroke1[] = { + { 2.5, 100 }, + { 69.1667, 100 }, +}; + +static const CoordRec char90_stroke2[] = { + { 2.5, 0 }, + { 69.1667, 0 }, +}; + +static const StrokeRec char90[] = { + { 2, char90_stroke0 }, + { 2, char90_stroke1 }, + { 2, char90_stroke2 }, +}; + +/* char: 91 '[' */ + +static const CoordRec char91_stroke0[] = { + { 7.78, 119.048 }, + { 7.78, -33.3333 }, +}; + +static const CoordRec char91_stroke1[] = { + { 12.5419, 119.048 }, + { 12.5419, -33.3333 }, +}; + +static const CoordRec char91_stroke2[] = { + { 7.78, 119.048 }, + { 41.1133, 119.048 }, +}; + +static const CoordRec char91_stroke3[] = { + { 7.78, -33.3333 }, + { 41.1133, -33.3333 }, +}; + +static const StrokeRec char91[] = { + { 2, char91_stroke0 }, + { 2, char91_stroke1 }, + { 2, char91_stroke2 }, + { 2, char91_stroke3 }, +}; + +/* char: 92 '\' */ + +static const CoordRec char92_stroke0[] = { + { 5.84, 100 }, + { 72.5067, -14.2857 }, +}; + +static const StrokeRec char92[] = { + { 2, char92_stroke0 }, +}; + +/* char: 93 ']' */ + +static const CoordRec char93_stroke0[] = { + { 33.0114, 119.048 }, + { 33.0114, -33.3333 }, +}; + +static const CoordRec char93_stroke1[] = { + { 37.7733, 119.048 }, + { 37.7733, -33.3333 }, +}; + +static const CoordRec char93_stroke2[] = { + { 4.44, 119.048 }, + { 37.7733, 119.048 }, +}; + +static const CoordRec char93_stroke3[] = { + { 4.44, -33.3333 }, + { 37.7733, -33.3333 }, +}; + +static const StrokeRec char93[] = { + { 2, char93_stroke0 }, + { 2, char93_stroke1 }, + { 2, char93_stroke2 }, + { 2, char93_stroke3 }, +}; + +/* char: 94 '^' */ + +static const CoordRec char94_stroke0[] = { + { 44.0752, 109.524 }, + { 5.98, 42.8571 }, +}; + +static const CoordRec char94_stroke1[] = { + { 44.0752, 109.524 }, + { 82.1705, 42.8571 }, +}; + +static const StrokeRec char94[] = { + { 2, char94_stroke0 }, + { 2, char94_stroke1 }, +}; + +/* char: 95 '_' */ + +static const CoordRec char95_stroke0[] = { + { -1.1, -33.3333 }, + { 103.662, -33.3333 }, + { 103.662, -28.5714 }, + { -1.1, -28.5714 }, + { -1.1, -33.3333 }, +}; + +static const StrokeRec char95[] = { + { 5, char95_stroke0 }, +}; + +/* char: 96 '`' */ + +static const CoordRec char96_stroke0[] = { + { 33.0219, 100 }, + { 56.8314, 71.4286 }, +}; + +static const CoordRec char96_stroke1[] = { + { 33.0219, 100 }, + { 28.26, 95.2381 }, + { 56.8314, 71.4286 }, +}; + +static const StrokeRec char96[] = { + { 2, char96_stroke0 }, + { 3, char96_stroke1 }, +}; + +/* char: 97 'a' */ + +static const CoordRec char97_stroke0[] = { + { 63.8229, 66.6667 }, + { 63.8229, 0 }, +}; + +static const CoordRec char97_stroke1[] = { + { 63.8229, 52.381 }, + { 54.299, 61.9048 }, + { 44.7752, 66.6667 }, + { 30.4895, 66.6667 }, + { 20.9657, 61.9048 }, + { 11.4419, 52.381 }, + { 6.68, 38.0952 }, + { 6.68, 28.5714 }, + { 11.4419, 14.2857 }, + { 20.9657, 4.7619 }, + { 30.4895, 0 }, + { 44.7752, 0 }, + { 54.299, 4.7619 }, + { 63.8229, 14.2857 }, +}; + +static const StrokeRec char97[] = { + { 2, char97_stroke0 }, + { 14, char97_stroke1 }, +}; + +/* char: 98 'b' */ + +static const CoordRec char98_stroke0[] = { + { 8.76, 100 }, + { 8.76, 0 }, +}; + +static const CoordRec char98_stroke1[] = { + { 8.76, 52.381 }, + { 18.2838, 61.9048 }, + { 27.8076, 66.6667 }, + { 42.0933, 66.6667 }, + { 51.6171, 61.9048 }, + { 61.141, 52.381 }, + { 65.9029, 38.0952 }, + { 65.9029, 28.5714 }, + { 61.141, 14.2857 }, + { 51.6171, 4.7619 }, + { 42.0933, 0 }, + { 27.8076, 0 }, + { 18.2838, 4.7619 }, + { 8.76, 14.2857 }, +}; + +static const StrokeRec char98[] = { + { 2, char98_stroke0 }, + { 14, char98_stroke1 }, +}; + +/* char: 99 'c' */ + +static const CoordRec char99_stroke0[] = { + { 62.6629, 52.381 }, + { 53.139, 61.9048 }, + { 43.6152, 66.6667 }, + { 29.3295, 66.6667 }, + { 19.8057, 61.9048 }, + { 10.2819, 52.381 }, + { 5.52, 38.0952 }, + { 5.52, 28.5714 }, + { 10.2819, 14.2857 }, + { 19.8057, 4.7619 }, + { 29.3295, 0 }, + { 43.6152, 0 }, + { 53.139, 4.7619 }, + { 62.6629, 14.2857 }, +}; + +static const StrokeRec char99[] = { + { 14, char99_stroke0 }, +}; + +/* char: 100 'd' */ + +static const CoordRec char100_stroke0[] = { + { 61.7829, 100 }, + { 61.7829, 0 }, +}; + +static const CoordRec char100_stroke1[] = { + { 61.7829, 52.381 }, + { 52.259, 61.9048 }, + { 42.7352, 66.6667 }, + { 28.4495, 66.6667 }, + { 18.9257, 61.9048 }, + { 9.4019, 52.381 }, + { 4.64, 38.0952 }, + { 4.64, 28.5714 }, + { 9.4019, 14.2857 }, + { 18.9257, 4.7619 }, + { 28.4495, 0 }, + { 42.7352, 0 }, + { 52.259, 4.7619 }, + { 61.7829, 14.2857 }, +}; + +static const StrokeRec char100[] = { + { 2, char100_stroke0 }, + { 14, char100_stroke1 }, +}; + +/* char: 101 'e' */ + +static const CoordRec char101_stroke0[] = { + { 5.72, 38.0952 }, + { 62.8629, 38.0952 }, + { 62.8629, 47.619 }, + { 58.101, 57.1429 }, + { 53.339, 61.9048 }, + { 43.8152, 66.6667 }, + { 29.5295, 66.6667 }, + { 20.0057, 61.9048 }, + { 10.4819, 52.381 }, + { 5.72, 38.0952 }, + { 5.72, 28.5714 }, + { 10.4819, 14.2857 }, + { 20.0057, 4.7619 }, + { 29.5295, 0 }, + { 43.8152, 0 }, + { 53.339, 4.7619 }, + { 62.8629, 14.2857 }, +}; + +static const StrokeRec char101[] = { + { 17, char101_stroke0 }, +}; + +/* char: 102 'f' */ + +static const CoordRec char102_stroke0[] = { + { 38.7752, 100 }, + { 29.2514, 100 }, + { 19.7276, 95.2381 }, + { 14.9657, 80.9524 }, + { 14.9657, 0 }, +}; + +static const CoordRec char102_stroke1[] = { + { 0.68, 66.6667 }, + { 34.0133, 66.6667 }, +}; + +static const StrokeRec char102[] = { + { 5, char102_stroke0 }, + { 2, char102_stroke1 }, +}; + +/* char: 103 'g' */ + +static const CoordRec char103_stroke0[] = { + { 62.5029, 66.6667 }, + { 62.5029, -9.5238 }, + { 57.741, -23.8095 }, + { 52.979, -28.5714 }, + { 43.4552, -33.3333 }, + { 29.1695, -33.3333 }, + { 19.6457, -28.5714 }, +}; + +static const CoordRec char103_stroke1[] = { + { 62.5029, 52.381 }, + { 52.979, 61.9048 }, + { 43.4552, 66.6667 }, + { 29.1695, 66.6667 }, + { 19.6457, 61.9048 }, + { 10.1219, 52.381 }, + { 5.36, 38.0952 }, + { 5.36, 28.5714 }, + { 10.1219, 14.2857 }, + { 19.6457, 4.7619 }, + { 29.1695, 0 }, + { 43.4552, 0 }, + { 52.979, 4.7619 }, + { 62.5029, 14.2857 }, +}; + +static const StrokeRec char103[] = { + { 7, char103_stroke0 }, + { 14, char103_stroke1 }, +}; + +/* char: 104 'h' */ + +static const CoordRec char104_stroke0[] = { + { 9.6, 100 }, + { 9.6, 0 }, +}; + +static const CoordRec char104_stroke1[] = { + { 9.6, 47.619 }, + { 23.8857, 61.9048 }, + { 33.4095, 66.6667 }, + { 47.6952, 66.6667 }, + { 57.219, 61.9048 }, + { 61.981, 47.619 }, + { 61.981, 0 }, +}; + +static const StrokeRec char104[] = { + { 2, char104_stroke0 }, + { 7, char104_stroke1 }, +}; + +/* char: 105 'i' */ + +static const CoordRec char105_stroke0[] = { + { 10.02, 100 }, + { 14.7819, 95.2381 }, + { 19.5438, 100 }, + { 14.7819, 104.762 }, + { 10.02, 100 }, +}; + +static const CoordRec char105_stroke1[] = { + { 14.7819, 66.6667 }, + { 14.7819, 0 }, +}; + +static const StrokeRec char105[] = { + { 5, char105_stroke0 }, + { 2, char105_stroke1 }, +}; + +/* char: 106 'j' */ + +static const CoordRec char106_stroke0[] = { + { 17.3876, 100 }, + { 22.1495, 95.2381 }, + { 26.9114, 100 }, + { 22.1495, 104.762 }, + { 17.3876, 100 }, +}; + +static const CoordRec char106_stroke1[] = { + { 22.1495, 66.6667 }, + { 22.1495, -14.2857 }, + { 17.3876, -28.5714 }, + { 7.8638, -33.3333 }, + { -1.66, -33.3333 }, +}; + +static const StrokeRec char106[] = { + { 5, char106_stroke0 }, + { 5, char106_stroke1 }, +}; + +/* char: 107 'k' */ + +static const CoordRec char107_stroke0[] = { + { 9.6, 100 }, + { 9.6, 0 }, +}; + +static const CoordRec char107_stroke1[] = { + { 57.219, 66.6667 }, + { 9.6, 19.0476 }, +}; + +static const CoordRec char107_stroke2[] = { + { 28.6476, 38.0952 }, + { 61.981, 0 }, +}; + +static const StrokeRec char107[] = { + { 2, char107_stroke0 }, + { 2, char107_stroke1 }, + { 2, char107_stroke2 }, +}; + +/* char: 108 'l' */ + +static const CoordRec char108_stroke0[] = { + { 10.02, 100 }, + { 10.02, 0 }, +}; + +static const StrokeRec char108[] = { + { 2, char108_stroke0 }, +}; + +/* char: 109 'm' */ + +static const CoordRec char109_stroke0[] = { + { 9.6, 66.6667 }, + { 9.6, 0 }, +}; + +static const CoordRec char109_stroke1[] = { + { 9.6, 47.619 }, + { 23.8857, 61.9048 }, + { 33.4095, 66.6667 }, + { 47.6952, 66.6667 }, + { 57.219, 61.9048 }, + { 61.981, 47.619 }, + { 61.981, 0 }, +}; + +static const CoordRec char109_stroke2[] = { + { 61.981, 47.619 }, + { 76.2667, 61.9048 }, + { 85.7905, 66.6667 }, + { 100.076, 66.6667 }, + { 109.6, 61.9048 }, + { 114.362, 47.619 }, + { 114.362, 0 }, +}; + +static const StrokeRec char109[] = { + { 2, char109_stroke0 }, + { 7, char109_stroke1 }, + { 7, char109_stroke2 }, +}; + +/* char: 110 'n' */ + +static const CoordRec char110_stroke0[] = { + { 9.18, 66.6667 }, + { 9.18, 0 }, +}; + +static const CoordRec char110_stroke1[] = { + { 9.18, 47.619 }, + { 23.4657, 61.9048 }, + { 32.9895, 66.6667 }, + { 47.2752, 66.6667 }, + { 56.799, 61.9048 }, + { 61.561, 47.619 }, + { 61.561, 0 }, +}; + +static const StrokeRec char110[] = { + { 2, char110_stroke0 }, + { 7, char110_stroke1 }, +}; + +/* char: 111 'o' */ + +static const CoordRec char111_stroke0[] = { + { 28.7895, 66.6667 }, + { 19.2657, 61.9048 }, + { 9.7419, 52.381 }, + { 4.98, 38.0952 }, + { 4.98, 28.5714 }, + { 9.7419, 14.2857 }, + { 19.2657, 4.7619 }, + { 28.7895, 0 }, + { 43.0752, 0 }, + { 52.599, 4.7619 }, + { 62.1229, 14.2857 }, + { 66.8848, 28.5714 }, + { 66.8848, 38.0952 }, + { 62.1229, 52.381 }, + { 52.599, 61.9048 }, + { 43.0752, 66.6667 }, + { 28.7895, 66.6667 }, +}; + +static const StrokeRec char111[] = { + { 17, char111_stroke0 }, +}; + +/* char: 112 'p' */ + +static const CoordRec char112_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, -33.3333 }, +}; + +static const CoordRec char112_stroke1[] = { + { 9.46, 52.381 }, + { 18.9838, 61.9048 }, + { 28.5076, 66.6667 }, + { 42.7933, 66.6667 }, + { 52.3171, 61.9048 }, + { 61.841, 52.381 }, + { 66.6029, 38.0952 }, + { 66.6029, 28.5714 }, + { 61.841, 14.2857 }, + { 52.3171, 4.7619 }, + { 42.7933, 0 }, + { 28.5076, 0 }, + { 18.9838, 4.7619 }, + { 9.46, 14.2857 }, +}; + +static const StrokeRec char112[] = { + { 2, char112_stroke0 }, + { 14, char112_stroke1 }, +}; + +/* char: 113 'q' */ + +static const CoordRec char113_stroke0[] = { + { 61.9829, 66.6667 }, + { 61.9829, -33.3333 }, +}; + +static const CoordRec char113_stroke1[] = { + { 61.9829, 52.381 }, + { 52.459, 61.9048 }, + { 42.9352, 66.6667 }, + { 28.6495, 66.6667 }, + { 19.1257, 61.9048 }, + { 9.6019, 52.381 }, + { 4.84, 38.0952 }, + { 4.84, 28.5714 }, + { 9.6019, 14.2857 }, + { 19.1257, 4.7619 }, + { 28.6495, 0 }, + { 42.9352, 0 }, + { 52.459, 4.7619 }, + { 61.9829, 14.2857 }, +}; + +static const StrokeRec char113[] = { + { 2, char113_stroke0 }, + { 14, char113_stroke1 }, +}; + +/* char: 114 'r' */ + +static const CoordRec char114_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, 0 }, +}; + +static const CoordRec char114_stroke1[] = { + { 9.46, 38.0952 }, + { 14.2219, 52.381 }, + { 23.7457, 61.9048 }, + { 33.2695, 66.6667 }, + { 47.5552, 66.6667 }, +}; + +static const StrokeRec char114[] = { + { 2, char114_stroke0 }, + { 5, char114_stroke1 }, +}; + +/* char: 115 's' */ + +static const CoordRec char115_stroke0[] = { + { 57.081, 52.381 }, + { 52.319, 61.9048 }, + { 38.0333, 66.6667 }, + { 23.7476, 66.6667 }, + { 9.4619, 61.9048 }, + { 4.7, 52.381 }, + { 9.4619, 42.8571 }, + { 18.9857, 38.0952 }, + { 42.7952, 33.3333 }, + { 52.319, 28.5714 }, + { 57.081, 19.0476 }, + { 57.081, 14.2857 }, + { 52.319, 4.7619 }, + { 38.0333, 0 }, + { 23.7476, 0 }, + { 9.4619, 4.7619 }, + { 4.7, 14.2857 }, +}; + +static const StrokeRec char115[] = { + { 17, char115_stroke0 }, +}; + +/* char: 116 't' */ + +static const CoordRec char116_stroke0[] = { + { 14.8257, 100 }, + { 14.8257, 19.0476 }, + { 19.5876, 4.7619 }, + { 29.1114, 0 }, + { 38.6352, 0 }, +}; + +static const CoordRec char116_stroke1[] = { + { 0.54, 66.6667 }, + { 33.8733, 66.6667 }, +}; + +static const StrokeRec char116[] = { + { 5, char116_stroke0 }, + { 2, char116_stroke1 }, +}; + +/* char: 117 'u' */ + +static const CoordRec char117_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, 19.0476 }, + { 14.2219, 4.7619 }, + { 23.7457, 0 }, + { 38.0314, 0 }, + { 47.5552, 4.7619 }, + { 61.841, 19.0476 }, +}; + +static const CoordRec char117_stroke1[] = { + { 61.841, 66.6667 }, + { 61.841, 0 }, +}; + +static const StrokeRec char117[] = { + { 7, char117_stroke0 }, + { 2, char117_stroke1 }, +}; + +/* char: 118 'v' */ + +static const CoordRec char118_stroke0[] = { + { 1.8, 66.6667 }, + { 30.3714, 0 }, +}; + +static const CoordRec char118_stroke1[] = { + { 58.9429, 66.6667 }, + { 30.3714, 0 }, +}; + +static const StrokeRec char118[] = { + { 2, char118_stroke0 }, + { 2, char118_stroke1 }, +}; + +/* char: 119 'w' */ + +static const CoordRec char119_stroke0[] = { + { 2.5, 66.6667 }, + { 21.5476, 0 }, +}; + +static const CoordRec char119_stroke1[] = { + { 40.5952, 66.6667 }, + { 21.5476, 0 }, +}; + +static const CoordRec char119_stroke2[] = { + { 40.5952, 66.6667 }, + { 59.6429, 0 }, +}; + +static const CoordRec char119_stroke3[] = { + { 78.6905, 66.6667 }, + { 59.6429, 0 }, +}; + +static const StrokeRec char119[] = { + { 2, char119_stroke0 }, + { 2, char119_stroke1 }, + { 2, char119_stroke2 }, + { 2, char119_stroke3 }, +}; + +/* char: 120 'x' */ + +static const CoordRec char120_stroke0[] = { + { 1.66, 66.6667 }, + { 54.041, 0 }, +}; + +static const CoordRec char120_stroke1[] = { + { 54.041, 66.6667 }, + { 1.66, 0 }, +}; + +static const StrokeRec char120[] = { + { 2, char120_stroke0 }, + { 2, char120_stroke1 }, +}; + +/* char: 121 'y' */ + +static const CoordRec char121_stroke0[] = { + { 6.5619, 66.6667 }, + { 35.1333, 0 }, +}; + +static const CoordRec char121_stroke1[] = { + { 63.7048, 66.6667 }, + { 35.1333, 0 }, + { 25.6095, -19.0476 }, + { 16.0857, -28.5714 }, + { 6.5619, -33.3333 }, + { 1.8, -33.3333 }, +}; + +static const StrokeRec char121[] = { + { 2, char121_stroke0 }, + { 6, char121_stroke1 }, +}; + +/* char: 122 'z' */ + +static const CoordRec char122_stroke0[] = { + { 56.821, 66.6667 }, + { 4.44, 0 }, +}; + +static const CoordRec char122_stroke1[] = { + { 4.44, 66.6667 }, + { 56.821, 66.6667 }, +}; + +static const CoordRec char122_stroke2[] = { + { 4.44, 0 }, + { 56.821, 0 }, +}; + +static const StrokeRec char122[] = { + { 2, char122_stroke0 }, + { 2, char122_stroke1 }, + { 2, char122_stroke2 }, +}; + +/* char: 123 '{' */ + +static const CoordRec char123_stroke0[] = { + { 31.1895, 119.048 }, + { 21.6657, 114.286 }, + { 16.9038, 109.524 }, + { 12.1419, 100 }, + { 12.1419, 90.4762 }, + { 16.9038, 80.9524 }, + { 21.6657, 76.1905 }, + { 26.4276, 66.6667 }, + { 26.4276, 57.1429 }, + { 16.9038, 47.619 }, +}; + +static const CoordRec char123_stroke1[] = { + { 21.6657, 114.286 }, + { 16.9038, 104.762 }, + { 16.9038, 95.2381 }, + { 21.6657, 85.7143 }, + { 26.4276, 80.9524 }, + { 31.1895, 71.4286 }, + { 31.1895, 61.9048 }, + { 26.4276, 52.381 }, + { 7.38, 42.8571 }, + { 26.4276, 33.3333 }, + { 31.1895, 23.8095 }, + { 31.1895, 14.2857 }, + { 26.4276, 4.7619 }, + { 21.6657, 0 }, + { 16.9038, -9.5238 }, + { 16.9038, -19.0476 }, + { 21.6657, -28.5714 }, +}; + +static const CoordRec char123_stroke2[] = { + { 16.9038, 38.0952 }, + { 26.4276, 28.5714 }, + { 26.4276, 19.0476 }, + { 21.6657, 9.5238 }, + { 16.9038, 4.7619 }, + { 12.1419, -4.7619 }, + { 12.1419, -14.2857 }, + { 16.9038, -23.8095 }, + { 21.6657, -28.5714 }, + { 31.1895, -33.3333 }, +}; + +static const StrokeRec char123[] = { + { 10, char123_stroke0 }, + { 17, char123_stroke1 }, + { 10, char123_stroke2 }, +}; + +/* char: 124 '|' */ + +static const CoordRec char124_stroke0[] = { + { 11.54, 119.048 }, + { 11.54, -33.3333 }, +}; + +static const StrokeRec char124[] = { + { 2, char124_stroke0 }, +}; + +/* char: 125 '}' */ + +static const CoordRec char125_stroke0[] = { + { 9.18, 119.048 }, + { 18.7038, 114.286 }, + { 23.4657, 109.524 }, + { 28.2276, 100 }, + { 28.2276, 90.4762 }, + { 23.4657, 80.9524 }, + { 18.7038, 76.1905 }, + { 13.9419, 66.6667 }, + { 13.9419, 57.1429 }, + { 23.4657, 47.619 }, +}; + +static const CoordRec char125_stroke1[] = { + { 18.7038, 114.286 }, + { 23.4657, 104.762 }, + { 23.4657, 95.2381 }, + { 18.7038, 85.7143 }, + { 13.9419, 80.9524 }, + { 9.18, 71.4286 }, + { 9.18, 61.9048 }, + { 13.9419, 52.381 }, + { 32.9895, 42.8571 }, + { 13.9419, 33.3333 }, + { 9.18, 23.8095 }, + { 9.18, 14.2857 }, + { 13.9419, 4.7619 }, + { 18.7038, 0 }, + { 23.4657, -9.5238 }, + { 23.4657, -19.0476 }, + { 18.7038, -28.5714 }, +}; + +static const CoordRec char125_stroke2[] = { + { 23.4657, 38.0952 }, + { 13.9419, 28.5714 }, + { 13.9419, 19.0476 }, + { 18.7038, 9.5238 }, + { 23.4657, 4.7619 }, + { 28.2276, -4.7619 }, + { 28.2276, -14.2857 }, + { 23.4657, -23.8095 }, + { 18.7038, -28.5714 }, + { 9.18, -33.3333 }, +}; + +static const StrokeRec char125[] = { + { 10, char125_stroke0 }, + { 17, char125_stroke1 }, + { 10, char125_stroke2 }, +}; + +/* char: 126 '~' */ + +static const CoordRec char126_stroke0[] = { + { 2.92, 28.5714 }, + { 2.92, 38.0952 }, + { 7.6819, 52.381 }, + { 17.2057, 57.1429 }, + { 26.7295, 57.1429 }, + { 36.2533, 52.381 }, + { 55.301, 38.0952 }, + { 64.8248, 33.3333 }, + { 74.3486, 33.3333 }, + { 83.8724, 38.0952 }, + { 88.6343, 47.619 }, +}; + +static const CoordRec char126_stroke1[] = { + { 2.92, 38.0952 }, + { 7.6819, 47.619 }, + { 17.2057, 52.381 }, + { 26.7295, 52.381 }, + { 36.2533, 47.619 }, + { 55.301, 33.3333 }, + { 64.8248, 28.5714 }, + { 74.3486, 28.5714 }, + { 83.8724, 33.3333 }, + { 88.6343, 47.619 }, + { 88.6343, 57.1429 }, +}; + +static const StrokeRec char126[] = { + { 11, char126_stroke0 }, + { 11, char126_stroke1 }, +}; + +/* char: 127 */ + +static const CoordRec char127_stroke0[] = { + { 52.381, 100 }, + { 14.2857, -33.3333 }, +}; + +static const CoordRec char127_stroke1[] = { + { 28.5714, 66.6667 }, + { 14.2857, 61.9048 }, + { 4.7619, 52.381 }, + { 0, 38.0952 }, + { 0, 23.8095 }, + { 4.7619, 14.2857 }, + { 14.2857, 4.7619 }, + { 28.5714, 0 }, + { 38.0952, 0 }, + { 52.381, 4.7619 }, + { 61.9048, 14.2857 }, + { 66.6667, 28.5714 }, + { 66.6667, 42.8571 }, + { 61.9048, 52.381 }, + { 52.381, 61.9048 }, + { 38.0952, 66.6667 }, + { 28.5714, 66.6667 }, +}; + +static const StrokeRec char127[] = { + { 2, char127_stroke0 }, + { 17, char127_stroke1 }, +}; + +static const StrokeCharRec chars[] = { + { 0, /* char0 */ 0, 0, 0 }, + { 0, /* char1 */ 0, 0, 0 }, + { 0, /* char2 */ 0, 0, 0 }, + { 0, /* char3 */ 0, 0, 0 }, + { 0, /* char4 */ 0, 0, 0 }, + { 0, /* char5 */ 0, 0, 0 }, + { 0, /* char6 */ 0, 0, 0 }, + { 0, /* char7 */ 0, 0, 0 }, + { 0, /* char8 */ 0, 0, 0 }, + { 0, /* char9 */ 0, 0, 0 }, + { 0, /* char10 */ 0, 0, 0 }, + { 0, /* char11 */ 0, 0, 0 }, + { 0, /* char12 */ 0, 0, 0 }, + { 0, /* char13 */ 0, 0, 0 }, + { 0, /* char14 */ 0, 0, 0 }, + { 0, /* char15 */ 0, 0, 0 }, + { 0, /* char16 */ 0, 0, 0 }, + { 0, /* char17 */ 0, 0, 0 }, + { 0, /* char18 */ 0, 0, 0 }, + { 0, /* char19 */ 0, 0, 0 }, + { 0, /* char20 */ 0, 0, 0 }, + { 0, /* char21 */ 0, 0, 0 }, + { 0, /* char22 */ 0, 0, 0 }, + { 0, /* char23 */ 0, 0, 0 }, + { 0, /* char24 */ 0, 0, 0 }, + { 0, /* char25 */ 0, 0, 0 }, + { 0, /* char26 */ 0, 0, 0 }, + { 0, /* char27 */ 0, 0, 0 }, + { 0, /* char28 */ 0, 0, 0 }, + { 0, /* char29 */ 0, 0, 0 }, + { 0, /* char30 */ 0, 0, 0 }, + { 0, /* char31 */ 0, 0, 0 }, + { 0, /* char32 */ 0, 52.381, 104.762 }, + { 2, char33, 13.3819, 26.6238 }, + { 2, char34, 23.0676, 51.4352 }, + { 4, char35, 36.5333, 79.4886 }, + { 3, char36, 38.1533, 76.2067 }, + { 3, char37, 49.2171, 96.5743 }, + { 1, char38, 53.599, 101.758 }, + { 1, char39, 4.44, 13.62 }, + { 1, char40, 21.8657, 47.1733 }, + { 1, char41, 24.3276, 47.5333 }, + { 3, char42, 30.7695, 59.439 }, + { 2, char43, 48.8371, 97.2543 }, + { 1, char44, 13.5219, 26.0638 }, + { 1, char45, 50.2371, 100.754 }, + { 1, char46, 13.1019, 26.4838 }, + { 1, char47, 40.5733, 82.1067 }, + { 1, char48, 38.3133, 77.0667 }, + { 1, char49, 30.8676, 66.5295 }, + { 1, char50, 38.7533, 77.6467 }, + { 1, char51, 38.3333, 77.0467 }, + { 2, char52, 37.2133, 80.1686 }, + { 1, char53, 38.1933, 77.6867 }, + { 1, char54, 34.1514, 73.8048 }, + { 2, char55, 38.8933, 77.2267 }, + { 1, char56, 38.9333, 77.6667 }, + { 1, char57, 39.9333, 74.0648 }, + { 2, char58, 14.0819, 26.2238 }, + { 2, char59, 12.9619, 26.3038 }, + { 1, char60, 41.1552, 81.6105 }, + { 2, char61, 48.5571, 97.2543 }, + { 1, char62, 40.8752, 81.6105 }, + { 2, char63, 36.9914, 73.9029 }, + { 2, char64, 34.9314, 74.3648 }, + { 3, char65, 40.5952, 80.4905 }, + { 3, char66, 44.7533, 83.6267 }, + { 1, char67, 39.9933, 84.4886 }, + { 2, char68, 45.2933, 85.2867 }, + { 4, char69, 39.9914, 78.1848 }, + { 3, char70, 39.9914, 78.7448 }, + { 2, char71, 40.3933, 89.7686 }, + { 3, char72, 44.7533, 89.0867 }, + { 1, char73, 10.86, 21.3 }, + { 1, char74, 31.0714, 59.999 }, + { 3, char75, 44.6133, 79.3267 }, + { 2, char76, 40.2514, 71.3229 }, + { 4, char77, 48.9552, 97.2105 }, + { 3, char78, 44.4733, 88.8067 }, + { 1, char79, 44.3352, 88.8305 }, + { 2, char80, 45.4333, 85.6667 }, + { 2, char81, 43.3952, 88.0905 }, + { 3, char82, 45.0133, 82.3667 }, + { 1, char83, 41.3333, 80.8267 }, + { 2, char84, 35.6933, 71.9467 }, + { 1, char85, 44.8733, 89.4867 }, + { 2, char86, 40.4552, 81.6105 }, + { 4, char87, 49.839, 100.518 }, + { 2, char88, 35.8333, 72.3667 }, + { 2, char89, 39.6152, 79.6505 }, + { 3, char90, 35.8333, 73.7467 }, + { 4, char91, 22.0657, 46.1133 }, + { 1, char92, 39.1733, 78.2067 }, + { 4, char93, 23.4876, 46.3933 }, + { 2, char94, 44.0752, 90.2305 }, + { 1, char95, 51.281, 104.062 }, + { 2, char96, 42.5457, 83.5714 }, + { 2, char97, 35.2514, 66.6029 }, + { 2, char98, 37.3314, 70.4629 }, + { 1, char99, 34.0914, 68.9229 }, + { 2, char100, 33.2114, 70.2629 }, + { 1, char101, 34.2914, 68.5229 }, + { 2, char102, 14.9657, 38.6552 }, + { 2, char103, 33.9314, 70.9829 }, + { 2, char104, 33.4095, 71.021 }, + { 2, char105, 14.7819, 28.8638 }, + { 2, char106, 17.3876, 36.2314 }, + { 3, char107, 33.4095, 62.521 }, + { 1, char108, 10.02, 19.34 }, + { 3, char109, 61.981, 123.962 }, + { 2, char110, 32.9895, 70.881 }, + { 1, char111, 33.5514, 71.7448 }, + { 2, char112, 38.0314, 70.8029 }, + { 2, char113, 33.4114, 70.7429 }, + { 2, char114, 23.7457, 49.4952 }, + { 1, char115, 28.5095, 62.321 }, + { 2, char116, 14.8257, 39.3152 }, + { 2, char117, 33.2695, 71.161 }, + { 2, char118, 30.3714, 60.6029 }, + { 4, char119, 40.5952, 80.4905 }, + { 2, char120, 25.4695, 56.401 }, + { 2, char121, 35.1333, 66.0648 }, + { 3, char122, 28.2495, 61.821 }, + { 3, char123, 21.6657, 41.6295 }, + { 1, char124, 11.54, 23.78 }, + { 3, char125, 18.7038, 41.4695 }, + { 2, char126, 45.7771, 91.2743 }, + { 2, char127, 33.3333, 66.6667 }, +}; + +StrokeFontRec glutStrokeRoman = { "Roman", 128, chars, 119.048, -33.3333 }; + diff --git a/lib/glut-3.7.6/lib/glut/glut_shapes.c b/lib/glut-3.7.6/lib/glut/glut_shapes.c new file mode 100644 index 0000000000..3d9dce1d97 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_shapes.c @@ -0,0 +1,596 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ + +/** +(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. +*/ + +#include +#include "glutint.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static GLUquadricObj *quadObj; + +#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); } + +static void +initQuadObj(void) +{ + quadObj = gluNewQuadric(); + if (!quadObj) + __glutFatalError("out of memory."); +} + +/* CENTRY */ +void APIENTRY +glutWireSphere(GLdouble radius, GLint slices, GLint stacks) +{ + QUAD_OBJ_INIT(); + gluQuadricDrawStyle(quadObj, GLU_LINE); + gluQuadricNormals(quadObj, GLU_SMOOTH); + /* If we ever changed/used the texture or orientation state + of quadObj, we'd need to change it to the defaults here + with gluQuadricTexture and/or gluQuadricOrientation. */ + gluSphere(quadObj, radius, slices, stacks); +} + +void APIENTRY +glutSolidSphere(GLdouble radius, GLint slices, GLint stacks) +{ + QUAD_OBJ_INIT(); + gluQuadricDrawStyle(quadObj, GLU_FILL); + gluQuadricNormals(quadObj, GLU_SMOOTH); + /* If we ever changed/used the texture or orientation state + of quadObj, we'd need to change it to the defaults here + with gluQuadricTexture and/or gluQuadricOrientation. */ + gluSphere(quadObj, radius, slices, stacks); +} + +void APIENTRY +glutWireCone(GLdouble base, GLdouble height, + GLint slices, GLint stacks) +{ + QUAD_OBJ_INIT(); + gluQuadricDrawStyle(quadObj, GLU_LINE); + gluQuadricNormals(quadObj, GLU_SMOOTH); + /* If we ever changed/used the texture or orientation state + of quadObj, we'd need to change it to the defaults here + with gluQuadricTexture and/or gluQuadricOrientation. */ + gluCylinder(quadObj, base, 0.0, height, slices, stacks); +} + +void APIENTRY +glutSolidCone(GLdouble base, GLdouble height, + GLint slices, GLint stacks) +{ + QUAD_OBJ_INIT(); + gluQuadricDrawStyle(quadObj, GLU_FILL); + gluQuadricNormals(quadObj, GLU_SMOOTH); + /* If we ever changed/used the texture or orientation state + of quadObj, we'd need to change it to the defaults here + with gluQuadricTexture and/or gluQuadricOrientation. */ + gluCylinder(quadObj, base, 0.0, height, slices, stacks); +} + +/* ENDCENTRY */ + +static void +drawBox(GLfloat size, GLenum type) +{ + static GLfloat n[6][3] = + { + {-1.0, 0.0, 0.0}, + {0.0, 1.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, -1.0} + }; + static GLint faces[6][4] = + { + {0, 1, 2, 3}, + {3, 2, 6, 7}, + {7, 6, 5, 4}, + {4, 5, 1, 0}, + {5, 6, 2, 1}, + {7, 4, 0, 3} + }; + GLfloat v[8][3]; + GLint i; + + v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2; + v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2; + v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2; + v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2; + v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2; + v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2; + + for (i = 5; i >= 0; i--) { + glBegin(type); + glNormal3fv(&n[i][0]); + glVertex3fv(&v[faces[i][0]][0]); + glVertex3fv(&v[faces[i][1]][0]); + glVertex3fv(&v[faces[i][2]][0]); + glVertex3fv(&v[faces[i][3]][0]); + glEnd(); + } +} + +/* CENTRY */ +void APIENTRY +glutWireCube(GLdouble size) +{ + drawBox(size, GL_LINE_LOOP); +} + +void APIENTRY +glutSolidCube(GLdouble size) +{ + drawBox(size, GL_QUADS); +} + +/* ENDCENTRY */ + +static void +doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + glBegin(GL_QUAD_STRIP); + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi); + } + glEnd(); + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } +} + +/* CENTRY */ +void APIENTRY +glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, + GLint nsides, GLint rings) +{ + glPushAttrib(GL_POLYGON_BIT); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + doughnut(innerRadius, outerRadius, nsides, rings); + glPopAttrib(); +} + +void APIENTRY +glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, + GLint nsides, GLint rings) +{ + doughnut(innerRadius, outerRadius, nsides, rings); +} + +/* ENDCENTRY */ + +static GLfloat dodec[20][3]; + +static void +initDodecahedron(void) +{ + GLfloat alpha, beta; + + alpha = sqrt(2.0 / (3.0 + sqrt(5.0))); + beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) - + 2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0)))); + /* *INDENT-OFF* */ + dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta; + dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta; + dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1; + dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1; + dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1; + dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1; + dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1; + dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1; + dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1; + dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1; + dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0; + dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0; + dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0; + dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0; + dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta; + dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta; + dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha; + dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha; + dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha; + dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha; + /* *INDENT-ON* */ + +} + +#define DIFF3(_a,_b,_c) { \ + (_c)[0] = (_a)[0] - (_b)[0]; \ + (_c)[1] = (_a)[1] - (_b)[1]; \ + (_c)[2] = (_a)[2] - (_b)[2]; \ +} + +static void +crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3]) +{ + GLfloat p[3]; /* in case prod == v1 or v2 */ + + p[0] = v1[1] * v2[2] - v2[1] * v1[2]; + p[1] = v1[2] * v2[0] - v2[2] * v1[0]; + p[2] = v1[0] * v2[1] - v2[0] * v1[1]; + prod[0] = p[0]; + prod[1] = p[1]; + prod[2] = p[2]; +} + +static void +normalize(GLfloat v[3]) +{ + GLfloat d; + + d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if (d == 0.0) { + __glutWarning("normalize: zero length vector"); + v[0] = d = 1.0; + } + d = 1 / d; + v[0] *= d; + v[1] *= d; + v[2] *= d; +} + +static void +pentagon(int a, int b, int c, int d, int e, GLenum shadeType) +{ + GLfloat n0[3], d1[3], d2[3]; + + DIFF3(dodec[a], dodec[b], d1); + DIFF3(dodec[b], dodec[c], d2); + crossprod(d1, d2, n0); + normalize(n0); + + glBegin(shadeType); + glNormal3fv(n0); + glVertex3fv(&dodec[a][0]); + glVertex3fv(&dodec[b][0]); + glVertex3fv(&dodec[c][0]); + glVertex3fv(&dodec[d][0]); + glVertex3fv(&dodec[e][0]); + glEnd(); +} + +static void +dodecahedron(GLenum type) +{ + static int inited = 0; + + if (inited == 0) { + inited = 1; + initDodecahedron(); + } + pentagon(0, 1, 9, 16, 5, type); + pentagon(1, 0, 3, 18, 7, type); + pentagon(1, 7, 11, 10, 9, type); + pentagon(11, 7, 18, 19, 6, type); + pentagon(8, 17, 16, 9, 10, type); + pentagon(2, 14, 15, 6, 19, type); + pentagon(2, 13, 12, 4, 14, type); + pentagon(2, 19, 18, 3, 13, type); + pentagon(3, 0, 5, 12, 13, type); + pentagon(6, 15, 8, 10, 11, type); + pentagon(4, 17, 8, 15, 14, type); + pentagon(4, 12, 5, 16, 17, type); +} + +/* CENTRY */ +void APIENTRY +glutWireDodecahedron(void) +{ + dodecahedron(GL_LINE_LOOP); +} + +void APIENTRY +glutSolidDodecahedron(void) +{ + dodecahedron(GL_TRIANGLE_FAN); +} + +/* ENDCENTRY */ + +static void +recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3, + GLenum shadeType) +{ + GLfloat q0[3], q1[3]; + + DIFF3(n1, n2, q0); + DIFF3(n2, n3, q1); + crossprod(q0, q1, q1); + normalize(q1); + + glBegin(shadeType); + glNormal3fv(q1); + glVertex3fv(n1); + glVertex3fv(n2); + glVertex3fv(n3); + glEnd(); +} + +static void +subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2, + GLenum shadeType) +{ + int depth; + GLfloat w0[3], w1[3], w2[3]; + GLfloat l; + int i, j, k, n; + + depth = 1; + for (i = 0; i < depth; i++) { + for (j = 0; i + j < depth; j++) { + k = depth - i - j; + for (n = 0; n < 3; n++) { + w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth; + w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n]) + / depth; + w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n]) + / depth; + } + l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]); + w0[0] /= l; + w0[1] /= l; + w0[2] /= l; + l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]); + w1[0] /= l; + w1[1] /= l; + w1[2] /= l; + l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]); + w2[0] /= l; + w2[1] /= l; + w2[2] /= l; + recorditem(w1, w0, w2, shadeType); + } + } +} + +static void +drawtriangle(int i, GLfloat data[][3], int ndx[][3], + GLenum shadeType) +{ + GLfloat *x0, *x1, *x2; + + x0 = data[ndx[i][0]]; + x1 = data[ndx[i][1]]; + x2 = data[ndx[i][2]]; + subdivide(x0, x1, x2, shadeType); +} + +/* octahedron data: The octahedron produced is centered at the + origin and has radius 1.0 */ +static GLfloat odata[6][3] = +{ + {1.0, 0.0, 0.0}, + {-1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, -1.0, 0.0}, + {0.0, 0.0, 1.0}, + {0.0, 0.0, -1.0} +}; + +static int ondex[8][3] = +{ + {0, 4, 2}, + {1, 2, 4}, + {0, 3, 4}, + {1, 4, 3}, + {0, 2, 5}, + {1, 5, 2}, + {0, 5, 3}, + {1, 3, 5} +}; + +static void +octahedron(GLenum shadeType) +{ + int i; + + for (i = 7; i >= 0; i--) { + drawtriangle(i, odata, ondex, shadeType); + } +} + +/* CENTRY */ +void APIENTRY +glutWireOctahedron(void) +{ + octahedron(GL_LINE_LOOP); +} + +void APIENTRY +glutSolidOctahedron(void) +{ + octahedron(GL_TRIANGLES); +} + +/* ENDCENTRY */ + +/* icosahedron data: These numbers are rigged to make an + icosahedron of radius 1.0 */ + +#define X .525731112119133606 +#define Z .850650808352039932 + +static GLfloat idata[12][3] = +{ + {-X, 0, Z}, + {X, 0, Z}, + {-X, 0, -Z}, + {X, 0, -Z}, + {0, Z, X}, + {0, Z, -X}, + {0, -Z, X}, + {0, -Z, -X}, + {Z, X, 0}, + {-Z, X, 0}, + {Z, -X, 0}, + {-Z, -X, 0} +}; + +static int index[20][3] = +{ + {0, 4, 1}, + {0, 9, 4}, + {9, 5, 4}, + {4, 5, 8}, + {4, 8, 1}, + {8, 10, 1}, + {8, 3, 10}, + {5, 3, 8}, + {5, 2, 3}, + {2, 7, 3}, + {7, 10, 3}, + {7, 6, 10}, + {7, 11, 6}, + {11, 0, 6}, + {0, 1, 6}, + {6, 1, 10}, + {9, 0, 11}, + {9, 11, 2}, + {9, 2, 5}, + {7, 2, 11}, +}; + +static void +icosahedron(GLenum shadeType) +{ + int i; + + for (i = 19; i >= 0; i--) { + drawtriangle(i, idata, index, shadeType); + } +} + +/* CENTRY */ +void APIENTRY +glutWireIcosahedron(void) +{ + icosahedron(GL_LINE_LOOP); +} + +void APIENTRY +glutSolidIcosahedron(void) +{ + icosahedron(GL_TRIANGLES); +} + +/* ENDCENTRY */ + +/* tetrahedron data: */ + +#define T 1.73205080756887729 + +static GLfloat tdata[4][3] = +{ + {T, T, T}, + {T, -T, -T}, + {-T, T, -T}, + {-T, -T, T} +}; + +static int tndex[4][3] = +{ + {0, 1, 3}, + {2, 1, 0}, + {3, 2, 0}, + {1, 2, 3} +}; + +static void +tetrahedron(GLenum shadeType) +{ + int i; + + for (i = 3; i >= 0; i--) + drawtriangle(i, tdata, tndex, shadeType); +} + +/* CENTRY */ +void APIENTRY +glutWireTetrahedron(void) +{ + tetrahedron(GL_LINE_LOOP); +} + +void APIENTRY +glutSolidTetrahedron(void) +{ + tetrahedron(GL_TRIANGLES); +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_space.c b/lib/glut-3.7.6/lib/glut/glut_space.c new file mode 100644 index 0000000000..7d43a271d6 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_space.c @@ -0,0 +1,35 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" + +void APIENTRY +glutSpaceballMotionFunc(GLUTspaceMotionCB spaceMotionFunc) +{ + __glutCurrentWindow->spaceMotion = spaceMotionFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} + +void APIENTRY +glutSpaceballRotateFunc(GLUTspaceRotateCB spaceRotateFunc) +{ + __glutCurrentWindow->spaceRotate = spaceRotateFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} + +void APIENTRY +glutSpaceballButtonFunc(GLUTspaceButtonCB spaceButtonFunc) +{ + __glutCurrentWindow->spaceButton = spaceButtonFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} diff --git a/lib/glut-3.7.6/lib/glut/glut_stroke.c b/lib/glut-3.7.6/lib/glut/glut_stroke.c new file mode 100644 index 0000000000..735f4f8999 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_stroke.c @@ -0,0 +1,42 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" +#include "glutstroke.h" + +void APIENTRY +glutStrokeCharacter(GLUTstrokeFont font, int c) +{ + const StrokeCharRec *ch; + const StrokeRec *stroke; + const CoordRec *coord; + StrokeFontPtr fontinfo; + int i, j; + + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + if (c < 0 || c >= fontinfo->num_chars) + return; + ch = &(fontinfo->ch[c]); + if (ch) { + for (i = ch->num_strokes, stroke = ch->stroke; + i > 0; i--, stroke++) { + glBegin(GL_LINE_STRIP); + for (j = stroke->num_coords, coord = stroke->coord; + j > 0; j--, coord++) { + glVertex2f(coord->x, coord->y); + } + glEnd(); + } + glTranslatef(ch->right, 0.0, 0.0); + } +} diff --git a/lib/glut-3.7.6/lib/glut/glut_swap.c b/lib/glut-3.7.6/lib/glut/glut_swap.c new file mode 100644 index 0000000000..9e0ff004f6 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_swap.c @@ -0,0 +1,47 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutSwapBuffers(void) +{ + GLUTwindow *window = __glutCurrentWindow; + + if (window->renderWin == window->win) { + if (__glutCurrentWindow->treatAsSingle) { + /* Pretend the double buffered window is single buffered, + so treat glutSwapBuffers as a no-op. */ + return; + } + } else { + if (__glutCurrentWindow->overlay->treatAsSingle) { + /* Pretend the double buffered overlay is single + buffered, so treat glutSwapBuffers as a no-op. */ + return; + } + } + + /* For the MESA_SWAP_HACK. */ + window->usedSwapBuffers = 1; + + SWAP_BUFFERS_LAYER(__glutCurrentWindow); + + /* I considered putting the window being swapped on the + GLUT_FINISH_WORK work list because you could call + glutSwapBuffers from an idle callback which doesn't call + __glutSetWindow which normally adds indirect rendering + windows to the GLUT_FINISH_WORK work list. Not being put + on the list could lead to the buffering up of multiple + redisplays and buffer swaps and hamper interactivity. I + consider this an application bug due to not using + glutPostRedisplay to trigger redraws. If + glutPostRedisplay were used, __glutSetWindow would be + called and a glFinish to throttle buffering would occur. */ +} +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_swidth.c b/lib/glut-3.7.6/lib/glut/glut_swidth.c new file mode 100644 index 0000000000..db2488b751 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_swidth.c @@ -0,0 +1,58 @@ + +/* Copyright (c) Mark J. Kilgard, 1995. */ + +/* 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 "glutint.h" +#include "glutstroke.h" + +/* CENTRY */ +int APIENTRY +glutStrokeWidth(GLUTstrokeFont font, int c) +{ + StrokeFontPtr fontinfo; + const StrokeCharRec *ch; + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + if (c < 0 || c >= fontinfo->num_chars) + return 0; + ch = &(fontinfo->ch[c]); + if (ch) + return ch->right; + else + return 0; +} + +int APIENTRY +glutStrokeLength(GLUTstrokeFont font, const unsigned char *string) +{ + int c, length; + StrokeFontPtr fontinfo; + const StrokeCharRec *ch; + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + length = 0; + for (; *string != '\0'; string++) { + c = *string; + if (c >= 0 && c < fontinfo->num_chars) { + ch = &(fontinfo->ch[c]); + if (ch) + length += ch->right; + } + } + return length; +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_tablet.c b/lib/glut-3.7.6/lib/glut/glut_tablet.c new file mode 100644 index 0000000000..ae94e840f7 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_tablet.c @@ -0,0 +1,33 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 "glutint.h" + +void APIENTRY +glutTabletMotionFunc(GLUTtabletMotionCB tabletMotionFunc) +{ + __glutCurrentWindow->tabletMotion = tabletMotionFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); + /* If deinstalling callback, invalidate tablet position. */ + if (tabletMotionFunc == NULL) { + __glutCurrentWindow->tabletPos[0] = -1; + __glutCurrentWindow->tabletPos[1] = -1; + } +} + +void APIENTRY +glutTabletButtonFunc(GLUTtabletButtonCB tabletButtonFunc) +{ + __glutCurrentWindow->tabletButton = tabletButtonFunc; + __glutUpdateInputDeviceMaskFunc = __glutUpdateInputDeviceMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_DEVICE_MASK_WORK); +} diff --git a/lib/glut-3.7.6/lib/glut/glut_teapot.c b/lib/glut-3.7.6/lib/glut/glut_teapot.c new file mode 100644 index 0000000000..f1d2a7e586 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_teapot.c @@ -0,0 +1,210 @@ + +/* 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. +*/ + +#include "glutint.h" + +/* Rim, body, lid, and bottom data must be reflected in x and + y; handle and spout data across the y axis only. */ + +static int patchdata[][16] = +{ + /* rim */ + {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15}, + /* body */ + {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27}, + {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40}, + /* lid */ + {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, + 101, 0, 1, 2, 3,}, + {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117}, + /* bottom */ + {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, + 125, 120, 40, 39, 38, 37}, + /* handle */ + {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56}, + {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 28, 65, 66, 67}, + /* spout */ + {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83}, + {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95} +}; +/* *INDENT-OFF* */ + +static float cpdata[][3] = +{ + {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0, + -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125}, + {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375, + 0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375, + 2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84, + 2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875}, + {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75, + 1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35}, + {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2, + 0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12, + 0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225}, + {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225}, + {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0, + -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5, + -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3, + 2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0, + 2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0, + 2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8}, + {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3, + -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3, + 1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2, + -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0, + 1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0, + 0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66, + 0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1}, + {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7, + -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0, + 2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375}, + {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475}, + {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4}, + {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0, + 3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8, + 3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4, + -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0, + 2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4, + 2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3, + 2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4}, + {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425, + -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425, + 0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075}, + {0.84, -1.5, 0.075} +}; + +static float tex[2][2][2] = +{ + { {0, 0}, + {1, 0}}, + { {0, 1}, + {1, 1}} +}; + +/* *INDENT-ON* */ + +static void +teapot(GLint grid, GLdouble scale, GLenum type) +{ + float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3]; + long i, j, k, l; + + glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_MAP2_TEXTURE_COORD_2); + glPushMatrix(); + glRotatef(270.0, 1.0, 0.0, 0.0); + glScalef(0.5 * scale, 0.5 * scale, 0.5 * scale); + glTranslatef(0.0, 0.0, -1.5); + for (i = 0; i < 10; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + for (l = 0; l < 3; l++) { + p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 1) + q[j][k][l] *= -1.0; + if (i < 6) { + r[j][k][l] = + cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 0) + r[j][k][l] *= -1.0; + s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + if (l == 0) + s[j][k][l] *= -1.0; + if (l == 1) + s[j][k][l] *= -1.0; + } + } + } + } + glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, + &tex[0][0][0]); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &p[0][0][0]); + glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &q[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + if (i < 6) { + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &r[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &s[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + } + } + glPopMatrix(); + glPopAttrib(); +} + +/* CENTRY */ +void APIENTRY +glutSolidTeapot(GLdouble scale) +{ + teapot(7, scale, GL_FILL); +} + +void APIENTRY +glutWireTeapot(GLdouble scale) +{ + teapot(10, scale, GL_LINE); +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_tr10.c b/lib/glut-3.7.6/lib/glut/glut_tr10.c new file mode 100644 index 0000000000..ec40e69765 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_tr10.c @@ -0,0 +1,1777 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmapTimesRoman10 XXX +#include "glutbitmap.h" +#undef glutBitmapTimesRoman10 + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0x80,0xc0,0x40,0x60,0xa0,0x90,0xb8,0x0,0xa0, +}; + +static const BitmapCharRec ch255 = {5,9,0,2,5,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0xc0,0x80,0xe0,0x90,0x90,0x90,0xe0,0x80,0x80, +}; + +static const BitmapCharRec ch254 = {4,9,0,2,5,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0x80,0xc0,0x40,0x60,0xa0,0x90,0xb8,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch253 = {5,10,0,2,5,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x68,0x90,0x90,0x90,0x90,0x0,0x50, +}; + +static const BitmapCharRec ch252 = {5,7,0,0,5,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x68,0x90,0x90,0x90,0x90,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch251 = {5,8,0,0,5,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x68,0x90,0x90,0x90,0x90,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch250 = {5,8,0,0,5,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x68,0x90,0x90,0x90,0x90,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch249 = {5,8,0,0,5,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0x80,0x70,0x48,0x48,0x48,0x38,0x4, +}; + +static const BitmapCharRec ch248 = {6,7,1,1,5,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x20,0x0,0xf8,0x0,0x20, +}; + +static const BitmapCharRec ch247 = {5,5,0,0,6,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x60,0x90,0x90,0x90,0x60,0x0,0xa0, +}; + +static const BitmapCharRec ch246 = {4,7,0,0,5,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x60,0x90,0x90,0x90,0x60,0x0,0xa0,0x50, +}; + +static const BitmapCharRec ch245 = {4,8,0,0,5,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x60,0x90,0x90,0x90,0x60,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch244 = {4,8,0,0,5,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x60,0x90,0x90,0x90,0x60,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch243 = {4,8,0,0,5,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x60,0x90,0x90,0x90,0x60,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch242 = {4,8,0,0,5,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0xd8,0x90,0x90,0x90,0xe0,0x0,0xa0,0x50, +}; + +static const BitmapCharRec ch241 = {5,8,0,0,5,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x60,0x90,0x90,0x90,0x70,0xa0,0x70,0x40, +}; + +static const BitmapCharRec ch240 = {4,8,0,0,5,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x0,0xa0, +}; + +static const BitmapCharRec ch239 = {3,7,0,0,4,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch238 = {3,8,0,0,4,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch237 = {3,8,0,0,4,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0xe0,0x40,0x40,0x40,0xc0,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch236 = {3,8,0,0,4,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x60,0x80,0xc0,0xa0,0x60,0x0,0xa0, +}; + +static const BitmapCharRec ch235 = {3,7,0,0,4,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x60,0x80,0xc0,0xa0,0x60,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch234 = {3,8,0,0,4,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x60,0x80,0xc0,0xa0,0x60,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch233 = {3,8,0,0,4,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x60,0x80,0xc0,0xa0,0x60,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch232 = {3,8,0,0,4,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0xc0,0x20,0x40,0x60,0x80,0x80,0x80,0x60, +}; + +static const BitmapCharRec ch231 = {3,8,0,3,4,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0xd8,0xa0,0x70,0x28,0xd8, +}; + +static const BitmapCharRec ch230 = {5,5,0,0,6,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x40,0xa0,0x40, +}; + +static const BitmapCharRec ch229 = {3,8,0,0,4,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x0,0xa0, +}; + +static const BitmapCharRec ch228 = {3,7,0,0,4,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x0,0xa0,0x50, +}; + +static const BitmapCharRec ch227 = {4,8,0,0,4,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch226 = {3,8,0,0,4,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch225 = {3,8,0,0,4,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0xe0,0xa0,0x60,0x20,0xc0,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch224 = {3,8,0,0,4,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0xe0,0x50,0x50,0x60,0x50,0x50,0x20, +}; + +static const BitmapCharRec ch223 = {4,7,0,0,5,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0xe0,0x40,0x70,0x48,0x70,0x40,0xe0, +}; + +static const BitmapCharRec ch222 = {5,7,0,0,6,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x38,0x10,0x10,0x28,0x28,0x44,0xee,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch221 = {7,10,0,0,8,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x38,0x6c,0x44,0x44,0x44,0x44,0xee,0x0,0x28, +}; + +static const BitmapCharRec ch220 = {7,9,0,0,8,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x38,0x6c,0x44,0x44,0x44,0x44,0xee,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch219 = {7,10,0,0,8,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x38,0x6c,0x44,0x44,0x44,0x44,0xee,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch218 = {7,10,0,0,8,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x38,0x6c,0x44,0x44,0x44,0x44,0xee,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch217 = {7,10,0,0,8,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x80,0x7c,0x66,0x52,0x52,0x4a,0x66,0x3e,0x1, +}; + +static const BitmapCharRec ch216 = {8,9,0,1,8,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x88,0x50,0x20,0x50,0x88, +}; + +static const BitmapCharRec ch215 = {5,5,0,0,6,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78,0x0,0x50, +}; + +static const BitmapCharRec ch214 = {6,9,0,0,7,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch213 = {6,10,0,0,7,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch212 = {6,10,0,0,7,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch211 = {6,10,0,0,7,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch210 = {6,10,0,0,7,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0xe4,0x4c,0x4c,0x54,0x54,0x64,0xee,0x0,0x50,0x28, +}; + +static const BitmapCharRec ch209 = {7,10,0,0,8,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0xf8,0x4c,0x44,0xe4,0x44,0x4c,0xf8, +}; + +static const BitmapCharRec ch208 = {6,7,0,0,7,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,0xa0, +}; + +static const BitmapCharRec ch207 = {3,9,0,0,4,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,0xa0,0x40, +}; + +static const BitmapCharRec ch206 = {3,10,0,0,4,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,0x40,0x20, +}; + +static const BitmapCharRec ch205 = {3,10,0,0,4,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,0x40,0x80, +}; + +static const BitmapCharRec ch204 = {3,10,0,0,4,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xf8,0x48,0x40,0x70,0x40,0x48,0xf8,0x0,0x50, +}; + +static const BitmapCharRec ch203 = {5,9,0,0,6,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xf8,0x48,0x40,0x70,0x40,0x48,0xf8,0x0,0x50,0x20, +}; + +static const BitmapCharRec ch202 = {5,10,0,0,6,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xf8,0x48,0x40,0x70,0x40,0x48,0xf8,0x0,0x20,0x10, +}; + +static const BitmapCharRec ch201 = {5,10,0,0,6,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xf8,0x48,0x40,0x70,0x40,0x48,0xf8,0x0,0x20,0x40, +}; + +static const BitmapCharRec ch200 = {5,10,0,0,6,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x60,0x10,0x20,0x78,0xc4,0x80,0x80,0x80,0xc4,0x7c, +}; + +static const BitmapCharRec ch199 = {6,10,0,3,7,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0xef,0x49,0x78,0x2e,0x28,0x39,0x1f, +}; + +static const BitmapCharRec ch198 = {8,7,0,0,9,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x10,0x28,0x10, +}; + +static const BitmapCharRec ch197 = {7,10,0,0,8,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x0,0x28, +}; + +static const BitmapCharRec ch196 = {7,9,0,0,8,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x0,0x28,0x14, +}; + +static const BitmapCharRec ch195 = {7,10,0,0,8,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x0,0x28,0x10, +}; + +static const BitmapCharRec ch194 = {7,10,0,0,8,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x0,0x10,0x8, +}; + +static const BitmapCharRec ch193 = {7,10,0,0,8,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10,0x0,0x10,0x20, +}; + +static const BitmapCharRec ch192 = {7,10,0,0,8,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0xe0,0xa0,0x80,0x40,0x40,0x0,0x40, +}; + +static const BitmapCharRec ch191 = {3,7,0,2,4,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x44,0x3e,0x2c,0xd4,0x28,0x48,0xe4, +}; + +static const BitmapCharRec ch190 = {7,7,0,0,8,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x4e,0x24,0x2a,0xf6,0x48,0xc8,0x44, +}; + +static const BitmapCharRec ch189 = {7,7,0,0,8,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x44,0x3e,0x2c,0xf4,0x48,0xc8,0x44, +}; + +static const BitmapCharRec ch188 = {7,7,0,0,8,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0xa0,0x50,0x50,0xa0, +}; + +static const BitmapCharRec ch187 = {4,4,0,-1,5,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xe0,0x0,0x40,0xa0,0x40, +}; + +static const BitmapCharRec ch186 = {3,5,0,-2,4,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0xe0,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch185 = {3,4,0,-3,3,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0xc0,0x20,0x40, +}; + +static const BitmapCharRec ch184 = {3,3,0,3,4,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0x80, +}; + +static const BitmapCharRec ch183 = {1,1,0,-2,2,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x28,0x28,0x28,0x28,0x68,0xe8,0xe8,0xe8,0x7c, +}; + +static const BitmapCharRec ch182 = {6,9,0,2,6,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x80,0x80,0xe8,0x90,0x90,0x90,0x90, +}; + +static const BitmapCharRec ch181 = {5,7,0,2,5,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0x80,0x40, +}; + +static const BitmapCharRec ch180 = {2,2,0,-5,3,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0xc0,0x20,0x40,0xe0, +}; + +static const BitmapCharRec ch179 = {3,4,0,-3,3,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xe0,0x40,0xa0,0x60, +}; + +static const BitmapCharRec ch178 = {3,4,0,-3,3,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xf8,0x0,0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch177 = {5,7,0,0,6,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch176 = {4,4,0,-3,4,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xe0, +}; + +static const BitmapCharRec ch175 = {3,1,0,-6,4,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x38,0x44,0xaa,0xb2,0xba,0x44,0x38, +}; + +static const BitmapCharRec ch174 = {7,7,-1,0,9,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xe0, +}; + +static const BitmapCharRec ch173 = {3,1,0,-2,4,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x8,0x8,0xf8, +}; + +static const BitmapCharRec ch172 = {5,3,-1,-1,7,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x50,0xa0,0xa0,0x50, +}; + +static const BitmapCharRec ch171 = {4,4,0,-1,5,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0xe0,0x0,0xa0,0x20,0xc0, +}; + +static const BitmapCharRec ch170 = {3,5,0,-2,4,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x38,0x44,0x9a,0xa2,0x9a,0x44,0x38, +}; + +static const BitmapCharRec ch169 = {7,7,-1,0,9,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xa0, +}; + +static const BitmapCharRec ch168 = {3,1,-1,-6,5,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0xe0,0x90,0x20,0x50,0x90,0xa0,0x40,0x90,0x70, +}; + +static const BitmapCharRec ch167 = {4,9,0,1,5,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0x80,0x80,0x80,0x0,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch166 = {1,7,0,0,2,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0x70,0x20,0xf8,0x20,0xd8,0x50,0x88, +}; + +static const BitmapCharRec ch165 = {5,7,0,0,5,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0x88,0x70,0x50,0x50,0x70,0x88, +}; + +static const BitmapCharRec ch164 = {5,6,0,-1,5,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xf0,0xc8,0x40,0xe0,0x40,0x50,0x30, +}; + +static const BitmapCharRec ch163 = {5,7,0,0,5,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x80,0xe0,0x90,0x80,0x90,0x70,0x10, +}; + +static const BitmapCharRec ch162 = {4,7,0,1,5,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0x80,0x80,0x80,0x80,0x80,0x0,0x80, +}; + +static const BitmapCharRec ch161 = {1,7,-1,2,3,ch161data}; + +/* char: 0xa0 */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,2,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,2,0}; +#endif + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x98,0x64, +}; + +static const BitmapCharRec ch126 = {6,2,0,-2,7,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0x80,0x40,0x40,0x40,0x20,0x40,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch125 = {3,9,0,2,4,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch124 = {1,9,0,2,2,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x20,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch123 = {3,9,0,2,4,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xf0,0x90,0x40,0x20,0xf0, +}; + +static const BitmapCharRec ch122 = {4,5,0,0,5,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0x40,0x40,0x20,0x30,0x50,0x48,0xdc, +}; + +static const BitmapCharRec ch121 = {6,7,1,2,5,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0xd8,0x50,0x20,0x50,0xd8, +}; + +static const BitmapCharRec ch120 = {5,5,0,0,6,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x28,0x6c,0x54,0x92,0xdb, +}; + +static const BitmapCharRec ch119 = {8,5,0,0,8,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x20,0x60,0x50,0x90,0xd8, +}; + +static const BitmapCharRec ch118 = {5,5,0,0,5,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x68,0x90,0x90,0x90,0x90, +}; + +static const BitmapCharRec ch117 = {5,5,0,0,5,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x30,0x40,0x40,0x40,0xe0,0x40, +}; + +static const BitmapCharRec ch116 = {4,6,0,0,4,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0xe0,0x20,0x60,0x80,0xe0, +}; + +static const BitmapCharRec ch115 = {3,5,0,0,4,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0xe0,0x40,0x40,0x60,0xa0, +}; + +static const BitmapCharRec ch114 = {3,5,0,0,4,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x38,0x10,0x70,0x90,0x90,0x90,0x70, +}; + +static const BitmapCharRec ch113 = {5,7,0,2,5,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0xc0,0x80,0xe0,0x90,0x90,0x90,0xe0, +}; + +static const BitmapCharRec ch112 = {4,7,0,2,5,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x60,0x90,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch111 = {4,5,0,0,5,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0xd8,0x90,0x90,0x90,0xe0, +}; + +static const BitmapCharRec ch110 = {5,5,0,0,5,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0xdb,0x92,0x92,0x92,0xec, +}; + +static const BitmapCharRec ch109 = {8,5,0,0,8,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xc0, +}; + +static const BitmapCharRec ch108 = {3,7,0,0,4,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0x98,0x90,0xe0,0xa0,0x90,0x80,0x80, +}; + +static const BitmapCharRec ch107 = {5,7,0,0,5,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0x80,0x40,0x40,0x40,0x40,0x40,0xc0,0x0,0x40, +}; + +static const BitmapCharRec ch106 = {2,9,0,2,3,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0x40,0x40,0x40,0x40,0xc0,0x0,0x40, +}; + +static const BitmapCharRec ch105 = {2,7,0,0,3,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0xd8,0x90,0x90,0x90,0xe0,0x80,0x80, +}; + +static const BitmapCharRec ch104 = {5,7,0,0,5,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0xe0,0x90,0x60,0x40,0xa0,0xa0,0x70, +}; + +static const BitmapCharRec ch103 = {4,7,0,2,5,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0xe0,0x40,0x40,0x40,0xe0,0x40,0x30, +}; + +static const BitmapCharRec ch102 = {4,7,0,0,4,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x60,0x80,0xc0,0xa0,0x60, +}; + +static const BitmapCharRec ch101 = {3,5,0,0,4,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x68,0x90,0x90,0x90,0x70,0x10,0x30, +}; + +static const BitmapCharRec ch100 = {5,7,0,0,5,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x60,0x80,0x80,0x80,0x60, +}; + +static const BitmapCharRec ch99 = {3,5,0,0,4,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0xe0,0x90,0x90,0x90,0xe0,0x80,0x80, +}; + +static const BitmapCharRec ch98 = {4,7,0,0,5,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0xe0,0xa0,0x60,0x20,0xc0, +}; + +static const BitmapCharRec ch97 = {3,5,0,0,4,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0xc0,0x80, +}; + +static const BitmapCharRec ch96 = {2,2,0,-5,3,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xf8, +}; + +static const BitmapCharRec ch95 = {5,1,0,3,5,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0xa0,0xa0,0x40, +}; + +static const BitmapCharRec ch94 = {3,3,-1,-4,5,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, +}; + +static const BitmapCharRec ch93 = {2,9,0,2,3,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x20,0x20,0x40,0x40,0x40,0x80,0x80, +}; + +static const BitmapCharRec ch92 = {3,7,0,0,3,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, +}; + +static const BitmapCharRec ch91 = {2,9,0,2,3,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xf8,0x88,0x40,0x20,0x10,0x88,0xf8, +}; + +static const BitmapCharRec ch90 = {5,7,0,0,6,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x38,0x10,0x10,0x28,0x28,0x44,0xee, +}; + +static const BitmapCharRec ch89 = {7,7,0,0,8,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0xee,0x44,0x28,0x10,0x28,0x44,0xee, +}; + +static const BitmapCharRec ch88 = {7,7,0,0,8,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x22,0x0,0x22,0x0,0x55,0x0,0x55,0x0,0xc9,0x80,0x88,0x80,0xdd,0xc0, +}; + +static const BitmapCharRec ch87 = {10,7,0,0,10,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x10,0x10,0x28,0x28,0x6c,0x44,0xee, +}; + +static const BitmapCharRec ch86 = {7,7,0,0,8,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x38,0x6c,0x44,0x44,0x44,0x44,0xee, +}; + +static const BitmapCharRec ch85 = {7,7,0,0,8,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0x70,0x20,0x20,0x20,0x20,0xa8,0xf8, +}; + +static const BitmapCharRec ch84 = {5,7,0,0,6,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0xe0,0x90,0x10,0x60,0xc0,0x90,0x70, +}; + +static const BitmapCharRec ch83 = {4,7,0,0,5,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0xec,0x48,0x50,0x70,0x48,0x48,0xf0, +}; + +static const BitmapCharRec ch82 = {6,7,0,0,7,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0xc,0x18,0x70,0xcc,0x84,0x84,0x84,0xcc,0x78, +}; + +static const BitmapCharRec ch81 = {6,9,0,2,7,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0xe0,0x40,0x40,0x70,0x48,0x48,0xf0, +}; + +static const BitmapCharRec ch80 = {5,7,0,0,6,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x78,0xcc,0x84,0x84,0x84,0xcc,0x78, +}; + +static const BitmapCharRec ch79 = {6,7,0,0,7,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0xe4,0x4c,0x4c,0x54,0x54,0x64,0xee, +}; + +static const BitmapCharRec ch78 = {7,7,0,0,8,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0xeb,0x80,0x49,0x0,0x55,0x0,0x55,0x0,0x63,0x0,0x63,0x0,0xe3,0x80, +}; + +static const BitmapCharRec ch77 = {9,7,0,0,10,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xf8,0x48,0x40,0x40,0x40,0x40,0xe0, +}; + +static const BitmapCharRec ch76 = {5,7,0,0,6,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0xec,0x48,0x50,0x60,0x50,0x48,0xec, +}; + +static const BitmapCharRec ch75 = {6,7,0,0,7,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0xc0,0xa0,0x20,0x20,0x20,0x20,0x70, +}; + +static const BitmapCharRec ch74 = {4,7,0,0,4,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0xe0,0x40,0x40,0x40,0x40,0x40,0xe0, +}; + +static const BitmapCharRec ch73 = {3,7,0,0,4,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0xee,0x44,0x44,0x7c,0x44,0x44,0xee, +}; + +static const BitmapCharRec ch72 = {7,7,0,0,8,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x78,0xc4,0x84,0x9c,0x80,0xc4,0x7c, +}; + +static const BitmapCharRec ch71 = {6,7,0,0,7,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0xe0,0x40,0x40,0x70,0x40,0x48,0xf8, +}; + +static const BitmapCharRec ch70 = {5,7,0,0,6,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xf8,0x48,0x40,0x70,0x40,0x48,0xf8, +}; + +static const BitmapCharRec ch69 = {5,7,0,0,6,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xf8,0x4c,0x44,0x44,0x44,0x4c,0xf8, +}; + +static const BitmapCharRec ch68 = {6,7,0,0,7,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x78,0xc4,0x80,0x80,0x80,0xc4,0x7c, +}; + +static const BitmapCharRec ch67 = {6,7,0,0,7,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xf0,0x48,0x48,0x70,0x48,0x48,0xf0, +}; + +static const BitmapCharRec ch66 = {5,7,0,0,6,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0xee,0x44,0x7c,0x28,0x28,0x38,0x10, +}; + +static const BitmapCharRec ch65 = {7,7,0,0,8,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x3e,0x40,0x92,0xad,0xa5,0xa5,0x9d,0x42,0x3c, +}; + +static const BitmapCharRec ch64 = {8,9,0,2,9,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x40,0x0,0x40,0x40,0x20,0xa0,0xe0, +}; + +static const BitmapCharRec ch63 = {3,7,0,0,4,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0x80,0x40,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch62 = {3,5,0,0,5,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xf8,0x0,0xf8, +}; + +static const BitmapCharRec ch61 = {5,3,0,-1,6,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x20,0x40,0x80,0x40,0x20, +}; + +static const BitmapCharRec ch60 = {3,5,-1,0,5,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0x80,0x80,0x80,0x0,0x0,0x0,0x80, +}; + +static const BitmapCharRec ch59 = {1,7,-1,2,3,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0x80,0x0,0x0,0x0,0x80, +}; + +static const BitmapCharRec ch58 = {1,5,-1,0,3,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0xc0,0x20,0x70,0x90,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch57 = {4,7,0,0,5,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x60,0x90,0x90,0x60,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch56 = {4,7,0,0,5,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x40,0x40,0x40,0x20,0x20,0x90,0xf0, +}; + +static const BitmapCharRec ch55 = {4,7,0,0,5,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x60,0x90,0x90,0x90,0xe0,0x40,0x30, +}; + +static const BitmapCharRec ch54 = {4,7,0,0,5,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0xe0,0x90,0x10,0x10,0xe0,0x40,0x70, +}; + +static const BitmapCharRec ch53 = {4,7,0,0,5,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x10,0x10,0xf8,0x90,0x50,0x30,0x10, +}; + +static const BitmapCharRec ch52 = {5,7,0,0,5,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0xe0,0x10,0x10,0x60,0x10,0x90,0x60, +}; + +static const BitmapCharRec ch51 = {4,7,0,0,5,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xf0,0x40,0x20,0x20,0x10,0x90,0x60, +}; + +static const BitmapCharRec ch50 = {4,7,0,0,5,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0xe0,0x40,0x40,0x40,0x40,0xc0,0x40, +}; + +static const BitmapCharRec ch49 = {3,7,-1,0,5,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x60,0x90,0x90,0x90,0x90,0x90,0x60, +}; + +static const BitmapCharRec ch48 = {4,7,0,0,5,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0x80,0x80,0x40,0x40,0x40,0x20,0x20, +}; + +static const BitmapCharRec ch47 = {3,7,0,0,3,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0x80, +}; + +static const BitmapCharRec ch46 = {1,1,-1,0,3,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xf0, +}; + +static const BitmapCharRec ch45 = {4,1,-1,-2,7,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0x80,0x80,0x80, +}; + +static const BitmapCharRec ch44 = {1,3,-1,2,3,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x20,0x20,0xf8,0x20,0x20, +}; + +static const BitmapCharRec ch43 = {5,5,0,0,6,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0xa0,0x40,0xa0, +}; + +static const BitmapCharRec ch42 = {3,3,0,-4,5,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x40,0x20,0x20,0x20,0x40,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {3,9,0,2,4,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x20,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20, +}; + +static const BitmapCharRec ch40 = {3,9,0,2,4,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0x40,0xc0, +}; + +static const BitmapCharRec ch39 = {2,2,0,-5,3,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x76,0x8d,0x98,0x74,0x6e,0x50,0x30, +}; + +static const BitmapCharRec ch38 = {8,7,0,0,8,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x44,0x2a,0x2a,0x56,0xa8,0xa4,0x7e, +}; + +static const BitmapCharRec ch37 = {7,7,0,0,8,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x20,0xe0,0x90,0x10,0x60,0x80,0x90,0x70,0x20, +}; + +static const BitmapCharRec ch36 = {4,9,0,1,5,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x50,0x50,0xf8,0x50,0xf8,0x50,0x50, +}; + +static const BitmapCharRec ch35 = {5,7,0,0,5,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0xa0,0xa0, +}; + +static const BitmapCharRec ch34 = {3,2,0,-5,4,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0x80,0x0,0x80,0x80,0x80,0x80,0x80, +}; + +static const BitmapCharRec ch33 = {1,7,-1,0,3,ch33data}; + +/* char: 0x20 ' ' */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,2,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,2,0}; +#endif + +static const BitmapCharRec * const chars[] = { +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmapTimesRoman10 = { +"-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", +224, +32, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_tr24.c b/lib/glut-3.7.6/lib/glut/glut_tr24.c new file mode 100644 index 0000000000..8476636d74 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_tr24.c @@ -0,0 +1,2060 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#define glutBitmapTimesRoman24 XXX +#include "glutbitmap.h" +#undef glutBitmapTimesRoman24 + +/* char: 0xff */ + +static const GLubyte ch255data[] = { +0xe0,0x0,0xf0,0x0,0x18,0x0,0x8,0x0,0xc,0x0,0x4,0x0,0xe,0x0,0xe,0x0, +0x1a,0x0,0x19,0x0,0x19,0x0,0x31,0x0,0x30,0x80,0x30,0x80,0x60,0x80,0x60,0xc0, +0xf1,0xe0,0x0,0x0,0x0,0x0,0x33,0x0,0x33,0x0, +}; + +static const BitmapCharRec ch255 = {11,21,0,5,11,ch255data}; + +/* char: 0xfe */ + +static const GLubyte ch254data[] = { +0xf0,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x6e,0x0,0x73,0x80,0x61,0x80, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x61,0x80,0x73,0x80, +0x6e,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0xe0,0x0, +}; + +static const BitmapCharRec ch254 = {10,22,-1,5,12,ch254data}; + +/* char: 0xfd */ + +static const GLubyte ch253data[] = { +0xe0,0x0,0xf0,0x0,0x18,0x0,0x8,0x0,0xc,0x0,0x4,0x0,0xe,0x0,0xe,0x0, +0x1a,0x0,0x19,0x0,0x19,0x0,0x31,0x0,0x30,0x80,0x30,0x80,0x60,0x80,0x60,0xc0, +0xf1,0xe0,0x0,0x0,0x8,0x0,0x6,0x0,0x3,0x80,0x1,0x80, +}; + +static const BitmapCharRec ch253 = {11,22,0,5,11,ch253data}; + +/* char: 0xfc */ + +static const GLubyte ch252data[] = { +0x1c,0xe0,0x3e,0xc0,0x71,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0xe1,0xc0,0x0,0x0,0x0,0x0,0x33,0x0,0x33,0x0, +}; + +static const BitmapCharRec ch252 = {11,16,-1,0,13,ch252data}; + +/* char: 0xfb */ + +static const GLubyte ch251data[] = { +0x1c,0xe0,0x3e,0xc0,0x71,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0xe1,0xc0,0x0,0x0,0x21,0x0,0x12,0x0,0x1e,0x0, +0xc,0x0, +}; + +static const BitmapCharRec ch251 = {11,17,-1,0,13,ch251data}; + +/* char: 0xfa */ + +static const GLubyte ch250data[] = { +0x1c,0xe0,0x3e,0xc0,0x71,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0xe1,0xc0,0x0,0x0,0x8,0x0,0x6,0x0,0x3,0x80, +0x1,0x80, +}; + +static const BitmapCharRec ch250 = {11,17,-1,0,13,ch250data}; + +/* char: 0xf9 */ + +static const GLubyte ch249data[] = { +0x1c,0xe0,0x3e,0xc0,0x71,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0xe1,0xc0,0x0,0x0,0x2,0x0,0xc,0x0,0x38,0x0, +0x30,0x0, +}; + +static const BitmapCharRec ch249 = {11,17,-1,0,13,ch249data}; + +/* char: 0xf8 */ + +static const GLubyte ch248data[] = { +0xc0,0x0,0xde,0x0,0x73,0x80,0x71,0x80,0xd0,0xc0,0xd8,0xc0,0xc8,0xc0,0xcc,0xc0, +0xc4,0xc0,0xc6,0xc0,0x63,0x80,0x73,0x80,0x1e,0xc0,0x0,0xc0, +}; + +static const BitmapCharRec ch248 = {10,14,-1,1,12,ch248data}; + +/* char: 0xf7 */ + +static const GLubyte ch247data[] = { +0x6,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0xff,0xf0,0xff,0xf0,0x0,0x0,0x0,0x0, +0x6,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch247 = {12,10,-1,-2,14,ch247data}; + +/* char: 0xf6 */ + +static const GLubyte ch246data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0,0x0,0x0,0x0,0x0,0x33,0x0,0x33,0x0, +}; + +static const BitmapCharRec ch246 = {10,16,-1,0,12,ch246data}; + +/* char: 0xf5 */ + +static const GLubyte ch245data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0,0x0,0x0,0x0,0x0,0x27,0x0,0x1c,0x80, +}; + +static const BitmapCharRec ch245 = {10,16,-1,0,12,ch245data}; + +/* char: 0xf4 */ + +static const GLubyte ch244data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0,0x0,0x0,0x21,0x0,0x12,0x0,0x1e,0x0, +0xc,0x0, +}; + +static const BitmapCharRec ch244 = {10,17,-1,0,12,ch244data}; + +/* char: 0xf3 */ + +static const GLubyte ch243data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0,0x0,0x0,0x8,0x0,0x6,0x0,0x3,0x80, +0x1,0x80, +}; + +static const BitmapCharRec ch243 = {10,17,-1,0,12,ch243data}; + +/* char: 0xf2 */ + +static const GLubyte ch242data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0,0x0,0x0,0x2,0x0,0xc,0x0,0x38,0x0, +0x30,0x0, +}; + +static const BitmapCharRec ch242 = {10,17,-1,0,12,ch242data}; + +/* char: 0xf1 */ + +static const GLubyte ch241data[] = { +0xf1,0xe0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x71,0xc0,0x6f,0x80,0xe7,0x0,0x0,0x0,0x0,0x0,0x27,0x0,0x1c,0x80, +}; + +static const BitmapCharRec ch241 = {11,16,-1,0,13,ch241data}; + +/* char: 0xf0 */ + +static const GLubyte ch240data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1f,0x0,0xc6,0x0,0x3c,0x0,0x1e,0x0,0x71,0x80, +0xc0,0x0, +}; + +static const BitmapCharRec ch240 = {10,17,-1,0,12,ch240data}; + +/* char: 0xef */ + +static const GLubyte ch239data[] = { +0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70,0x0,0x0,0xcc,0xcc, +}; + +static const BitmapCharRec ch239 = {6,16,0,0,6,ch239data}; + +/* char: 0xee */ + +static const GLubyte ch238data[] = { +0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70,0x0,0x84,0x48,0x78, +0x30, +}; + +static const BitmapCharRec ch238 = {6,17,0,0,6,ch238data}; + +/* char: 0xed */ + +static const GLubyte ch237data[] = { +0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xe0,0x0,0x80,0x60,0x38, +0x18, +}; + +static const BitmapCharRec ch237 = {5,17,-1,0,6,ch237data}; + +/* char: 0xec */ + +static const GLubyte ch236data[] = { +0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70,0x0,0x8,0x30,0xe0, +0xc0, +}; + +static const BitmapCharRec ch236 = {5,17,0,0,6,ch236data}; + +/* char: 0xeb */ + +static const GLubyte ch235data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80, +0xc1,0x80,0x41,0x80,0x63,0x0,0x1e,0x0,0x0,0x0,0x0,0x0,0x33,0x0,0x33,0x0, +}; + +static const BitmapCharRec ch235 = {9,16,-1,0,11,ch235data}; + +/* char: 0xea */ + +static const GLubyte ch234data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80, +0xc1,0x80,0x41,0x80,0x63,0x0,0x1e,0x0,0x0,0x0,0x21,0x0,0x12,0x0,0x1e,0x0, +0xc,0x0, +}; + +static const BitmapCharRec ch234 = {9,17,-1,0,11,ch234data}; + +/* char: 0xe9 */ + +static const GLubyte ch233data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80, +0xc1,0x80,0x41,0x80,0x63,0x0,0x1e,0x0,0x0,0x0,0x10,0x0,0xc,0x0,0x7,0x0, +0x3,0x0, +}; + +static const BitmapCharRec ch233 = {9,17,-1,0,11,ch233data}; + +/* char: 0xe8 */ + +static const GLubyte ch232data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80, +0xc1,0x80,0x41,0x80,0x63,0x0,0x1e,0x0,0x0,0x0,0x4,0x0,0x18,0x0,0x70,0x0, +0x60,0x0, +}; + +static const BitmapCharRec ch232 = {9,17,-1,0,11,ch232data}; + +/* char: 0xe7 */ + +static const GLubyte ch231data[] = { +0x3c,0x0,0x66,0x0,0x6,0x0,0x1e,0x0,0x18,0x0,0x8,0x0,0x1e,0x0,0x7f,0x0, +0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0x41,0x80, +0x63,0x80,0x1f,0x0, +}; + +static const BitmapCharRec ch231 = {9,18,-1,6,11,ch231data}; + +/* char: 0xe6 */ + +static const GLubyte ch230data[] = { +0x70,0xf0,0xfb,0xf8,0xc7,0x84,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0xfc, +0x3,0xc,0x63,0xc,0x67,0x98,0x3c,0xf0, +}; + +static const BitmapCharRec ch230 = {14,12,-1,0,16,ch230data}; + +/* char: 0xe5 */ + +static const GLubyte ch229data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x1c,0x0,0x22,0x0,0x22,0x0, +0x1c,0x0, +}; + +static const BitmapCharRec ch229 = {9,17,-1,0,11,ch229data}; + +/* char: 0xe4 */ + +static const GLubyte ch228data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x0,0x0,0x66,0x0,0x66,0x0, +}; + +static const BitmapCharRec ch228 = {9,16,-1,0,11,ch228data}; + +/* char: 0xe3 */ + +static const GLubyte ch227data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x0,0x0,0x5c,0x0,0x3a,0x0, +}; + +static const BitmapCharRec ch227 = {9,16,-1,0,11,ch227data}; + +/* char: 0xe2 */ + +static const GLubyte ch226data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x42,0x0,0x24,0x0,0x3c,0x0, +0x18,0x0, +}; + +static const BitmapCharRec ch226 = {9,17,-1,0,11,ch226data}; + +/* char: 0xe1 */ + +static const GLubyte ch225data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x10,0x0,0xc,0x0,0x7,0x0, +0x3,0x0, +}; + +static const BitmapCharRec ch225 = {9,17,-1,0,11,ch225data}; + +/* char: 0xe0 */ + +static const GLubyte ch224data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0,0x0,0x0,0x4,0x0,0x18,0x0,0x70,0x0, +0x60,0x0, +}; + +static const BitmapCharRec ch224 = {9,17,-1,0,11,ch224data}; + +/* char: 0xdf */ + +static const GLubyte ch223data[] = { +0xe7,0x0,0x6c,0x80,0x6c,0xc0,0x60,0xc0,0x60,0xc0,0x61,0xc0,0x61,0x80,0x63,0x80, +0x67,0x0,0x6c,0x0,0x63,0x0,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x0, +0x1e,0x0, +}; + +static const BitmapCharRec ch223 = {10,17,-1,0,12,ch223data}; + +/* char: 0xde */ + +static const GLubyte ch222data[] = { +0xfc,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x3f,0xc0,0x30,0x70,0x30,0x30,0x30,0x18, +0x30,0x18,0x30,0x18,0x30,0x30,0x30,0x70,0x3f,0xc0,0x30,0x0,0x30,0x0,0x30,0x0, +0xfc,0x0, +}; + +static const BitmapCharRec ch222 = {13,17,-1,0,15,ch222data}; + +/* char: 0xdd */ + +static const GLubyte ch221data[] = { +0x7,0xe0,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x3,0xc0, +0x3,0x40,0x6,0x60,0x6,0x20,0xc,0x30,0x1c,0x10,0x18,0x18,0x38,0x8,0x30,0xc, +0xfc,0x3f,0x0,0x0,0x1,0x0,0x0,0xc0,0x0,0x70,0x0,0x30, +}; + +static const BitmapCharRec ch221 = {16,22,0,0,16,ch221data}; + +/* char: 0xdc */ + +static const GLubyte ch220data[] = { +0x7,0xe0,0x1c,0x30,0x18,0x8,0x30,0x8,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0xfc,0x1f,0x0,0x0,0x0,0x0,0x6,0x30,0x6,0x30, +}; + +static const BitmapCharRec ch220 = {16,21,-1,0,18,ch220data}; + +/* char: 0xdb */ + +static const GLubyte ch219data[] = { +0x7,0xe0,0x1c,0x30,0x18,0x8,0x30,0x8,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0xfc,0x1f,0x0,0x0,0x8,0x10,0x6,0x60,0x3,0xc0,0x1,0x80, +}; + +static const BitmapCharRec ch219 = {16,22,-1,0,18,ch219data}; + +/* char: 0xda */ + +static const GLubyte ch218data[] = { +0x7,0xe0,0x1c,0x30,0x18,0x8,0x30,0x8,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0xfc,0x1f,0x0,0x0,0x1,0x0,0x0,0xc0,0x0,0x70,0x0,0x30, +}; + +static const BitmapCharRec ch218 = {16,22,-1,0,18,ch218data}; + +/* char: 0xd9 */ + +static const GLubyte ch217data[] = { +0x7,0xe0,0x1c,0x30,0x18,0x8,0x30,0x8,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0xfc,0x1f,0x0,0x0,0x0,0x40,0x1,0x80,0x7,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch217 = {16,22,-1,0,18,ch217data}; + +/* char: 0xd8 */ + +static const GLubyte ch216data[] = { +0x20,0x0,0x27,0xe0,0x1c,0x38,0x38,0x1c,0x68,0x6,0x64,0x6,0xc2,0x3,0xc2,0x3, +0xc1,0x3,0xc1,0x3,0xc0,0x83,0xc0,0x83,0xc0,0x43,0x60,0x46,0x60,0x26,0x38,0x1c, +0x1c,0x38,0x7,0xe4,0x0,0x4, +}; + +static const BitmapCharRec ch216 = {16,19,-1,1,18,ch216data}; + +/* char: 0xd7 */ + +static const GLubyte ch215data[] = { +0x80,0x40,0xc0,0xc0,0x61,0x80,0x33,0x0,0x1e,0x0,0xc,0x0,0x1e,0x0,0x33,0x0, +0x61,0x80,0xc0,0xc0,0x80,0x40, +}; + +static const BitmapCharRec ch215 = {10,11,-2,-1,14,ch215data}; + +/* char: 0xd6 */ + +static const GLubyte ch214data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0,0x0,0x0,0x0,0x0,0x6,0x60,0x6,0x60, +}; + +static const BitmapCharRec ch214 = {16,21,-1,0,18,ch214data}; + +/* char: 0xd5 */ + +static const GLubyte ch213data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0,0x0,0x0,0x0,0x0,0x4,0xe0,0x3,0x90, +}; + +static const BitmapCharRec ch213 = {16,21,-1,0,18,ch213data}; + +/* char: 0xd4 */ + +static const GLubyte ch212data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0,0x0,0x0,0x8,0x10,0x6,0x60,0x3,0xc0,0x1,0x80, +}; + +static const BitmapCharRec ch212 = {16,22,-1,0,18,ch212data}; + +/* char: 0xd3 */ + +static const GLubyte ch211data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0,0x0,0x0,0x1,0x0,0x0,0xc0,0x0,0x70,0x0,0x30, +}; + +static const BitmapCharRec ch211 = {16,22,-1,0,18,ch211data}; + +/* char: 0xd2 */ + +static const GLubyte ch210data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0,0x0,0x0,0x0,0x40,0x1,0x80,0x7,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch210 = {16,22,-1,0,18,ch210data}; + +/* char: 0xd1 */ + +static const GLubyte ch209data[] = { +0xf8,0xc,0x20,0x1c,0x20,0x1c,0x20,0x34,0x20,0x64,0x20,0x64,0x20,0xc4,0x21,0x84, +0x21,0x84,0x23,0x4,0x26,0x4,0x26,0x4,0x2c,0x4,0x38,0x4,0x38,0x4,0x30,0x4, +0xf0,0x1f,0x0,0x0,0x0,0x0,0x4,0xe0,0x3,0x90, +}; + +static const BitmapCharRec ch209 = {16,21,-1,0,18,ch209data}; + +/* char: 0xd0 */ + +static const GLubyte ch208data[] = { +0x7f,0xe0,0x18,0x38,0x18,0x1c,0x18,0x6,0x18,0x6,0x18,0x3,0x18,0x3,0x18,0x3, +0xff,0x3,0x18,0x3,0x18,0x3,0x18,0x3,0x18,0x6,0x18,0x6,0x18,0x1c,0x18,0x38, +0x7f,0xe0, +}; + +static const BitmapCharRec ch208 = {16,17,0,0,17,ch208data}; + +/* char: 0xcf */ + +static const GLubyte ch207data[] = { +0xfc,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0xfc,0x0,0x0,0xcc,0xcc, +}; + +static const BitmapCharRec ch207 = {6,21,-1,0,8,ch207data}; + +/* char: 0xce */ + +static const GLubyte ch206data[] = { +0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x7e,0x0,0x81,0x66,0x3c,0x18, +}; + +static const BitmapCharRec ch206 = {8,22,-1,0,8,ch206data}; + +/* char: 0xcd */ + +static const GLubyte ch205data[] = { +0xfc,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0xfc,0x0,0x40,0x30,0x1c,0xc, +}; + +static const BitmapCharRec ch205 = {6,22,-1,0,8,ch205data}; + +/* char: 0xcc */ + +static const GLubyte ch204data[] = { +0xfc,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0xfc,0x0,0x8,0x30,0xe0,0xc0, +}; + +static const BitmapCharRec ch204 = {6,22,-1,0,8,ch204data}; + +/* char: 0xcb */ + +static const GLubyte ch203data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x40,0x30,0x40, +0x3f,0xc0,0x30,0x40,0x30,0x40,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0,0x0,0x0,0x0,0x0,0x19,0x80,0x19,0x80, +}; + +static const BitmapCharRec ch203 = {13,21,-1,0,15,ch203data}; + +/* char: 0xca */ + +static const GLubyte ch202data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x40,0x30,0x40, +0x3f,0xc0,0x30,0x40,0x30,0x40,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0,0x0,0x0,0x10,0x20,0xc,0xc0,0x7,0x80,0x3,0x0, +}; + +static const BitmapCharRec ch202 = {13,22,-1,0,15,ch202data}; + +/* char: 0xc9 */ + +static const GLubyte ch201data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x40,0x30,0x40, +0x3f,0xc0,0x30,0x40,0x30,0x40,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0,0x0,0x0,0x4,0x0,0x3,0x0,0x1,0xc0,0x0,0xc0, +}; + +static const BitmapCharRec ch201 = {13,22,-1,0,15,ch201data}; + +/* char: 0xc8 */ + +static const GLubyte ch200data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x40,0x30,0x40, +0x3f,0xc0,0x30,0x40,0x30,0x40,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0,0x0,0x0,0x1,0x0,0x6,0x0,0x1c,0x0,0x18,0x0, +}; + +static const BitmapCharRec ch200 = {13,22,-1,0,15,ch200data}; + +/* char: 0xc7 */ + +static const GLubyte ch199data[] = { +0x7,0x80,0xc,0xc0,0x0,0xc0,0x3,0xc0,0x3,0x0,0x1,0x0,0x7,0xe0,0x1e,0x38, +0x38,0x8,0x60,0x4,0x60,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +0xc0,0x0,0xc0,0x0,0x60,0x4,0x60,0x4,0x38,0xc,0x1c,0x3c,0x7,0xe4, +}; + +static const BitmapCharRec ch199 = {14,23,-1,6,16,ch199data}; + +/* char: 0xc6 */ + +static const GLubyte ch198data[] = { +0xf9,0xff,0xf0,0x30,0x60,0x30,0x10,0x60,0x10,0x10,0x60,0x10,0x18,0x60,0x0,0x8, +0x60,0x0,0xf,0xe0,0x80,0xc,0x60,0x80,0x4,0x7f,0x80,0x4,0x60,0x80,0x6,0x60, +0x80,0x2,0x60,0x0,0x2,0x60,0x0,0x1,0x60,0x20,0x1,0x60,0x20,0x1,0xe0,0x60, +0x3,0xff,0xe0, +}; + +static const BitmapCharRec ch198 = {20,17,0,0,21,ch198data}; + +/* char: 0xc5 */ + +static const GLubyte ch197data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x1,0xc0,0x0,0x2,0x20,0x0,0x2,0x20,0x0,0x1,0xc0,0x0, +}; + +static const BitmapCharRec ch197 = {17,21,0,0,17,ch197data}; + +/* char: 0xc4 */ + +static const GLubyte ch196data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x30,0x0,0x6,0x30,0x0, +}; + +static const BitmapCharRec ch196 = {17,21,0,0,17,ch196data}; + +/* char: 0xc3 */ + +static const GLubyte ch195data[] = { +0xfc,0x1f,0x80,0x30,0x7,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xe0,0x0,0x3,0x90,0x0, +}; + +static const BitmapCharRec ch195 = {17,21,0,0,17,ch195data}; + +/* char: 0xc2 */ + +static const GLubyte ch194data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x0,0x0,0x0,0x8,0x10,0x0,0x6,0x60,0x0,0x3,0xc0,0x0,0x1, +0x80,0x0, +}; + +static const BitmapCharRec ch194 = {17,22,0,0,17,ch194data}; + +/* char: 0xc1 */ + +static const GLubyte ch193data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0xc0,0x0,0x0,0x70,0x0,0x0, +0x30,0x0, +}; + +static const BitmapCharRec ch193 = {17,22,0,0,17,ch193data}; + +/* char: 0xc0 */ + +static const GLubyte ch192data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0xc0,0x0,0x3,0x80,0x0,0x3, +0x0,0x0, +}; + +static const BitmapCharRec ch192 = {17,22,0,0,17,ch192data}; + +/* char: 0xbf */ + +static const GLubyte ch191data[] = { +0x3e,0x63,0xc1,0xc3,0xc3,0xe0,0x70,0x30,0x38,0x18,0x18,0x8,0x8,0x0,0x0,0xc, +0xc, +}; + +static const BitmapCharRec ch191 = {8,17,-1,5,11,ch191data}; + +/* char: 0xbe */ + +static const GLubyte ch190data[] = { +0x18,0x2,0x0,0x8,0x2,0x0,0xc,0x7f,0x80,0x4,0x22,0x0,0x6,0x32,0x0,0x3, +0x12,0x0,0x1,0xa,0x0,0x71,0x8e,0x0,0x88,0x86,0x0,0x8c,0xc2,0x0,0xc,0x60, +0x0,0x8,0x20,0x0,0x30,0x30,0x0,0x8,0x10,0x0,0x8c,0x18,0x0,0x4c,0xc,0x0, +0x38,0x4,0x0, +}; + +static const BitmapCharRec ch190 = {17,17,0,0,18,ch190data}; + +/* char: 0xbd */ + +static const GLubyte ch189data[] = { +0x30,0x7e,0x10,0x22,0x18,0x10,0x8,0x18,0xc,0x8,0x6,0x4,0x2,0x6,0xfb,0x46, +0x21,0x26,0x21,0x9c,0x20,0xc0,0x20,0x40,0x20,0x60,0x20,0x20,0xa0,0x30,0x60,0x18, +0x20,0x8, +}; + +static const BitmapCharRec ch189 = {15,17,-1,0,18,ch189data}; + +/* char: 0xbc */ + +static const GLubyte ch188data[] = { +0x30,0x4,0x10,0x4,0x18,0xff,0x8,0x44,0xc,0x64,0x6,0x24,0x2,0x14,0xfb,0x1c, +0x21,0xc,0x21,0x84,0x20,0xc0,0x20,0x40,0x20,0x60,0x20,0x20,0xa0,0x30,0x60,0x18, +0x20,0x8, +}; + +static const BitmapCharRec ch188 = {16,17,-1,0,18,ch188data}; + +/* char: 0xbb */ + +static const GLubyte ch187data[] = { +0x88,0x0,0xcc,0x0,0x66,0x0,0x33,0x0,0x19,0x80,0x19,0x80,0x33,0x0,0x66,0x0, +0xcc,0x0,0x88,0x0, +}; + +static const BitmapCharRec ch187 = {9,10,-2,-1,12,ch187data}; + +/* char: 0xba */ + +static const GLubyte ch186data[] = { +0xfc,0x0,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0x78, +}; + +static const BitmapCharRec ch186 = {6,9,-1,-8,8,ch186data}; + +/* char: 0xb9 */ + +static const GLubyte ch185data[] = { +0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x60,0x20, +}; + +static const BitmapCharRec ch185 = {5,10,-1,-7,7,ch185data}; + +/* char: 0xb8 */ + +static const GLubyte ch184data[] = { +0x78,0xcc,0xc,0x3c,0x30,0x10, +}; + +static const BitmapCharRec ch184 = {6,6,-1,6,8,ch184data}; + +/* char: 0xb7 */ + +static const GLubyte ch183data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch183 = {2,2,-2,-6,6,ch183data}; + +/* char: 0xb6 */ + +static const GLubyte ch182data[] = { +0x9,0x0,0x9,0x0,0x9,0x0,0x9,0x0,0x9,0x0,0x9,0x0,0x9,0x0,0x9,0x0, +0x9,0x0,0x9,0x0,0x9,0x0,0x19,0x0,0x39,0x0,0x79,0x0,0x79,0x0,0xf9,0x0, +0xf9,0x0,0xf9,0x0,0x79,0x0,0x79,0x0,0x39,0x0,0x1f,0x80, +}; + +static const BitmapCharRec ch182 = {9,22,-1,5,11,ch182data}; + +/* char: 0xb5 */ + +static const GLubyte ch181data[] = { +0x40,0x0,0xe0,0x0,0xc0,0x0,0x40,0x0,0x40,0x0,0x5c,0xe0,0x7e,0xc0,0x71,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0xe1,0xc0, +}; + +static const BitmapCharRec ch181 = {11,17,-1,5,13,ch181data}; + +/* char: 0xb4 */ + +static const GLubyte ch180data[] = { +0x80,0x60,0x38,0x18, +}; + +static const BitmapCharRec ch180 = {5,4,-2,-13,8,ch180data}; + +/* char: 0xb3 */ + +static const GLubyte ch179data[] = { +0x70,0x88,0x8c,0xc,0x8,0x30,0x8,0x8c,0x4c,0x38, +}; + +static const BitmapCharRec ch179 = {6,10,0,-7,7,ch179data}; + +/* char: 0xb2 */ + +static const GLubyte ch178data[] = { +0xfc,0x44,0x20,0x30,0x10,0x8,0xc,0x8c,0x4c,0x38, +}; + +static const BitmapCharRec ch178 = {6,10,0,-7,7,ch178data}; + +/* char: 0xb1 */ + +static const GLubyte ch177data[] = { +0xff,0xf0,0xff,0xf0,0x0,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0, +0xff,0xf0,0xff,0xf0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch177 = {12,15,-1,0,14,ch177data}; + +/* char: 0xb0 */ + +static const GLubyte ch176data[] = { +0x38,0x44,0x82,0x82,0x82,0x44,0x38, +}; + +static const BitmapCharRec ch176 = {7,7,-1,-10,9,ch176data}; + +/* char: 0xaf */ + +static const GLubyte ch175data[] = { +0xfc,0xfc, +}; + +static const BitmapCharRec ch175 = {6,2,-1,-14,8,ch175data}; + +/* char: 0xae */ + +static const GLubyte ch174data[] = { +0x7,0xf0,0x0,0x1c,0x1c,0x0,0x30,0x6,0x0,0x60,0x3,0x0,0x47,0x19,0x0,0xc2, +0x31,0x80,0x82,0x20,0x80,0x82,0x40,0x80,0x83,0xe0,0x80,0x82,0x30,0x80,0x82,0x10, +0x80,0xc2,0x11,0x80,0x42,0x31,0x0,0x67,0xe3,0x0,0x30,0x6,0x0,0x1c,0x1c,0x0, +0x7,0xf0,0x0, +}; + +static const BitmapCharRec ch174 = {17,17,-1,0,19,ch174data}; + +/* char: 0xad */ + +static const GLubyte ch173data[] = { +0xfe,0xfe, +}; + +static const BitmapCharRec ch173 = {7,2,-1,-5,9,ch173data}; + +/* char: 0xac */ + +static const GLubyte ch172data[] = { +0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0xff,0xf0,0xff,0xf0, +}; + +static const BitmapCharRec ch172 = {12,7,-1,-3,14,ch172data}; + +/* char: 0xab */ + +static const GLubyte ch171data[] = { +0x8,0x80,0x19,0x80,0x33,0x0,0x66,0x0,0xcc,0x0,0xcc,0x0,0x66,0x0,0x33,0x0, +0x19,0x80,0x8,0x80, +}; + +static const BitmapCharRec ch171 = {9,10,-2,-1,13,ch171data}; + +/* char: 0xaa */ + +static const GLubyte ch170data[] = { +0x7e,0x0,0x76,0xcc,0xcc,0x7c,0xc,0xcc,0x78, +}; + +static const BitmapCharRec ch170 = {7,9,0,-8,8,ch170data}; + +/* char: 0xa9 */ + +static const GLubyte ch169data[] = { +0x7,0xf0,0x0,0x1c,0x1c,0x0,0x30,0x6,0x0,0x61,0xc3,0x0,0x47,0x71,0x0,0xc4, +0x19,0x80,0x8c,0x0,0x80,0x88,0x0,0x80,0x88,0x0,0x80,0x88,0x0,0x80,0x8c,0x0, +0x80,0xc4,0x19,0x80,0x47,0x31,0x0,0x61,0xe3,0x0,0x30,0x6,0x0,0x1c,0x1c,0x0, +0x7,0xf0,0x0, +}; + +static const BitmapCharRec ch169 = {17,17,-1,0,19,ch169data}; + +/* char: 0xa8 */ + +static const GLubyte ch168data[] = { +0xcc,0xcc, +}; + +static const BitmapCharRec ch168 = {6,2,-1,-14,8,ch168data}; + +/* char: 0xa7 */ + +static const GLubyte ch167data[] = { +0x38,0x64,0x62,0x6,0xe,0x1c,0x38,0x74,0xe2,0xc3,0x83,0x87,0x4e,0x3c,0x38,0x70, +0x60,0x46,0x26,0x1c, +}; + +static const BitmapCharRec ch167 = {8,20,-2,2,12,ch167data}; + +/* char: 0xa6 */ + +static const GLubyte ch166data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0x0,0x0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0, +}; + +static const BitmapCharRec ch166 = {2,17,-2,0,6,ch166data}; + +/* char: 0xa5 */ + +static const GLubyte ch165data[] = { +0xf,0xc0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x1f,0xe0,0x3,0x0,0x1f,0xe0, +0x3,0x0,0x7,0x80,0xc,0x80,0xc,0xc0,0x18,0x40,0x18,0x60,0x30,0x20,0x70,0x30, +0xf8,0x7c, +}; + +static const BitmapCharRec ch165 = {14,17,0,0,14,ch165data}; + +/* char: 0xa4 */ + +static const GLubyte ch164data[] = { +0xc0,0x60,0xee,0xe0,0x7f,0xc0,0x31,0x80,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x31,0x80,0x7f,0xc0,0xee,0xe0,0xc0,0x60, +}; + +static const BitmapCharRec ch164 = {11,12,-1,-3,13,ch164data}; + +/* char: 0xa3 */ + +static const GLubyte ch163data[] = { +0xe7,0x80,0xbe,0xc0,0x78,0x40,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0, +0x30,0x0,0xfc,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x31,0x80,0x19,0x80, +0xf,0x0, +}; + +static const BitmapCharRec ch163 = {10,17,-1,0,12,ch163data}; + +/* char: 0xa2 */ + +static const GLubyte ch162data[] = { +0x40,0x0,0x40,0x0,0x3e,0x0,0x7f,0x0,0x70,0x80,0xd0,0x0,0xc8,0x0,0xc8,0x0, +0xc8,0x0,0xc4,0x0,0xc4,0x0,0x43,0x80,0x63,0x80,0x1f,0x0,0x1,0x0,0x1,0x0, +}; + +static const BitmapCharRec ch162 = {9,16,-1,2,12,ch162data}; + +/* char: 0xa1 */ + +static const GLubyte ch161data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x0,0x0,0x0,0xc0, +0xc0, +}; + +static const BitmapCharRec ch161 = {2,17,-4,5,8,ch161data}; + +/* char: 0xa0 */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch160data[] = { 0x0 }; +static const BitmapCharRec ch160 = {1,1,0,0,6,ch160data}; +#else +static const BitmapCharRec ch160 = {0,0,0,0,6,0}; +#endif + +/* char: 0x7e '~' */ + +static const GLubyte ch126data[] = { +0x83,0x80,0xc7,0xc0,0x7c,0x60,0x38,0x20, +}; + +static const BitmapCharRec ch126 = {11,4,-1,-5,13,ch126data}; + +/* char: 0x7d '}' */ + +static const GLubyte ch125data[] = { +0xe0,0x30,0x18,0x18,0x18,0x18,0x18,0x18,0x8,0xc,0x4,0x3,0x4,0xc,0x8,0x18, +0x18,0x18,0x18,0x18,0x30,0xe0, +}; + +static const BitmapCharRec ch125 = {8,22,-1,5,10,ch125data}; + +/* char: 0x7c '|' */ + +static const GLubyte ch124data[] = { +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0, +}; + +static const BitmapCharRec ch124 = {2,17,-2,0,6,ch124data}; + +/* char: 0x7b '{' */ + +static const GLubyte ch123data[] = { +0x7,0xc,0x18,0x18,0x18,0x18,0x18,0x18,0x10,0x30,0x20,0xc0,0x20,0x30,0x10,0x18, +0x18,0x18,0x18,0x18,0xc,0x7, +}; + +static const BitmapCharRec ch123 = {8,22,-1,5,10,ch123data}; + +/* char: 0x7a 'z' */ + +static const GLubyte ch122data[] = { +0xff,0xc3,0x61,0x70,0x30,0x38,0x18,0x1c,0xe,0x86,0xc3,0xff, +}; + +static const BitmapCharRec ch122 = {8,12,-1,0,10,ch122data}; + +/* char: 0x79 'y' */ + +static const GLubyte ch121data[] = { +0xe0,0x0,0xf0,0x0,0x18,0x0,0x8,0x0,0xc,0x0,0x4,0x0,0xe,0x0,0xe,0x0, +0x1a,0x0,0x19,0x0,0x19,0x0,0x31,0x0,0x30,0x80,0x30,0x80,0x60,0x80,0x60,0xc0, +0xf1,0xe0, +}; + +static const BitmapCharRec ch121 = {11,17,0,5,11,ch121data}; + +/* char: 0x78 'x' */ + +static const GLubyte ch120data[] = { +0xf1,0xe0,0x60,0xc0,0x21,0x80,0x33,0x80,0x1b,0x0,0xe,0x0,0xc,0x0,0x1a,0x0, +0x39,0x0,0x31,0x80,0x60,0xc0,0xf1,0xe0, +}; + +static const BitmapCharRec ch120 = {11,12,-1,0,13,ch120data}; + +/* char: 0x77 'w' */ + +static const GLubyte ch119data[] = { +0x4,0x10,0x0,0xe,0x38,0x0,0xe,0x38,0x0,0x1a,0x28,0x0,0x1a,0x64,0x0,0x19, +0x64,0x0,0x31,0x64,0x0,0x30,0xc2,0x0,0x30,0xc2,0x0,0x60,0xc2,0x0,0x60,0xc3, +0x0,0xf1,0xe7,0x80, +}; + +static const BitmapCharRec ch119 = {17,12,0,0,17,ch119data}; + +/* char: 0x76 'v' */ + +static const GLubyte ch118data[] = { +0x4,0x0,0xe,0x0,0xe,0x0,0x1a,0x0,0x19,0x0,0x19,0x0,0x31,0x0,0x30,0x80, +0x30,0x80,0x60,0x80,0x60,0xc0,0xf1,0xe0, +}; + +static const BitmapCharRec ch118 = {11,12,0,0,11,ch118data}; + +/* char: 0x75 'u' */ + +static const GLubyte ch117data[] = { +0x1c,0xe0,0x3e,0xc0,0x71,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0xe1,0xc0, +}; + +static const BitmapCharRec ch117 = {11,12,-1,0,13,ch117data}; + +/* char: 0x74 't' */ + +static const GLubyte ch116data[] = { +0x1c,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xfe,0x70,0x30,0x10, +}; + +static const BitmapCharRec ch116 = {7,15,0,0,7,ch116data}; + +/* char: 0x73 's' */ + +static const GLubyte ch115data[] = { +0xf8,0xc6,0x83,0x3,0x7,0x1e,0x7c,0x70,0xe0,0xc2,0x66,0x3e, +}; + +static const BitmapCharRec ch115 = {8,12,-1,0,10,ch115data}; + +/* char: 0x72 'r' */ + +static const GLubyte ch114data[] = { +0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x76,0x6e,0xe6, +}; + +static const BitmapCharRec ch114 = {7,12,-1,0,8,ch114data}; + +/* char: 0x71 'q' */ + +static const GLubyte ch113data[] = { +0x3,0xc0,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1d,0x80,0x73,0x80,0x61,0x80, +0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0x61,0x80,0x73,0x80, +0x1d,0x80, +}; + +static const BitmapCharRec ch113 = {10,17,-1,5,12,ch113data}; + +/* char: 0x70 'p' */ + +static const GLubyte ch112data[] = { +0xf0,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x6e,0x0,0x73,0x80,0x61,0x80, +0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x61,0x80,0x73,0x80, +0xee,0x0, +}; + +static const BitmapCharRec ch112 = {10,17,-1,5,12,ch112data}; + +/* char: 0x6f 'o' */ + +static const GLubyte ch111data[] = { +0x1e,0x0,0x73,0x80,0x61,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0x61,0x80,0x73,0x80,0x1e,0x0, +}; + +static const BitmapCharRec ch111 = {10,12,-1,0,12,ch111data}; + +/* char: 0x6e 'n' */ + +static const GLubyte ch110data[] = { +0xf1,0xe0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x71,0xc0,0x6f,0x80,0xe7,0x0, +}; + +static const BitmapCharRec ch110 = {11,12,-1,0,13,ch110data}; + +/* char: 0x6d 'm' */ + +static const GLubyte ch109data[] = { +0xf1,0xe3,0xc0,0x60,0xc1,0x80,0x60,0xc1,0x80,0x60,0xc1,0x80,0x60,0xc1,0x80,0x60, +0xc1,0x80,0x60,0xc1,0x80,0x60,0xc1,0x80,0x60,0xc1,0x80,0x71,0xe3,0x80,0x6f,0x9f, +0x0,0xe7,0xe,0x0, +}; + +static const BitmapCharRec ch109 = {18,12,-1,0,20,ch109data}; + +/* char: 0x6c 'l' */ + +static const GLubyte ch108data[] = { +0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, +0xe0, +}; + +static const BitmapCharRec ch108 = {4,17,-1,0,6,ch108data}; + +/* char: 0x6b 'k' */ + +static const GLubyte ch107data[] = { +0xf3,0xe0,0x61,0xc0,0x63,0x80,0x67,0x0,0x6e,0x0,0x6c,0x0,0x78,0x0,0x68,0x0, +0x64,0x0,0x66,0x0,0x63,0x0,0x67,0xc0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0, +0xe0,0x0, +}; + +static const BitmapCharRec ch107 = {11,17,-1,0,12,ch107data}; + +/* char: 0x6a 'j' */ + +static const GLubyte ch106data[] = { +0xc0,0xe0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0x70,0x0,0x0,0x0,0x30,0x30, +}; + +static const BitmapCharRec ch106 = {4,22,0,5,6,ch106data}; + +/* char: 0x69 'i' */ + +static const GLubyte ch105data[] = { +0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xe0,0x0,0x0,0x0,0x60, +0x60, +}; + +static const BitmapCharRec ch105 = {4,17,-1,0,6,ch105data}; + +/* char: 0x68 'h' */ + +static const GLubyte ch104data[] = { +0xf1,0xe0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x71,0xc0,0x6f,0x80,0x67,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0, +0xe0,0x0, +}; + +static const BitmapCharRec ch104 = {11,17,-1,0,13,ch104data}; + +/* char: 0x67 'g' */ + +static const GLubyte ch103data[] = { +0x3f,0x0,0xf1,0xc0,0xc0,0x60,0xc0,0x20,0x60,0x60,0x3f,0xc0,0x7f,0x0,0x60,0x0, +0x30,0x0,0x3e,0x0,0x33,0x0,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x0, +0x1f,0xc0, +}; + +static const BitmapCharRec ch103 = {11,17,-1,5,12,ch103data}; + +/* char: 0x66 'f' */ + +static const GLubyte ch102data[] = { +0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xfe,0x30,0x30,0x30,0x16, +0xe, +}; + +static const BitmapCharRec ch102 = {7,17,0,0,7,ch102data}; + +/* char: 0x65 'e' */ + +static const GLubyte ch101data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xff,0x80, +0xc1,0x80,0x41,0x80,0x63,0x0,0x1e,0x0, +}; + +static const BitmapCharRec ch101 = {9,12,-1,0,11,ch101data}; + +/* char: 0x64 'd' */ + +static const GLubyte ch100data[] = { +0x1e,0xc0,0x73,0x80,0x61,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80,0xc1,0x80, +0xc1,0x80,0x61,0x80,0x73,0x80,0x1d,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80, +0x3,0x80, +}; + +static const BitmapCharRec ch100 = {10,17,-1,0,12,ch100data}; + +/* char: 0x63 'c' */ + +static const GLubyte ch99data[] = { +0x1e,0x0,0x7f,0x0,0x70,0x80,0xe0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +0xc0,0x0,0x41,0x80,0x63,0x80,0x1f,0x0, +}; + +static const BitmapCharRec ch99 = {9,12,-1,0,11,ch99data}; + +/* char: 0x62 'b' */ + +static const GLubyte ch98data[] = { +0x5e,0x0,0x73,0x80,0x61,0x80,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0,0x60,0xc0, +0x60,0xc0,0x61,0x80,0x73,0x80,0x6e,0x0,0x60,0x0,0x60,0x0,0x60,0x0,0x60,0x0, +0xe0,0x0, +}; + +static const BitmapCharRec ch98 = {10,17,-1,0,12,ch98data}; + +/* char: 0x61 'a' */ + +static const GLubyte ch97data[] = { +0x71,0x80,0xfb,0x0,0xc7,0x0,0xc3,0x0,0xc3,0x0,0x63,0x0,0x3b,0x0,0xf,0x0, +0x3,0x0,0x63,0x0,0x67,0x0,0x3e,0x0, +}; + +static const BitmapCharRec ch97 = {9,12,-1,0,11,ch97data}; + +/* char: 0x60 '`' */ + +static const GLubyte ch96data[] = { +0x60,0xe0,0x80,0xc0,0x60, +}; + +static const BitmapCharRec ch96 = {3,5,-2,-12,7,ch96data}; + +/* char: 0x5f '_' */ + +static const GLubyte ch95data[] = { +0xff,0xf8,0xff,0xf8, +}; + +static const BitmapCharRec ch95 = {13,2,0,5,13,ch95data}; + +/* char: 0x5e '^' */ + +static const GLubyte ch94data[] = { +0x80,0x80,0xc1,0x80,0x41,0x0,0x63,0x0,0x22,0x0,0x36,0x0,0x14,0x0,0x1c,0x0, +0x8,0x0, +}; + +static const BitmapCharRec ch94 = {9,9,-1,-8,11,ch94data}; + +/* char: 0x5d ']' */ + +static const GLubyte ch93data[] = { +0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0xf8, +}; + +static const BitmapCharRec ch93 = {5,21,-1,4,8,ch93data}; + +/* char: 0x5c '\' */ + +static const GLubyte ch92data[] = { +0x6,0x6,0x4,0xc,0xc,0x8,0x18,0x18,0x10,0x30,0x30,0x20,0x60,0x60,0x40,0xc0, +0xc0, +}; + +static const BitmapCharRec ch92 = {7,17,0,0,7,ch92data}; + +/* char: 0x5b '[' */ + +static const GLubyte ch91data[] = { +0xf8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0xc0,0xc0,0xf8, +}; + +static const BitmapCharRec ch91 = {5,21,-2,4,8,ch91data}; + +/* char: 0x5a 'Z' */ + +static const GLubyte ch90data[] = { +0xff,0xf8,0xe0,0x18,0x70,0x8,0x30,0x8,0x38,0x0,0x18,0x0,0x1c,0x0,0xe,0x0, +0x6,0x0,0x7,0x0,0x3,0x0,0x3,0x80,0x1,0xc0,0x80,0xc0,0x80,0xe0,0xc0,0x70, +0xff,0xf0, +}; + +static const BitmapCharRec ch90 = {13,17,-1,0,15,ch90data}; + +/* char: 0x59 'Y' */ + +static const GLubyte ch89data[] = { +0x7,0xe0,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x1,0x80,0x3,0xc0, +0x3,0x40,0x6,0x60,0x6,0x20,0xc,0x30,0x1c,0x10,0x18,0x18,0x38,0x8,0x30,0xc, +0xfc,0x3f, +}; + +static const BitmapCharRec ch89 = {16,17,0,0,16,ch89data}; + +/* char: 0x58 'X' */ + +static const GLubyte ch88data[] = { +0xfc,0xf,0xc0,0x30,0x3,0x80,0x18,0x7,0x0,0x8,0xe,0x0,0x4,0xc,0x0,0x6, +0x18,0x0,0x2,0x38,0x0,0x1,0x70,0x0,0x0,0xe0,0x0,0x0,0xc0,0x0,0x1,0xc0, +0x0,0x3,0xa0,0x0,0x3,0x10,0x0,0x6,0x8,0x0,0xe,0xc,0x0,0x1c,0x6,0x0, +0x7e,0xf,0x80, +}; + +static const BitmapCharRec ch88 = {18,17,0,0,18,ch88data}; + +/* char: 0x57 'W' */ + +static const GLubyte ch87data[] = { +0x1,0x83,0x0,0x1,0x83,0x0,0x1,0x83,0x80,0x3,0x87,0x80,0x3,0x46,0x80,0x3, +0x46,0xc0,0x6,0x46,0x40,0x6,0x4c,0x40,0x6,0x4c,0x60,0xc,0x2c,0x60,0xc,0x2c, +0x20,0x18,0x2c,0x20,0x18,0x18,0x30,0x18,0x18,0x10,0x30,0x18,0x10,0x30,0x18,0x18, +0xfc,0x7e,0x7e, +}; + +static const BitmapCharRec ch87 = {23,17,0,0,23,ch87data}; + +/* char: 0x56 'V' */ + +static const GLubyte ch86data[] = { +0x1,0x80,0x0,0x1,0x80,0x0,0x1,0x80,0x0,0x3,0xc0,0x0,0x3,0x40,0x0,0x3, +0x60,0x0,0x6,0x20,0x0,0x6,0x20,0x0,0x6,0x30,0x0,0xc,0x10,0x0,0xc,0x18, +0x0,0x18,0x8,0x0,0x18,0x8,0x0,0x18,0xc,0x0,0x30,0x4,0x0,0x30,0x6,0x0, +0xfc,0x1f,0x80, +}; + +static const BitmapCharRec ch86 = {17,17,0,0,17,ch86data}; + +/* char: 0x55 'U' */ + +static const GLubyte ch85data[] = { +0x7,0xe0,0x1c,0x30,0x18,0x8,0x30,0x8,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4,0x30,0x4, +0xfc,0x1f, +}; + +static const BitmapCharRec ch85 = {16,17,-1,0,18,ch85data}; + +/* char: 0x54 'T' */ + +static const GLubyte ch84data[] = { +0xf,0xc0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0, +0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0x83,0x4,0x83,0x4,0xc3,0xc, +0xff,0xfc, +}; + +static const BitmapCharRec ch84 = {14,17,-1,0,16,ch84data}; + +/* char: 0x53 'S' */ + +static const GLubyte ch83data[] = { +0x9e,0x0,0xf1,0x80,0xc0,0xc0,0x80,0x60,0x80,0x60,0x0,0x60,0x0,0xe0,0x3,0xc0, +0xf,0x80,0x1e,0x0,0x78,0x0,0xe0,0x0,0xc0,0x40,0xc0,0x40,0xc0,0xc0,0x63,0xc0, +0x1e,0x40, +}; + +static const BitmapCharRec ch83 = {11,17,-1,0,13,ch83data}; + +/* char: 0x52 'R' */ + +static const GLubyte ch82data[] = { +0xfc,0x1e,0x30,0x1c,0x30,0x38,0x30,0x70,0x30,0x60,0x30,0xc0,0x31,0xc0,0x33,0x80, +0x3f,0xc0,0x30,0x70,0x30,0x30,0x30,0x38,0x30,0x18,0x30,0x38,0x30,0x30,0x30,0x70, +0xff,0xc0, +}; + +static const BitmapCharRec ch82 = {15,17,-1,0,16,ch82data}; + +/* char: 0x51 'Q' */ + +static const GLubyte ch81data[] = { +0x0,0xf,0x0,0x38,0x0,0x70,0x0,0xe0,0x1,0xc0,0x7,0xe0,0x1c,0x38,0x38,0x1c, +0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38,0x7,0xe0, +}; + +static const BitmapCharRec ch81 = {16,22,-1,5,18,ch81data}; + +/* char: 0x50 'P' */ + +static const GLubyte ch80data[] = { +0xfc,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0, +0x3f,0xc0,0x30,0x70,0x30,0x30,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x30,0x30,0x70, +0xff,0xc0, +}; + +static const BitmapCharRec ch80 = {13,17,-1,0,15,ch80data}; + +/* char: 0x4f 'O' */ + +static const GLubyte ch79data[] = { +0x7,0xe0,0x1c,0x38,0x38,0x1c,0x60,0x6,0x60,0x6,0xc0,0x3,0xc0,0x3,0xc0,0x3, +0xc0,0x3,0xc0,0x3,0xc0,0x3,0xc0,0x3,0x60,0x6,0x60,0x6,0x38,0x1c,0x1c,0x38, +0x7,0xe0, +}; + +static const BitmapCharRec ch79 = {16,17,-1,0,18,ch79data}; + +/* char: 0x4e 'N' */ + +static const GLubyte ch78data[] = { +0xf8,0xc,0x20,0x1c,0x20,0x1c,0x20,0x34,0x20,0x64,0x20,0x64,0x20,0xc4,0x21,0x84, +0x21,0x84,0x23,0x4,0x26,0x4,0x26,0x4,0x2c,0x4,0x38,0x4,0x38,0x4,0x30,0x4, +0xf0,0x1f, +}; + +static const BitmapCharRec ch78 = {16,17,-1,0,18,ch78data}; + +/* char: 0x4d 'M' */ + +static const GLubyte ch77data[] = { +0xf8,0x21,0xf8,0x20,0x60,0x60,0x20,0x60,0x60,0x20,0xd0,0x60,0x20,0xd0,0x60,0x21, +0x88,0x60,0x21,0x88,0x60,0x23,0x8,0x60,0x23,0x4,0x60,0x26,0x4,0x60,0x26,0x2, +0x60,0x2c,0x2,0x60,0x2c,0x2,0x60,0x38,0x1,0x60,0x38,0x1,0x60,0x30,0x0,0xe0, +0xf0,0x0,0xf8, +}; + +static const BitmapCharRec ch77 = {21,17,-1,0,22,ch77data}; + +/* char: 0x4c 'L' */ + +static const GLubyte ch76data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0, +0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0, +0xfc,0x0, +}; + +static const BitmapCharRec ch76 = {13,17,-1,0,14,ch76data}; + +/* char: 0x4b 'K' */ + +static const GLubyte ch75data[] = { +0xfc,0x1f,0x30,0xe,0x30,0x1c,0x30,0x38,0x30,0x70,0x30,0xe0,0x31,0xc0,0x33,0x80, +0x3f,0x0,0x3e,0x0,0x33,0x0,0x31,0x80,0x30,0xc0,0x30,0x60,0x30,0x30,0x30,0x18, +0xfc,0x7e, +}; + +static const BitmapCharRec ch75 = {16,17,-1,0,17,ch75data}; + +/* char: 0x4a 'J' */ + +static const GLubyte ch74data[] = { +0x78,0x0,0xcc,0x0,0xc6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0, +0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0, +0x1f,0x80, +}; + +static const BitmapCharRec ch74 = {9,17,-1,0,11,ch74data}; + +/* char: 0x49 'I' */ + +static const GLubyte ch73data[] = { +0xfc,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, +0xfc, +}; + +static const BitmapCharRec ch73 = {6,17,-1,0,8,ch73data}; + +/* char: 0x48 'H' */ + +static const GLubyte ch72data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x30, +0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x3f,0xfe,0x0,0x30,0x6,0x0,0x30,0x6, +0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0,0x30,0x6,0x0, +0xfc,0x1f,0x80, +}; + +static const BitmapCharRec ch72 = {17,17,-1,0,19,ch72data}; + +/* char: 0x47 'G' */ + +static const GLubyte ch71data[] = { +0x7,0xe0,0x1e,0x38,0x38,0x1c,0x60,0xc,0x60,0xc,0xc0,0xc,0xc0,0xc,0xc0,0x3f, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0x60,0x4,0x60,0x4,0x38,0xc,0x1c,0x3c, +0x7,0xe4, +}; + +static const BitmapCharRec ch71 = {16,17,-1,0,18,ch71data}; + +/* char: 0x46 'F' */ + +static const GLubyte ch70data[] = { +0xfc,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x20,0x30,0x20, +0x3f,0xe0,0x30,0x20,0x30,0x20,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0, +}; + +static const BitmapCharRec ch70 = {12,17,-1,0,14,ch70data}; + +/* char: 0x45 'E' */ + +static const GLubyte ch69data[] = { +0xff,0xf8,0x30,0x18,0x30,0x8,0x30,0x8,0x30,0x0,0x30,0x0,0x30,0x40,0x30,0x40, +0x3f,0xc0,0x30,0x40,0x30,0x40,0x30,0x0,0x30,0x0,0x30,0x10,0x30,0x10,0x30,0x30, +0xff,0xf0, +}; + +static const BitmapCharRec ch69 = {13,17,-1,0,15,ch69data}; + +/* char: 0x44 'D' */ + +static const GLubyte ch68data[] = { +0xff,0xc0,0x30,0x70,0x30,0x38,0x30,0xc,0x30,0xc,0x30,0x6,0x30,0x6,0x30,0x6, +0x30,0x6,0x30,0x6,0x30,0x6,0x30,0x6,0x30,0xc,0x30,0xc,0x30,0x38,0x30,0x70, +0xff,0xc0, +}; + +static const BitmapCharRec ch68 = {15,17,-1,0,17,ch68data}; + +/* char: 0x43 'C' */ + +static const GLubyte ch67data[] = { +0x7,0xe0,0x1e,0x38,0x38,0x8,0x60,0x4,0x60,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0, +0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0x60,0x4,0x60,0x4,0x38,0xc,0x1c,0x3c, +0x7,0xe4, +}; + +static const BitmapCharRec ch67 = {14,17,-1,0,16,ch67data}; + +/* char: 0x42 'B' */ + +static const GLubyte ch66data[] = { +0xff,0xe0,0x30,0x78,0x30,0x18,0x30,0xc,0x30,0xc,0x30,0xc,0x30,0x18,0x30,0x38, +0x3f,0xe0,0x30,0x40,0x30,0x30,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x30,0x30,0x70, +0xff,0xc0, +}; + +static const BitmapCharRec ch66 = {14,17,-1,0,16,ch66data}; + +/* char: 0x41 'A' */ + +static const GLubyte ch65data[] = { +0xfc,0x1f,0x80,0x30,0x6,0x0,0x10,0x6,0x0,0x10,0xc,0x0,0x18,0xc,0x0,0x8, +0xc,0x0,0xf,0xf8,0x0,0xc,0x18,0x0,0x4,0x18,0x0,0x4,0x30,0x0,0x6,0x30, +0x0,0x2,0x30,0x0,0x2,0x60,0x0,0x1,0x60,0x0,0x1,0xc0,0x0,0x1,0xc0,0x0, +0x0,0x80,0x0, +}; + +static const BitmapCharRec ch65 = {17,17,0,0,17,ch65data}; + +/* char: 0x40 '@' */ + +static const GLubyte ch64data[] = { +0x3,0xf0,0x0,0xe,0xc,0x0,0x18,0x0,0x0,0x30,0x0,0x0,0x61,0xde,0x0,0x63, +0x7b,0x0,0xc6,0x39,0x80,0xc6,0x18,0x80,0xc6,0x18,0xc0,0xc6,0x18,0x40,0xc6,0xc, +0x40,0xc3,0xc,0x40,0xc3,0x8c,0x40,0xe1,0xfc,0x40,0x60,0xec,0xc0,0x70,0x0,0x80, +0x38,0x1,0x80,0x1c,0x3,0x0,0xf,0xe,0x0,0x3,0xf8,0x0, +}; + +static const BitmapCharRec ch64 = {18,20,-2,3,22,ch64data}; + +/* char: 0x3f '?' */ + +static const GLubyte ch63data[] = { +0x30,0x30,0x0,0x0,0x10,0x10,0x10,0x18,0x18,0xc,0xe,0x7,0xc3,0xc3,0x83,0xc6, +0x7c, +}; + +static const BitmapCharRec ch63 = {8,17,-2,0,11,ch63data}; + +/* char: 0x3e '>' */ + +static const GLubyte ch62data[] = { +0xc0,0x0,0x70,0x0,0x1c,0x0,0x7,0x0,0x1,0xc0,0x0,0x60,0x1,0xc0,0x7,0x0, +0x1c,0x0,0x70,0x0,0xc0,0x0, +}; + +static const BitmapCharRec ch62 = {11,11,-1,-1,13,ch62data}; + +/* char: 0x3d '=' */ + +static const GLubyte ch61data[] = { +0xff,0xf0,0xff,0xf0,0x0,0x0,0x0,0x0,0xff,0xf0,0xff,0xf0, +}; + +static const BitmapCharRec ch61 = {12,6,-1,-4,14,ch61data}; + +/* char: 0x3c '<' */ + +static const GLubyte ch60data[] = { +0x0,0x60,0x1,0xc0,0x7,0x0,0x1c,0x0,0x70,0x0,0xc0,0x0,0x70,0x0,0x1c,0x0, +0x7,0x0,0x1,0xc0,0x0,0x60, +}; + +static const BitmapCharRec ch60 = {11,11,-1,-1,13,ch60data}; + +/* char: 0x3b ';' */ + +static const GLubyte ch59data[] = { +0xc0,0x60,0x20,0xe0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch59 = {3,14,-2,3,7,ch59data}; + +/* char: 0x3a ':' */ + +static const GLubyte ch58data[] = { +0xc0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0xc0, +}; + +static const BitmapCharRec ch58 = {2,11,-2,0,6,ch58data}; + +/* char: 0x39 '9' */ + +static const GLubyte ch57data[] = { +0xf0,0x0,0x1c,0x0,0x6,0x0,0x3,0x0,0x3,0x80,0x1,0x80,0x1d,0x80,0x73,0xc0, +0x61,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc1,0xc0,0x61,0x80,0x77,0x80, +0x1e,0x0, +}; + +static const BitmapCharRec ch57 = {10,17,-1,0,12,ch57data}; + +/* char: 0x38 '8' */ + +static const GLubyte ch56data[] = { +0x1e,0x0,0x73,0x80,0xe1,0x80,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x41,0xc0,0x61,0x80, +0x37,0x0,0x1e,0x0,0x1e,0x0,0x33,0x0,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x0, +0x1e,0x0, +}; + +static const BitmapCharRec ch56 = {10,17,-1,0,12,ch56data}; + +/* char: 0x37 '7' */ + +static const GLubyte ch55data[] = { +0x18,0x0,0x18,0x0,0xc,0x0,0xc,0x0,0xc,0x0,0x4,0x0,0x6,0x0,0x6,0x0, +0x2,0x0,0x3,0x0,0x3,0x0,0x1,0x0,0x1,0x80,0x81,0x80,0xc0,0xc0,0xff,0xc0, +0x7f,0xc0, +}; + +static const BitmapCharRec ch55 = {10,17,-1,0,12,ch55data}; + +/* char: 0x36 '6' */ + +static const GLubyte ch54data[] = { +0x1e,0x0,0x7b,0x80,0x61,0x80,0xe0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc1,0x80,0xf3,0x80,0xee,0x0,0x60,0x0,0x70,0x0,0x30,0x0,0x18,0x0,0xe,0x0, +0x3,0xc0, +}; + +static const BitmapCharRec ch54 = {10,17,-1,0,12,ch54data}; + +/* char: 0x35 '5' */ + +static const GLubyte ch53data[] = { +0x7e,0x0,0xe3,0x80,0xc1,0x80,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x0,0xc0,0x1,0xc0, +0x3,0x80,0xf,0x80,0x7e,0x0,0x78,0x0,0x60,0x0,0x20,0x0,0x20,0x0,0x1f,0x80, +0x1f,0xc0, +}; + +static const BitmapCharRec ch53 = {10,17,-1,0,12,ch53data}; + +/* char: 0x34 '4' */ + +static const GLubyte ch52data[] = { +0x3,0x0,0x3,0x0,0x3,0x0,0x3,0x0,0xff,0xc0,0xff,0xc0,0xc3,0x0,0x43,0x0, +0x63,0x0,0x23,0x0,0x33,0x0,0x13,0x0,0x1b,0x0,0xb,0x0,0x7,0x0,0x7,0x0, +0x3,0x0, +}; + +static const BitmapCharRec ch52 = {10,17,-1,0,12,ch52data}; + +/* char: 0x33 '3' */ + +static const GLubyte ch51data[] = { +0x78,0x0,0xe6,0x0,0xc3,0x0,0x1,0x0,0x1,0x80,0x1,0x80,0x1,0x80,0x3,0x80, +0x7,0x0,0x1e,0x0,0xc,0x0,0x6,0x0,0x83,0x0,0x83,0x0,0x47,0x0,0x7e,0x0, +0x1c,0x0, +}; + +static const BitmapCharRec ch51 = {9,17,-1,0,12,ch51data}; + +/* char: 0x32 '2' */ + +static const GLubyte ch50data[] = { +0xff,0x80,0xff,0xc0,0x60,0x40,0x30,0x0,0x18,0x0,0xc,0x0,0x4,0x0,0x6,0x0, +0x3,0x0,0x3,0x0,0x1,0x80,0x1,0x80,0x81,0x80,0x81,0x80,0x43,0x80,0x7f,0x0, +0x1c,0x0, +}; + +static const BitmapCharRec ch50 = {10,17,-1,0,12,ch50data}; + +/* char: 0x31 '1' */ + +static const GLubyte ch49data[] = { +0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x18, +0x8, +}; + +static const BitmapCharRec ch49 = {8,17,-2,0,12,ch49data}; + +/* char: 0x30 '0' */ + +static const GLubyte ch48data[] = { +0x1e,0x0,0x33,0x0,0x61,0x80,0x61,0x80,0xe1,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x61,0x80,0x61,0x80,0x33,0x0, +0x1e,0x0, +}; + +static const BitmapCharRec ch48 = {10,17,-1,0,12,ch48data}; + +/* char: 0x2f '/' */ + +static const GLubyte ch47data[] = { +0xc0,0xc0,0xc0,0x60,0x60,0x20,0x30,0x30,0x10,0x18,0x18,0x8,0xc,0xc,0x4,0x6, +0x6,0x3,0x3,0x3, +}; + +static const BitmapCharRec ch47 = {8,20,1,3,7,ch47data}; + +/* char: 0x2e '.' */ + +static const GLubyte ch46data[] = { +0xc0,0xc0, +}; + +static const BitmapCharRec ch46 = {2,2,-2,0,6,ch46data}; + +/* char: 0x2d '-' */ + +static const GLubyte ch45data[] = { +0xff,0xf0,0xff,0xf0, +}; + +static const BitmapCharRec ch45 = {12,2,-1,-6,14,ch45data}; + +/* char: 0x2c ',' */ + +static const GLubyte ch44data[] = { +0xc0,0x60,0x20,0xe0,0xc0, +}; + +static const BitmapCharRec ch44 = {3,5,-2,3,7,ch44data}; + +/* char: 0x2b '+' */ + +static const GLubyte ch43data[] = { +0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0xff,0xf0,0xff,0xf0,0x6,0x0, +0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0, +}; + +static const BitmapCharRec ch43 = {12,12,-1,-1,14,ch43data}; + +/* char: 0x2a '*' */ + +static const GLubyte ch42data[] = { +0x8,0x0,0x1c,0x0,0xc9,0x80,0xeb,0x80,0x1c,0x0,0xeb,0x80,0xc9,0x80,0x1c,0x0, +0x8,0x0, +}; + +static const BitmapCharRec ch42 = {9,9,-2,-8,12,ch42data}; + +/* char: 0x29 ')' */ + +static const GLubyte ch41data[] = { +0x80,0x40,0x20,0x30,0x10,0x18,0x18,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0x18, +0x18,0x10,0x30,0x20,0x40,0x80, +}; + +static const BitmapCharRec ch41 = {6,22,-1,5,8,ch41data}; + +/* char: 0x28 '(' */ + +static const GLubyte ch40data[] = { +0x4,0x8,0x10,0x30,0x20,0x60,0x60,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x60, +0x60,0x20,0x30,0x10,0x8,0x4, +}; + +static const BitmapCharRec ch40 = {6,22,-1,5,8,ch40data}; + +/* char: 0x27 ''' */ + +static const GLubyte ch39data[] = { +0xc0,0x60,0x20,0xe0,0xc0, +}; + +static const BitmapCharRec ch39 = {3,5,-3,-12,8,ch39data}; + +/* char: 0x26 '&' */ + +static const GLubyte ch38data[] = { +0x3c,0x3c,0x7f,0x7e,0xe1,0xe1,0xc0,0xc0,0xc1,0xc0,0xc1,0xa0,0x63,0x20,0x37,0x10, +0x1e,0x18,0xe,0x3e,0xf,0x0,0x1d,0x80,0x18,0xc0,0x18,0x40,0x18,0x40,0xc,0xc0, +0x7,0x80, +}; + +static const BitmapCharRec ch38 = {16,17,-1,0,18,ch38data}; + +/* char: 0x25 '%' */ + +static const GLubyte ch37data[] = { +0x30,0x3c,0x0,0x18,0x72,0x0,0xc,0x61,0x0,0x4,0x60,0x80,0x6,0x60,0x80,0x3, +0x30,0x80,0x1,0x19,0x80,0x1,0x8f,0x0,0x78,0xc0,0x0,0xe4,0x40,0x0,0xc2,0x60, +0x0,0xc1,0x30,0x0,0xc1,0x10,0x0,0x61,0x18,0x0,0x33,0xfc,0x0,0x1e,0xc,0x0, +}; + +static const BitmapCharRec ch37 = {17,16,-1,0,19,ch37data}; + +/* char: 0x24 '$' */ + +static const GLubyte ch36data[] = { +0x4,0x0,0x4,0x0,0x3f,0x0,0xe5,0xc0,0xc4,0xc0,0x84,0x60,0x84,0x60,0x4,0x60, +0x4,0xe0,0x7,0xc0,0x7,0x80,0x1e,0x0,0x3c,0x0,0x74,0x0,0x64,0x0,0x64,0x20, +0x64,0x60,0x34,0xe0,0x1f,0x80,0x4,0x0,0x4,0x0, +}; + +static const BitmapCharRec ch36 = {11,21,0,2,12,ch36data}; + +/* char: 0x23 '#' */ + +static const GLubyte ch35data[] = { +0x22,0x0,0x22,0x0,0x22,0x0,0x22,0x0,0x22,0x0,0xff,0xc0,0xff,0xc0,0x11,0x0, +0x11,0x0,0x11,0x0,0x7f,0xe0,0x7f,0xe0,0x8,0x80,0x8,0x80,0x8,0x80,0x8,0x80, +0x8,0x80, +}; + +static const BitmapCharRec ch35 = {11,17,-1,0,13,ch35data}; + +/* char: 0x22 '"' */ + +static const GLubyte ch34data[] = { +0x88,0xcc,0xcc,0xcc,0xcc, +}; + +static const BitmapCharRec ch34 = {6,5,-1,-12,10,ch34data}; + +/* char: 0x21 '!' */ + +static const GLubyte ch33data[] = { +0xc0,0xc0,0x0,0x0,0x0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, +0xc0, +}; + +static const BitmapCharRec ch33 = {2,17,-3,0,8,ch33data}; + +/* char: 0x20 ' ' */ + +#ifdef _WIN32 +/* XXX Work around Microsoft OpenGL 1.1 bug where glBitmap with + a height or width of zero does not advance the raster position + as specified by OpenGL. (Cosmo OpenGL does not have this bug.) */ +static const GLubyte ch32data[] = { 0x0 }; +static const BitmapCharRec ch32 = {1,1,0,0,6,ch32data}; +#else +static const BitmapCharRec ch32 = {0,0,0,0,6,0}; +#endif + +static const BitmapCharRec * const chars[] = { +&ch32, +&ch33, +&ch34, +&ch35, +&ch36, +&ch37, +&ch38, +&ch39, +&ch40, +&ch41, +&ch42, +&ch43, +&ch44, +&ch45, +&ch46, +&ch47, +&ch48, +&ch49, +&ch50, +&ch51, +&ch52, +&ch53, +&ch54, +&ch55, +&ch56, +&ch57, +&ch58, +&ch59, +&ch60, +&ch61, +&ch62, +&ch63, +&ch64, +&ch65, +&ch66, +&ch67, +&ch68, +&ch69, +&ch70, +&ch71, +&ch72, +&ch73, +&ch74, +&ch75, +&ch76, +&ch77, +&ch78, +&ch79, +&ch80, +&ch81, +&ch82, +&ch83, +&ch84, +&ch85, +&ch86, +&ch87, +&ch88, +&ch89, +&ch90, +&ch91, +&ch92, +&ch93, +&ch94, +&ch95, +&ch96, +&ch97, +&ch98, +&ch99, +&ch100, +&ch101, +&ch102, +&ch103, +&ch104, +&ch105, +&ch106, +&ch107, +&ch108, +&ch109, +&ch110, +&ch111, +&ch112, +&ch113, +&ch114, +&ch115, +&ch116, +&ch117, +&ch118, +&ch119, +&ch120, +&ch121, +&ch122, +&ch123, +&ch124, +&ch125, +&ch126, +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, +&ch160, +&ch161, +&ch162, +&ch163, +&ch164, +&ch165, +&ch166, +&ch167, +&ch168, +&ch169, +&ch170, +&ch171, +&ch172, +&ch173, +&ch174, +&ch175, +&ch176, +&ch177, +&ch178, +&ch179, +&ch180, +&ch181, +&ch182, +&ch183, +&ch184, +&ch185, +&ch186, +&ch187, +&ch188, +&ch189, +&ch190, +&ch191, +&ch192, +&ch193, +&ch194, +&ch195, +&ch196, +&ch197, +&ch198, +&ch199, +&ch200, +&ch201, +&ch202, +&ch203, +&ch204, +&ch205, +&ch206, +&ch207, +&ch208, +&ch209, +&ch210, +&ch211, +&ch212, +&ch213, +&ch214, +&ch215, +&ch216, +&ch217, +&ch218, +&ch219, +&ch220, +&ch221, +&ch222, +&ch223, +&ch224, +&ch225, +&ch226, +&ch227, +&ch228, +&ch229, +&ch230, +&ch231, +&ch232, +&ch233, +&ch234, +&ch235, +&ch236, +&ch237, +&ch238, +&ch239, +&ch240, +&ch241, +&ch242, +&ch243, +&ch244, +&ch245, +&ch246, +&ch247, +&ch248, +&ch249, +&ch250, +&ch251, +&ch252, +&ch253, +&ch254, +&ch255, +}; + +const BitmapFontRec glutBitmapTimesRoman24 = { +"-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", +224, +32, +chars +}; + diff --git a/lib/glut-3.7.6/lib/glut/glut_util.c b/lib/glut-3.7.6/lib/glut/glut_util.c new file mode 100644 index 0000000000..ae1a232cec --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_util.c @@ -0,0 +1,86 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 +#include +#include + +#include "glutint.h" + +/* strdup is actually not a standard ANSI C or POSIX routine + so implement a private one for GLUT. OpenVMS does not have a + strdup; Linux's standard libc doesn't declare strdup by default + (unless BSD or SVID interfaces are requested). */ +char * +__glutStrdup(const char *string) +{ + char *copy; + + copy = (char*) malloc(strlen(string) + 1); + if (copy == NULL) + return NULL; + strcpy(copy, string); + return copy; +} + +void +__glutWarning(char *format,...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "GLUT: Warning in %s: ", + __glutProgramName ? __glutProgramName : "(unamed)"); + vfprintf(stderr, format, args); + va_end(args); + putc('\n', stderr); +} + +/* CENTRY */ +void APIENTRY +glutReportErrors(void) +{ + GLenum error; + + while ((error = glGetError()) != GL_NO_ERROR) + __glutWarning("GL error: %s", gluErrorString(error)); +} +/* ENDCENTRY */ + +void +__glutFatalError(char *format,...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "GLUT: Fatal Error in %s: ", + __glutProgramName ? __glutProgramName : "(unamed)"); + vfprintf(stderr, format, args); + va_end(args); + putc('\n', stderr); +#ifdef _WIN32 + if (__glutExitFunc) { + __glutExitFunc(1); + } +#endif + exit(1); +} + +void +__glutFatalUsage(char *format,...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "GLUT: Fatal API Usage in %s: ", + __glutProgramName ? __glutProgramName : "(unamed)"); + vfprintf(stderr, format, args); + va_end(args); + putc('\n', stderr); + abort(); +} diff --git a/lib/glut-3.7.6/lib/glut/glut_vidresize.c b/lib/glut-3.7.6/lib/glut/glut_vidresize.c new file mode 100644 index 0000000000..e07db8f37a --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_vidresize.c @@ -0,0 +1,230 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 + +#if !defined(_WIN32) +#include +#endif + +#ifdef __sgi +#include +#endif + +#include "glutint.h" + +/* Grumble. The IRIX 6.3 and early IRIX 6.4 OpenGL headers + support the video resize extension, but failed to define + GLX_SGIX_video_resize. */ +#ifdef GLX_SYNC_FRAME_SGIX +#define GLX_SGIX_video_resize 1 +#endif + +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) +static int canVideoResize = -1; +static int videoResizeChannel; +#else +static int canVideoResize = 0; +#endif +static int videoResizeInUse = 0; +static int dx = -1, dy = -1, dw = -1, dh = -1; + +/* XXX Note that IRIX 6.2, 6.3, and some 6.4 versions have a + bug where programs seg-fault when they attempt video + resizing from an indirect OpenGL context (either local or + over a network). */ + +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + +static volatile int errorCaught; + +/* ARGSUSED */ +static +catchXSGIvcErrors(Display * dpy, XErrorEvent * event) +{ + errorCaught = 1; + return 0; +} +#endif + +/* CENTRY */ +int APIENTRY +glutVideoResizeGet(GLenum param) +{ +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (canVideoResize < 0) { + canVideoResize = __glutIsSupportedByGLX("GLX_SGIX_video_resize"); + if (canVideoResize) { +#if __sgi + /* This is a hack because IRIX 6.2, 6.3, and some 6.4 + versions were released with GLX_SGIX_video_resize + being advertised by the X server though the video + resize extension is not actually supported. We try to + determine if the libGL.so we are using actually has a + video resize entrypoint before we try to use the + feature. */ + void (*func) (void); + void *glxDso = dlopen("libGL.so", RTLD_LAZY); + + func = (void (*)(void)) dlsym(glxDso, "glXQueryChannelDeltasSGIX"); + if (!func) { + canVideoResize = 0; + } else +#endif + { + char *channelString; + int (*handler) (Display *, XErrorEvent *); + + channelString = getenv("GLUT_VIDEO_RESIZE_CHANNEL"); + videoResizeChannel = channelString ? atoi(channelString) : 0; + + /* Work around another annoying problem with SGI's + GLX_SGIX_video_resize implementation. Early IRIX + 6.4 OpenGL's advertise the extension and have the + video resize API, but an XSGIvc X protocol errors + result trying to use the API. Set up an error + handler to intercept what would otherwise be a fatal + error. If an error was recieved, do not report that + video resize is possible. */ + handler = XSetErrorHandler(catchXSGIvcErrors); + + errorCaught = 0; + + glXQueryChannelDeltasSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, &dx, &dy, &dw, &dh); + + /* glXQueryChannelDeltasSGIX is an inherent X server + round-trip so we know we will have gotten either the + correct reply or and error by this time. */ + XSetErrorHandler(handler); + + /* Still yet another work around. In IRIX 6.4 betas, + glXQueryChannelDeltasSGIX will return as if it + succeeded, but the values are filled with junk. + Watch to make sure the delta variables really make + sense. */ + if (errorCaught || + dx < 0 || dy < 0 || dw < 0 || dh < 0 || + dx > 2048 || dy > 2048 || dw > 2048 || dh > 2048) { + canVideoResize = 0; + } + } + } + } +#endif /* GLX_SGIX_video_resize */ + + switch (param) { + case GLUT_VIDEO_RESIZE_POSSIBLE: + return canVideoResize; + case GLUT_VIDEO_RESIZE_IN_USE: + return videoResizeInUse; + case GLUT_VIDEO_RESIZE_X_DELTA: + return dx; + case GLUT_VIDEO_RESIZE_Y_DELTA: + return dy; + case GLUT_VIDEO_RESIZE_WIDTH_DELTA: + return dw; + case GLUT_VIDEO_RESIZE_HEIGHT_DELTA: + return dh; + case GLUT_VIDEO_RESIZE_X: + case GLUT_VIDEO_RESIZE_Y: + case GLUT_VIDEO_RESIZE_WIDTH: + case GLUT_VIDEO_RESIZE_HEIGHT: +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (videoResizeInUse) { + int x, y, width, height; + + glXQueryChannelRectSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, &x, &y, &width, &height); + switch (param) { + case GLUT_VIDEO_RESIZE_X: + return x; + case GLUT_VIDEO_RESIZE_Y: + return y; + case GLUT_VIDEO_RESIZE_WIDTH: + return width; + case GLUT_VIDEO_RESIZE_HEIGHT: + return height; + } + } +#endif + return -1; + default: + __glutWarning("invalid glutVideoResizeGet parameter: %d", param); + return -1; + } +} + +void APIENTRY +glutSetupVideoResizing(void) +{ +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) { + glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, __glutCurrentWindow->win); + videoResizeInUse = 1; + } else +#endif + __glutFatalError("glutEstablishVideoResizing: video resizing not possible.\n"); +} + +void APIENTRY +glutStopVideoResizing(void) +{ +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) { + if (videoResizeInUse) { + glXBindChannelToWindowSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, None); + videoResizeInUse = 0; + } + } +#endif +} + +/* ARGSUSED */ +void APIENTRY +glutVideoResize(int x, int y, int width, int height) +{ +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (videoResizeInUse) { +#ifdef GLX_SYNC_SWAP_SGIX + /* glXChannelRectSyncSGIX introduced in a patch to IRIX + 6.2; the original unpatched IRIX 6.2 behavior is always + GLX_SYNC_SWAP_SGIX. */ + glXChannelRectSyncSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, GLX_SYNC_SWAP_SGIX); +#endif + glXChannelRectSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, x, y, width, height); + } +#endif +} + +/* ARGSUSED */ +void APIENTRY +glutVideoPan(int x, int y, int width, int height) +{ +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_video_resize) + if (videoResizeInUse) { +#ifdef GLX_SYNC_FRAME_SGIX + /* glXChannelRectSyncSGIX introduced in a patch to IRIX + 6.2; the original unpatched IRIX 6.2 behavior is always + GLX_SYNC_SWAP_SGIX. We just ignore that we cannot + accomplish GLX_SYNC_FRAME_SGIX on IRIX unpatched 6.2; + this means you'd need a glutSwapBuffers to actually + realize the video resize. */ + glXChannelRectSyncSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, GLX_SYNC_FRAME_SGIX); +#endif + glXChannelRectSGIX(__glutDisplay, __glutScreen, + videoResizeChannel, x, y, width, height); + } +#endif +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_warp.c b/lib/glut-3.7.6/lib/glut/glut_warp.c new file mode 100644 index 0000000000..a24ef23593 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_warp.c @@ -0,0 +1,23 @@ + +/* Copyright (c) Mark J. Kilgard, 1996, 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. */ + +#include +#include +#include + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutWarpPointer(int x, int y) +{ + XWarpPointer(__glutDisplay, None, __glutCurrentWindow->win, + 0, 0, 0, 0, x, y); + XFlush(__glutDisplay); +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glut_win.c b/lib/glut-3.7.6/lib/glut/glut_win.c new file mode 100644 index 0000000000..74576504e2 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_win.c @@ -0,0 +1,1014 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +#include +#include +#include +#include +#if !defined(_WIN32) +#include +#include +#endif + +#include "glutint.h" + +GLUTwindow *__glutCurrentWindow = NULL; +GLUTwindow **__glutWindowList = NULL; +int __glutWindowListSize = 0; +#if !defined(_WIN32) +GLUTstale *__glutStaleWindowList = NULL; +#endif +GLUTwindow *__glutMenuWindow = NULL; + +void (*__glutFreeOverlayFunc) (GLUToverlay *); +XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle, + Criterion * requiredCriteria, int nRequired, int requiredMask, void** fbc) = NULL; + +static Criterion requiredWindowCriteria[] = +{ + {LEVEL, EQ, 0}, + {TRANSPARENT, EQ, 0} +}; +static int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion); +static int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT); + +static void +cleanWindowWorkList(GLUTwindow * window) +{ + GLUTwindow **pEntry = &__glutWindowWorkList; + GLUTwindow *entry = __glutWindowWorkList; + + /* Tranverse singly-linked window work list look for the + window. */ + while (entry) { + if (entry == window) { + /* Found it; delete it. */ + *pEntry = entry->prevWorkWin; + return; + } else { + pEntry = &entry->prevWorkWin; + entry = *pEntry; + } + } +} + +#if !defined(_WIN32) + +static void +cleanStaleWindowList(GLUTwindow * window) +{ + GLUTstale **pEntry = &__glutStaleWindowList; + GLUTstale *entry = __glutStaleWindowList; + + /* Tranverse singly-linked stale window list look for the + window ID. */ + while (entry) { + if (entry->window == window) { + /* Found it; delete it. */ + *pEntry = entry->next; + free(entry); + return; + } else { + pEntry = &entry->next; + entry = *pEntry; + } + } +} + +#endif + +static GLUTwindow *__glutWindowCache = NULL; + +GLUTwindow * +__glutGetWindow(Window win) +{ + int i; + + /* Does win belong to the last window ID looked up? */ + if (__glutWindowCache && (win == __glutWindowCache->win || + (__glutWindowCache->overlay && win == + __glutWindowCache->overlay->win))) { + return + __glutWindowCache; + } + /* Otherwise scan the window list looking for the window ID. */ + for (i = 0; i < __glutWindowListSize; i++) { + if (__glutWindowList[i]) { + if (win == __glutWindowList[i]->win) { + __glutWindowCache = __glutWindowList[i]; + return __glutWindowCache; + } + if (__glutWindowList[i]->overlay) { + if (win == __glutWindowList[i]->overlay->win) { + __glutWindowCache = __glutWindowList[i]; + return __glutWindowCache; + } + } + } + } +#if !defined(_WIN32) + { + GLUTstale *entry; + + /* Scan through destroyed overlay window IDs for which no + DestroyNotify has yet been received. */ + for (entry = __glutStaleWindowList; entry; entry = entry->next) { + if (entry->win == win) + return entry->window; + } + } +#endif + return NULL; +} + +/* CENTRY */ +int APIENTRY +glutGetWindow(void) +{ + if (__glutCurrentWindow) { + return __glutCurrentWindow->num + 1; + } else { + return 0; + } +} +/* ENDCENTRY */ + +void +__glutSetWindow(GLUTwindow * window) +{ + /* It is tempting to try to short-circuit the call to + glXMakeCurrent if we "know" we are going to make current + to a window we are already current to. In fact, this + assumption breaks when GLUT is expected to integrated with + other OpenGL windowing APIs that also make current to + OpenGL contexts. Since glXMakeCurrent short-circuits the + "already bound" case, GLUT avoids the temptation to do so + too. */ + __glutCurrentWindow = window; + + MAKE_CURRENT_LAYER(__glutCurrentWindow); + +#if !defined(_WIN32) + /* We should be careful to force a finish between each + iteration through the GLUT main loop if indirect OpenGL + contexts are in use; indirect contexts tend to have much + longer latency because lots of OpenGL extension requests + can queue up in the X protocol stream. We accomplish this + by posting GLUT_FINISH_WORK to be done. */ + if (!__glutCurrentWindow->isDirect) + __glutPutOnWorkList(__glutCurrentWindow, GLUT_FINISH_WORK); +#endif + + /* If debugging is enabled, we'll want to check this window + for any OpenGL errors every iteration through the GLUT + main loop. To accomplish this, we post the + GLUT_DEBUG_WORK to be done on this window. */ + if (__glutDebug) { + __glutPutOnWorkList(__glutCurrentWindow, GLUT_DEBUG_WORK); + } +} + +/* CENTRY */ +void APIENTRY +glutSetWindow(int win) +{ + GLUTwindow *window; + + if (win < 1 || win > __glutWindowListSize) { + __glutWarning("glutSetWindow attempted on bogus window."); + return; + } + window = __glutWindowList[win - 1]; + if (!window) { + __glutWarning("glutSetWindow attempted on bogus window."); + return; + } + __glutSetWindow(window); +} +/* ENDCENTRY */ + +static int +getUnusedWindowSlot(void) +{ + int i; + + /* Look for allocated, unused slot. */ + for (i = 0; i < __glutWindowListSize; i++) { + if (!__glutWindowList[i]) { + return i; + } + } + /* Allocate a new slot. */ + __glutWindowListSize++; + if (__glutWindowList) { + __glutWindowList = (GLUTwindow **) + realloc(__glutWindowList, + __glutWindowListSize * sizeof(GLUTwindow *)); + } else { + /* XXX Some realloc's do not correctly perform a malloc + when asked to perform a realloc on a NULL pointer, + though the ANSI C library spec requires this. */ + __glutWindowList = (GLUTwindow **) + malloc(sizeof(GLUTwindow *)); + } + if (!__glutWindowList) + __glutFatalError("out of memory."); + __glutWindowList[__glutWindowListSize - 1] = NULL; + return __glutWindowListSize - 1; +} + +static XVisualInfo * +getVisualInfoCI(unsigned int mode) +{ + static int bufSizeList[] = + {16, 12, 8, 4, 2, 1, 0}; + XVisualInfo *vi; + int list[32]; + int i, n = 0; + + /* Should not be looking at display mode mask if + __glutDisplayString is non-NULL. */ + assert(!__glutDisplayString); + + list[n++] = GLX_BUFFER_SIZE; + list[n++] = 1; + if (GLUT_WIND_IS_DOUBLE(mode)) { + list[n++] = GLX_DOUBLEBUFFER; + } + if (GLUT_WIND_IS_STEREO(mode)) { + list[n++] = GLX_STEREO; + } + if (GLUT_WIND_HAS_DEPTH(mode)) { + list[n++] = GLX_DEPTH_SIZE; + list[n++] = 1; + } + if (GLUT_WIND_HAS_STENCIL(mode)) { + list[n++] = GLX_STENCIL_SIZE; + list[n++] = 1; + } + list[n] = (int) None; /* terminate list */ + + /* glXChooseVisual specify GLX_BUFFER_SIZE prefers the + "smallest index buffer of at least the specified size". + This would be reasonable if GLUT allowed the user to + specify the required buffe size, but GLUT's display mode + is too simplistic (easy to use?). GLUT should try to find + the "largest". So start with a large buffer size and + shrink until we find a matching one that exists. */ + + for (i = 0; bufSizeList[i]; i++) { + /* XXX Assumes list[1] is where GLX_BUFFER_SIZE parameter + is. */ + list[1] = bufSizeList[i]; + vi = glXChooseVisual(__glutDisplay, + __glutScreen, list); + if (vi) + return vi; + } + return NULL; +} + +static XVisualInfo * +getVisualInfoRGB(unsigned int mode) +{ + int list[32]; + int n = 0; + + /* Should not be looking at display mode mask if + __glutDisplayString is non-NULL. */ + assert(!__glutDisplayString); + + /* XXX Would a caching mechanism to minize the calls to + glXChooseVisual? You'd have to reference count + XVisualInfo* pointers. Would also have to properly + interact with glutInitDisplayString. */ + + list[n++] = GLX_RGBA; + list[n++] = GLX_RED_SIZE; + list[n++] = 1; + list[n++] = GLX_GREEN_SIZE; + list[n++] = 1; + list[n++] = GLX_BLUE_SIZE; + list[n++] = 1; + if (GLUT_WIND_HAS_ALPHA(mode)) { + list[n++] = GLX_ALPHA_SIZE; + list[n++] = 1; + } + if (GLUT_WIND_IS_DOUBLE(mode)) { + list[n++] = GLX_DOUBLEBUFFER; + } + if (GLUT_WIND_IS_STEREO(mode)) { + list[n++] = GLX_STEREO; + } + if (GLUT_WIND_HAS_DEPTH(mode)) { + list[n++] = GLX_DEPTH_SIZE; + list[n++] = 1; + } + if (GLUT_WIND_HAS_STENCIL(mode)) { + list[n++] = GLX_STENCIL_SIZE; + list[n++] = 1; + } + if (GLUT_WIND_HAS_ACCUM(mode)) { + list[n++] = GLX_ACCUM_RED_SIZE; + list[n++] = 1; + list[n++] = GLX_ACCUM_GREEN_SIZE; + list[n++] = 1; + list[n++] = GLX_ACCUM_BLUE_SIZE; + list[n++] = 1; + if (GLUT_WIND_HAS_ALPHA(mode)) { + list[n++] = GLX_ACCUM_ALPHA_SIZE; + list[n++] = 1; + } + } +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + if (GLUT_WIND_IS_MULTISAMPLE(mode)) { + if (!__glutIsSupportedByGLX("GLX_SGIS_multisample")) + return NULL; + list[n++] = GLX_SAMPLES_SGIS; + /* XXX Is 4 a reasonable minimum acceptable number of + samples? */ + list[n++] = 4; + } +#endif + list[n] = (int) None; /* terminate list */ + + return glXChooseVisual(__glutDisplay, + __glutScreen, list); +} + +XVisualInfo * +__glutGetVisualInfo(unsigned int mode) +{ + /* XXX GLUT_LUMINANCE not implemented for GLUT 3.0. */ + if (GLUT_WIND_IS_LUMINANCE(mode)) + return NULL; + + if (GLUT_WIND_IS_RGB(mode)) + return getVisualInfoRGB(mode); + else + return getVisualInfoCI(mode); +} + +XVisualInfo * +__glutDetermineVisual( + unsigned int displayMode, + Bool * treatAsSingle, + XVisualInfo * (getVisualInfo) (unsigned int)) +{ + XVisualInfo *vis; + + /* Should not be looking at display mode mask if + __glutDisplayString is non-NULL. */ + assert(!__glutDisplayString); + + *treatAsSingle = GLUT_WIND_IS_SINGLE(displayMode); + vis = getVisualInfo(displayMode); + if (!vis) { + /* Fallback cases when can't get exactly what was asked + for... */ + if (GLUT_WIND_IS_SINGLE(displayMode)) { + /* If we can't find a single buffered visual, try looking + for a double buffered visual. We can treat a double + buffered visual as a single buffer visual by changing + the draw buffer to GL_FRONT and treating any swap + buffers as no-ops. */ + displayMode |= GLUT_DOUBLE; + vis = getVisualInfo(displayMode); + *treatAsSingle = True; + } + if (!vis && GLUT_WIND_IS_MULTISAMPLE(displayMode)) { + /* If we can't seem to get multisampling (ie, not Reality + Engine class graphics!), go without multisampling. It + is up to the application to query how many multisamples + were allocated (0 equals no multisampling) if the + application is going to use multisampling for more than + just antialiasing. */ + displayMode &= ~GLUT_MULTISAMPLE; + vis = getVisualInfo(displayMode); + } + } + return vis; +} + +void GLUTCALLBACK +__glutDefaultDisplay(void) +{ + /* XXX Remove the warning after GLUT 3.0. */ + __glutWarning("The following is a new check for GLUT 3.0; update your code."); + __glutFatalError( + "redisplay needed for window %d, but no display callback.", + __glutCurrentWindow->num + 1); +} + +void GLUTCALLBACK +__glutDefaultReshape(int width, int height) +{ + GLUToverlay *overlay; + + /* Adjust the viewport of the window (and overlay if one + exists). */ + MAKE_CURRENT_WINDOW(__glutCurrentWindow); + glViewport(0, 0, (GLsizei) width, (GLsizei) height); + overlay = __glutCurrentWindow->overlay; + if (overlay) { + MAKE_CURRENT_OVERLAY(overlay); + glViewport(0, 0, (GLsizei) width, (GLsizei) height); + } + /* Make sure we are current to the current layer (application + should be able to count on the current layer not changing + unless the application explicitly calls glutUseLayer). */ + MAKE_CURRENT_LAYER(__glutCurrentWindow); +} + +XVisualInfo * +__glutDetermineWindowVisual(Bool * treatAsSingle, Bool * visAlloced, void **fbc) +{ + if (__glutDisplayString) { + + /* __glutDisplayString should be NULL except if + glutInitDisplayString has been called to register a + different display string. Calling glutInitDisplayString + means using a string instead of an integer mask determine + the visual to use. Using the function pointer variable + __glutDetermineVisualFromString below avoids linking in + the code for implementing glutInitDisplayString (ie, + glut_dstr.o) unless glutInitDisplayString gets called by + the application. */ + + assert(__glutDetermineVisualFromString); + *visAlloced = False; + *fbc = NULL; + return __glutDetermineVisualFromString(__glutDisplayString, treatAsSingle, + requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, fbc); + } else { + *visAlloced = True; + *fbc = NULL; + return __glutDetermineVisual(__glutDisplayMode, + treatAsSingle, __glutGetVisualInfo); + } +} + +/* ARGSUSED5 */ /* Only Win32 uses gameMode parameter. */ +GLUTwindow * +__glutCreateWindow(GLUTwindow * parent, + int x, int y, int width, int height, int gameMode) +{ + GLUTwindow *window; + XSetWindowAttributes wa; + unsigned long attribMask; + int winnum; + int i; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + GLXFBConfigSGIX fbc; +#else + void *fbc; +#endif + +#if defined(_WIN32) + WNDCLASS wc; + int style; + + if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) { + __glutOpenWin32Connection(NULL); + } +#else + if (!__glutDisplay) { + __glutOpenXConnection(NULL); + } +#endif + if (__glutGameModeWindow) { + __glutFatalError("cannot create windows in game mode."); + } + winnum = getUnusedWindowSlot(); + window = (GLUTwindow *) malloc(sizeof(GLUTwindow)); + if (!window) { + __glutFatalError("out of memory."); + } + window->num = winnum; + +#if !defined(_WIN32) + window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, + &window->visAlloced, (void**) &fbc); + if (!window->vis) { + __glutFatalError( + "visual with necessary capabilities not found."); + } + __glutSetupColormap(window->vis, &window->colormap, &window->cmap); +#else + window->cmap = 0; +#endif + window->eventMask = StructureNotifyMask | ExposureMask; + + attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; + wa.background_pixmap = None; + wa.border_pixel = 0; + wa.colormap = window->cmap; + wa.event_mask = window->eventMask; + if (parent) { + if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) + wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK; + attribMask |= CWDontPropagate; + wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK; + } else { + wa.do_not_propagate_mask = 0; + } + + /* Stash width and height before Win32's __glutAdjustCoords + possibly overwrites the values. */ + window->width = width; + window->height = height; + window->forceReshape = True; + window->ignoreKeyRepeat = False; + +#if defined(_WIN32) + __glutAdjustCoords(parent ? parent->win : NULL, + &x, &y, &width, &height); + if (parent) { + style = WS_CHILD; + } else { + if (gameMode) { + /* Game mode window should be a WS_POPUP window to + ensure that the taskbar is hidden by it. A standard + WS_OVERLAPPEDWINDOW does not hide the task bar. */ + style = WS_POPUP | WS_MAXIMIZE; + } else { + /* A standard toplevel window with borders and such. */ + style = WS_OVERLAPPEDWINDOW; + } + } + window->win = CreateWindow("GLUT", "GLUT", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style, + x, y, width, height, parent ? parent->win : __glutRoot, + NULL, GetModuleHandle(NULL), 0); + window->hdc = GetDC(window->win); + /* Must set the XHDC for fake glXChooseVisual & fake + glXCreateContext & fake XAllocColorCells. */ + XHDC = window->hdc; + window->vis = __glutDetermineWindowVisual(&window->treatAsSingle, + &window->visAlloced, &fbc); + if (!window->vis) { + __glutFatalError( + "pixel format with necessary capabilities not found."); + } + if (!SetPixelFormat(window->hdc, + ChoosePixelFormat(window->hdc, window->vis), + window->vis)) { + __glutFatalError("SetPixelFormat failed during window create."); + } + __glutSetupColormap(window->vis, &window->colormap, &window->cmap); + /* Make sure subwindows get a windowStatus callback. */ + if (parent) { + PostMessage(parent->win, WM_ACTIVATE, 0, 0); + } + window->renderDc = window->hdc; +#else + window->win = XCreateWindow(__glutDisplay, + parent == NULL ? __glutRoot : parent->win, + x, y, width, height, 0, + window->vis->depth, InputOutput, window->vis->visual, + attribMask, &wa); +#endif + window->renderWin = window->win; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + if (fbc) { + window->ctx = glXCreateContextWithConfigSGIX(__glutDisplay, fbc, + GLX_RGBA_TYPE_SGIX, None, __glutTryDirect); + } else +#endif + { + window->ctx = glXCreateContext(__glutDisplay, window->vis, + None, __glutTryDirect); + } + if (!window->ctx) { + __glutFatalError( + "failed to create OpenGL rendering context."); + } + window->renderCtx = window->ctx; +#if !defined(_WIN32) + window->isDirect = glXIsDirect(__glutDisplay, window->ctx); + if (__glutForceDirect) { + if (!window->isDirect) + __glutFatalError("direct rendering not possible."); + } +#endif + + window->parent = parent; + if (parent) { + window->siblings = parent->children; + parent->children = window; + } else { + window->siblings = NULL; + } + window->overlay = NULL; + window->children = NULL; + window->display = __glutDefaultDisplay; + window->reshape = __glutDefaultReshape; + window->mouse = NULL; + window->motion = NULL; + window->passive = NULL; + window->entry = NULL; + window->keyboard = NULL; + window->keyboardUp = NULL; + window->windowStatus = NULL; + window->visibility = NULL; + window->special = NULL; + window->specialUp = NULL; + window->buttonBox = NULL; + window->dials = NULL; + window->spaceMotion = NULL; + window->spaceRotate = NULL; + window->spaceButton = NULL; + window->tabletMotion = NULL; + window->tabletButton = NULL; +#ifdef _WIN32 + window->joystick = NULL; + window->joyPollInterval = 0; +#endif + window->tabletPos[0] = -1; + window->tabletPos[1] = -1; + window->shownState = 0; + window->visState = -1; /* not VisibilityUnobscured, + VisibilityPartiallyObscured, or + VisibilityFullyObscured */ + window->entryState = -1; /* not EnterNotify or LeaveNotify */ + + window->desiredConfMask = 0; + window->buttonUses = 0; + window->cursor = GLUT_CURSOR_INHERIT; + + /* Setup window to be mapped when glutMainLoop starts. */ + window->workMask = GLUT_MAP_WORK; +#ifdef _WIN32 + if (gameMode) { + /* When mapping a game mode window, just show + the window. We have already created the game + mode window with a maximize flag at creation + time. Doing a ShowWindow(window->win, SW_SHOWNORMAL) + would be wrong for a game mode window since it + would unmaximize the window. */ + window->desiredMapState = GameModeState; + } else { + window->desiredMapState = NormalState; + } +#else + window->desiredMapState = NormalState; +#endif + window->prevWorkWin = __glutWindowWorkList; + __glutWindowWorkList = window; + + /* Initially, no menus attached. */ + for (i = 0; i < GLUT_MAX_MENUS; i++) { + window->menu[i] = 0; + } + + /* Add this new window to the window list. */ + __glutWindowList[winnum] = window; + + /* Make the new window the current window. */ + __glutSetWindow(window); + + __glutDetermineMesaSwapHackSupport(); + + if (window->treatAsSingle) { + /* We do this because either the window really is single + buffered (in which case this is redundant, but harmless, + because this is the initial single-buffered context + state); or we are treating a double buffered window as a + single-buffered window because the system does not appear + to export any suitable single- buffered visuals (in which + the following are necessary). */ + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + } + #ifdef WIN32 + if (gameMode) { + glutFullScreen(); + } + #endif + return window; +} + +/* CENTRY */ +int APIENTRY +glutCreateWindow(const char *title) +{ + static int firstWindow = 1; + GLUTwindow *window; +#if !defined(_WIN32) + XWMHints *wmHints; +#endif + Window win; + XTextProperty textprop; + + if (__glutGameModeWindow) { + __glutFatalError("cannot create windows in game mode."); + } + window = __glutCreateWindow(NULL, + __glutSizeHints.x, __glutSizeHints.y, + __glutInitWidth, __glutInitHeight, + /* not game mode */ 0); + win = window->win; + /* Setup ICCCM properties. */ + textprop.value = (unsigned char *) title; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(title); +#if defined(_WIN32) + SetWindowText(win, title); + if (__glutIconic) { + window->desiredMapState = IconicState; + } +#else + wmHints = XAllocWMHints(); + wmHints->initial_state = + __glutIconic ? IconicState : NormalState; + wmHints->flags = StateHint; + XSetWMProperties(__glutDisplay, win, &textprop, &textprop, + /* Only put WM_COMMAND property on first window. */ + firstWindow ? __glutArgv : NULL, + firstWindow ? __glutArgc : 0, + &__glutSizeHints, wmHints, NULL); + XFree(wmHints); + XSetWMProtocols(__glutDisplay, win, &__glutWMDeleteWindow, 1); +#endif + firstWindow = 0; + return window->num + 1; +} + +#ifdef _WIN32 +int APIENTRY +__glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)) +{ + __glutExitFunc = exitfunc; + return glutCreateWindow(title); +} +#endif + +int APIENTRY +glutCreateSubWindow(int win, int x, int y, int width, int height) +{ + GLUTwindow *window; + + window = __glutCreateWindow(__glutWindowList[win - 1], + x, y, width, height, /* not game mode */ 0); +#if !defined(_WIN32) + { + GLUTwindow *toplevel; + + toplevel = __glutToplevelOf(window); + if (toplevel->cmap != window->cmap) { + __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK); + } + } +#endif + return window->num + 1; +} +/* ENDCENTRY */ + +void +__glutDestroyWindow(GLUTwindow * window, + GLUTwindow * initialWindow) +{ + GLUTwindow **prev, *cur, *parent, *siblings; + + /* Recursively destroy any children. */ + cur = window->children; + while (cur) { + siblings = cur->siblings; + __glutDestroyWindow(cur, initialWindow); + cur = siblings; + } + /* Remove from parent's children list (only necessary for + non-initial windows and subwindows!). */ + parent = window->parent; + if (parent && parent == initialWindow->parent) { + prev = &parent->children; + cur = parent->children; + while (cur) { + if (cur == window) { + *prev = cur->siblings; + break; + } + prev = &(cur->siblings); + cur = cur->siblings; + } + } + /* Unbind if bound to this window. */ + if (window == __glutCurrentWindow) { + UNMAKE_CURRENT(); + __glutCurrentWindow = NULL; + } + /* Begin tearing down window itself. */ + if (window->overlay) { + __glutFreeOverlayFunc(window->overlay); + } + XDestroyWindow(__glutDisplay, window->win); + glXDestroyContext(__glutDisplay, window->ctx); + if (window->colormap) { + /* Only color index windows have colormap data structure. */ + __glutFreeColormap(window->colormap); + } + /* NULLing the __glutWindowList helps detect is a window + instance has been destroyed, given a window number. */ + __glutWindowList[window->num] = NULL; + + /* Cleanup data structures that might contain window. */ + cleanWindowWorkList(window); +#if !defined(_WIN32) + cleanStaleWindowList(window); +#endif + /* Remove window from the "get window cache" if it is there. */ + if (__glutWindowCache == window) + __glutWindowCache = NULL; + + if (window->visAlloced) { + /* Only free XVisualInfo* gotten from glXChooseVisual. */ + XFree(window->vis); + } + + if (window == __glutGameModeWindow) { + /* Destroying the game mode window should implicitly + have GLUT leave game mode. */ + __glutCloseDownGameMode(); + } + + free(window); +} + +/* CENTRY */ +void APIENTRY +glutDestroyWindow(int win) +{ + GLUTwindow *window = __glutWindowList[win - 1]; + + if (__glutMappedMenu && __glutMenuWindow == window) { + __glutFatalUsage("destroying menu window not allowed while menus in use"); + } +#if !defined(_WIN32) + /* If not a toplevel window... */ + if (window->parent) { + /* Destroying subwindows may change colormap requirements; + recalculate toplevel window's WM_COLORMAP_WINDOWS + property. */ + __glutPutOnWorkList(__glutToplevelOf(window->parent), + GLUT_COLORMAP_WORK); + } +#endif + __glutDestroyWindow(window, window); + XFlush(__glutDisplay); +} +/* ENDCENTRY */ + +void +__glutChangeWindowEventMask(long eventMask, Bool add) +{ + if (add) { + /* Add eventMask to window's event mask. */ + if ((__glutCurrentWindow->eventMask & eventMask) != + eventMask) { + __glutCurrentWindow->eventMask |= eventMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_EVENT_MASK_WORK); + } + } else { + /* Remove eventMask from window's event mask. */ + if (__glutCurrentWindow->eventMask & eventMask) { + __glutCurrentWindow->eventMask &= ~eventMask; + __glutPutOnWorkList(__glutCurrentWindow, + GLUT_EVENT_MASK_WORK); + } + } +} + +void APIENTRY +glutDisplayFunc(GLUTdisplayCB displayFunc) +{ + /* XXX Remove the warning after GLUT 3.0. */ + if (!displayFunc) + __glutFatalError("NULL display callback not allowed in GLUT 3.0; update your code."); + __glutCurrentWindow->display = displayFunc; +} + +void APIENTRY +glutMouseFunc(GLUTmouseCB mouseFunc) +{ + if (__glutCurrentWindow->mouse) { + if (!mouseFunc) { + /* Previous mouseFunc being disabled. */ + __glutCurrentWindow->buttonUses--; + __glutChangeWindowEventMask( + ButtonPressMask | ButtonReleaseMask, + __glutCurrentWindow->buttonUses > 0); + } + } else { + if (mouseFunc) { + /* Previously no mouseFunc, new one being installed. */ + __glutCurrentWindow->buttonUses++; + __glutChangeWindowEventMask( + ButtonPressMask | ButtonReleaseMask, True); + } + } + __glutCurrentWindow->mouse = mouseFunc; +} + +void APIENTRY +glutMotionFunc(GLUTmotionCB motionFunc) +{ + /* Hack. Some window managers (4Dwm by default) will mask + motion events if the client is not selecting for button + press and release events. So we select for press and + release events too (being careful to use reference + counting). */ + if (__glutCurrentWindow->motion) { + if (!motionFunc) { + /* previous mouseFunc being disabled */ + __glutCurrentWindow->buttonUses--; + __glutChangeWindowEventMask( + ButtonPressMask | ButtonReleaseMask, + __glutCurrentWindow->buttonUses > 0); + } + } else { + if (motionFunc) { + /* Previously no mouseFunc, new one being installed. */ + __glutCurrentWindow->buttonUses++; + __glutChangeWindowEventMask( + ButtonPressMask | ButtonReleaseMask, True); + } + } + /* Real work of selecting for passive mouse motion. */ + __glutChangeWindowEventMask( + Button1MotionMask | Button2MotionMask | Button3MotionMask, + motionFunc != NULL); + __glutCurrentWindow->motion = motionFunc; +} + +void APIENTRY +glutPassiveMotionFunc(GLUTpassiveCB passiveMotionFunc) +{ + __glutChangeWindowEventMask(PointerMotionMask, + passiveMotionFunc != NULL); + + /* Passive motion also requires watching enters and leaves so + that a fake passive motion event can be generated on an + enter. */ + __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask, + __glutCurrentWindow->entry != NULL || passiveMotionFunc != NULL); + + __glutCurrentWindow->passive = passiveMotionFunc; +} + +void APIENTRY +glutEntryFunc(GLUTentryCB entryFunc) +{ + __glutChangeWindowEventMask(EnterWindowMask | LeaveWindowMask, + entryFunc != NULL || __glutCurrentWindow->passive); + __glutCurrentWindow->entry = entryFunc; + if (!entryFunc) { + __glutCurrentWindow->entryState = -1; + } +} + +void APIENTRY +glutWindowStatusFunc(GLUTwindowStatusCB windowStatusFunc) +{ + __glutChangeWindowEventMask(VisibilityChangeMask, + windowStatusFunc != NULL); + __glutCurrentWindow->windowStatus = windowStatusFunc; + if (!windowStatusFunc) { + /* Make state invalid. */ + __glutCurrentWindow->visState = -1; + } +} + +static void GLUTCALLBACK +visibilityHelper(int status) +{ + if (status == GLUT_HIDDEN || status == GLUT_FULLY_COVERED) + __glutCurrentWindow->visibility(GLUT_NOT_VISIBLE); + else + __glutCurrentWindow->visibility(GLUT_VISIBLE); +} + +void APIENTRY +glutVisibilityFunc(GLUTvisibilityCB visibilityFunc) +{ + __glutCurrentWindow->visibility = visibilityFunc; + if (visibilityFunc) + glutWindowStatusFunc(visibilityHelper); + else + glutWindowStatusFunc(NULL); +} + +void APIENTRY +glutReshapeFunc(GLUTreshapeCB reshapeFunc) +{ + if (reshapeFunc) { + __glutCurrentWindow->reshape = reshapeFunc; + } else { + __glutCurrentWindow->reshape = __glutDefaultReshape; + } +} diff --git a/lib/glut-3.7.6/lib/glut/glut_winmisc.c b/lib/glut-3.7.6/lib/glut/glut_winmisc.c new file mode 100644 index 0000000000..1331885792 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glut_winmisc.c @@ -0,0 +1,122 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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 +#include +#include + +#if !defined(_WIN32) +#include +#include +#include /* for XA_STRING atom */ +#endif + +#include "glutint.h" + +/* CENTRY */ +void APIENTRY +glutSetWindowTitle(const char *title) +{ + XTextProperty textprop; + + assert(!__glutCurrentWindow->parent); + IGNORE_IN_GAME_MODE(); + textprop.value = (unsigned char *) title; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(title); + XSetWMName(__glutDisplay, + __glutCurrentWindow->win, &textprop); + XFlush(__glutDisplay); +} + +void APIENTRY +glutSetIconTitle(const char *title) +{ +#if !defined(_WIN32) + XTextProperty textprop; + + assert(!__glutCurrentWindow->parent); + IGNORE_IN_GAME_MODE(); + textprop.value = (unsigned char *) title; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(title); + XSetWMIconName(__glutDisplay, + __glutCurrentWindow->win, &textprop); + XFlush(__glutDisplay); +#endif +} + +void APIENTRY +glutPositionWindow(int x, int y) +{ + IGNORE_IN_GAME_MODE(); + __glutCurrentWindow->desiredX = x; + __glutCurrentWindow->desiredY = y; + __glutCurrentWindow->desiredConfMask |= CWX | CWY; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK); +} + +void APIENTRY +glutReshapeWindow(int w, int h) +{ + IGNORE_IN_GAME_MODE(); + if (w <= 0 || h <= 0) + __glutWarning("glutReshapeWindow: non-positive width or height not allowed"); + + __glutCurrentWindow->desiredWidth = w; + __glutCurrentWindow->desiredHeight = h; + __glutCurrentWindow->desiredConfMask |= CWWidth | CWHeight; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK); +} + +void APIENTRY +glutPopWindow(void) +{ + IGNORE_IN_GAME_MODE(); + __glutCurrentWindow->desiredStack = Above; + __glutCurrentWindow->desiredConfMask |= CWStackMode; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK); +} + +void APIENTRY +glutPushWindow(void) +{ + IGNORE_IN_GAME_MODE(); + __glutCurrentWindow->desiredStack = Below; + __glutCurrentWindow->desiredConfMask |= CWStackMode; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_CONFIGURE_WORK); +} + +void APIENTRY +glutIconifyWindow(void) +{ + IGNORE_IN_GAME_MODE(); + assert(!__glutCurrentWindow->parent); + __glutCurrentWindow->desiredMapState = IconicState; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK); +} + +void APIENTRY +glutShowWindow(void) +{ + IGNORE_IN_GAME_MODE(); + __glutCurrentWindow->desiredMapState = NormalState; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK); +} + +void APIENTRY +glutHideWindow(void) +{ + IGNORE_IN_GAME_MODE(); + __glutCurrentWindow->desiredMapState = WithdrawnState; + __glutPutOnWorkList(__glutCurrentWindow, GLUT_MAP_WORK); +} + +/* ENDCENTRY */ diff --git a/lib/glut-3.7.6/lib/glut/glutbitmap.h b/lib/glut-3.7.6/lib/glut/glutbitmap.h new file mode 100644 index 0000000000..dc1b61af19 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glutbitmap.h @@ -0,0 +1,32 @@ +#ifndef __glutbitmap_h__ +#define __glutbitmap_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 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. */ + +#define GLUT_NO_LIB_PRAGMA /* Avoid auto library linking when building + the GLUT library itself. */ +#include + +typedef struct { + const GLsizei width; + const GLsizei height; + const GLfloat xorig; + const GLfloat yorig; + const GLfloat advance; + const GLubyte *bitmap; +} BitmapCharRec, *BitmapCharPtr; + +typedef struct { + const char *name; + const int num_chars; + const int first; + const BitmapCharRec * const *ch; +} BitmapFontRec, *BitmapFontPtr; + +typedef void *GLUTbitmapFont; + +#endif /* __glutbitmap_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/glutint.h b/lib/glut-3.7.6/lib/glut/glutint.h new file mode 100644 index 0000000000..3f9a8cb1db --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glutint.h @@ -0,0 +1,779 @@ +#ifndef __glutint_h__ +#define __glutint_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 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. */ + +#if defined(__CYGWIN32__) +#include +#endif + +#define SUPPORT_FORTRAN /* With GLUT 3.7, everyone supports Fortran. */ + +#if defined(_WIN32) +#include "glutwin32.h" +#else +#include +#include +#include +#endif + +#define GLUT_BUILDING_LIB /* Building the GLUT library itself. */ + +/* GLUT_BUILDING_LIB is used by to 1) not #pragma link + with the GLUT library, and 2) avoid the Win32 atexit hack. */ + +#include + +#ifndef CDECL +# if defined(_WIN32) && defined(_MSC_VER) +# define CDECL __cdecl +# else +# define CDECL +# endif +#endif + +/* This must be done after is included. MESA is defined + if the is supplied by Brian Paul's Mesa library. */ +#if defined(MESA) && defined(_WIN32) +/* Mesa implements "wgl" versions of GDI entry points needed for + using OpenGL. Map these "wgl" versions to the GDI names via + macros. */ +WINGDIAPI int WINAPI wglChoosePixelFormat(HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd); +WINGDIAPI int WINAPI wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd); +WINGDIAPI int WINAPI wglGetPixelFormat(HDC hdc); +WINGDIAPI BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd); +WINGDIAPI BOOL WINAPI wglSwapBuffers(HDC hdc); +#define ChoosePixelFormat wglChoosePixelFormat +#define DescribePixelFormat wglDescribePixelFormat +#define GetPixelFormat wglGetPixelFormat +#define SetPixelFormat wglSetPixelFormat +#define SwapBuffers wglSwapBuffers +#endif + +/* Non-Win32 platforms need APIENTRY defined to nothing + because all the GLUT routines have the APIENTRY prefix + to make Win32 happy. */ +#ifndef APIENTRY +#define APIENTRY +#endif + +#ifdef SUPPORT_FORTRAN +#include +#endif + +#ifdef __vms +#if ( __VMS_VER < 70000000 ) +struct timeval { + __int64 val; +}; +extern int sys$gettim(struct timeval *); +#else +#include +#endif +#else +#include +#if !defined(_WIN32) +#include +#else +#include +#endif +#endif +#if defined(__vms) && ( __VMS_VER < 70000000 ) + +/* For VMS6.2 or lower : + One TICK on VMS is 100 nanoseconds; 0.1 microseconds or + 0.0001 milliseconds. This means that there are 0.01 + ticks/ns, 10 ticks/us, 10,000 ticks/ms and 10,000,000 + ticks/second. */ + +#define TICKS_PER_MILLISECOND 10000 +#define TICKS_PER_SECOND 10000000 + +#define GETTIMEOFDAY(_x) (void) sys$gettim (_x); + +#define ADD_TIME(dest, src1, src2) { \ + (dest).val = (src1).val + (src2).val; \ +} + +#define TIMEDELTA(dest, src1, src2) { \ + (dest).val = (src1).val - (src2).val; \ +} + +#define IS_AFTER(t1, t2) ((t2).val > (t1).val) + +#define IS_AT_OR_AFTER(t1, t2) ((t2).val >= (t1).val) + +#else +#if defined(SVR4) && !defined(sun) /* Sun claims SVR4, but + wants 2 args. */ +#define GETTIMEOFDAY(_x) gettimeofday(_x) +#else +#define GETTIMEOFDAY(_x) gettimeofday(_x, NULL) +#endif +#define ADD_TIME(dest, src1, src2) { \ + if(((dest).tv_usec = \ + (src1).tv_usec + (src2).tv_usec) >= 1000000) { \ + (dest).tv_usec -= 1000000; \ + (dest).tv_sec = (src1).tv_sec + (src2).tv_sec + 1; \ + } else { \ + (dest).tv_sec = (src1).tv_sec + (src2).tv_sec; \ + if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { \ + (dest).tv_sec --;(dest).tv_usec += 1000000; \ + } \ + } \ +} +#define TIMEDELTA(dest, src1, src2) { \ + if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) { \ + (dest).tv_usec += 1000000; \ + (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; \ + } else { \ + (dest).tv_sec = (src1).tv_sec - (src2).tv_sec; \ + } \ +} +#define IS_AFTER(t1, t2) \ + (((t2).tv_sec > (t1).tv_sec) || \ + (((t2).tv_sec == (t1).tv_sec) && \ + ((t2).tv_usec > (t1).tv_usec))) +#define IS_AT_OR_AFTER(t1, t2) \ + (((t2).tv_sec > (t1).tv_sec) || \ + (((t2).tv_sec == (t1).tv_sec) && \ + ((t2).tv_usec >= (t1).tv_usec))) +#endif + +#define IGNORE_IN_GAME_MODE() \ + { if (__glutGameModeWindow) return; } + +#define GLUT_WIND_IS_RGB(x) (((x) & GLUT_INDEX) == 0) +#define GLUT_WIND_IS_INDEX(x) (((x) & GLUT_INDEX) != 0) +#define GLUT_WIND_IS_SINGLE(x) (((x) & GLUT_DOUBLE) == 0) +#define GLUT_WIND_IS_DOUBLE(x) (((x) & GLUT_DOUBLE) != 0) +#define GLUT_WIND_HAS_ACCUM(x) (((x) & GLUT_ACCUM) != 0) +#define GLUT_WIND_HAS_ALPHA(x) (((x) & GLUT_ALPHA) != 0) +#define GLUT_WIND_HAS_DEPTH(x) (((x) & GLUT_DEPTH) != 0) +#define GLUT_WIND_HAS_STENCIL(x) (((x) & GLUT_STENCIL) != 0) +#define GLUT_WIND_IS_MULTISAMPLE(x) (((x) & GLUT_MULTISAMPLE) != 0) +#define GLUT_WIND_IS_STEREO(x) (((x) & GLUT_STEREO) != 0) +#define GLUT_WIND_IS_LUMINANCE(x) (((x) & GLUT_LUMINANCE) != 0) +#define GLUT_MAP_WORK (1 << 0) +#define GLUT_EVENT_MASK_WORK (1 << 1) +#define GLUT_REDISPLAY_WORK (1 << 2) +#define GLUT_CONFIGURE_WORK (1 << 3) +#define GLUT_COLORMAP_WORK (1 << 4) +#define GLUT_DEVICE_MASK_WORK (1 << 5) +#define GLUT_FINISH_WORK (1 << 6) +#define GLUT_DEBUG_WORK (1 << 7) +#define GLUT_DUMMY_WORK (1 << 8) +#define GLUT_FULL_SCREEN_WORK (1 << 9) +#define GLUT_OVERLAY_REDISPLAY_WORK (1 << 10) +#define GLUT_REPAIR_WORK (1 << 11) +#define GLUT_OVERLAY_REPAIR_WORK (1 << 12) + +/* Frame buffer capability macros and types. */ +#define RGBA 0 +#define BUFFER_SIZE 1 +#define DOUBLEBUFFER 2 +#define STEREO 3 +#define AUX_BUFFERS 4 +#define RED_SIZE 5 /* Used as mask bit for + "color selected". */ +#define GREEN_SIZE 6 +#define BLUE_SIZE 7 +#define ALPHA_SIZE 8 +#define DEPTH_SIZE 9 +#define STENCIL_SIZE 10 +#define ACCUM_RED_SIZE 11 /* Used as mask bit for + "acc selected". */ +#define ACCUM_GREEN_SIZE 12 +#define ACCUM_BLUE_SIZE 13 +#define ACCUM_ALPHA_SIZE 14 +#define LEVEL 15 + +#define NUM_GLXCAPS (LEVEL + 1) + +#define XVISUAL (NUM_GLXCAPS + 0) +#define TRANSPARENT (NUM_GLXCAPS + 1) +#define SAMPLES (NUM_GLXCAPS + 2) +#define XSTATICGRAY (NUM_GLXCAPS + 3) /* Used as + mask bit + for "any + visual type + selected". */ +#define XGRAYSCALE (NUM_GLXCAPS + 4) +#define XSTATICCOLOR (NUM_GLXCAPS + 5) +#define XPSEUDOCOLOR (NUM_GLXCAPS + 6) +#define XTRUECOLOR (NUM_GLXCAPS + 7) +#define XDIRECTCOLOR (NUM_GLXCAPS + 8) +#define SLOW (NUM_GLXCAPS + 9) +#define CONFORMANT (NUM_GLXCAPS + 10) + +#define NUM_CAPS (NUM_GLXCAPS + 11) + +/* Frame buffer capablities that don't have a corresponding + FrameBufferMode entry. These get used as mask bits. */ +#define NUM (NUM_CAPS + 0) +#define RGBA_MODE (NUM_CAPS + 1) +#define CI_MODE (NUM_CAPS + 2) +#define LUMINANCE_MODE (NUM_CAPS + 3) + +#define NONE 0 +#define EQ 1 +#define NEQ 2 +#define LTE 3 +#define GTE 4 +#define GT 5 +#define LT 6 +#define MIN 7 + +typedef struct _Criterion { + int capability; + int comparison; + int value; +} Criterion; + +typedef struct _FrameBufferMode { + XVisualInfo *vi; +#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) + + /* fbc is non-NULL when the XVisualInfo* is not OpenGL-capable + (ie, GLX_USE_GL is false), but the SGIX_fbconfig extension shows + the visual's fbconfig is OpenGL-capable. The reason for this is typically + an RGBA luminance fbconfig such as 16-bit StaticGray that could + not be advertised as a GLX visual since StaticGray visuals are + required (by the GLX specification) to be color index. The + SGIX_fbconfig allows StaticGray visuals to instead advertised as + fbconfigs that can provide RGBA luminance support. */ + + GLXFBConfigSGIX fbc; +#endif + int valid; + int cap[NUM_CAPS]; +} FrameBufferMode; + +/* DisplayMode capability macros for game mode. */ +#define DM_WIDTH 0 /* "width" */ +#define DM_HEIGHT 1 /* "height" */ +#define DM_PIXEL_DEPTH 2 /* "bpp" (bits per pixel) */ +#define DM_HERTZ 3 /* "hertz" */ +#define DM_NUM 4 /* "num" */ + +#define NUM_DM_CAPS (DM_NUM+1) + +typedef struct _DisplayMode { +#ifdef _WIN32 + DEVMODE devmode; +#else + /* XXX The X Window System does not have a standard + mechanism for display setting changes. On SGI + systems, GLUT could use the XSGIvc (SGI X video + control extension). Perhaps this can be done in + a future release of GLUT. */ +#endif + int valid; + int cap[NUM_DM_CAPS]; +} DisplayMode; + +/* GLUT function types */ +typedef void (GLUTCALLBACK *GLUTdisplayCB) (void); +typedef void (GLUTCALLBACK *GLUTreshapeCB) (int, int); +typedef void (GLUTCALLBACK *GLUTkeyboardCB) (unsigned char, int, int); +typedef void (GLUTCALLBACK *GLUTmouseCB) (int, int, int, int); +typedef void (GLUTCALLBACK *GLUTmotionCB) (int, int); +typedef void (GLUTCALLBACK *GLUTpassiveCB) (int, int); +typedef void (GLUTCALLBACK *GLUTentryCB) (int); +typedef void (GLUTCALLBACK *GLUTvisibilityCB) (int); +typedef void (GLUTCALLBACK *GLUTwindowStatusCB) (int); +typedef void (GLUTCALLBACK *GLUTidleCB) (void); +typedef void (GLUTCALLBACK *GLUTtimerCB) (int); +typedef void (GLUTCALLBACK *GLUTmenuStateCB) (int); /* DEPRICATED. */ +typedef void (GLUTCALLBACK *GLUTmenuStatusCB) (int, int, int); +typedef void (GLUTCALLBACK *GLUTselectCB) (int); +typedef void (GLUTCALLBACK *GLUTspecialCB) (int, int, int); +typedef void (GLUTCALLBACK *GLUTspaceMotionCB) (int, int, int); +typedef void (GLUTCALLBACK *GLUTspaceRotateCB) (int, int, int); +typedef void (GLUTCALLBACK *GLUTspaceButtonCB) (int, int); +typedef void (GLUTCALLBACK *GLUTdialsCB) (int, int); +typedef void (GLUTCALLBACK *GLUTbuttonBoxCB) (int, int); +typedef void (GLUTCALLBACK *GLUTtabletMotionCB) (int, int); +typedef void (GLUTCALLBACK *GLUTtabletButtonCB) (int, int, int, int); +typedef void (GLUTCALLBACK *GLUTjoystickCB) (unsigned int buttonMask, int x, int y, int z); + +typedef struct _GLUTcolorcell GLUTcolorcell; +struct _GLUTcolorcell { + /* GLUT_RED, GLUT_GREEN, GLUT_BLUE */ + GLfloat component[3]; +}; + +typedef struct _GLUTcolormap GLUTcolormap; +struct _GLUTcolormap { + Visual *visual; /* visual of the colormap */ + Colormap cmap; /* X colormap ID */ + int refcnt; /* number of windows using colormap */ + int size; /* number of cells in colormap */ + int transparent; /* transparent pixel, or -1 if opaque */ + GLUTcolorcell *cells; /* array of cells */ + GLUTcolormap *next; /* next colormap in list */ +}; + +typedef struct _GLUTwindow GLUTwindow; +typedef struct _GLUToverlay GLUToverlay; +struct _GLUTwindow { + int num; /* Small integer window id (0-based). */ + + /* Window system related state. */ +#if defined(_WIN32) + int pf; /* Pixel format. */ + HDC hdc; /* Window's Win32 device context. */ +#endif + Window win; /* X window for GLUT window */ + GLXContext ctx; /* OpenGL context GLUT glut window */ + XVisualInfo *vis; /* visual for window */ + Bool visAlloced; /* if vis needs deallocate on destroy */ + Colormap cmap; /* RGB colormap for window; None if CI */ + GLUTcolormap *colormap; /* colormap; NULL if RGBA */ + GLUToverlay *overlay; /* overlay; NULL if no overlay */ +#if defined(_WIN32) + HDC renderDc; /* Win32's device context for rendering. */ +#endif + Window renderWin; /* X window for rendering (might be + overlay) */ + GLXContext renderCtx; /* OpenGL context for rendering (might + be overlay) */ + /* GLUT settable or visible window state. */ + int width; /* window width in pixels */ + int height; /* window height in pixels */ + int cursor; /* cursor name */ + int visState; /* visibility state (-1 is unknown) */ + int shownState; /* if window mapped */ + int entryState; /* entry state (-1 is unknown) */ +#define GLUT_MAX_MENUS 3 + + int menu[GLUT_MAX_MENUS]; /* attatched menu nums */ + /* Window relationship state. */ + GLUTwindow *parent; /* parent window */ + GLUTwindow *children; /* list of children */ + GLUTwindow *siblings; /* list of siblings */ + /* Misc. non-API visible (hidden) state. */ + Bool treatAsSingle; /* treat this window as single-buffered + (it might be "fake" though) */ + Bool forceReshape; /* force reshape before display */ +#if !defined(_WIN32) + Bool isDirect; /* if direct context (X11 only) */ +#endif + Bool usedSwapBuffers; /* if swap buffers used last display */ + long eventMask; /* mask of X events selected for */ + int buttonUses; /* number of button uses, ref cnt */ + int tabletPos[2]; /* tablet position (-1 is invalid) */ + /* Work list related state. */ + unsigned int workMask; /* mask of window work to be done */ + GLUTwindow *prevWorkWin; /* link list of windows to work on */ + Bool desiredMapState; /* how to mapped window if on map work + list */ + Bool ignoreKeyRepeat; /* if window ignores autorepeat */ + int desiredConfMask; /* mask of desired window configuration + */ + int desiredX; /* desired X location */ + int desiredY; /* desired Y location */ + int desiredWidth; /* desired window width */ + int desiredHeight; /* desired window height */ + int desiredStack; /* desired window stack */ + /* Per-window callbacks. */ + GLUTdisplayCB display; /* redraw */ + GLUTreshapeCB reshape; /* resize (width,height) */ + GLUTmouseCB mouse; /* mouse (button,state,x,y) */ + GLUTmotionCB motion; /* motion (x,y) */ + GLUTpassiveCB passive; /* passive motion (x,y) */ + GLUTentryCB entry; /* window entry/exit (state) */ + GLUTkeyboardCB keyboard; /* keyboard (ASCII,x,y) */ + GLUTkeyboardCB keyboardUp; /* keyboard up (ASCII,x,y) */ + GLUTwindowStatusCB windowStatus; /* window status */ + GLUTvisibilityCB visibility; /* visibility */ + GLUTspecialCB special; /* special key */ + GLUTspecialCB specialUp; /* special up key */ + GLUTbuttonBoxCB buttonBox; /* button box */ + GLUTdialsCB dials; /* dials */ + GLUTspaceMotionCB spaceMotion; /* Spaceball motion */ + GLUTspaceRotateCB spaceRotate; /* Spaceball rotate */ + GLUTspaceButtonCB spaceButton; /* Spaceball button */ + GLUTtabletMotionCB tabletMotion; /* tablet motion */ + GLUTtabletButtonCB tabletButton; /* tablet button */ +#ifdef _WIN32 + GLUTjoystickCB joystick; /* joystick */ + int joyPollInterval; /* joystick polling interval */ +#endif +#ifdef SUPPORT_FORTRAN + GLUTdisplayFCB fdisplay; /* Fortran display */ + GLUTreshapeFCB freshape; /* Fortran reshape */ + GLUTmouseFCB fmouse; /* Fortran mouse */ + GLUTmotionFCB fmotion; /* Fortran motion */ + GLUTpassiveFCB fpassive; /* Fortran passive */ + GLUTentryFCB fentry; /* Fortran entry */ + GLUTkeyboardFCB fkeyboard; /* Fortran keyboard */ + GLUTkeyboardFCB fkeyboardUp; /* Fortran keyboard up */ + GLUTwindowStatusFCB fwindowStatus; /* Fortran window status */ + GLUTvisibilityFCB fvisibility; /* Fortran visibility */ + GLUTspecialFCB fspecial; /* special key */ + GLUTspecialFCB fspecialUp; /* special key up */ + GLUTbuttonBoxFCB fbuttonBox; /* button box */ + GLUTdialsFCB fdials; /* dials */ + GLUTspaceMotionFCB fspaceMotion; /* Spaceball motion */ + GLUTspaceRotateFCB fspaceRotate; /* Spaceball rotate */ + GLUTspaceButtonFCB fspaceButton; /* Spaceball button */ + GLUTtabletMotionFCB ftabletMotion; /* tablet motion */ + GLUTtabletButtonFCB ftabletButton; /* tablet button */ +#ifdef _WIN32 + GLUTjoystickFCB fjoystick; /* joystick */ +#endif +#endif +}; + +struct _GLUToverlay { +#if defined(_WIN32) + int pf; + HDC hdc; +#endif + Window win; + GLXContext ctx; + XVisualInfo *vis; /* visual for window */ + Bool visAlloced; /* if vis needs deallocate on destroy */ + Colormap cmap; /* RGB colormap for window; None if CI */ + GLUTcolormap *colormap; /* colormap; NULL if RGBA */ + int shownState; /* if overlay window mapped */ + Bool treatAsSingle; /* treat as single-buffered */ +#if !defined(_WIN32) + Bool isDirect; /* if direct context */ +#endif + int transparentPixel; /* transparent pixel value */ + GLUTdisplayCB display; /* redraw */ +#ifdef SUPPORT_FORTRAN + GLUTdisplayFCB fdisplay; /* redraw */ +#endif +}; + +typedef struct _GLUTstale GLUTstale; +struct _GLUTstale { + GLUTwindow *window; + Window win; + GLUTstale *next; +}; + +extern GLUTstale *__glutStaleWindowList; + +#define GLUT_OVERLAY_EVENT_FILTER_MASK \ + (ExposureMask | \ + StructureNotifyMask | \ + EnterWindowMask | \ + LeaveWindowMask) +#define GLUT_DONT_PROPAGATE_FILTER_MASK \ + (ButtonReleaseMask | \ + ButtonPressMask | \ + KeyPressMask | \ + KeyReleaseMask | \ + PointerMotionMask | \ + Button1MotionMask | \ + Button2MotionMask | \ + Button3MotionMask) +#define GLUT_HACK_STOP_PROPAGATE_MASK \ + (KeyPressMask | \ + KeyReleaseMask) + +typedef struct _GLUTmenu GLUTmenu; +typedef struct _GLUTmenuItem GLUTmenuItem; +struct _GLUTmenu { + int id; /* small integer menu id (0-based) */ +#if defined(_WIN32) + HMENU win; /* Win32 menu */ +#else + Window win; /* X window for the menu */ +#endif + GLUTselectCB select; /* function of menu */ + GLUTmenuItem *list; /* list of menu entries */ + int num; /* number of entries */ +#if !defined(_WIN32) + Bool managed; /* are the InputOnly windows size + validated? */ + Bool searched; /* help detect menu loops */ + int pixheight; /* height of menu in pixels */ + int pixwidth; /* width of menu in pixels */ +#endif + int submenus; /* number of submenu entries */ + GLUTmenuItem *highlighted; /* pointer to highlighted menu + entry, NULL not highlighted */ + GLUTmenu *cascade; /* currently cascading this menu */ + GLUTmenuItem *anchor; /* currently anchored to this entry */ + int x; /* current x origin relative to the + root window */ + int y; /* current y origin relative to the + root window */ +#ifdef SUPPORT_FORTRAN + GLUTselectFCB fselect; /* function of menu */ +#endif +}; + +struct _GLUTmenuItem { +#if defined(_WIN32) + HMENU win; /* Win32 window for entry */ +#else + Window win; /* InputOnly X window for entry */ +#endif + GLUTmenu *menu; /* menu entry belongs to */ + Bool isTrigger; /* is a submenu trigger? */ + int value; /* value to return for selecting this + entry; doubles as submenu id + (0-base) if submenu trigger */ +#if defined(_WIN32) + UINT unique; /* unique menu item id (Win32 only) */ +#endif + char *label; /* __glutStrdup'ed label string */ + int len; /* length of label string */ + int pixwidth; /* width of X window in pixels */ + GLUTmenuItem *next; /* next menu entry on list for menu */ +}; + +typedef struct _GLUTtimer GLUTtimer; +struct _GLUTtimer { + GLUTtimer *next; /* list of timers */ + struct timeval timeout; /* time to be called */ + GLUTtimerCB func; /* timer (value) */ + int value; /* return value */ +#ifdef SUPPORT_FORTRAN + GLUTtimerFCB ffunc; /* Fortran timer */ +#endif +}; + +typedef struct _GLUTeventParser GLUTeventParser; +struct _GLUTeventParser { + int (*func) (XEvent *); + GLUTeventParser *next; +}; + +/* Declarations to implement glutFullScreen support with + mwm/4Dwm. */ + +/* The following X property format is defined in Motif 1.1's + Xm/MwmUtils.h, but GLUT should not depend on that header + file. Note: Motif 1.2 expanded this structure with + uninteresting fields (to GLUT) so just stick with the + smaller Motif 1.1 structure. */ +typedef struct { +#define MWM_HINTS_DECORATIONS 2 + long flags; + long functions; + long decorations; + long input_mode; +} MotifWmHints; + +/* Make current and buffer swap macros. */ +#ifdef _WIN32 +#define MAKE_CURRENT_LAYER(window) \ + { \ + HGLRC currentContext = wglGetCurrentContext(); \ + HDC currentDc = wglGetCurrentDC(); \ + \ + if (currentContext != window->renderCtx \ + || currentDc != window->renderDc) { \ + wglMakeCurrent(window->renderDc, window->renderCtx); \ + } \ + } +#define MAKE_CURRENT_WINDOW(window) \ + { \ + HGLRC currentContext = wglGetCurrentContext(); \ + HDC currentDc = wglGetCurrentDC(); \ + \ + if (currentContext != window->ctx || currentDc != window->hdc) { \ + wglMakeCurrent(window->hdc, window->ctx); \ + } \ + } +#define MAKE_CURRENT_OVERLAY(overlay) \ + wglMakeCurrent(overlay->hdc, overlay->ctx) +#define UNMAKE_CURRENT() \ + wglMakeCurrent(NULL, NULL) +#define SWAP_BUFFERS_WINDOW(window) \ + SwapBuffers(window->hdc) +#define SWAP_BUFFERS_LAYER(window) \ + SwapBuffers(window->renderDc) +#else +#define MAKE_CURRENT_LAYER(window) \ + glXMakeCurrent(__glutDisplay, window->renderWin, window->renderCtx) +#define MAKE_CURRENT_WINDOW(window) \ + glXMakeCurrent(__glutDisplay, window->win, window->ctx) +#define MAKE_CURRENT_OVERLAY(overlay) \ + glXMakeCurrent(__glutDisplay, overlay->win, overlay->ctx) +#define UNMAKE_CURRENT() \ + glXMakeCurrent(__glutDisplay, None, NULL) +#define SWAP_BUFFERS_WINDOW(window) \ + glXSwapBuffers(__glutDisplay, window->win) +#define SWAP_BUFFERS_LAYER(window) \ + glXSwapBuffers(__glutDisplay, window->renderWin) +#endif + +/* private variables from glut_event.c */ +extern GLUTwindow *__glutWindowWorkList; +extern int __glutWindowDamaged; +#ifdef SUPPORT_FORTRAN +extern GLUTtimer *__glutTimerList; +extern GLUTtimer *__glutNewTimer; +#endif +extern GLUTmenu *__glutMappedMenu; + +extern void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *); +#if !defined(_WIN32) +extern void (*__glutMenuItemEnterOrLeave)(GLUTmenuItem * item, + int num, int type); +extern void (*__glutFinishMenu)(Window win, int x, int y); +extern void (*__glutPaintMenu)(GLUTmenu * menu); +extern void (*__glutStartMenu)(GLUTmenu * menu, + GLUTwindow * window, int x, int y, int x_win, int y_win); +extern GLUTmenu * (*__glutGetMenuByNum)(int menunum); +extern GLUTmenuItem * (*__glutGetMenuItem)(GLUTmenu * menu, + Window win, int *which); +extern GLUTmenu * (*__glutGetMenu)(Window win); +#endif + +/* private variables from glut_init.c */ +extern Atom __glutWMDeleteWindow; +extern Display *__glutDisplay; +extern unsigned int __glutDisplayMode; +extern char *__glutDisplayString; +extern XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle, + Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc); +extern GLboolean __glutDebug; +extern GLboolean __glutForceDirect; +extern GLboolean __glutIconic; +extern GLboolean __glutTryDirect; +extern Window __glutRoot; +extern XSizeHints __glutSizeHints; +extern char **__glutArgv; +extern char *__glutProgramName; +extern int __glutArgc; +extern int __glutConnectionFD; +extern int __glutInitHeight; +extern int __glutInitWidth; +extern int __glutInitX; +extern int __glutInitY; +extern int __glutScreen; +extern int __glutScreenHeight; +extern int __glutScreenWidth; +extern Atom __glutMotifHints; +extern unsigned int __glutModifierMask; +#ifdef _WIN32 +extern void (__cdecl *__glutExitFunc)(int retval); +#endif + +/* private variables from glut_menu.c */ +extern GLUTmenuItem *__glutItemSelected; +extern GLUTmenu **__glutMenuList; +extern void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int); +extern void __glutMenuModificationError(void); +extern void __glutSetMenuItem(GLUTmenuItem * item, + const char *label, int value, Bool isTrigger); + +/* private variables from glut_win.c */ +extern GLUTwindow **__glutWindowList; +extern GLUTwindow *__glutCurrentWindow; +extern GLUTwindow *__glutMenuWindow; +extern GLUTmenu *__glutCurrentMenu; +extern int __glutWindowListSize; +extern void (*__glutFreeOverlayFunc) (GLUToverlay *); +extern XVisualInfo *__glutDetermineWindowVisual(Bool * treatAsSingle, + Bool * visAlloced, void **fbc); + +/* private variables from glut_mesa.c */ +extern int __glutMesaSwapHackSupport; + +/* private variables from glut_gamemode.c */ +extern GLUTwindow *__glutGameModeWindow; + +/* private routines from glut_cindex.c */ +extern GLUTcolormap * __glutAssociateNewColormap(XVisualInfo * vis); +extern void __glutFreeColormap(GLUTcolormap *); + +/* private routines from glut_cmap.c */ +extern void __glutSetupColormap( + XVisualInfo * vi, + GLUTcolormap ** colormap, + Colormap * cmap); +#if !defined(_WIN32) +extern void __glutEstablishColormapsProperty( + GLUTwindow * window); +extern GLUTwindow *__glutToplevelOf(GLUTwindow * window); +#endif + +/* private routines from glut_cursor.c */ +extern void __glutSetCursor(GLUTwindow *window); + +/* private routines from glut_event.c */ +extern void __glutPutOnWorkList(GLUTwindow * window, + int work_mask); +extern void __glutRegisterEventParser(GLUTeventParser * parser); +extern void __glutPostRedisplay(GLUTwindow * window, int layerMask); + +/* private routines from glut_init.c */ +#if !defined(_WIN32) +extern void __glutOpenXConnection(char *display); +#else +extern void __glutOpenWin32Connection(char *display); +#endif +extern void __glutInitTime(struct timeval *beginning); + +/* private routines for glut_menu.c (or win32_menu.c) */ +#if defined(_WIN32) +extern GLUTmenu *__glutGetMenu(HMENU win); +extern GLUTmenu *__glutGetMenuByNum(int menunum); +extern GLUTmenuItem *__glutGetMenuItem(GLUTmenu * menu, + HMENU win, int *which); +extern void __glutStartMenu(GLUTmenu * menu, + GLUTwindow * window, int x, int y, int x_win, int y_win); +extern void __glutFinishMenu(Window win, int x, int y); +#endif +extern void __glutSetMenu(GLUTmenu * menu); + +/* private routines from glut_util.c */ +extern char * __glutStrdup(const char *string); +extern void __glutWarning(char *format,...); +extern void __glutFatalError(char *format,...); +extern void __glutFatalUsage(char *format,...); + +/* private routines from glut_win.c */ +extern GLUTwindow *__glutGetWindow(Window win); +extern void __glutChangeWindowEventMask(long mask, Bool add); +extern XVisualInfo *__glutDetermineVisual( + unsigned int mode, + Bool * fakeSingle, + XVisualInfo * (getVisualInfo) (unsigned int)); +extern XVisualInfo *__glutGetVisualInfo(unsigned int mode); +extern void __glutSetWindow(GLUTwindow * window); +extern void __glutReshapeFunc(GLUTreshapeCB reshapeFunc, + int callingConvention); +extern void GLUTCALLBACK __glutDefaultReshape(int, int); +extern GLUTwindow *__glutCreateWindow( + GLUTwindow * parent, + int x, int y, int width, int height, int gamemode); +extern void __glutDestroyWindow( + GLUTwindow * window, + GLUTwindow * initialWindow); + +#if !defined(_WIN32) +/* private routines from glut_glxext.c */ +extern int __glutIsSupportedByGLX(char *); +#endif + +/* private routines from glut_input.c */ +extern void __glutUpdateInputDeviceMask(GLUTwindow * window); + +/* private routines from glut_mesa.c */ +extern void __glutDetermineMesaSwapHackSupport(void); + +/* private routines from glut_gameglut.c */ +extern void CDECL __glutCloseDownGameMode(void); + +#if defined(_WIN32) +/* private routines from win32_*.c */ +extern LONG WINAPI __glutWindowProc(HWND win, UINT msg, WPARAM w, LPARAM l); +extern HDC XHDC; +#endif + +#endif /* __glutint_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/glutstroke.h b/lib/glut-3.7.6/lib/glut/glutstroke.h new file mode 100644 index 0000000000..fbbc70d6cc --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glutstroke.h @@ -0,0 +1,42 @@ +#ifndef __glutstroke_h__ +#define __glutstroke_h__ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* 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. */ + +#if defined(_WIN32) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +typedef struct { + float x; + float y; +} CoordRec, *CoordPtr; + +typedef struct { + int num_coords; + const CoordRec *coord; +} StrokeRec, *StrokePtr; + +typedef struct { + int num_strokes; + const StrokeRec *stroke; + float center; + float right; +} StrokeCharRec, *StrokeCharPtr; + +typedef struct { + const char *name; + int num_chars; + const StrokeCharRec *ch; + float top; + float bottom; +} StrokeFontRec, *StrokeFontPtr; + +typedef void *GLUTstrokeFont; + +#endif /* __glutstroke_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/glutwin32.h b/lib/glut-3.7.6/lib/glut/glutwin32.h new file mode 100644 index 0000000000..15ba945e65 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/glutwin32.h @@ -0,0 +1,48 @@ +#ifndef __glutwin32_h__ +#define __glutwin32_h__ + +/* Copyright (c) Nate Robins, 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. */ + +#include "win32_x11.h" +#include "win32_glx.h" + +/* We have to undef some things because Microsoft likes to pollute the + global namespace. */ +#undef TRANSPARENT + +/* Win32 "equivalent" cursors - eventually, the X glyphs should be + converted to Win32 cursors -- then they will look the same */ +#define XC_arrow IDC_ARROW +#define XC_top_left_arrow IDC_ARROW +#define XC_hand1 IDC_SIZEALL +#define XC_pirate IDC_NO +#define XC_question_arrow IDC_HELP +#define XC_exchange IDC_NO +#define XC_spraycan IDC_SIZEALL +#define XC_watch IDC_WAIT +#define XC_xterm IDC_IBEAM +#define XC_crosshair IDC_CROSS +#define XC_sb_v_double_arrow IDC_SIZENS +#define XC_sb_h_double_arrow IDC_SIZEWE +#define XC_top_side IDC_UPARROW +#define XC_bottom_side IDC_SIZENS +#define XC_left_side IDC_SIZEWE +#define XC_right_side IDC_SIZEWE +#define XC_top_left_corner IDC_SIZENWSE +#define XC_top_right_corner IDC_SIZENESW +#define XC_bottom_right_corner IDC_SIZENWSE +#define XC_bottom_left_corner IDC_SIZENESW + +#define XA_STRING 0 + +/* Private routines from win32_util.c */ +extern int gettimeofday(struct timeval* tp, void* tzp); +extern void *__glutFont(void *font); +extern int __glutGetTransparentPixel(Display *dpy, XVisualInfo *vinfo); +extern void __glutAdjustCoords(Window parent, int *x, int *y, int *width, int *height); + +#endif /* __glutwin32_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/layerutil.c b/lib/glut-3.7.6/lib/glut/layerutil.c new file mode 100644 index 0000000000..70a9ed9db8 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/layerutil.c @@ -0,0 +1,201 @@ + +/* Copyright (c) Mark J. Kilgard, 1993, 1994. */ + +/* 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. */ + +/* Based on XLayerUtil.c: Revision: 1.5 */ + +#include +#include +#include "layerutil.h" + +/* SGI optimization introduced in IRIX 6.3 to avoid X server + round trips for interning common X atoms. */ +#include +#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) +#include +#else +#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how) +#endif + +static Bool layersRead = False; +static OverlayInfo **overlayInfoPerScreen; +static unsigned long *numOverlaysPerScreen; + +static void +findServerOverlayVisualsInfo(Display * dpy) +{ + static Atom overlayVisualsAtom; + Atom actualType; + Status status; + unsigned long sizeData, bytesLeft; + Window root; + int actualFormat, numScreens, i; + + if (layersRead == False) { + overlayVisualsAtom = XSGIFastInternAtom(dpy, + "SERVER_OVERLAY_VISUALS", SGI_XA_SERVER_OVERLAY_VISUALS, True); + if (overlayVisualsAtom != None) { + numScreens = ScreenCount(dpy); + overlayInfoPerScreen = (OverlayInfo **) + malloc(numScreens * sizeof(OverlayInfo *)); + numOverlaysPerScreen = (unsigned long *) + malloc(numScreens * sizeof(unsigned long)); + if (overlayInfoPerScreen != NULL && + numOverlaysPerScreen != NULL) { + for (i = 0; i < numScreens; i++) { + root = RootWindow(dpy, i); + status = XGetWindowProperty(dpy, root, + overlayVisualsAtom, 0L, (long) 10000, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + (unsigned char **) &overlayInfoPerScreen[i]); + if (status != Success || + actualType != overlayVisualsAtom || + actualFormat != 32 || sizeData < 4) + numOverlaysPerScreen[i] = 0; + else + /* Four 32-bit quantities per + SERVER_OVERLAY_VISUALS entry. */ + numOverlaysPerScreen[i] = sizeData / 4; + } + layersRead = True; + } else { + if (overlayInfoPerScreen != NULL) + free(overlayInfoPerScreen); + if (numOverlaysPerScreen != NULL) + free(numOverlaysPerScreen); + } + } + } +} + +int +__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo) +{ + int i, screen = vinfo->screen; + OverlayInfo *overlayInfo; + + findServerOverlayVisualsInfo(dpy); + if (layersRead) { + for (i = 0; i < numOverlaysPerScreen[screen]; i++) { + overlayInfo = &overlayInfoPerScreen[screen][i]; + if (vinfo->visualid == overlayInfo->overlay_visual) { + if (overlayInfo->transparent_type == TransparentPixel) { + return (int) overlayInfo->value; + } else { + return -1; + } + } + } + } + return -1; +} + +XLayerVisualInfo * +__glutXGetLayerVisualInfo(Display * dpy, long lvinfo_mask, + XLayerVisualInfo * lvinfo_template, int *nitems_return) +{ + XVisualInfo *vinfo; + XLayerVisualInfo *layerInfo; + int numVisuals, count, i, j; + + vinfo = XGetVisualInfo(dpy, lvinfo_mask & VisualAllMask, + &lvinfo_template->vinfo, nitems_return); + if (vinfo == NULL) + return NULL; + numVisuals = *nitems_return; + findServerOverlayVisualsInfo(dpy); + layerInfo = (XLayerVisualInfo *) + malloc(numVisuals * sizeof(XLayerVisualInfo)); + if (layerInfo == NULL) { + XFree(vinfo); + return NULL; + } + count = 0; + for (i = 0; i < numVisuals; i++) { + XVisualInfo *pVinfo = &vinfo[i]; + int screen = pVinfo->screen; + OverlayInfo *overlayInfo = NULL; + + overlayInfo = NULL; + if (layersRead) { + for (j = 0; j < numOverlaysPerScreen[screen]; j++) + if (pVinfo->visualid == + overlayInfoPerScreen[screen][j].overlay_visual) { + overlayInfo = &overlayInfoPerScreen[screen][j]; + break; + } + } + if (lvinfo_mask & VisualLayerMask) + if (overlayInfo == NULL) { + if (lvinfo_template->layer != 0) + continue; + } else if (lvinfo_template->layer != overlayInfo->layer) + continue; + if (lvinfo_mask & VisualTransparentType) + if (overlayInfo == NULL) { + if (lvinfo_template->type != None) + continue; + } else if (lvinfo_template->type != + overlayInfo->transparent_type) + continue; + if (lvinfo_mask & VisualTransparentValue) + if (overlayInfo == NULL) + /* Non-overlay visuals have no sense of + TransparentValue. */ + continue; + else if (lvinfo_template->value != overlayInfo->value) + continue; + layerInfo[count].vinfo = *pVinfo; + if (overlayInfo == NULL) { + layerInfo[count].layer = 0; + layerInfo[count].type = None; + layerInfo[count].value = 0; /* meaningless */ + } else { + layerInfo[count].layer = overlayInfo->layer; + layerInfo[count].type = overlayInfo->transparent_type; + layerInfo[count].value = overlayInfo->value; + } + count++; + } + XFree(vinfo); + *nitems_return = count; + if (count == 0) { + XFree(layerInfo); + return NULL; + } else + return layerInfo; +} + +#if 0 /* Unused by GLUT. */ +Status +__glutXMatchLayerVisualInfo(Display * dpy, int screen, + int depth, int visualClass, int layer, + XLayerVisualInfo * lvinfo_return) +{ + XLayerVisualInfo *lvinfo; + XLayerVisualInfo lvinfoTemplate; + int nitems; + + lvinfoTemplate.vinfo.screen = screen; + lvinfoTemplate.vinfo.depth = depth; +#if defined(__cplusplus) || defined(c_plusplus) + lvinfoTemplate.vinfo.c_class = visualClass; +#else + lvinfoTemplate.vinfo.class = visualClass; +#endif + lvinfoTemplate.layer = layer; + lvinfo = __glutXGetLayerVisualInfo(dpy, + VisualScreenMask | VisualDepthMask | + VisualClassMask | VisualLayerMask, + &lvinfoTemplate, &nitems); + if (lvinfo != NULL && nitems > 0) { + *lvinfo_return = *lvinfo; + return 1; + } else + return 0; +} +#endif diff --git a/lib/glut-3.7.6/lib/glut/layerutil.h b/lib/glut-3.7.6/lib/glut/layerutil.h new file mode 100644 index 0000000000..b65ebde72c --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/layerutil.h @@ -0,0 +1,55 @@ +#ifndef __layerutil_h__ +#define __layerutil_h__ + +/* Copyright (c) Mark J. Kilgard, 1993, 1994. */ + +/* 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. */ + +/* Based on XLayerUtil.h: Revision: 1.3 */ + +#if !defined(_WIN32) +#include +#include +#include +#endif /* !_WIN32 */ + +/* Transparent type values */ +/* None 0 */ +#define TransparentPixel 1 +#define TransparentMask 2 + +/* layered visual info template flags */ +#define VisualLayerMask 0x200 +#define VisualTransparentType 0x400 +#define VisualTransparentValue 0x800 +#define VisualAllLayerMask 0xFFF + +/* layered visual info structure */ +typedef struct _XLayerVisualInfo { + XVisualInfo vinfo; + long layer; + long type; + unsigned long value; +} XLayerVisualInfo; + +/* SERVER_OVERLAY_VISUALS property element */ +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. */ + long overlay_visual; + long transparent_type; + long value; + long layer; +} OverlayInfo; + +extern int __glutGetTransparentPixel(Display *, XVisualInfo *); +extern XLayerVisualInfo *__glutXGetLayerVisualInfo(Display *, + long, XLayerVisualInfo *, int *); +extern Status __glutXMatchLayerVisualInfo(Display *, + int, int, int, int, XLayerVisualInfo *); + +#endif /* __layerutil_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/mesa.patch2 b/lib/glut-3.7.6/lib/glut/mesa.patch2 new file mode 100644 index 0000000000..d323234cca --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/mesa.patch2 @@ -0,0 +1,38 @@ +==== //sw/main/apps/OpenGL/glut/lib/glut/win32_x11.c#6 - d:\src\sw\main\apps\OpenGL\glut\lib\glut\win32_x11.c ==== +*************** +*** 6,13 **** + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +! #include +! #include "win32_x11.h" + + /* global variable that must be set for some functions to operate + correctly. */ +--- 6,12 ---- + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +! #include "glutint.h" + + /* global variable that must be set for some functions to operate + correctly. */ +==== //sw/main/apps/OpenGL/glut/lib/glut/win32_glx.c#8 - d:\src\sw\main\apps\OpenGL\glut\lib\glut\win32_glx.c ==== +*************** +*** 5,12 **** + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +! #include +! #include "win32_glx.h" + + /* global current HDC */ + extern HDC XHDC; +--- 5,11 ---- + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +! #include "glutint.h" + + /* global current HDC */ + extern HDC XHDC; diff --git a/lib/glut-3.7.6/lib/glut/stroke.h b/lib/glut-3.7.6/lib/glut/stroke.h new file mode 100644 index 0000000000..bd5e058c5e --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/stroke.h @@ -0,0 +1,134 @@ +/* $XConsortium: wfont.h,v 5.1 91/02/16 09:46:37 rws Exp $ */ + +/***************************************************************** +Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. + + 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 names of Sun Microsystems, +the X Consortium, and MIT not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT +SHALL SUN MICROSYSTEMS 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. + +******************************************************************/ + +#ifndef WFONT_INCLUDED +#define WFONT_INCLUDED + +#define WFONT_MAGIC 0x813 +#define WFONT_MAGIC_PLUS 0x715 +#define WFONT_MAGIC_PEX 0x70686e74 +#define START_PROPS 0x100 +#define START_DISPATCH(_num_props) (START_PROPS + 160 * _num_props) +#define START_PATH(_num_ch_, _num_props) (START_DISPATCH(_num_props) + sizeof(Dispatch) * _num_ch_) +#define NUM_DISPATCH 128 + +typedef struct { + unsigned short x; + unsigned short y; +} Path_point2dpx; + +typedef struct { + float x; + float y; +} Path_point2df; + +typedef struct { + int x; + int y; + int z; +} Path_point3di; + +typedef struct { + float x; + float y; + float z; +} Path_point3df; + +typedef struct { + float x; + float y; + float z; + float w; +} Path_point4df; + +typedef union { + Path_point2dpx *pt2dpx; + Path_point2df *pt2df; + Path_point3di *pt3di; + Path_point3df *pt3df; + Path_point4df *pt4df; +} Path_pt_ptr; + +typedef enum { + PATH_2DF, + PATH_2DPX, + PATH_3DF, + PATH_3DI, + PATH_4DF +} Path_type; + +typedef struct { + int n_pts; /* number of points in the subpath */ + Path_pt_ptr pts; /* pointer to them */ + int closed; /* true if the subpath is closed */ + int dcmp_flag; /* flag for pgon dcmp, pgon type + * and dcmped triangle type */ +} Path_subpath; + +typedef struct { + Path_type type; /* type of vertices in this path */ + int n_subpaths; /* number of subpaths */ + int n_vertices; /* total number of vertices */ + Path_subpath *subpaths; /* array of subpaths */ +} Path; + +typedef Path *Path_handle; + +typedef struct { + char propname[80]; /* font property name */ + char propvalue[80]; /* font property value */ +} Property; + +typedef struct { + int magic; /* magic number */ + char name[80]; /* name of this font */ + float top, /* extreme values */ + bottom, max_width; + int num_ch; /* no. of fonts in the set */ + int num_props; /* no. of font properties */ + Property *properties; /* array of properties */ +} Font_header; + +typedef struct { + float center, /* center of the character */ + right; /* right edge */ + long offset; /* offset in the file of the character + * * description */ +} Dispatch; + +typedef struct { + float center, right; + Path strokes; +} Ch_font; + +typedef struct { + char name[80]; + float top, bottom, max_width; + int num_ch; /* # characters in the font */ + Ch_font **ch_data; +} Phg_font; + +#endif /*WFONT_INCLUDED */ diff --git a/lib/glut-3.7.6/lib/glut/strokegen.y b/lib/glut-3.7.6/lib/glut/strokegen.y new file mode 100644 index 0000000000..dd44d2d3a3 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/strokegen.y @@ -0,0 +1,649 @@ +%{ +/* $XConsortium: to_wfont.y,v 5.7 94/04/17 20:10:08 rws Exp $ */ + +/***************************************************************** + +Copyright (c) 1989,1990, 1991 X Consortium + +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 THE +X CONSORTIUM 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. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + +Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. + + 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 names of Sun Microsystems, +and the X Consortium, not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT +SHALL SUN MICROSYSTEMS 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. + +******************************************************************/ + + +#define YYMAXDEPTH 10000 + +#include +#include +#include +#ifndef L_SET +#define L_SET SEEK_SET +#endif +#include "stroke.h" + +#ifdef X_NOT_STDC_ENV +FILE *fopen(); +#endif + +typedef struct { + + float std_left, /* NCGA standard left spacing */ + std_wide, /* character width */ + std_rght; /* Right spacing */ +} Standard; + + +char fname[80]; +char symname[80] = "FONT"; +Dispatch *Table; /* dispatch table */ +Standard *sp_table; /* NCGA font spacings */ +Path *strokes; /* strokes of each character */ +Property *property; /* property list */ + +struct { + int path, point, props; +} count, expect; + +Path_subpath *current_path; + +Font_header head; /* font header */ +int tableindex; /* which character */ +int yyerrno; /* error number */ + +%} + +%union { + int nil; /* void is reserved */ + int ival; + float dval; + char *cval; +} + +%start font + +%token REAL +%token INTEGER +%token STRING + +%token BOTTOM +%token CENTER +%token CLOSE +%token FONTNAME +%token PROPERTIES +%token NUM_CH +%token INDEX +%token L_SPACE +%token MAGIC +%token OPEN +%token RIGHT +%token R_SPACE +%token STROKE +%token TOP +%token VERTICES +%token BEARING +%token WIDTH + +%type fontname +%type properties +%type top bottom center right +%type nstroke nvertice n_pts index num_ch +%type closeflag +%type counter +%type sp_left wide sp_right + +%% + +font : fontheader num_ch fontprops fontbody spacing { fini(); }| + fontheader fontbody { fini(); }; + +fontheader : fontname top bottom + { wf_header($1, $2, $3); }; + +fontname : FONTNAME STRING + { $$ = $2; }; + +top : TOP REAL { $$ = $2;}; + +bottom : BOTTOM REAL { $$ = $2;}; + +num_ch: NUM_CH INTEGER { set_num_ch($2);}; + +fontprops : /* empty */ | properties; + +properties : PROPERTIES INTEGER { init_properties ($2); } property_list + { check_num_props (); } + +property_list : /* empty */ | single_property property_list + +single_property : STRING STRING { add_property($1, $2); }; + +fontbody : /* empty */ + | glyph fontbody; + +glyph : glyph_header strokes + { check_nstroke(); }; + +glyph_header : index { tableindex = $1; } sym_headinfo; + +sym_headinfo : nstroke center right nvertice + { glyph_header($1, $2, $3, $4); }; + +index : INDEX INTEGER { check_num_ch(); $$ = $2; }; + +nstroke : STROKE INTEGER { $$ = $2; expect.path = $2; }; + +nvertice: {$$ = 0;} | VERTICES INTEGER { $$ = $2; } ; + +center : CENTER REAL{ $$ = $2; }; + +right : RIGHT REAL{ $$ = $2; }; + +strokes : /* empty */ | path strokes; + +path : closeflag n_pts { init_path($1, $2); } points + { check_npts(); } + +points : /* empty */ | coord points; + +closeflag : CLOSE { $$ = $1 == CLOSE; } | OPEN { $$ = $1 == CLOSE; } ; + +n_pts : INTEGER { $$ = $1; }; + +coord : REAL REAL { add_point($1, $2); }; + +spacing : /* empty */ + | item spacing; + +item : counter {tableindex = $1;} sp_left wide sp_right + { std_space($3, $4, $5); }; + +counter : BEARING INTEGER {$$ = $2;}; + +sp_left: L_SPACE REAL {$$ = $2;}; + +wide : WIDTH REAL {$$ = $2;}; + +sp_right: R_SPACE REAL {$$ = $2;}; + +%% + +#define BYE(err) yyerrno = (err), yyerror() + +#define ERR_BASE 1000 +#define OPEN_ERROR 1001 +#define WRITE_ERROR 1002 +#define WRONG_NAME 1003 +#define NO_MEMORY 1004 +#define EXCEED_PATH 1005 +#define EXCEED_POINT 1006 +#define PATH_MISMATCH 1007 +#define POINT_MISMATCH 1008 +#define PROP_MISMATCH 1009 +#define EXCEED_PROPS 1010 + +char *prog; + +main(argc, argv) + int argc; + char *argv[]; + +{ + /* Usage : to_wfont [-o outfile] [infile] */ + char *s; + + fname[0] = 0; + tableindex = 0; + head.num_ch = -1; + + prog = *argv; + while (--argc > 0 && *++argv != NULL) { + s = *argv; + if (*s++ == '-') + switch (*s) { + case 's': + if (*++argv != NULL) + { + --argc; + (void) strcpy(symname, *argv); + } + break; + case 'o': + if (*++argv != NULL) + { + --argc; + (void) strcpy(fname, *argv); + } + break; + default: /* ignore other options */ + ; + } + else { + FILE *fp; + + /* standard input redirection */ + fp = fopen(*argv, "r"); + if (fp != NULL) { + if (close(fileno(stdin)) < 0) + { + perror(prog); + return; + } + if (dup(fileno(fp)) < 0) + { + perror(prog); + return; + } + (void) fclose(fp); + } + } + } + return (yyparse()); +} + +/* set number of characters */ +set_num_ch(num_ch) +int num_ch; +{ + yyerrno = 0; + head.num_ch = num_ch; + if (num_ch > 0) { + Table = (Dispatch *) malloc(num_ch * sizeof(Dispatch)); + sp_table = (Standard *) malloc(num_ch * sizeof(Standard)); + strokes = (Path *) malloc(num_ch * sizeof(Path)); + } + + for (tableindex = 0; tableindex < num_ch; tableindex++) { + Table[tableindex].center = 0.0; + Table[tableindex].right = 0.0; + Table[tableindex].offset = 0; + + sp_table[tableindex].std_left = 0.0; + sp_table[tableindex].std_wide = 0.0; + sp_table[tableindex].std_rght = 0.0; + + strokes[tableindex].n_subpaths = 0; + strokes[tableindex].n_vertices = 0; + strokes[tableindex].subpaths = NULL; + } +} + +/* initialize the property info in the header */ +init_properties(num_props) + int num_props; +{ + if (num_props > 0) { + head.properties = (Property *) + malloc (num_props * sizeof (Property)); + head.num_props = expect.props = num_props; + } + else { + head.properties = NULL; + head.num_props = expect.props = 0; + } + count.props = -1; + property = head.properties; /* initialize the list pointer */ +} + +check_num_props() +{ + count.props++; + if (count.props != expect.props) + BYE (PROP_MISMATCH); +} + +/* add individual property info into the buffer */ +add_property(name, value) + char *name, + *value; +{ + /* check if the property exceeds allocated space */ + + if (++count.props >= head.num_props) + BYE(EXCEED_PROPS); + + /* copy the strings into the buffer */ + + (void) strcpy (property->propname, name); + (void) strcpy (property->propvalue, value); + + /* increment the property pointer */ + + property++; +} + +check_num_ch() +{ + + if (head.num_ch == -1) + set_num_ch(128); + +} + +yyerror() +{ +#ifndef __bsdi__ + extern int yylineno; +#endif +# define ERR_SIZE (sizeof(err_string) / sizeof(char *)) + static char *err_string[] = { + "Cannot open file", + "Write fails", + "Illegal font name", + "Memory allocation failure", + "Specified number of strokes exceeded", + "Specified number of points exceeded", + "Number of strokes do not match", + "Number of points do not match", + "Number of properties do not match", + "Specified number of properties exceeded", + 0}; + char *str; + + yyerrno -= ERR_BASE; + if (yyerrno > 0 && yyerrno < ERR_SIZE) + str = err_string[yyerrno-1]; + else + str = "Syntax error"; +#ifdef __bsdi__ + fprintf(stderr, "%s.\n", str); +#else + fprintf(stderr, "line %d: %s.\n", yylineno, str); +#endif + freeall(); + (void) unlink(fname); + exit(1); +} + +/* create wfont header */ +wf_header(name, top, bottom) + char *name; + float top, + bottom; +{ + + if (name == NULL) + BYE(WRONG_NAME); + head.top = (float) top; + head.bottom = (float) bottom; + head.magic = WFONT_MAGIC_PEX; + (void) strcpy(head.name, name); + free(name); +} + +/* create header for each glyph */ +glyph_header(npath, center, right, npts) + int npath, + npts; + float center, + right; +{ + { + register Path *strk = strokes + tableindex; + + if (npath > 0) /* Don't allocate space unless the character + has strokes associated with it. */ + { + strk->subpaths = (Path_subpath *) + malloc(npath * sizeof (Path_subpath)); + + if (strk->subpaths == NULL) + BYE(NO_MEMORY); + + strk->type = PATH_2DF; + strk->n_subpaths = npath; + strk->n_vertices = npts; + } + else { /* Just initialize the entry */ + strk->subpaths = NULL; + strk->type = PATH_2DF; + strk->n_subpaths = 0; + strk->n_vertices = 0; + } + } + { + register Dispatch *tbl = Table + tableindex; + + tbl->offset = 0; + tbl->center = center; + tbl->right = right; + } + count.path = -1; /* initialize path counter, not to + * exceed n_subpath */ +} + +/* create standard spacing info for each glyph */ +std_space(l_bear, wide, r_bear) + + float l_bear, + wide, + r_bear; +{ + register Standard *tbl = sp_table +tableindex; + tbl->std_left = l_bear; + tbl->std_wide = wide; + tbl->std_rght = r_bear; +} + +/* initialize each sub_path */ +init_path(close, n) + int close, + n; +{ + register Path_subpath *path; + + if (++count.path >= strokes[tableindex].n_subpaths) + BYE(EXCEED_PATH); + path = current_path = strokes[tableindex].subpaths + count.path; + path->n_pts = n; + path->closed = close; + if (n > 0) + path->pts.pt2df = (Path_point2df *) + malloc(n * sizeof (Path_point2df)); + if (path->pts.pt2df == NULL) + BYE(NO_MEMORY); + expect.point = path->n_pts; + count.point = -1; /* initialize point counter, not to + * exceed n_pts */ +} + +/* accumulating points for each sub_path */ +add_point(x, y) + float x, + y; +{ + register Path_subpath *path; + register Path_point2df *pt_ptr; + + path = current_path; + if (++count.point >= path->n_pts) + BYE(EXCEED_POINT); + pt_ptr = path->pts.pt2df + count.point; + pt_ptr->x = x; + pt_ptr->y = y; +} + +/* Path_type + n_subpaths + n_vertices */ +#define STROKE_HEAD (sizeof (Path_type) + sizeof (int) + sizeof (int)) + +/* write out file, close everything, free everything */ +fini() +{ + static long zero = 0; + + /* pointers used to walk the arrays */ + register Path_subpath *spath; + register Dispatch *tbl_ptr; + register Path *strptr; + register Property *prop_ptr; + + FILE *fp; + int npath; + register int i, + j, + k; + Standard *sp_ptr; + Path_point2df *pt; + + printf("\n/* GENERATED FILE -- DO NOT MODIFY */\n\n"); + printf("#include \"glutstroke.h\"\n\n"); + +# define BY_BYE(err) fclose(fp), BYE(err) + + /* adjust the characters for spacing, note max char width */ + head.max_width = 0.0; + for (i = 0, tbl_ptr = Table, strptr = strokes, sp_ptr = sp_table; + i < head.num_ch; i++, tbl_ptr++, strptr++, sp_ptr++) { + tbl_ptr->center += sp_ptr->std_left; + tbl_ptr->right += sp_ptr->std_left + sp_ptr->std_rght; + if (tbl_ptr->right > head.max_width) + head.max_width = tbl_ptr->right; + npath = strptr->n_subpaths; + if (npath > 0 || tbl_ptr->center != 0.0 || + tbl_ptr->right != 0.0) { + for (j = 0, spath = strptr->subpaths; + j < npath; j++, spath++) { + for(k=0, pt = spath->pts.pt2df; + kn_pts; k++, pt++) { + pt->x += sp_ptr->std_left; + } + } + } + } + + /* write the stroke table */ + for (i = 0, tbl_ptr = Table, strptr = strokes; + i < head.num_ch; i++, tbl_ptr++, strptr++) { + if (strptr->n_subpaths > 0 && + tbl_ptr->center != 0.0 && + tbl_ptr->right != 0.0) { + if(isprint(i)) { + printf("/* char: %d '%c' */\n\n", i, i); + } else { + printf("/* char: %d */\n\n", i); + } + + for (j = 0, spath = strptr->subpaths; + j < strptr->n_subpaths; j++, spath++) { + int z; + + printf("static const CoordRec char%d_stroke%d[] = {\n", i, j); + for(z = 0; z < spath->n_pts; z++) { + printf(" { %g, %g },\n", + spath->pts.pt2df[z].x, spath->pts.pt2df[z].y); + } + printf("};\n\n"); + } + + printf("static const StrokeRec char%d[] = {\n", i); + for (j = 0, spath = strptr->subpaths; + j < strptr->n_subpaths; j++, spath++) { + printf(" { %d, char%d_stroke%d },\n", + spath->n_pts, i, j); + } + printf("};\n\n"); + } + } + printf("static const StrokeCharRec chars[] = {\n"); + for (i = 0, tbl_ptr = Table, strptr = strokes; + i < head.num_ch; i++, tbl_ptr++, strptr++) { + if (strptr->n_subpaths > 0 && + tbl_ptr->center != 0.0 && + tbl_ptr->right != 0.0) { + printf(" { %d, char%d, %g, %g },\n", + strptr->n_subpaths, i, tbl_ptr->center, tbl_ptr->right); + } else { + printf(" { 0, /* char%d */ 0, %g, %g },\n", + i, tbl_ptr->center, tbl_ptr->right); + } + } + printf("};\n\n"); + + printf("StrokeFontRec %s = { \"%s\", %d, chars, %.6g, %.6g };\n\n", + symname, head.name, head.num_ch, + (double) head.top, (double) head.bottom); + + fflush(stdout); + + freeall(); +# undef BY_BYE +} + +freeall() +{ + register Path *path; + register Path_subpath *spath; + register int i, + j, + n; + + path = strokes; + for (i = 0; i < head.num_ch; i++, path++) { + n = path->n_subpaths; + if (n <= 0) + continue; + spath = path->subpaths; + for (j = 0; j < n; j++, spath++) + if (spath->pts.pt2df != NULL) + free((char *) spath->pts.pt2df); + if (path->subpaths != NULL) + free((char *) path->subpaths); + } + free(Table); + free(sp_table); + free(strokes); + if (head.properties != NULL) + free((char *) head.properties); +} + +check_nstroke() +{ + count.path++; + if (expect.path != count.path) + BYE(PATH_MISMATCH); +} + +check_npts() +{ + count.point++; + if (expect.point != count.point) + BYE(POINT_MISMATCH); +} diff --git a/lib/glut-3.7.6/lib/glut/strokelex.l b/lib/glut-3.7.6/lib/glut/strokelex.l new file mode 100644 index 0000000000..82b5989562 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/strokelex.l @@ -0,0 +1,131 @@ +%{ +/* $XConsortium: lex.l,v 5.4 91/08/26 10:55:26 gildea Exp $ */ + +/***************************************************************** +Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. + + 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 names of Sun Microsystems, +the X Consortium, and MIT not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT +SHALL SUN MICROSYSTEMS 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. + +******************************************************************/ + + +#include +#include +#include +#include "strokegen.h" + +#if defined(ISC) && defined(SYSV) && defined(SYSV386) && __STDC__ +extern double atof(char *); +#endif + +#ifdef FLEX_SCANNER +int yylineno; +#endif + +%} +%% +\'[^']*\' | +\"[^"]*\" return string(yytext, yyleng); +#.* ; +[ ,;\t\n]* /* natural dilimters */ ; + +[a-zA-Z][a-zA-Z0-9_.]* { + int token; + if (token = res_words(yytext)) + return token; + return string(yytext, yyleng); + } + +[+-]?[0-9]+\.?[0-9]*[eE][+-]?[0-9]+ | +[+-]?[0-9]+\.[0-9]* | +\.[0-9]+ { + yylval.dval = atof(yytext); + return REAL; + } +[+-]?[0-9]+#[0-9]+ { + return INTEGER; + } +[+-]?[0-9]+ { + yylval.ival = atoi(yytext); + return INTEGER; + } +[()] ; +%% + +int +res_words(str) +char str[]; +{ + static struct res_strct { + char *word; + int token; + } res_table[] = { + {"BOTTOM", BOTTOM}, + {"CENTER", CENTER}, + {"PROPERTIES", PROPERTIES}, + {"CLOSE", CLOSE}, + {"FONTNAME", FONTNAME}, + {"INDEX", INDEX}, + {"MAGIC", MAGIC}, + {"OPEN", OPEN}, + {"RIGHT", RIGHT}, + {"STROKE", STROKE}, + {"TOP", TOP}, + {"VERTICES", VERTICES}, + {"BEARING", BEARING}, + {"L_SPACE", L_SPACE}, + {"WIDTH", WIDTH}, + {"R_SPACE", R_SPACE}, + {"NUM_CH", NUM_CH}, + {0, 0} + }; + + { + register struct res_strct *reserved; + + reserved = res_table; + + do + if (!strcmp(str, reserved->word)) + break; + while ((++reserved)->word != 0); + return reserved->token; + } +} + +int +string(str, n) +char *str; +int n; +{ + if (*str == '\"' || *str == '\'') + { + str++; + n -= 2; /* one for EOL, one for end quote */ + } + if ((yylval.cval = (char *)malloc(n+1)) != NULL) + { + strncpy(yylval.cval, str, n); + yylval.cval[n] = '\0'; + return STRING; + } + else + return 0; +} diff --git a/lib/glut-3.7.6/lib/glut/win32_glx.c b/lib/glut-3.7.6/lib/glut/win32_glx.c new file mode 100644 index 0000000000..47b84f5bae --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_glx.c @@ -0,0 +1,254 @@ + +/* Copyright (c) Nate Robins, 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. */ + +#include "glutint.h" + +/* global current HDC */ +extern HDC XHDC; + +GLXContext +glXCreateContext(Display * display, XVisualInfo * visinfo, + GLXContext share, Bool direct) +{ + /* KLUDGE: GLX really expects a display pointer to be passed + in as the first parameter, but Win32 needs an HDC instead, + so BE SURE that the global XHDC is set before calling this + routine. */ + HGLRC context; + + context = wglCreateContext(XHDC); + +#if 0 + /* XXX GLUT doesn't support it now, so don't worry about display list + and texture object sharing. */ + if (share) { + wglShareLists(share, context); + } +#endif + + /* Since direct rendering is implicit, the direct flag is + ignored. */ + + return context; +} + +int +glXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value) +{ + if (!visual) + return GLX_BAD_VISUAL; + + switch (attrib) { + case GLX_USE_GL: + if ((visual->dwFlags & PFD_SUPPORT_OPENGL ) && (visual->dwFlags & PFD_DRAW_TO_WINDOW)) { + /* XXX Brad's Matrix Millenium II has problems creating + color index windows in 24-bit mode (lead to GDI crash) + and 32-bit mode (lead to black window). The cColorBits + filed of the PIXELFORMATDESCRIPTOR returned claims to + have 24 and 32 bits respectively of color indices. 2^24 + and 2^32 are ridiculously huge writable colormaps. + Assume that if we get back a color index + PIXELFORMATDESCRIPTOR with 24 or more bits, the + PIXELFORMATDESCRIPTOR doesn't really work and skip it. + -mjk */ + if (visual->iPixelType == PFD_TYPE_COLORINDEX + && visual->cColorBits >= 24) { + *value = 0; + } else { + *value = 1; + } + } else { + *value = 0; + } + break; + case GLX_BUFFER_SIZE: + /* KLUDGE: if we're RGBA, return the number of bits/pixel, + otherwise, return 8 (we guessed at 256 colors in CI + mode). */ + if (visual->iPixelType == PFD_TYPE_RGBA) + *value = visual->cColorBits; + else + *value = 8; + break; + case GLX_LEVEL: + /* The bReserved flag of the pfd contains the + overlay/underlay info. */ + *value = visual->bReserved; + break; + case GLX_RGBA: + *value = visual->iPixelType == PFD_TYPE_RGBA; + break; + case GLX_DOUBLEBUFFER: + *value = visual->dwFlags & PFD_DOUBLEBUFFER; + break; + case GLX_STEREO: + *value = visual->dwFlags & PFD_STEREO; + break; + case GLX_AUX_BUFFERS: + *value = visual->cAuxBuffers; + break; + case GLX_RED_SIZE: + *value = visual->cRedBits; + break; + case GLX_GREEN_SIZE: + *value = visual->cGreenBits; + break; + case GLX_BLUE_SIZE: + *value = visual->cBlueBits; + break; + case GLX_ALPHA_SIZE: + *value = visual->cAlphaBits; + break; + case GLX_DEPTH_SIZE: + *value = visual->cDepthBits; + break; + case GLX_STENCIL_SIZE: + *value = visual->cStencilBits; + break; + case GLX_ACCUM_RED_SIZE: + *value = visual->cAccumRedBits; + break; + case GLX_ACCUM_GREEN_SIZE: + *value = visual->cAccumGreenBits; + break; + case GLX_ACCUM_BLUE_SIZE: + *value = visual->cAccumBlueBits; + break; + case GLX_ACCUM_ALPHA_SIZE: + *value = visual->cAccumAlphaBits; + break; + default: + return GLX_BAD_ATTRIB; + } + return 0; +} + +XVisualInfo * +glXChooseVisual(Display * display, int screen, int *attribList) +{ + /* KLUDGE: since we need the HDC, MAKE SURE to set XHDC + before calling this routine. */ + + int *p = attribList; + int pf; + PIXELFORMATDESCRIPTOR pfd; + PIXELFORMATDESCRIPTOR *match = NULL; + int stereo = 0; + + /* Avoid seg-faults. */ + if (!p) + return NULL; + + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nVersion = 1; + + /* Defaults. */ + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pfd.iPixelType = PFD_TYPE_COLORINDEX; + pfd.cColorBits = 32; + pfd.cDepthBits = 0; + + while (*p) { + switch (*p) { + case GLX_USE_GL: + pfd.dwFlags |= PFD_SUPPORT_OPENGL; + break; + case GLX_BUFFER_SIZE: + pfd.cColorBits = *(++p); + break; + case GLX_LEVEL: + /* the bReserved flag of the pfd contains the + overlay/underlay info. */ + pfd.bReserved = *(++p); + break; + case GLX_RGBA: + pfd.iPixelType = PFD_TYPE_RGBA; + break; + case GLX_DOUBLEBUFFER: + pfd.dwFlags |= PFD_DOUBLEBUFFER; + break; + case GLX_STEREO: + stereo = 1; + pfd.dwFlags |= PFD_STEREO; + break; + case GLX_AUX_BUFFERS: + pfd.cAuxBuffers = *(++p); + break; + case GLX_RED_SIZE: + pfd.cRedBits = 8; /* Try to get the maximum. */ + ++p; + break; + case GLX_GREEN_SIZE: + pfd.cGreenBits = 8; + ++p; + break; + case GLX_BLUE_SIZE: + pfd.cBlueBits = 8; + ++p; + break; + case GLX_ALPHA_SIZE: + pfd.cAlphaBits = 8; + ++p; + break; + case GLX_DEPTH_SIZE: + pfd.cDepthBits = 32; + ++p; + break; + case GLX_STENCIL_SIZE: + pfd.cStencilBits = *(++p); + break; + case GLX_ACCUM_RED_SIZE: + case GLX_ACCUM_GREEN_SIZE: + case GLX_ACCUM_BLUE_SIZE: + case GLX_ACCUM_ALPHA_SIZE: + /* I believe that WGL only used the cAccumRedBits, + cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields + when returning info about the accumulation buffer precision. + Only cAccumBits is used for requesting an accumulation + buffer. */ + pfd.cAccumBits = 1; + ++p; + break; + } + ++p; + } + + /* Let Win32 choose one for us. */ + pf = ChoosePixelFormat(XHDC, &pfd); + if (pf > 0) { + match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR)); + DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match); + + /* ChoosePixelFormat is dumb in that it will return a pixel + format that doesn't have stereo even if it was requested + so we need to make sure that if stereo was selected, we + got it. */ + if (stereo) { + if (!(match->dwFlags & PFD_STEREO)) { + free(match); + return NULL; + } + } + /* XXX Brad's Matrix Millenium II has problems creating + color index windows in 24-bit mode (lead to GDI crash) + and 32-bit mode (lead to black window). The cColorBits + filed of the PIXELFORMATDESCRIPTOR returned claims to + have 24 and 32 bits respectively of color indices. 2^24 + and 2^32 are ridiculously huge writable colormaps. + Assume that if we get back a color index + PIXELFORMATDESCRIPTOR with 24 or more bits, the + PIXELFORMATDESCRIPTOR doesn't really work and skip it. + -mjk */ + if (match->iPixelType == PFD_TYPE_COLORINDEX + && match->cColorBits >= 24) { + free(match); + return NULL; + } + } + return match; +} diff --git a/lib/glut-3.7.6/lib/glut/win32_glx.h b/lib/glut-3.7.6/lib/glut/win32_glx.h new file mode 100644 index 0000000000..fd3c503550 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_glx.h @@ -0,0 +1,58 @@ +#ifndef __win32_glx_h__ +#define __win32_glx_h__ + +/* Copyright (c) Nate Robins, 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. */ + +#include "win32_x11.h" + +/* Type definitions (conversions). */ +typedef HGLRC GLXContext; + +#define GLX_USE_GL 1 /* support GLX rendering */ +#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ +#define GLX_LEVEL 3 /* level in plane stacking */ +#define GLX_RGBA 4 /* true if RGBA mode */ +#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ +#define GLX_STEREO 6 /* stereo buffering supported */ +#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ +#define GLX_RED_SIZE 8 /* number of red component bits */ +#define GLX_GREEN_SIZE 9 /* number of green component bits */ +#define GLX_BLUE_SIZE 10 /* number of blue component bits */ +#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ +#define GLX_DEPTH_SIZE 12 /* number of depth bits */ +#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ +#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ +#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ +#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ +#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ + +#define GLX_BAD_ATTRIB 2 +#define GLX_BAD_VISUAL 4 + +/* Functions emulated by macros. */ + +#define glXDestroyContext(display, context) \ + wglDeleteContext(context) + +/* Function prototypes. */ + +extern GLXContext glXCreateContext( + Display* display, + XVisualInfo* visinfo, + GLXContext share, + Bool direct); +extern int glXGetConfig( + Display* display, + XVisualInfo* visual, + int attrib, + int* value); +extern XVisualInfo* glXChooseVisual( + Display* display, + int screen, + int* attribList); + +#endif /* __win32_glx_h__ */ diff --git a/lib/glut-3.7.6/lib/glut/win32_menu.c b/lib/glut-3.7.6/lib/glut/win32_menu.c new file mode 100644 index 0000000000..f7c7c82158 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_menu.c @@ -0,0 +1,531 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */ +/* Copyright (c) Nate Robins, 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 file completely re-implements glut_menu.c and glut_menu2.c + for Win32. Note that neither glut_menu.c nor glut_menu2.c are + compiled into Win32 GLUT. */ + +#include +#include +#include +#include +#include + +#include "glutint.h" + +void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int); +GLUTmenu *__glutMappedMenu; +GLUTwindow *__glutMenuWindow; +GLUTmenuItem *__glutItemSelected; +unsigned __glutMenuButton; + +static GLUTmenu **menuList = NULL; +static int menuListSize = 0; +static UINT uniqueMenuHandler = 1; + +/* DEPRICATED, use glutMenuStatusFunc instead. */ +void APIENTRY +glutMenuStateFunc(GLUTmenuStateCB menuStateFunc) +{ + __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc; +} + +void APIENTRY +glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc) +{ + __glutMenuStatusFunc = menuStatusFunc; +} + +void +__glutSetMenu(GLUTmenu * menu) +{ + __glutCurrentMenu = menu; +} + +static void +unmapMenu(GLUTmenu * menu) +{ + if (menu->cascade) { + unmapMenu(menu->cascade); + menu->cascade = NULL; + } + menu->anchor = NULL; + menu->highlighted = NULL; +} + +void +__glutFinishMenu(Window win, int x, int y) +{ + + unmapMenu(__glutMappedMenu); + + /* XXX Put in a GdiFlush just in case. Probably unnecessary. -mjk */ + GdiFlush(); + + if (__glutMenuStatusFunc) { + __glutSetWindow(__glutMenuWindow); + __glutSetMenu(__glutMappedMenu); + + /* Setting __glutMappedMenu to NULL permits operations that + change menus or destroy the menu window again. */ + __glutMappedMenu = NULL; + + __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y); + } + /* Setting __glutMappedMenu to NULL permits operations that + change menus or destroy the menu window again. */ + __glutMappedMenu = NULL; + + /* If an item is selected and it is not a submenu trigger, + generate menu callback. */ + if (__glutItemSelected && !__glutItemSelected->isTrigger) { + __glutSetWindow(__glutMenuWindow); + /* When menu callback is triggered, current menu should be + set to the callback menu. */ + __glutSetMenu(__glutItemSelected->menu); + __glutItemSelected->menu->select(__glutItemSelected->value); + } + __glutMenuWindow = NULL; +} + +static void +mapMenu(GLUTmenu * menu, int x, int y) +{ + TrackPopupMenu(menu->win, TPM_LEFTALIGN | + (__glutMenuButton == TPM_RIGHTBUTTON) ? + TPM_RIGHTBUTTON : TPM_LEFTBUTTON, + x, y, 0, __glutCurrentWindow->win, NULL); +} + +void +__glutStartMenu(GLUTmenu * menu, GLUTwindow * window, + int x, int y, int x_win, int y_win) +{ + assert(__glutMappedMenu == NULL); + __glutMappedMenu = menu; + __glutMenuWindow = window; + __glutItemSelected = NULL; + if (__glutMenuStatusFunc) { + __glutSetMenu(menu); + __glutSetWindow(window); + __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win); + } + mapMenu(menu, x, y); +} + +GLUTmenuItem * +__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique) +{ + GLUTmenuItem *item; + int i; + + i = menu->num; + item = menu->list; + while (item) { + if (item->unique == unique) { + return item; + } + if (item->isTrigger) { + GLUTmenuItem *subitem; + subitem = __glutGetUniqueMenuItem(menuList[item->value], unique); + if (subitem) { + return subitem; + } + } + i--; + item = item->next; + } + return NULL; +} + +GLUTmenuItem * +__glutGetMenuItem(GLUTmenu * menu, HMENU win, int *which) +{ + GLUTmenuItem *item; + int i; + + i = menu->num; + item = menu->list; + while (item) { + if (item->win == win) { + *which = i; + return item; + } + if (item->isTrigger) { + GLUTmenuItem *subitem; + + subitem = __glutGetMenuItem(menuList[item->value], + win, which); + if (subitem) { + return subitem; + } + } + i--; + item = item->next; + } + return NULL; +} + +GLUTmenu * +__glutGetMenu(HMENU win) +{ + GLUTmenu *menu; + + menu = __glutMappedMenu; + while (menu) { + if (win == menu->win) { + return menu; + } + menu = menu->cascade; + } + return NULL; +} + +GLUTmenu * +__glutGetMenuByNum(int menunum) +{ + if (menunum < 1 || menunum > menuListSize) { + return NULL; + } + return menuList[menunum - 1]; +} + +static int +getUnusedMenuSlot(void) +{ + int i; + + /* Look for allocated, unused slot. */ + for (i = 0; i < menuListSize; i++) { + if (!menuList[i]) { + return i; + } + } + /* Allocate a new slot. */ + menuListSize++; + if (menuList) { + menuList = (GLUTmenu **) + realloc(menuList, menuListSize * sizeof(GLUTmenu *)); + } else { + /* XXX Some realloc's do not correctly perform a malloc + when asked to perform a realloc on a NULL pointer, + though the ANSI C library spec requires this. */ + menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *)); + } + if (!menuList) { + __glutFatalError("out of memory."); + } + menuList[menuListSize - 1] = NULL; + return menuListSize - 1; +} + +static void +menuModificationError(void) +{ + /* XXX Remove the warning after GLUT 3.0. */ + __glutWarning("The following is a new check for GLUT 3.0; update your code."); + __glutFatalError("menu manipulation not allowed while menus in use."); +} + +int APIENTRY +glutCreateMenu(GLUTselectCB selectFunc) +{ + GLUTmenu *menu; + int menuid; + + if (__glutMappedMenu) { + menuModificationError(); + } + menuid = getUnusedMenuSlot(); + menu = (GLUTmenu *) malloc(sizeof(GLUTmenu)); + if (!menu) { + __glutFatalError("out of memory."); + } + menu->id = menuid; + menu->num = 0; + menu->submenus = 0; + menu->select = selectFunc; + menu->list = NULL; + menu->cascade = NULL; + menu->highlighted = NULL; + menu->anchor = NULL; + menu->win = CreatePopupMenu(); + menuList[menuid] = menu; + __glutSetMenu(menu); + return menuid + 1; +} + +int APIENTRY +__glutCreateMenuWithExit(GLUTselectCB selectFunc, void (__cdecl *exitfunc)(int)) +{ + __glutExitFunc = exitfunc; + return glutCreateMenu(selectFunc); +} + +void APIENTRY +glutDestroyMenu(int menunum) +{ + GLUTmenu *menu = __glutGetMenuByNum(menunum); + GLUTmenuItem *item, *next; + + if (__glutMappedMenu) { + menuModificationError(); + } + assert(menu->id == menunum - 1); + DestroyMenu(menu->win); + menuList[menunum - 1] = NULL; + /* free all menu entries */ + item = menu->list; + while (item) { + assert(item->menu == menu); + next = item->next; + free(item->label); + free(item); + item = next; + } + if (__glutCurrentMenu == menu) { + __glutCurrentMenu = NULL; + } + free(menu); +} + +int APIENTRY +glutGetMenu(void) +{ + if (__glutCurrentMenu) { + return __glutCurrentMenu->id + 1; + } else { + return 0; + } +} + +void APIENTRY +glutSetMenu(int menuid) +{ + GLUTmenu *menu; + + if (menuid < 1 || menuid > menuListSize) { + __glutWarning("glutSetMenu attempted on bogus menu."); + return; + } + menu = menuList[menuid - 1]; + if (!menu) { + __glutWarning("glutSetMenu attempted on bogus menu."); + return; + } + __glutSetMenu(menu); +} + +static void +setMenuItem(GLUTmenuItem * item, const char *label, + int value, Bool isTrigger) +{ + GLUTmenu *menu; + + menu = item->menu; + item->label = __glutStrdup(label); + if (!item->label) { + __glutFatalError("out of memory."); + } + item->isTrigger = isTrigger; + item->len = (int) strlen(label); + item->value = value; + item->unique = uniqueMenuHandler++; + if (isTrigger) { + AppendMenu(menu->win, MF_POPUP, (UINT)item->win, label); + } else { + AppendMenu(menu->win, MF_STRING, item->unique, label); + } +} + +void APIENTRY +glutAddMenuEntry(const char *label, int value) +{ + GLUTmenuItem *entry; + + if (__glutMappedMenu) { + menuModificationError(); + } + entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem)); + if (!entry) { + __glutFatalError("out of memory."); + } + entry->menu = __glutCurrentMenu; + setMenuItem(entry, label, value, FALSE); + __glutCurrentMenu->num++; + entry->next = __glutCurrentMenu->list; + __glutCurrentMenu->list = entry; +} + +void APIENTRY +glutAddSubMenu(const char *label, int menu) +{ + GLUTmenuItem *submenu; + GLUTmenu *popupmenu; + + if (__glutMappedMenu) { + menuModificationError(); + } + submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem)); + if (!submenu) { + __glutFatalError("out of memory."); + } + __glutCurrentMenu->submenus++; + submenu->menu = __glutCurrentMenu; + popupmenu = __glutGetMenuByNum(menu); + if (popupmenu) { + submenu->win = popupmenu->win; + } + setMenuItem(submenu, label, /* base 0 */ menu - 1, TRUE); + __glutCurrentMenu->num++; + submenu->next = __glutCurrentMenu->list; + __glutCurrentMenu->list = submenu; +} + +void APIENTRY +glutChangeToMenuEntry(int num, const char *label, int value) +{ + GLUTmenuItem *item; + int i; + + if (__glutMappedMenu) { + menuModificationError(); + } + i = __glutCurrentMenu->num; + item = __glutCurrentMenu->list; + while (item) { + if (i == num) { + if (item->isTrigger) { + /* If changing a submenu trigger to a menu entry, we + need to account for submenus. */ + item->menu->submenus--; + } + + free(item->label); + item->label = strdup(label); + if (!item->label) __glutFatalError("out of memory"); + item->isTrigger = FALSE; + item->len = (int) strlen(label); + item->value = value; + item->unique = uniqueMenuHandler++; + + RemoveMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION); + InsertMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION | MFT_STRING, item->unique, label); + + return; + } + i--; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutChangeToSubMenu(int num, const char *label, int menu) +{ + GLUTmenu *popupmenu; + GLUTmenuItem *item; + int i; + + if (__glutMappedMenu) { + menuModificationError(); + } + i = __glutCurrentMenu->num; + item = __glutCurrentMenu->list; + while (item) { + if (i == num) { + if (!item->isTrigger) { + /* If changing a menu entry to as submenu trigger, we + need to account for submenus. */ + item->menu->submenus++; + } + free(item->label); + + item->label = strdup(label); + if (!item->label) + __glutFatalError("out of memory"); + item->isTrigger = TRUE; + item->len = (int) strlen(label); + item->value = menu - 1; + item->unique = uniqueMenuHandler++; + popupmenu = __glutGetMenuByNum(menu); + if (popupmenu) + item->win = popupmenu->win; + + RemoveMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION); + InsertMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION | MFT_STRING | MF_POPUP, (UINT)item->win, label); + + return; + } + i--; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutRemoveMenuItem(int num) +{ + GLUTmenuItem *item, **prev; + int i; + + if (__glutMappedMenu) { + menuModificationError(); + } + i = __glutCurrentMenu->num; + prev = &__glutCurrentMenu->list; + item = __glutCurrentMenu->list; + while (item) { + if (i == num) { + /* Found the menu item in list to remove. */ + __glutCurrentMenu->num--; + + /* Patch up menu's item list. */ + *prev = item->next; + + RemoveMenu(__glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION); + + free(item->label); + free(item); + return; + } + i--; + prev = &item->next; + item = item->next; + } + __glutWarning("Current menu has no %d item.", num); +} + +void APIENTRY +glutAttachMenu(int button) +{ + if (__glutCurrentWindow == __glutGameModeWindow) { + __glutWarning("cannot attach menus in game mode."); + return; + } + if (__glutMappedMenu) { + menuModificationError(); + } + if (__glutCurrentWindow->menu[button] < 1) { + __glutCurrentWindow->buttonUses++; + } + __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1; +} + +void APIENTRY +glutDetachMenu(int button) +{ + if (__glutMappedMenu) { + menuModificationError(); + } + if (__glutCurrentWindow->menu[button] > 0) { + __glutCurrentWindow->buttonUses--; + __glutCurrentWindow->menu[button] = 0; + } +} + diff --git a/lib/glut-3.7.6/lib/glut/win32_util.c b/lib/glut-3.7.6/lib/glut/win32_util.c new file mode 100644 index 0000000000..253e795814 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_util.c @@ -0,0 +1,134 @@ + +/* Copyright (c) Nate Robins, 1997. */ + +/* portions Copyright (c) Mark Kilgard, 1997, 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 "glutint.h" +#include "glutstroke.h" +#include "glutbitmap.h" +#if defined(__CYGWIN32__) +typedef MINMAXINFO* LPMINMAXINFO; +#else +#include +#endif + +/* The following added by Paul Garceau */ +#if defined(__MINGW32__) +#include +#include +struct timeval; +#endif + +extern StrokeFontRec glutStrokeRoman, glutStrokeMonoRoman; +extern BitmapFontRec glutBitmap8By13, glutBitmap9By15, glutBitmapTimesRoman10, glutBitmapTimesRoman24, glutBitmapHelvetica10, glutBitmapHelvetica12, glutBitmapHelvetica18; + +int +gettimeofday(struct timeval* tp, void* tzp) +{ + LARGE_INTEGER t; + + if(QueryPerformanceCounter(&t)) { + /* hardware supports a performance counter */ + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + tp->tv_sec = t.QuadPart/f.QuadPart; + tp->tv_usec = ((float)t.QuadPart/f.QuadPart*1000*1000) - (tp->tv_sec*1000*1000); + } else { + /* hardware doesn't support a performance counter, + so get the time in a more traditional way. */ + DWORD t; + t = timeGetTime(); + tp->tv_sec = t / 1000; + tp->tv_usec = t % 1000; + } + + /* 0 indicates that the call succeeded. */ + return 0; +} + +/* To get around the fact that Microsoft DLLs only allow functions + to be exported and now data addresses (as Unix DSOs support), the + GLUT API constants such as GLUT_STROKE_ROMAN have to get passed + through a case statement to get mapped to the actual data structure + address. */ +void* +__glutFont(void *font) +{ + switch((int)font) { + case (int)GLUT_STROKE_ROMAN: + return &glutStrokeRoman; + case (int)GLUT_STROKE_MONO_ROMAN: + return &glutStrokeMonoRoman; + case (int)GLUT_BITMAP_9_BY_15: + return &glutBitmap9By15; + case (int)GLUT_BITMAP_8_BY_13: + return &glutBitmap8By13; + case (int)GLUT_BITMAP_TIMES_ROMAN_10: + return &glutBitmapTimesRoman10; + case (int)GLUT_BITMAP_TIMES_ROMAN_24: + return &glutBitmapTimesRoman24; + case (int)GLUT_BITMAP_HELVETICA_10: + return &glutBitmapHelvetica10; + case (int)GLUT_BITMAP_HELVETICA_12: + return &glutBitmapHelvetica12; + case (int)GLUT_BITMAP_HELVETICA_18: + return &glutBitmapHelvetica18; + } + __glutFatalError("out of memory."); + /* NOTREACHED */ + + return NULL; /* keep MSVC compiler happy */ +} + +int +__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo) +{ + /* the transparent pixel on Win32 is always index number 0. So if + we put this routine in this file, we can avoid compiling the + whole of layerutil.c which is where this routine normally comes + from. */ + return 0; +} + +void +__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height) +{ + RECT rect; + + /* adjust the window rectangle because Win32 thinks that the x, y, + width & height are the WHOLE window (including decorations), + whereas GLUT treats the x, y, width & height as only the CLIENT + area of the window. */ + rect.left = *x; rect.top = *y; + rect.right = *x + *width; rect.bottom = *y + *height; + + /* must adjust the coordinates according to the correct style + because depending on the style, there may or may not be + borders. */ + AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | + (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW), + FALSE); + /* FALSE in the third parameter = window has no menu bar */ + + /* readjust if the x and y are offscreen */ + if(rect.left < 0) { + *x = 0; + } else { + *x = rect.left; + } + + if(rect.top < 0) { + *y = 0; + } else { + *y = rect.top; + } + + *width = rect.right - rect.left; /* adjusted width */ + *height = rect.bottom - rect.top; /* adjusted height */ +} + diff --git a/lib/glut-3.7.6/lib/glut/win32_winproc.c b/lib/glut-3.7.6/lib/glut/win32_winproc.c new file mode 100644 index 0000000000..a03e318042 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_winproc.c @@ -0,0 +1,763 @@ + +/* Copyright (c) Nate Robins, 1997, 2001. */ +/* portions Copyright (c) Mark Kilgard, 1997, 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 "glutint.h" +#if defined(__CYGWIN32__) +typedef MINMAXINFO* LPMINMAXINFO; +#else +#include +#endif + +#ifdef _WIN32 +#include +#include +#include +#include /* Win32 Multimedia API header. */ +#endif + +extern unsigned __glutMenuButton; +extern GLUTidleCB __glutIdleFunc; +extern GLUTtimer *__glutTimerList; +extern void handleTimeouts(void); +extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique); +static HMENU __glutHMenu; + +static int __glutOnCreate( HWND hwnd, LPCREATESTRUCT createStruct ) +{ + return TRUE; +} + +static void __glutOnClose( HWND hwnd ) +{ + if ( __glutExitFunc ) + { + __glutExitFunc( 0 ); + } + + DestroyWindow( hwnd ); +} + +static void __glutOnDestroy( HWND hwnd ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + if ( window->ctx ) + { + wglMakeCurrent( NULL, NULL ); + wglDeleteContext( window->ctx ); + } + } +} + +static void __glutOnPaint( HWND hwnd ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + + PAINTSTRUCT ps; + BeginPaint( hwnd, &ps ); + EndPaint( hwnd, &ps ); + + if ( window ) + { + if ( window->win == hwnd ) + { + __glutPostRedisplay(window, GLUT_REPAIR_WORK); + } + } +} + +static void __glutOnSize( HWND hwnd, UINT state, int width, int height ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + if ( window->width != width || window->height != height ) + { + window->width = width; + window->height = height; + + __glutSetWindow( window ); + + /* Do not execute OpenGL out of sequence with respect to the + SetWindowPos request! */ + GdiFlush(); + + window->reshape( width, height ); + window->forceReshape = FALSE; + + /* A reshape should be considered like posting a repair request. */ + __glutPostRedisplay( window, GLUT_REPAIR_WORK ); + } + } +} + +static void updateWindowState( GLUTwindow *window, int visState ) +{ + GLUTwindow* child; + + /* XXX shownState and visState are the same in Win32. */ + window->shownState = visState; + if ( visState != window->visState ) + { + if ( window->windowStatus ) + { + window->visState = visState; + __glutSetWindow( window ); + window->windowStatus( visState ); + } + } + /* Since Win32 only sends an activate for the toplevel window, + update the visibility for all the child windows. */ + child = window->children; + while ( child ) + { + updateWindowState( child, visState ); + child = child->siblings; + } +} + +static void __glutOnActivate( HWND hwnd, UINT state, HWND hWndPrev, BOOL minimized ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + int visState = ! minimized; + updateWindowState( window, visState ); + } + + /* Just in case there is a palette, make sure we re-select it if the + window is being activated. */ + if ( state != WA_INACTIVE ) + { + PostMessage( hwnd, WM_PALETTECHANGED, 0, 0 ); + } +} + +static void __glutOnSetFocus( HWND hwnd, HWND hwndOldFocus ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + window->entryState = WM_SETFOCUS; + if ( window->entry ) + { + __glutSetWindow( window ); + window->entry( GLUT_ENTERED ); + /* XXX Generation of fake passive notify? See how much + work the X11 code does to support fake passive notify + callbacks. */ + } + + if ( window->joystick && __glutCurrentWindow ) + { + if ( __glutCurrentWindow->joyPollInterval > 0 ) + { + /* Because Win32 will only let one window capture the + joystick at a time, we must capture it when we get the + focus and release it when we lose the focus. */ + MMRESULT result = joySetCapture( __glutCurrentWindow->win, JOYSTICKID1, 0, TRUE ); + if ( result == JOYERR_NOERROR ) + { + joySetThreshold( JOYSTICKID1, __glutCurrentWindow->joyPollInterval ); + } + } + } + } +} + +static void __glutOnKillFocus( HWND hwnd, HWND hwndNewFocus ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + window->entryState = WM_KILLFOCUS; + if ( window->entry ) + { + __glutSetWindow( window ); + window->entry( GLUT_LEFT ); + } + + if ( window->joystick && __glutCurrentWindow ) + { + if ( __glutCurrentWindow->joyPollInterval > 0 ) + { + joyReleaseCapture( JOYSTICKID1 ); + } + } + } +} + +static void __glutOnGetMinMaxInfo( HWND hwnd, LPMINMAXINFO mmi ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + RECT r; + + /* set it to as small as possible, although it doesn't seem to allow + the decorations to be munged. */ + r.top = 0; + r.left = 0; + r.bottom = 1; + r.right = 1; + + /* get window coordinates from the client coordinates. */ + AdjustWindowRect( &r, GetWindowLong( hwnd, GWL_STYLE ), FALSE ); + mmi->ptMinTrackSize.x = r.right - r.left; + mmi->ptMinTrackSize.y = r.bottom - r.top; + mmi->ptMaxTrackSize.x = __glutScreenWidth; + mmi->ptMaxTrackSize.y = __glutScreenHeight; + } +} + +static GLUTwindow* getWindowUnderCursor( HWND hwndParent, GLUTwindow* windowParent ) +{ + /* It seems that some messages are sent to the parent window only. Since + GLUT wants to send information to the "current" window, descend the + heirarchy until the window with the cursor in it is found. */ + + assert( windowParent ); + + if ( windowParent->children ) + { + HWND hwndChild; + + POINT p; + GetCursorPos( &p ); + ScreenToClient( hwndParent, &p ); + + hwndChild = ChildWindowFromPoint( hwndParent, p ); + if ( hwndChild && hwndChild != hwndParent ) + { + GLUTwindow* windowChild = __glutGetWindow( hwndChild ); + if ( windowChild ) + { + windowParent = getWindowUnderCursor( hwndChild, windowChild ); + } + } + } + + return windowParent; +} + +static unsigned int getModifierMask( void ) +{ + unsigned int mask = 0; + + if ( ( GetKeyState( VK_SHIFT ) & 0xFF00 ) ) + { + mask |= ShiftMask; + } + if ( ( GetKeyState( VK_CONTROL ) & 0xFF00 ) ) + { + mask |= ControlMask; + } + if ( ( GetKeyState( VK_MENU ) & 0xFF00 ) ) + { + mask |= Mod1Mask; + } + + return mask; +} + +static int vkToSpecial( UINT vk ) +{ + switch ( vk ) + { + case VK_F1: return -GLUT_KEY_F1; + case VK_F2: return -GLUT_KEY_F2; + case VK_F3: return -GLUT_KEY_F3; + case VK_F4: return -GLUT_KEY_F4; + case VK_F5: return -GLUT_KEY_F5; + case VK_F6: return -GLUT_KEY_F6; + case VK_F7: return -GLUT_KEY_F7; + case VK_F8: return -GLUT_KEY_F8; + case VK_F9: return -GLUT_KEY_F9; + case VK_F10: return -GLUT_KEY_F10; + case VK_F11: return -GLUT_KEY_F11; + case VK_F12: return -GLUT_KEY_F12; + case VK_LEFT: return -GLUT_KEY_LEFT; + case VK_UP: return -GLUT_KEY_UP; + case VK_RIGHT: return -GLUT_KEY_RIGHT; + case VK_DOWN: return -GLUT_KEY_DOWN; + case VK_PRIOR: return -GLUT_KEY_PAGE_UP; + case VK_NEXT: return -GLUT_KEY_PAGE_DOWN; + case VK_HOME: return -GLUT_KEY_HOME; + case VK_END: return -GLUT_KEY_END; + case VK_INSERT: return -GLUT_KEY_INSERT; + default: return 0; + } +} + +static int getKey( UINT vk ) +{ + BYTE keyState[ 256 ]; + WORD c[ 2 ]; + + GetKeyboardState( keyState ); + + if ( ToAscii( vk, 0, keyState, c, 0 ) == 1 ) + { + return c[ 0 ]; + } + else + { + if ( vk == VK_DELETE ) + { + return 127; /* 127 = DEL in ascii */ + } + else + { + return vkToSpecial( vk ); + } + } +} + +static void __glutOnKey( HWND hwnd, UINT vk, BOOL down, int repeats, UINT flags ) +{ + int key; + POINT point; + + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + window = getWindowUnderCursor( hwnd, window ); + + /* If we are ignoring auto repeated key strokes for the window, + and this keystroke is an autorepeat generated one, bail. */ + if ( down ) + { + BOOL autorepeat = ( ( flags >> 14 ) & 0x1 ) == 1; + + if ( window->ignoreKeyRepeat && autorepeat ) + { + return; + } + } + + GetCursorPos( &point ); + ScreenToClient( window->win, &point ); + + __glutModifierMask = getModifierMask(); + + key = getKey( vk ); + if ( key < 0 ) + { + /* special */ + + if ( down ) + { + if ( window->special ) + { + __glutSetWindow( window ); + window->special( -key, point.x, point.y ); + } + } + else + { + if ( window->specialUp ) + { + __glutSetWindow( window ); + window->specialUp( -key, point.x, point.y ); + } + } + } + else if ( key > 0 ) + { + /* ascii */ + + if ( down ) + { + if ( window->keyboard ) + { + __glutSetWindow( window ); + window->keyboard( ( unsigned char )key, point.x, point.y ); + } + } + else + { + if ( window->keyboardUp ) + { + __glutSetWindow( window ); + window->keyboardUp( ( unsigned char )key, point.x, point.y ); + } + } + } + + __glutModifierMask = ( unsigned int )~0; + } +} + +static void __glutOnButtonDn( HWND hwnd, int x, int y, int button ) +{ + GLUTmenu* menu; + GLUTwindow* window = __glutGetWindow( hwnd ); + + // !!! - look at this more closely sometime + // !!! - look at this more closely sometime + // !!! - look at this more closely sometime + + /* finish the menu if we get a button down message (user must have + cancelled the menu). */ + if ( __glutMappedMenu ) + { + POINT point; + + /* TODO: take this out once the menu on middle mouse stuff works + properly. */ + if (button == GLUT_MIDDLE_BUTTON) + return; + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + __glutItemSelected = NULL; + __glutFinishMenu(hwnd, point.x, point.y); + return; + } + + // !!! + // !!! + // !!! + + /* Set the capture so we can get mouse events outside the window. */ + SetCapture( hwnd ); + + if ( window ) + { + menu = __glutGetMenuByNum( window->menu[ button ] ); + if ( menu ) + { + POINT point; + point.x = x; point.y = y; + ClientToScreen(window->win, &point); + __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON : + button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON : + 0x0001; + __glutStartMenu(menu, window, point.x, point.y, x, y); + } + else if ( window->mouse ) + { + __glutModifierMask = getModifierMask(); + + __glutSetWindow( window ); + window->mouse( button, GLUT_DOWN, x, y ); + + __glutModifierMask = ( unsigned int )~0; + } + } +} + +static void __glutOnButtonUp( HWND hwnd, int x, int y, int button ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + + // !!! - look at this more closely sometime + // !!! - look at this more closely sometime + // !!! - look at this more closely sometime + + /* Bail out if we're processing a menu. */ + if (__glutMappedMenu) { + POINT point; + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + /* if we're getting the middle button up signal, then something + on the menu was selected. */ + if (button == GLUT_MIDDLE_BUTTON) { + return; + + /* For some reason, the code below always returns -1 even + though the point IS IN THE ITEM! Therefore, just bail out if + we get a middle mouse up. The user must select using the + left mouse button. Stupid Win32. */ + #if 0 + int item = MenuItemFromPoint(hwnd, __glutHMenu, point); + if (item != -1) + __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item); + else + __glutItemSelected = NULL; + __glutFinishMenu(hwnd, point.x, point.y); + #endif + + } else { + __glutItemSelected = NULL; + __glutFinishMenu(hwnd, point.x, point.y); + } + return; + } + + // !!! + // !!! + // !!! + + /* Release the mouse capture. */ + ReleaseCapture(); + + if ( window ) + { + if ( window->mouse ) + { + __glutModifierMask = getModifierMask(); + + __glutSetWindow( window ); + window->mouse( button, GLUT_UP, x, y ); + + __glutModifierMask = ( unsigned int )~0; + } + } +} + +static void __glutOnLButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags ) +{ + __glutOnButtonDn( hwnd, x, y, GLUT_LEFT_BUTTON ); +} + +static void __glutOnRButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags ) +{ + __glutOnButtonDn( hwnd, x, y, GLUT_RIGHT_BUTTON ); +} + +static void __glutOnMButtonDn( HWND hwnd, BOOL doubleClick, int x, int y, UINT flags ) +{ + __glutOnButtonDn( hwnd, x, y, GLUT_MIDDLE_BUTTON ); +} + +static void __glutOnLButtonUp( HWND hwnd, int x, int y, UINT flags ) +{ + __glutOnButtonUp( hwnd, x, y, GLUT_LEFT_BUTTON ); +} + +static void __glutOnRButtonUp( HWND hwnd, int x, int y, UINT flags ) +{ + __glutOnButtonUp( hwnd, x, y, GLUT_RIGHT_BUTTON ); +} + +static void __glutOnMButtonUp( HWND hwnd, int x, int y, UINT flags ) +{ + __glutOnButtonUp( hwnd, x, y, GLUT_MIDDLE_BUTTON ); +} + +static void __glutOnMouseMove( HWND hwnd, int x, int y, UINT flags ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + + if ( __glutMappedMenu ) + { + return; + } + + if ( window ) + { + BOOL down = ( flags & MK_LBUTTON ) || ( flags & MK_RBUTTON ) || ( flags & MK_MBUTTON ); + + if ( window->motion && down ) + { + __glutSetWindow( window ); + window->motion( x, y ); + } + if ( window->passive && ! down ) + { + __glutSetWindow( window ); + window->passive( x, y ); + } + } +} + +static BOOL __glutOnEnterMenuLoop( HWND hwnd ) +{ + /* KLUDGE: create a timer that fires every 100 ms when we start a + menu so that we can still process the idle & timer events (that + way, the timers will fire during a menu pick and so will the + idle func. */ + SetTimer( hwnd, 'MENU', 1, NULL ); + + return FALSE; +} + +static BOOL __glutOnExitMenuLoop( HWND hwnd ) +{ + /* nuke the above created timer...we don't need it anymore, since + the menu is gone now. */ + KillTimer( hwnd, 'MENU' ); + + return FALSE; +} + +static void __glutOnMenuSelect( HWND hwnd, HMENU hmenu, int item, HMENU hmenuPopup, UINT flags ) +{ + if ( hmenu != 0 ) + { + __glutHMenu = hmenu; + } +} + +static void __glutOnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify ) +{ + if ( __glutMappedMenu ) + { + POINT point; + + #if 0 + if ( GetSubMenu( __glutHMenu, id ) ) + { + __glutItemSelected = NULL; + } + else + #endif + { + __glutItemSelected = __glutGetUniqueMenuItem( __glutMappedMenu, id ); + } + + GetCursorPos( &point ); + ScreenToClient( hwnd, &point ); + + __glutFinishMenu( hwnd, point.x, point.y ); + } +} + +static void __glutOnTimer( HWND hwnd, UINT id ) +{ + /* only worry about the idle function and the timeouts, since + these are the only events we expect to process during + processing of a menu. */ + /* we no longer process the idle functions (as outlined in the + README), since drawing can't be done until the menu has + finished...it's pretty lame when the animation goes on, but + doesn't update, so you get this weird jerkiness. */ + #if 0 + if ( __glutIdleFunc ) + { + __glutIdleFunc(); + } + #endif + + if ( __glutTimerList ) + { + handleTimeouts(); + } +} + +static BOOL __glutOnSetCursor( HWND hwnd, HWND hWndCursor, UINT codeHitTest, UINT msg ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window ) + { + __glutSetCursor( window ); + } + + return FALSE; +} + +static BOOL __glutOnPalette( HWND hwnd ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window && window->colormap ) + { + UnrealizeObject( window->colormap->cmap ); + SelectPalette( window->hdc, window->colormap->cmap, FALSE ); + RealizePalette( window->hdc ); + + return TRUE; + } + + return FALSE; +} + +static BOOL __glutOnJoystick( HWND hwnd ) +{ + GLUTwindow* window = __glutGetWindow( hwnd ); + if ( window->joystick ) + { + JOYINFOEX jix; + int x, y, z; + + /* Because WIN32 only supports messages for X, Y, and Z + translations, we must poll for the rest */ + jix.dwSize = sizeof( jix ); + jix.dwFlags = JOY_RETURNALL; + joyGetPosEx( JOYSTICKID1, &jix ); + + #define SCALE( v ) ( ( int )( ( v - 32767 ) / 32.768 ) ) + + /* Convert to integer for scaling. */ + x = jix.dwXpos; + y = jix.dwYpos; + z = jix.dwZpos; + window->joystick( jix.dwButtons, SCALE( x ), SCALE( y ), SCALE( z ) ); + + return TRUE; + } + + return FALSE; +} + +LONG WINAPI __glutWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + switch ( msg ) + { + case WM_CREATE: return HANDLE_WM_CREATE ( hwnd, wparam, lparam, __glutOnCreate ); + case WM_CLOSE: return HANDLE_WM_CLOSE ( hwnd, wparam, lparam, __glutOnClose ); + case WM_DESTROY: return HANDLE_WM_DESTROY ( hwnd, wparam, lparam, __glutOnDestroy ); + case WM_PAINT: return HANDLE_WM_PAINT ( hwnd, wparam, lparam, __glutOnPaint ); + case WM_SIZE: return HANDLE_WM_SIZE ( hwnd, wparam, lparam, __glutOnSize ); + case WM_ACTIVATE: return HANDLE_WM_ACTIVATE ( hwnd, wparam, lparam, __glutOnActivate ); + case WM_SETFOCUS: return HANDLE_WM_SETFOCUS ( hwnd, wparam, lparam, __glutOnSetFocus ); + case WM_KILLFOCUS: return HANDLE_WM_KILLFOCUS ( hwnd, wparam, lparam, __glutOnKillFocus ); + case WM_GETMINMAXINFO: return HANDLE_WM_GETMINMAXINFO ( hwnd, wparam, lparam, __glutOnGetMinMaxInfo ); + case WM_KEYDOWN: return HANDLE_WM_KEYDOWN ( hwnd, wparam, lparam, __glutOnKey ); + case WM_KEYUP: return HANDLE_WM_KEYUP ( hwnd, wparam, lparam, __glutOnKey ); + case WM_SYSKEYDOWN: return HANDLE_WM_KEYDOWN ( hwnd, wparam, lparam, __glutOnKey ); + case WM_SYSKEYUP: return HANDLE_WM_KEYUP ( hwnd, wparam, lparam, __glutOnKey ); + case WM_LBUTTONDOWN: return HANDLE_WM_LBUTTONDOWN ( hwnd, wparam, lparam, __glutOnLButtonDn ); + case WM_RBUTTONDOWN: return HANDLE_WM_RBUTTONDOWN ( hwnd, wparam, lparam, __glutOnRButtonDn ); + case WM_MBUTTONDOWN: return HANDLE_WM_MBUTTONDOWN ( hwnd, wparam, lparam, __glutOnMButtonDn ); + case WM_LBUTTONUP: return HANDLE_WM_LBUTTONUP ( hwnd, wparam, lparam, __glutOnLButtonUp ); + case WM_RBUTTONUP: return HANDLE_WM_RBUTTONUP ( hwnd, wparam, lparam, __glutOnRButtonUp ); + case WM_MBUTTONUP: return HANDLE_WM_MBUTTONUP ( hwnd, wparam, lparam, __glutOnMButtonUp ); + case WM_MOUSEMOVE: return HANDLE_WM_MOUSEMOVE ( hwnd, wparam, lparam, __glutOnMouseMove ); + case WM_ENTERMENULOOP: return __glutOnEnterMenuLoop( hwnd ); + case WM_EXITMENULOOP: return __glutOnExitMenuLoop( hwnd ); + case WM_COMMAND: return HANDLE_WM_COMMAND ( hwnd, wparam, lparam, __glutOnCommand ); + case WM_TIMER: return HANDLE_WM_TIMER ( hwnd, wparam, lparam, __glutOnTimer ); + + case WM_SETCURSOR: + if ( LOWORD( lparam ) != HTCLIENT ) + { + /* Let the default window proc handle cursors outside the client area */ + break; + } + else + { + return HANDLE_WM_SETCURSOR( hwnd, wparam, lparam, __glutOnSetCursor ); + } + + case WM_PALETTECHANGED: + if ( ( HWND )wparam == hwnd ) + { + /* Don't respond to the message that we sent! */ + break; + } + /* Fall through to WM_QUERYNEWPALETTE */ + + case WM_QUERYNEWPALETTE: + return __glutOnPalette( hwnd ); + + case MM_JOY1MOVE: + case MM_JOY1ZMOVE: + case MM_JOY1BUTTONDOWN: + case MM_JOY1BUTTONUP: + return __glutOnJoystick( hwnd ); + + default: + break; + } + + return DefWindowProc( hwnd, msg, wparam, lparam ); +} diff --git a/lib/glut-3.7.6/lib/glut/win32_x11.c b/lib/glut-3.7.6/lib/glut/win32_x11.c new file mode 100644 index 0000000000..decca9c0b0 --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_x11.c @@ -0,0 +1,403 @@ + +/* Copyright (c) Nate Robins, 1997. */ +/* portions Copyright (c) Mark Kilgard, 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 "glutint.h" + +/* global variable that must be set for some functions to operate + correctly. */ +HDC XHDC; + +XVisualInfo* +XGetVisualInfo(Display* display, long mask, XVisualInfo* template, int* nitems) +{ + /* KLUDGE: this function needs XHDC to be set to the HDC currently + being operated on before it is invoked! */ + + PIXELFORMATDESCRIPTOR* pfds = NULL; + int i, n; + + n = DescribePixelFormat(XHDC, 1, 0, NULL); + + if (n > 0) { + pfds = (PIXELFORMATDESCRIPTOR*)malloc(sizeof(PIXELFORMATDESCRIPTOR) * n); + memset(pfds, 0, sizeof(PIXELFORMATDESCRIPTOR) * n); + } + + for (i = 0; i < n; i++) { + DescribePixelFormat(XHDC, i + 1, sizeof(PIXELFORMATDESCRIPTOR), &pfds[i]); + } + + *nitems = n; + return pfds; +} + +Colormap +XCreateColormap(Display* display, Window root, Visual* visual, int alloc) +{ + /* KLUDGE: this function needs XHDC to be set to the HDC currently + being operated on before it is invoked! */ + + PIXELFORMATDESCRIPTOR pfd; + LOGPALETTE *logical; + HPALETTE palette; + int n; + + /* grab the pixel format */ + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + DescribePixelFormat(XHDC, GetPixelFormat(XHDC), + sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + if (!(pfd.dwFlags & PFD_NEED_PALETTE || + pfd.iPixelType == PFD_TYPE_COLORINDEX)) + { + return 0; + } + + n = 1 << pfd.cColorBits; + + /* allocate a bunch of memory for the logical palette (assume 256 + colors in a Win32 palette */ + logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + + sizeof(PALETTEENTRY) * n); + memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n); + + /* set the entries in the logical palette */ + logical->palVersion = 0x300; + logical->palNumEntries = n; + + /* start with a copy of the current system palette */ + GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]); + + if (pfd.iPixelType == PFD_TYPE_RGBA) { + int redMask = (1 << pfd.cRedBits) - 1; + int greenMask = (1 << pfd.cGreenBits) - 1; + int blueMask = (1 << pfd.cBlueBits) - 1; + int i; + + /* fill in an RGBA color palette */ + for (i = 0; i < n; ++i) { + logical->palPalEntry[i].peRed = + (((i >> pfd.cRedShift) & redMask) * 255) / redMask; + logical->palPalEntry[i].peGreen = + (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; + logical->palPalEntry[i].peBlue = + (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; + logical->palPalEntry[i].peFlags = 0; + } + } + + palette = CreatePalette(logical); + free(logical); + + SelectPalette(XHDC, palette, FALSE); + RealizePalette(XHDC); + + return palette; +} + +void +XAllocColorCells(Display* display, Colormap colormap, Bool contig, + unsigned long plane_masks_return[], unsigned int nplanes, + unsigned long pixels_return[], unsigned int npixels) +{ + /* NOP -- we did all the allocating in XCreateColormap! */ +} + +void +XStoreColor(Display* display, Colormap colormap, XColor* color) +{ + /* KLUDGE: set XHDC to 0 if the palette should NOT be realized after + setting the color. set XHDC to the correct HDC if it should. */ + + PALETTEENTRY pe; + + /* X11 stores color from 0-65535, Win32 expects them to be 0-256, so + twiddle the bits ( / 256). */ + pe.peRed = color->red / 256; + pe.peGreen = color->green / 256; + pe.peBlue = color->blue / 256; + + /* make sure we use this flag, otherwise the colors might get mapped + to another place in the colormap, and when we glIndex() that + color, it may have moved (argh!!) */ + pe.peFlags = PC_NOCOLLAPSE; + + /* the pixel field of the XColor structure is the index into the + colormap */ + SetPaletteEntries(colormap, color->pixel, 1, &pe); + + if (XHDC) { + UnrealizeObject(colormap); + SelectPalette(XHDC, colormap, FALSE); + RealizePalette(XHDC); + } +} + +void +XSetWindowColormap(Display* display, Window window, Colormap colormap) +{ + HDC hdc = GetDC(window); + + /* if the third parameter is FALSE, the logical colormap is copied + into the device palette when the application is in the + foreground, if it is TRUE, the colors are mapped into the current + palette in the best possible way. */ + SelectPalette(hdc, colormap, FALSE); + RealizePalette(hdc); + + /* note that we don't have to release the DC, since our window class + uses the WC_OWNDC flag! */ +} + +Bool +XTranslateCoordinates(Display *display, Window src, Window dst, + int src_x, int src_y, + int* dest_x_return, int* dest_y_return, + Window* child_return) +{ + /* KLUDGE: this isn't really a translate coordinates into some other + windows coordinate system...it only translates coordinates into the + root window (screen) coordinate system. */ + + POINT point; + + point.x = src_x; + point.y = src_y; + + ClientToScreen(src, &point); + + *dest_x_return = point.x; + *dest_y_return = point.y; + + /* just to make compilers happy...we don't use the return value. */ + return True; +} + +Status +XGetGeometry(Display* display, Window window, Window* root_return, + int* x_return, int* y_return, + unsigned int* width_return, unsigned int* height_return, + unsigned int *border_width_return, unsigned int* depth_return) +{ + /* KLUDGE: doesn't return the border_width or depth or root, x & y + are in screen coordinates. */ + + RECT rect; + POINT point; + + GetClientRect(window, &rect); + + point.x = 0; + point.y = 0; + ClientToScreen(window, &point); + + *x_return = point.x; + *y_return = point.y; + *width_return = rect.right; + *height_return = rect.bottom; + + /* just to make compilers happy...we don't use the return value. */ + return 1; +} + +int +DisplayWidthMM(Display* display, int screen) +{ + int width; + HWND hwnd = GetDesktopWindow(); + HDC hdc = GetDC(hwnd); + + width = GetDeviceCaps(hdc, HORZSIZE); + + /* make sure to release this DC (it's the desktops, not ours) */ + ReleaseDC(hwnd, hdc); + + return width; +} + +int +DisplayHeightMM(Display* display, int screen) +{ + int height; + HWND hwnd = GetDesktopWindow(); + HDC hdc = GetDC(hwnd); + + height = GetDeviceCaps(hdc, VERTSIZE); + + /* make sure to release this DC (it's the desktops, not ours) */ + ReleaseDC(hwnd, hdc); + + return height; +} + +void +XWarpPointer(Display* display, Window src, Window dst, + int src_x, int src_y, int src_width, int src_height, + int dst_x, int dst_y) +{ + /* KLUDGE: this isn't really a warp pointer into some other windows + coordinate system...it only warps the pointer into the root window + (screen) coordinate system. */ + + POINT point; + + point.x = dst_x; + point.y = dst_y; + ClientToScreen(dst, &point); + + SetCursorPos(point.x, point.y); +} + +int +XPending(Display* display) +{ + /* similar functionality...I don't think that it is exact, but this + will have to do. */ + MSG msg; + + return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); +} + +/* the following function was stolen from the X sources as indicated. */ + +/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */ +/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */ + +/* +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. M.I.T. makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. +*/ + +/* + * XParseGeometry parses strings of the form + * "=x{+-}{+-}", where + * width, height, xoffset, and yoffset are unsigned integers. + * Example: "=80x24+300-49" + * The equal sign is optional. + * It returns a bitmask that indicates which of the four values + * were actually found in the string. For each value found, + * the corresponding argument is updated; for each value + * not found, the corresponding argument is left unchanged. + */ + +static int +ReadInteger(char *string, char **NextString) +{ + register int Result = 0; + int Sign = 1; + + if (*string == '+') + string++; + else if (*string == '-') + { + string++; + Sign = -1; + } + for (; (*string >= '0') && (*string <= '9'); string++) + { + Result = (Result * 10) + (*string - '0'); + } + *NextString = string; + if (Sign >= 0) + return (Result); + else + return (-Result); +} + +int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height) +{ + int mask = NoValue; + register char *strind; + unsigned int tempWidth, tempHeight; + int tempX, tempY; + char *nextCharacter; + + if ( (string == NULL) || (*string == '\0')) return(mask); + if (*string == '=') + string++; /* ignore possible '=' at beg of geometry spec */ + + strind = (char *)string; + if (*strind != '+' && *strind != '-' && *strind != 'x') { + tempWidth = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= WidthValue; + } + + if (*strind == 'x' || *strind == 'X') { + strind++; + tempHeight = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= HeightValue; + } + + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempX = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= XNegative; + + } + else + { strind++; + tempX = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= XValue; + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempY = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + mask |= YNegative; + + } + else + { + strind++; + tempY = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= YValue; + } + } + + /* If strind isn't at the end of the string the it's an invalid + geometry specification. */ + + if (*strind != '\0') return (0); + + if (mask & XValue) + *x = tempX; + if (mask & YValue) + *y = tempY; + if (mask & WidthValue) + *width = tempWidth; + if (mask & HeightValue) + *height = tempHeight; + return (mask); +} diff --git a/lib/glut-3.7.6/lib/glut/win32_x11.h b/lib/glut-3.7.6/lib/glut/win32_x11.h new file mode 100644 index 0000000000..5aed5b89de --- /dev/null +++ b/lib/glut-3.7.6/lib/glut/win32_x11.h @@ -0,0 +1,319 @@ +#ifndef __win32_x11_h__ +#define __win32_x11_h__ + +/* Copyright (c) Nate Robins, 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. */ + +#include +#include + +/* Type definitions (conversions) */ +typedef int Visual; /* Win32 equivalent of X11 type */ +typedef HWND Window; +typedef HPALETTE Colormap; +typedef PIXELFORMATDESCRIPTOR XVisualInfo; +typedef BOOL Bool; +typedef MSG XEvent; +typedef HDC Display; +typedef HCURSOR Cursor; + +typedef int Atom; /* dummies */ +typedef int XDevice; +typedef int Status; + +#define True TRUE /* Win32 equivalents of X11 booleans */ +#define False FALSE + +#define None 0L /* universal null resource or null atom */ + +/* Input Event Masks. Used as event-mask window attribute and as arguments + to Grab requests. Not to be confused with event names. */ + +#define NoEventMask 0L +#define KeyPressMask (1L<<0) +#define KeyReleaseMask (1L<<1) +#define ButtonPressMask (1L<<2) +#define ButtonReleaseMask (1L<<3) +#define EnterWindowMask (1L<<4) +#define LeaveWindowMask (1L<<5) +#define PointerMotionMask (1L<<6) +#define PointerMotionHintMask (1L<<7) +#define Button1MotionMask (1L<<8) +#define Button2MotionMask (1L<<9) +#define Button3MotionMask (1L<<10) +#define Button4MotionMask (1L<<11) +#define Button5MotionMask (1L<<12) +#define ButtonMotionMask (1L<<13) +#define KeymapStateMask (1L<<14) +#define ExposureMask (1L<<15) +#define VisibilityChangeMask (1L<<16) +#define StructureNotifyMask (1L<<17) +#define ResizeRedirectMask (1L<<18) +#define SubstructureNotifyMask (1L<<19) +#define SubstructureRedirectMask (1L<<20) +#define FocusChangeMask (1L<<21) +#define PropertyChangeMask (1L<<22) +#define ColormapChangeMask (1L<<23) +#define OwnerGrabButtonMask (1L<<24) + +/* Key masks. Used as modifiers to GrabButton and GrabKey, results of + QueryPointer, state in various key-, mouse-, and button-related + events. */ + +#define ShiftMask (1<<0) +#define LockMask (1<<1) +#define ControlMask (1<<2) +#define Mod1Mask (1<<3) +#define Mod2Mask (1<<4) +#define Mod3Mask (1<<5) +#define Mod4Mask (1<<6) +#define Mod5Mask (1<<7) + +/* Window classes used by CreateWindow */ +/* Note that CopyFromParent is already defined as 0 above */ + +#define InputOutput 1 +#define InputOnly 2 + +/* Window attributes for CreateWindow and ChangeWindowAttributes */ + +#define CWBackPixmap (1L<<0) +#define CWBackPixel (1L<<1) +#define CWBorderPixmap (1L<<2) +#define CWBorderPixel (1L<<3) +#define CWBitGravity (1L<<4) +#define CWWinGravity (1L<<5) +#define CWBackingStore (1L<<6) +#define CWBackingPlanes (1L<<7) +#define CWBackingPixel (1L<<8) +#define CWOverrideRedirect (1L<<9) +#define CWSaveUnder (1L<<10) +#define CWEventMask (1L<<11) +#define CWDontPropagate (1L<<12) +#define CWColormap (1L<<13) +#define CWCursor (1L<<14) + +/* ConfigureWindow structure */ + +#define CWX (1<<0) +#define CWY (1<<1) +#define CWWidth (1<<2) +#define CWHeight (1<<3) +#define CWBorderWidth (1<<4) +#define CWSibling (1<<5) +#define CWStackMode (1<<6) + + +/* Used in GetWindowAttributes reply */ + +#define IsUnmapped 0 +#define IsUnviewable 1 +#define IsViewable 2 + +/* Window stacking method (in configureWindow) */ + +#define Above 0 +#define Below 1 +#define TopIf 2 +#define BottomIf 3 +#define Opposite 4 + +/* For CreateColormap */ + +#define AllocNone 0 /* create map with no entries */ +#define AllocAll 1 /* allocate entire map writeable */ + + +/* Flags used in StoreNamedColor, StoreColors */ + +#define DoRed (1<<0) +#define DoGreen (1<<1) +#define DoBlue (1<<2) + +/* + * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding + * value (x, y, width, height) was found in the parsed string. + */ +#define NoValue 0x0000 +#define XValue 0x0001 +#define YValue 0x0002 +#define WidthValue 0x0004 +#define HeightValue 0x0008 +#define AllValues 0x000F +#define XNegative 0x0010 +#define YNegative 0x0020 + +/* flags argument in size hints */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ + +/* definitions for initial window state */ +#define WithdrawnState 0 /* for windows that are not mapped */ +#define NormalState 1 /* most applications want to start this way */ +#define IconicState 3 /* application wants to start as an icon */ +#define GameModeState 4 /* Win32 GLUT only (not in Xlib!). */ + +/* Type definitions */ + +typedef struct { + unsigned int background_pixmap; /* background pixmap */ + unsigned long background_pixel; /* background pixel */ + unsigned long border_pixel; /* border pixel value */ + long event_mask; /* set of events that should be saved */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Colormap colormap; /* color map to be associated with window */ +} XSetWindowAttributes; + +typedef struct { + unsigned long pixel; + unsigned short red, green, blue; + char flags; /* do_red, do_green, do_blue */ +} XColor; + +typedef struct { + unsigned char *value; /* same as Property routines */ + Atom encoding; /* prop type */ + int format; /* prop data format: 8, 16, or 32 */ + unsigned long nitems; /* number of data items in value */ +} XTextProperty; + +typedef struct { + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ +} XSizeHints; + +/* Functions emulated by macros. */ + +#define XFreeColormap(display, colormap) \ + DeleteObject(colormap) + +#define XCreateFontCursor(display, shape) \ + LoadCursor(NULL, shape) + +#define XDefineCursor(display, window, cursor) \ + SetCursor(cursor) + +#define XFlush(display) \ + /* Nothing. */ + +#define DisplayWidth(display, screen) \ + GetSystemMetrics(SM_CXSCREEN) + +#define DisplayHeight(display, screen) \ + GetSystemMetrics(SM_CYSCREEN) + +#define XMapWindow(display, window) \ + ShowWindow(window, SW_SHOWNORMAL) + +#define XUnmapWindow(display, window) \ + ShowWindow(window, SW_HIDE) + +#define XIconifyWindow(display, window, screen) \ + ShowWindow(window, SW_MINIMIZE) + +#define XWithdrawWindow(display, window, screen) \ + ShowWindow(window, SW_HIDE) + +#define XLowerWindow(display, window) \ + SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) + +#define XSetWMName(display, window, tp) \ + SetWindowText(window, (tp)->value) + +/* There really isn't a way to set the icon name separate from the + windows name in Win32, so, just set the windows name. */ +#define XSetWMIconName(display, window, tp) \ + XSetWMName(display, window, tp) + +#define XDestroyWindow(display, window) \ + DestroyWindow(window) + +/* Anything that needs to be freed was allocated with malloc in our + fake X windows library for Win32, so free it with plain old + free(). */ +#define XFree(data) \ + free(data) + +/* Nothing to be done for this...the pointer is always 'ungrabbed' + in Win32. */ +#define XUngrabPointer(display, time) \ + /* Nothing. */ + +/* Function prototypes. */ + +extern XVisualInfo* XGetVisualInfo( + Display* display, + long mask, + XVisualInfo* ttemplate, /* Avoid class with C++ keyword. */ + int*nitems); + +extern Colormap XCreateColormap( + Display* display, + Window root, + Visual* visual, + int alloc); + +extern void XAllocColorCells( + Display* display, + Colormap colormap, + Bool contig, + unsigned long plane_masks_return[], + unsigned int nplanes, + unsigned long pixels_return[], + unsigned int npixels); + +extern void XStoreColor( + Display* display, + Colormap colormap, + XColor* color); + +extern void XSetWindowColormap( + Display* display, + Window window, + Colormap colormap); + +extern Bool XTranslateCoordinates( + Display *display, + Window src, Window dst, + int src_x, int src_y, + int* dest_x_return, int* dest_y_return, + Window* child_return); + +extern Status XGetGeometry( + Display* display, + Window window, + Window* root_return, + int* x_return, int* y_return, + unsigned int* width_return, unsigned int* height_return, + unsigned int *border_width_return, + unsigned int* depth_return); + +extern int DisplayWidthMM( + Display* display, + int screen); + +extern int DisplayHeightMM( + Display* display, + int screen); + +extern void XWarpPointer( + Display* display, + Window src, Window dst, + int src_x, int src_y, + int src_width, int src_height, + int dst_x, int dst_y); + +extern int XParseGeometry( + char* string, + int* x, int* y, + unsigned int* width, unsigned int* height); + +extern int XPending( + Display* display); + +#endif /* __win32_x11_h__ */ diff --git a/lib/glut-3.7.6/lib/lib.dsw b/lib/glut-3.7.6/lib/lib.dsw new file mode 100644 index 0000000000..0174a8f880 --- /dev/null +++ b/lib/glut-3.7.6/lib/lib.dsw @@ -0,0 +1,89 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "_all"=".\_all.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name gle + End Project Dependency + Begin Project Dependency + Project_Dep_Name glsmap + End Project Dependency + Begin Project Dependency + Project_Dep_Name glut32 + End Project Dependency + Begin Project Dependency + Project_Dep_Name mui + End Project Dependency +}}} + +############################################################################### + +Project: "gle"=".\gle\gle.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "glsmap"=".\glsmap\glsmap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "glut32"=".\glut\glut32.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "mui"=".\mui\mui.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/lib/mui.n32/ObjectType.mk b/lib/glut-3.7.6/lib/mui.n32/ObjectType.mk new file mode 100644 index 0000000000..6116ff97eb --- /dev/null +++ b/lib/glut-3.7.6/lib/mui.n32/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_N32) +CSTYLE = $(CSTYLE_N32) diff --git a/lib/glut-3.7.6/lib/mui.n64/ObjectType.mk b/lib/glut-3.7.6/lib/mui.n64/ObjectType.mk new file mode 100644 index 0000000000..55d0f47555 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui.n64/ObjectType.mk @@ -0,0 +1,3 @@ +LDOPTS = $(LDOPTS_64) +#OPTIMIZER = -O0 +CSTYLE = $(CSTYLE_64) diff --git a/lib/glut-3.7.6/lib/mui/Imakefile b/lib/glut-3.7.6/lib/mui/Imakefile new file mode 100644 index 0000000000..84e069c7db --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/Imakefile @@ -0,0 +1,26 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#define DoNormalLib YES + +#include + +#include "../../Glut.cf" + +SRCS = button.c displaylist.c gizmo.c glutmui.c \ + hslider.c miscui.c mui.c pulldown.c textlist.c uicolor.c vslider.c + +OBJS = button.o displaylist.o gizmo.o glutmui.o \ + hslider.o miscui.o mui.o pulldown.o textlist.o uicolor.o vslider.o + +#ifdef LibraryObjectRule +LibraryObjectRule() +#else +/* XXX Very lame, you must be using pre-R5 config files! This + will probably do essentially what LibraryObjectRule does. */ +NormalLibraryObjectRule() +#endif + +NormalLibraryTarget(mui,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/lib/mui/ObjectType.mk b/lib/glut-3.7.6/lib/mui/ObjectType.mk new file mode 100644 index 0000000000..f94dc77f5f --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/ObjectType.mk @@ -0,0 +1,2 @@ +LDOPTS = $(LDOPTS_32) +CSTYLE = $(CSTYLE_32) diff --git a/lib/glut-3.7.6/lib/mui/browseparse.c b/lib/glut-3.7.6/lib/mui/browseparse.c new file mode 100644 index 0000000000..e7280bb1a1 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/browseparse.c @@ -0,0 +1,98 @@ +/* + * 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. + */ + +#include +#include +#include + +char currentdirectoryname[200]; +char currentfilename[200]; +char browseprompt[200]; + +int xcenter = 300, ycenter = 300; + +void nukecr(char *s) +{ + while (*s && *s != '\n') s++; + *s = 0; +} + +void parsebrowsefile(FILE *f) +{ + char buffer[300]; + + while (0 != fgets(buffer, 299, f)) + switch(buffer[0]) { + case 'D': + strcpy(currentdirectoryname, &buffer[2]); + nukecr(currentdirectoryname); + break; + case 'F': + strcpy(currentfilename, &buffer[2]); + nukecr(currentfilename); + break; + case 'P': + strcpy(browseprompt, &buffer[2]); + nukecr(browseprompt); + break; + case 'X': + xcenter = atoi(&buffer[2]); + break; + case 'Y': + ycenter = atoi(&buffer[2]); + break; + } +} + +void setcurrentfilename(char *s) +{ + int len = strlen(s); + char *sptr; + + sptr = &s[len-1]; + while (sptr != s) { + if (*sptr == '/') { + strcpy(currentfilename, sptr+1); + *sptr = 0; + strcpy(currentdirectoryname, s); + return; + } + sptr--; + } + strcpy(currentfilename, s); +} + diff --git a/lib/glut-3.7.6/lib/mui/browser.c b/lib/glut-3.7.6/lib/mui/browser.c new file mode 100644 index 0000000000..7b71d82ebc --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/browser.c @@ -0,0 +1,419 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXFILES 400 +char *filelist[MAXFILES]; +char err[80]; +char *dot = "."; +char *dotdot = ".."; +char directory[300], originaldir[300]; +struct stat d, dd; +struct dirent *dir; + +DIR *file; +int off; + +extern int mui_singlebuffered; +int selectedfile = -1; +int cd(char *s); +void pwd(void); +void ls(void); + +extern void settlstrings(muiObject *obj, char **s); +void settltop(muiObject *obj, int top); + +muiObject *tl, *vs, *l4; + +void writeoutputfile(char *dir, char *file) +{ + FILE *f; + f = fopen(BROWSEFILE, "w"); + fprintf(f, "D:%s\n", dir); + if (file) + fprintf(f, "F:%s\n", file); + fclose(f); +} + +void controltltop(muiObject *obj, enum muiReturnValue value) +{ + float sliderval; + + if ((value != MUI_SLIDER_RETURN) && (value != MUI_SLIDER_THUMB)) return; + sliderval = muiGetVSVal(obj); + muiSetTLTop(tl, sliderval); +} + +void handlefileselection(muiObject *obj, enum muiReturnValue value) +{ + char *fname; + int len; + + if (value == MUI_TEXTLIST_RETURN_CONFIRM) { + selectedfile = muiGetTLSelectedItem(obj); + fname = filelist[selectedfile]; + len = strlen(fname); + if (fname[len-1] == '/') { + fname[len-1] = 0; + cd(fname); + return; + } else { + writeoutputfile(directory, fname); + exit(0); + } + } + if (value != MUI_TEXTLIST_RETURN) return; + selectedfile = muiGetTLSelectedItem(obj); + muiSetVSValue(vs, 1.0); +} + +void handleaccept(muiObject *obj, enum muiReturnValue value) +{ + char *fname; + int len; + + if (value != MUI_BUTTON_PRESS) return; + if (selectedfile == -1) return; + fname = filelist[selectedfile]; + len = strlen(fname); + if (fname[len-1] == '/') { + fname[len-1] = 0; + cd(fname); + return; + } else { + writeoutputfile(directory, fname); + exit(0); + } + obj = 0; /* for lint's sake */ +} + +void handleoriginal(muiObject *obj, enum muiReturnValue value) +{ + if (value != MUI_BUTTON_PRESS) return; + cd(originaldir); + obj = 0; /* for lint's sake */ +} + +void handleupdir(muiObject *obj, enum muiReturnValue value) +{ + if (value != MUI_BUTTON_PRESS) return; + cd(".."); + obj = 0; /* for lint's sake */ +} + +void handlecancel(muiObject *obj, enum muiReturnValue value) +{ + if (value != MUI_BUTTON_PRESS) return; + writeoutputfile(directory, 0); + exit(0); + obj = 0; /* for lint's sake */ +} + +void handletextbox(muiObject *obj, enum muiReturnValue value) +{ + char *s, *slash; + + if (value != MUI_TEXTBOX_RETURN) return; + s = muiGetTBString(obj); + if (0 == chdir(s)) { + pwd(); + ls(); + settlstrings(tl, filelist); + selectedfile = 0; + muiChangeLabel(l4, directory); + muiClearTBString(obj); + return; + } + /* hack up the path, if any */ + slash = strrchr(s, '/'); + if (slash == 0) { + slash = s-1; /* to make filename == slash+1 */ + } else { + if (*s == '/') { /* absolute path */ + strncpy(directory, s, slash-s); + directory[slash-s] = 0; + } else { + strcat(directory, "/"); + strncat(directory, s, slash-s); + } + } + /* now filename == slash+1 */ + writeoutputfile(directory, slash+1); + exit(0); +} + +#define THUMBHEIGHT 20 +#define ARROWSPACE 40 + +void maketestui(void) +{ + muiObject *l1, *l2, *l3, *b1, *b2, *b3, *b4, *t; + int xmin, ymin, xmax, ymax; + + muiNewUIList(1); + l1 = muiNewBoldLabel(10, 475, "Directory:"); + muiAddToUIList(1, l1); + l4 = muiNewLabel(80, 475, "./"); + muiAddToUIList(1, l4); + l2 = muiNewBoldLabel(10, 430, "Set directory:"); + muiAddToUIList(1, l2); + b1 = muiNewButton(10, 100, 390, 415); + muiLoadButton(b1, "Up"); + muiAddToUIList(1, b1); + muiSetCallback(b1, handleupdir); + b2 = muiNewButton(10, 100, 355, 380); + muiLoadButton(b2, "Original"); + muiAddToUIList(1, b2); + muiSetCallback(b2, handleoriginal); + tl = muiNewTextList(120, 80, 370, 22); + muiAddToUIList(1, tl); + muiGetObjectSize(tl, &xmin, &ymin, &xmax, &ymax); + vs = muiNewVSlider(xmax, ymin+2, ymax, 0, THUMBHEIGHT); + muiSetVSValue(vs, 1.0); + muiSetVSArrowDelta(vs, 10); + muiAddToUIList(1, vs); + t = muiNewTextbox(120, 390, 40); + muiSetActive(t, 1); + muiAddToUIList(1, t); + muiSetCallback(t, handletextbox); + l3 = muiNewBoldLabel(40, 50, "Open File:"); + muiAddToUIList(1, l3); + b3 = muiNewButton(130, 230, 9, 34); + muiLoadButton(b3, "Accept"); + muiSetCallback(b3, handleaccept); + muiAddToUIList(1, b3); + b4 = muiNewButton(250, 350, 9, 34); + muiLoadButton(b4, "Cancel"); + muiSetCallback(b4, handlecancel); + muiAddToUIList(1, b4); + muiSetCallback(vs, controltltop); + muiSetCallback(tl, handlefileselection); + + cd(directory); + strcpy(originaldir, directory); +} + +void main(int argc, char **argv) +{ + FILE *f; + + f = fopen(BROWSEFILE, "r"); + parsebrowsefile(f); + fclose(f); + strcpy(directory, currentdirectoryname); + maketestui(); + glutInit(&argc, argv); + if (argc > 1) mui_singlebuffered = 1; + glutInitWindowPosition(xcenter-200, ycenter-250); + glutInitWindowSize(400, 500); + if (mui_singlebuffered) + glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE ); + else + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow("browser"); + muiInit(); + glutMainLoop(); +} + +void errormsg(char *s) +{ + fprintf(stderr, "%s\n", s); +} + +void prname(void) +{ + directory[0] = '/'; + if (off == 0) + off = 1; + directory[off] = 0; +} + +int dirlevels(char *s) +{ + int levels; + + for (levels = 0; *s; s++) + if (*s == '/') + levels++; + return(levels); +} + +int cat(void) +{ + register i, j; + char *name = directory + 1; /* I love C */ + + i = -1; + while (dir->d_name[++i] != 0) + if ((off+i+2) > MAXNAMLEN - 1) { + prname(); + return 1; + } + for(j=off+1; j>=0; --j) + name[j+i+1] = name[j]; + off=i+off+1; + name[i] = '/'; + for(--i; i>=0; --i) + name[i] = dir->d_name[i]; + return 0; +} + +/* get the current working directory (the following 3 routines are from pwd.c) */ +void pwd(void) +{ + for(off = 0;;) { + if(stat(dot, &d) < 0) { + fprintf(stderr, "pwd: cannot stat .!\n"); + exit(2); + } + if ((file = opendir(dotdot)) == NULL) { + fprintf(stderr,"pwd: cannot open ..\n"); + exit(2); + } + if(fstat(file->dd_fd, &dd) < 0) { + fprintf(stderr, "pwd: cannot stat ..!\n"); + exit(2); + } + if(chdir(dotdot) < 0) { + fprintf(stderr, "pwd: cannot chdir to ..\n"); + exit(2); + } + if(d.st_dev == dd.st_dev) { + if(d.st_ino == dd.st_ino) { + prname(); + chdir(directory); + return; + } + do + if ((dir = readdir(file)) == NULL) { + fprintf(stderr, "pwd: read error in ..\n"); + exit(2); + } + while (dir->d_ino != d.st_ino); + } + else do { + if((dir = readdir(file)) == NULL) { + fprintf(stderr, "pwd: read error in ..\n"); + exit(2); + } + stat(dir->d_name, &dd); + } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); + (void)closedir(file); + if (cat()) { + chdir(directory); + return; + } + } +} + +void freels(void) +{ + char **p; + + p = filelist; + while (*p != 0) { + free(*p); + *p = 0; + p++; + } +} + +int mystrcmp(char **s1, char **s2) +{ + return strcmp(*s1,*s2); +} + +void ls(void) +{ + DIR *dirp; + int i = 0; + int len; + struct dirent *dir; + struct stat statbuf; + + + if ((dirp = opendir(directory)) == NULL) { + errormsg("bad directory\n"); + return; + } + freels(); + chdir(directory); + while ((dir = readdir(dirp)) != NULL) { + if (dir->d_name[0] == '.') + continue; + /*f = open(dir->d_name, O_RDONLY); + if (!f) + continue; + if (!okfiletype(getfiletype(f))) + continue; + close(f);*/ + stat(dir->d_name,&statbuf); + len = strlen(dir->d_name) + 1 + (statbuf.st_mode & S_IFDIR? 1 : 0); + filelist[i] = (char *)malloc(len); + strcpy(filelist[i], dir->d_name); + if (statbuf.st_mode & S_IFDIR) { + filelist[i][len-2] = '/'; filelist[i][len-1] = 0; + } + i++; + } + filelist[i] = 0; + qsort(&filelist[0], i, sizeof (char *), (int (*)(const void *, const void *))mystrcmp); + closedir(dirp); +} + +int cd(char *s) +{ + if(chdir(s) < 0) { + fprintf(stderr,"cannot open %s\n",s); + return -1; + } + pwd(); + ls(); + settlstrings(tl, filelist); + muiChangeLabel(l4, directory); + selectedfile = 0; + return 0; +} diff --git a/lib/glut-3.7.6/lib/mui/button.c b/lib/glut-3.7.6/lib/mui/button.c new file mode 100644 index 0000000000..40e4e87f17 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/button.c @@ -0,0 +1,508 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +void muiLinkButtons(muiObject *obj1, muiObject *obj2) +{ + Button *b1, *b2, *tmp; + + if ((obj1->type != MUI_RADIOBUTTON || obj2->type != MUI_RADIOBUTTON) && + (obj1->type != MUI_TINYRADIOBUTTON || obj2->type != MUI_TINYRADIOBUTTON)) { + muiError("muiLinkButtons: attempt to link non radio buttons"); + } + b1 = (Button *)obj1->object; + b2 = (Button *)obj2->object; + if (b1->link == 0 && b2->link == 0) { + b1->link = b2; + b2->link = b1; + return; + } + if (b1->link == 0) { + b1->link = b2->link; + b2->link = b1; + return; + } + if (b2->link == 0) { + b2->link = b1->link; + b1->link = b2; + return; + } + tmp = b1->link; + b1->link = b2->link; + b2->link = tmp; + return; +} + +void muiClearRadio(muiObject *rad) +{ + Button *b1, *b2; + b2 = b1 = (Button *)rad->object; + muiSetActive(b1->object, 0); + if (b1->link == 0) return; + b1 = b1->link; + while (b1 != b2) { + muiSetActive(b1->object, 0); + b1 = b1->link; + } +} + + +static void drawbuttonlabel(muiObject *obj) +{ + int xmin, ymin; + Button *b = (Button *)obj->object; + + if (!b->str) + return; + + switch (obj->type) { +/* + case TINYTOGGLE: + xmin = obj->xmin+16; + ymin = obj->ymin+4; + break; + case GENERICBUTTON: + xmin = obj->xmin+ (obj->xmax - obj->xmin - strwidth(obj->str))/2 + 1; + ymin = obj->ymin+9; + break; + case PUSHBUTTON: + if (getdefaultbut(b)) { + xmin = obj->xmin+ (obj->xmax - 15 - obj->xmin - strwidth(obj->str))/2 + 1; + ymin = obj->ymin+9; + } else { + xmin = obj->xmin+ (obj->xmax - obj->xmin - strwidth(obj->str))/2 + 1; + ymin = obj->ymin+9; + } + break; + case BED: + xmin = obj->xmin+ (obj->xmax - obj->xmin - strwidth(obj->str))/2 + 1; + ymin = obj->ymin+8; + break; + case CHECKBUTTON: + xmin = obj->xmin+27; + ymin = obj->ymin+6; + break; +*/ + case MUI_TINYRADIOBUTTON: + xmin = obj->xmin+19; + ymin = obj->ymin+4; + break; + case MUI_RADIOBUTTON: + xmin = obj->xmin+30; + ymin = obj->ymin+8; + break; +/* + case INDICATOR: + xmin = obj->xmin+20; + ymin = obj->ymin+8; + break; +*/ + default: + xmin = obj->xmin+20; + ymin = obj->ymin+9; + break; + } + { + if (muiGetEnable(obj)) + uiBlack(); + else + uiDkGray(); + uicmov2i(xmin, ymin); + uicharstr(b->str, UI_FONT_NORMAL); + + } +} + +void drawradiobutton(muiObject *obj) +{ + int xmin = obj->xmin, xmax = obj->xmax, ymin = obj->ymin, ymax = obj->ymax; + + if (!muiGetVisible(obj)) { +/* + int sl = 0; + font(BUTTONFONT1); + if (b->str) sl = strwidth(b->str); + backgrounddraw(b->xmin,b->ymin,b->xmin+30+sl,b->ymax); +*/ + return; + } + + if (muiGetEnable(obj)) { + if (obj->locate) { + if (obj->select) { + if (obj->active) { + uiDkGray(); + uipmv2i(xmin,ymin+10); uipdr2i(xmin,ymin+13); + uipdr2i(xmin+10,ymax); + uipdr2i(xmin+13,ymax); uipdr2i(xmax,ymin+13); uipdr2i(xmax,ymin+10); + uipdr2i(xmin+13,ymin); uipdr2i(xmin+10,ymin); uipclos(); + + uiVyLtGray(); + uipmv2i(xmin+1,ymin+11); uipdr2i(xmin+1,ymin+13); + uipdr2i(xmin+10,ymax-1); uipdr2i(xmin+13,ymax-1); + uipdr2i(xmax-1,ymin+13); uipdr2i(xmax-1,ymin+11); + uipdr2i(xmin+13,ymin+2); uipdr2i(xmin+10,ymin+2); + uipclos(); + + uiWhite(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + uimove2i(xmin+1,ymin+13); uidraw2i(xmin+10,ymax-1); + uidraw2i(xmin+13,ymax-1); uidraw2i(xmax-1,ymin+13); + uiendline(); + + } else { + + uiDkGray(); + uimove2i(xmin,ymin+13); uidraw2i(xmin+10,ymax); + uidraw2i(xmin+13,ymax); uidraw2i(xmax,ymin+13); + uiendline(); + uimove2i(xmin,ymin+12); uidraw2i(xmin+10,ymax-1); + uidraw2i(xmin+13,ymax-1); uidraw2i(xmax,ymin+12); + uiendline(); + + uiLtGray(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + + uiWhite(); + uimove2i(xmin+2,ymin+12); uidraw2i(xmin+11,ymax-2); + uidraw2i(xmin+12,ymax-2); uidraw2i(xmax-2,ymin+12); + uiendline(); + uimove2i(xmin+3,ymin+12); uidraw2i(xmin+11,ymax-3); + uidraw2i(xmin+12,ymax-3); uidraw2i(xmax-3,ymin+12); + uiendline(); + + uiVyLtGray(); + uipmv2i(xmin+4,ymin+12); uipdr2i(xmin+11,ymax-4); + uipdr2i(xmin+12,ymax-4); uipdr2i(xmax-4,ymin+12); + uipdr2i(xmin+12,ymin+5); uipdr2i(xmin+11,ymin+5); + uipclos(); + + uiLtGray(); + uimove2i(xmin+3,ymin+11); uidraw2i(xmin+11,ymin+3); + uidraw2i(xmin+12,ymin+3); uidraw2i(xmax-3,ymin+11); + uiendline(); + uimove2i(xmin+4,ymin+11); uidraw2i(xmin+11,ymin+4); + uidraw2i(xmin+12,ymin+4); uidraw2i(xmax-4,ymin+11); + uiendline(); + + uiBlack(); + uimove2i(xmin+2,ymin+11); uidraw2i(xmin+11,ymin+2); + uidraw2i(xmin+12,ymin+2); uidraw2i(xmax-2,ymin+11); + uiendline(); + + uiWhite(); + uimove2i(xmin,ymin+10); uidraw2i(xmin+10,ymin); + uidraw2i(xmin+13,ymin); uidraw2i(xmax,ymin+10); + uiendline(); + uimove2i(xmin,ymin+11); uidraw2i(xmin+10,ymin+1); + uidraw2i(xmin+13,ymin+1);uidraw2i(xmax,ymin+11); + uiendline(); + uimove2i(xmin+1,ymin+11);uidraw2i(xmin+10,ymin+2); + uimove2i(xmin+13,ymin+2);uidraw2i(xmax-1,ymin+11); + uiendline(); + } + + } else { /* not selected */ + + if (obj->active) { + + uiDkGray(); + uimove2i(xmin,ymin+13); uidraw2i(xmin+10,ymax); + uidraw2i(xmin+13,ymax); uidraw2i(xmax,ymin+13); + uiendline(); + uimove2i(xmin,ymin+12); uidraw2i(xmin+10,ymax-1); + uidraw2i(xmin+13,ymax-1); uidraw2i(xmax,ymin+12); + uiendline(); + + uiLtGray(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + + uiWhite(); + uimove2i(xmin+2,ymin+12); uidraw2i(xmin+11,ymax-2); + uidraw2i(xmin+12,ymax-2); uidraw2i(xmax-2,ymin+12); + uiendline(); + uimove2i(xmin+3,ymin+12); uidraw2i(xmin+11,ymax-3); + uidraw2i(xmin+12,ymax-3); uidraw2i(xmax-3,ymin+12); + uiendline(); + + uiVyLtGray(); + uipmv2i(xmin+4,ymin+12); uipdr2i(xmin+11,ymax-4); + uipdr2i(xmin+12,ymax-4); uipdr2i(xmax-4,ymin+12); + uipdr2i(xmin+12,ymin+5); uipdr2i(xmin+11,ymin+5); + uipclos(); + + uiLtGray(); + uimove2i(xmin+3,ymin+11); uidraw2i(xmin+11,ymin+3); + uidraw2i(xmin+12,ymin+3); uidraw2i(xmax-3,ymin+11); + uiendline(); + uimove2i(xmin+4,ymin+11); uidraw2i(xmin+11,ymin+4); + uidraw2i(xmin+12,ymin+4); uidraw2i(xmax-4,ymin+11); + uiendline(); + + uiBlack(); + uimove2i(xmin+2,ymin+11); uidraw2i(xmin+11,ymin+2); + uidraw2i(xmin+12,ymin+2); uidraw2i(xmax-2,ymin+11); + uiendline(); + + uiWhite(); + uimove2i(xmin,ymin+10); uidraw2i(xmin+10,ymin); + uidraw2i(xmin+13,ymin); uidraw2i(xmax,ymin+10); + uiendline(); + uimove2i(xmin,ymin+11); uidraw2i(xmin+10,ymin+1); + uidraw2i(xmin+13,ymin+1);uidraw2i(xmax,ymin+11); + uiendline(); + uimove2i(xmin+1,ymin+11);uidraw2i(xmin+10,ymin+2); + uimove2i(xmin+13,ymin+2);uidraw2i(xmax-1,ymin+11); + uiendline(); + + } else { /* not active */ + + uiDkGray(); + uipmv2i(xmin,ymin+10); uipdr2i(xmin,ymin+13); + uipdr2i(xmin+10,ymax); + uipdr2i(xmin+13,ymax); uipdr2i(xmax,ymin+13); uipdr2i(xmax,ymin+10); + uipdr2i(xmin+13,ymin); uipdr2i(xmin+10,ymin); uipclos(); + + uiVyLtGray(); + uipmv2i(xmin+1,ymin+11); uipdr2i(xmin+1,ymin+13); + uipdr2i(xmin+10,ymax-1); uipdr2i(xmin+13,ymax-1); + uipdr2i(xmax-1,ymin+13); uipdr2i(xmax-1,ymin+11); + uipdr2i(xmin+13,ymin+2); uipdr2i(xmin+10,ymin+2); + uipclos(); + + uiWhite(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + uimove2i(xmin+1,ymin+13); uidraw2i(xmin+10,ymax-1); + uidraw2i(xmin+13,ymax-1); uidraw2i(xmax-1,ymin+13); + uiendline(); + } + } + + } else { /* not located */ + + if (obj->active) { + + uiDkGray(); + uimove2i(xmin,ymin+13); uidraw2i(xmin+10,ymax); + uidraw2i(xmin+13,ymax); uidraw2i(xmax,ymin+13); + uiendline(); + uimove2i(xmin,ymin+12); uidraw2i(xmin+10,ymax-1); + uidraw2i(xmin+13,ymax-1); uidraw2i(xmax,ymin+12); + uiendline(); + + uiLtGray(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + + uiWhite(); + uimove2i(xmin+2,ymin+12); uidraw2i(xmin+11,ymax-2); + uidraw2i(xmin+12,ymax-2); uidraw2i(xmax-2,ymin+12); + uiendline(); + uimove2i(xmin+3,ymin+12); uidraw2i(xmin+11,ymax-3); + uidraw2i(xmin+12,ymax-3); uidraw2i(xmax-3,ymin+12); + uiendline(); + + uiLtGray(); + uipmv2i(xmin+4,ymin+12); uipdr2i(xmin+11,ymax-4); + uipdr2i(xmin+12,ymax-4); uipdr2i(xmax-4,ymin+12); + uipdr2i(xmin+12,ymin+5); uipdr2i(xmin+11,ymin+5); uipclos(); + + uiLtGray(); + uimove2i(xmin+3,ymin+11); uidraw2i(xmin+11,ymin+3); + uidraw2i(xmin+12,ymin+3); uidraw2i(xmax-3,ymin+11); + uiendline(); + uimove2i(xmin+4,ymin+11); uidraw2i(xmin+11,ymin+4); + uidraw2i(xmin+12,ymin+4); uidraw2i(xmax-4,ymin+11); + uiendline(); + + uiBlack(); + uimove2i(xmin+2,ymin+11); uidraw2i(xmin+11,ymin+2); + uidraw2i(xmin+12,ymin+2); uidraw2i(xmax-2,ymin+11); + uiendline(); + + uiWhite(); + uimove2i(xmin,ymin+10); uidraw2i(xmin+10,ymin); + uidraw2i(xmin+13,ymin); uidraw2i(xmax,ymin+10); + uiendline(); + uimove2i(xmin,ymin+11); uidraw2i(xmin+10,ymin+1); + uidraw2i(xmin+13,ymin+1);uidraw2i(xmax,ymin+11); + uiendline(); + uimove2i(xmin+1,ymin+11);uidraw2i(xmin+10,ymin+2); + uimove2i(xmin+13,ymin+2);uidraw2i(xmax-1,ymin+11); + uiendline(); + + } else { + + uiDkGray(); + uipmv2i(xmin,ymin+10); uipdr2i(xmin,ymin+13); + uipdr2i(xmin+10,ymax); + uipdr2i(xmin+13,ymax); uipdr2i(xmax,ymin+13); + uipdr2i(xmax,ymin+10); + uipdr2i(xmin+13,ymin); uipdr2i(xmin+10,ymin); uipclos(); + + uiLtGray(); + uipmv2i(xmin+1,ymin+11); uipdr2i(xmin+1,ymin+13); + uipdr2i(xmin+10,ymax-1); uipdr2i(xmin+13,ymax-1); + uipdr2i(xmax-1,ymin+13); uipdr2i(xmax-1,ymin+11); + uipdr2i(xmin+13,ymin+2); uipdr2i(xmin+10,ymin+2); uipclos(); + + uiWhite(); + uimove2i(xmin+1,ymin+12); uidraw2i(xmin+11,ymax-1); + uidraw2i(xmin+12,ymax-1); uidraw2i(xmax-1,ymin+12); + uiendline(); + } + } + + } else { /* not enabled */ + uiDkGray(); + uipmv2i(xmin,ymin+10); uipdr2i(xmin,ymin+13); uipdr2i(xmin+10,ymax); + uipdr2i(xmin+13,ymax); uipdr2i(xmax,ymin+13); uipdr2i(xmax,ymin+10); + uipdr2i(xmin+13,ymin); uipdr2i(xmin+10,ymin); uipclos(); + + uiLtGray(); + uipmv2i(xmin+1,ymin+10); uipdr2i(xmin+1,ymin+13); + uipdr2i(xmin+10,ymax-1); uipdr2i(xmin+13,ymax-1); + uipdr2i(xmax-1,ymin+13); uipdr2i(xmax-1,ymin+10); + uipdr2i(xmin+13,ymin+1); uipdr2i(xmin+10,ymin+1); uipclos(); + } + + if (obj->active) { + if (muiGetEnable(obj)) { + uiSlateBlue(); + uipmv2i(xmin+12,ymax-5); uipdr2i(xmax-6,ymin+13); + uipdr2i(xmax-8,ymin+13); uipdr2i(xmin+12,ymax-7); uipclos(); + + uiBlue(); + uipmv2i(xmin+12,ymax-8); uipdr2i(xmax-9,ymin+13); + uipdr2i(xmax-9,ymin+12); uipdr2i(xmin+12,ymin+10); uipclos(); + + uiBlack(); + uipmv2i(xmin+12,ymin+9); uipdr2i(xmin+15,ymin+12); + uipdr2i(xmax-6,ymin+12); uipdr2i(xmin+13,ymin+8); + uipdr2i(xmin+12,ymin+8); uipclos(); + + uiDkGray(); + uimove2i(xmin+13,ymin+7); uidraw2i(xmax-5,ymin+12); + uiendline(); + } else { + uiSlateBlue(); + uipmv2i(xmin+12,ymax-5); uipdr2i(xmax-6,ymin+13); + uipdr2i(xmax-6,ymin+12); uipdr2i(xmin+13,ymin+8); + uipdr2i(xmin+12,ymin+8); uipclos(); + + uiBlack(); + uimove2i(xmin+13,ymin+7); uidraw2i(xmax-5,ymin+12); + uiendline(); + } + } + drawbuttonlabel(obj); +} + +void drawtinyradio(muiObject *obj) +{ + int xmin = obj->xmin, xmax = obj->xmax, + ymin = obj->ymin, ymax = obj->ymax; + int sxmin = obj->xmin+4, sxmax = obj->xmin+13, sxmid = obj->xmin+8, + symin = obj->ymin+3, symax = obj->ymin+12, symid = obj->ymin+7; + + if (!muiGetVisible(obj)) { + backgrounddraw(obj->xmin,obj->ymin,obj->xmax,obj->ymax); + return; + } + + if (muiGetEnable(obj) && obj->locate) { + if (obj->select) { + drawedges(xmin++,xmax--,ymin++,ymax--,uiBlack,uiWhite); + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiBlack); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiMmGray); + + uiVyLtGray(); + uirectfi(xmin,ymin,xmax,ymax); + } else { + uiWhite(); + uirectfi(xmin,ymin,xmax,ymax); + } + } else { + uiBackground(); + uirectfi(xmin,ymin,xmax,ymax); + } + + + uiBlack(); + uipmv2i(sxmin, symid); uipdr2i(sxmin++, symid+1); + uipdr2i(sxmid, symax); uipdr2i(sxmid+1, symax--); uipdr2i(sxmax, symid+1); + uipclos(); + + uiLtGray(); + uipmv2i(sxmax--, symid); uipdr2i(sxmid+1, symin); + uipdr2i(sxmid, symin++); uipdr2i(sxmin, symid-1); + uipclos(); + + if (obj->active) { + if (!muiGetEnable(obj)) + uiLtYellow(); + else + uiYellow(); + } else { + if (!muiGetEnable(obj)) + uiMmGray(); + else if (obj->locate) + uiMmYellow(); + else + uiDkYellow(); + } + uipmv2i(sxmin, symid); uipdr2i(sxmin, symid+1); + uipdr2i(sxmid, symax); uipdr2i(sxmid+1, symax); uipdr2i(sxmax, symid+1); + uipdr2i(sxmax, symid); uipdr2i(sxmid+1, symin); uipdr2i(sxmid, symin); + uipclos(); + + drawbuttonlabel(obj); +} + diff --git a/lib/glut-3.7.6/lib/mui/dirent32.h b/lib/glut-3.7.6/lib/mui/dirent32.h new file mode 100644 index 0000000000..02608c4b32 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/dirent32.h @@ -0,0 +1,96 @@ +/* + + Win32 lacks unix dirent support. But, we can fake it. Many + thanks to Dave Lubrik (lubrik@jaka.ece.uiuc.edu) who found and + fixed many bugs in the original code. + + */ + + +#ifndef _WIN32 +#include +#else + +#include + + + +struct dirent { + char d_name[MAX_PATH]; +}; + +typedef struct { + WIN32_FIND_DATA wfd; + HANDLE hFind; + struct dirent de; +} DIR; + + +static DIR * +opendir(char *pSpec) +{ + DIR *pDir = malloc(sizeof(DIR)); + char pathnamespec[MAX_PATH]; + int l; /* length of directory specifier */ + char c; /* last char of directory specifier */ + + /* Given a directory pathname in pSpec, add \ (if necessary) and * + to yield a globbable expression describing all the files in that + directory */ + strcpy(pathnamespec, pSpec); + + /* Add a \ to separate the directory name from the filename-wildcard + "*", unless it already ends in a \ (don't create \\ sequences), + or it is a drivespec (since "C:*" differs in meaning from "C:\*") */ + if (((l = strlen(pSpec)) > 0) && ((c = pSpec[l-1]) != '\\') && (c != ':')) + strcat(pathnamespec, "\\"); + + /* Add the filename wildcard "*" */ + strcat(pathnamespec,"*"); + + /* Find files matching that expression (all the files in that + directory) */ + pDir->hFind = FindFirstFile(pathnamespec, &pDir->wfd); + + return pDir; +} + + +/* closedir takes a pointer to a DIR structure created by opendir, and + frees up resources allocated by opendir. Call it when done with a + directory. */ +static void +closedir(DIR * pDir) +{ + FindClose(pDir->hFind); /* Release system resources */ + free(pDir); /* release memory */ +} + +/* readdir is used to iterate through the files in a directory. It + takes a pointer to a DIR structure created by opendir, and each + time it is called it returns the name of another file in the + directory passed to opendir. Returns: a pointer to a dirent + structure, containing the file name. NULL if there are no more + files in the directory. */ +static struct dirent * +readdir(DIR *pDir) +{ + /* The previous call to opendir or readdir has already found the next + file (using FindFirstFile or FindNextFile respectively). Return + that file name to the caller, and silently find the next one. */ + + if (*(pDir->wfd.cFileName)) { /* If we haven't exhausted the files */ + strcpy(pDir->de.d_name, pDir->wfd.cFileName); /* copy name */ + + if (!FindNextFile(pDir->hFind, &pDir->wfd)) /* get next */ + *(pDir->wfd.cFileName) = 0; + /* if no more, zero next filename, so that next time through, + we don't even try. */ + + return &pDir->de; /* return dirent struct w/filename */ + } + + return NULL; /* No more files to find. */ +} + +#endif diff --git a/lib/glut-3.7.6/lib/mui/displaylist.c b/lib/glut-3.7.6/lib/mui/displaylist.c new file mode 100644 index 0000000000..64cf3edb0d --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/displaylist.c @@ -0,0 +1,154 @@ +/* + * 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. + */ + +#include +#include +#include + +#define MOVE2I 1 +#define DRAW2I 2 +#define RECTFI 3 +#define CMOV2I 4 +#define CHARSTR 5 +#define PMV2I 6 +#define PDR2I 7 +#define PCLOS 8 +#define RECTI 9 +#define CLEAR 10 +#define ENDLINE 11 +#define PUSHVP 12 +#define POPVP 13 +#define VP 14 + +extern short ditherflag; + +void charstr(char *s, int font) +{ + int len = (int) strlen(s); + int i; + void **f; + switch(font) { + case UI_FONT_BOLD: + case UI_FONT_NORMAL: + f = GLUT_BITMAP_HELVETICA_12; + break; + case UI_FONT_FIXED_PITCH: + f = GLUT_BITMAP_9_BY_15; + break; + } + for (i = 0; i < len; i++) + glutBitmapCharacter(f, s[i]); +} + +void uipushviewport(void) +{ +} + +void uipopviewport(void) +{ + glDisable(GL_SCISSOR_TEST); +} + +void uiviewport(int x, int y, int width, int height) +{ + glScissor(x, y, width, height); + glEnable(GL_SCISSOR_TEST); +} + +void uicharstr(char *s, int font) +{ + charstr(s, font); +} + +void uirecti(int x, int y, int z, int w) +{ + glBegin(GL_LINE_LOOP); + glVertex2i(x, y); + glVertex2i(x, w); + glVertex2i(z, w); + glVertex2i(z, y); + glEnd(); +} + +void uirectfi(int x, int y, int x1, int y1) +{ + glRecti(x, y, x1, y1); +} + +void uipclos(void) +{ + glEnd(); +} + +void uiclear(void) +{ + glClearColor(214.0/255.0, 214.0/255.0, 214.0/255.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); +} + +void uipdr2i(int x, int y) +{ + glVertex2i(x, y); +} + +void uipmv2i(int x, int y) +{ + glBegin(GL_POLYGON); + glVertex2i(x, y); +} + +void uicmov2i(int x, int y) +{ + glRasterPos2i(x, y); +} + +void uidraw2i(int x, int y) +{ + glVertex2i(x, y); +} + +void uiendline(void) +{ + glEnd(); +} + +void uimove2i(int x, int y) +{ + glBegin(GL_LINE_STRIP); + glVertex2i(x, y); +} + diff --git a/lib/glut-3.7.6/lib/mui/gizmo.c b/lib/glut-3.7.6/lib/mui/gizmo.c new file mode 100644 index 0000000000..14ee1cd121 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/gizmo.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 1992, 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. + */ + + /* jot text editor source code. */ + /* Tom Davis */ + /* February 7, 1992 */ + +#include +#include +#include +#include +#include +#include + +#define BUTTONUP 0 +#define BUTTONDOWN 1 +#define BUTTONCLICK 2 +#define BUTTONDOUBLE 3 + +void drawtb(muiObject *); + +int definescaledfont = 0; +char *tmpfilename; + +/* NEW BUTTON PROCEDURES */ + +int strwidth(char *s) +{ + int len = 0; + while (*s) { + len += glutBitmapWidth(GLUT_BITMAP_HELVETICA_12, *s++); + } + return len; +} + +Button *newbut(void) +{ + Button *b; + b = newbed(); + b->type = BUTTON; + b->link = 0; + return b; +} + +Button *newradiobut(void) +{ + Button *b; + b = newbed(); + b->type = RADIOBUTTON; + b->link = 0; + return b; +} + +Button *newbed(void) +{ + Button *b; + + b = (Button *)malloc(sizeof(Button)); + b->str[0] = 0; + b->type = BED; + return b; +} + +void muiLoadButton(muiObject *b, char *s) +{ + int temp; + Button *but = (Button *)b->object; + + strcpy(but->str, s); + switch (but->type) { + case PUSHBUTTON: + temp = b->xmin + strwidth(but->str) + 20; + if (temp > b->xmax) + b->xmax = temp; + break; + default: + break; + } +} + +void drawbuttonbackground(muiObject *b) +{ + int xmin = b->xmin, xmax = b->xmax, ymin = b->ymin, ymax = b->ymax; + + if (b->locate) { + if (b->select) { + drawedges(xmin++,xmax--,ymin++,ymax--,uiVyDkGray,uiWhite); + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiWhite); + drawedges(xmin++,xmax--,ymin++,ymax--,uiLtGray,uiBlack); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiLtGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiVyLtGray); + } else { + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiVyDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiLtGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiLtGray); + } + } else { + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiVyDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiVyLtGray,uiMmGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiVyLtGray,uiMmGray); + } + (b->locate)?uiVyLtGray():uiLtGray(); + uirectfi(xmin,ymin,xmax+1,ymax+1); +} + +void drawpushbut(muiObject *b) +{ + Button *but = (Button *)b->object; + + drawbuttonbackground(b); + uiBlack(); + uicmov2i(b->xmin+ (b->xmax - b->xmin - strwidth(but->str))/2 + 1, b->ymin+9); + uicharstr(but->str, UI_FONT_NORMAL); +} + +void drawbut(muiObject *b) +{ + switch(b->type) { + case BUTTON: + case PUSHBUTTON: + drawpushbut(b); + break; + case BED: + break; + default: + drawpushbut(b); + break; + } +} + +void muiChangeLabel(muiObject *obj, char *s) +{ + Label *l; + + if (obj->type != MUI_LABEL && obj->type != MUI_BOLDLABEL) + muiError("muiChangeLabel: not a label"); + l = (Label *)obj->object; + strncpy(l->str, s, LABELSTRLEN); + l->str[LABELSTRLEN] = 0; + return; +} + +Label *newlabel(char *s) +{ + Label *l = (Label *)malloc(sizeof(Label)); + strncpy(l->str, s, LABELSTRLEN); + l->str[LABELSTRLEN] = 0; + return l; +} + +TextBox *activetb = 0; + +TextBox *newtb(int xmin, int xmax) +{ + TextBox *tb; + static int inited = 0; + + if (!inited) { + inited = 1; + } + + tb = (TextBox *)malloc(sizeof(TextBox)); + tb->charWidth = (xmax - xmin - 9)/FONTWIDTH; + tb->tp1 = tb->tp2 = 0; + *tb->str = 0; + *tb->label = 0; + return tb; +} + +char *muiGetTBString(muiObject *obj) +{ + TextBox *tb = (TextBox *)obj->object; + return tb->str; +} + +void muiClearTBString(muiObject *obj) +{ + TextBox *tb = (TextBox *)obj->object; + *tb->str = 0; + tb->tp1 = tb->tp2 = 0; +} + +void loadtb(TextBox *tb, char *s) +{ + if (s == 0) + *tb->str = 0; + else + strcpy(tb->str, s); + tb->tp1 = tb->tp2 = (int) strlen(s); +} + +void muiSetTBString(muiObject *obj, char *s) +{ + TextBox *tb = (TextBox *)obj->object; + loadtb(tb, s); +} + +void backspacetb(TextBox *tb) +{ + char *s1, *s2, *stemp; + + if ((tb->tp1 == tb->tp2) && tb->tp1 > 0) { + s1 = &tb->str[tb->tp1-1]; + while (*s1) { + *s1 = *(s1+1); + s1++; + } + tb->tp1--; tb->tp2--; + return; + } + s1 = &tb->str[tb->tp1]; + s2 = &tb->str[tb->tp2]; + if (s1 > s2) { stemp = s1; s1 = s2; s2 = stemp; } + stemp = s1; + while (*s2) {*s1++ = *s2++;} + *s1 = 0; + tb->tp1 = tb->tp2 = (int) (stemp - tb->str); +} + +void inserttbchar(TextBox *tb, char c) +{ + char *s1, *s2; + int len; + + if (tb->tp1 != tb->tp2) backspacetb(tb); + len = (int) strlen(tb->str); + if (len == TBSTRLEN) return; + s1 = &tb->str[tb->tp1]; + s2 = &tb->str[len+1]; + while (s2 != s1) { + *s2 = *(s2 - 1); + s2--; + } + *s1 = c; + tb->tp1++; tb->tp2++; +} + +int findtp(muiObject *obj, int x) +{ + TextBox *tb = (TextBox *)obj->object; + int tp, sl = (int) strlen(tb->str); + + tp = (x - obj->xmin)/FONTWIDTH; + if (tp < 0) tp = 0; + if (tp > tb->charWidth) tp = tb->charWidth; + if (tp > sl) tp = sl; + return tp; +} + +void drawtbcontents(muiObject *obj) +{ + int xmin = obj->xmin, ymin = obj->ymin; + int ymax = ymin+TEXTBOXHEIGHT; + int s1, s2; + char str[160], *s; + TextBox *tb = (TextBox *)obj->object; + + strncpy(str, tb->str, (unsigned int)tb->charWidth); + for (s = str; *s; s++) + if (*s < ' ' || *s >= '\177') *s = '*'; + str[tb->charWidth] = 0; + s1 = tb->tp1; s2 = tb->tp2; + if (s1 > tb->charWidth) s1 = tb->charWidth; + if (s2 > tb->charWidth) s2 = tb->charWidth; + + /* selected area */ + if (obj->active && (s1 != s2)) { + uiVyLtGray(); + uirectfi(xmin+6+FONTWIDTH*s1, ymin+7, xmin+6+FONTWIDTH*s2, ymax-6); + } + + /* contents of text box */ + if (muiGetEnable(obj)) uiBlack(); else uiDkGray(); + uicmov2i(xmin+6, ymin+9); + uicharstr(str, UI_FONT_FIXED_PITCH); + + /* Blue bar */ + if ((obj->active == 0) || (obj->enable == 0) || (s1 != s2)) return; + uiBlue(); + uimove2i(xmin+4+FONTWIDTH*s1, ymin+7); uidraw2i(xmin+4+FONTWIDTH*s1, ymax-6); uiendline(); + uimove2i(xmin+5+FONTWIDTH*s1, ymin+7); uidraw2i(xmin+5+FONTWIDTH*s1, ymax-6); uiendline(); +} + +void drawtb(muiObject *tb) +{ + int xmin = tb->xmin, xmax = tb->xmax, ymin = tb->ymin; + int ymax = ymin+TEXTBOXHEIGHT; + + if(!muiGetVisible(tb)) return; + + if( muiGetEnable(tb) ) { + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiWhite); + drawedges(xmin++,xmax--,ymin++,ymax--,uiBlack,uiVyLtGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiLtGray,uiDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiTerraCotta,uiTerraCotta); + uiTerraCotta(); + } + else { + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiWhite); + drawedges(xmin++,xmax--,ymin++,ymax--,uiMmGray,uiVyLtGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiLtGray,uiDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiLtGray,uiDkGray); + uiLtGray(); + } + uirectfi(xmin, ymin, xmax+1, ymax+1); + + drawtbcontents(tb); +} + +void muiActivateTB(muiObject *obj) +{ + muiCons *mcons; + + if ((mcons = muiGetListCons(muiGetUIList(obj))) == (muiCons *)0) return; + muiSetActive(obj, 1); + while (mcons) { + if (mcons->object != obj && mcons->object->type == MUI_TEXTBOX) + muiSetActive(mcons->object, 0); + mcons = mcons->next; + } +} + +muiObject *muiGetActiveTB(void) +{ + muiCons *mcons; + int list = muiGetActiveUIList(); + + if (list == 0) return 0; + if ((mcons = muiGetListCons(list)) == (muiCons *)0) return 0; + while (mcons) { + if (mcons->object->type == MUI_TEXTBOX && muiGetActive(mcons->object)) + return mcons->object; + mcons = mcons->next; + } + return 0; +} + +enum muiReturnValue textboxhandler(muiObject *obj, int event, int value, int x, int y) +{ + int tp; + TextBox *tb = (TextBox *)obj->object; + + if( !muiGetEnable(obj) || !muiGetVisible(obj) ) return MUI_NO_ACTION; + + switch (event) { + case MUI_DEVICE_DOWN: + tp = findtp(obj, x); + tb->tp2 = tp; + break; + case MUI_DEVICE_UP: + break; + case MUI_DEVICE_PRESS: + muiActivateTB(obj); + tp = findtp(obj, x); + tb->tp1 = tb->tp2 = tp; + break; + case MUI_DEVICE_RELEASE: + break; + case MUI_DEVICE_CLICK: + case MUI_DEVICE_DOUBLE_CLICK: + muiActivateTB(obj); + tp = findtp(obj, x); + tb->tp1 = tb->tp2 = tp; + break; + case MUI_KEYSTROKE: + if (value == '\n' || value == '\r') /* carriage return */ + return MUI_TEXTBOX_RETURN; + if (value == '\025') { muiClearTBString(obj); } + else if (value == '\b') { backspacetb((TextBox *)obj->object); } + else inserttbchar((TextBox *)obj->object, (char)value); + break; + } + x = y; /* for lint's sake */ + return MUI_NO_ACTION; +} + +void helpdrawlabel(char *s, int x, int y) +{ + uiBlack(); + uicmov2i(x, y); + uicharstr(s, UI_FONT_NORMAL); +} + +void helpdrawboldlabel(char *s, int x, int y) +{ + uiBlack(); /* XXX Hack! -- no bold font in GLUT */ + uicmov2i(x, y); + uicharstr(s, UI_FONT_NORMAL); + uicmov2i(x+1, y); + uicharstr(s, UI_FONT_NORMAL); +} + +void drawlabel(muiObject *lab) +{ + Label *l = (Label *)lab->object; + if(!muiGetVisible(lab)) return; + if(muiGetEnable(lab)) uiBlack(); else uiDkGray(); + uicmov2i(lab->xmin, lab->ymin); + uicharstr(l->str, UI_FONT_NORMAL); +} + +void drawboldlabel(muiObject *lab) +{ + Label *l = (Label *)lab->object; + if(!muiGetVisible(lab)) return; + if(muiGetEnable(lab)) uiBlack(); else uiDkGray(); + uicmov2i(lab->xmin, lab->ymin); /* XXX Hack! -- no bold font in GLUT */ + uicharstr(l->str, UI_FONT_NORMAL); + uicmov2i(lab->xmin+1, lab->ymin); + uicharstr(l->str, UI_FONT_NORMAL); +} diff --git a/lib/glut-3.7.6/lib/mui/glutmui.c b/lib/glut-3.7.6/lib/mui/glutmui.c new file mode 100644 index 0000000000..e6db10842e --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/glutmui.c @@ -0,0 +1,184 @@ +/* + * 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. + */ + +#include +#include +#include + +typedef struct _Window { + int mui_xorg, mui_yorg, mui_xsize, mui_ysize; + int uilist; + int mbleft; +} WindowRec, *Window; + +static Window winList = NULL; +static int numWins = 0; + +int mui_singlebuffered = 0; + +int menuinuse = 0; + +static int mbmiddle = 0, mbright = 0; /* XXX unused currently */ + +void setmousebuttons(int b, int s) +{ + Window win = &winList[glutGetWindow()-1]; + + switch (b) { + case GLUT_LEFT_BUTTON: + win->mbleft = (s == GLUT_DOWN); + break; + case GLUT_MIDDLE_BUTTON: + mbmiddle =(s == GLUT_DOWN); + break; + case GLUT_RIGHT_BUTTON: + mbright =(s == GLUT_DOWN); + break; + } +} + +void mui_drawgeom(void) +{ + Window win = &winList[glutGetWindow()-1]; + + glViewport(0, 0, win->mui_xsize, win->mui_ysize); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, win->mui_xsize, 0, win->mui_ysize); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + muiDrawUIList(win->uilist); + if (mui_singlebuffered == 0) + glutSwapBuffers(); + else + glFlush(); +} + +void mui_keyboard(unsigned char c, int x, int y) +{ + Window win = &winList[glutGetWindow()-1]; + + muiSetActiveUIList(win->uilist); + muiHandleEvent(MUI_KEYSTROKE, c, x, win->mui_ysize-y); + glutPostRedisplay(); +} + +void mui_mouse(int b, int s, int x, int y) +{ + Window win = &winList[glutGetWindow()-1]; + + muiSetActiveUIList(win->uilist); + setmousebuttons(b, s); + if (b == GLUT_MIDDLE_BUTTON && s == GLUT_DOWN) { + muiHandleEvent(MUI_DEVICE_DOUBLE_CLICK, 0, x, win->mui_ysize-y); + glutPostRedisplay(); + } + if (b != GLUT_LEFT_BUTTON) { return; } + muiHandleEvent((s==GLUT_DOWN)?MUI_DEVICE_PRESS:MUI_DEVICE_RELEASE, 0, x, win->mui_ysize-y); + glutPostRedisplay(); +} + +static void mui_Reshape(int width, int height) +{ + Window win = &winList[glutGetWindow()-1]; + + win->mui_xorg = glutGet(GLUT_WINDOW_X); + win->mui_yorg = glutGet(GLUT_WINDOW_Y); + win->mui_xsize = width; + win->mui_ysize = height; + glViewport(0, 0, win->mui_xsize, win->mui_ysize); +} + +void mui_glutmotion(int x, int y) +{ + Window win = &winList[glutGetWindow()-1]; + + muiSetActiveUIList(win->uilist); + if (win->mbleft == 0) return; + muiHandleEvent(MUI_DEVICE_DOWN, 0, x, win->mui_ysize-y); + glutPostRedisplay(); +} + +void mui_glutpassivemotion(int x, int y) +{ + Window win = &winList[glutGetWindow()-1]; + + muiSetActiveUIList(win->uilist); + muiHandleEvent(MUI_DEVICE_UP, 0, x, win->mui_ysize-y); + glutPostRedisplay(); +} + +void mui_menufunc(int state) +{ + menuinuse = state; +} + +void muiInit(void) +{ + int winNum = glutGetWindow(); + Window win; + + if (winNum >= numWins) { + numWins = winNum; + winList = (Window) realloc(winList, numWins * sizeof(WindowRec)); + } + win = &winList[glutGetWindow()-1]; + win->mui_xorg = glutGet(GLUT_WINDOW_X); + win->mui_yorg = glutGet(GLUT_WINDOW_Y); + win->mui_xsize = glutGet(GLUT_WINDOW_WIDTH); + win->mui_ysize = glutGet(GLUT_WINDOW_HEIGHT);; + win->mbleft = 0; + /* The "uilist = 1" is for compatibility with GLUT 3.5's MUI + implementation that was hardwired to support a single window + only with UI list 1. */ + win->uilist = 1; + + glutKeyboardFunc(mui_keyboard); + glutMouseFunc(mui_mouse); + glutReshapeFunc(mui_Reshape); + glutMotionFunc(mui_glutmotion); + glutPassiveMotionFunc(mui_glutpassivemotion); + glutDisplayFunc(mui_drawgeom); + glutMenuStateFunc(mui_menufunc); +} + +void muiAttachUIList(int uilist) +{ + Window win = &winList[glutGetWindow()-1]; + + win->uilist = uilist; +} diff --git a/lib/glut-3.7.6/lib/mui/hslider.c b/lib/glut-3.7.6/lib/mui/hslider.c new file mode 100644 index 0000000000..24db16a5c9 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/hslider.c @@ -0,0 +1,488 @@ +/* + * Copyright (c) 1990,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. + */ + +#include +#include +#include +#include +#include +#include + +extern HSlider *locatedhs; + +int gethstrough(muiObject *obj) +{ + return obj->xmax - obj->xmin - 2*ARROWHEIGHT; +} + +void sethscenter(muiObject *obj, int scenter) +{ + HSlider *hs = (HSlider *)obj->object; + if ((scenter - hs->shalf) < (obj->xmin+ARROWHEIGHT)) + hs->scenter = gethstrough(obj)/2 + obj->xmin+ARROWHEIGHT; + else + hs->scenter = scenter; +} + +void muiSetHSArrowDelta(muiObject *obj, int newd) +{ + HSlider *hs = (HSlider *)obj->object; + hs->arrowdelta = newd; +} + +HSlider *newhs(muiObject *obj, int xmin, int xmax, int scenter, int shalf) +{ + HSlider *hs; + + hs = (HSlider *)malloc(sizeof(HSlider)); + obj->object = (HSlider *)hs; + if (shalf == 0) { + hs->shalf = 0; + } else if (shalf < MINSHALF) + hs->shalf = MINSHALF; + else + hs->shalf = shalf; + + if ((xmax - xmin + 1) <= (2*ARROWHEIGHT+2*MINSHALF)) + hs->thumb = 0; + else + hs->thumb = 1; + + sethscenter(obj, scenter); + hs->oldpos = hs->scenter; + + muiSetHSArrowDelta(obj, 1); + return hs; +} + +void freehs(HSlider *hs) +{ + if (hs) { + free(hs); + } +} + +void drawhsarrows(muiObject *obj) +{ + int ymin = obj->ymin, ymax = obj->ymin+ARROWHEIGHT, + xmin = obj->xmin, xmax = obj->xmax; + + if (!muiGetVisible(obj)) + return; + + /* Draw the arrows: */ + + /* down arrow */ + uiDkGray(); + uirecti(xmin,ymin,xmin+20,ymax); + + if (muiGetVisible(obj)) { + if (obj->locate == SCROLLDOWN) { + if (obj->select == SCROLLDOWN) { + drawedges(xmin+1,xmin+19,ymin+1,ymax-1,uiMmGray,uiWhite); + drawedges(xmin+2,xmin+18,ymin+2,ymax-2,uiLtGray,uiWhite); + } else { + drawedges(xmin+1,xmin+19,ymin+1,ymax-1,uiWhite,uiMmGray); + drawedges(xmin+2,xmin+18,ymin+2,ymax-2,uiWhite,uiLtGray); + } + uiVyLtGray(); + uirectfi(xmin+3,ymin+3,xmin+17,ymax-3); + } else { + if (obj->select == SCROLLDOWN) { + drawedges(xmin+1,xmin+19,ymin+1,ymax-1,uiMmGray,uiVyLtGray); + drawedges(xmin+2,xmin+18,ymin+2,ymax-2,uiMmGray,uiVyLtGray); + } else { + drawedges(xmin+1,xmin+19,ymin+1,ymax-1,uiWhite,uiMmGray); + drawedges(xmin+2,xmin+18,ymin+2,ymax-2,uiVyLtGray,uiMmGray); + } + uiLtGray(); + uirectfi(xmin+3,ymin+3,xmin+17,ymax-3); + } + } else { + drawedges(xmin+1,xmin+19,ymin+1,ymax-1,uiVyLtGray,uiMmGray); + uiLtGray(); + uirectfi(xmin+2,ymin+2,xmin+18,ymax-2); + } + + /* arrow XXX probably wrong for hsliders XXX */ + if (muiGetEnable(obj)) + uiDkGray(); + else + uiMmGray(); + uimove2i(xmin+14, ymin+5); + uidraw2i(xmin+14, ymin+14); + uiendline(); + uirectfi(xmin+13,ymin+6,xmin+12,ymin+13); + uirectfi(xmin+11,ymin+7,xmin+10,ymin+12); + uirectfi(xmin+8,ymin+8,xmin+9,ymin+11); + uirectfi(xmin+6,ymin+9,xmin+7,ymin+10); + + /* up arrow */ + uiDkGray(); + uirecti(xmax-20,ymin,xmax,ymax); + + if (muiGetEnable(obj)) { + if (obj->locate == SCROLLUP) { + if (obj->select == SCROLLUP) { + drawedges(xmax-19,xmax-1,ymin+1,ymax-1,uiMmGray,uiWhite); + drawedges(xmax-18,xmax-2,ymin+2,ymax-2,uiLtGray,uiWhite); + } else { + drawedges(xmax-19,xmax-1,ymin+1,ymax-1,uiWhite,uiMmGray); + drawedges(xmax-18,xmax-2,ymin+2,ymax-2,uiWhite,uiLtGray); + } + uiVyLtGray(); + uirectfi(xmax-17,ymin+3,xmax-3,ymax-3); + } else { + if (obj->select == SCROLLUP) { + drawedges(xmax-19,xmax-1,ymin+1,ymax-1,uiMmGray,uiVyLtGray); + drawedges(xmax-18,xmax-2,ymin+2,ymax-2,uiMmGray,uiVyLtGray); + } else { + drawedges(xmax-19,xmax-1,ymin+1,ymax-1,uiWhite,uiMmGray); + drawedges(xmax-18,xmax-2,ymin+2,ymax-2,uiVyLtGray,uiMmGray); + } + uiLtGray(); + uirectfi(xmax-17,ymin+3,xmax-3,ymax-3); + } + } else { + drawedges(xmin+1,xmax-1,ymin+1,ymax-1,uiVyLtGray,uiMmGray); + uiLtGray(); + uirectfi(xmax-18,ymin+2,xmax-2,ymax-2); + } + + /* arrow XXX probably wrong for hslider XXX */ + if (muiGetEnable(obj)) + uiDkGray(); + else + uiMmGray(); + uirectfi(xmax-6,ymin+9,xmax-7,ymin+10); + uirectfi(xmax-8,ymin+8,xmax-9,ymin+11); + uirectfi(xmax-10,ymin+7,xmax-11,ymin+12); + uirectfi(xmax-12,ymin+6,xmax-13,ymin+13); + uimove2i(xmax-14, ymin+5); + uidraw2i(xmax-14, ymin+14); + uiendline(); +} + +void drawhs(muiObject *obj) +{ + HSlider *hs = (HSlider *)obj->object; + + int ymin = obj->ymin, xmax = obj->xmax-ARROWHEIGHT, + xmin = obj->xmin+ARROWHEIGHT; + int ymax = ymin+SLIDERWIDTH; + int sxmin = hs->scenter - hs->shalf; + int sxmax = hs->scenter + hs->shalf; + int oldsxmin = hs->oldpos - hs->shalf; + int oldsxmax = hs->oldpos + hs->shalf; + + drawsetup(); + + if (!muiGetVisible(obj)) { + backgrounddraw(xmin,ymin,xmax,ymax); + drawrestore(); + return; + } + + /* trough */ + + uiDkGray(); + uirecti(xmin, ymin, xmax, ymax); + + drawedges(xmin+1,xmax-1,ymin+1,ymax-1,uiVyLtGray,uiMmGray); + + uiLtGray(); + uirectfi(xmin+2, ymin+2, xmax-2, ymax-2); + + if (hs->thumb) { + /* last thumb position */ + if ((hs->oldpos != hs->scenter) && (obj->enable)) { + + uiDkGray(); + uimove2i(oldsxmax, ymax-2); + uidraw2i(oldsxmax, ymin+1); + uiendline(); + + uiMmGray(); + uimove2i(oldsxmax, ymin+1); + uidraw2i(oldsxmin, ymin+1); + uiendline(); + + uiVyLtGray(); + uimove2i(oldsxmin, ymin+2); + uidraw2i(oldsxmin, ymax-1); + uiendline(); + + uiLtGray(); + uimove2i(oldsxmin, ymax-1); + uidraw2i(oldsxmax, ymax-1); + uiendline(); + + uiVyLtGray(); + uimove2i(--oldsxmax, ymax-2); + uidraw2i(++oldsxmin, ymax-2); + uidraw2i(oldsxmin, ymin+2); + uiendline(); + + uiVyDkGray(); + uimove2i(oldsxmin, ymin+2); + uidraw2i(oldsxmax, ymin+2); + uidraw2i(oldsxmax, ymax-3); + uiendline(); + + uiDkGray(); + uimove2i(--oldsxmax, ymin+3); + uidraw2i(oldsxmax, ymax-3); + uiendline(); + + uiLtGray(); + uimove2i(oldsxmax, ymax-3); + uidraw2i(++oldsxmin, ymax-3); + uidraw2i(oldsxmin, ymin+3); + uiendline(); + + uiMmGray(); + uirectfi(++oldsxmin, ymin+3, --oldsxmax, ymax-4); + + } + + if (obj->enable) { + + /* thumb */ + uiDkGray(); + uirecti(sxmin,ymin,sxmax,ymax); + if (obj->locate == THUMB) { + drawedges(sxmin+1,sxmax-1,ymin+1,ymax-1,uiWhite,uiDkGray); + drawedges(sxmin+2,sxmax-2,ymin+2,ymax-2,uiWhite,uiLtGray); + drawedges(sxmin+3,sxmax-3,ymin+3,ymax-3,uiWhite,uiLtGray); + + uiVyLtGray(); + uirectfi(sxmin+4, ymin+4, sxmax-4, ymax-4); + + /* ridges on thumb */ + uiDkGray(); + uimove2i(hs->scenter, ymin+3); + uidraw2i(hs->scenter, ymax-3); + uiendline(); + uimove2i(hs->scenter-4, ymin+3); + uidraw2i(hs->scenter-4, ymax-3); + uiendline(); + uimove2i(hs->scenter+4, ymin+3); + uidraw2i(hs->scenter+4, ymax-3); + uiendline(); + + uiWhite(); + uirectfi(hs->scenter+1,ymin+3,hs->scenter+2,ymax-3); + uirectfi(hs->scenter+5,ymin+3,hs->scenter+6,ymax-3); + uirectfi(hs->scenter-2,ymin+3,hs->scenter-3,ymax-3); + } else { + drawedges(sxmin+1,sxmax-1,ymin+1,ymax-1,uiWhite,uiDkGray); + drawedges(sxmin+2,sxmax-2,ymin+2,ymax-2,uiVyLtGray,uiMmGray); + drawedges(sxmin+3,sxmax-3,ymin+3,ymax-3,uiVyLtGray,uiMmGray); + + uiLtGray(); + uirectfi(sxmin+4, ymin+4, sxmax-4, ymax-4); + + /* ridges on thumb */ + uiBlack(); + uimove2i(hs->scenter, ymin+3); + uidraw2i(hs->scenter, ymax-3); + uiendline(); + uimove2i(hs->scenter-4, ymin+3); + uidraw2i(hs->scenter-4, ymax-3); + uiendline(); + uimove2i(hs->scenter+4, ymin+3); + uidraw2i(hs->scenter+4, ymax-3); + uiendline(); + + uiWhite(); + uimove2i(hs->scenter+1, ymin+3); + uidraw2i(hs->scenter+1, ymax-3); + uiendline(); + uimove2i(hs->scenter-3, ymin+3); + uidraw2i(hs->scenter-3, ymax-3); + uiendline(); + uimove2i(hs->scenter+5, ymin+3); + uidraw2i(hs->scenter+5, ymax-3); + uiendline(); + } + } + } + drawhsarrows(obj); + + drawrestore(); +} + +enum muiReturnValue hshandler(muiObject *obj, int event, int value, int x, int y) +{ + int my = x; + static int mfudge=0; + static enum muiReturnValue retval = MUI_NO_ACTION; + HSlider *hs = (HSlider *)obj->object; + + if (!muiGetEnable(obj) || !muiGetVisible(obj)) + return MUI_NO_ACTION; + switch (event) { + case MUI_DEVICE_RELEASE: + if (value == 0) { + hs->oldpos = hs->scenter; + muiSetSelect(obj, 0); + return MUI_SLIDER_RETURN; + } + case MUI_DEVICE_PRESS: + case MUI_DEVICE_CLICK: + /* in the arrows */ + if (my >= obj->xmin && my <= obj->xmax && + (my < obj->xmin+ARROWHEIGHT || my > obj->xmax-ARROWHEIGHT)) { + mfudge = -10000; + if (my < obj->xmin+ARROWHEIGHT) { /* boink down */ + my = hs->scenter - hs->arrowdelta; + retval = MUI_SLIDER_SCROLLDOWN; + } else { /* boink up */ + my = hs->scenter + hs->arrowdelta; + retval = MUI_SLIDER_SCROLLUP; + } + if (event == MUI_DEVICE_CLICK) { + muiSetSelect(obj, 0); + retval = MUI_SLIDER_RETURN; + } + if (my - hs->shalf < obj->xmin+1+ARROWHEIGHT) + my = obj->xmin+1+hs->shalf+ARROWHEIGHT; + if (my + hs->shalf > obj->xmax-1-ARROWHEIGHT) + my = obj->xmax-1-hs->shalf-ARROWHEIGHT; + hs->scenter = my; + break; + } else if (my >= obj->xmin && my <= obj->xmax) + retval = MUI_SLIDER_THUMB; + hs->oldpos = hs->scenter; + if (my >= hs->scenter-hs->shalf && my <= hs->scenter+hs->shalf) + mfudge = hs->scenter - my; + else + mfudge = 0; + break; + case MUI_DEVICE_DOWN: + if (mfudge == -10000) { /* auto - repeat the arrow keys */ + if (retval == MUI_SLIDER_SCROLLDOWN) { + my = hs->scenter - hs->arrowdelta; + if (my - hs->shalf < obj->xmin+1+ARROWHEIGHT) + my = obj->xmin+1+hs->shalf+ARROWHEIGHT; + } else { + my = hs->scenter + hs->arrowdelta; + if (my + hs->shalf > obj->xmax-1-ARROWHEIGHT) + my = obj->xmax-1-hs->shalf-ARROWHEIGHT; + } + hs->scenter = my; + break; + } + my = x+mfudge; + if (my - hs->shalf < obj->xmin+1+ARROWHEIGHT) + my = obj->xmin+1+hs->shalf+ARROWHEIGHT; + if (my + hs->shalf > obj->xmax-1-ARROWHEIGHT) + my = obj->xmax-1-hs->shalf-ARROWHEIGHT; + + /* adjust thumb */ + hs->scenter = my; + break; + } + y = y; /* for lint's sake */ + return retval; +} + +float muiGetHSVal(muiObject *obj) +{ + HSlider *hs = (HSlider *)obj->object; + + return (hs->scenter-obj->xmin-1.0-hs->shalf-ARROWHEIGHT)/ + (obj->xmax - obj->xmin - 2.0*hs->shalf - 2.0-2*ARROWHEIGHT); +} + +void sethshalf(muiObject *obj, int shalf) +{ + HSlider *hs = (HSlider *)obj->object; + hs->shalf = shalf; + if (hs->shalf==0) + muiSetEnable(obj, 0); + else if (hs->shalf < MINSHALF) { + hs->shalf = MINSHALF; + muiSetEnable(obj, 1); + } else if (2*hs->shalf >= gethstrough(obj)) { + hs->shalf = gethstrough(obj)/2; + muiSetEnable(obj, 0); + } +} + +void movehsval(muiObject *obj, float val) +{ + float f; + HSlider *hs = (HSlider *)obj->object; + + if (val < 0.0) val = 0.0; + if (val > 1.0) val = 1.0; + f = val*(obj->xmax - obj->xmin - 2.0*hs->shalf - 2.0-2*ARROWHEIGHT); + hs->scenter = f + hs->shalf + obj->xmin + 1.0+ARROWHEIGHT; + + if ((hs->scenter + hs->shalf) > (obj->xmax - ARROWHEIGHT)) + hs->scenter = obj->xmax - ARROWHEIGHT - hs->shalf; + if ((hs->scenter - hs->shalf) < (obj->xmin+ ARROWHEIGHT)) + hs->scenter = obj->xmin + ARROWHEIGHT + hs->shalf; +} + +void muiSetHSValue(muiObject *obj, float val) +{ + HSlider *hs = (HSlider *)obj->object; + movehsval(obj, (float) val); + hs->oldpos = hs->scenter; +} + +/* + * visible is windowheight/dataheight + * top is top/dataheight + */ + +void +adjusthsthumb(muiObject *obj, double visible, double top) +{ + int size; + + if (visible >= 1.0) { + size = gethstrough(obj) + 1; + } else { + size = visible*gethstrough(obj); + } + muiSetEnable(obj, 1); + sethshalf(obj, size/2); + muiSetHSValue(obj, (float) (1.0 - top)); +} diff --git a/lib/glut-3.7.6/lib/mui/miscui.c b/lib/glut-3.7.6/lib/mui/miscui.c new file mode 100644 index 0000000000..4042512c7d --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/miscui.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1990,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. + */ + +#include +#include +#include +#include + +extern int mui_xsize, mui_ysize; + +short sharefont1 = 0; +short sharefont2 = 0; + +void drawedges(int xmin,int xmax,int ymin,int ymax, + void (*topleft)(void), void (*bottomright)(void)) +{ + (*topleft)(); + uimove2i(xmin,ymin); + uidraw2i(xmin,ymax); + uidraw2i(xmax,ymax); + uiendline(); + + (*bottomright)(); + uimove2i(xmax,ymax-1); + uidraw2i(xmax,ymin); + uidraw2i(xmin+1,ymin); + uiendline(); +} + +static short called = 0; + +void drawsetup(void) +{ + if (called) return; + else called = 1; +} + +void drawrestore(void) +{ + called = 0; +} + +void backgrounddraw(int xmin, int ymin, int xmax, int ymax) +{ + drawsetup(); + + uiBackground(); + uirectfi(xmin, ymin, xmax, ymax); + + drawrestore(); +} + +void muiBackgroundClear(void) +{ + drawsetup(); + + uiBackground(); + uiclear(); + + drawrestore(); +} + +#if 0 +void windowborderdraw(void) +{ + int sxsize, sysize; + + sxsize = mui_xsize-1; sysize = mui_ysize-1; + + drawsetup(); + + uiBlack(); + uirecti(0,0,sxsize,sysize); + + uiWhite(); + uirecti(0+1,0+1,sxsize-1,sysize-1); + uirecti(0+2,0+2,sxsize-2,sysize-2); + + uiLtGray(); + uirecti(0+3,0+3,sxsize-3,sysize-3); + uirecti(0+4,0+4,sxsize-4,sysize-4); + uirecti(0+5,0+5,sxsize-5,sysize-5); + uirecti(0+6,0+6,sxsize-6,sysize-6); + + uiBlack(); + uirecti(0+7,0+7,sxsize-7,sysize-7); + + uiDkGray(); + uimove2i(0+1,0+1); uidraw2i(sxsize-1,0+1); uiendline(); + uimove2i(0+2,0+2); uidraw2i(sxsize-2,0+2); uiendline(); + uimove2i(0+3,0+3); uidraw2i(sxsize-3,0+3); uiendline(); + + drawrestore(); +} +#endif diff --git a/lib/glut-3.7.6/lib/mui/mui.c b/lib/glut-3.7.6/lib/mui/mui.c new file mode 100644 index 0000000000..3d6afb44bd --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/mui.c @@ -0,0 +1,638 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +extern int activemenu; +extern int menuinuse; + +static muiObject *newmuiobj(void) +{ + muiObject *newobj = (muiObject *)malloc(sizeof(muiObject)); + newobj->active = 0; + newobj->enable = 1; + newobj->select = 0; + newobj->locate = 0; + newobj->visible = 1; + newobj->callback = 0; + muiSetUIList(newobj, muiGetActiveUIList()); + muiAddToUIList(muiGetActiveUIList(), newobj); + newobj->id = 0; + return newobj; +} + +muiObject *muiNewPulldown(void) +{ + muiObject *newPD = newmuiobj(); + newPD->type = MUI_PULLDOWN; + newPD->xmin = 0; + newPD->ymin = glutGet(GLUT_WINDOW_HEIGHT) - PULLDOWN_HEIGHT; + newPD->xmax = glutGet(GLUT_WINDOW_WIDTH); + newPD->ymax = glutGet(GLUT_WINDOW_HEIGHT); + newPD->object = (void *)newpd(); + newPD->handler = pdhandler; + return newPD; +} + +muiObject *muiNewButton(int xmin, int xmax, int ymin, int ymax) +{ + muiObject *newb = newmuiobj(); + newb->type = MUI_BUTTON; + newb->xmin = xmin; + newb->ymin = ymin; + newb->xmax = xmax; + newb->ymax = ymax; + newb->object = (void *)newbut(); + ((Button *)(newb->object))->object = newb; + newb->handler = buttonhandler; + return newb; +} + +muiObject *muiNewRadioButton(int xmin, int ymin) +{ + muiObject *newb = newmuiobj(); + newb->type = MUI_RADIOBUTTON; + newb->xmin = xmin; + newb->ymin = ymin; + newb->xmax = xmin+ RADIOWIDTH-1; + newb->ymax = ymin+RADIOHEIGHT-1; + newb->object = (void *)newradiobut(); + ((Button *)(newb->object))->object = newb; + newb->handler = buttonhandler; + return newb; +} + +muiObject *muiNewTinyRadioButton(int xmin, int ymin) +{ + muiObject *newb = newmuiobj(); + newb->type = MUI_TINYRADIOBUTTON; + newb->xmin = xmin; + newb->ymin = ymin; + newb->xmax = xmin+ TINYRADIOWIDTH-1; + newb->ymax = ymin+ TINYRADIOHEIGHT-1; + newb->object = (void *)newradiobut(); + ((Button *)(newb->object))->object = newb; + newb->handler = buttonhandler; + return newb; +} + +muiObject *muiNewVSlider(int xmin, int ymin, int ymax, int scenter, int shalf) +{ + muiObject *newvsl = newmuiobj(); + newvsl->type = MUI_VSLIDER; + newvsl->xmin = xmin; + newvsl->ymin = ymin; + newvsl->xmax = xmin+SLIDERWIDTH-1; + newvsl->ymax = ymax; + newvsl->object = (void *)newvs(newvsl, ymin, ymax, scenter, shalf); + newvsl->handler = vshandler; + return newvsl; +} + +muiObject *muiNewHSlider(int xmin, int ymin, int xmax, int scenter, int shalf) +{ + muiObject *newhsl = newmuiobj(); + newhsl->type = MUI_HSLIDER; + newhsl->xmin = xmin; + newhsl->ymin = ymin; + newhsl->xmax = xmax; + newhsl->ymax = ymin+SLIDERWIDTH-1; + newhsl->object = (void *)newhs(newhsl, xmin, xmax, scenter, shalf); + newhsl->handler = hshandler; + return newhsl; +} + +muiObject *muiNewTextList(int xmin, int ymin, int xmax, int listheight) +{ + muiObject *newtlo = newmuiobj(); + newtlo->type = MUI_TEXTLIST; + newtlo->xmin = xmin; + newtlo->ymin = ymin; + newtlo->xmax = xmax; + newtlo->object = (void *)newtl(newtlo, listheight); + newtlo->handler = tlhandler; + return newtlo; +} + +muiObject *muiNewLabel(int xmin, int ymin, char *label) +{ + muiObject *newlbl = newmuiobj(); + newlbl->type = MUI_LABEL; + newlbl->xmin = xmin; + newlbl->ymin = ymin; + /* XXX maximums */ + newlbl->object = (void *)newlabel(label); + newlbl->handler = nullhandler; + return newlbl; +} + +muiObject *muiNewBoldLabel(int xmin, int ymin, char *label) +{ + muiObject *newlbl = newmuiobj(); + newlbl->type = MUI_BOLDLABEL; + newlbl->xmin = xmin; + newlbl->ymin = ymin; + /* XXX maximums */ + newlbl->object = (void *)newlabel(label); + newlbl->handler = nullhandler; + return newlbl; +} + +muiObject *muiNewTextbox(int xmin, int xmax, int ymin) +{ + muiObject *newtextbox = newmuiobj(); + newtextbox->type = MUI_TEXTBOX; + newtextbox->xmin = xmin; + newtextbox->ymin = ymin; + newtextbox->xmax = xmax; + newtextbox->ymax = ymin + TEXTBOXHEIGHT - 1; + newtextbox->object = (void *)newtb(xmin, xmax); + newtextbox->handler = textboxhandler; + return newtextbox; +} + +void muiGetObjectSize(muiObject *obj, int *xmin, int *ymin, int *xmax, int *ymax) +{ + *xmin = obj->xmin; + *xmax = obj->xmax; + *ymin = obj->ymin; + *ymax = obj->ymax; +} + +void muiFreeObject(muiObject *obj) +{ + switch (obj->type) { + case MUI_BUTTON: + case MUI_RADIOBUTTON: + case MUI_TINYRADIOBUTTON: + case MUI_VSLIDER: + case MUI_HSLIDER: + case MUI_TEXTBOX: + case MUI_TEXTLIST: + case MUI_PULLDOWN: + free(obj->object); + break; + case MUI_LABEL: + case MUI_BOLDLABEL: + break; + } + free(obj); +} + +void muiSetID(muiObject *obj, int id) +{ + obj->id = id; +} + +int muiGetID(muiObject *obj) +{ + return obj->id; +} + +void muiSetCallback(muiObject *obj, void (*callback)(muiObject *, enum muiReturnValue)) +{ + obj->callback = callback; +} + +int muiInObject(muiObject *obj, int x, int y) +{ + if (obj->xmin <= x && x <= obj->xmax && obj->ymin <= y && y <= obj->ymax) + return 1; + return 0; +} + +int muiGetLocate(muiObject *obj) +{ + return obj->locate; +} + +void muiSetLocate(muiObject *obj, int state) +{ + obj->locate = (short) state; +} + +int muiGetSelect(muiObject *obj) +{ + return obj->select; +} + +void muiSetUIList(muiObject *obj, int list) +{ + obj->uilist = list; +} + +int muiGetUIList(muiObject *obj) +{ + return obj->uilist; +} + +void muiSetSelect(muiObject *obj, int state) +{ + obj->select = (short) state; +} + +int muiGetVisible(muiObject *obj) +{ + return obj->visible; +} + +void muiSetVisible(muiObject *obj, int state) +{ + obj->visible = (short) state; +} + +int muiGetActive(muiObject *obj) +{ + return obj->active; +} + +void muiSetActive(muiObject *obj, int state) +{ + obj->active = (short) state; +} + +int muiGetEnable(muiObject *obj) +{ + return obj->enable; +} + +void muiSetEnable(muiObject *obj, int state) +{ + obj->enable = (short) state; +} + +void muiDrawObject(muiObject *obj) +{ + switch (obj->type) { + case MUI_BUTTON: + drawbut(obj); + break; + case MUI_RADIOBUTTON: + drawradiobutton(obj); + break; + case MUI_TINYRADIOBUTTON: + drawtinyradio(obj); + break; + case MUI_LABEL: + drawlabel(obj); + break; + case MUI_BOLDLABEL: + drawboldlabel(obj); + break; + case MUI_TEXTBOX: + drawtb(obj); + break; + case MUI_VSLIDER: + drawvs(obj); + break; + case MUI_HSLIDER: + drawhs(obj); + break; + case MUI_TEXTLIST: + drawtl(obj); + break; + case MUI_PULLDOWN: + drawpulldown(obj); + break; + } +} + +void muiError(char *s) +{ + fprintf(stderr, "%s\n", s); + exit(0); +} + +#define MAX_UI_LISTS 50 +static muiCons *muilist[MAX_UI_LISTS]; +static int muilistindex[MAX_UI_LISTS]; + +void muiNewUIList(int listid) +{ + static int inited = 0; + int i; + + if (inited == 0) { + inited = 1; + for (i = 1; i < MAX_UI_LISTS; i++) + muilistindex[i] = -1; + muilistindex[0] = listid; + muiSetActiveUIList(listid); + return; + } + for (i = 0; i < MAX_UI_LISTS; i++) + if (muilistindex[i] == -1) { + muilistindex[i] = listid; + muiSetActiveUIList(listid); + return; + } + muiError("muiNewUIList: No more UI lists available"); +} + +int muiGetListId(int uilist) +{ + int i; + + for (i = 0; i < MAX_UI_LISTS; i++) { + if (muilistindex[i] == uilist) return i; + } + muiError("muiAddToUIList: illegal UI list identifier"); + return -1; +} + +muiCons *muiGetListCons(int uilist) +{ + int i; + + for (i = 0; i < MAX_UI_LISTS; i++) { + if (muilistindex[i] == uilist) return muilist[i]; + } + muiError("muiGetListCons: illegal UI list identifier"); + return (muiCons *)0; +} + +void muiAddToUIList(int uilist, muiObject *obj) +{ + int i; + muiCons *mcons; + + if (uilist == 0) { + muiError("muiAddToUIList: no active UI list"); + } + if ((i = muiGetListId(uilist)) == -1) return; + mcons = (muiCons *)malloc(sizeof(muiCons)); + mcons->next = muilist[i]; + muilist[i] = mcons; + mcons->object = obj; +} + +static muiObject *muiFastHitInList(muiCons *mcons, int x, int y) +{ + while (mcons) { + if (muiInObject(mcons->object, x, y)) + switch (mcons->object->type) { + case MUI_BUTTON: + case MUI_TEXTBOX: + case MUI_VSLIDER: + case MUI_HSLIDER: + case MUI_TEXTLIST: + case MUI_RADIOBUTTON: + case MUI_TINYRADIOBUTTON: + case MUI_PULLDOWN: + return mcons->object; + case MUI_LABEL: + case MUI_BOLDLABEL: + return 0; + } + mcons = mcons->next; + } + return (muiObject *)0; /* not found */ +} + +muiObject *muiHitInList(int uilist, int x, int y) +{ + muiCons *mcons; + + if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return (muiObject *)0; + return muiFastHitInList(mcons, x, y); +} + +void muiDrawUIList(int uilist) +{ + muiCons *mcons; + + if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return; + muiBackgroundClear(); + while (mcons) { + muiDrawObject(mcons->object); + mcons = mcons->next; + } +} + +static muiObject *SelectedObj, *LocatedObj; +static muiCons *ActiveCons; +static int ActiveUIList = 0; +static muiObject *ActiveSlider = 0; + +void muiSetActiveUIList(int i) +{ + ActiveUIList = i; +} + +int muiGetActiveUIList(void) +{ + return ActiveUIList; +} + +static void muiInitInteraction(int uilist) +{ + muiCons *mcons; + muiObject *obj; + + if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return; + SelectedObj = LocatedObj = (muiObject *)0; + ActiveCons = mcons; + ActiveUIList = uilist; + while (mcons) { + obj = mcons->object; + muiSetSelect(obj, 0); + muiSetLocate(obj, 0); + mcons = mcons->next; + } +} + +static void (*noncallback)(int, int) = 0; + +static void nonmuicallback(int x, int y) +{ + if (noncallback == 0) return; + noncallback(x, y); +} + +void muiSetNonMUIcallback(void (*nc)(int, int)) +{ + noncallback = nc; +} + +void muiHandleEvent(int event, int value, int x, int y) +{ + muiObject *obj; + static int lastactive = 0; + enum muiReturnValue retval; + + if (ActiveUIList == 0) { + muiError("muiHandleEvent: no active UI list"); + } + if (lastactive != ActiveUIList) { + muiInitInteraction(lastactive = ActiveUIList); + } + if ((event == MUI_KEYSTROKE)) { + if (obj = muiGetActiveTB()) { + retval = (obj->handler)(obj, event, value, x, y); + if (retval && obj->callback) + (obj->callback)(obj, retval); + return; + } + /* may have to add text editors, et cetera */ + return; + } + if (event == MUI_DEVICE_RELEASE && ActiveSlider) { + retval = (ActiveSlider->handler)(ActiveSlider, event, value, x, y); + if (retval && ActiveSlider->callback) + (ActiveSlider->callback)(ActiveSlider, retval); + ActiveSlider = 0; + return; + } + ActiveCons = muiGetListCons(ActiveUIList); + obj = muiFastHitInList(ActiveCons, x, y); + if (obj == 0 && event == MUI_DEVICE_PRESS) { + nonmuicallback(x, y); + return; + } + if (event == MUI_DEVICE_UP && (!menuinuse) && (activemenu != -1) && (obj == 0 || obj->type != MUI_PULLDOWN)) { + activemenu = -1; + glutDetachMenu(GLUT_LEFT_BUTTON); + } + if (obj && (obj->type == MUI_VSLIDER || obj->type == MUI_HSLIDER) + && event == MUI_DEVICE_PRESS) + ActiveSlider = obj; + if (obj == 0) { + if (ActiveSlider) { + retval = (ActiveSlider->handler)(ActiveSlider, event, value, x, y); + if (retval && ActiveSlider->callback) + (ActiveSlider->callback)(ActiveSlider, retval); + return; + } + if (LocatedObj) { + muiSetLocate(LocatedObj, 0); + muiDrawObject(LocatedObj); + LocatedObj = 0; + } + if ((event == MUI_DEVICE_RELEASE) && SelectedObj) { + muiSetSelect(SelectedObj, 0); + muiSetLocate(SelectedObj, 0); + muiDrawObject(SelectedObj); + LocatedObj = SelectedObj = 0; + } + return; + } + retval = (obj->handler)(obj, event, value, x, y); + if (retval && obj->callback) + (obj->callback)(obj, retval); + return; +} + +/* ARGSUSED2 */ +enum muiReturnValue buttonhandler(muiObject *obj, int event, int value, int x, int y) +{ + if (!muiGetEnable(obj) || !muiGetVisible(obj)) return MUI_NO_ACTION; + + switch (event) { + case MUI_DEVICE_DOWN: + return MUI_NO_ACTION; + case MUI_DEVICE_UP: + if (LocatedObj != obj) { + if (LocatedObj) { + muiSetLocate(LocatedObj, 0); + muiDrawObject(LocatedObj); + } + muiSetLocate(obj, 1); + muiDrawObject(obj); + LocatedObj = obj; + } + return MUI_NO_ACTION; + case MUI_DEVICE_PRESS: + muiSetSelect(obj, 1); + muiSetLocate(obj, 1); + SelectedObj = LocatedObj = obj; + muiDrawObject(obj); + return MUI_NO_ACTION; + case MUI_DEVICE_RELEASE: + if (SelectedObj != obj) { + muiSetSelect(SelectedObj, 0); + muiSetLocate(SelectedObj, 0); + muiDrawObject(SelectedObj); + muiSetLocate(obj, 1); + LocatedObj = obj; + muiDrawObject(obj); + return MUI_NO_ACTION; + } + if (obj->type == MUI_RADIOBUTTON || obj->type == MUI_TINYRADIOBUTTON) { + Button *b = (Button *)obj->object, *b1; + if (b->link) { + muiSetActive(obj, 1); + b1 = b->link; + while (b1 != b) { + muiSetActive(b1->object, 0); + b1 = b1->link; + } + } else { + muiSetActive(obj, ( muiGetActive(obj) ? 0 : 1 ) ); + } + } + muiSetSelect(obj, 0); + muiDrawObject(obj); + return MUI_BUTTON_PRESS; + case MUI_DEVICE_CLICK: + muiSetSelect(obj, 0); + muiSetLocate(obj, 1); + LocatedObj = obj; + muiDrawObject(obj); + return MUI_BUTTON_PRESS; + case MUI_DEVICE_DOUBLE_CLICK: + muiSetSelect(obj, 0); + muiSetLocate(obj, 1); + LocatedObj = obj; + muiDrawObject(obj); + return MUI_BUTTON_PRESS; /* XXX this may not be right; */ + case MUI_KEYSTROKE: + return MUI_NO_ACTION; + default: + muiError("buttonhandler: wacko event"); + return MUI_NO_ACTION; + } +} + +/* ARGSUSED */ +enum muiReturnValue nullhandler(muiObject *obj, int event, int value, int x, int y) +{ + return MUI_NO_ACTION; +} + diff --git a/lib/glut-3.7.6/lib/mui/mui.dsp b/lib/glut-3.7.6/lib/mui/mui.dsp new file mode 100644 index 0000000000..9d40327704 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/mui.dsp @@ -0,0 +1,137 @@ +# Microsoft Developer Studio Project File - Name="mui" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=mui - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mui.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mui.mak" CFG="mui - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mui - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "mui - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mui - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "mui - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "mui - Win32 Release" +# Name "mui - Win32 Debug" +# Begin Source File + +SOURCE=.\browseparse.c +# End Source File +# Begin Source File + +SOURCE=.\browser.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\button.c +# End Source File +# Begin Source File + +SOURCE=.\displaylist.c +# End Source File +# Begin Source File + +SOURCE=.\gizmo.c +# End Source File +# Begin Source File + +SOURCE=.\glutmui.c +# End Source File +# Begin Source File + +SOURCE=.\hslider.c +# End Source File +# Begin Source File + +SOURCE=.\miscui.c +# End Source File +# Begin Source File + +SOURCE=.\mui.c +# End Source File +# Begin Source File + +SOURCE=.\pulldown.c +# End Source File +# Begin Source File + +SOURCE=.\textlist.c +# End Source File +# Begin Source File + +SOURCE=.\uicolor.c +# End Source File +# Begin Source File + +SOURCE=.\vslider.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/lib/mui/pulldown.c b/lib/glut-3.7.6/lib/mui/pulldown.c new file mode 100644 index 0000000000..6ae8489d30 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/pulldown.c @@ -0,0 +1,469 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* M E N U B A R F U N C T I O N S */ + +Pulldown *newpd(void) +{ + Pulldown *pd = (Pulldown *)malloc(sizeof(Pulldown)); + pd->count = 0; + return pd; +} + +void muiAddPulldownEntry(muiObject *obj, char *title, int menu, int ishelp) +{ + Pulldown *pd = (Pulldown *)obj->object; + int space = obj->xmax - obj->xmin - 66; + int i, delta; + + if (ishelp) { + strcpy(pd->helpmenu.title, title); + pd->ishelp = 1; + pd->helpmenu.xoffset = obj->xmax - 58; + pd->helpmenu.menu = menu; + return; + } + if (pd->count == 29) muiError("muiAddPulldownEntry: more than 29 entries"); + strcpy(pd->menus[pd->count].title, title); + pd->menus[pd->count].menu = menu; + pd->count++; + /* now recalculate spacings */ + if (space > 50*pd->count) { + for (i = 0; i <= pd->count; i++) + pd->menus[i].xoffset = 8 + i*50; + } else { + delta = space/pd->count; + for (i = 0; i <= pd->count; i++) + pd->menus[i].xoffset = 8 + i*delta; + } +} + +int activemenu = -1; +extern int menuinuse; + +/* ARGSUSED2 */ +enum muiReturnValue pdhandler(muiObject *obj, int event, int value, int x, int y) +{ + int i; + Pulldown *pd = (Pulldown *)obj->object; + + if( !muiGetEnable(obj) || !muiGetVisible(obj) ) return MUI_NO_ACTION; + + if (event == MUI_DEVICE_UP) { + for (i = 0; i < pd->count; i++) + if (pd->menus[i].xoffset-8 < x && x < pd->menus[i+1].xoffset-8) { + if (activemenu != pd->menus[i].menu && !menuinuse) { + glutSetMenu(activemenu = pd->menus[i].menu); + glutAttachMenu(GLUT_LEFT_BUTTON); + } + return MUI_NO_ACTION; + } + if (pd->ishelp && (x > pd->helpmenu.xoffset-8)) { + if ((activemenu != pd->helpmenu.menu) && !menuinuse) { + glutSetMenu(activemenu = pd->helpmenu.menu); + glutAttachMenu(GLUT_LEFT_BUTTON); + } + return MUI_NO_ACTION; + } + if (activemenu && !menuinuse) { + glutDetachMenu(GLUT_LEFT_BUTTON); + activemenu = -1; + } + } + return MUI_NO_ACTION; +} + +void drawpulldown(muiObject *obj) +{ + int i; + int xmin, xmax, ymin, ymax; + + if (!muiGetVisible(obj)) + return; + + drawsetup(); + + xmin = obj->xmin; + ymin = obj->ymin; + xmax = obj->xmax; + ymax = obj->ymax; + + drawedges(xmin++,xmax--,ymin++,ymax--,uiDkGray,uiVyDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiWhite,uiDkGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiVyLtGray,uiMmGray); + drawedges(xmin++,xmax--,ymin++,ymax--,uiVyLtGray,uiMmGray); + + uiLtGray(); + uirectfi(xmin,ymin,xmax,ymax); + + if (obj->object) { + Pulldown *pd = (Pulldown *)obj->object; + + for (i = 0; i < pd->count; i++) { + if (muiGetEnable(obj)) uiBlack(); else uiDkGray(); + uicmov2i(obj->xmin + pd->menus[i].xoffset, obj->ymin + 8); + uicharstr(pd->menus[i].title, UI_FONT_NORMAL); + } + if (pd->ishelp) { + if(muiGetEnable(obj)) uiBlack(); else uiDkGray(); + uicmov2i(obj->xmin + pd->helpmenu.xoffset, obj->ymin + 8); + uicharstr(pd->helpmenu.title, UI_FONT_NORMAL); + } + } + + drawrestore(); +} + +#ifdef NOTDEF + +/* static variables */ +static int offrightside; +static PullDown *basepd; +static int menubut; +static int menuretval; +static int inpdmode = 0; +static int indopd = 0; +static int savep; +static short savedev[SAVELEN]; +static short saveval[SAVELEN]; + +extern MenuBar *locatedmb; + +static short pdinit = 0; + +void movemenubar(muiObject *obj) +{ + int i, tx = MENUXENDGAP-9, totaltwidth = 0; + int xsize, ysize, width; + + mb->xmin = mb->xorg; + mb->xmax = mb->xorg+xsize-1; + mb->ymin = mb->yorg+ysize-MENUBARHEIGHT; + mb->ymax = mb->yorg+ysize-1; + + width = mb->xmax - mb->xmin + 1; + + font(PULLDOWNFONT); /* for correct strwidths */ + for (i = 0; i < mb->count; i++) + totaltwidth += strwidth(mb->pds[i]->title) + 2*MENUXENDGAP; + + for (i = 0; i < mb->count; i++) { + if (mb->pds[i]->title) + mb->pds[i]->twidth = strwidth(mb->pds[i]->title); + if ((mb->pds[i]->title) && (!strcmp(mb->pds[i]->title,"Help"))) + mb->pds[i]->txorg = mb->xmax-MENUXENDGAP-mb->pds[i]->twidth-MENUXGAP; + else + mb->pds[i]->txorg = mb->xmin + tx; + mb->pds[i]->xorg = mb->pds[i]->txorg; + mb->pds[i]->yorg = mb->ymin-TITLESEP; + mb->pds[i]->orglocked = 1; + mb->pds[i]->mb = mb; + + if (totaltwidth > width) + tx += (width-2*MENUXENDGAP)/mb->count-2; + else + tx += mb->pds[i]->twidth+24; + } +} + +MenuBar *newmenubar(void) +{ + MenuBar *mb; + + mb = (MenuBar *)calloc(1,sizeof(MenuBar)); + mb->count = 0; + mb->pds = 0; + mb->locate = -1; + mb->enable = 1; + mb->invisible = 0; + + return mb; +} + +/* ENABLE STATE FUNCTIONS FOR MENU BARS */ + +void enablemb(MenuBar *mb) +{ + if (mb->enable) + return; + mb->enable = 1; +} + +void disablemb(MenuBar *mb) +{ + if (!mb->enable) + return; + mb->enable = 0; +} + +short getenablemb(MenuBar *mb) +{ + return mb->enable; +} + +/* LOCATE STATE FUNCTIONS FOR MENU BARS */ + +short gethighlightmb(MenuBar *mb) +{ + return mb->locate; +} + +void highlightmb(MenuBar *mb, int pdnum) +{ + short oldpdnum = mb->locate; + + if (mb->locate == pdnum) + return; + mb->locate = pdnum; + locatedmb = mb; + if (!mb->invisible) { + if (pdnum != -1) + drawmenubartext(mb,pdnum); + if (oldpdnum != -1) + drawmenubartext(mb,oldpdnum); + } +} + +void unhighlightmb(MenuBar *mb) +{ + short oldpdnum = mb->locate; + + if (mb->locate == -1) + return; + mb->locate = -1; + if (locatedmb == mb) + locatedmb = 0; + if (!mb->invisible) + if (oldpdnum != -1) + drawmenubartext(mb,oldpdnum); +} + +/* VISIBLE STATE FUNCTIONS */ + +void makevisiblemb(MenuBar *mb) +{ + if (!mb->invisible) + return; + mb->invisible = 0; +} + +void makeinvisiblemb(MenuBar *mb) +{ + if (mb->invisible) + return; + mb->invisible = 1; +} + +short getvisiblemb(MenuBar *mb) +{ + return 1-mb->invisible; +} + +void loadmenubar(MenuBar *mb, int menucount, PullDown **pdarray) +{ + int i; + + drawsetup(); + + mb->count = menucount; + mb->pds = (PullDown **)calloc(menucount,sizeof(PullDown)); + mb->locate = -1; + mb->enable = 1; + mb->invisible = 0; + + for (i = 0; i < mb->count; i++){ + mb->pds[i] = pdarray[i]; + } + movemenubar(mb); + + drawrestore(); +} + +void addtomenubar(MenuBar *mb, PullDown *pd) +{ + PullDown **pds; + int i; + + mb->count++; + pds = (PullDown **)calloc(mb->count,sizeof(PullDown)); + + for (i = 0; i < mb->count-1; i++){ + pds[i] = mb->pds[i]; + } + pds[i] = pd; + + free(mb->pds); + mb->pds = pds; +} + +void addtopd(PullDown *pd, MenuItem *mi) +{ + MenuItem *m, *tail; + + tail = pd->entries; + + if (tail) { + while (tail->next) + tail = tail->next; + tail->next = mi; + } else + tail = pd->entries = mi; + + m = pd->entries; + + while (m) { + pd->nentries++; + m->no = pd->nentries; + m = m->next; + } + + fixuppd(pd); +} + +void removefrommenubar(MenuBar *mb, PullDown *pd) +{ + PullDown **pds; + int i, j; + + mb->count--; + pds = (PullDown **)calloc(mb->count,sizeof(PullDown)); + + for (i = 0,j = 0; i <= mb->count; i++) { + if (mb->pds[i] != pd) { + pds[j] = mb->pds[i]; + j++; + } + } + + free(mb->pds); + mb->pds = pds; +} + +void movemenubar(MenuBar *mb) +{ + int i, tx = MENUXENDGAP-9, totaltwidth = 0; + int xsize, ysize, width; + + getorigin(&mb->xorg, &mb->yorg); + getsize(&xsize, &ysize); + mb->xmin = mb->xorg; + mb->xmax = mb->xorg+xsize-1; + mb->ymin = mb->yorg+ysize-MENUBARHEIGHT; + mb->ymax = mb->yorg+ysize-1; + + width = mb->xmax - mb->xmin + 1; + + font(PULLDOWNFONT); /* for correct strwidths */ + for (i = 0; i < mb->count; i++) + totaltwidth += strwidth(mb->pds[i]->title) + 2*MENUXENDGAP; + + for (i = 0; i < mb->count; i++) { + if (mb->pds[i]->title) + mb->pds[i]->twidth = strwidth(mb->pds[i]->title); + if ((mb->pds[i]->title) && (!strcmp(mb->pds[i]->title,"Help"))) + mb->pds[i]->txorg = mb->xmax-MENUXENDGAP-mb->pds[i]->twidth-MENUXGAP; + else + mb->pds[i]->txorg = mb->xmin + tx; + mb->pds[i]->xorg = mb->pds[i]->txorg; + mb->pds[i]->yorg = mb->ymin-TITLESEP; + mb->pds[i]->orglocked = 1; + mb->pds[i]->mb = mb; + + if (totaltwidth > width) + tx += (width-2*MENUXENDGAP)/mb->count-2; + else + tx += mb->pds[i]->twidth+24; + } +} + +int inmenubar(MenuBar *mb, int mx, int my) /* Window coordinates */ +{ + int i; + + if (!getenablemb(mb)) + return -1; + + if (getdrawmode() == NORMALDRAW) { + mx += mb->xorg; + my += mb->yorg; + } + if (mb->xmin <= mx && mx <= mb->xmax && + mb->ymin+2 <= my && my <= mb->ymax-2) /* +-2 for locate highlight*/ + for (i = 0; i < mb->count; i++) { + if ((mx >= mb->pds[i]->txorg) && + (mx <= mb->pds[i]->txorg+mb->pds[i]->twidth+MENUXGAP*2)) + return i; + } + return -1; +} + +short locatemenubar(MenuBar *mb, int mx, int my) /* window coordinates */ +{ + int highlight = gethighlightmb(mb); + int inmb = inmenubar(mb,mx,my); + + if (!getenablemb(mb) || !getvisiblemb(mb) || (highlight == inmb)) + return 0; + if (inmb != -1) { + unlocateall(); + highlightmb(mb,inmb); + return 1; + } else { + unhighlightmb(mb); + return 0; + } +} + +/* DRAWING MENUBAR FUNCTIONS */ + +void drawmenubarnow(MenuBar *mb) +{ + uifrontbuffer(1); + drawmenubar(mb); + uifrontbuffer(0); +} + + +#endif /* NOTDEF */ diff --git a/lib/glut-3.7.6/lib/mui/textlist.c b/lib/glut-3.7.6/lib/mui/textlist.c new file mode 100644 index 0000000000..929e85ec79 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/textlist.c @@ -0,0 +1,438 @@ +/* + * Copyright (c) 1990,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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern short sharefont1; + +extern TextList *locatedtl; + +int gettlheightcount(int ymin, int ymax) +{ + if (ymin > ymax) { + int tmp = ymin; + ymin = ymax; + ymax = tmp; + } + return ((ymax-ymin+1-7)/TEXTHEIGHT); +} + +void movetl(TextList *tl, int ymin, int ymax) +{ + tl->listheight = gettlheightcount(ymin, ymax); +} + +int gettextlistheight(int count) +{ + return (count*TEXTHEIGHT+7); +} + +TextList *newtl(muiObject *obj, int listheight) +{ + TextList *tl; + + tl = (TextList *)malloc(sizeof(TextList)); + + tl->strs = 0; + tl->top = 0; + tl->selecteditem = -1; + tl->locateditem = -1; + tl->listheight = listheight; + + movetl(tl, obj->ymin, obj->ymax = obj->ymin+gettextlistheight(listheight)); + + return tl; +} + +void resettl(TextList *tl) +{ + tl->selecteditem = -1; + tl->top = 0; +} + +void drawtl(muiObject *obj) +{ + TextList *tl = (TextList *)obj->object; + int xmin = obj->xmin, xmax = obj->xmax, + ymin = obj->ymin, ymax = obj->ymax; + int item = 0, ybot, xright; + char **s = &tl->strs[tl->top]; + + if (!muiGetVisible(obj)) + return; + + drawsetup(); + + drawedges(xmin++, xmax--, ymin++, ymax--, uiMmGray, uiWhite); + drawedges(xmin++, xmax--, ymin++, ymax--, uiDkGray, uiVyLtGray); + drawedges(xmin++, xmax--, ymin++, ymax--, uiVyDkGray, uiDkGray); + + drawedges(xmin++, xmax--, ymin++, ymax--, uiVyLtGray, uiMmGray); + + uiLtGray(); + uirectfi(xmin, ymin, xmax, ymax); + + uiBlack(); + uipushviewport(); + uiviewport(xmin+3, ymin-1, xmax-xmin-6, ymax-ymin); + if (s) while (*s && item < tl->listheight) { + if (item == tl->selecteditem - tl->top && muiGetEnable(obj)) { + ybot = ymin + 1 + (tl->listheight - item - 1)*TEXTHEIGHT; + xright = xmin + 11 + FONTWIDTH*(int)strlen(*s); + uiWhite(); + uirectfi(xmin+4, ybot, xright, ybot + TEXTHEIGHT - 3); + } + + /* locate highlight */ + if (item == tl->locateditem - tl->top && muiGetEnable(obj)) { + ybot = ymin + 1 + (tl->listheight - item - 1)*TEXTHEIGHT; + xright = xmin + 11 + FONTWIDTH*(int)strlen(*s); + uiWhite(); + uirecti(xmin+3, ybot-1, xright+1, ybot + TEXTHEIGHT - 2); + uirecti(xmin+4, ybot, xright, ybot + TEXTHEIGHT - 3); + } + if (muiGetEnable(obj)) uiBlack(); else uiDkGray(); + uicmov2i(xmin+8, ymin + 6 + (tl->listheight - item - 1)*TEXTHEIGHT); + uicharstr(*s, UI_FONT_NORMAL); + item++; s++; + } + uiBlack(); + uipopviewport(); + drawrestore(); +} + +int muiGetTLSelectedItem(muiObject *obj) +{ + TextList *tl = (TextList *)obj->object; + return tl->selecteditem; +} + +void muiSetTLStrings(muiObject *obj, char **s) +{ + TextList *tl = (TextList *)obj->object; + tl->strs = s; + + tl->count = 0; + while(*s) { + tl->count++; + s++; + } + resettl(tl); + tl->selecteditem = 0; +} + +/* ARGSUSED3 */ +enum muiReturnValue tlhandler(muiObject *obj, int event, int value, int x, int y) +{ + int i; + TextList *tl = (TextList *)obj->object; + + if( !muiGetEnable(obj) || !muiGetVisible(obj) ) return MUI_NO_ACTION; + + if (event == MUI_DEVICE_DOUBLE_CLICK) { + i = (y - obj->ymin - 3)/TEXTHEIGHT; + tl->selecteditem = (tl->listheight - i - 1) + tl->top; + return MUI_TEXTLIST_RETURN_CONFIRM; + } + if (event == MUI_DEVICE_RELEASE) { + i = (y - obj->ymin - 3)/TEXTHEIGHT; + tl->selecteditem = (tl->listheight - i - 1) + tl->top; + return MUI_TEXTLIST_RETURN; + } + if (event == MUI_DEVICE_PRESS || event == MUI_DEVICE_DOWN) { + i = (y - obj->ymin - 3)/TEXTHEIGHT; + tl->selecteditem = (tl->listheight - i - 1) + tl->top; + return MUI_NO_ACTION; + } + return MUI_NO_ACTION; +} + +void muiSetTLTopInt(muiObject *obj, int top) +{ + TextList *tl = (TextList *)obj->object; + if (top < 0) top = 0; + if (top >= tl->count) top = tl->count - 1; + tl->top = top; +} + +void muiSetTLTop(muiObject *obj, float p) +{ + TextList *tl = (TextList *)obj->object; + if (tl->count <= tl->listheight) { tl->top = 0; return; } + tl->top = (1.0-p)*(tl->count + 1 - tl->listheight); +} + + +void settlstrings(TextList *tl, char **s) +{ + tl->strs = s; + + tl->count = 0; + while(*s) { + tl->count++; + s++; + } +} + +#ifdef NOTDEF + +/* SELECT STATE FUNCTIONS */ + +void unselecttl(TextList *tl) +{ + int oldselect = tl->selecteditem; + + if (tl->selecteditem == -1) + return; + tl->selecteditem = -1; + if (!tl->invisible) + if (oldselect != -1) + drawparttl(tl,oldselect); +} + +void selecttlitem(TextList *tl, int item) +{ + int oldselect = tl->selecteditem; + + if (tl->selecteditem == item) + return; + tl->selecteditem = item; + if (!tl->invisible) { + if (tl->selecteditem != -1) + drawparttl(tl,tl->selecteditem); + if (oldselect != -1) + drawparttl(tl,oldselect); + } +} + +short getselectedtlitem(TextList *tl) +{ + return tl->selecteditem; /* returns -1 if none selected */ +} + +void highlighttl(TextList *tl, int item) +{ + int oldhighlight = tl->locateditem; + + if (tl->locateditem == item) + return; + tl->locateditem = item; + locatedtl = tl; + if (!tl->invisible) { + if (tl->locateditem != -1) + drawparttl(tl,tl->locateditem); + if (oldhighlight != -1) + drawparttl(tl,oldhighlight); + } +} + +void unhighlighttl(TextList *tl) +{ + int oldhighlight = tl->locateditem; + + if (tl->locateditem == -1) + return; + tl->locateditem = -1; + if (locatedtl == tl) + locatedtl = 0; + if (!tl->invisible) { + if (oldhighlight != -1) + drawparttl(tl,oldhighlight); + } +} + +short gethighlighttl(TextList *tl) +{ + return tl->locateditem; +} + +void makevisibletl(TextList *tl) +{ + if (!tl->invisible) + return; + tl->invisible = 0; +} + +void makeinvisibletl(TextList *tl) +{ + if (tl->invisible) + return; + tl->invisible = 1; +} + +/* whether or not the text list is showing */ +short getvisibletl(TextList *tl) +{ + return 1-tl->invisible; +} + +/* whether or not the item is showing */ +short getitemvisibletl(TextList *tl, int item) +{ + if ((item < tl->top) || (item >= (tl->top+tl->listheight)) || + (item >= tl->count) || (item == -1)) + return 0; + else + return 1; +} + +short locatetl(TextList *tl, int x, int y) +{ + int highlight = gethighlighttl(tl); + int intextlist = intl(tl,x,y); + + if ((intextlist == highlight) || !getvisibletl(tl)) + return 0; + if (intextlist != -1) { + unlocateall(); + highlighttl(tl,intextlist); + return 1; + } else { + unhighlighttl(tl); + return 0; + } +} + +char *selectedstring(TextList *tl) +{ + if (tl->selecteditem == -1) return 0; + return tl->strs[tl->selecteditem]; +} + +void drawtlnow(TextList *tl) +{ + uifrontbuffer(1); + drawtl(tl); + uifrontbuffer(0); +} + +void drawparttl(TextList *tl,int item) +{ + int xmin = tl->xmin+8, xmax = tl->xmax-8-SLIDERWIDTH; + int ymin = + tl->ymin+5+(tl->listheight - item + tl->top - 1)*TEXTHEIGHT; + int ymax = ymin + TEXTHEIGHT - 3; + char **s; + + if (!getvisibletl(tl) || !getitemvisibletl(tl,item)) + return; + + s = &tl->strs[item]; + drawsetup(); + + uifrontbuffer(1); + + uiLtGray(); + uirectfi(xmin-1, ymin-1, xmax+1, ymax+1); + + font(TEXTLISTFONT); + pushviewport(); + scrmask(xmin-1, xmax+1, ymin-1, ymax+1); + if (s) { + xmax = xmin + 7 + strwidth(*s); + if (item == tl->selecteditem) { + uiWhite(); + uirectfi(xmin, ymin, xmax, ymax); + } + if (item == tl->locateditem) { + uiWhite(); + uirecti(xmin-1, ymin-1, xmax+1, ymax+1); + uirecti(xmin, ymin, xmax, ymax); + } + uiBlack(); + uicmov2i(xmin+4, ymin + 5); + uicharstr(*s); + } + popviewport(); + + uifrontbuffer(0); + + drawrestore(); +} + +void settlstrslinkhandle(char **l, TextList *tl) +{ + int vshalf, d; + float p; + + settlstrings(tl, l); + + if (tl->count <= tl->listheight) { + vshalf = ((tl->listheight*TEXTHEIGHT - 36)/2) - 2; + d = 0; + p = 1.0; + disablevs(tl->vs); + } else { + enablevs(tl->vs); + p = getvsval(tl->vs); + vshalf = tl->listheight*(tl->listheight*TEXTHEIGHT-36)/(2*tl->count); + d = (tl->listheight*TEXTHEIGHT - 2*vshalf)/(tl->count - tl->listheight); + if (d == 0) d = 1; + } + setvsarrowdelta(tl->vs, d); + setvshalf(tl->vs, vshalf); + movevsval(tl->vs, p); +} + +void adjustslider(TextList *tl, VSlider *sl) +{ + setvsval(sl, (float) (1.0 - (float) tl->top/ (float) tl->count)); +} + +short selectedtl(TextList *tl, int x, int y, int val) +{ + if (intl(tl, x, y) == -1) { + if (intlboundaries(tl, x, y)) { + tl->selecteditem = -1; + drawtlnow(tl); + } + } else { + if (val == UIBUTTONUP) return 0; + return handletl(tl, LEFTMOUSE, val); + } + return 0; +} + +#endif /* NOTDEF */ diff --git a/lib/glut-3.7.6/lib/mui/uicolor.c b/lib/glut-3.7.6/lib/mui/uicolor.c new file mode 100644 index 0000000000..83c4afcee8 --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/uicolor.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1990,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. + */ + +#include +#include + +#define MKRGB(r, g, b) ((((r)&0xff)<<0) | (((g)&0xff)<<8) | (((b)&0xff)<<16)) +extern short ditherflag; + +void uiBlack(void) +{ + glColor3f(0.0, 0.0, 0.0); +} + +void uiWhite(void) +{ + glColor3f(1.0, 1.0, 1.0); +} + +void uiLtGray(void) +{ + glColor3f(170.0/255.0, 170.0/255.0, 170.0/255.0); +} + +void uiDkGray(void) +{ + glColor3f(85.0/255.0, 85.0/255.0, 85.0/255.0); +} + +void uiSlateBlue(void) +{ + glColor3f(113.0/255.0, 113.0/255.0, 198.0/255.0); +} + +void uiBlue(void) +{ + glColor3f(0.0, 0.0, 1.0); +} + +void uiBackground(void) +{ + uiVyLtGray(); +} + +void uiVyDkGray(void) +{ + glColor3f(40.0/255.0, 40.0/255.0, 40.0/255.0); +} + +void uiMmGray(void) +{ + glColor3f(132.0/255.0, 132.0/255.0, 132.0/255.0); +} + +void uiVyLtGray(void) +{ + glColor3f(214.0/255.0, 214.0/255.0, 214.0/255.0); +} + +void uiTerraCotta(void) +{ + glColor3f(198.0/255.0, 113.0/255.0, 113.0/255.0); +} + +void uiYellow(void) +{ + glColor3f(1.0, 1.0, 0.0); +} + +void uiDkYellow(void) +{ + glColor3f(0x47/255.0, 0x72/255.0, 0x72/255.0); +} + +void uiMmYellow(void) +{ + glColor3f(0x38/255.0, 0xc7/255.0, 0xc7/255.0); +} + +void uiLtYellow(void) +{ + glColor3f(0x80/255.0, 0xff/255.0, 0xff/255.0); +} + +/* +void uiPupBlack(void) +{ + color(PUP_BLACK); +} + +void uiPupWhite(void) +{ + color(PUP_WHITE); +} + +void uiPupGray(void) +{ + color(PUP_COLOR); +} + +void uiPupClear(void) +{ + color(PUP_CLEAR); +} +*/ diff --git a/lib/glut-3.7.6/lib/mui/vslider.c b/lib/glut-3.7.6/lib/mui/vslider.c new file mode 100644 index 0000000000..1b08b69e9f --- /dev/null +++ b/lib/glut-3.7.6/lib/mui/vslider.c @@ -0,0 +1,490 @@ +/* + * Copyright (c) 1990,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. + */ + +#include +#include +#include +#include +#include +#include + +extern VSlider *locatedvs; + +int getvstrough(muiObject *obj) +{ + return obj->ymax - obj->ymin - 2*ARROWHEIGHT; +} + +void setvscenter(muiObject *obj, int scenter) +{ + VSlider *vs = (VSlider *)obj->object; + if ((scenter - vs->shalf) < (obj->ymin+ARROWHEIGHT)) + vs->scenter = getvstrough(obj)/2 + obj->ymin+ARROWHEIGHT; + else + vs->scenter = scenter; +} + +void muiSetVSArrowDelta(muiObject *obj, int newd) +{ + VSlider *vs = (VSlider *)obj->object; + vs->arrowdelta = newd; +} + +VSlider *newvs(muiObject *obj, int ymin, int ymax, int scenter, int shalf) +{ + VSlider *vs; + + vs = (VSlider *)malloc(sizeof(VSlider)); + obj->object = (VSlider *)vs; + if (shalf == 0) { + vs->shalf = 0; + } else if (shalf < MINSHALF) + vs->shalf = MINSHALF; + else + vs->shalf = shalf; + + if ((ymax - ymin + 1) <= (2*ARROWHEIGHT+2*MINSHALF)) + vs->thumb = 0; + else + vs->thumb = 1; + + setvscenter(obj, scenter); + vs->oldpos = vs->scenter; + + muiSetVSArrowDelta(obj, 1); + return vs; +} + +void freevs(VSlider *vs) +{ + if (vs) { + free(vs); + } +} + +void drawvsarrows(muiObject *obj) +{ + int xmin = obj->xmin, xmax = obj->xmin+ARROWHEIGHT, + ymin = obj->ymin, ymax = obj->ymax; + + if (!muiGetVisible(obj)) + return; + + /* Draw the arrows: */ + + /* down arrow */ + uiDkGray(); + uirecti(xmin,ymin,xmax,ymin+20); + + if (muiGetVisible(obj)) { + if (obj->locate == SCROLLDOWN) { + if (obj->select == SCROLLDOWN) { + drawedges(xmin+1,xmax-1,ymin+1,ymin+19,uiMmGray,uiWhite); + drawedges(xmin+2,xmax-2,ymin+2,ymin+18,uiLtGray,uiWhite); + } else { + drawedges(xmin+1,xmax-1,ymin+1,ymin+19,uiWhite,uiMmGray); + drawedges(xmin+2,xmax-2,ymin+2,ymin+18,uiWhite,uiLtGray); + } + uiVyLtGray(); + uirectfi(xmin+3,ymin+3,xmax-3,ymin+17); + } else { + if (obj->select == SCROLLDOWN) { + drawedges(xmin+1,xmax-1,ymin+1,ymin+19,uiMmGray,uiVyLtGray); + drawedges(xmin+2,xmax-2,ymin+2,ymin+18,uiMmGray,uiVyLtGray); + } else { + drawedges(xmin+1,xmax-1,ymin+1,ymin+19,uiWhite,uiMmGray); + drawedges(xmin+2,xmax-2,ymin+2,ymin+18,uiVyLtGray,uiMmGray); + } + uiLtGray(); + uirectfi(xmin+3,ymin+3,xmax-3,ymin+17); + } + } else { + drawedges(xmin+1,xmax-1,ymin+1,ymin+19,uiVyLtGray,uiMmGray); + uiLtGray(); + uirectfi(xmin+2,ymin+2,xmax-2,ymin+18); + } + + /* arrow */ + if (muiGetEnable(obj)) + uiDkGray(); + else + uiMmGray(); + uimove2i(xmin+5,ymin+14); + uidraw2i(xmin+14,ymin+14); + uiendline(); + uirectfi(xmin+6,ymin+13,xmin+13,ymin+12); + uirectfi(xmin+7,ymin+11,xmin+12,ymin+10); + uirectfi(xmin+8,ymin+8,xmin+11,ymin+9); + uirectfi(xmin+9,ymin+6,xmin+10,ymin+7); + + /* up arrow */ + uiDkGray(); + uirecti(xmin,ymax-20,xmax,ymax); + + if (muiGetEnable(obj)) { + if (obj->locate == SCROLLUP) { + if (obj->select == SCROLLUP) { + drawedges(xmin+1,xmax-1,ymax-19,ymax-1,uiMmGray,uiWhite); + drawedges(xmin+2,xmax-2,ymax-18,ymax-2,uiLtGray,uiWhite); + } else { + drawedges(xmin+1,xmax-1,ymax-19,ymax-1,uiWhite,uiMmGray); + drawedges(xmin+2,xmax-2,ymax-18,ymax-2,uiWhite,uiLtGray); + } + uiVyLtGray(); + uirectfi(xmin+3,ymax-17,xmax-3,ymax-3); + } else { + if (obj->select == SCROLLUP) { + drawedges(xmin+1,xmax-1,ymax-19,ymax-1,uiMmGray,uiVyLtGray); + drawedges(xmin+2,xmax-2,ymax-18,ymax-2,uiMmGray,uiVyLtGray); + } else { + drawedges(xmin+1,xmax-1,ymax-19,ymax-1,uiWhite,uiMmGray); + drawedges(xmin+2,xmax-2,ymax-18,ymax-2,uiVyLtGray,uiMmGray); + } + uiLtGray(); + uirectfi(xmin+3,ymax-17,xmax-3,ymax-3); + } + } else { + drawedges(xmin+1,xmax-1,ymax-19,ymax-1,uiVyLtGray,uiMmGray); + uiLtGray(); + uirectfi(xmin+2,ymax-18,xmax-2,ymax-2); + } + + /* arrow */ + + if (muiGetEnable(obj)) + uiDkGray(); + else + uiMmGray(); + uirectfi(xmin+9,ymax-6,xmin+10,ymax-7); + uirectfi(xmin+8,ymax-8,xmin+11,ymax-9); + uirectfi(xmin+7,ymax-10,xmin+12,ymax-11); + uirectfi(xmin+6,ymax-12,xmin+13,ymax-13); + uimove2i(xmin+5,ymax-14); + uidraw2i(xmin+14,ymax-14); + uiendline(); +} + +void drawvs(muiObject *obj) +{ + VSlider *vs = (VSlider *)obj->object; + + int xmin = obj->xmin, ymax = obj->ymax-ARROWHEIGHT, + ymin = obj->ymin+ARROWHEIGHT; + int xmax = xmin+SLIDERWIDTH; + int symin = vs->scenter - vs->shalf; + int symax = vs->scenter + vs->shalf; + int oldsymin = vs->oldpos - vs->shalf; + int oldsymax = vs->oldpos + vs->shalf; + + drawsetup(); + + if (!muiGetVisible(obj)) { + backgrounddraw(xmin,ymin,xmax,ymax); + drawrestore(); + return; + } + + /* trough */ + + uiDkGray(); + uirecti(xmin, ymin, xmax, ymax); + + drawedges(xmin+1,xmax-1,ymin+1,ymax-1,uiVyLtGray,uiMmGray); + + uiLtGray(); + uirectfi(xmin+2, ymin+2, xmax-2, ymax-2); + + if (vs->thumb) { + /* last thumb position */ + if ((vs->oldpos != vs->scenter) && (obj->enable)) { + + uiDkGray(); + uimove2i(xmax-2, oldsymax); + uidraw2i(xmin+1, oldsymax); + uiendline(); + + uiMmGray(); + uimove2i(xmin+1, oldsymax); + uidraw2i(xmin+1, oldsymin); + uiendline(); + + uiVyLtGray(); + uimove2i(xmin+2, oldsymin); + uidraw2i(xmax-1, oldsymin); + uiendline(); + + uiLtGray(); + uimove2i(xmax-1, oldsymin); + uidraw2i(xmax-1, oldsymax); + uiendline(); + + uiVyLtGray(); + uimove2i(xmax-2, --oldsymax); + uidraw2i(xmax-2, ++oldsymin); + uidraw2i(xmin+2, oldsymin); + uiendline(); + + uiVyDkGray(); + uimove2i(xmin+2, oldsymin); + uidraw2i(xmin+2, oldsymax); + uidraw2i(xmax-3, oldsymax); + uiendline(); + + uiDkGray(); + uimove2i(xmin+3, --oldsymax); + uidraw2i(xmax-3, oldsymax); + uiendline(); + + uiLtGray(); + uimove2i(xmax-3, oldsymax); + uidraw2i(xmax-3, ++oldsymin); + uidraw2i(xmin+3, oldsymin); + uiendline(); + + uiMmGray(); + uirectfi(xmin+3, ++oldsymin, xmax-4, --oldsymax); + + } + + if (obj->enable) { + + /* thumb */ + uiDkGray(); + uirecti(xmin,symin,xmax,symax); + + if (obj->locate == THUMB) { + drawedges(xmin+1,xmax-1,symin+1,symax-1,uiWhite,uiDkGray); + drawedges(xmin+2,xmax-2,symin+2,symax-2,uiWhite,uiLtGray); + drawedges(xmin+3,xmax-3,symin+3,symax-3,uiWhite,uiLtGray); + + uiVyLtGray(); + uirectfi(xmin+4, symin+4, xmax-4, symax-4); + + /* ridges on thumb */ + uiDkGray(); + uimove2i(xmin+3,vs->scenter); + uidraw2i(xmax-3,vs->scenter); + uiendline(); + uimove2i(xmin+3,vs->scenter-4); + uidraw2i(xmax-3,vs->scenter-4); + uiendline(); + uimove2i(xmin+3,vs->scenter+4); + uidraw2i(xmax-3,vs->scenter+4); + uiendline(); + + uiWhite(); + uirectfi(xmin+3,vs->scenter+1,xmax-3,vs->scenter+2); + uirectfi(xmin+3,vs->scenter+5,xmax-3,vs->scenter+6); + uirectfi(xmin+3,vs->scenter-2,xmax-3,vs->scenter-3); + } else { + drawedges(xmin+1,xmax-1,symin+1,symax-1,uiWhite,uiDkGray); + drawedges(xmin+2,xmax-2,symin+2,symax-2,uiVyLtGray,uiMmGray); + drawedges(xmin+3,xmax-3,symin+3,symax-3,uiVyLtGray,uiMmGray); + + uiLtGray(); + uirectfi(xmin+4, symin+4, xmax-4, symax-4); + + /* ridges on thumb */ + uiBlack(); + uimove2i(xmin+3,vs->scenter); + uidraw2i(xmax-3,vs->scenter); + uiendline(); + uimove2i(xmin+3,vs->scenter-4); + uidraw2i(xmax-3,vs->scenter-4); + uiendline(); + uimove2i(xmin+3,vs->scenter+4); + uidraw2i(xmax-3,vs->scenter+4); + uiendline(); + + uiWhite(); + uimove2i(xmin+3,vs->scenter+1); + uidraw2i(xmax-3,vs->scenter+1); + uiendline(); + uimove2i(xmin+3,vs->scenter-3); + uidraw2i(xmax-3,vs->scenter-3); + uiendline(); + uimove2i(xmin+3,vs->scenter+5); + uidraw2i(xmax-3,vs->scenter+5); + uiendline(); + } + } + } + drawvsarrows(obj); + + drawrestore(); +} + +enum muiReturnValue vshandler(muiObject *obj, int event, int value, int x, int y) +{ + int my = y; + static int mfudge=0; + static enum muiReturnValue retval = MUI_NO_ACTION; + VSlider *vs = (VSlider *)obj->object; + + if (!muiGetEnable(obj) || !muiGetVisible(obj)) + return MUI_NO_ACTION; + switch (event) { + case MUI_DEVICE_RELEASE: + if (value == 0) { + vs->oldpos = vs->scenter; + muiSetSelect(obj, 0); + return MUI_SLIDER_RETURN; + } + case MUI_DEVICE_PRESS: + case MUI_DEVICE_CLICK: + /* in the arrows */ + if (my >= obj->ymin && my <= obj->ymax && + (my < obj->ymin+ARROWHEIGHT || my > obj->ymax-ARROWHEIGHT)) { + mfudge = -10000; + if (my < obj->ymin+ARROWHEIGHT) { /* boink down */ + my = vs->scenter - vs->arrowdelta; + retval = MUI_SLIDER_SCROLLDOWN; + } else { /* boink up */ + my = vs->scenter + vs->arrowdelta; + retval = MUI_SLIDER_SCROLLUP; + } + if (event == MUI_DEVICE_CLICK) { + muiSetSelect(obj, 0); + retval = MUI_SLIDER_RETURN; + } + if (my - vs->shalf < obj->ymin+1+ARROWHEIGHT) + my = obj->ymin+1+vs->shalf+ARROWHEIGHT; + if (my + vs->shalf > obj->ymax-1-ARROWHEIGHT) + my = obj->ymax-1-vs->shalf-ARROWHEIGHT; + vs->scenter = my; + break; + } else if (my >= obj->ymin && my <= obj->ymax) + retval = MUI_SLIDER_THUMB; + vs->oldpos = vs->scenter; + if (my >= vs->scenter-vs->shalf && my <= vs->scenter+vs->shalf) + mfudge = vs->scenter - my; + else + mfudge = 0; + break; + case MUI_DEVICE_DOWN: + if (mfudge == -10000) { /* auto - repeat the arrow keys */ + if (retval == MUI_SLIDER_SCROLLDOWN) { + my = vs->scenter - vs->arrowdelta; + if (my - vs->shalf < obj->ymin+1+ARROWHEIGHT) + my = obj->ymin+1+vs->shalf+ARROWHEIGHT; + } else { + my = vs->scenter + vs->arrowdelta; + if (my + vs->shalf > obj->ymax-1-ARROWHEIGHT) + my = obj->ymax-1-vs->shalf-ARROWHEIGHT; + } + vs->scenter = my; + break; + } + my = y+mfudge; + if (my - vs->shalf < obj->ymin+1+ARROWHEIGHT) + my = obj->ymin+1+vs->shalf+ARROWHEIGHT; + if (my + vs->shalf > obj->ymax-1-ARROWHEIGHT) + my = obj->ymax-1-vs->shalf-ARROWHEIGHT; + + /* adjust thumb */ + vs->scenter = my; + break; + } + x = x; /* for lint's sake */ + return retval; +} + +float muiGetVSVal(muiObject *obj) +{ + VSlider *vs = (VSlider *)obj->object; + + return (vs->scenter-obj->ymin-1.0-vs->shalf-ARROWHEIGHT)/ + (obj->ymax - obj->ymin - 2.0*vs->shalf - 2.0-2*ARROWHEIGHT); +} + +void setvshalf(muiObject *obj, int shalf) +{ + VSlider *vs = (VSlider *)obj->object; + vs->shalf = shalf; + if (vs->shalf==0) + muiSetEnable(obj, 0); + else if (vs->shalf < MINSHALF) { + vs->shalf = MINSHALF; + muiSetEnable(obj, 1); + } else if (2*vs->shalf >= getvstrough(obj)) { + vs->shalf = getvstrough(obj)/2; + muiSetEnable(obj, 0); + } +} + +void movevsval(muiObject *obj, float val) +{ + float f; + VSlider *vs = (VSlider *)obj->object; + + if (val < 0.0) val = 0.0; + if (val > 1.0) val = 1.0; + f = val*(obj->ymax - obj->ymin - 2.0*vs->shalf - 2.0-2*ARROWHEIGHT); + vs->scenter = f + vs->shalf + obj->ymin + 1.0+ARROWHEIGHT; + + if ((vs->scenter + vs->shalf) > (obj->ymax - ARROWHEIGHT)) + vs->scenter = obj->ymax - ARROWHEIGHT - vs->shalf; + if ((vs->scenter - vs->shalf) < (obj->ymin+ ARROWHEIGHT)) + vs->scenter = obj->ymin + ARROWHEIGHT + vs->shalf; +} + +void muiSetVSValue(muiObject *obj, float val) +{ + VSlider *vs = (VSlider *)obj->object; + movevsval(obj, (float) val); + vs->oldpos = vs->scenter; +} + +/* + * visible is windowheight/dataheight + * top is top/dataheight + */ + +void +adjustvsthumb(muiObject *obj, double visible, double top) +{ + int size; + + if (visible >= 1.0) { + size = getvstrough(obj) + 1; + } else { + size = visible*getvstrough(obj); + } + muiSetEnable(obj, 1); + setvshalf(obj, size/2); + muiSetVSValue(obj, (float) (1.0 - top)); +} diff --git a/lib/glut-3.7.6/man/Imakefile b/lib/glut-3.7.6/man/Imakefile new file mode 100644 index 0000000000..451179923a --- /dev/null +++ b/lib/glut-3.7.6/man/Imakefile @@ -0,0 +1,7 @@ +#define IHaveSubdirs +#define PassCDebugFlags + +SUBDIRS = glut gle + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) diff --git a/lib/glut-3.7.6/man/gle/Imakefile b/lib/glut-3.7.6/man/gle/Imakefile new file mode 100644 index 0000000000..465ada5cac --- /dev/null +++ b/lib/glut-3.7.6/man/gle/Imakefile @@ -0,0 +1,39 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* This file is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This file is -not- in the public domain. */ + +#include "../../Glut.cf" + +MANDIR = $(LIBMANDIR) +MANSUFFIX = $(LIBMANSUFFIX)gle + +#ifdef SGIArchitecture +/* This ensures that all the GLE man pages get put in a GLE subdirectory. */ +MANPACKAGE = /GLE +#endif + +all: + @echo 'The default rule in GLUT API man page Makefile is a no-op.' + @echo 'Try "make install.man" to build and install man pages.' + +InstallManPageLong(gle,$(MANDIR),gle) +InstallManPageLong(gleExtrusion,$(MANDIR),gleExtrusion) +InstallManPageLong(gleHelicoid,$(MANDIR),gleHelicoid) +InstallManPageLong(gleLathe,XXX,gleLathe) +InstallManPageLong(glePolyCone,$(MANDIR),glePolyCone) +InstallManPageLong(glePolyCylinder,$(MANDIR),glePolyCylinder) +InstallManPageLong(gleScrew,$(MANDIR),gleScrew) +InstallManPageLong(gleSetJoinStyle,$(MANDIR),gleSetJoinStyle) +InstallManPageLong(gleSpiral,$(MANDIR),gleSpiral) +InstallManPageLong(gleSuperExtrusion,$(MANDIR),gleSuperExtrusion) +InstallManPageLong(gleTextureMode,$(MANDIR),gleTextureMode) +InstallManPageLong(gleToroid,$(MANDIR),gleToroid) +InstallManPageLong(gleTwistExtrusion,$(MANDIR),gleTwistExtrusion) + +InstallManPageAliases(gleSetJoinStyle,$(MANDIR),gleGetJoinStyle) +InstallManPageAliases(gle,$(MANDIR),intro) + +DependTarget() diff --git a/lib/glut-3.7.6/man/gle/gle.man b/lib/glut-3.7.6/man/gle/gle.man new file mode 100644 index 0000000000..c837ab3fb5 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gle.man @@ -0,0 +1,66 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gle 3GLE "3.6" "GLE" "GLE" +.SH NAME +gle - an introduction to the GLE Tubing & Extrusions Library +.SH SYNOPSIS +.nf +.LP +#include +.fi +.SH DESCRIPTION +The GLE Tubing and Extrusion Library is a graphics application +programming interface (API). The library consists of a number of "C" +language subroutines for drawing tubing and extrusions. The library is +distributed in source code form, in a package that includes +documentation, a VRML proposal, Makefiles, and full source code and +header files. It uses the OpenGL (TM) programming API to perform the +actual drawing of the tubing and extrusions. + +A "sweep" or "extrusion" is a 2D contour (polyline) that is swept or +extruded along a 3D path (polyline). For example, sweeping a circle +along a straight line will generate a cylinder. Sweeping a circle +along a circular path will generate a doughnut (torus). + +The library also includes a set of utility routines for drawing some of +the more common extruded shapes: a polycylinder, a polycone, a +generalized torus (circle swept along a helical path), a "helix" +(arbitrary contour swept along a helical path) and a "lathe" (arbitrary +contour swept along a helical path, with torsion used to keep the +contour aligned). + +The most general extrusion supported by this library allows an +arbitrary 2D contour to be swept around an arbitrary 3D path. A set of +normal vectors can be specified to go along with the contour; the +normal vectors determine the appearance of the contour when lighting is +turned on. A set of colors and affine matrices can be specified to go +along with the 3D path. The colors are used to color along the path. +The affine matrices are used to operate on the contour as it is swept +along. If no affine matrices are specified, the contour is extruded +using the mathematical concept of "parallel translation" or "Gaussian +translation". That is, the contour is moved (and drawn) along the +extrusion path in a "straight" manner. If there are affine matrices, +they are applied to the contour at each extrusion segment before the +segment is drawn. + +The affine matrices allow work in a quasi-non-Euclidean space. They +essentially allow the contour to be distorted as it is swept along. The +allow the contour to be rotated, translated and rescaled as it is +drawn. For example, a rescaling will turn a polycylinder into a +poly-cone, since the circle that is being extruded is scaled to a +different size at each extrusion vertex. A rotation allows the contour +to be spun around while it is being extruded, thus for instance +allowing drill-bit type shapes to be drawn. A translation allows the +appearance of shearing in real space; that is, taking a contour and +displacing it, without otherwise bending it. Note that the affines are +2x3 matrices, not 3x4 matrices, since they apply to the 2D contour as +it is being extruded. +.SH WEB SITE +http://linas.org/gle/index.html +.SH SEE ALSO +gleExtrusion, gleHelicoid, gleLathe, glePolyCone, glePolyCylinder, +gleScrew, gleSetJoinStyle, gleSpiral, gleSuperExtrusion, gleTextureMode, +gleToroid, gleTwistExtrusion, gleTwistExtrusion, gleSuperExtrusion +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleExtrusion.man b/lib/glut-3.7.6/man/gle/gleExtrusion.man new file mode 100644 index 0000000000..e18f59fcbb --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleExtrusion.man @@ -0,0 +1,57 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleExtrusion 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleExtrusion - Extrude arbitrary 2D contour along arbitrary 3D path. +.SH SYNTAX +.nf +.LP +void gleExtrusion (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + int npoints, + gleDouble point_array[][3], + float color_array[][3]); +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fInpoints\fP 1i +numpoints in poly-line +.IP \fIpoint_array\fP 1i +polyline vertices +.IP \fIcolor_array\fP 1i +colors at polyline verts +.SH DESCRIPTION + +Extrude arbitrary 2D contour along arbitrary 3D path. The argument +"contour" specifies the 2D contour to be extruded, while the argument +"point_array" specifies the path along which to extrude. The vector +"up" defines the orientation of the contour y-axis in real 3D space. + +Note that neither the very first segment, nor the very last segment are +drawn. The first and last segments serve only to define the angle of +the join at the very ends of the polyline. Thus, to draw one segment, +three must be specified. To draw two segments, four must be specified, +etc. + +The normal array may be NULL. If it is, normal vectors will NOT be +automatically generated, and the object will look terrible when lit. + +The color array may be NULL. If NULL, the current color is used. If not +NULL, the glColor3f() routine is used to set the color; therefore, +specifying the glColorMaterial() subroutine before this primitive can +be used to set diffuse, specular, ambient, etc. colors. + +.SH SEE ALSO +gleTwistExtrusion, gleSuperExtrusion +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleHelicoid.man b/lib/glut-3.7.6/man/gle/gleHelicoid.man new file mode 100644 index 0000000000..b3c56e48c4 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleHelicoid.man @@ -0,0 +1,48 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleHelicoid 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleHelicoid - Generalized torus, spiral with circle contour. +.SH SYNTAX +.nf +.LP +void gleHelicoid (gleDouble rToroid, + gleDouble up[3], + gleDouble startRadius, + gleDouble drdTheta, + gleDouble startZ, + gleDouble dzdTheta, + gleDouble startXform[2][3], + gleDouble dXformdTheta[2][3], + gleDouble startTheta, + gleDouble sweepTheta); +.fi +.SH ARGUMENTS +.IP \fIrToroid\fP 1i +circle contour (torus) radius +.IP \fIstartRadius\fP 1i +spiral starts in x-y plane +.IP \fIdrdTheta\fP 1i +change in radius per revolution +.IP \fIstartZ\fP 1i +starting z value +.IP \fIdzdTheta\fP 1i +change in Z per revolution +.IP \fIstartXform\fP 1i +starting contour affine transformation +.IP \fIdXformdTheta\fP 1i +tangent change xform per revolution +.IP \fIstartTheta\fP 1i +start angle in x-y plane +.IP \fIsweepTheta\fP 1i +degrees to spiral around +.SH DESCRIPTION + +Generalized Torus. Similar to gleSpiral, except contour is a circle. +Uses gleSpiral to draw. + +.SH SEE ALSO +gleSpiral, gleToroid +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleLathe.man b/lib/glut-3.7.6/man/gle/gleLathe.man new file mode 100644 index 0000000000..34a904540b --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleLathe.man @@ -0,0 +1,62 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleLathe 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleLathe - Sweep using a Z-axis shear to create an arbitrary contour along a helical path. +.SH SYNTAX +.nf +.LP +void gleLathe (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fIstartRadius\fP 1i +spiral starts in x-y plane +.IP \fIdrdTheta\fP 1i +change in radius per revolution +.IP \fIstartZ\fP 1i +starting z value +.IP \fIdzdTheta\fP 1i +change in Z per revolution +.IP \fIstartXform\fP 1i +starting contour affine transformation +.IP \fIdXformdTheta\fP 1i +tangent change xform per revolution +.IP \fIstartTheta\fP 1i +start angle in x-y plane +.IP \fIsweepTheta\fP 1i +degrees to spiral around +.SH DESCRIPTION + +Sweep an arbitrary contour along a helical path. The sweep will be +performed as a shear along the z-axis, so that the orientation of the +contour is displaced, rather than translated, as the contour is swept. + +The axis of the helix lies along the modeling coordinate z-axis. + +An affine transform can be applied as the contour is swept. For most +ordinary usage, the affines should be given as NULL. + +.SH SEE ALSO +gleSpiral +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/glePolyCone.man b/lib/glut-3.7.6/man/gle/glePolyCone.man new file mode 100644 index 0000000000..035584b25a --- /dev/null +++ b/lib/glut-3.7.6/man/gle/glePolyCone.man @@ -0,0 +1,42 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH glePolyCone 3GLE "3.6" "GLE" "GLE" +.SH NAME +glePolyCone - Draw polycone, specified as a polyline with radii. +.SH SYNTAX +.nf +.LP +void glePolyCone(int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble radius_array[]); +.fi +.SH ARGUMENTS +.IP \fInpoints\fP 1i +numpoints in poly-line +.IP \fIpoint_array\fP 1i +polyline vertices +.IP \fIcolor_array\fP 1i +colors at polyline verts +.IP \fIradius_array\fP 1i +cone radii at polyline +.SH DESCRIPTION + +Draw polycone, specified as a polyline with radii. + +Note that neither the very first segment, nor the very last segment are +drawn. The first and last segments serve only to define the angle of +the join at the very ends of the polyline. Thus, to draw one segment, +three must be specified. To draw two segments, four must be specified, +etc. + +The color array may be NULL. If NULL, the current color is used. If not +NULL, the glColor3f() routine is used to set the color; therefore, +specifying the glColorMaterial() subroutine before this primitive can +be used to set diffuse, specular, ambient, etc. colors. + +.SH SEE ALSO +glePolyCylinder +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/glePolyCylinder.man b/lib/glut-3.7.6/man/gle/glePolyCylinder.man new file mode 100644 index 0000000000..d7d7dff4a9 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/glePolyCylinder.man @@ -0,0 +1,42 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH glePolyCylinder 3GLE "3.6" "GLE" "GLE" +.SH NAME +glePolyCylinder - Draw polycylinder, specified as a polyline. +.SH SYNTAX +.nf +.LP +void glePolyCylinder(int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble radius); +.fi +.SH ARGUMENTS +.IP \fInpoints\fP 1i +numpoints in poly-line +.IP \fIpoint_array\fP 1i +polyline vertices +.IP \fIcolor_array\fP 1i +colors at polyline verts +.IP \fIradius\fP 1i +cylinder radius +.SH DESCRIPTION + +Draw polycylinder, specified as a polyline. + +Note that neither the very first segment, nor the very last segment are +drawn. The first and last segments serve only to define the angle of +the join at the very ends of the polyline. Thus, to draw one segment, +three must be specified. To draw two segments, four must be specified, +etc. + +The color array may be NULL. If NULL, the current color is used. If not +NULL, the glColor3f() routine is used to set the color; therefore, +specifying the glColorMaterial() subroutine before this primitive can +be used to set diffuse, specular, ambient, etc. colors. + +.SH SEE ALSO +glePolyCone +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleScrew.man b/lib/glut-3.7.6/man/gle/gleScrew.man new file mode 100644 index 0000000000..bc65f58b8f --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleScrew.man @@ -0,0 +1,43 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleScrew 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleScrew - Draws screw-type shapes. +.SH SYNTAX +.nf +.LP +void gleScrew (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + gleDouble startz, + gleDouble endz, + gleDouble twist); +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fIstartx\fP 1i +start of segment +.IP \fIendz\fP 1i +end of segment +.IP \fItwist\fP 1i +number of rotations +.SH DESCRIPTION + +Draws screw-type shapes. Takes a contour, and extrudes it along the +z-axis, from a start z value of startz to an end z-value of endz. +During the extrusion, it will spin the contour along the contour origin +by twist degrees. + +.SH SEE ALSO +gleExtrusion +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleSetJoinStyle.man b/lib/glut-3.7.6/man/gle/gleSetJoinStyle.man new file mode 100644 index 0000000000..726dddf2a9 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleSetJoinStyle.man @@ -0,0 +1,88 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleSetJoinStyle 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleSetJoinStyle, gleGetJoinStyle - Query and Set the GLE join style flags. +.SH SYNTAX +.nf +.LP +void gleSetJoinStyle (int style); +int gleGetJoinStyle (void); +.fi +.SH ARGUMENTS +.IP \fIstyle\fP 1i +bitwise OR of flags +.SH DESCRIPTION + +Query and set the GLE join style flags. This word is a bitwise OR of +the flags described below. + +The initial join style is TUBE_JN_ANGLE | TUBE_JN_CAP | TUBE_NORM_FACET. + +.B "Extrusion Join Styles" +.IP \fBTUBE_JN_RAW\fP +Draw polycylinders, polycones, extrusions, etc. with no special +treatment of the extrusion ends. +.IP \fBTUBE_JN_ANGLE\fP +Draw polycylinders, polycones, extrusions, etc. by extending the +different segments until they butt into each other with an +angular style. +.IP \fBTUBE_JN_CUT\fP +Draw polycylinders, polycones, extrusions, etc. by joining together the +different segments and slicing off the joint at half the angle between +the segments. A cap is drawn. Note that the slicing plane runs through +the origin of the contour coordinate system. Thus, the amount of slice +can be varied by offsetting the contour with respect to the origin. + +Note that when two segments meet at a shallow angle, the cut join style +will potentially shave off a whole lot of the contour, leading to +"surprising" results... +.IP \fBTUBE_JN_ROUND\fP +Joints will be rounded. Strictly speaking, the part of the joint above +the origin will be rounded. The part below the origin will come +together in an angular join. +.IP \fBTUBE_JN_MASK\fP +Mask bits. This can be used to mask off the bit field that defines the +join style. + +.B "End Caps" +.IP \fBTUBE_JN_CAP\fP +If this is set, a cap will be drawn at each end of the extrusion. + +.B "Automatic Normal Vector Generation" +.IP \fBTUBE_NORM_FACET\fP +A normal vector is generated per facet. Useful for having an extrusion +have a "faceted" look, such as when extruding a square -- each of the +four sides of the square will look flat. +.IP \fBTUBE_NORM_EDGE\fP +Normal vectors are generated so that they lie along edges. Useful for +making angular things look rounded under lighting. For example, when +extruding a hexagon and using this flag, the hexagonal extrusion will +look (more like a) smooth perfectly round cylinder, rather than a +six-sided shape. +.IP \fBTUBE_NORM_PATH_EDGE\fP +Normal vectors are generated so that they both lie on edges, and so +that they interpolate between neighboring segments. Useful for drawing +"spaghetti" -- extrusions that follow a spline path. Because the +spline path must be "tessellated" into small straight segments, each +segment will look straight unless this flag is set. +.IP \fBTUBE_NORM_MASK\fP +A mask useful for masking out the "norm" bits. + +.B "Closed or Open Contours" +.IP \fBTUBE_CONTOUR_CLOSED\fP +If this bit is set, the contour will be treated as a "closed" contour, +where the last point connects back up to the first. It is useful to set +this flag when drawing closed shapes (such as extruded cylinders, +star-shapes, I-Beams, etc. When drawing open extrusions (e.g. +corrugated sheet metal), you DON'T want to set this flag. + +.SH BUGS + +Multiple threads using GLE share a single global join style. + +.SH SEE ALSO +gleExtrusion, gleTextureMode +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleSpiral.man b/lib/glut-3.7.6/man/gle/gleSpiral.man new file mode 100644 index 0000000000..8f60c3f54f --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleSpiral.man @@ -0,0 +1,110 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleSpiral 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleSpiral - Sweep an arbitrary contour along a helical path. +.SH SYNTAX +.nf +.LP +void gleSpiral (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + gleDouble startRadius, /* spiral starts in x-y plane */ + gleDouble drdTheta, /* change in radius per revolution */ + gleDouble startZ, /* starting z value */ + gleDouble dzdTheta, /* change in Z per revolution */ + gleDouble startXform[2][3], /* starting contour affine xform */ + gleDouble dXformdTheta[2][3], /* tangent change xform per revoln */ + gleDouble startTheta, /* start angle in x-y plane */ + gleDouble sweepTheta); /* degrees to spiral around */ +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fIstartRadius\fP 1i +spiral starts in x-y plane +.IP \fIdrdTheta\fP 1i +change in radius per revolution +.IP \fIstartZ\fP 1i +starting z value +.IP \fIdzdTheta\fP 1i +change in Z per revolution +.IP \fIstartXform\fP 1i +starting contour affine transformation +.IP \fIdXformdTheta\fP 1i +tangent change xform per revolution +.IP \fIstartTheta\fP 1i +start angle in x-y plane +.IP \fIsweepTheta\fP 1i +degrees to spiral around +.SH DESCRIPTION + +Sweep an arbitrary contour along a helical path. + +The axis of the helix lies along the modeling coordinate z-axis. + +An affine transform can be applied as the contour is swept. For most +ordinary usage, the affines should be given as NULL. + +The "startXform[][]" is an affine matrix applied to the contour to +deform the contour. Thus, "startXform" of the form + + | cos sin 0 | + | -sin cos 0 | + +will rotate the contour (in the plane of the contour), while + + | 1 0 tx | + | 0 1 ty | + +will translate the contour, and + + | sx 0 0 | + | 0 sy 0 | + +scales along the two axes of the contour. In particular, note that + + | 1 0 0 | + | 0 1 0 | + +is the identity matrix. + +The "dXformdTheta[][]" is a differential affine matrix that is +integrated while the contour is extruded. Note that this affine matrix +lives in the tangent space, and so it should have the form of a +generator. Thus, dx/dt's of the form + + | 0 r 0 | + | -r 0 0 | + +rotate the the contour as it is extruded (r == 0 implies no rotation, r +== 2*PI implies that the contour is rotated once, etc.), while + + | 0 0 tx | + | 0 0 ty | + +translates the contour, and + + | sx 0 0 | + | 0 sy 0 | + +scales it. In particular, note that + + | 0 0 0 | + | 0 0 0 | + +is the identity matrix -- i.e. the derivatives are zero, and therefore +the integral is a constant. + +.SH SEE ALSO +gleLathe +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleSuperExtrusion.man b/lib/glut-3.7.6/man/gle/gleSuperExtrusion.man new file mode 100644 index 0000000000..b63a84b128 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleSuperExtrusion.man @@ -0,0 +1,64 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleSuperExtrusion 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleSuperExtrusion - Extrude arbitrary 2D contour along arbitrary 3D path, specifying local affine transformations. +.SH SYNTAX +.nf +.LP +void gleSuperExtrusion (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble xform_array[][2][3]); +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fInpoints\fP 1i +numpoints in poly-line +.IP \fIpoint_array\fP 1i +polyline vertices +.IP \fIcolor_array\fP 1i +colors at polyline verts +.IP \fIxform_array\fP 1i +2D contour affine transforms +.SH DESCRIPTION + +Extrude arbitrary 2D contour along arbitrary 3D path, specifying local +affine transformations. As the contour is extruded, the affine will be +applied to the points in the contour. + +The argument "contour" specifies the 2D contour to be extruded, while +the argument "point_array" specifies the path along which to extrude. +The vector "up" defines the orientation of the contour y-axis in real +3D space. + +Note that neither the very first segment, nor the very last segment are +drawn. The first and last segments serve only to define the angle of +the join at the very ends of the polyline. Thus, to draw one segment, +three must be specified. To draw two segments, four must be specified, +etc. + +The normal array may be NULL. If it is, normal vectors will NOT be +automatically generated, and the object will look terrible when lit. + +The color array may be NULL. If NULL, the current color is used. If not +NULL, the glColor3f() routine is used to set the color; therefore, +specifying the glColorMaterial() subroutine before this primitive can +be used to set diffuse, specular, ambient, etc. colors. + +.SH SEE ALSO +gleExtrusion, gleTwistExtrusion +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleTextureMode.man b/lib/glut-3.7.6/man/gle/gleTextureMode.man new file mode 100644 index 0000000000..2a3bf3ff26 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleTextureMode.man @@ -0,0 +1,160 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleTextureMode 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleTextureMode - set the type of GLE automatic texture coordinate generation. +.SH SYNTAX +.nf +.LP +void gleTextureMode (int mode); +.fi +.SH ARGUMENTS +.IP \fImode\fP 1i +bitwise OR of GLE texture mode flags +.SH DESCRIPTION + +In addition to the default glTexGen modes that are supplied by OpenGL, +the tubing library also contains some of its own automatic texture +coordinate generation routines. In addition, user-defined texture coord +generation routines can be supplied. + +To use texture mapping with the extrusion library, one must remember to "do the obvious": +.IP +Enable texture mapping through OpenGL +.IP +Define and load (glTexImage2D/glBindTexture) a texture +.IP +If using the routine below, then disable glTexgGen +.LP +gleTextureMode can be used to set the type of automatic texture +coordinate generation to be used. The argument should be a bitwise-OR +of any of the following flags: +.IP \fBGLE_TEXTURE_ENABLE\fP +If this bit is set, then texturing is enabled. If this bit is NOT set, +then automatic texture coordinate generation is disabled. +.LP +The way in which the automatic texture coordinate generation occurs is +determined by one of the following flags. One and only one of these +should be selected at a time. These tokens are enumerants, not +bit-flags. +.IP \fBGLE_TEXTURE_VERTEX_FLAT\fP +Uses the vertexes "x" coordinate as the texture "u" coordinate, and the +accumulated segment length as the "v" coordinate. +.IP \fBGLE_TEXTURE_NORMAL_FLAT\fP +Uses the normal vector's "x" coordinate as the texture "u" coordinate, +and the accumulated segment length as the "v" coordinate. +.IP \fBGLE_TEXTURE_VERTEX_CYL\fP +Uses u = phi/(2*pi) = arctan (vy/vx)/(2*pi) as the texture "u" +coordinate, and the accumulated segment length as the "v" coordinate. +In the above equation, "vx" and "vy" stand for the vertex's x and y +coordinates. +.IP \fBGLE_TEXTURE_NORMAL_CYL\fP +Uses u = phi/(2*pi) = arctan (ny/nx)/(2*pi) as the texture "u" +coordinate, and the accumulated segment length as the "v" coordinate. +In the above equation, "nx" and "ny" stand for the normal's x and y +coordinates. +.IP \fBGLE_TEXTURE_VERTEX_SPH\fP +Uses u = phi/(2*pi) = arctan (vy/vx)/(2*pi) as the texture "u" +coordinate, and v = theta/pi = (1.0 - arccos(vz))/pi as the texture "v" +coordinate. In the above equation, "vx","vy" and "vz" stand for the +vertex's x, y and z coordinates. +.IP \fBGLE_TEXTURE_NORMAL_SPH\fP +Uses u = phi/(2*pi) = arctan (ny/nx)/(2*pi) as the texture "u" +coordinate, and v = theta/pi = (1.0 - arccos(nz))/pi as the texture "v" +coordinate. In the above equation, "nx","ny" and "nz" stand for the +normal's x, y and z coordinates. +.IP \fBGLE_TEXTURE_VERTEX_MODEL_FLAT\fP +.IP \fBGLE_TEXTURE_NORMAL_MODEL_FLAT\fP +.IP \fBGLE_TEXTURE_VERTEX_MODEL_CYL\fP +.IP \fBGLE_TEXTURE_NORMAL_MODEL_CYL\fP +.IP \fBGLE_TEXTURE_VERTEX_MODEL_SPH\fP +.IP \fBGLE_TEXTURE_NORMAL_MODEL_SPH\fP +These define texture mapping modes that are very similar to those +described above, except that the untransformed vertices and/or normals +are used. As a result, textures tends to stick to the extrusion +according to the extrusions local surface coordinates rather than +according to real-space coordinates. This will in general provide the +correct style of texture mapping when affine transforms are being +applied to the contour, since the coordinates used are those prior to +the affine transform. +.SH OPERATION +To best understand how to use the above functions, it is best to +understand how the tubing is actually drawn. Let us start by defining +some terms. The tubing library "extrudes" a "contour" along a "path". +The contour is a 2D polyline. The path is a 3D polyline. We use the +word "segment" to refer to a straight-line segment of the path +polyline. We also interchangeably use the word "segment" to stand for +the section of the extrusion that lies along a path segment. + +The tubing library draws segments one at a time. It uses glPushmatrix() +and glPopmatrix() to orient each segment along the negative z-axis. The +segment starts at z=0 and ends at some negative z-value (equal to the +length of the segment). The segment is then drawn by calling +glVertex3f() (and glNormal3F()) by drawing the 2D contour at z=0 and +again at z=-len. (Of course, if the join style is one of the fancy +ones, then the end-points are trimmed in a variety of ways, and do not +land exactly on z=0, or z=-len, but they do come close). Note that +glBegin() and glEnd() are called around each segment. (Note also that +additional glBegins/Ends may be called to draw end-caps or filleting +triangles for the more complex join styles.) + +The obvious way to automatically generate textures is to warp the +glVertex() and glNormal() functions, and compute texture coordinates +based on the 3-space vertex and normal coordinates. This is essentially +what the tubing code does, except that it passes some extra parameters. +The glBegin calls are wrapped, and the integer segment number and the +floating-point length of the segment are passed in. By knowing the +segment number, and the segment length, the texture coordinates can be +adjusted. Knowing the length allows the length to be accumulated, so +that a texture is applied lengthwise along the extrusion. It is this +accumulated length that is used in the FLAT and CYL mapping modes. + +For each vertex, not only are the vertex x,y,z coordinates available, +but so is a contour vertex counter indicating which contour vertex this +corresponds to. There is also a flag indicating whether the vertex +corresponds to a front or back vertex (i.e. a z=0 or z=-len vertex). +Again, this info can be used to avoid confusion when drawing the more +complex join styles. +.SH HINTS +Here are a few hints, tips, and techniques: +.IP o +Hint: Confused? RUN THE DEMOS! The best way to understand what all the +different texture modes are doing is to see them in action. +.IP o +Hint: The texture matrix can be used to your advantage! That is, you +can use glMatrixMode(GL_TEXTURE) to control how textures are mapped to +the surface. In particular, you may/will want to use it to to rescale +the V coordinate. +.IP o +The origin of the contour will in general change the vertex x's and +y's, thus changing the texture coordinates. +.IP o +The contour "up" vector will NOT influence the texture coordinates. +.IP o +For the FLAT and CYL modes, the accumulated length really is the +accumulated length of the segments in modeling coordinates. Unless the +extrusion is very small, this length will probably be much larger than +1.0, and so the resulting texture coordinate will wrap. You will +generally want to rescale the "V" coordinate to make the texture map +fit. +.IP o +If the texture is "swimming" around on the surface in an undesired way, +try using the "MODEL" version of the texture generation flag. +.IP o +Typically, you will NOT want to use the "SPH" versions of the texture +generation engine unless you really, really have an extrusion for which +spherical coordinates are appropriate. Most uses of extrusions are best +handled with the "FLAT" and "CYL" generation methods. +.IP o +User-defined texture generation callbacks are not currently +implemented, but these should be very, very easy to hack in as desired. +It should be easy to let your imagination run wild in here. Look at +texgen.c -- what needs to be done should be obvious, I hope. When in +doubt, experiment. +.SH BUGS +Multiple threads using GLE share a single texture mode. +.SH SEE ALSO +gleExtrusion, gleSetJoinStyle +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleToroid.man b/lib/glut-3.7.6/man/gle/gleToroid.man new file mode 100644 index 0000000000..ac2e9fd96b --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleToroid.man @@ -0,0 +1,48 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleToroid 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleToroid - Generalized torus, lathe with circle contour. +.SH SYNTAX +.nf +.LP +void gleToroid (gleDouble rToroid, + gleDouble up[3], + gleDouble startRadius, + gleDouble drdTheta, + gleDouble startZ, + gleDouble dzdTheta, + gleDouble startXform[2][3], + gleDouble dXformdTheta[2][3], + gleDouble startTheta, + gleDouble sweepTheta); +.fi +.SH ARGUMENTS +.IP \fIrToroid\fP 1i +circle contour (torus) radius +.IP \fIstartRadius\fP 1i +spiral starts in x-y plane +.IP \fIdrdTheta\fP 1i +change in radius per revolution +.IP \fIstartZ\fP 1i +starting z value +.IP \fIdzdTheta\fP 1i +change in Z per revolution +.IP \fIstartXform\fP 1i +starting contour affine transformation +.IP \fIdXformdTheta\fP 1i +tangent change xform per revolution +.IP \fIstartTheta\fP 1i +start angle in x-y plane +.IP \fIsweepTheta\fP 1i +degrees to spiral around +.SH DESCRIPTION + +Generalized Torus. Similar to gleLathe, except contour is a circle. +Uses gleLathe to draw. + +.SH SEE ALSO +gleSpiral, gleHelicoid +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/gle/gleTwistExtrusion.man b/lib/glut-3.7.6/man/gle/gleTwistExtrusion.man new file mode 100644 index 0000000000..2f791df517 --- /dev/null +++ b/lib/glut-3.7.6/man/gle/gleTwistExtrusion.man @@ -0,0 +1,66 @@ +.\" +.\" GLE Tubing & Extrusions Library Documentation +.\" +.TH gleTwistExtrusion 3GLE "3.6" "GLE" "GLE" +.SH NAME +gleTwistExtrusion - Extrude arbitrary 2D contour along arbitrary 3D path, specifying local rotations (twists). +.SH SYNTAX +.nf +.LP +void gleTwistExtrusion (int ncp, + gleDouble contour[][2], + gleDouble cont_normal[][2], + gleDouble up[3], + int npoints, + gleDouble point_array[][3], + float color_array[][3], + gleDouble twist_array[]); +.fi +.SH ARGUMENTS +.IP \fIncp\fP 1i +number of contour points +.IP \fIcontour\fP 1i +2D contour +.IP \fIcont_normal\fP 1i +2D contour normals +.IP \fIup\fP 1i +up vector for contour +.IP \fInpoints\fP 1i +numpoints in poly-line +.IP \fIpoint_array\fP 1i +polyline vertices +.IP \fIcolor_array\fP 1i +colors at polyline verts +.IP \fItwist_array\fP 1i +contour twists (in degrees) +.SH DESCRIPTION + +Extrude arbitrary 2D contour along arbitrary 3D path, specifying local +rotations (twists). As the contour is extruded, it will be twisted by +the amount specified in the array "twist_array". The angles are +measured in degrees, and the rotation is about the origin of the +contour coordinate system. + +The argument "contour" specifies the 2D contour to be extruded, while +the argument "point_array" specifies the path along which to extrude. +The vector "up" defines the orientation of the contour y-axis in real +3D space. + +Note that neither the very first segment, nor the very last segment are +drawn. The first and last segments serve only to define the angle of +the join at the very ends of the polyline. Thus, to draw one segment, +three must be specified. To draw two segments, four must be specified, +etc. + +The normal array may be NULL. If it is, normal vectors will NOT be +automatically generated, and the object will look terrible when lit. + +The color array may be NULL. If NULL, the current color is used. If not +NULL, the glColor3f() routine is used to set the color; therefore, +specifying the glColorMaterial() subroutine before this primitive can +be used to set diffuse, specular, ambient, etc. colors. + +.SH SEE ALSO +gleExtrusion, gleSuperExtrusion +.SH AUTHOR +Linas Vepstas (linas@fc.net) diff --git a/lib/glut-3.7.6/man/glut/Imakefile b/lib/glut-3.7.6/man/glut/Imakefile new file mode 100644 index 0000000000..c61303f501 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/Imakefile @@ -0,0 +1,132 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* This file is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This file is -not- in the public domain. */ + +#include "../../Glut.cf" + +MANDIR = $(LIBMANDIR) +MANSUFFIX = $(LIBMANSUFFIX)glut + +#ifdef SGIArchitecture +/* This ensurs that all the GLUT man pages get put in a GLUT subdirectory. */ +MANPACKAGE = /GLUT +#endif + +all: + @echo 'The default rule in GLUT API man page Makefile is a no-op.' + @echo 'Try "make install.man" to build and install man pages.' + +InstallManPageLong(glutAddMenuEntry,$(MANDIR),glutAddMenuEntry) +InstallManPageLong(glutAddSubMenu,$(MANDIR),glutAddSubMenu) +InstallManPageLong(glutAttachMenu,$(MANDIR),glutAttachMenu) +InstallManPageLong(glutBitmapCharacter,$(MANDIR),glutBitmapCharacter) +InstallManPageLong(glutBitmapWidth,$(MANDIR),glutBitmapWidth) +InstallManPageLong(glutButtonBoxFunc,$(MANDIR),glutButtonBoxFunc) +InstallManPageLong(glutChangeToMenuEntry,$(MANDIR),glutChangeToMenuEntry) +InstallManPageLong(glutChangeToSubMenu,$(MANDIR),glutChangeToSubMenu) +InstallManPageLong(glutCopyColormap,$(MANDIR),glutCopyColormap) +InstallManPageLong(glutCreateMenu,$(MANDIR),glutCreateMenu) +InstallManPageLong(glutCreateSubWindow,$(MANDIR),glutCreateSubWindow) +InstallManPageLong(glutCreateWindow,$(MANDIR),glutCreateWindow) +InstallManPageLong(glutDestroyMenu,$(MANDIR),glutDestroyMenu) +InstallManPageLong(glutDestroyWindow,$(MANDIR),glutDestroyWindow) +InstallManPageLong(glutDeviceGet,$(MANDIR),glutDeviceGet) +InstallManPageLong(glutDialsFunc,$(MANDIR),glutDialsFunc) +InstallManPageLong(glutDisplayFunc,$(MANDIR),glutDisplayFunc) +InstallManPageLong(glutEnterGameMode,$(MANDIR),glutEnterGameMode) +InstallManPageLong(glutEntryFunc,$(MANDIR),glutEntryFunc) +InstallManPageLong(glutEstablishOverlay,$(MANDIR),glutEstablishOverlay) +InstallManPageLong(glutExtensionSupported,$(MANDIR),glutExtensionSupported) +InstallManPageLong(glutForceJoystickFunc,$(MANDIR),glutForceJoystickFunc) +InstallManPageLong(glutFullScreen,$(MANDIR),glutFullScreen) +InstallManPageLong(glutGameModeGet,$(MANDIR),glutGameModeGet) +InstallManPageLong(glutGameModeString,$(MANDIR),glutGameModeString) +InstallManPageLong(glutGet,$(MANDIR),glutGet) +InstallManPageLong(glutGetColor,$(MANDIR),glutGetColor) +InstallManPageLong(glutGetModifiers,$(MANDIR),glutGetModifiers) +InstallManPageLong(glutIdleFunc,$(MANDIR),glutIdleFunc) +InstallManPageLong(glutIgnoreKeyRepeat,$(MANDIR),glutIgnoreKeyRepeat) +InstallManPageLong(glutInit,$(MANDIR),glutInit) +InstallManPageLong(glutInitDisplayMode,$(MANDIR),glutInitDisplayMode) +InstallManPageLong(glutInitDisplayString,$(MANDIR),glutInitDisplayString) +InstallManPageLong(glutInitWindowPosition,$(MANDIR),glutInitWindowPosition) +InstallManPageLong(glutJoystickFunc,$(MANDIR),glutJoystickFunc) +InstallManPageLong(glutKeyboardFunc,$(MANDIR),glutKeyboardFunc) +InstallManPageLong(glutKeyboardUpFunc,$(MANDIR),glutKeyboardUpFunc) +InstallManPageLong(glutLayerGet,$(MANDIR),glutLayerGet) +InstallManPageLong(glutMainLoop,$(MANDIR),glutMainLoop) +InstallManPageLong(glutMenuStatusFunc,$(MANDIR),glutMenuStatusFunc) +InstallManPageLong(glutMotionFunc,$(MANDIR),glutMotionFunc) +InstallManPageLong(glutMouseFunc,$(MANDIR),glutMouseFunc) +InstallManPageLong(glutOverlayDisplayFunc,$(MANDIR),glutOverlayDisplayFunc) +InstallManPageLong(glutPopWindow,$(MANDIR),glutPopWindow) +InstallManPageLong(glutPositionWindow,$(MANDIR),glutPositionWindow) +InstallManPageLong(glutPostOverlayRedisplay,$(MANDIR),glutPostOverlayRedisplay) +InstallManPageLong(glutPostRedisplay,$(MANDIR),glutPostRedisplay) +InstallManPageLong(glutRemoveMenuItem,$(MANDIR),glutRemoveMenuItem) +InstallManPageLong(glutRemoveOverlay,$(MANDIR),glutRemoveOverlay) +InstallManPageLong(glutReportErrors,$(MANDIR),glutReportErrors) +InstallManPageLong(glutReshapeFunc,$(MANDIR),glutReshapeFunc) +InstallManPageLong(glutReshapeWindow,$(MANDIR),glutReshapeWindow) +InstallManPageLong(glutSetColor,$(MANDIR),glutSetColor) +InstallManPageLong(glutSetCursor,$(MANDIR),glutSetCursor) +InstallManPageLong(glutSetKeyRepeat,$(MANDIR),glutSetKeyRepeat) +InstallManPageLong(glutSetMenu,$(MANDIR),glutSetMenu) +InstallManPageLong(glutSetWindow,$(MANDIR),glutSetWindow) +InstallManPageLong(glutSetWindowTitle,$(MANDIR),glutSetWindowTitle) +InstallManPageLong(glutShowOverlay,$(MANDIR),glutShowOverlay) +InstallManPageLong(glutShowWindow,$(MANDIR),glutShowWindow) +InstallManPageLong(glutSolidCone,$(MANDIR),glutSolidCone) +InstallManPageLong(glutSolidCube,$(MANDIR),glutSolidCube) +InstallManPageLong(glutSolidDodecahedron,$(MANDIR),glutSolidDodecahedron) +InstallManPageLong(glutSolidIcosahedron,$(MANDIR),glutSolidIcosahedron) +InstallManPageLong(glutSolidOctahedron,$(MANDIR),glutSolidOctahedron) +InstallManPageLong(glutSolidSphere,$(MANDIR),glutSolidSphere) +InstallManPageLong(glutSolidTeapot,$(MANDIR),glutSolidTeapot) +InstallManPageLong(glutSolidTetrahedron,$(MANDIR),glutSolidTetrahedron) +InstallManPageLong(glutSolidTorus,$(MANDIR),glutSolidTorus) +InstallManPageLong(glutSpaceballButtonFunc,$(MANDIR),glutSpaceballButtonFunc) +InstallManPageLong(glutSpaceballMotionFunc,$(MANDIR),glutSpaceballMotionFunc) +InstallManPageLong(glutSpaceballRotateFunc,$(MANDIR),glutSpaceballRotateFunc) +InstallManPageLong(glutSpecialFunc,$(MANDIR),glutSpecialFunc) +InstallManPageLong(glutSpecialUpFunc,$(MANDIR),glutSpecialUpFunc) +InstallManPageLong(glutStrokeCharacter,$(MANDIR),glutStrokeCharacter) +InstallManPageLong(glutStrokeWidth,$(MANDIR),glutStrokeWidth) +InstallManPageLong(glutSwapBuffers,$(MANDIR),glutSwapBuffers) +InstallManPageLong(glutTabletButtonFunc,$(MANDIR),glutTabletButtonFunc) +InstallManPageLong(glutTabletMotionFunc,$(MANDIR),glutTabletMotionFunc) +InstallManPageLong(glutTimerFunc,$(MANDIR),glutTimerFunc) +InstallManPageLong(glutUseLayer,$(MANDIR),glutUseLayer) +InstallManPageLong(glutVisibilityFunc,$(MANDIR),glutVisibilityFunc) +InstallManPageLong(glutWarpPointer,$(MANDIR),glutWarpPointer) +InstallManPageLong(glut,$(MANDIR),glut) + +InstallManPageAliases(glutSolidCone,$(MANDIR),glutWireCone) +InstallManPageAliases(glutSolidCube,$(MANDIR),glutWireCube) +InstallManPageAliases(glutSolidDodecahedron,$(MANDIR),glutWireDodecahedron) +InstallManPageAliases(glutSolidIcosahedron,$(MANDIR),glutWireIcosahedron) +InstallManPageAliases(glutSolidOctahedron,$(MANDIR),glutWireOctahedron) +InstallManPageAliases(glutSolidSphere,$(MANDIR),glutWireSphere) +InstallManPageAliases(glutSolidTeapot,$(MANDIR),glutWireTeapot) +InstallManPageAliases(glutSolidTetrahedron,$(MANDIR),glutWireTetrahedron) +InstallManPageAliases(glutSolidTorus,$(MANDIR),glutWireTorus) + +InstallManPageAliases(glutSetWindow,$(MANDIR),glutGetWindow) +InstallManPageAliases(glutPopWindow,$(MANDIR),glutPushWindow) +InstallManPageAliases(glutShowWindow,$(MANDIR),glutHideWindow glutIconifyWindow) +InstallManPageAliases(glutSetWindowTitle,$(MANDIR),glutSetIconTitle) +InstallManPageAliases(glutShowOverlay,$(MANDIR),glutHideOverlay) +InstallManPageAliases(glutSetMenu,$(MANDIR),glutGetMenu) +InstallManPageAliases(glutAttachMenu,$(MANDIR),glutDetachMenu) +InstallManPageAliases(glutMotionFunc,$(MANDIR),glutPassiveMotionFunc) +InstallManPageAliases(glut,$(MANDIR),intro) + +InstallManPageAliases(glutBitmapWidth,$(MANDIR),glutBitmapLength) +InstallManPageAliases(glutStrokeWidth,$(MANDIR),glutStrokeLength) + +InstallManPageAliases(glutEnterGameMode,$(MANDIR),glutLeaveGameMode) + +DependTarget() diff --git a/lib/glut-3.7.6/man/glut/glut.man b/lib/glut-3.7.6/man/glut/glut.man new file mode 100644 index 0000000000..54bd981c0e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glut.man @@ -0,0 +1,247 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glut 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glut - an introduction to the OpenGL Utility Toolkit +.SH SYNOPSIS +.nf +.LP +#include +.fi +.SH DESCRIPTION +The OpenGL Utility Toolkit (GLUT) is a programming interface with ANSI C and FORTRAN bindings for writing +window system independent OpenGL programs. The toolkit supports the following functionality: +.IP +Multiple windows for OpenGL rendering. +.IP +Callback driven event processing. +.IP +Sophisticated input devices. +.IP +An ``idle'' routine and timers. +.IP +A simple, cascading pop-up menu facility. +.IP +Utility routines to generate various solid and wire frame objects. +.IP +Support for bitmap and stroke fonts. +.IP +Miscellaneous window management functions, including managing overlays. +.LP +An ANSI C implementation of GLUT for the X Window System has been +implemented by the author. Windows NT and OS/2 versions of GLUT are +also available. +.SH BACKGROUND +One of the major accomplishments in the specification of OpenGL +was the isolation of window system dependencies from OpenGL's +rendering model. The result is that OpenGL is window system independent. + +Window system operations such as the creation of a rendering window and +the handling of window system events are left to the native window system +to define. Necessary interactions between OpenGL and the window system +such as creating and binding an OpenGL context to a window are described +separately from the OpenGL specification in a window system dependent +specification. For example, the GLX specification describes the standard +by which OpenGL interacts with the X Window System. + +The predecessor to OpenGL is IRIS GL. Unlike OpenGL, IRIS GL +does specify how rendering windows are created and manipulated. IRIS +GL's windowing interface is reasonably popular largely because it is simple +to use. IRIS GL programmers can worry about graphics programming +without needing to be an expert in programming the native window system. +Experience also demonstrated that IRIS GL's windowing interface was +high-level enough that it could be retargeted to different window systems. +Silicon Graphics migrated from NeWS to the X Window System without +any major changes to IRIS GL's basic windowing interface. + +Removing window system operations from OpenGL is a sound decision +because it allows the OpenGL graphics system to be retargeted to various +systems including powerful but expensive graphics workstations as well as +mass-production graphics systems like video games, set-top boxes for +interactive television, and PCs. + +Unfortunately, the lack of a window system interface for OpenGL is a gap +in OpenGL's utility. Learning native window system APIs such as the X +Window System's Xlib or Motif can be daunting. Even those +familiar with native window system APIs need to understand the interface +that binds OpenGL to the native window system. And when an OpenGL +program is written using the native window system interface, despite the +portability of the program's OpenGL rendering code, the program itself +will be window system dependent. + +Testing and documenting OpenGL's functionality lead to the development +of the tk and aux toolkits. The aux toolkit is used in the examples found in +the OpenGL Programming Guide. Unfortunately, aux has numerous +limitations and its utility is largely limited to toy programs. The tk library +has more functionality than aux but was developed in an ad hoc fashion and +still lacks much important functionality that IRIS GL programmers expect, +like pop-up menus and overlays. + +GLUT is designed to fill the need for a window system independent +programming interface for OpenGL programs. The interface is designed to +be simple yet still meet the needs of useful OpenGL programs. Features +from the IRIS GL, aux, and tk interfaces are included to make it easy for +programmers used to these interfaces to develop programs for GLUT. +.SH PHILOSPHY +GLUT simplifies the implementation of programs using OpenGL +rendering. The GLUT application programming interface (API) requires +very few routines to display a graphics scene rendered using OpenGL. The +GLUT API (like the OpenGL API) is stateful. Most initial GLUT state is +defined and the initial state is reasonable for simple programs. + +The GLUT routines also take relatively few parameters. No pointers are +returned. The only pointers passed into GLUT are pointers to character +strings (all strings passed to GLUT are copied, not referenced) and opaque +font handles. + +The GLUT API is (as much as reasonable) window system independent. For +this reason, GLUT does not return any native window system handles, +pointers, or other data structures. More subtle window system dependencies +such as reliance on window system dependent fonts are avoided by GLUT; +instead, GLUT supplies its own (limited) set of fonts. + +For programming ease, GLUT provides a simple menu sub-API. While the +menuing support is designed to be implemented as pop-up menus, GLUT +gives window system leeway to support the menu functionality in another +manner (pull-down menus for example). + +Two of the most important pieces of GLUT state are the current window +and current menu. Most window and menu routines affect the current +window or menu respectively. Most callbacks implicitly set the current +window and menu to the appropriate window or menu responsible for the +callback. GLUT is designed so that a program with only a single window +and/or menu will not need to keep track of any window or menu identifiers. +This greatly simplifies very simple GLUT programs. + +GLUT is designed for simple to moderately complex programs focused on +OpenGL rendering. GLUT implements its own event loop. For this reason, +mixing GLUT with other APIs that demand their own event handling +structure may be difficult. The advantage of a builtin event dispatch loop is +simplicity. + +GLUT contains routines for rendering fonts and geometric objects, however +GLUT makes no claims on the OpenGL display list name space. For this +reason, none of the GLUT rendering routines use OpenGL display lists. It is +up to the GLUT programmer to compile the output from GLUT rendering +routines into display lists if this is desired. + +GLUT routines are logically organized into several sub-APIs according to +their functionality. The sub-APIs are: +.IP Initialization. +Command line processing, window system initialization, and initial +window creation state are controlled by these routines. +.IP "Beginning Event Processing." +This routine enters GLUT's event processing loop. This routine never +returns, and it continuously calls GLUT callbacks as necessary. +.IP "Window Management." +These routines create and control windows. +.IP "Overlay Management." +These routines establish and manage overlays for windows. +.IP "Menu Management." +These routines create and control pop-up menus. +.IP "Callback Registration." +These routines register callbacks to be called by the GLUT event +processing loop. +.IP "Color Index Colormap Management." +These routines allow the manipulation of color index colormaps for +windows. +.IP "State Retrieval." +These routines allows programs to retrieve state from GLUT. +.IP "Font Rendering." +These routines allow rendering of stroke and bitmap fonts. +.IP "Geometric Shape Rendering." +These routines allow the rendering of 3D geometric objects including +spheres, cones, icosahedrons, and teapots. +.SH CONVENTIONS +GLUT window and screen coordinates are expressed in pixels. The +upper left hand corner of the screen or a window is (0,0). X coordinates +increase in a rightward direction; Y coordinates increase in a +downward direction. Note: This is inconsistent with OpenGL's +coordinate scheme that generally considers the lower left hand +coordinate of a window to be at (0,0) but is consistent with most +popular window systems. + +Integer identifiers in GLUT begin with one, not zero. So window +identifiers, menu identifiers, and menu item indexes are based from +one, not zero. + +In GLUT's ANSI C binding, for most routines, basic types (int, +char*) are used as parameters. In routines where the parameters are +directly passed to OpenGL routines, OpenGL types (GLfloat) are +used. + +The header files for GLUT should be included in GLUT programs +with the following include directive: +.nf +.LP +#include +.fi +.LP +Because a very large window system software vendor (who will +remain nameless) has an apparent inability to appreciate that +OpenGL's API is independent of their window system API, portable +ANSI C GLUT programs should not directly include or +. Instead, ANSI C GLUT programs should rely on + to include the necessary OpenGL and GLU related +header files. + +The ANSI C GLUT library archive is typically named libglut.a on +Unix systems. GLUT programs need to link with the system's OpenGL +and GLUT libraries (and any libraries these libraries potentially +depend on). A set of window system dependent libraries may also be +necessary for linking GLUT programs. For example, programs using +the X11 GLUT implementation typically need to link with Xlib, the X +extension library, possibly the X Input extension library, the X +miscellaneous utilities library, and the math library. An example +X11/Unix compile line would look like: +.nf +.LP +cc -o foo foo.c -lglut -lGLU -lGL -lXmu -lXi -lXext -lX11 -lm +.fi +.SH SEE ALSO +glutAddMenuEntry, glutAddSubMenu, glutAttachMenu, glutBitmapCharacter, +glutBitmapWidth, glutButtonBoxFunc, glutChangeToMenuEntry, +glutChangeToSubMenu, glutCopyColormap, glutCreateMenu, +glutCreateSubWindow, glutCreateWindow, glutDestroyMenu, +glutDestroyWindow, glutDeviceGet, glutDialsFunc, glutDisplayFunc, +glutEntryFunc, glutEstablishOverlay, glutExtensionSupported, +glutFullScreen, glutGet, glutGetColor, glutGetModifiers, glutIdleFunc, +glutInit, glutInitDisplayMode, glutInitWindowPosition, +glutKeyboardFunc, glutLayerGet, glutMainLoop, glutMenuStatusFunc, +glutMotionFunc, glutMouseFunc, glutOverlayDisplayFunc, glutPopWindow, +glutPositionWindow, glutPostOverlayRedisplay, glutPostRedisplay, +glutRemoveMenuItem, glutRemoveOverlay, glutReshapeFunc, +glutReshapeWindow, glutSetColor, glutSetCursor, glutSetMenu, +glutSetWindow, glutSetWindowTitle, glutShowOverlay, glutShowWindow, +glutSolidCone, glutSolidCube, glutSolidDodecahedron, +glutSolidIcosahedron, glutSolidOctahedron, glutSolidSphere, +glutSolidTeapot, glutSolidTetrahedron, glutSolidTorus, +glutSpaceballButtonFunc, glutSpaceballMotionFunc, +glutSpaceballRotateFunc, glutSpecialFunc, glutStrokeCharacter, +glutStrokeWidth, glutSwapBuffers, glutTabletButtonFunc, +glutTabletMotionFunc, glutTimerFunc, glutUseLayer, glutVisibilityFunc, +.SH REFERENCES +Mark Kilgard, \fIProgramming OpenGL for the X Window System\fP, Addison-Wesley, ISBN 0-201-48359-9, 1996. + +Mark Kilgard, \fIThe OpenGL Utility Toolkit (GLUT) Programming Interface API Version 3\fP (the official GLUT specification). +.SH WEB REFERENCES +Main GLUT page +.br +http://reality.sgi.com/mjk/glut3/glut3.html + +GLUT Frequently Asked Question list +.br +http://reality.sgi.com/mjk/glut3/glut-faq.html + +The OpenGL Utility Toolkit (GLUT) Programming Interface API Version 3 +.br +http://reality.sgi.com/mjk/spec3/spec3.html +.br +http://reality.sgi.com/mjk/glut3/glut-3.spec.ps.gz + +OpenGL and X: An OpenGL Toolkit article (PostScript) +.br +http://reality.sgi.com/mjk/glut3/glut.column1.ps.gz +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutAddMenuEntry.man b/lib/glut-3.7.6/man/glut/glutAddMenuEntry.man new file mode 100644 index 0000000000..5df7c2c58a --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutAddMenuEntry.man @@ -0,0 +1,26 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutAddMenuEntry 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutAddMenuEntry - adds a menu entry to the bottom of the current menu. +.SH SYNTAX +.nf +.LP +void glutAddMenuEntry(char *name, int value); +.fi +.SH ARGUMENTS +.IP \fIname\fP 1i +ASCII character string to display in the menu entry. +.IP \fIvalue\fP 1i +Value to return to the menu's callback function if the menu +entry is selected. +.SH DESCRIPTION +glutAddMenuEntry adds a menu entry to the bottom of the current +menu. The string name will be displayed for the newly added menu +entry. If the menu entry is selected by the user, the menu's callback +will be called passing value as the callback's parameter. +.SH SEE ALSO +glutAddSubMenu, glutCreateMenu, glutChangeToMenuEntry, glutRemoveMenuItem +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutAddSubMenu.man b/lib/glut-3.7.6/man/glut/glutAddSubMenu.man new file mode 100644 index 0000000000..0446b99047 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutAddSubMenu.man @@ -0,0 +1,27 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutAddSubMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutAddSubMenu - adds a sub-menu trigger to the bottom of the current menu. +.SH SYNTAX +.nf +.LP +void glutAddSubMenu(char *name, int menu); +.fi +.SH ARGUMENTS +.IP \fIname\fP 1i +ASCII character string to display in the menu item from which +to cascade the sub-menu. +.IP \fImenu\fP 1i +Identifier of the menu to cascade from this sub-menu menu item. +.SH DESCRIPTION +glutAddSubMenu adds a sub-menu trigger to the bottom of the +current menu. The string name will be displayed for the newly added +sub-menu trigger. If the sub-menu trigger is entered, the sub-menu +numbered menu will be cascaded, allowing sub-menu menu items to +be selected. +.SH SEE ALSO +glutAddMenuEntry, glutChangeToSubMenu, glutRemoveItem +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutAttachMenu.man b/lib/glut-3.7.6/man/glut/glutAttachMenu.man new file mode 100644 index 0000000000..0bfb8963ac --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutAttachMenu.man @@ -0,0 +1,29 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutAttachMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutAttachMenu - attaches a mouse button for the current window to the +identifier of the current menu; glutDetachMenu - detaches an attached +mouse button from the current window. +.SH SYNTAX +.nf +.LP +void glutAttachMenu(int button); +void glutDetachMenu(int button); +.fi +.SH ARGUMENTS +.IP \fIbutton\fP 1i +The button to attach a menu or detach a menu. +.SH DESCRIPTION +glutAttachMenu attaches a mouse button for the current window to the +identifier of the current menu; glutDetachMenu detaches an attached +mouse button from the current window. By attaching a menu identifier to +a button, the named menu will be popped up when the user presses the +specified button. button should be one of GLUT_LEFT_BUTTON, +GLUT_MIDDLE_BUTTON, and GLUT_RIGHT_BUTTON. Note that the menu +is attached to the button by identifier, not by reference. +.SH SEE ALSO +glutCreateMenu, glutMouseFunc, glutMenuStatusFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutBitmapCharacter.man b/lib/glut-3.7.6/man/glut/glutBitmapCharacter.man new file mode 100644 index 0000000000..7aae01731e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutBitmapCharacter.man @@ -0,0 +1,102 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutBitmapCharacter 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutBitmapCharacter - renders a bitmap character using OpenGL. +.SH SYNTAX +.nf +.LP +void glutBitmapCharacter(void *font, int character); +.fi +.SH ARGUMENTS +.IP \fIfont\fP 1i +Bitmap font to use. +.IP \fIcharacter\fP 1i +Character to render (not confined to 8 bits). +.SH DESCRIPTION +Without using any display lists, glutBitmapCharacter renders the +character in the named bitmap font. The available fonts are: +.TP 8 +.B GLUT_BITMAP_8_BY_13 +A fixed width font with every character fitting in an 8 by 13 pixel +rectangle. The exact bitmaps to be used is defined by the standard X +glyph bitmaps for the X font named: + +-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_9_BY_15 +A fixed width font with every character fitting in an 9 by 15 pixel +rectangle. The exact bitmaps to be used is defined by the standard X +glyph bitmaps for the X font named: + +-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_TIMES_ROMAN_10 +A 10-point proportional spaced Times Roman font. The exact +bitmaps to be used is defined by the standard X glyph bitmaps for +the X font named: + +-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_TIMES_ROMAN_24 +A 24-point proportional spaced Times Roman font. The exact +bitmaps to be used is defined by the standard X glyph bitmaps for +the X font named: + +-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_HELVETICA_10 +A 10-point proportional spaced Helvetica font. The exact bitmaps +to be used is defined by the standard X glyph bitmaps for the X font +named: + +-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_HELVETICA_12 +A 12-point proportional spaced Helvetica font. The exact bitmaps +to be used is defined by the standard X glyph bitmaps for the X font +named: + +-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1 + +.TP 8 +.B GLUT_BITMAP_HELVETICA_18 +A 18-point proportional spaced Helvetica font. The exact bitmaps +to be used is defined by the standard X glyph bitmaps for the X font +named: + +-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1 +.LP +Rendering a nonexistent character has no effect. +glutBitmapCharacter automatically sets the OpenGL unpack pixel +storage modes it needs appropriately and saves and restores the previous +modes before returning. The generated call to glBitmap will adjust the +current raster position based on the width of the character. +.SH EXAMPLE +Here is a routine that shows how to render a string of ASCII +text with glutBitmapCharacter: +.nf +.LP + void + output(int x, int y, char *string) + { + int len, i; + + glRasterPos2f(x, y); + len = (int) strlen(string); + for (i = 0; i < len; i++) { + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]); + } + } +.fi +.LP +.SH SEE ALSO +glutBitmapWidth, glutStrokeCharacter +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutBitmapWidth.man b/lib/glut-3.7.6/man/glut/glutBitmapWidth.man new file mode 100644 index 0000000000..d87afd8ef1 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutBitmapWidth.man @@ -0,0 +1,34 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutBitmapWidth 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutBitmapWidth - returns the width of a bitmap character, +glutBitmapLength returns the length of a bitmap font string. +.SH SYNTAX +.nf +.LP +int glutBitmapWidth(void *font, int character) +int glutBitmapLength(void *font, const unsigned char *string) +.fi +.SH ARGUMENTS +.IP \fIfont\fP 1i +Bitmap font to use. For valid values, see the +glutBitmapCharacter description. +.IP \fIcharacter\fP 1i +Character to return width of (not confined to 8 bits). +.IP \fIstring\fP 1i +Text string (8-bit characters), nul terminated. +.SH DESCRIPTION +glutBitmapWidth returns the width in pixels of a bitmap character in +a supported bitmap font. While the width of characters in a font may vary +(though fixed width fonts do not vary), the maximum height +characteristics of a particular font are fixed. + +glutBitmapLength returns the length in pixels of a string (8-bit +characters). This length is equivalent to summing all the widths +returned by glutBitmapWidth for each character in the string. +.SH SEE ALSO +glutBitmapCharacter, glutStrokeWidth +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutButtonBoxFunc.man b/lib/glut-3.7.6/man/glut/glutButtonBoxFunc.man new file mode 100644 index 0000000000..f5742a7cd6 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutButtonBoxFunc.man @@ -0,0 +1,37 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutButtonBoxFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutButtonBoxFunc - sets the dial & button box button callback for the current window. +.SH SYNTAX +.nf +.LP +void glutButtonBoxFunc(void (*func)(int button, int state)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new button box callback function. +.SH DESCRIPTION +glutButtonBoxFunc sets the dial & button box button callback for the +current window. The dial & button box button callback for a window is +called when the window has dial & button box input focus (normally, +when the mouse is in the window) and the user generates dial & button +box button presses. The button parameter will be the button number +(starting at one). The number of available dial & button box buttons can +be determined with +glutDeviceGet(GLUT_NUM_BUTTON_BOX_BUTTONS). The state is +either GLUT_UP or GLUT_DOWN indicating whether the callback was due +to a release or press respectively. + +Registering a dial & button box button callback when a dial & button +box device is not available is ineffectual and not an error. In this case, no +dial & button box button callbacks will be generated. + +Passing NULL to glutButtonBoxFunc disables the generation of dial & +button box button callbacks. When a new window is created, no dial & +button box button callback is initially registered. +.SH SEE ALSO +glutDialsFunc, glutDeviceGet, glutSpaceballButtonFunc, glutTabletButtonFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutChangeToMenuEntry.man b/lib/glut-3.7.6/man/glut/glutChangeToMenuEntry.man new file mode 100644 index 0000000000..409068a321 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutChangeToMenuEntry.man @@ -0,0 +1,32 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutChangeToMenuEntry 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutChangeToMenuEntry - changes the specified menu item in +the current menu into a menu entry. +.SH SYNTAX +.nf +.LP +void glutChangeToMenuEntry(int entry, char *name, int value); +.fi +.SH ARGUMENTS +.IP \fIentry\fP 1i +Index into the menu items of the current menu (1 is the topmost menu item). +.IP \fIname\fP 1i +ASCII character string to display in the menu entry. +.IP \fIvalue\fP 1i +Value to return to the menu's callback function if the menu entry is selected. +.SH DESCRIPTION +glutChangeToMenuEntry changes the specified menu entry in the +current menu into a menu entry. The entry parameter determines which +menu item should be changed, with one being the topmost item. entry +must be between 1 and glutGet(GLUT_MENU_NUM_ITEMS) inclusive. +The menu item to change does not have to be a menu entry already. The +string name will be displayed for the newly changed menu entry. The +value will be returned to the menu's callback if this menu entry is +selected. +.SH SEE ALSO +glutChangeToSubMenu, glutAddMenuEntry, glutRemoveMenuItem +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutChangeToSubMenu.man b/lib/glut-3.7.6/man/glut/glutChangeToSubMenu.man new file mode 100644 index 0000000000..e735bd137f --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutChangeToSubMenu.man @@ -0,0 +1,32 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutChangeToSubMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutChangeToSubMenu - changes the specified menu item in the current +menu into a sub-menu trigger. +.SH SYNTAX +.nf +.LP +void glutChangeToSubMenu(int entry, char *name, int menu); +.fi +.SH ARGUMENTS +.IP \fIentry\fP 1i +Index into the menu items of the current menu (1 is the topmost menu item). +.IP \fIname\fP 1i +ASCII character string to display in the menu item to cascade the sub-menu from. +.IP \fImenu\fP 1i +Identifier of the menu to cascade from this sub-menu menu item. +.SH DESCRIPTION +glutChangeToSubMenu changes the specified menu item in the current +menu into a sub-menu trigger. The entry parameter determines which +menu item should be changed, with one being the topmost item. entry +must be between 1 and glutGet(GLUT_MENU_NUM_ITEMS) inclusive. +The menu item to change does not have to be a sub-menu trigger already. +The string name will be displayed for the newly changed sub-menu +trigger. The menu identifier names the sub-menu to cascade from the +newly added sub-menu trigger. +.SH SEE ALSO +glutChangeToMenuEntry, glutAddSubMenu, glutRemoveMenuItem +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutCopyColormap.man b/lib/glut-3.7.6/man/glut/glutCopyColormap.man new file mode 100644 index 0000000000..a1d055905e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutCopyColormap.man @@ -0,0 +1,47 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutCopyColormap 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutCopyColormap - copies the logical colormap for the layer in use +from a specified window to the current window. +.SH SYNTAX +.nf +.LP +void glutCopyColormap(int win); +.fi +.SH ARGUMENTS +.IP \fIwin\fP 1i +The identifier of the window to copy the logical colormap from. +.SH DESCRIPTION +glutCopyColormap copies (lazily if possible to promote sharing) the +logical colormap from a specified window to the current window's layer +in use. The copy will be from the normal plane to the normal plane; or +from the overlay to the overlay (never across different layers). Once a +colormap has been copied, avoid setting cells in the colormap with +glutSetColor since that will force an actual copy of the colormap if it +was previously copied by reference. glutCopyColormap should only +be called when both the current window and the win window are color +index windows. +.SH EXAMPLE +Here is an example of how to create two color index GLUT windows with +their colormaps loaded identically and so that the windows are +likely to share the same colormap: +.nf +.LP + int win1, win2; + + glutInitDisplayMode(GLUT_INDEX); + win1 = glutCreateWindow("first color index win"); + glutSetColor(0, 0.0, 0.0, 0.0); /* black */ + glutSetColor(1, 0.5, 0.5, 0.5); /* gray */ + glutSetColor(2, 1.0, 1.0, 1.0); /* black */ + glutSetColor(3, 1.0, 0.0, 0.0); /* red */ + win2 = glutCreateWindow("second color index win"); + glutCopyColormap(win1); +.fi +.LP +.SH SEE ALSO +glutSetColor, glutGetColor, glutCreateWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutCreateMenu.man b/lib/glut-3.7.6/man/glut/glutCreateMenu.man new file mode 100644 index 0000000000..b8762ad1b1 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutCreateMenu.man @@ -0,0 +1,61 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutCreateMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutCreateMenu - creates a new pop-up menu. +.SH SYNTAX +.nf +.LP +int glutCreateMenu(void (*func)(int value)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The callback function for the menu that is called when a menu +entry from the menu is selected. The value passed to the +callback is determined by the value for the selected menu +entry. +.SH DESCRIPTION +glutCreateMenu creates a new pop-up menu and returns a unique +small integer identifier. The range of allocated identifiers starts at +one. The menu identifier range is separate from the window +identifier range. Implicitly, the current menu is set to the newly +created menu. This menu identifier can be used when calling +glutSetMenu. + +When the menu callback is called because a menu entry is selected +for the menu, the current menu will be implicitly set to the menu +with the selected entry before the callback is made. +.SH EXAMPLE +Here is a quick example of how to create a GLUT popup menu with +two submenus and attach it to the right button of the current window: +.nf +.LP + int submenu1, submenu2; + + submenu1 = glutCreateMenu(selectMessage); + glutAddMenuEntry("abc", 1); + glutAddMenuEntry("ABC", 2); + submenu2 = glutCreateMenu(selectColor); + glutAddMenuEntry("Green", 1); + glutAddMenuEntry("Red", 2); + glutAddMenuEntry("White", 3); + glutCreateMenu(selectFont); + glutAddMenuEntry("9 by 15", 0); + glutAddMenuEntry("Times Roman 10", 1); + glutAddMenuEntry("Times Roman 24", 2); + glutAddSubMenu("Messages", submenu1); + glutAddSubMenu("Color", submenu2); + glutAttachMenu(GLUT_RIGHT_BUTTON); +.fi +.LP +.SH X IMPLEMENTATION NOTES +If available, GLUT for X will take advantage of overlay planes for +implementing pop-up menus. The use of overlay planes can +eliminate display callbacks when pop-up menus are deactivated. The +SERVER_OVERLAY_VISUALS convention is used to determine +if overlay visuals are available. +.SH SEE ALSO +glutCreateWindow, glutDestroyMenu, glutSetMenu, glutAttachMenu +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutCreateSubWindow.man b/lib/glut-3.7.6/man/glut/glutCreateSubWindow.man new file mode 100644 index 0000000000..a9e5273ccc --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutCreateSubWindow.man @@ -0,0 +1,47 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutCreateSubWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutCreateSubWindow - creates a subwindow. +.SH SYNTAX +.nf +.LP +int glutCreateSubWindow(int win, + int x, int y, int width, int height); +.fi +.SH ARGUMENTS +.IP \fIwin\fP 1i +Identifier of the subwindow's parent window. +.IP \fIx\fP 1i +Window X location in pixels relative to parent window's origin. +.IP \fIy\fP 1i +Window Y location in pixels relative to parent window's origin. +.IP \fIwidth\fP 1i +Width in pixels. +.IP \fIheight\fP 1i +Height in pixels. +.SH DESCRIPTION +glutCreateSubWindow creates a subwindow of the window identified +by win of size width and height at location x and y within the current +window. Implicitly, the current window is set to the newly created +subwindow. + +Each created window has a unique associated OpenGL context. State +changes to a window's associated OpenGL context can be done +immediately after the window is created. + +The display state of a window is initially for the window to be shown. +But the window's display state is not actually acted upon until +glutMainLoop is entered. This means until glutMainLoop is called, +rendering to a created window is ineffective. Subwindows can not be +iconified. + +Subwindows can be nested arbitrarily deep. + +The value returned is a unique small integer identifier for the window. +The range of allocated identifiers starts at one. +.SH SEE ALSO +glutCreateWindow, glutDestroyWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutCreateWindow.man b/lib/glut-3.7.6/man/glut/glutCreateWindow.man new file mode 100644 index 0000000000..0d39863d37 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutCreateWindow.man @@ -0,0 +1,43 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutCreateWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutCreateWindow - creates a top-level window. +.SH SYNTAX +.nf +.LP +int glutCreateWindow(char *name); +.fi +.SH ARGUMENTS +.IP \fIname\fP 1i +ASCII character string for use as window name. +.SH DESCRIPTION +glutCreateWindow creates a top-level window. The +name will be provided to the window system as the window's name. The +intent is that the window system will label the window with the name. + +Implicitly, the current window is set to the newly created window. + +Each created window has a unique associated OpenGL context. State +changes to a window's associated OpenGL context can be done +immediately after the window is created. + +The display state of a window is initially for the window to be shown. +But the window's display state is not actually acted upon until +glutMainLoop is entered. This means until glutMainLoop is called, +rendering to a created window is ineffective because the window can not +yet be displayed. + +The value returned is a unique small integer identifier for the window. +The range of allocated identifiers starts at one. This window identifier +can be used when calling glutSetWindow. +.SH X IMPLEMENTATION NOTES +The proper X Inter-Client Communication Conventions Manual +(ICCCM) top-level properties are established. The WM_COMMAND +property that lists the command line used to invoke the GLUT program +is only established for the first window created. +.SH SEE ALSO +glutCreateSubWindow, glutCreateMenu, glutDestroyWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutDestroyMenu.man b/lib/glut-3.7.6/man/glut/glutDestroyMenu.man new file mode 100644 index 0000000000..55d5a6ccd3 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutDestroyMenu.man @@ -0,0 +1,22 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutDestroyMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutDestroyMenu - destroys the specified menu. +.SH SYNTAX +.nf +.LP +void glutDestroyMenu(int menu); +.fi +.SH ARGUMENTS +.IP \fImenu\fP 1i +The identifier of the menu to destroy. +.SH DESCRIPTION +glutDestroyMenu destroys the specified menu by menu. If menu +was the current menu, the current menu becomes invalid and +glutGetMenu will return zero. +.SH SEE ALSO +glutCreateMenu, glutDestroyWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutDestroyWindow.man b/lib/glut-3.7.6/man/glut/glutDestroyWindow.man new file mode 100644 index 0000000000..5c30e67796 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutDestroyWindow.man @@ -0,0 +1,25 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutDestroyWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutDestroyWindow - destroys the specified window. +.SH SYNTAX +.nf +.LP +void glutDestroyWindow(int win); +.fi +.SH ARGUMENTS +.IP \fIwin\fP 1i +Identifier of GLUT window to destroy. +.SH DESCRIPTION +glutDestroyWindow destroys the window specified by win and the +window's associated OpenGL context, logical colormap (if the window +is color index), and overlay and related state (if an overlay has been +established). Any subwindows of destroyed windows are also destroyed +by glutDestroyWindow. If win was the current window, the current +window becomes invalid ( glutGetWindow will return zero). +.SH SEE ALSO +glutCreateWindow, glutCreateSubWindow, glutDestroyMenu +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutDeviceGet.man b/lib/glut-3.7.6/man/glut/glutDeviceGet.man new file mode 100644 index 0000000000..e689055fcc --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutDeviceGet.man @@ -0,0 +1,85 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996, 1998. +.\" +.TH glutDeviceGet 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutDeviceGet - retrieves GLUT device information represented by integers. +.SH SYNTAX +.nf +.LP +int glutDeviceGet(GLenum info); +.fi +.SH ARGUMENTS +.IP \fIinfo\fP 1i +Name of device information to retrieve. +.TP 8 +.B GLUT_HAS_KEYBOARD +Non-zero if a keyboard is available; zero if not available. For most +GLUT implementations, a keyboard can be assumed. +.TP 8 +.B GLUT_HAS_MOUSE +Non-zero if a mouse is available; zero if not available. For most GLUT +implementations, a keyboard can be assumed. +.TP 8 +.B GLUT_HAS_SPACEBALL +Non-zero if a Spaceball is available; zero if not available. +.TP 8 +.B GLUT_HAS_DIAL_AND_BUTTON_BOX +Non-zero if a dial & button box is available; zero if not available. +.TP 8 +.B GLUT_HAS_TABLET +Non-zero if a tablet is available; zero if not available. +.TP 8 +.B GLUT_NUM_MOUSE_BUTTONS +Number of buttons supported by the mouse. If no mouse is supported, zero is +returned. +.TP 8 +.B GLUT_NUM_SPACEBALL_BUTTONS +Number of buttons supported by the Spaceball. If no Spaceball is supported, zero is +returned. +.TP 8 +.B GLUT_NUM_BUTTON_BOX_BUTTONS +Number of buttons supported by the dial & button box device. If no dials & button +box device is supported, zero is returned. +.TP 8 +.B GLUT_NUM_DIALS +Number of dials supported by the dial & button box device. If no dials & button +box device is supported, zero is returned. +.TP 8 +.B GLUT_NUM_TABLET_BUTTONS +Number of buttons supported by the tablet. If no tablet is supported, zero is +returned. +.TP 8 +.B GLUT_DEVICE_IGNORE_KEY_REPEAT +Returns true if the current window's auto repeated keys are ignored. +This state is controlled by glutIgnoreKeyRepeat. +.TP 8 +.B GLUT_DEVICE_KEY_REPEAT +The window system's global key repeat state. Returns either GLUT_KEY_REPEAT_OFF, GLUT_KEY_REPEAT_ON, or GLUT_KEY_REPEAT_DEFAULT. This will not necessarily return the value last passed to glutSetKeyRepeat. +.TP 8 +.B GLUT_JOYSTICK_POLL_RATE +Returns the current window's joystick poll rate as set by glutJoystickFunc. If no joystick is supported, the poll rate will always be zero. The joystick poll +rate also returns zero if the poll rate last specified to glutJoystickFunc is negative or a NULL callback was registered. +.TP 8 +.B GLUT_HAS_JOYSTICK +Non-zero if a joystick is available; zero if not available. +.TP 8 +.B GLUT_JOYSTICK_BUTTONS +Number of buttons supported by the joystick. If no joystick is supported, zero is returned. +.TP 8 +.B GLUT_JOYSTICK_AXES +Number of axes supported by the joystick. If no joystick is supposrted, zero is returned. +.SH DESCRIPTION +glutDeviceGet retrieves GLUT device information represented by integers. The info +parameter determines what type of device information to return. Requesting device +information for an invalid GLUT device information name returns negative one. +.SH X IMPLEMENTATION NOTES +The current implementation uses to X Input extension to regonize SGI's Spaceball, +tablet, and dial and button box devices. +.SH WIN32 IMPLEMENTATION NOTES +The GLUT_DEVICE_KEY_REPEAT alwasy returns GLUT_KEY_REPEAT_ON. +.SH SEE ALSO +glutGet, glutKeyboardFunc, glutMouseFunc, glutSpaceballMotion, glutTabletMotionFunc, glutTabletButtonFunc, +glutDialsFunc, glutButtonBoxFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, glutJoystickFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutDialsFunc.man b/lib/glut-3.7.6/man/glut/glutDialsFunc.man new file mode 100644 index 0000000000..e7bf9268d2 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutDialsFunc.man @@ -0,0 +1,37 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutDialsFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutDialsFunc - sets the dial & button box dials callback for the current window. +.SH SYNTAX +.nf +.LP +void glutDialsFunc(void (*func)(int dial, int value)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new dials callback function. +.SH DESCRIPTION +glutDialsFunc sets the dial & button box dials callback for the +current window. The dial & button box dials callback for a window is +called when the window has dial & button box input focus (normally, +when the mouse is in the window) and the user generates dial & button +box dial changes. The dial parameter will be the dial number (starting +at one). The number of available dial & button box dials can be +determined with glutDeviceGet(GLUT_NUM_DIALS). The value +measures the absolute rotation in degrees. Dial values do not ``roll over'' +with each complete rotation but continue to accumulate degrees (until the +int dial value overflows). + +Registering a dial & button box dials callback when a dial & button box +device is not available is ineffectual and not an error. In this case, no dial +& button box dials callbacks will be generated. + +Passing NULL to glutDialsFunc disables the generation of dial & +button box dials callbacks. When a new window is created, no dial & +button box dials callback is initially registered. +.SH SEE ALSO +glutButtonBoxFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutDisplayFunc.man b/lib/glut-3.7.6/man/glut/glutDisplayFunc.man new file mode 100644 index 0000000000..5753bf70eb --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutDisplayFunc.man @@ -0,0 +1,59 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutDisplayFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutDisplayFunc - sets the display callback for the current window. +.SH SYNTAX +.nf +.LP +void glutDisplayFunc(void (*func)(void)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new display callback function. +.SH DESCRIPTION +glutDisplayFunc sets the display callback for the current window. +When GLUT determines that the normal plane for the window needs to be +redisplayed, the display callback for the window is called. Before the +callback, the current window is set to the window needing to be +redisplayed and (if no overlay display callback is registered) the layer in +use is set to the normal plane. The display callback is called with no +parameters. The entire normal plane region should be redisplayed in +response to the callback (this includes ancillary buffers if your program +depends on their state). + +GLUT determines when the display callback should be triggered based on +the window's redisplay state. The redisplay state for a window can be +either set explicitly by calling glutPostRedisplay or implicitly as the +result of window damage reported by the window system. Multiple posted +redisplays for a window are coalesced by GLUT to minimize the number +of display callbacks called. + +When an overlay is established for a window, but there is no overlay +display callback registered, the display callback is used for redisplaying +both the overlay and normal plane (that is, it will be called if either the +redisplay state or overlay redisplay state is set). In this case, the layer in +use is not implicitly changed on entry to the display callback. + +See glutOverlayDisplayFunc to understand how distinct callbacks +for the overlay and normal plane of a window may be established. + +When a window is created, no display callback exists for the window. It is +the responsibility of the programmer to install a display callback for the +window before the window is shown. A display callback must be +registered for any window that is shown. If a window becomes displayed +without a display callback being registered, a fatal error occurs. Passing +NULL to glutDisplayFunc is illegal as of GLUT 3.0; there is no way to +``deregister'' a display callback (though another callback routine can +always be registered). + +Upon return from the display callback, the normal damaged state of the +window (returned by calling glutLayerGet(GLUT_NORMAL_DAMAGED) +is cleared. If there is no overlay display callback registered the overlay +damaged state of the window (returned by calling +glutLayerGet(GLUT_OVERLAY_DAMAGED) is also cleared. +.SH SEE ALSO +glutCreateMenu, glutPostRedisplay, glutOverlayDisplayFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutEnterGameMode.man b/lib/glut-3.7.6/man/glut/glutEnterGameMode.man new file mode 100644 index 0000000000..db46602d42 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutEnterGameMode.man @@ -0,0 +1,72 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutEnterGameMode 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutEnterGameMode, glutLeaveGameMode - enters and leaves GLUT's game mode. +.SH SYNTAX +.nf +.LP +void glutEnterGameMode(void); +void glutLeaveGameMode(void); +.fi +.SH DESCRIPTION + +glutEnterGameMode is designed to enable high-performance fullscreen GLUT rendering, possibly +at a different screen display format. Calling glutEnterGameMode creates a +special fullscreen GLUT window (with its own callbacks and OpenGL rendering context +state). If the game mode string describes a possible screen display format, +GLUT also changes the screen display format to the one described by the +game mode string. glutLeaveGameMode leaves the GLUT game mode and returns the +screen display format to its default format. + +When game mode is entered, certain GLUT functionality is disable to facilitate +high-performance fullscreen rendering. GLUT pop-up menus are not available +while in game mode. Other created windows and subwindows are not displayed +in GLUT game mode. Game mode will also hide all other applications running +on the computer's display screen. +The intent of these restrictions is to eliminate window +clipping issues, permit screen display format changes, +and permit fullscreen +rendering optimization such as page flipping for fullscreen buffer swaps. + +After leaving game mode, the GLUT functionality disabled in game mode is +available again. The game mode window (and its OpenGL rendering state) is +destroyed when leaving game mode. Any windows and subwindows created before +entering the game mode are displayed in their previous locations. The OpenGL +state of normal GLUT windows and subwindows is not disturbed by entering +and/or leaving game mode. + +The following GLUT routines are ignored in game mode: glutFullScreen, +glutSetWindowTitle, glutSetIconTitle, glutPositionWindow, glutReshapeWindow, +glutPopWindow, glutPushWindow, glutIconifyWindow, glutShowWindow, +glutHideWindow. + +glutEnterGameMode can be called when already in game mode. This will destroy +the previous game mode window (including any OpenGL rendering state) and +create a new game mode window with a new OpenGL rendering context. +Also if glutEnterGameMode is called when already in game mode and if the game mode +string has changed and describes a possible screen display format, the new +screen display format takes effect. A reshape callback is generated if the +game mode window changes size due to a screen display format change. + +Re-entering game mode provides a mechanism for changing the screen display +format while already in game mode. Note though that the game mode window's +OpenGL state is lost in this process and the application is responsible for +re-initializing the newly created game mode window OpenGL state when +re-entering game mode. + +Game mode cannot be entered while pop-up menus are in use. + +Note that the glutEnterGameMode and glutFullScreen routines operate differently. +glutFullScreen simply makes the current window match the size of the screen. +glutFullScreen does not change the screen display format and does not disable +any GLUT features such as pop-up menus; glutFullScreen continues to operate +in a "windowed" mode of operation. glutEnterGameMode creates a new window +style, possibly changes the screen display mode, limits GLUT functionality, +and hides other applications. + +.SH SEE ALSO +glutGameModeGet, glutGameModeString, glutInitDisplayString +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutEntryFunc.man b/lib/glut-3.7.6/man/glut/glutEntryFunc.man new file mode 100644 index 0000000000..e357ee2325 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutEntryFunc.man @@ -0,0 +1,31 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutEntryFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutEntryFunc - sets the mouse enter/leave callback for the current window. +.SH SYNTAX +.nf +.LP +void glutEntryFunc(void (*func)(int state)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new entry callback function. +.SH DESCRIPTION +glutEntryFunc sets the mouse enter/leave callback for the current +window. The state callback parameter is either GLUT_LEFT or +GLUT_ENTERED depending on if the mouse pointer has last left or entered +the window. + +Passing NULL to glutEntryFunc disables the generation of the mouse +enter/leave callback. + +Some window systems may not generate accurate enter/leave callbacks. +X IMPLEMENTATION NOTES +An X implementation of GLUT should generate accurate enter/leave +callbacks. +.SH SEE ALSO +glutMotionFunc, glutCreateWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutEstablishOverlay.man b/lib/glut-3.7.6/man/glut/glutEstablishOverlay.man new file mode 100644 index 0000000000..db4dc883d6 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutEstablishOverlay.man @@ -0,0 +1,97 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutEstablishOverlay 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutEstablishOverlay - establishes an overlay (if possible) for the +current window. +.SH SYNTAX +.nf +.LP +void glutEstablishOverlay(void); +.fi +.SH DESCRIPTION +glutEstablishOverlay establishes an overlay (if possible) for the +current window. The requested display mode for the overlay is +determined by the initial display mode. +glutLayerGet(GLUT_OVERLAY_POSSIBLE) can be called to +determine if an overlay is possible for the current window with the +current initial display mode. Do not attempt to establish an overlay when +one is not possible; GLUT will terminate the program. + +If glutEstablishOverlay is called when an overlay already exists, +the existing overlay is first removed, and then a new overlay is +established. The state of the old overlay's OpenGL context is discarded. + +The initial display state of an overlay is shown, however the overlay is +only actually shown if the overlay's window is shown. + +Implicitly, the window's layer in use changes to the overlay immediately +after the overlay is established. +.SH EXAMPLE +Establishing an overlay is a bit involved, but easy once you get the +hang of it. Here is an example: +.nf +.LP + int overlaySupport; + int transparent, red, white; + + glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX); + overlaySupport = glutLayerGet(GLUT_OVERLAY_POSSIBLE); + if (overlaySupport) { + glutEstablishOverlay(); + glutHideOverlay(); + transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX); + glClearIndex(transparent); + red = (transparent + 1) % glutGet(GLUT_WINDOW_COLORMAP_SIZE); + white = (transparent + 2) % glutGet(GLUT_WINDOW_COLORMAP_SIZE); + glutSetColor(red, 1.0, 0.0, 0.0); /* Red. */ + glutSetColor(white, 1.0, 1.0, 1.0); /* White. */ + glutOverlayDisplayFunc(redrawOverlay); + glutReshapeFunc(reshape); + } else { + printf("Sorry, no nifty overlay (try an SGI workstation)!\n"); + } +.fi +.LP +If you setup an overlay and you install a reshape callback, you need +to update the viewports and possibly projection matrices of both the +normal plane and the overlay. For example, your reshape callback +might look like this: +.nf +.LP + void + reshape(int w, int h) + { + if (overlaySupport) { + glutUseLayer(GLUT_OVERLAY); + /* Setup overlay to have X style coordinate system. */ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, w, 0, h); + glScalef(1, -1, 1); + glTranslatef(0, -h, 0); + glMatrixMode(GL_MODELVIEW); + glutUseLayer(GLUT_NORMAL); + } + glViewport(0, 0, w, h); + } +.fi +.LP +See the glutOverlayDisplayFunc man page for an example showing one way to write +your overlay display callback. +.SH X IMPLEMENTATION NOTES +GLUT for X uses the SERVER_OVERLAY_VISUALS convention is +used to determine if overlay visuals are available. While the convention +allows for opaque overlays (no transparency) and overlays with the +transparency specified as a bitmask, GLUT overlay management only +provides access to transparent pixel overlays. + +Until RGBA overlays are better understood, GLUT only supports color +index overlays. +.SH SEE ALSO +glutUseLayer, glutRemoveLayer, glutCreateWindow, glutPostOverlayRedisplay, glutShowOverlay, +glutOverlayDisplayFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutExtensionSupported.man b/lib/glut-3.7.6/man/glut/glutExtensionSupported.man new file mode 100644 index 0000000000..1f5eca64cc --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutExtensionSupported.man @@ -0,0 +1,49 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutExtensionSupported 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutExtensionSupported - helps to easily determine whether a +given OpenGL extension is supported. +.SH SYNTAX +.nf +.LP +int glutExtensionSupported(char *extension); +.fi +.SH ARGUMENTS +.IP \fIextension\fP 1i +Name of OpenGL extension. +.SH DESCRIPTION +glutExtensionSupported helps to easily determine whether a +given OpenGL extension is supported or not. The extension +parameter names the extension to query. The supported extensions can +also be determined with glGetString(GL_EXTENSIONS), but +glutExtensionSupported does the correct parsing of the returned +string. + +glutExtensionSupported returns non-zero if the extension is +supported, zero if not supported. + +There must be a valid current window to call +glutExtensionSupported. + +glutExtensionSupported only returns information about OpenGL +extensions only. This means window system dependent extensions (for +example, GLX extensions) are not reported by +glutExtensionSupported. +.SH EXAMPLE +Here is an example of using glutExtensionSupported: +.nf +.LP + if (!glutExtensionSupported("GL_EXT_texture")) { + fprintf(stderr, "Missing the texture extension!\\n"); + exit(1); + } + +.fi +Notice that the name argument includes both the GL prefix and the +extension family prefix (EXT). +.SH SEE ALSO +glutGet, glGetString +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutForceJoystickFunc.man b/lib/glut-3.7.6/man/glut/glutForceJoystickFunc.man new file mode 100644 index 0000000000..0e94fb5df0 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutForceJoystickFunc.man @@ -0,0 +1,40 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutForceJoystickFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutForceJoystickFunc - forces current window's joystick callback to be called. +.SH SYNTAX +.nf +.LP +void glutForceJoystickFunc(void); +.fi +.SH DESCRIPTION +glutForceJoystickFunc forces the current window's joystick callback to be +called, reporting the latest joystick state. + +The joystick callback is called either due to polling of the joystick +at the uniform timer interval set by glutJoystickFunc's +pollInterval (specified in milliseconds) or +in response to calling glutForceJoystickFunc. If the pollInterval is +non-positive, no joystick polling is performed and the GLUT application +must frequently (usually from an idle callback) call glutForceJoystickFunc. + +The joystick callback will be called once (if one exists) +for each time glutForceJoystickFunc is called. The callback is called +from glutJoystickFunc. That is, when glutJoystickFunc returns, the +callback will have already happened. +.SH GLUT IMPLEMENTATION NOTES FOR X11 +The GLUT 3.7 implementation of GLUT for X11 supports the joystick API, but +not actual joystick input. A future implementation of GLUT for X11 may +add joystick support. +.SH GLUT IMPLEMENTATION NOTES FOR WIN32 +The GLUT 3.7 implementation of GLUT for Win32 supports the joystick API +and joystick input, but does so through the dated joySetCapture and +joyGetPosEx Win32 Multimedia API. The GLUT 3.7 joystick support for +Win32 has all the limitations of the Win32 Multimedia API joystick support. +A future implementation of GLUT for Win32 may use DirectInput. +.SH SEE ALSO +glutJoystickFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutFullScreen.man b/lib/glut-3.7.6/man/glut/glutFullScreen.man new file mode 100644 index 0000000000..196065038c --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutFullScreen.man @@ -0,0 +1,38 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutFullScreen 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutFullScreen - requests that the current window be made full screen. +.SH SYNTAX +.nf +.LP +void glutFullScreen(void); +.fi +.SH DESCRIPTION +glutFullScreen requests that the current window be made full screen. +The exact semantics of what full screen means may vary by window +system. The intent is to make the window as large as possible and disable +any window decorations or borders added the window system. The +window width and height are not guaranteed to be the same as the screen +width and height, but that is the intent of making a window full screen. + +glutFullScreen is defined to work only on top-level windows. + +The glutFullScreen requests are not processed immediately. The +request is executed after returning to the main event loop. This allows +multiple glutReshapeWindow, glutPositionWindow, and +glutFullScreen requests to the same window to be coalesced. + +Subsequent glutReshapeWindow and glutPositionWindow +requests on the window will disable the full screen status of the window. +.SH X IMPLEMENTATION NOTES +In the X implementation of GLUT, full screen is implemented by sizing +and positioning the window to cover the entire screen and posting the +_MOTIF_WM_HINTS property on the window requesting absolutely no +decorations. Non-Motif window managers may not respond to +_MOTIF_WM_HINTS. +.SH SEE ALSO +glutReshapeWindow, glutPositionWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutGameModeGet.man b/lib/glut-3.7.6/man/glut/glutGameModeGet.man new file mode 100644 index 0000000000..a268da49bd --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutGameModeGet.man @@ -0,0 +1,52 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996, 1998. +.\" +.TH glutGameModeGet 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutGameModeGet - retrieves GLUT device information represented by integers. +.SH SYNTAX +.nf +.LP +int glutGameModeGet(GLenum info); +.fi +.SH ARGUMENTS +.IP \fIinfo\fP 1i +Name of game mode information to retrieve. +.TP 8 +.B GLUT_GAME_MODE_ACTIVE +Non-zero if GLUT's game mode is active; zero if not active. +Game mode is not active initially. Game mode becomes active when +glutEnterGameMode is called. Game mode becomes inactive when +glutLeaveGameMode is called. +.TP 8 +.B GLUT_GAME_MODE_POSSIBLE +Non-zero if the game mode string last specified to glutGameModeString is +a possible game mode configuration; zero otherwise. Being "possible" +does not guarantee that if game mode is entered with glutEnterGameMode +that the display settings will actually changed. GLUT_GAME_MODE_DISPLAY_CHANGED should be called once game mode is entered to determine if the display mode is actually changed. +.TP 8 +.B GLUT_GAME_MODE_WIDTH +Width in pixels of the screen when game mode is activated. +.TP 8 +.B GLUT_GAME_MODE_HEIGHT +Height in pixels of the screen when game mode is activated. +.TP 8 +.B GLUT_GAME_MODE_PIXEL_DEPTH +Pixel depth of the screen when game mode is activiated. +.TP 8 +.B GLUT_GAME_MODE_REFRESH_RATE +Screen refresh rate in cyles per second (hertz) when game mode is activated. +Zero is returned if the refresh rate is unknown or cannot be queried. +.TP 8 +.B GLUT_GAME_MODE_DISPLAY_CHANGED +Non-zero if entering game mode actually changed the display settings. +If the game mode string is not possible or the display mode could not be +changed for any other reason, zero is returned. +.SH DESCRIPTION +glutGameModeGet retrieves GLUT game mode information represented by integers. The info +parameter determines what type of game mode information to return. Requesting game mode +information for an invalid GLUT game mode information name returns negative one. +.SH SEE ALSO +glutGet, glutDeviceGet, glutLayerGet, glutGameModeString, glutEnterGameMode, glutLeaveGameMode +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutGameModeString.man b/lib/glut-3.7.6/man/glut/glutGameModeString.man new file mode 100644 index 0000000000..df5c58f09e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutGameModeString.man @@ -0,0 +1,20 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutGameModeString 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutGameModeString - sets the game mode configuration via a string. +.SH SYNTAX +.nf +.LP +void glutGameModeString(const char *string); +.fi +.SH ARGUMENTS +.IP \fIstring\fP 1i +ASCII string for selecting a game mode configuration. +.SH DESCRIPTION +.I XXX fix me +.SH SEE ALSO +glutGameModeGet, glutEnterGameMode, glutLeaveGameMode, glutInitDisplayString +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutGet.man b/lib/glut-3.7.6/man/glut/glutGet.man new file mode 100644 index 0000000000..2f7fd98efa --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutGet.man @@ -0,0 +1,161 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutGet 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutGet - retrieves simple GLUT state represented by integers. +.SH SYNTAX +.nf +.LP +int glutGet(GLenum state); +.fi +.SH ARGUMENTS +.IP \fIstate\fP 1i +Name of state to retrieve. +.TP 8 +.B GLUT_WINDOW_X +X location in pixels (relative to the screen origin) of the current +window. +.TP 8 +.B GLUT_WINDOW_Y +Y location in pixels (relative to the screen origin) of the current +window. +.TP 8 +.B GLUT_WINDOW_WIDTH +Width in pixels of the current window. +.TP 8 +.B GLUT_WINDOW_HEIGHT +Height in pixels of the current window. +.TP 8 +.B GLUT_WINDOW_BUFFER_SIZE +Total number of bits for current layer of current window's color buffer. For an +RGBA window, this is the sum of GLUT_WINDOW_RED_SIZE, +GLUT_WINDOW_GREEN_SIZE, GLUT_WINDOW_BLUE_SIZE, and +GLUT_WINDOW_ALPHA_SIZE. For color index windows, this is +the size of the color indexes. +.TP 8 +.B GLUT_WINDOW_STENCIL_SIZE +Number of bits in the current layer of current window's stencil buffer. +.TP 8 +.B GLUT_WINDOW_DEPTH_SIZE +Number of bits in the current layer of current window's depth buffer. +.TP 8 +.B GLUT_WINDOW_RED_SIZE +Number of bits of red stored the current layer of current window's color buffer. +Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_GREEN_SIZE +Number of bits of green stored the current layer of current window's color buffer. +Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_BLUE_SIZE +Number of bits of blue stored the current layer of current window's color buffer. +Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_ALPHA_SIZE +Number of bits of alpha stored the current layer of current window's color buffer. +Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_ACCUM_RED_SIZE +Number of bits of red stored in the current layer of current window's accumulation +buffer. Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_ACCUM_GREEN_SIZE +Number of bits of green stored in the current layer of current window's +accumulation buffer. Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_ACCUM_BLUE_SIZE +Number of bits of blue stored in the current layer of current window's +accumulation buffer. Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_ACCUM_ALPHA_SIZE +Number of bits of alpha stored in the current layer of current window's +accumulation buffer. Zero if the current layer of the current window is color index. +.TP 8 +.B GLUT_WINDOW_DOUBLEBUFFER +One if the current layer of the current window is double buffered, zero otherwise. +.TP 8 +.B GLUT_WINDOW_RGBA +One if the current layer of the current window is RGBA mode, zero otherwise (i.e., +color index). +.TP 8 +.B GLUT_WINDOW_PARENT +The window number of the current window's parent; zero if the +window is a top-level window. +.TP 8 +.B GLUT_WINDOW_NUM_CHILDREN +The number of subwindows the current window has (not counting +children of children). +.TP 8 +.B GLUT_WINDOW_COLORMAP_SIZE +Size of current layer of current window's color index colormap; zero for RGBA +color model layers. +.TP 8 +.B GLUT_WINDOW_NUM_SAMPLES +Number of samples for multisampling for the current layer of the current window. +.TP 8 +.B GLUT_WINDOW_STEREO +One if the current layer of the current window is stereo, zero otherwise. +.TP 8 +.B GLUT_WINDOW_CURSOR +Current cursor for the current window. +.TP 8 +.B GLUT_SCREEN_WIDTH +Width of the screen in pixels. Zero indicates the width is unknown +or not available. +.TP 8 +.B GLUT_SCREEN_HEIGHT +Height of the screen in pixels. Zero indicates the height is +unknown or not available. +.TP 8 +.B GLUT_SCREEN_WIDTH_MM +Width of the screen in millimeters. Zero indicates the width is +unknown or not available. +.TP 8 +.B GLUT_SCREEN_HEIGHT_MM +Height of the screen in millimeters. Zero indicates the height is +unknown or not available. +.TP 8 +.B GLUT_MENU_NUM_ITEMS +Number of menu items in the current menu. +.TP 8 +.B GLUT_DISPLAY_MODE_POSSIBLE +Whether the current display mode is supported or not. +.TP 8 +.B GLUT_INIT_DISPLAY_MODE +The initial display mode bit mask. +.TP 8 +.B GLUT_INIT_WINDOW_X +The X value of the initial window position. +.TP 8 +.B GLUT_INIT_WINDOW_Y +The Y value of the initial window position. +.TP 8 +.B GLUT_INIT_WINDOW_WIDTH +The width value of the initial window size. +.TP 8 +.B GLUT_INIT_WINDOW_HEIGHT +The height value of the initial window size. +.TP 8 +.B GLUT_ELAPSED_TIME +Number of milliseconds since glutInit called (or first call to +glutGet(GLUT_ELAPSED_TIME)). +.TP 8 +.B GLUT_WINDOW_FORMAT_ID +The window system dependent format ID for the current layer of the +current window. On X11 GLUT implementations, this is the X visual ID. +On Win32 GLUT implementations, this is the Win32 Pixel Format +Descriptor number. This value is returned for debugging, benchmarking, +and testing ease. +.SH DESCRIPTION +glutGet retrieves simple GLUT state represented by integers. The +state parameter determines what type of state to return. Where appropriate, window +capability state is returned for the layer in use. GLUT state names +beginning with GLUT_WINDOW_ return state for the current window. +GLUT state names beginning with GLUT_MENU_ return state for the +current menu. Other GLUT state names return global state. Requesting +state for an invalid GLUT state name returns negative one. +.SH SEE ALSO +glutDeviceGet, glutLayerGet, glutGetColor, glutGetWindow, glutGetMenu, glutGetModifiers, glutExtensionSupported +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutGetColor.man b/lib/glut-3.7.6/man/glut/glutGetColor.man new file mode 100644 index 0000000000..8303ad94bc --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutGetColor.man @@ -0,0 +1,33 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutGetColor 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutGetColor - retrieves a red, green, or blue component for a given +color index colormap entry for the layer in use's logical colormap for the +current window. +.SH SYNTAX +.nf +.LP +GLfloat glutGetColor(int cell, int component); +.fi +.SH ARGUMENTS +.IP \fIcell\fP 1i +Color cell index (starting at zero). +.IP \fIcomponent\fP 1i +One of GLUT_RED, GLUT_GREEN, or GLUT_BLUE. +.SH DESCRIPTION +glutGetColor retrieves a red, green, or blue component for a given +color index colormap entry for the current window's logical colormap. +The current window should be a color index window. cell should be +zero or greater and less than the total number of colormap entries for the +window. For valid color indices, the value returned is a floating point +value between 0.0 and 1.0 inclusive. glutGetColor will return -1.0 if +the color index specified is an overlay's transparent index, less than zero, +or greater or equal to the value returned by +glutGet(GLUT_WINDOW_COLORMAP_SIZE), that is if the color index +is transparent or outside the valid range of color indices. +.SH SEE ALSO +glutGet, glutSetColor, glutCopyColormap +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutGetModifiers.man b/lib/glut-3.7.6/man/glut/glutGetModifiers.man new file mode 100644 index 0000000000..cf4bed1e81 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutGetModifiers.man @@ -0,0 +1,35 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutGetModifiers 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutGetModifiers - returns the modifier key state when certain +callbacks were generated. +.SH SYNTAX +.nf +.LP +int glutGetModifiers(void); +.fi +.SH DESCRIPTION +glutGetModifiers returns the modifier key state at the time the +input event for a keyboard, special, or mouse callback is generated. +This routine may only be called while a keyboard, special, or mouse +callback is being handled. The window system is permitted to intercept +window system defined modifier key strokes or mouse buttons, in +which case, no GLUT callback will be generated. This interception +will be independent of use of glutGetModifiers. + +The bitmask components of the returned integer value are: +.TP 8 +.B GLUT_ACTIVE_SHIFT +Set if the Shift modifier or Caps Lock is active. +.TP 8 +.B GLUT_ACTIVE_CTRL +Set if the Ctrl modifier is active. +.TP 8 +.B GLUT_ACTIVE_ALT +Set if the Alt modifier is active. +.SH SEE ALSO +glutSpecialFunc, glutKeyboardFunc, glutMouseFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutIdleFunc.man b/lib/glut-3.7.6/man/glut/glutIdleFunc.man new file mode 100644 index 0000000000..4ba574b394 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutIdleFunc.man @@ -0,0 +1,73 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutIdleFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutIdleFunc - sets the global idle callback. +.SH SYNTAX +.nf +.LP +void glutIdleFunc(void (*func)(void)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new idle callback function. +.SH DESCRIPTION +glutIdleFunc sets the global idle callback to be func so a GLUT +program can perform background processing tasks or continuous +animation when window system events are not being received. If +enabled, the idle callback is continuously called when events are not +being received. The callback routine has no parameters. The current +window and current menu will not be changed before the idle callback. +Programs with multiple windows and/or menus should explicitly set the +current window and/or current menu and not rely on its current setting. + +The amount of computation and rendering done in an idle callback +should be minimized to avoid affecting the program's interactive +response. In general, not more than a single frame of rendering should be +done in an idle callback. + +Passing NULL to glutIdleFunc disables the generation of the idle +callback. +.SH EXAMPLE +A typical idle callback to animate a window might look like: +.nf +.LP + void + idle(void) + { + time += 0.05; + glutSetWindow(window); + glutPostRedisplay(); + } +.fi +.LP +Notice how the idle callback does not do any actual drawing; it only +advances the time scene state global variable. That +is left to the window's display callback which will be triggered +by the call to glutPostRedisplay. +.LP +If you use the idle callback for animation, you should be sure to stop +rendering when the window is not visible. This is easy to set up +with a visibility callback. For example: +.nf +.LP + void + visible(int vis) + { + if (vis == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); + } +.fi +.LP +If you do use the idle callback for animation, one thing you should +.I not +do is setup the idle callback before calling glutMainLoop. It is much +better to use the visibility callback to install idle callback when the +window first becomes visible on the screen. +.SH SEE ALSO +glutTimerFunc, glutVisibilityFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutIgnoreKeyRepeat.man b/lib/glut-3.7.6/man/glut/glutIgnoreKeyRepeat.man new file mode 100644 index 0000000000..3860d67db4 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutIgnoreKeyRepeat.man @@ -0,0 +1,30 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutIgnoreKeyRepeat 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutIgnoreKeyRepeat - determines if auto repeat keystrokes are reported to the current window +.SH SYNTAX +.nf +.LP +void glutIgnoreKeyRepeat(int ignore); +.fi +.SH ARGUMENTS +.IP \fIignore\fP 1i +Non-zero indicates auto repeat keystrokes should not be reported by the keyboard and special callbacks; zero indicates that auto repeat keystrokes will be reported. +.SH DESCRIPTION +glutIgnoreKeyRepeat determines if auto repeat keystrokes are reported to the current window. +The ignore auto repeat state of a window can be queried with +glutDeviceGet(GLUT_DEVICE_IGNORE_KEY_REPEAT). + +Ignoring auto repeated keystrokes is generally done in conjunction +with using the glutKeyboardUpFunc and glutSpecialUpFunc callbacks +to repeat key releases. If you do not ignore auto repeated keystrokes, +your GLUT application will experience repeated release/press callbacks. +Games using the keyboard will typically want to ignore key repeat. +.SH GLUT IMPLEMENTATION NOTES FOR X11 +X11 sends KeyPress events repeatedly when the window system's global auto repeat is enabled. glutIgnoreKeyRepeat can prevent these auto repeated keystrokes from being reported as keyboard or special callbacks, but there is still some minimal overhead by the X server to continually stream KeyPress events to the GLUT application. The glutSetKeyRepeat routine can be used to actually disable the global sending of auto repeated KeyPress events. Note that glutSetKeyRepeat affects the global window system auto repeat state so other applications will not auto repeat if you disable auto repeat globally through glutSetKeyRepeat. +.SH SEE ALSO +glutSetKeyRepeat, glutDeviceGet, glutKeyboardFunc, glutKeyboardUpFunc, glutSpecialFunc, glutSpecialUpFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutInit.man b/lib/glut-3.7.6/man/glut/glutInit.man new file mode 100644 index 0000000000..c64cf37d60 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutInit.man @@ -0,0 +1,81 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutInit 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutInit - initialize the GLUT library. +.SH SYNTAX +.nf +.LP +void glutInit(int *argcp, char **argv); +.fi +.SH ARGUMENTS +.IP \fIargcp\fP 1i +A pointer to the program's unmodified argc variable from main. +Upon return, the value pointed to by argcp will be updated, +because glutInit extracts any command line options intended +for the GLUT library. +.IP \fIargv\fP 1i +The program's unmodified argv variable from main. Like +argcp, the data for argv will be updated because glutInit +extracts any command line options understood by the GLUT +library. +.SH DESCRIPTION +glutInit will initialize the GLUT library and negotiate a session with +the window system. During this process, glutInit may cause the +termination of the GLUT program with an error message to the user if +GLUT cannot be properly initialized. Examples of this situation include +the failure to connect to the window system, the lack of window system +support for OpenGL, and invalid command line options. +.LP +glutInit also processes command line options, but the specific options +parse are window system dependent. +.SH X IMPLEMENTATION NOTES +The X Window System specific options parsed by glutInit are as +follows: +.TP 8 +.B \-display \fIDISPLAY\fP +Specify the X server to connect to. If not specified, the value of the +DISPLAY environment variable is used. +.TP 8 +.B \-geometry \fIWxH+X+Y\fP +Determines where window's should be created on the screen. The +parameter following -geometry should be formatted as a +standard X geometry specification. The effect of using this option +is to change the GLUT initial size and initial position the same as +if glutInitWindowSize or glutInitWindowPosition were +called directly. +.TP 8 +.B \-iconic +Requests all top-level windows be created in an iconic state. +.TP 8 +.B \-indirect +Force the use of indirect OpenGL rendering contexts. +.TP 8 +.B \-direct +Force the use of direct OpenGL rendering contexts (not all GLX +implementations support direct rendering contexts). A fatal error +is generated if direct rendering is not supported by the OpenGL +implementation. + +If neither -indirect or -direct are used to force a particular +behavior, GLUT will attempt to use direct rendering if possible +and otherwise fallback to indirect rendering. +.TP 8 +.B \-gldebug +After processing callbacks and/or events, check if there are any +OpenGL errors by calling glGetError. If an error is reported, +print out a warning by looking up the error code with +gluErrorString. Using this option is helpful in detecting +OpenGL run-time errors. +.TP 8 +.B \-sync +Enable synchronous X protocol transactions. This option makes it +easier to track down potential X protocol errors. +.SH SEE ALSO +glutCreateWindow, +glutInitWindowPosition, +glutInitWindowSize, +glutMainLoop +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutInitDisplayMode.man b/lib/glut-3.7.6/man/glut/glutInitDisplayMode.man new file mode 100644 index 0000000000..6e91baf236 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutInitDisplayMode.man @@ -0,0 +1,93 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutInitDisplayMode 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutInitDisplayMode - sets the initial display mode. +.SH SYNTAX +.nf +.LP +void glutInitDisplayMode(unsigned int mode); +.fi +.SH ARGUMENTS +.IP \fImode\fP 1i +Display mode, normally the bitwise {\em OR}-ing of GLUT display mode bit masks. +See values below: +.TP 8 +.B GLUT_RGBA +Bit mask to select an RGBA mode window. This is the default if +neither GLUT_RGBA nor GLUT_INDEX are specified. +.TP 8 +.B GLUT_RGB +An alias for GLUT_RGBA. +.TP 8 +.B GLUT_INDEX +Bit mask to select a color index mode window. This overrides +GLUT_RGBA if it is also specified. +.TP 8 +.B GLUT_SINGLE +Bit mask to select a single buffered window. This is the default if +neither GLUT_DOUBLE or GLUT_SINGLE are specified. +.TP 8 +.B GLUT_DOUBLE +Bit mask to select a double buffered window. This overrides +GLUT_SINGLE if it is also specified. +.TP 8 +.B GLUT_ACCUM +Bit mask to request a window with an accumulation buffer. +.TP 8 +.B GLUT_ALPHA +Bit mask to request a window with an alpha component to the color +buffer(s). +.TP 8 +.B GLUT_DEPTH +Bit mask to request a window with a depth buffer. +.TP 8 +.B GLUT_STENCIL +Bit mask to request a window with a stencil buffer. +.TP 8 +.B GLUT_MULTISAMPLE +Bit mask to request a window with multisampling support. If +multisampling is not available, a non-multisampling window will +automatically be chosen. Note: both the OpenGL client-side and +server-side implementations must support the +GLX_SAMPLE_SGIS extension for multisampling to be available. +.TP 8 +.B GLUT_STEREO +Bit mask to select a stereo window. +.TP 8 +.B GLUT_LUMINANCE +Bit mask to select a window with a ``luminance'' color model. +This model provides the functionality of OpenGL's RGBA color +model, but the green and blue components are not maintained in +the frame buffer. Instead each pixel's red component is converted +to an index between zero and +glutGet(GLUT_WINDOW_COLORMAP_SIZE)-1 and looked up in +a per-window color map to determine the color of pixels within +the window. The initial colormap of GLUT_LUMINANCE windows +is initialized to be a linear gray ramp, but can be modified with +GLUT's colormap routines. +.SH DESCRIPTION +The initial display mode is used when creating top-level windows, +subwindows, and overlays to determine the OpenGL display mode for +the to-be-created window or overlay. + +Note that GLUT_RGBA selects the RGBA color model, but it does not +request any bits of alpha (sometimes called an alpha buffer or destination +alpha) be allocated. To request alpha, specify GLUT_ALPHA. The same +applies to GLUT_LUMINANCE. + +Note that some bits "request" a capability and other bits "select" +a capability. A requestable capability may be assigned to the created +window even if the bit for the capability was not set. For example, +GLUT may create a window with a depth buffer even though GLUT_DEPTH +is not specified. + +The glutInitDisplayString routine provides a more powerful way to +select frame buffer capabilities for GLUT windows. +.SH GLUT_LUMINANCE IMPLEMENTATION NOTES +GLUT_LUMINANCE is not supported on most OpenGL platforms. +.SH SEE ALSO +glutInit, glutCreateWindow, glutInitDisplayString +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutInitDisplayString.man b/lib/glut-3.7.6/man/glut/glutInitDisplayString.man new file mode 100644 index 0000000000..8c07e434fe --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutInitDisplayString.man @@ -0,0 +1,250 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutInitDisplayString 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutInitDisplayString - sets the initial display mode via a string. +.SH SYNTAX +.nf +.LP +void glutInitDisplayString(char *string); +.fi +.SH ARGUMENTS +.IP \fIstring\fP 1i +Display mode description string, see below. +.SH DESCRIPTION +The initial display mode description string is used when creating top-level windows, +subwindows, and overlays to determine the OpenGL display mode for +the to-be-created window or overlay. + +The string is a list of zero or more capability descriptions separated by +spaces and tabs. Each capability description is a capability name that +is optionally followed by a comparator and a numeric value. For +example, "double" and "depth>=12" are both valid criteria. + +The capability descriptions are translated into a set of criteria +used to select the appropriate frame buffer configuration. + +The criteria are matched in +strict left to right order of precdence. That is, the first specified +criteria (leftmost) takes precedence over the later criteria for non-exact +criteria (greater than, less than, etc. comparators). Exact +criteria (equal, not equal compartors) must match exactly so precedence is +not relevant. + +The numeric value is an integer that is parsed according to ANSI C's +strtol(str, strptr, 0) behavior. This means that decimal, octal +(leading 0), and hexidecimal values (leading 0x) are accepeted. + +The valid compartors are: +.TP 8 +.B = +Equal. +.TP 8 +.B != +Not equal. +.TP 8 +.B < +Less than and preferring larger difference (the least is best). +.TP 8 +.B > +Greeater than and preferring larger differences (the most is best). +.TP 8 +.B <= +Less than or equal and preferring larger difference (the least is best). +.TP 8 +.B >= +Greater than or equal and preferring more instead of less. +This comparator is useful for allocating resources like color +precsion or depth buffer precision where the maximum precison +is generally preferred. Contrast with the tilde (~) comprator. +.TP 8 +.B ~ +Greater than or equal but preferring less instead of more. This +compartor is useful for allocating resources such as stencil bits or +auxillary color buffers where you would rather not over allocate. + +When the compartor and numeric value are not specified, each +capability name has a different default (one default is to require +a a compartor and numeric value). + +.LP +The valid capability names are: +.TP 8 +.B alpha +Alpha color buffer precision in bits. +Default is ">=1". +.TP 8 +.B acca +Red, green, blue, and alpha accumulation buffer precision in bits. +Default is ">=1" for red, green, blue, and alpha capabilities. +.TP 8 +.B acc +Red, green, and green accumulation buffer precision in bits and zero +bits of alpha accumulation buffer precision. +Default is ">=1" for red, green, and blue capabilities, and +"~0" for the alpha capability. +.TP 8 +.B blue +Blue color buffer precision in bits. +Default is ">=1". +.TP 8 +.B buffer +Number of bits in the color index color buffer. +Default is ">=1". +.TP 8 +.B conformant +Boolean indicating if the frame buffer configuration is conformant or +not. Conformance information is based on GLX's EXT_visual_rating +extension if supported. If the extension is not supported, all visuals +are assumed conformat. +Default is "=1". +.TP 8 +.B depth +Number of bits of precsion in the depth buffer. +Default is ">=12". +.TP 8 +.B double +Boolean indicating if the color buffer is double buffered. +Default is "=1". +.TP 8 +.B green +Green color buffer precision in bits. +Default is ">=1". +.TP 8 +.B index +Boolean if the color model is color index or not. True is color index. +Default is ">=1". +.TP 8 +.B num +A special capability name indicating where the value represents the +Nth frame buffer configuration matching the description string. +When not specified, glutInitDisplayString also returns the first +(best matching) configuration. num requires a compartor and +numeric value. +.TP 8 +.B red +Red color buffer precision in bits. +Default is ">=1". +.TP 8 +.B rgba +Number of bits of red, green, blue, and alpha in the RGBA color buffer. +Default is ">=1" for red, green, blue, and alpha capabilities, +and "=1" for the RGBA color model capability. +.TP 8 +.B rgb +Number of bits of red, green, and blue in the RGBA color buffer and +zero bits of alpha color buffer precision. +Default is ">=1" for the red, green, and blue capabilities, and "~0" for +alpha capability, and "=1" for the RGBA color model capability. +.TP 8 +.B luminance +Number of bits of red in the RGBA and zero bits of green, blue (alpha +not specified) of color buffer precision. +Default is ">=1" for the red capabilitis, and "=0" for the +green and blue capabilities, and "=1" for the RGBA color model +capability, and, for X11, "=1" for the StaticGray ("xstaticgray") +capability. + +SGI InfiniteReality (and other future machines) support a 16-bit +luminance (single channel) display mode (an additional 16-bit alpha +channel can also be requested). The red channel maps to gray scale and +green and blue channels are not available. A 16-bit precision +luminance display mode is often appropriate for medical imaging +applications. Do not expect many machines to support extended +precision luminance display modes. +.TP 8 +.B stencil +Number of bits in the stencil buffer. +.TP 8 +.B single +Boolean indicate the color buffer is single buffered. +Double buffer capability "=1". +.TP 8 +.B stereo +Boolean indicating the color buffer is supports OpenGL-style stereo. +Default is "=1". +.TP 8 +.B samples +Indicates the number of multisamples to use based on GLX's +SGIS_multisample extension (for antialiasing). +Default is "<=4". This default means that a GLUT application can +request multipsampling if available by simply specifying "samples". +.TP 8 +.B slow +Boolean indicating if the frame buffer configuration is slow or +not. Slowness information is based on GLX's EXT_visual_rating +extension if supported. If the extension is not supported, all visuals +are assumed fast. Note that slowness is a relative designation relative +to other frame buffer configurations available. The intent of the +slow capability is to help programs avoid frame buffer configurations +that are slower (but perhaps higher precision) for the current machine. +Default is ">=0". This default means that slow visuals are used in +preference to fast visuals, but fast visuals will still be allowed. +.TP 8 +.B win32pfd +Only recognized on GLUT implementations for Win32, this capability +name matches the Win32 Pixel Format Descriptor by numer. win32pfd +requires a compartor and numeric value. +.TP 8 +.B xvisual +Only recongized on GLUT implementations for the X Window System, this +capability name matches the X visual ID by number. +xvisual requires a compartor and numeric value. +.TP 8 +.B xstaticgray +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type StaticGray. +Default is "=1". +.TP 8 +.B xgrayscale +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type GrayScale. +Default is "=1". +.TP 8 +.B xstaticcolor +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type StaticColor. +Default is "=1". +.TP 8 +.B xpseudocolor +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type PsuedoColor. +Default is "=1". +.TP 8 +.B xtruecolor +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type TrueColor. +Default is "=1". +.TP 8 +.B xdirectcolor +Only recongized on GLUT implementations for the X Window System, +boolean indicating if the frame buffer configuration's X visual is +of type DirectColor. +Default is "=1". +.LP +Unspecifed capability descriptions will result in unspecified +criteria being generated. These unspecified criteria help +glutInitDisplayString behave sensibly with terse +display mode description strings. +.SH EXAMPLE +Here is an examples using glutInitDisplayString: +.nf +.LP + glutInitDisplayString("stencil~2 rgb double depth>=16 samples"); +.LP +.fi +The above call requests a window with an RGBA color model (but requesting +no bits of alpha), a depth buffer with at least 16 bits of precsion but +preferring more, mutlisampling +if available, and at least 2 bits of stencil (favoring less stencil +to more as long as 2 bits are available). +.SH SEE ALSO +glutInit, glutCreateWindow, glutInitDisplayMode +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutInitWindowPosition.man b/lib/glut-3.7.6/man/glut/glutInitWindowPosition.man new file mode 100644 index 0000000000..20b710a443 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutInitWindowPosition.man @@ -0,0 +1,74 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutInitWindowPosition 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutInitWindowPosition, glutInitWindowSize - set the +initial window position and size respectively. +.SH SYNTAX +.nf +.LP +void glutInitWindowSize(int width, int height); +void glutInitWindowPosition(int x, int y); +.fi +.SH ARGUMENTS +.IP \fIwidth\fP 1i +Width in pixels. +.IP \fIheight\fP 1i +Height in pixels. +.IP \fIx\fP 1i +Window X location in pixels. +.IP \fIy\fP 1i +Window Y location in pixels. +.SH DESCRIPTION +Windows created by glutCreateWindow will be requested to be +created with the current initial window position and size. + +The initial value of the initial window position GLUT state is -1 and -1. +If either the X or Y component to the initial window position is negative, +the actual window position is left to the window system to determine. +The initial value of the initial window size GLUT state is 300 by 300. +The initial window size components must be greater than zero. + +The intent of the initial window position and size values is to provide a +suggestion to the window system for a window's initial size and +position. The window system is not obligated to use this information. +Therefore, GLUT programs should not assume the window was created +at the specified size or position. A GLUT program should use the +window's reshape callback to determine the true size of the window. +.SH EXAMPLE +If you would like your GLUT program to default to starting at a given +screen location and at a given size, but you would also like to let +the user override these defaults via a command line argument (such as +-geometry for X11), call glutInitWindowSize and glutInitWindowPosition +.I before +your call to glutInit. For example: +.nf +.LP + int main(int argc, char **argv) + { + glutInitWindowSize(500, 300); + glutInitWindowPosition(100, 100); + glutInit(&argc, argv); + ... + } +.fi +.LP +However, if you'd like to force your program to start up at a given +size, call glutInitWindowSize and glutInitWindowPosition +.I after +your call to glutInit. For example: +.nf +.LP + int main(int argc, char **argv) + { + glutInit(&argc, argv); + glutInitWindowSize(500, 300); + glutInitWindowPosition(100, 100); + ... + } +.fi +.SH SEE ALSO +glutInit, glutCreateWindow, glutCreateSubWindow, glutReshapeFunc, glutGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutJoystickFunc.man b/lib/glut-3.7.6/man/glut/glutJoystickFunc.man new file mode 100644 index 0000000000..1e11919e39 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutJoystickFunc.man @@ -0,0 +1,67 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutJoystickFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutJoystickFunc - sets the joystick callback for the current window. +.SH SYNTAX +.nf +.LP +void glutJoystickFunc(void (*func)(unsigned int buttonMask, + int x, int y, int z), int pollInterval); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new joystick callback function. +.IP \fIpollInterval\fP 1i +Joystick polling interval in milliseconds. +.SH DESCRIPTION +glutJoystickFunc sets the joystick callback for the current window. + +The joystick callback is called either due to polling of the joystick +at the uniform timer interval specified by pollInterval (in milliseconds) or +in response to calling glutForceJoystickFunc. If the pollInterval is +non-positive, no joystick polling is performed and the GLUT application +must frequently (usually from an idle callback) call glutForceJoystickFunc. + +The joystick buttons are reported by the callback's buttonMask parameter. +The constants GLUT_JOYSTICK_BUTTON_A (0x1), GLUT_JOYSTICK_BUTTON_B (0x2), +GLUT_JOYSTICK_BUTTON_C (0x4), and GLUT_JOYSTICK_BUTTON_D (0x8) are provided +for programming convience. + +The x, y, and z callback parameters report the X, Y, and Z axes of the +joystick. The joystick is centered at (0,0,0). X, Y, and Z are +scaled to range between -1000 and 1000. Moving the joystick left reports +negative X; right reports positive X. Pulling the stick towards +you reports negative Y; push the stick away from you reports positive Y. +If the joystick has a third axis (rudder or up/down), down reports +negative Z; up reports positive Z. + +Passing a NULL func to glutJoystickFunc +disables the generation of joystick callbacks. Without a joystick +callback registered, glutForceJoystickFunc does nothing. + +When a new window is created, no joystick callback is +initially registered. +.SH LIMITATIONS +The GLUT joystick callback only reports the first 3 axes and 32 buttons. +GLUT supports only a single joystick. +.SH GLUT IMPLEMENTATION NOTES FOR X11 +The GLUT 3.7 implementation of GLUT for X11 supports the joystick API, but +not joystick input. A future implementation of GLUT for X11 may +add joystick support. +.SH GLUT IMPLEMENTATION NOTES FOR WIN32 +The GLUT 3.7 implementation of GLUT for Win32 supports the joystick API +and joystick input, but does so through the dated joySetCapture and +joyGetPosEx Win32 Multimedia API. The GLUT 3.7 joystick support for +Win32 has all the limitations of the Win32 Multimedia API joystick support. +A future implementation of GLUT for Win32 may use DirectInput. +.SH GLUT IMPLEMENTATION NOTES FOR NON-ANALOG JOYSTICKS +If the connected joystick does not return (x,y,z) as a continuous range +(for example, an 8 position Atari 2600 joystick), the implementation should +report the most extreme (x,y,z) location. That is, if a 2D joystick is +pushed to the upper left, report (-1000,1000,0). +.SH SEE ALSO +glutForceJoystickFunc, glutMotionFunc, glutMouseFunc, glutSpaceballButtonFunc, glutSpaceballMotionFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutKeyboardFunc.man b/lib/glut-3.7.6/man/glut/glutKeyboardFunc.man new file mode 100644 index 0000000000..9455190430 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutKeyboardFunc.man @@ -0,0 +1,38 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutKeyboardFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutKeyboardFunc - sets the keyboard callback for the current window. +.SH SYNTAX +.nf +.LP +void glutKeyboardFunc(void (*func)(unsigned char key, + int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new keyboard callback function. +.SH DESCRIPTION +glutKeyboardFunc sets the keyboard callback for the current window. +When a user types into the window, each key press generating an ASCII +character will generate a keyboard callback. The key callback parameter +is the generated ASCII character. The state of modifier keys such as Shift +cannot be determined directly; their only effect will be on the returned +ASCII data. The x and y callback parameters indicate the mouse location +in window relative coordinates when the key was pressed. When a new +window is created, no keyboard callback is initially registered, and ASCII +key strokes in the window are ignored. Passing NULL to +glutKeyboardFunc disables the generation of keyboard callbacks. + +During a keyboard callback, glutGetModifiers may be called to +determine the state of modifier keys when the keystroke generating the +callback occurred. + +Use glutSpecialFunc for a means to detect non-ASCII key +strokes. +.SH SEE ALSO +glutKeyboardUpFunc, +glutSpecialFunc, glutCreateWindow, glutMouseFunc, glutSpaceballButtonFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutGetModifiers +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutKeyboardUpFunc.man b/lib/glut-3.7.6/man/glut/glutKeyboardUpFunc.man new file mode 100644 index 0000000000..66fc630372 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutKeyboardUpFunc.man @@ -0,0 +1,47 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutKeyboardUpFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutKeyboardUpFunc - sets the keyboard up (key release) callback for the current window. +.SH SYNTAX +.nf +.LP +void glutKeyboardUpFunc(void (*func)(unsigned char key, + int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new keyboard up callback function. +.SH DESCRIPTION +glutKeyboardFunc sets the keyboard up (key release) callback for the current window. +When a user types into the window, each key release matching an ASCII +character will generate a keyboard up callback. The key callback parameter +is the generated ASCII character. The state of modifier keys such as Shift +cannot be determined directly; their only effect will be on the returned +ASCII data. The x and y callback parameters indicate the mouse location +in window relative coordinates when the key was pressed. When a new +window is created, no keyboard callback is initially registered, and ASCII +key strokes in the window are ignored. Passing NULL to +glutKeyboardFunc disables the generation of keyboard callbacks. + +During a keyboard up callback, glutGetModifiers may be called to +determine the state of modifier keys when the keystroke generating the +callback occurred. + +To avoid the reporting of key release/press pairs due to auto +repeat, use glutIgnoreKeyRepeat to ignore auto repeated keystrokes. + +There is no guarantee that the keyboard press callback will match +the exact ASCII character as the keyboard up callback. For example, +the key down may be for a lowercase b, but the key release may +report an uppercase B if the shift state has changed. The same +applies to symbols and control characters. The precise behavior +is window system dependent. + +Use glutSpecialUpFunc for a means to detect non-ASCII key +releases. +.SH SEE ALSO +glutKeyboardFunc, glutSpecialUpFunc, glutSpecialFunc, glutCreateWindow, glutMouseFunc, glutSpaceballButtonFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutGetModifiers, glutIgnoreKeyRepeat +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutLayerGet.man b/lib/glut-3.7.6/man/glut/glutLayerGet.man new file mode 100644 index 0000000000..8c11c76e8b --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutLayerGet.man @@ -0,0 +1,51 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutLayerGet 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutLayerGet - retrieves GLUT state pertaining to the layers of the +current window. +.SH SYNTAX +.nf +.LP +int glutLayerGet(GLenum info); +.fi +.SH ARGUMENTS +.IP \fIinfo\fP 1i +Name of device information to retrieve. +.TP 8 +.B GLUT_OVERLAY_POSSIBLE +Whether an overlay could be established for the current window +given the current initial display mode. If false, +glutEstablishOverlay will fail with a fatal error if called. +.TP 8 +.B GLUT_LAYER_IN_USE +Either GLUT_NORMAL or GLUT_OVERLAY depending on whether +the normal plane or overlay is the layer in use. +.TP 8 +.B GLUT_HAS_OVERLAY +If the current window has an overlay established. +.TP 8 +.B GLUT_TRANSPARENT_INDEX +The transparent color index of the overlay of the current window; +negative one is returned if no overlay is in use. +.TP 8 +.B GLUT_NORMAL_DAMAGED +True if the normal plane of the current window has damaged (by +window system activity) since the last display callback was +triggered. Calling glutPostRedisplay will not set this true. +.TP 8 +.B GLUT_OVERLAY_DAMAGED +True if the overlay plane of the current window has damaged (by +window system activity) since the last display callback was +triggered. Calling glutPostRedisplay or +glutPostOverlayRedisplay will not set this true. Negative +one is returned if no overlay is in use. +.SH DESCRIPTION +glutLayerGet retrieves GLUT layer information for the current +window represented by integers. The info parameter determines what +type of layer information to return. +.SH SEE ALSO +glutEstablishOverlay, glutUseOverlay, glutCreateWindow, glutSetColor +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutMainLoop.man b/lib/glut-3.7.6/man/glut/glutMainLoop.man new file mode 100644 index 0000000000..5e222f0e05 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutMainLoop.man @@ -0,0 +1,20 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutMainLoop 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutMainLoop - enters the GLUT event processing loop. +.SH SYNTAX +.nf +.LP +void glutMainLoop(void); +.fi +.SH DESCRIPTION +glutMainLoop enters the GLUT event processing loop. This routine +should be called at most once in a GLUT program. Once called, this +routine will never return. It will call as necessary any callbacks that have +been registered. +.SH SEE ALSO +glutInit +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutMenuStatusFunc.man b/lib/glut-3.7.6/man/glut/glutMenuStatusFunc.man new file mode 100644 index 0000000000..e52a99a8c1 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutMenuStatusFunc.man @@ -0,0 +1,50 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutMenuStatusFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutMenuStatusFunc - sets the global menu status callback. +.SH SYNTAX +.nf +.LP +void glutMenuStatusFunc(void (*func)(int status, int x, int y)); +void glutMenuStateFunc(void (*func)(int status)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new menu status (or state) callback function. +.SH DESCRIPTION +glutMenuStatusFunc sets the global menu status callback so a GLUT +program can determine when a menu is in use or not. When a menu +status callback is registered, it will be called with the value +GLUT_MENU_IN_USE for its value parameter when pop-up menus are +in use by the user; and the callback will be called with the value +GLUT_MENU_NOT_IN_USE for its status parameter when pop-up +menus are no longer in use. The x and y parameters indicate the location +in window coordinates of the button press that caused the menu to go +into use, or the location where the menu was released (may be outside the +window). The func parameter names the callback function. Other +callbacks continue to operate (except mouse motion callbacks) when +pop-up menus are in use so the menu status callback allows a program to +suspend animation or other tasks when menus are in use. The cascading +and unmapping of sub-menus from an initial pop-up menu does not +generate menu status callbacks. There is a single menu status callback for +GLUT. + +When the menu status callback is called, the current menu will be set to +the initial pop-up menu in both the GLUT_MENU_IN_USE and +GLUT_MENU_NOT_IN_USE cases. The current window will be set to the +window from which the initial menu was popped up from, also in both +cases. + +Passing NULL to glutMenuStatusFunc disables the generation of the +menu status callback. + +glutMenuStateFunc is a deprecated version of the +glutMenuStatusFunc routine. The only difference is +glutMenuStateFunc callback prototype does not deliver the two +additional x and y coordinates. +.SH SEE ALSO +glutCreateMenu, glutCreateWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutMotionFunc.man b/lib/glut-3.7.6/man/glut/glutMotionFunc.man new file mode 100644 index 0000000000..09b37ddf96 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutMotionFunc.man @@ -0,0 +1,34 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutMotionFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutMotionFunc, glutPassiveMotionFunc - set the motion and +passive motion callbacks respectively for the current window. +.SH SYNTAX +.nf +.LP +void glutMotionFunc(void (*func)(int x, int y)); +void glutPassiveMotionFunc(void (*func)(int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new motion or passive motion callback function. +.SH DESCRIPTION +glutMotionFunc and glutPassiveMotionFunc set the motion and +passive motion callback respectively for the current window. The motion +callback for a window is called when the mouse moves within the window +while one or more mouse buttons are pressed. The passive motion callback +for a window is called when the mouse moves within the window while +no mouse buttons are pressed. + +The x and y callback parameters indicate the mouse location in window +relative coordinates. + +Passing NULL to glutMotionFunc or glutPassiveMotionFunc +disables the generation of the mouse or passive motion callback +respectively. +.SH SEE ALSO +glutMouseFunc, glutSpaceballMotionFunc, glutTabletMotionFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutMouseFunc.man b/lib/glut-3.7.6/man/glut/glutMouseFunc.man new file mode 100644 index 0000000000..0cfc95f1b4 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutMouseFunc.man @@ -0,0 +1,45 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutMouseFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutMouseFunc - sets the mouse callback for the current window. +.SH SYNTAX +.nf +.LP +void glutMouseFunc(void (*func)(int button, int state, + int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new mouse callback function. +.SH DESCRIPTION +glutMouseFunc sets the mouse callback for the current window. When a +user presses and releases mouse buttons in the window, each press and +each release generates a mouse callback. The button parameter is one of +GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or +GLUT_RIGHT_BUTTON. For systems with only two mouse buttons, it may +not be possible to generate GLUT_MIDDLE_BUTTON callback. For systems +with a single mouse button, it may be possible to generate only a +GLUT_LEFT_BUTTON callback. The state parameter is either GLUT_UP +or GLUT_DOWN indicating whether the callback was due to a release or +press respectively. The x and y callback parameters indicate the window +relative coordinates when the mouse button state changed. If a +GLUT_DOWN callback for a specific button is triggered, the program can +assume a GLUT_UP callback for the same button will be generated +(assuming the window still has a mouse callback registered) when the +mouse button is released even if the mouse has moved outside the window. + +If a menu is attached to a button for a window, mouse callbacks will not +be generated for that button. + +During a mouse callback, glutGetModifiers may be called to +determine the state of modifier keys when the mouse event generating the +callback occurred. + +Passing NULL to glutMouseFunc disables the generation of mouse +callbacks. +.SH SEE ALSO +glutKeyboardFunc, glutMotionFunc, glutSpaceballButtonFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutGetModifiers +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutOverlayDisplayFunc.man b/lib/glut-3.7.6/man/glut/glutOverlayDisplayFunc.man new file mode 100644 index 0000000000..524704be0b --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutOverlayDisplayFunc.man @@ -0,0 +1,49 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutOverlayDisplayFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutOverlayDisplayFunc - sets the overlay display callback for the current window. +.SH SYNTAX +.nf +.LP +void glutOverlayDisplayFunc(void (*func)(void)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new overlay display callback function. +.SH DESCRIPTION +glutDisplayFunc sets the overlay display callback for the current +window. The overlay display callback is functionally the same as the +window's display callback except that the overlay display callback is used +to redisplay the window's overlay. + +When GLUT determines that the overlay plane for the window needs to +be redisplayed, the overlay display callback for the window is called. +Before the callback, the current window is set to the window needing to be +redisplayed and the layer in use is set to the overlay. The overlay display +callback is called with no parameters. The entire overlay region should be +redisplayed in response to the callback (this includes ancillary buffers if +your program depends on their state). + +GLUT determines when the overlay display callback should be triggered +based on the window's overlay redisplay state. The overlay redisplay state +for a window can be either set explicitly by calling +glutPostOverlayRedisplay or implicitly as the result of window +damage reported by the window system. Multiple posted overlay +redisplays for a window are coalesced by GLUT to minimize the number +of overlay display callbacks called. + +Upon return from the overlay display callback, the overlay damaged state +of the window (returned by calling +glutLayerGet(GLUT_OVERLAY_DAMAGED) is cleared. + +The overlay display callback can be deregistered by passing NULL to +glutOverlayDisplayFunc. The overlay display callback is initially +NULL when an overlay is established. See glutDisplayFunc to +understand how the display callback alone is used if an overlay display +callback is not registered. +.SH SEE ALSO +glutDisplayFunc, glutPostOverlayRedisplay +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutPopWindow.man b/lib/glut-3.7.6/man/glut/glutPopWindow.man new file mode 100644 index 0000000000..dde6e8fb34 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutPopWindow.man @@ -0,0 +1,24 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutPopWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutPopWindow, glutPushWindow - change the stacking order of the current window relative to its siblings. +.SH SYNTAX +.nf +.LP +void glutPopWindow(void); +void glutPushWindow(void); +.fi +.SH DESCRIPTION +glutPopWindow and glutPushWindow work on both top-level +windows and subwindows. The effect of pushing and popping windows +does not take place immediately. Instead the push or pop is saved for +execution upon return to the GLUT event loop. Subsequent push or pop +requests on a window replace the previously saved request for that +window. The effect of pushing and popping top-level windows is subject +to the window system's policy for restacking windows. +.SH SEE ALSO +glutShowWindow, glutIconifyWindow, glutHideWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutPositionWindow.man b/lib/glut-3.7.6/man/glut/glutPositionWindow.man new file mode 100644 index 0000000000..7862b696f6 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutPositionWindow.man @@ -0,0 +1,39 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutPositionWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutPositionWindow - requests a change to the position of the current window. +.SH SYNTAX +.nf +.LP +void glutPositionWindow(int x, int y); +.fi +.SH ARGUMENTS +.IP \fIx\fP 1i +New X location of window in pixels. +.IP \fIy\fP 1i +New Y location of window in pixels. +.SH DESCRIPTION +glutPositionWindow requests a change in the position of the current +window. For top-level windows, the x and y parameters are pixel offsets +from the screen origin. For subwindows, the x and y parameters are +pixel offsets from the window's parent window origin. + +The requests by glutPositionWindow are not processed immediately. +The request is executed after returning to the main event loop. This +allows multiple glutPositionWindow, glutReshapeWindow, and +glutFullScreen requests to the same window to be coalesced. + +In the case of top-level windows, a glutPositionWindow call is +considered only a request for positioning the window. The window +system is free to apply its own policies to top-level window placement. +The intent is that top-level windows should be repositioned according +glutPositionWindow's parameters. + +glutPositionWindow disables the full screen status of a window if +previously enabled. +.SH SEE ALSO +glutInitWindowPosition, glutReshapeWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutPostOverlayRedisplay.man b/lib/glut-3.7.6/man/glut/glutPostOverlayRedisplay.man new file mode 100644 index 0000000000..9c73e3c35c --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutPostOverlayRedisplay.man @@ -0,0 +1,88 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutPostOverlayRedisplay 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutPostOverlayRedisplay, glutPostWindowOverlayRedisplay - marks the +overlay of the current or specified window as needing to be +redisplayed. +.SH SYNTAX +.nf +.LP +void glutPostOverlayRedisplay(void); +void glutPostWindowOverlayRedisplay(int win); +.fi +.SH DESCRIPTION +Mark the overlay of current window as needing to be redisplayed. +The next iteration through glutMainLoop, the window's overlay +display callback (or simply the display callback if no overlay display +callback is registered) will be called to redisplay the window's +overlay plane. Multiple calls to glutPostOverlayRedisplay +before the next display callback opportunity (or overlay display +callback opportunity if one is registered) generate only a single +redisplay. glutPostOverlayRedisplay may be called within a +window's display or overlay display callback to re-mark that +window for redisplay. + +Logically, overlay damage notification for a window is treated as a +glutPostOverlayRedisplay on the damaged window. Unlike +damage reported by the window system, +glutPostOverlayRedisplay will not set to true the overlay's +damaged status (returned by +glutLayerGet(GLUT_OVERLAY_DAMAGED). + +If the window you want to post an overlay redisplay on is not already current +(and you do not require it to be immediately made current), using +glutPostWindowOverlayRedisplay is more efficient that calling glutSetWindow to +the desired window and then calling glutPostOverlayRedisplay. +.SH EXAMPLE +If you are doing an interactive effect like rubberbanding in the +overlay, it is a good idea to structure your rendering to minimize +flicker (most overlays are single-buffered). Only clear the +overlay if you know that the window has been damaged. Otherwise, +try to simply erase what you last drew and redraw it in an updated +position. Here is an example overlay display callback used to +implement overlay rubberbanding: +.nf +.LP + void + redrawOverlay(void) + { + static int prevStretchX, prevStretchY; + + if (glutLayerGet(GLUT_OVERLAY_DAMAGED)) { + /* Damage means we need a full clear. */ + glClear(GL_COLOR_BUFFER_BIT); + } else { + /* Undraw last rubber-band. */ + glIndexi(transparent); + glBegin(GL_LINE_LOOP); + glVertex2i(anchorX, anchorY); + glVertex2i(anchorX, prevStretchY); + glVertex2i(prevStretchX, prevStretchY); + glVertex2i(prevStretchX, anchorY); + glEnd(); + } + glIndexi(red); + glBegin(GL_LINE_LOOP); + glVertex2i(anchorX, anchorY); + glVertex2i(anchorX, stretchY); + glVertex2i(stretchX, stretchY); + glVertex2i(stretchX, anchorY); + glEnd(); + prevStretchX = stretchX; + prevStretchY = stretchY; + } +.fi +.LP +Notice how glutLayerGet(GLUT_OVERLAY_DAMAGED) is used to determine if +a clear needs to take place because of damage; if a clear is unnecessary, +it is faster to just draw the last rubberband using the transparent pixel. +.LP +When the application is through with the rubberbanding effect, the best +way to get ride of the rubberband is to simply hide the overlay by +calling glutHideOverlay. +.SH SEE ALSO +glutPostRedisplay, glutEstablishOverlay, glutLayerGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutPostRedisplay.man b/lib/glut-3.7.6/man/glut/glutPostRedisplay.man new file mode 100644 index 0000000000..730ff7fe54 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutPostRedisplay.man @@ -0,0 +1,37 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutPostRedisplay 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutPostRedisplay, glutPostWindowRedisplay - marks the current or specified window as needing to be +redisplayed. +.SH SYNTAX +.nf +.LP +void glutPostRedisplay(void); +void glutPostWindowRedisplay(int win); +.fi +.SH DESCRIPTION +glutPostRedisplay marks the normal plane of current window as needing to be redisplayed. +glutPostWindowRedisplay works the specified window as needing to be redisplayed. +After either call, the next iteration through glutMainLoop, the window's display +callback will be called to redisplay the window's normal plane. Multiple +calls to glutPostRedisplay before the next display callback +opportunity generates only a single redisplay callback. +glutPostRedisplay may be called within a window's display or +overlay display callback to re-mark that window for redisplay. + +Logically, normal plane damage notification for a window is treated as a +glutPostRedisplay on the damaged window. Unlike damage +reported by the window system, glutPostRedisplay will not set to +true the normal plane's damaged status (returned by +glutLayerGet(GLUT_NORMAL_DAMAGED). + +If the window you want to post a redisplay on is not already current +(and you do not require it to be immediately made current), using +glutPostWindowRedisplay is more efficient that calling glutSetWindow to +the desired window and then calling glutPostRedisplay. +.SH SEE ALSO +glutPostOverlayRedisplay, glutDisplayFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutRemoveMenuItem.man b/lib/glut-3.7.6/man/glut/glutRemoveMenuItem.man new file mode 100644 index 0000000000..59486eee55 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutRemoveMenuItem.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutRemoveMenuItem 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutRemoveMenuItem - remove the specified menu item. +.SH SYNTAX +.nf +.LP +void glutRemoveMenuItem(int entry); +.fi +.SH ARGUMENTS +.IP \fIentry\fP 1i +Index into the menu items of the current menu (1 is the topmost menu item). +.SH DESCRIPTION +glutRemoveMenuItem remove the entry menu item regardless of +whether it is a menu entry or sub-menu trigger. entry must be between 1 +and glutGet(GLUT_MENU_NUM_ITEMS) inclusive. Menu items below +the removed menu item are renumbered. +.SH SEE ALSO +glutAddMenuEntry, glutAddSubMenu, glutChangeToMenuEntry, glutChangeToSubMenu +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutRemoveOverlay.man b/lib/glut-3.7.6/man/glut/glutRemoveOverlay.man new file mode 100644 index 0000000000..55a756afa0 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutRemoveOverlay.man @@ -0,0 +1,26 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutRemoveLayer 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutRemoveOverlay - removes the overlay (if one exists) from the current window. +.SH SYNTAX +.nf +.LP +void glutRemoveOverlay(void); +.fi +.SH DESCRIPTION +glutRemoveOverlay removes the overlay (if one exists). It is safe +to call glutRemoveOverlay even if no overlay is currently +established--it does nothing in this case. Implicitly, the window's +layer in use changes to the normal plane immediately once the +overlay is removed. + +If the program intends to re-establish the overlay later, it is typically +faster and less resource intensive to use glutHideOverlay and +glutShowOverlay to simply change the display status of the +overlay. +.SH SEE ALSO +glutEstablishOverlay, glutDestroyWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutReportErrors.man b/lib/glut-3.7.6/man/glut/glutReportErrors.man new file mode 100644 index 0000000000..40e8b70a68 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutReportErrors.man @@ -0,0 +1,29 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutReportErrors 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutReportErrors - for debugging purposes; prints out OpenGL run-time errors. +.SH SYNTAX +.nf +.LP +void glutReportErrors(void); +.SH DESCRIPTION +This routine prints out any OpenGL run-time errors pending and clears +the errors. This routine typically should only be used for debugging purposes +since calling it will slow OpenGL programs. It is provided as a convenience; +all the routine does is call +.I glGetError +until no more errors are reported. Any errors detected are reported +with a GLUT warning and the corresponding text message generated by +.I gluErrorString. + +Calling glutReportErrors repeatedly in your program can help isolate +OpenGL errors to the offending OpenGL command. Remember that you +can use the +.I -gldebug +option to detect OpenGL errors in any GLUT program. +.SH SEE ALSO +glutInit, glutCreateWindow, glutInitDisplayMode, gluErrorString, glGetError +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutReshapeFunc.man b/lib/glut-3.7.6/man/glut/glutReshapeFunc.man new file mode 100644 index 0000000000..399224e738 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutReshapeFunc.man @@ -0,0 +1,41 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutReshapeFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutReshapeFunc - sets the reshape callback for the current window. +.SH SYNTAX +.nf +.LP +void glutReshapeFunc(void (*func)(int width, int height)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new reshape callback function. +.SH DESCRIPTION +glutReshapeFunc sets the reshape callback for the current window. The +reshape callback is triggered when a window is reshaped. A reshape +callback is also triggered immediately before a window's first display +callback after a window is created or whenever an overlay for the window +is established. The width and height parameters of the callback specify +the new window size in pixels. Before the callback, the current window is +set to the window that has been reshaped. + +If a reshape callback is not registered for a window or NULL is passed to +glutReshapeFunc (to deregister a previously registered callback), the +default reshape callback is used. This default callback will simply call +glViewport(0,0,width,height) on the normal plane (and on the +overlay if one exists). + +If an overlay is established for the window, a single reshape callback is +generated. It is the callback's responsibility to update both the normal +plane and overlay for the window (changing the layer in use as necessary). + +When a top-level window is reshaped, subwindows are not reshaped. It is +up to the GLUT program to manage the size and positions of subwindows +within a top-level window. Still, reshape callbacks will be triggered for +subwindows when their size is changed using glutReshapeWindow. +.SH SEE ALSO +glutDisplayFunc, glutReshapeWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutReshapeWindow.man b/lib/glut-3.7.6/man/glut/glutReshapeWindow.man new file mode 100644 index 0000000000..d4af32a387 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutReshapeWindow.man @@ -0,0 +1,40 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutReshapeWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutReshapeWindow - requests a change to the size of the current window. +.SH SYNTAX +.nf +.LP +void glutReshapeWindow(int width, int height); +.fi +.SH ARGUMENTS +.IP \fIwidth\fP 1i +New width of window in pixels. +.IP \fIheight\fP 1i +New height of window in pixels. +.SH DESCRIPTION +glutReshapeWindow requests a change in the size of the current +window. The width and height parameters are size extents in pixels. +The width and height must be positive values. + +The requests by glutReshapeWindow are not processed immediately. +The request is executed after returning to the main event loop. This +allows multiple glutReshapeWindow, glutPositionWindow, and +glutFullScreen requests to the same window to be coalesced. + +In the case of top-level windows, a glutReshapeWindow call is +considered only a request for sizing the window. The window system is +free to apply its own policies to top-level window sizing. The intent is +that top-level windows should be reshaped according +glutReshapeWindow's parameters. Whether a reshape actually takes +effect and, if so, the reshaped dimensions are reported to the program by +a reshape callback. + +glutReshapeWindow disables the full screen status of a window if +previously enabled. +.SH SEE ALSO +glutPositionWindow, glutReshapeFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetColor.man b/lib/glut-3.7.6/man/glut/glutSetColor.man new file mode 100644 index 0000000000..874a686e9e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetColor.man @@ -0,0 +1,35 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSetColor 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetColor - sets the color of a colormap entry in the layer of use +for the current window. +.SH SYNTAX +.nf +.LP +void glutSetColor(int cell, + GLfloat red, GLfloat green, GLfloat blue); +.fi +.SH ARGUMENTS +.IP \fIcell\fP 1i +Color cell index (starting at zero). +.IP \fIred\fP 1i +Red intensity (clamped between 0.0 and 1.0 inclusive). +.IP \fIgreen\fP 1i +Green intensity (clamped between 0.0 and 1.0 inclusive). +.IP \fIblue\fP 1i +Blue intensity (clamped between 0.0 and 1.0 inclusive). +.SH DESCRIPTION +Sets the cell color index colormap entry of the current window's +logical colormap for the layer in use with the color specified by red, +green, and blue. The layer in use of the current window should be a +color index window. cell should be zero or greater and less than the +total number of colormap entries for the window. If the layer in use's +colormap was copied by reference, a glutSetColor call will force the +duplication of the colormap. Do not attempt to set the color of an +overlay's transparent index. +.SH SEE ALSO +glutGetColor, glutCopyColormap, glutInitDisplayMode +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetCursor.man b/lib/glut-3.7.6/man/glut/glutSetCursor.man new file mode 100644 index 0000000000..4e568ee55e --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetCursor.man @@ -0,0 +1,99 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSetCursor 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetCursor - changes the cursor image of the current window. +.SH SYNTAX +.nf +.LP +void glutSetCursor(int cursor); +.fi +.SH ARGUMENTS +.IP \fIcursor\fP 1i +Name of cursor image to change to. Possible values follow: +.TP 8 +.B GLUT_CURSOR_RIGHT_ARROW +Arrow pointing up and to the right. +.TP 8 +.B GLUT_CURSOR_LEFT_ARROW +Arrow pointing up and to the left. +.TP 8 +.B GLUT_CURSOR_INFO +Pointing hand. +.TP 8 +.B GLUT_CURSOR_DESTROY +Skull & cross bones. +.TP 8 +.B GLUT_CURSOR_HELP +Question mark. +.TP 8 +.B GLUT_CURSOR_CYCLE +Arrows rotating in a circle. +.TP 8 +.B GLUT_CURSOR_SPRAY +Spray can. +.TP 8 +.B GLUT_CURSOR_WAIT +Wrist watch. +.TP 8 +.B GLUT_CURSOR_TEXT +Insertion point cursor for text. +.TP 8 +.B GLUT_CURSOR_CROSSHAIR +Simple cross-hair. +.TP 8 +.B GLUT_CURSOR_UP_DOWN +Bi-directional pointing up & down. +.TP 8 +.B GLUT_CURSOR_LEFT_RIGHT +Bi-directional pointing left & right. +.TP 8 +.B GLUT_CURSOR_TOP_SIDE +Arrow pointing to top side. +.TP 8 +.B GLUT_CURSOR_BOTTOM_SIDE +Arrow pointing to bottom side. +.TP 8 +.B GLUT_CURSOR_LEFT_SIDE +Arrow pointing to left side. +.TP 8 +.B GLUT_CURSOR_RIGHT_SIDE +Arrow pointing to right side. +.TP 8 +.B GLUT_CURSOR_TOP_LEFT_CORNER +Arrow pointing to top-left corner. +.TP 8 +.B GLUT_CURSOR_TOP_RIGHT_CORNER +Arrow pointing to top-right corner. +.TP 8 +.B GLUT_CURSOR_BOTTOM_RIGHT_CORNER +Arrow pointing to bottom-left corner. +.TP 8 +.B GLUT_CURSOR_BOTTOM_LEFT_CORNER +Arrow pointing to bottom-right corner. +.TP 8 +.B GLUT_CURSOR_FULL_CROSSHAIR +Full-screen cross-hair cursor (if possible, otherwise +GLUT_CURSOR_CROSSHAIR). +.TP 8 +.B GLUT_CURSOR_NONE +Invisible cursor. +.TP 8 +.B GLUT_CURSOR_INHERIT +Use parent's cursor. +.SH DESCRIPTION +glutSetCursor changes the cursor image of the current window. +Each call requests the window system change the cursor appropriately. +The cursor image when a window is created is +GLUT_CURSOR_INHERIT. The exact cursor images used are +implementation dependent. The intent is for the image to convey the +meaning of the cursor name. For a top-level window, +GLUT_CURSOR_INHERIT uses the default window system cursor. +.SH X IMPLEMENTATION NOTES +GLUT for X uses SGI's _SGI_CROSSHAIR_CURSOR convention to +access a full-screen cross-hair cursor if possible. +.SH SEE ALSO +glutCreateWindow, glutCreateSubWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetKeyRepeat.man b/lib/glut-3.7.6/man/glut/glutSetKeyRepeat.man new file mode 100644 index 0000000000..7e66ac5f30 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetKeyRepeat.man @@ -0,0 +1,30 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1998. +.\" +.TH glutSetKeyRepeat 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetKeyRepeat - retrieves simple GLUT state represented by integers. +.SH SYNTAX +.nf +.LP +int glutSetKeyRepeat(int repeatMode); +.fi +.SH ARGUMENTS +.IP \fIrepeatMode\fP 1i +Mode for setting key repeat to. +.TP 8 +.B GLUT_KEY_REPEAT_OFF +Disable key repeat for the window system on a global basis if possible. +.TP 8 +.B GLUT_KEY_REPEAT_ON +Enable key repeat for the window system on a global basis if possible. +.TP 8 +.B GLUT_KEY_REPEAT_DEFAULT +Reset the key repeat mode for the window system to its default state +if possible. +.SH DESCRIPTION +.I XXX fix me +.SH SEE ALSO +glutIgnoreKeyRepeat, glutKeyboardFunc, glutSpecialFunc, glutKeyboardUpFunc, glutSpecialUpFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetMenu.man b/lib/glut-3.7.6/man/glut/glutSetMenu.man new file mode 100644 index 0000000000..72f0770879 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetMenu.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSetMenu 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetMenu - sets the current menu; glutGetMenu - returns the identifier of the current menu. +.SH SYNTAX +.nf +.LP +void glutSetMenu(int menu); +int glutGetMenu(void); +.fi +.SH ARGUMENTS +.IP \fImenu\fP 1i +The identifier of the menu to make the current menu. +.SH DESCRIPTION +glutSetMenu sets the current menu; glutGetMenu returns the +identifier of the current menu. If no menus exist or the previous +current menu was destroyed, glutGetMenu returns zero. +.SH SEE ALSO +glutCreateMenu, glutSetWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetWindow.man b/lib/glut-3.7.6/man/glut/glutSetWindow.man new file mode 100644 index 0000000000..481b283d6a --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetWindow.man @@ -0,0 +1,26 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSetWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetWindow - sets the current window; glutGetWindow - returns +the identifier of the current window. +.SH SYNTAX +.nf +.LP +void glutSetWindow(int win); +int glutGetWindow(void); +.fi +.SH ARGUMENTS +.IP \fIwin\fP 1i +Identifier of GLUT window to make the current window. +.SH DESCRIPTION +glutSetWindow sets the current window; glutGetWindow returns the +identifier of the current window. If no windows exist or the previously +current window was destroyed, glutGetWindow returns zero. +glutSetWindow does not change the layer in use for the window; this is +done using glutUseLayer. +.SH SEE ALSO +glutCreateWindow, glutSetMenu +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSetWindowTitle.man b/lib/glut-3.7.6/man/glut/glutSetWindowTitle.man new file mode 100644 index 0000000000..51293ba588 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSetWindowTitle.man @@ -0,0 +1,30 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSetWindowTitle 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSetWindowTitle, glutSetIconTitle - change the window or icon title respectively of the current top-level window. +.SH SYNTAX +.nf +.LP +void glutSetWindowTitle(char *name); +void glutSetIconTitle(char *name); +.fi +.SH ARGUMENTS +.IP \fIname\fP 1i +ASCII character string for the window or icon name to be set for +the window. +.SH DESCRIPTION +These routines should be called only when the current window is a +top-level window. Upon creation of a top-level window, the window +and icon names are determined by the name parameter to +glutCreateWindow. Once created, glutSetWindowTitle and +glutSetIconTitle can change the window and icon names +respectively of top-level windows. Each call requests the window +system change the title appropriately. Requests are not buffered or +coalesced. The policy by which the window and icon name are displayed +is window system dependent. +.SH SEE ALSO +glutCreateWindow, glutIconifyWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutShowOverlay.man b/lib/glut-3.7.6/man/glut/glutShowOverlay.man new file mode 100644 index 0000000000..14affb8292 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutShowOverlay.man @@ -0,0 +1,26 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutShowOverlay 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutShowOverlay, glutHideOverlay - shows or hides the overlay of the current window +.SH SYNTAX +.nf +.LP +void glutShowOverlay(void); +void glutHideOverlay(void); +.fi +.SH DESCRIPTION +glutShowOverlay shows the overlay of the current window; +glutHideOverlay hides the overlay. The effect of showing or +hiding an overlay takes place immediately. Note that +glutShowOverlay will not actually display the overlay unless the +window is also shown (and even a shown window may be obscured +by other windows, thereby obscuring the overlay). It is typically +faster and less resource intensive to use these routines to control the +display status of an overlay as opposed to removing and +re-establishing the overlay. +.SH SEE ALSO +glutEstablishOverlay, glutShowWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutShowWindow.man b/lib/glut-3.7.6/man/glut/glutShowWindow.man new file mode 100644 index 0000000000..3e534c545f --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutShowWindow.man @@ -0,0 +1,28 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutShowWindow 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutShowWindow, glutHideWindow, glutIconifyWindow - change the display status of the current window. +.SH SYNTAX +.nf +.LP +void glutShowWindow(void); +void glutHideWindow(void); +void glutIconifyWindow(void); +.fi +.SH DESCRIPTION +glutShowWindow will show the current window (though it may still +not be visible if obscured by other shown windows). glutHideWindow +will hide the current window. glutIconifyWindow will iconify a +top-level window, but GLUT prohibits iconification of a subwindow. +The effect of showing, hiding, and iconifying windows does not take +place immediately. Instead the requests are saved for execution upon +return to the GLUT event loop. Subsequent show, hide, or iconification +requests on a window replace the previously saved request for that +window. The effect of hiding, showing, or iconifying top-level windows +is subject to the window system's policy for displaying windows. +.SH SEE ALSO +glutPopWindow, glutPushWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidCone.man b/lib/glut-3.7.6/man/glut/glutSolidCone.man new file mode 100644 index 0000000000..f0a6dca497 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidCone.man @@ -0,0 +1,34 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidCone 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidCone, glutWireCone - render a solid or wireframe cone respectively. +.SH SYNTAX +.nf +.LP +void glutSolidCone(GLdouble base, GLdouble height, + GLint slices, GLint stacks); +void glutWireCone(GLdouble base, GLdouble height, + GLint slices, GLint stacks); +.fi +.SH ARGUMENTS +.IP \fIbase\fP 1i +The radius of the base of the cone. +.IP \fIheight\fP 1i +The height of the cone. +.IP \fIslices\fP 1i +The number of subdivisions around the Z axis. +.IP \fIstacks\fP 1i +The number of subdivisions along the Z axis. +.SH DESCRIPTION +glutSolidCone and glutWireCone render a solid or wireframe cone +respectively oriented along the Z axis. The base of the cone is placed at Z += 0, and the top at Z = height. The cone is subdivided around the Z axis +into slices, and along the Z axis into stacks. +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidCube.man b/lib/glut-3.7.6/man/glut/glutSolidCube.man new file mode 100644 index 0000000000..f9ba2c00f3 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidCube.man @@ -0,0 +1,25 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidCube 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidCube, glutWireCube - render a solid or wireframe cube respectively. +.SH SYNTAX +.nf +.LP +void glutSolidCube(GLdouble size); +void glutWireCube(GLdouble size); +.fi +.SH ARGUMENTS +.IP \fIsize\fP 1i +Length of each edge. +.SH DESCRIPTION +glutSolidCube and glutWireCube render a solid or wireframe cube +respectively. The cube is centered at the modeling coordinates origin with +sides of length size. +.SH SEE ALSO +glutSolidSphere, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidDodecahedron.man b/lib/glut-3.7.6/man/glut/glutSolidDodecahedron.man new file mode 100644 index 0000000000..2be20cf9a5 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidDodecahedron.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidDodecahedron 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidDodecahedron, glutWireDodecahedron - render a +solid or wireframe dodecahedron (12-sided regular solid) respectively. +.SH SYNTAX +.nf +.LP +void glutSolidDodecahedron(void); +void glutWireDodecahedron(void); +.fi +.SH DESCRIPTION +glutSolidDodecahedron and glutWireDodecahedron render a +solid or wireframe dodecahedron respectively centered at the modeling +coordinates origin with a radius of sqrt(3). +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidIcosahedron.man b/lib/glut-3.7.6/man/glut/glutSolidIcosahedron.man new file mode 100644 index 0000000000..50b7156670 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidIcosahedron.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidIcosahedron 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidIcosahedron, glutWireIcosahedron - render a +solid or wireframe icosahedron (20-sided regular solid) respectively. +.SH SYNTAX +.nf +.LP +void glutSolidIcosahedron(void); +void glutWireIcosahedron(void); +.fi +.SH DESCRIPTION +glutSolidIcosahedron and glutWireIcosahedron render a solid +or wireframe icosahedron respectively. The icosahedron is centered at the +modeling coordinates origin and has a radius of 1.0. +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidOctahedron.man b/lib/glut-3.7.6/man/glut/glutSolidOctahedron.man new file mode 100644 index 0000000000..0b058e7a37 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidOctahedron.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidOctahedron 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidOctahedron, glutWireOctahedron - render a solid +or wireframe octahedron (8-sided regular solid) respectively. +.SH SYNTAX +.nf +.LP +void glutSolidOctahedron(void); +void glutWireOctahedron(void); +.fi +.SH DESCRIPTION +glutSolidOctahedron and glutWireOctahedron render a solid or +wireframe octahedron respectively centered at the modeling coordinates +origin with a radius of 1.0. +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidSphere.man b/lib/glut-3.7.6/man/glut/glutSolidSphere.man new file mode 100644 index 0000000000..531f3a1f7a --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidSphere.man @@ -0,0 +1,31 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidSphere 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidSphere, glutWireSphere - render a solid or wireframe sphere respectively. +.SH SYNTAX +.nf +.LP +void glutSolidSphere(GLdouble radius, + GLint slices, GLint stacks); +void glutWireSphere(GLdouble radius, + GLint slices, GLint stacks); +.fi +.SH ARGUMENTS +.IP \fIradius\fP 1i +The radius of the sphere. +.IP \fIslices\fP 1i +The number of subdivisions around the Z axis (similar to lines of longitude). +.IP \fIstacks\fP 1i +The number of subdivisions along the Z axis (similar to lines of latitude). +.SH DESCRIPTION +Renders a sphere centered at the modeling coordinates origin of the +specified radius. The sphere is subdivided around the Z axis into slices +and along the Z axis into stacks. +.SH SEE ALSO +glutSolidCube, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidTeapot.man b/lib/glut-3.7.6/man/glut/glutSolidTeapot.man new file mode 100644 index 0000000000..8090f3296c --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidTeapot.man @@ -0,0 +1,42 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidTeapot 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidTeapot, glutWireTeapot - render a solid or wireframe teapot respectively. +.SH SYNTAX +.nf +.LP +void glutSolidTeapot(GLdouble size); +void glutWireTeapot(GLdouble size); +.fi +.SH ARGUMENTS +.IP \fIsize\fP 1i +Relative size of the teapot. +.SH DESCRIPTION +glutSolidTeapot and glutWireTeapot render a solid or wireframe +teapot respectively. Both surface normals and texture coordinates for the +teapot are generated. The teapot is generated with OpenGL evaluators. +.SH BUGS +The teapot is greatly over-tesselated; it renders way too slow. + +OpenGL's default glFrontFace state assumes that front facing polygons +(for the purpose of face culling) +have vertices that wind counter clockwise when projected into window +space. This teapot is rendered with its front facing polygon vertices +winding clockwise. For OpenGL's default back face culling to work, +you should use: +.nf +.LP + glFrontFace(GL_CW); + glutSolidTeapot(size); + glFrontFace(GL_CCW); +.fi +.LP +Both these bugs reflect issues in the original aux toolkit's +teapot rendering routines (GLUT used the same teapot rendering routine). +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidTetrahedron.man b/lib/glut-3.7.6/man/glut/glutSolidTetrahedron.man new file mode 100644 index 0000000000..88e3bccdce --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidTetrahedron.man @@ -0,0 +1,23 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidTetrahedron 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidTetrahedron, glutWireTetrahedron - render a +solid or wireframe tetrahedron (4-sided regular solid) respectively. +.SH SYNTAX +.nf +.LP +void glutSolidTetrahedron(void); +void glutWireTetrahedron(void); +.fi +.SH DESCRIPTION +glutSolidTetrahedron and glutWireTetrahedron render a solid +or wireframe tetrahedron respectively centered at the modeling +coordinates origin with a radius of sqrt(3). +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSolidTorus.man b/lib/glut-3.7.6/man/glut/glutSolidTorus.man new file mode 100644 index 0000000000..648e579307 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSolidTorus.man @@ -0,0 +1,36 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSolidTorus 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSolidTorus, glutWireTorus - render a solid or wireframe +torus (doughnut) respectively. +.SH SYNTAX +.nf +.LP +void glutSolidTorus(GLdouble innerRadius, + GLdouble outerRadius, + GLint nsides, GLint rings); +void glutWireTorus(GLdouble innerRadius, + GLdouble outerRadius, + GLint nsides, GLint rings); +.fi +.SH ARGUMENTS +.IP \fIinnerRadius\fP 1i +Inner radius of the torus. +.IP \fIouterRadius\fP 1i +Outer radius of the torus. +.IP \fInsides\fP 1i +Number of sides for each radial section. +.IP \fIrings\fP 1i +Number of radial divisions for the torus. +.SH DESCRIPTION +glutSolidTorus and glutWireTorus render a solid or wireframe +torus (doughnut) respectively centered at the modeling coordinates origin +whose axis is aligned with the Z axis. +.SH SEE ALSO +glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidDodecahedron, +glutSolidOctahedron, glutSolidTetrahedron, glutSolidIcosahedron, +glutSolidTeapot +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSpaceballButtonFunc.man b/lib/glut-3.7.6/man/glut/glutSpaceballButtonFunc.man new file mode 100644 index 0000000000..d095d4e6d7 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSpaceballButtonFunc.man @@ -0,0 +1,36 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSpaceballButtonFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSpaceballButtonFunc - sets the Spaceball button callback for the current window. +.SH SYNTAX +.nf +.LP +void glutSpaceballButtonFunc(void (*func)(int button, int state)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new spaceball button callback function. +.SH DESCRIPTION +glutSpaceballButtonFunc sets the Spaceball button callback for the +current window. The Spaceball button callback for a window is called +when the window has Spaceball input focus (normally, when the mouse +is in the window) and the user generates Spaceball button presses. The +button parameter will be the button number (starting at one). The +number of available Spaceball buttons can be determined with +glutDeviceGet(GLUT_NUM_SPACEBALL_BUTTONS). The state is +either GLUT_UP or GLUT_DOWN indicating whether the callback was due +to a release or press respectively. + +Registering a Spaceball button callback when a Spaceball device is not +available is ineffectual and not an error. In this case, no Spaceball button +callbacks will be generated. + +Passing NULL to glutSpaceballButtonFunc disables the generation +of Spaceball button callbacks. When a new window is created, no +Spaceball button callback is initially registered. +.SH SEE ALSO +glutSpaceballMotionFunc, glutSpaceballRotateFunc, glutMouseFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutJoystickFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSpaceballMotionFunc.man b/lib/glut-3.7.6/man/glut/glutSpaceballMotionFunc.man new file mode 100644 index 0000000000..6f2c6df769 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSpaceballMotionFunc.man @@ -0,0 +1,34 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSpaceballMotionFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSpaceballMotionFunc - sets the Spaceball motion callback for the current window. +.SH SYNTAX +.nf +.LP +void glutSpaceballMotionFunc(void (*func)(int x, int y, int z)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new entry callback function. +.SH DESCRIPTION +glutSpaceballMotionFunc sets the Spaceball motion callback for +the current window. The Spaceball motion callback for a window is +called when the window has Spaceball input focus (normally, when the +mouse is in the window) and the user generates Spaceball translations. +The x, y, and z callback parameters indicate the translations along the X, +Y, and Z axes. The callback parameters are normalized to be within the +range of -1000 to 1000 inclusive. + +Registering a Spaceball motion callback when a Spaceball device is not +available has no effect and is not an error. In this case, no Spaceball +motion callbacks will be generated. + +Passing NULL to glutSpaceballMotionFunc disables the generation +of Spaceball motion callbacks. When a new window is created, no +Spaceball motion callback is initially registered. +.SH SEE ALSO +glutSpaceballRotateFunc, glutSpaceballButtonFunc, glutMotionFunc, glutTabletMotionFunc, glutJoystickFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSpaceballRotateFunc.man b/lib/glut-3.7.6/man/glut/glutSpaceballRotateFunc.man new file mode 100644 index 0000000000..d06f9a89bd --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSpaceballRotateFunc.man @@ -0,0 +1,35 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSpaceballRotateFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSpaceballRotateFunc - sets the Spaceball rotation callback for the current +window. +.SH SYNTAX +.nf +.LP +void glutSpaceballRotateFunc(void (*func)(int x, int y, int z)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new spaceball rotate callback function. +.SH DESCRIPTION +glutSpaceballRotateFunc sets the Spaceball rotate callback for the +current window. The Spaceball rotate callback for a window is called +when the window has Spaceball input focus (normally, when the mouse +is in the window) and the user generates Spaceball rotations. The x, y, +and z callback parameters indicate the rotation along the X, Y, and Z +axes. The callback parameters are normalized to be within the range of +-1800 to 1800 inclusive. + +Registering a Spaceball rotate callback when a Spaceball device is not +available is ineffectual and not an error. In this case, no Spaceball rotate +callbacks will be generated. + +Passing NULL to glutSpaceballRotateFunc disables the generation +of Spaceball rotate callbacks. When a new window is created, no +Spaceball rotate callback is initially registered. +.SH SEE ALSO +glutSpaceballMotionFunc, glutSpaceballButtonFunc, glutMotionFunc, glutTabletMotionFunc, glutJoystickFunc, glutDeviceGet +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSpecialFunc.man b/lib/glut-3.7.6/man/glut/glutSpecialFunc.man new file mode 100644 index 0000000000..c346a2ed69 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSpecialFunc.man @@ -0,0 +1,102 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSpecialFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSpecialFunc - sets the special keyboard callback for the current window. +.SH SYNTAX +.nf +.LP +void glutSpecialFunc(void (*func)(int key, int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new special callback function. +.SH DESCRIPTION +glutSpecialFunc sets the special keyboard callback for the current +window. The special keyboard callback is triggered when keyboard +function or directional keys are pressed. The key callback parameter is a +GLUT_KEY_* constant for the special key pressed. The x and y callback +parameters indicate the mouse in window relative coordinates when the +key was pressed. When a new window is created, no special callback is +initially registered and special key strokes in the window are ignored. +Passing NULL to glutSpecialFunc disables the generation of special +callbacks. + +During a special callback, glutGetModifiers may be called to +determine the state of modifier keys when the keystroke generating the +callback occurred. + +An implementation should do its best to provide ways to generate all the +GLUT_KEY_* special keys. The available GLUT_KEY_* values are: +.TP 8 +.B GLUT_KEY_F1 +F1 function key. +.TP 8 +.B GLUT_KEY_F2 +F2 function key. +.TP 8 +.B GLUT_KEY_F3 +F3 function key. +.TP 8 +.B GLUT_KEY_F4 +F4 function key. +.TP 8 +.B GLUT_KEY_F5 +F5 function key. +.TP 8 +.B GLUT_KEY_F6 +F6 function key. +.TP 8 +.B GLUT_KEY_F7 +F7 function key. +.TP 8 +.B GLUT_KEY_F8 +F8 function key. +.TP 8 +.B GLUT_KEY_F9 +F9 function key. +.TP 8 +.B GLUT_KEY_F10 +F10 function key. +.TP 8 +.B GLUT_KEY_F11 +F11 function key. +.TP 8 +.B GLUT_KEY_F12 +F12 function key. +.TP 8 +.B GLUT_KEY_LEFT +Left directional key. +.TP 8 +.B GLUT_KEY_UP +Up directional key. +.TP 8 +.B GLUT_KEY_RIGHT +Right directional key. +.TP 8 +.B GLUT_KEY_DOWN +Down directional key. +.TP 8 +.B GLUT_KEY_PAGE_UP +Page up directional key. +.TP 8 +.B GLUT_KEY_PAGE_DOWN +Page down directional key. +.TP 8 +.B GLUT_KEY_HOME +Home directional key. +.TP 8 +.B GLUT_KEY_END +End directional key. +.TP 8 +.B GLUT_KEY_INSERT +Inset directional key. +.LP +Note that the escape, backspace, and delete keys are generated as an ASCII +character. +.SH SEE ALSO +glutSpecialUpFunc, +glutKeyboardFunc, glutMouseFunc, glutSpaceballButtonFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutGetModifiers +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSpecialUpFunc.man b/lib/glut-3.7.6/man/glut/glutSpecialUpFunc.man new file mode 100644 index 0000000000..d112d8ad59 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSpecialUpFunc.man @@ -0,0 +1,105 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSpecialUpFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSpecialUpFunc - sets the special keyboard up (key release) callback for the current window. +.SH SYNTAX +.nf +.LP +void glutSpecialUpFunc(void (*func)(int key, int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new special callback function. +.SH DESCRIPTION +glutSpecialUpFunc sets the special keyboard up (key release) callback for the current +window. The special keyboard up callback is triggered when keyboard +function or directional keys are released. The key callback parameter is a +GLUT_KEY_* constant for the special key pressed. The x and y callback +parameters indicate the mouse in window relative coordinates when the +key was pressed. When a new window is created, no special up callback is +initially registered and special key releases in the window are ignored. +Passing NULL to glutSpecialUpFunc disables the generation of special up +callbacks. + +During a special up callback, glutGetModifiers may be called to +determine the state of modifier keys when the key release generating the +callback occurred. + +To avoid the reporting of key release/press pairs due to auto +repeat, use glutIgnoreKeyRepeat to ignore auto repeated keystrokes. + +An implementation should do its best to provide ways to generate all the +GLUT_KEY_* special keys. The available GLUT_KEY_* values are: +.TP 8 +.B GLUT_KEY_F1 +F1 function key. +.TP 8 +.B GLUT_KEY_F2 +F2 function key. +.TP 8 +.B GLUT_KEY_F3 +F3 function key. +.TP 8 +.B GLUT_KEY_F4 +F4 function key. +.TP 8 +.B GLUT_KEY_F5 +F5 function key. +.TP 8 +.B GLUT_KEY_F6 +F6 function key. +.TP 8 +.B GLUT_KEY_F7 +F7 function key. +.TP 8 +.B GLUT_KEY_F8 +F8 function key. +.TP 8 +.B GLUT_KEY_F9 +F9 function key. +.TP 8 +.B GLUT_KEY_F10 +F10 function key. +.TP 8 +.B GLUT_KEY_F11 +F11 function key. +.TP 8 +.B GLUT_KEY_F12 +F12 function key. +.TP 8 +.B GLUT_KEY_LEFT +Left directional key. +.TP 8 +.B GLUT_KEY_UP +Up directional key. +.TP 8 +.B GLUT_KEY_RIGHT +Right directional key. +.TP 8 +.B GLUT_KEY_DOWN +Down directional key. +.TP 8 +.B GLUT_KEY_PAGE_UP +Page up directional key. +.TP 8 +.B GLUT_KEY_PAGE_DOWN +Page down directional key. +.TP 8 +.B GLUT_KEY_HOME +Home directional key. +.TP 8 +.B GLUT_KEY_END +End directional key. +.TP 8 +.B GLUT_KEY_INSERT +Inset directional key. +.LP +Note that the escape, backspace, and delete keys are generated as an ASCII +character. +.SH SEE ALSO +glutSpecialFunc, +glutKeyboardFunc, glutKeyboardUpFunc, glutMouseFunc, glutSpaceballButtonFunc, glutButtonBoxFunc, glutTabletButtonFunc, glutGetModifiers, glutIgnoreKeyRepeat +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutStrokeCharacter.man b/lib/glut-3.7.6/man/glut/glutStrokeCharacter.man new file mode 100644 index 0000000000..237bbd9be0 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutStrokeCharacter.man @@ -0,0 +1,66 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutStrokeCharacter 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutStrokeCharacter - renders a stroke character using OpenGL. +.SH SYNTAX +.nf +.LP +void glutStrokeCharacter(void *font, int character); +.fi +.SH ARGUMENTS +.IP \fIfont\fP 1i +Stroke font to use. +.IP \fIcharacter\fP 1i +Character to render (not confined to 8 bits). +.SH DESCRIPTION +Without using any display lists, glutStrokeCharacter renders the +character in the named stroke font. The available fonts are: +.TP 8 +.B GLUT_STROKE_ROMAN +A proportionally spaced Roman Simplex font for ASCII characters +32 through 127. The maximum top character in the font is 119.05 +units; the bottom descends 33.33 units. +.TP 8 +.B GLUT_STROKE_MONO_ROMAN +A mono-spaced spaced Roman Simplex font (same characters as +GLUT_STROKE_ROMAN) for ASCII characters 32 through 127. The +maximum top character in the font is 119.05 units; the bottom +descends 33.33 units. Each character is 104.76 units wide. +.LP +Rendering a nonexistent character has no effect. A glTranslatef is +used to translate the current model view matrix to advance the width of +the character. +.SH EXAMPLE +Here is a routine that shows how to render a string of ASCII text +with glutStrokeCharacter: +.nf +.LP + void + output(GLfloat x, GLfloat y, char *text) + { + char *p; + + glPushMatrix(); + glTranslatef(x, y, 0); + for (p = text; *p; p++) + glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); + glPopMatrix(); + } +.fi +.LP +If you want to draw stroke font text using wide, antialiased lines, use: +.nf +.LP + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glLineWidth(2.0); + output(200, 225, "This is antialiased."); +.fi +.LP +.SH SEE ALSO +glutBitmapCharacter, glutStrokeWidth +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutStrokeWidth.man b/lib/glut-3.7.6/man/glut/glutStrokeWidth.man new file mode 100644 index 0000000000..ba0bcda274 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutStrokeWidth.man @@ -0,0 +1,35 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutStrokeWidth 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutStrokeWidth returns the width of a stroke character, +glutStrokeLength returns the length of a stroke font string. +.SH SYNTAX +.nf +.LP +int glutStrokeWidth(void *font, int character); +int glutStrokeLength(void *font, const unsigned char *string); +.fi +.SH ARGUMENTS +.IP \fIfont\fP 1i +Stroke font to use. +For valid values, see the +glutStrokeWidth description. +.IP \fIcharacter\fP 1i +Character to return width of (not confined to 8 bits). +.IP \fIstring\fP 1i +Text string (8-bit characters), nul terminated. +.SH DESCRIPTION +glutStrokeWidth returns the width in modeling units of a stroke character in a +supported stroke font. While the width of characters in a font may vary +(though fixed width fonts do not vary), the maximum height +characteristics of a particular font are fixed. + +glutStrokeLength returns the length in modeling units of a string (8-bit +characters). This length is equivalent to summing all the widths +returned by glutStrokeWidth for each character in the string. +.SH SEE ALSO +glutStrokeCharacter, glutBitmapWidth +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutSwapBuffers.man b/lib/glut-3.7.6/man/glut/glutSwapBuffers.man new file mode 100644 index 0000000000..005b36ce72 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutSwapBuffers.man @@ -0,0 +1,30 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutSwapBuffers 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutSwapBuffers - swaps the buffers of the current window if double buffered. +.SH SYNTAX +.nf +.LP +void glutSwapBuffers(void); +.fi +.SH DESCRIPTION +Performs a buffer swap on the layer in use for the current window. +Specifically, glutSwapBuffers promotes the contents of the back +buffer of the layer in use of the current window to become the contents +of the front buffer. The contents of the back buffer then become +undefined. The update typically takes place during the vertical retrace of +the monitor, rather than immediately after glutSwapBuffers is called. + +An implicit glFlush is done by glutSwapBuffers before it returns. +Subsequent OpenGL commands can be issued immediately after calling +glutSwapBuffers, but are not executed until the buffer exchange is +completed. + +If the layer in use is not double buffered, glutSwapBuffers has no +effect. +.SH SEE ALSO +glutPostRedisplay, glutDisplayFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutTabletButtonFunc.man b/lib/glut-3.7.6/man/glut/glutTabletButtonFunc.man new file mode 100644 index 0000000000..14dcff3193 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutTabletButtonFunc.man @@ -0,0 +1,39 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutTabletButtonFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutTabletButtonFunc - sets the special keyboard callback for the current window. +.SH SYNTAX +.nf +.LP +void glutTabletButtonFunc(void (*func)(int button, int state, + int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new tablet button callback function. +.SH DESCRIPTION +glutTabletButtonFunc sets the tablet button callback for the current +window. The tablet button callback for a window is called when the +window has tablet input focus (normally, when the mouse is in the +window) and the user generates tablet button presses. The button +parameter will be the button number (starting at one). The number of +available tablet buttons can be determined with +glutDeviceGet(GLUT_NUM_TABLET_BUTTONS). The state is +either GLUT_UP or GLUT_DOWN indicating whether the callback was due +to a release or press respectively. The x and y callback parameters +indicate the window relative coordinates when the tablet button state +changed. + +Registering a tablet button callback when a tablet device is not available +is ineffectual and not an error. In this case, no tablet button callbacks will +be generated. + +Passing NULL to glutTabletButtonFunc disables the generation of +tablet button callbacks. When a new window is created, no tablet button +callback is initially registered. +.SH SEE ALSO +glutTabletMotionFunc, glutDeviceGet, glutMotionFunc, glutSpaceballMotionFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutTabletMotionFunc.man b/lib/glut-3.7.6/man/glut/glutTabletMotionFunc.man new file mode 100644 index 0000000000..370b690dfe --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutTabletMotionFunc.man @@ -0,0 +1,34 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutTabletMotionFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutTabletMotionFunc - sets the special keyboard callback for the current window. +.SH SYNTAX +.nf +.LP +void glutTabletMotionFunc(void (*func)(int x, int y)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new entry callback function. +.SH DESCRIPTION +glutTabletMotionFunc sets the tablet motion callback for the +current window. The tablet motion callback for a window is called when +the window has tablet input focus (normally, when the mouse is in the +window) and the user generates tablet motion. The x and y callback +parameters indicate the absolute position of the tablet ``puck'' on the +tablet. The callback parameters are normalized to be within the range of +0 to 2000 inclusive. + +Registering a tablet motion callback when a tablet device is not available +is ineffectual and not an error. In this case, no tablet motion callbacks +will be generated. + +Passing NULL to glutTabletMotionFunc disables the generation of +tablet motion callbacks. When a new window is created, no tablet motion +callback is initially registered. +.SH SEE ALSO +glutTabletButtonFunc, glutDeviceGet, glutMotionFunc, glutSpaceballMotionFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutTimerFunc.man b/lib/glut-3.7.6/man/glut/glutTimerFunc.man new file mode 100644 index 0000000000..013b91eb12 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutTimerFunc.man @@ -0,0 +1,37 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutTimerFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutTimerFunc - registers a timer callback to be triggered in a +specified number of milliseconds. +.SH SYNTAX +.nf +.LP +void glutTimerFunc(unsigned int msecs, + void (*func)(int value), value); +.fi +.SH ARGUMENTS +.IP \fImsecs\fP 1i +Number of milliseconds to pass before calling the callback. +.IP \fIfunc\fP 1i +The timer callback function. +.IP \fIvalue\fP 1i +Integer value to pass to the timer callback. +.SH DESCRIPTION +glutTimerFunc registers the timer callback func to be triggered in at +least msecs milliseconds. The value parameter to the timer callback +will be the value of the value parameter to glutTimerFunc. Multiple +timer callbacks at same or differing times may be registered +simultaneously. + +The number of milliseconds is a lower bound on the time before the +callback is generated. GLUT attempts to deliver the timer callback as +soon as possible after the expiration of the callback's time interval. + +There is no support for canceling a registered callback. Instead, ignore a +callback based on its value parameter when it is triggered. +.SH SEE ALSO +glutIdleFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutUseLayer.man b/lib/glut-3.7.6/man/glut/glutUseLayer.man new file mode 100644 index 0000000000..b35c95213f --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutUseLayer.man @@ -0,0 +1,28 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutUseLayer 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutUseLayer - changes the layer in use for the current window. +.SH SYNTAX +.nf +.LP +void glutUseLayer(GLenum layer); +.fi +.SH ARGUMENTS +.IP \fIlayer\fP 1i +Either GLUT_NORMAL or GLUT_OVERLAY, selecting the normal +plane or overlay respectively. +.SH DESCRIPTION +glutUseLayer changes the per-window layer in use for the current +window, selecting either the normal plane or overlay. The overlay should +only be specified if an overlay exists, however windows without an +overlay may still call glutUseLayer(GLUT_NORMAL). OpenGL +commands for the window are directed to the current layer in use. + +To query the layer in use for a window, call +glutLayerGet(GLUT_LAYER_IN_USE). +.SH SEE ALSO +glutEstablishOverlay, glutSetWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutVisibilityFunc.man b/lib/glut-3.7.6/man/glut/glutVisibilityFunc.man new file mode 100644 index 0000000000..62aa1ed2e0 --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutVisibilityFunc.man @@ -0,0 +1,39 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1996. +.\" +.TH glutVisibilityFunc 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutVisibilityFunc - sets the visibility callback for the current window. +.SH SYNTAX +.nf +.LP +void glutVisibilityFunc(void (*func)(int state)); +.fi +.SH ARGUMENTS +.IP \fIfunc\fP 1i +The new visibility callback function. +.SH DESCRIPTION +glutVisibilityFunc sets the visibility callback for the current +window. The visibility callback for a window is called when the visibility +of a window changes. The state callback parameter is either +GLUT_NOT_VISIBLE or GLUT_VISIBLE depending on the current +visibility of the window. GLUT_VISIBLE does not distinguish a window +being totally versus partially visible. GLUT_NOT_VISIBLE means no part +of the window is visible, i.e., until the window's visibility changes, all +further rendering to the window is discarded. + +GLUT considers a window visible if any pixel of the window is visible or +any pixel of any descendant window is visible on the screen. + +Passing NULL to glutVisibilityFunc disables the generation of the +visibility callback. + +If the visibility callback for a window is disabled and later re-enabled, the +visibility status of the window is undefined; any change in window +visibility will be reported, that is if you disable a visibility callback and +re-enable the callback, you are guaranteed the next visibility change will +be reported. +.SH SEE ALSO +glutCreateWindow, glutPopWindow +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/man/glut/glutWarpPointer.man b/lib/glut-3.7.6/man/glut/glutWarpPointer.man new file mode 100644 index 0000000000..7f733904eb --- /dev/null +++ b/lib/glut-3.7.6/man/glut/glutWarpPointer.man @@ -0,0 +1,39 @@ +.\" +.\" Copyright (c) Mark J. Kilgard, 1997. +.\" +.TH glutWarpPointer 3GLUT "3.7" "GLUT" "GLUT" +.SH NAME +glutWarpPointer warps the pointer's location. +.SH SYNTAX +.nf +.LP +void glutWarpPointer(int x, int y); +.fi +.SH ARGUMENTS +.IP \fIx\fP 1i +X offset relative to the current window's origin (upper left). +.IP \fIy\fP 1i +Y offset relative to the current window's origin (upper left). +.SH DESCRIPTION +glutWarpPointer warps the window system's pointer to a new location +relative to the origin of the current window. The new location will +be offset +.I x +pixels on the X axis and +.I y +pixels on the Y axis. +These parameters may be negative. The warp is done immediately. + +If the pointer would be warped outside the screen's frame buffer +region, the location will be clamped to the nearest screen edge. The +window system is allowed to further constrain the pointer's location in +window system dependent ways. + +The following is good advice that applies to glutWarpPointer: +``There is seldom any reason for calling this function. The pointer +should normally be left to the user.'' (from Xlib's +XWarpPointer man page.) +.SH SEE ALSO +glutMouseFunc, glutMotionFunc +.SH AUTHOR +Mark J. Kilgard (mjk@nvidia.com) diff --git a/lib/glut-3.7.6/mkmkfiles.imake b/lib/glut-3.7.6/mkmkfiles.imake new file mode 100644 index 0000000000..20982537a0 --- /dev/null +++ b/lib/glut-3.7.6/mkmkfiles.imake @@ -0,0 +1,65 @@ +#!/bin/csh -f +# +# Let user know what's going on... +# +set verbose +# +mv -f Makefile Makefile.bak >& /dev/null +# +# Unfortunately, some systems vary where they find imake, imake's config +# files, and/or xmkmf. You may need to be clever to get Makefiles +# generated if your system is non-standard. The following tries its best +# to generate the Makefiles for you... +# +if ( -d /usr/lib/X11/config) then + if ( -x /usr/bin/X11/imake ) then + # Things are in standard places + /usr/bin/X11/imake -DUseInstalled -I/usr/lib/X11/config -DTOPDIR=. + else + # Hope imake is on your path! + imake -DUseInstalled -I/usr/lib/X11/config -DTOPDIR=. + endif +else # Try non-standard places vendor locations + # Look for IBM's non-standard placement of imake + if ( -d /usr/lpp/X11/Xamples/config) then + if ( -x /usr/lpp/X11/Xamples/config/imake ) then + # Things are in non-standard IBM AIX places + /usr/lpp/X11/Xamples/config/imake -DUseInstalled -I/usr/lpp/X11/Xamples/config -DTOPDIR=. + else + # Hope imake is on your path! + imake -DUseInstalled -I/usr/lpp/X11/Xamples/config -DTOPDIR=. + endif + else + # Look for Sun's non-standard placement of imake and xmkmf + if ( -x /usr/openwin/bin/xmkmf ) then + # Make sure that /usr/openwin/bin is at the front of your + # path so that you pick up /usr/openwin/bin/imake when + # you run /usr/openwin/bin/xmkmf instead of some other + # imake potentially mismatched with the /usr/openwin/lib/config + # config files. + set path = ( /usr/openwin/bin $path ) + /usr/openwin/bin/xmkmf + else + # Look for FreeBSD's non-standard placement of imake and xmkmf + if ( -d /usr/X11R6/lib/X11/config ) then + if ( -x /usr/X11R6/bin/imake ) then + # We found FreeBSD's location for imake and xmkmf + /usr/X11R6/bin/imake -DUseInstalled -I/usr/X11R6/lib/X11/config -DTOPDIR=. + else + # Hope imake is on your path! + imake -DUseInstalled -I/usr/X11R6/lib/X11/config -DTOPDIR=. + endif + else + # Hope xmkmf is on your path! + xmkmf + endif + endif + endif +endif +make Makefiles + +## man subdirectory is not built by default +## uncomment line below to build its Makefiles +#make SUBDIRS=man Makefiles + +make depend diff --git a/lib/glut-3.7.6/mkmkfiles.sgi b/lib/glut-3.7.6/mkmkfiles.sgi new file mode 100644 index 0000000000..0d8c125a9f --- /dev/null +++ b/lib/glut-3.7.6/mkmkfiles.sgi @@ -0,0 +1,12 @@ +#!/bin/csh -f +echo "Setting up use of SGI Makefiles" +echo "" +echo "NOTE: If you have a Fortran compiler and IRIX 5.3 or later, please see" +echo "the instructions in README.fortran for building the GLUT Fortran" +echo "API and sample programs. Fortran code is not built by default." +echo "" +foreach i ( `find . -name Makefile.sgi -print` ) + echo "Linking $i to $i:r" + rm -f $i:r + ln -s Makefile.sgi $i:r +end diff --git a/lib/glut-3.7.6/progs/Imakefile b/lib/glut-3.7.6/progs/Imakefile new file mode 100644 index 0000000000..f454a38260 --- /dev/null +++ b/lib/glut-3.7.6/progs/Imakefile @@ -0,0 +1,14 @@ + +/* Copyright (c) Mark J. Kilgard, 1997, 1998. */ + +#define IHaveSubdirs +#define PassCDebugFlags + +SUBDIRS = examples redbook demos contrib advanced mesademos \ + texfont perf_harness mui gle gameglut bucciarelli advanced97 spheremap tiff + +/* not yet ready for gnu/linux (mostly headers): glc inventor sgi-stero */ +/* not yet ready for gnu/linux (mostly language): ada fortran */ + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) diff --git a/lib/glut-3.7.6/progs/ada/README b/lib/glut-3.7.6/progs/ada/README new file mode 100644 index 0000000000..5057033a35 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/README @@ -0,0 +1,10 @@ + +See the ../../README.ada file for details of how to use GLUT with the +Ada language binding. Unless you program in Ada, this directory is +probably not that interesting to you. + +For the most part, these programs are the "redbook" programs just +converted to use Ada instead of C. + +- Mark Kilgard + October 9, 1997 diff --git a/lib/glut-3.7.6/progs/ada/ada_sphere.adb b/lib/glut-3.7.6/progs/ada/ada_sphere.adb new file mode 100644 index 0000000000..4cde400f7c --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/ada_sphere.adb @@ -0,0 +1,40 @@ + +with GL; use GL; +with Interfaces.C.Strings; +with Glut; use Glut; +with ada_sphere_procs; use ada_sphere_procs; + +procedure ada_sphere is + + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + win : Integer; + m : Integer; + +begin + + glutInit (argc'access, argv); + + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_DOUBLE); + win := glutCreateWindow("ada_sphere"); + + glutDisplayFunc(display'access); + glutReshapeFunc(reshape'access); + + init; + + m := glutCreateMenu(menu'access); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop; + +end ada_sphere; diff --git a/lib/glut-3.7.6/progs/ada/ada_sphere_procs.adb b/lib/glut-3.7.6/progs/ada/ada_sphere_procs.adb new file mode 100644 index 0000000000..01ce267cce --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/ada_sphere_procs.adb @@ -0,0 +1,60 @@ + +with GL; use GL; +with GLU; use GLU; +with Glut; use Glut; +with GNAT.OS_Lib; + +package body ada_sphere_procs is + + procedure display is + + begin + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + glutSolidSphere(1.0, 10, 10); + glutSwapBuffers; + end display; + + procedure reshape(w : Integer; h : Integer) is + + begin + glViewport(0, 0, GLsizei(w), GLsizei(h)); + end reshape; + + procedure menu (value : Integer) is + + begin + if (value = 666) then + GNAT.OS_Lib.OS_Exit (0); + end if; + end menu; + + procedure init is + + light_diffuse : array(0 .. 3) of aliased GLfloat := + (1.0, 0.0, 0.0, 1.0); + light_position : array(0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 0.0); + + begin + glClearColor(0.1, 0.1, 0.1, 0.0); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse(0)'access); + glLightfv(GL_LIGHT0, GL_POSITION, light_position(0)'access); + + glFrontFace(GL_CW); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + glMatrixMode(GL_PROJECTION); + gluPerspective(40.0, 1.0, 1.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + gluLookAt( + 0.0, 0.0, -5.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + end init; + +end ada_sphere_procs; diff --git a/lib/glut-3.7.6/progs/ada/ada_sphere_procs.ads b/lib/glut-3.7.6/progs/ada/ada_sphere_procs.ads new file mode 100644 index 0000000000..bb0e3f4de9 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/ada_sphere_procs.ads @@ -0,0 +1,10 @@ + +with GL; use GL; +with Glut; use Glut; + +package ada_sphere_procs is + procedure display; + procedure reshape (w : Integer; h : Integer); + procedure menu (value : Integer); + procedure init; +end ada_sphere_procs; diff --git a/lib/glut-3.7.6/progs/ada/bezmesh.adb b/lib/glut-3.7.6/progs/ada/bezmesh.adb new file mode 100644 index 0000000000..be94b4cfe0 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/bezmesh.adb @@ -0,0 +1,71 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. + +with GL; use GL; +with Glut; use Glut; +with Bezmesh_Procs; use Bezmesh_Procs; +with Interfaces.C.Strings; + +procedure Bezmesh is + + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + winRet : Integer; +begin + glutInitWindowSize(500, 500); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + winRet := glutCreateWindow ("OpenGL and Ada: bezmesh"); + + Initialize; + + glutReshapeFunc(HandleReshape'ACCESS); + glutDisplayFunc(Display'ACCESS); + glutMainLoop; +end Bezmesh; diff --git a/lib/glut-3.7.6/progs/ada/bezmesh_procs.adb b/lib/glut-3.7.6/progs/ada/bezmesh_procs.adb new file mode 100644 index 0000000000..62ff489473 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/bezmesh_procs.adb @@ -0,0 +1,116 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Text_IO; use Text_IO; + +package body Bezmesh_Procs is + Bezier_Control_Points : array (1 .. 4, 1 .. 4, 1 .. 3) of aliased GLfloat := + (((-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))); + + + procedure Initialize is + ambient : array (0 .. 3) of aliased GLfloat := + (0.2, 0.2, 0.2, 1.0); + diffuse : array (0 .. 3) of aliased GLfloat := + (0.0, 0.0, 2.0, 1.0); + position : array (0 .. 3) of aliased GLfloat := + (0.6, 0.6, 0.6, 1.0); + + mat_diffuse : array (0 .. 3) of aliased GLfloat := + (0.6, 0.6, 0.6, 1.0); + mat_specular : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + mat_shininess : aliased GLfloat := 50.0; + + begin + glClearColor (0.0, 0.0, 0.0, 1.0); + glEnable (GL_DEPTH_TEST); + glMap2f (GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, + Bezier_Control_Points(1,1,1)'ACCESS); + glEnable (GL_MAP2_VERTEX_3); + glEnable (GL_AUTO_NORMAL); + glEnable (GL_NORMALIZE); + glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); + + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + + glLightfv (GL_LIGHT0, GL_AMBIENT, ambient (0)'access); + glLightfv (GL_LIGHT0, GL_POSITION, position (0)'access); + + glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse (0)'access); + glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular (0)'access); + glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess'access); + end Initialize; + + procedure Display is + begin + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + + glPushMatrix; + +-- Glloadidentity; + Glrotatef (85.0, 1.0, 1.0, 1.0); + glEvalMesh2 (GL_FILL, 0, 20, 0, 20); + + glPopMatrix; + + glFlush; + end Display; + + procedure HandleReshape (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + GlMatrixMode (GL_PROJECTION); + GlLoadIdentity; + if (W < H) then + Glortho (-4.0, 4.0, -4.0 * Gldouble (H / W), 4.0 * Gldouble (H / W), + -4.0, 4.0); + else + Glortho (-4.0 * Gldouble (W / H), 4.0 * Gldouble (W / H), + -4.0, 4.0, -4.0, 4.0); + end if; + end HandleReshape; +end Bezmesh_Procs; diff --git a/lib/glut-3.7.6/progs/ada/bezmesh_procs.ads b/lib/glut-3.7.6/progs/ada/bezmesh_procs.ads new file mode 100644 index 0000000000..59f78d0eb2 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/bezmesh_procs.ads @@ -0,0 +1,46 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Bezmesh_Procs is + procedure Initialize; + procedure Display; + procedure HandleReshape (w : Integer; h : Integer); + + An_Error : exception; +end Bezmesh_Procs; diff --git a/lib/glut-3.7.6/progs/ada/cone.adb b/lib/glut-3.7.6/progs/ada/cone.adb new file mode 100644 index 0000000000..d1f3b53b14 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/cone.adb @@ -0,0 +1,68 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Cone_Procs; use Cone_Procs; +with Interfaces.C.Strings; + +procedure Cone is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize(500, 500); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL and Ada: cone"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'ACCESS); + glutDisplayFunc (DoDisplay'ACCESS); + glutMainLoop; +end Cone; diff --git a/lib/glut-3.7.6/progs/ada/cone_procs.adb b/lib/glut-3.7.6/progs/ada/cone_procs.adb new file mode 100644 index 0000000000..d2b1f60372 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/cone_procs.adb @@ -0,0 +1,120 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with GLU; use GLU; + +package body Cone_Procs is + procedure DoInit is + mat_ambient : array (0 .. 3) of aliased GLfloat := + (0.2, 0.2, 0.2, 1.0); + mat_diffuse : array (0 .. 3) of aliased GLfloat := + (0.8, 0.8, 0.8, 1.0); + -- Specular and Shininess are not default values + mat_specular : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + mat_shininess : aliased GLfloat := 50.0; + + light_ambient : array (0 .. 3) of aliased GLfloat := + (0.0, 0.0, 0.0, 1.0); + light_diffuse : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + light_specular : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + light_position : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 0.0); + + lmodel_ambient : array (0 .. 3) of aliased GLfloat := + (0.2, 0.2, 0.2, 1.0); + begin + glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient (0)'Access); + glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse (0)'Access); + glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular (0)'Access); + glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess'Access); + + glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient (0)'Access); + glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse (0)'Access); + glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular (0)'Access); + glLightfv (GL_LIGHT0, GL_POSITION, light_position (0)'Access); + + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient (0)'Access); + + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_DEPTH_TEST); + end DoInit; + + procedure solidCone (base : Float; height : Float) is + quadObj : GLUquadricObj_Ptr; + begin + quadObj := gluNewQuadric; + gluQuadricDrawStyle (quadObj, GLU_FILL); + gluQuadricNormals (quadObj, GLU_SMOOTH); + gluCylinder (quadObj, GLdouble(base), 0.0, GLdouble(height), 15, 10); + gluDeleteQuadric (quadObj); + end solidCone; + + procedure DoDisplay is + begin + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + + glPushMatrix; + glTranslatef (0.0, -1.0, 0.0); + glRotatef (250.0, 1.0, 0.0, 0.0); + solidCone (1.0, 2.0); + glPopMatrix; + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + + if w <= h then + glOrtho (-1.5, 1.5, GLdouble (-1.5*Float (h)/Float (w)), + GLdouble (1.5*Float (h)/Float (w)), -10.0, 10.0); + else + glOrtho (GLdouble (-1.5*Float (w)/Float (h)), + GLdouble (1.5*Float (w)/Float (h)), -1.5, 1.5, -10.0, 10.0); + end if; + + glMatrixMode (GL_MODELVIEW); + end ReshapeCallback; +end Cone_Procs; diff --git a/lib/glut-3.7.6/progs/ada/cone_procs.ads b/lib/glut-3.7.6/progs/ada/cone_procs.ads new file mode 100644 index 0000000000..e79cd72125 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/cone_procs.ads @@ -0,0 +1,44 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Cone_Procs is + procedure DoInit; + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Cone_Procs; diff --git a/lib/glut-3.7.6/progs/ada/dof.adb b/lib/glut-3.7.6/progs/ada/dof.adb new file mode 100644 index 0000000000..22bbe2e2e0 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/dof.adb @@ -0,0 +1,68 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Dof_Procs; use Dof_Procs; +with Interfaces.C.Strings; + +procedure Dof is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize(500, 500); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL and Ada: dof"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'Access); + glutDisplayFunc (DoDisplay'Access); + glutMainLoop; +end Dof; diff --git a/lib/glut-3.7.6/progs/ada/dof_procs.adb b/lib/glut-3.7.6/progs/ada/dof_procs.adb new file mode 100644 index 0000000000..e287f2f7c5 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/dof_procs.adb @@ -0,0 +1,200 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Jitter; +with Ada.Numerics; +with Ada.Numerics.Generic_Elementary_Functions; + +package body Dof_Procs is + package Num renames Ada.Numerics; + package GLdouble_GEF is new + Num.Generic_Elementary_Functions (GLdouble); + use GLdouble_GEF; + + procedure accFrustum + (left : GLdouble; right : GLdouble; bottom : GLdouble; + top : GLdouble; near : GLdouble; far : GLdouble; + pixdx : GLdouble; pixdy : GLdouble; eyedx : GLdouble; + eyedy : GLdouble; focus : GLdouble) + is + xwsize, ywsize : GLdouble; + dx, dy : GLdouble; + viewport : array (0 .. 3) of aliased GLint; + begin + glGetIntegerv (GL_VIEWPORT, viewport (0)'Access); + + xwsize := right - left; + ywsize := top - bottom; + + dx := -(pixdx * xwsize / GLdouble (viewport (2)) + eyedx * near / focus); + dy := -(pixdy * ywsize / GLdouble (viewport (3)) + eyedy * near / focus); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + glFrustum (left + dx, right + dx, bottom + dy, top + dy, near, far); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + glTranslated (-eyedx, -eyedy, 0.0); + end accFrustum; + + procedure accPerspective + (fovy : GLdouble; aspect : GLdouble; near : GLdouble; + far : GLdouble; pixdx : GLdouble; pixdy : GLdouble; + eyedx : GLdouble; eyedy : GLdouble; focus : GLdouble) + is + fov2, left, right, bottom, top : GLdouble; + begin + fov2 := ((fovy * Num.Pi) / 180.0) / 2.0; + + top := near / (Cos (fov2) / Sin (fov2)); + bottom := -top; + + right := top * aspect; + left := -right; + + accFrustum (left, right, bottom, top, near, far, pixdx, + pixdy, eyedx, eyedy, focus); + end accPerspective; + + procedure DoInit is + ambient : array (0 .. 3) of aliased GLfloat := + (0.0, 0.0, 0.0, 1.0); + diffuse : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + position : array (0 .. 3) of aliased GLfloat := + (0.0, 3.0, 3.0, 0.0); + + lmodel_ambient : array (0 .. 3) of aliased GLfloat := + (0.2, 0.2, 0.2, 1.0); + local_view : aliased GLfloat := 0.0; + begin + glLightfv (GL_LIGHT0, GL_AMBIENT, ambient (0)'Access); + glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse (0)'Access); + glLightfv (GL_LIGHT0, GL_POSITION, position (0)'Access); + + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient (0)'Access); + glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, local_view'Access); + + glFrontFace (GL_CW); + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_AUTO_NORMAL); + glEnable (GL_NORMALIZE); + + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + + glClearColor (0.0, 0.0, 0.0, 0.0); + glClearAccum (0.0, 0.0, 0.0, 0.0); + end DoInit; + + procedure renderTeapot + (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 : GLfloat) + is + mat : array (0 .. 3) of aliased GLfloat; + begin + glPushMatrix; + + glTranslatef (x, y, z); + + mat (0) := ambr; + mat (1) := ambg; + mat (2) := ambb; + mat (3) := 1.0; + glMaterialfv (GL_FRONT, GL_AMBIENT, mat (0)'Access); + + mat (0) := difr; + mat (1) := difg; + mat (2) := difb; + glMaterialfv (GL_FRONT, GL_DIFFUSE, mat (0)'Access); + + mat (0) := specr; + mat (1) := specg; + mat (2) := specb; + glMaterialfv (GL_FRONT, GL_SPECULAR, mat (0)'Access); + + glMaterialf (GL_FRONT, GL_SHININESS, shine * 128.0); + + glutSolidTeapot (0.5); + glPopMatrix; + end renderTeapot; + + procedure DoDisplay is + viewport : array (0 .. 3) of aliased GLint; + begin + glGetIntegerv (GL_VIEWPORT, viewport (0)'Access); + glClear (GL_ACCUM_BUFFER_BIT); + + for jitval in 1 .. 8 loop + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + accPerspective (45.0, GLdouble (viewport (2)) / + GLdouble (viewport (3)), + 1.0, 15.0, 0.0, 0.0, GLdouble (0.33 * Jitter.j8 (jitval).x), + GLdouble (0.33 * Jitter.j8 (jitval).y), 5.0); + + 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, 0.25); + glAccum (GL_ACCUM, 0.125); + end loop; + + glAccum (GL_RETURN, 1.0); + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + end ReshapeCallback; +end Dof_Procs; diff --git a/lib/glut-3.7.6/progs/ada/dof_procs.ads b/lib/glut-3.7.6/progs/ada/dof_procs.ads new file mode 100644 index 0000000000..d2922e7d76 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/dof_procs.ads @@ -0,0 +1,62 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Dof_Procs is + procedure accFrustum + (left : GLdouble; right : GLdouble; bottom : GLdouble; + top : GLdouble; near : GLdouble; far : GLdouble; + pixdx : GLdouble; pixdy : GLdouble; eyedx : GLdouble; + eyedy : GLdouble; focus : GLdouble); + + procedure accPerspective + (fovy : GLdouble; aspect : GLdouble; near : GLdouble; + far : GLdouble; pixdx : GLdouble; pixdy : GLdouble; + eyedx : GLdouble; eyedy : GLdouble; focus : GLdouble); + + procedure renderTeapot + (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 : GLfloat); + + procedure DoInit; + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Dof_Procs; diff --git a/lib/glut-3.7.6/progs/ada/fog.adb b/lib/glut-3.7.6/progs/ada/fog.adb new file mode 100644 index 0000000000..444e45e705 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/fog.adb @@ -0,0 +1,67 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Fog_Procs; use Fog_Procs; +with Interfaces.C.Strings; + +procedure Fog is + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + winRet : Integer; +begin + glutInitWindowSize(450, 150); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + winRet := glutCreateWindow ("OpenGL and Ada: fog"); + glutMouseFunc (CycleFog'ACCESS); + + Initialize; + + glutReshapeFunc (HandleReshape'ACCESS); + glutDisplayFunc (Display'ACCESS); + glutMainLoop; +end Fog; diff --git a/lib/glut-3.7.6/progs/ada/fog_procs.adb b/lib/glut-3.7.6/progs/ada/fog_procs.adb new file mode 100644 index 0000000000..6835a866cf --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/fog_procs.adb @@ -0,0 +1,162 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; use Text_IO; +with Unchecked_Conversion; + +package body Fog_Procs is + package tio renames Text_IO; + + function FogToInt is new + Unchecked_Conversion (Source => FogMode, Target => GLint); + + procedure CycleFog (btn: Integer; state: Integer; x, y: Integer) is + begin + if btn = GLUT_LEFT_BUTTON then + if state = GLUT_DOWN then + if fogType = GL_EXP then + fogType := GL_EXP2; + elsif fogType = GL_EXP2 then + fogType := GL_LINEAR; + glFogf (GL_FOG_START, 1.0); + glFogf (GL_FOG_END, 5.0); + elsif fogType = GL_LINEAR then + fogType := GL_EXP; + end if; + +-- tio.Put_Line("Fog mode is " & FogMode'IMAGE (fogType)); + + glFogi (GL_FOG_MODE, FogToInt (fogType)); + glutPostRedisplay; + end if; + end if; + end CycleFog; + + procedure Initialize is + position : array (0 .. 3) of aliased GLfloat := + (0.0, 3.0, 3.0, 0.0); + local_view : aliased GLfloat := 0.0; + + fogColor : array (0 .. 3) of aliased GLfloat := + (0.5, 0.5, 0.5, 1.0); + begin + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + + glLightfv (GL_LIGHT0, GL_POSITION, position (0)'Access); + glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, local_view'Access); + + glFrontFace (GL_CW); + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_AUTO_NORMAL); + glEnable (GL_NORMALIZE); + glEnable (GL_FOG); + + fogType := GL_EXP; + + glFogi (GL_FOG_MODE, FogToInt (fogType)); + glFogfv (GL_FOG_COLOR, fogColor (0)'Access); + glFogf (GL_FOG_DENSITY, 0.35); + glHint (GL_FOG_HINT, GL_DONT_CARE); + glClearColor (0.5, 0.5, 0.5, 1.0); + end Initialize; + + procedure RenderRedTeapot (x : GLfloat; y : GLfloat; z : GLfloat) is + mat : array (0 .. 3) of aliased GLfloat; + begin + 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 (0)'Access); + + mat (0) := 0.61424; + mat (1) := 0.04136; + mat (2) := 0.04136; + glMaterialfv (GL_FRONT, GL_DIFFUSE, mat (0)'Access); + + mat (0) := 0.727811; + mat (1) := 0.626959; + mat (2) := 0.626959; + glMaterialfv (GL_FRONT, GL_SPECULAR, mat (0)'Access); + + glMaterialf (GL_FRONT, GL_SHININESS, 0.6*128.0); + + glutSolidTeapot (1.0); + + glPopMatrix; + end RenderRedTeapot; + + procedure Display is + begin + glClear (GL_COLOR_BUFFER_BIT or 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; + end Display; + + procedure HandleReshape (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + glMatrixMode (GL_PROJECTION); + + glLoadIdentity; + + if w <= (h * 3) then + glOrtho (-6.0, 6.0, + GLdouble (-2.0 * (GLdouble (h) * 3.0) / GLdouble (w)), + GLdouble (2.0 * (GLdouble (h) * 3.0 / GLdouble (w))), 0.0, 10.0); + else + glOrtho (GLdouble (-6.0 * GLdouble (w) / (GLdouble (h) * 3.0)), + GLdouble (6.0 * GLdouble (w) / (GLdouble (h) * 3.0)), + -2.0, 2.0, 0.0, 10.0); + end if; + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + end HandleReshape; +end Fog_Procs; diff --git a/lib/glut-3.7.6/progs/ada/fog_procs.ads b/lib/glut-3.7.6/progs/ada/fog_procs.ads new file mode 100644 index 0000000000..92e86f8f07 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/fog_procs.ads @@ -0,0 +1,48 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Fog_Procs is + fogType : FogMode; + + procedure CycleFog (btn: Integer; state: Integer; x, y: Integer); + procedure Initialize; + procedure RenderRedTeapot (x : GLfloat; y : GLfloat; z : GLfloat); + procedure Display; + procedure HandleReshape (w : Integer; h : Integer); +end Fog_Procs; diff --git a/lib/glut-3.7.6/progs/ada/jitter.ads b/lib/glut-3.7.6/progs/ada/jitter.ads new file mode 100644 index 0000000000..72d835d45a --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/jitter.ads @@ -0,0 +1,182 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Jitter is + type Jitter_Point is + record + x, y : GLfloat; + end record; + + j2 : array (1 .. 2) of Jitter_Point := + ((0.246490, 0.249999), + (-0.246490, -0.249999)); + + j3 : array (1 .. 3) of Jitter_Point := + ((-0.373411, -0.250550), + (0.256263, 0.368119), + (0.117148, -0.117570)); + + j4 : array (1 .. 4) of Jitter_Point := + ((-0.208147, 0.353730), + (0.203849, -0.353780), + (-0.292626, -0.149945), + (0.296924, 0.149994)); + + j8 : array (1 .. 8) of Jitter_Point := + ((-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)); + + j15 : array (1 .. 15) of Jitter_Point := + ((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)); + + j24 : array (1 .. 24) of Jitter_Point := + ((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)); + + j66 : array (1 .. 66) of Jitter_Point := + ((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)); + +end Jitter; diff --git a/lib/glut-3.7.6/progs/ada/pickdepth.adb b/lib/glut-3.7.6/progs/ada/pickdepth.adb new file mode 100644 index 0000000000..794725857a --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/pickdepth.adb @@ -0,0 +1,69 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with PickDepth_Procs; use PickDepth_Procs; +with Interfaces.C.Strings; + +procedure PickDepth is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize (300, 300); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL & Ada: pickdepth"); + + DoInit; + + glutMouseFunc (PickRects'Access); + glutReshapeFunc (ReshapeCallback'Access); + glutDisplayFunc (DoDisplay'Access); + glutMainLoop; +end PickDepth; diff --git a/lib/glut-3.7.6/progs/ada/pickdepth_procs.adb b/lib/glut-3.7.6/progs/ada/pickdepth_procs.adb new file mode 100644 index 0000000000..24e9f29063 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/pickdepth_procs.adb @@ -0,0 +1,166 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with GLU; use GLU; +with GLUT; use GLUT; +with Text_IO; + +package body PickDepth_Procs is + package tio renames Text_IO; + + procedure DoInit is + begin + glClearColor (0.0, 0.0, 0.0, 0.0); + glDepthFunc (GL_LESS); + glEnable (GL_DEPTH_TEST); + glShadeModel (GL_FLAT); + glDepthRange (0.0, 1.0); + end DoInit; + + procedure DrawRects (mode : RenderingMode) is + begin + if mode = GL_SELECT then glLoadName (1); end if; + 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 then glLoadName (2); end if; + 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 then glLoadName (3); end if; + 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; + end DrawRects; + + type int_ar is array (Integer range <>) of aliased GLuint; + + procedure ProcessHits (hits : GLint; buffer : in int_ar) is + j : Integer := buffer'First; + begin + tio.Put_Line ("Hits = " & GLint'Image (hits)); + + if hits /= 0 then + for i in + Integer (buffer'First) .. + Integer (buffer'First + Integer (hits) - 1) + loop + tio.Put_Line (" number of names for hit = " & + GLuint'Image (buffer (j))); + j := j + 1; + tio.Put (" z1 is " & GLuint'Image (buffer (j))); + j := j + 1; + tio.Put ("; z2 is " & GLuint'Image (buffer (j))); + j := j + 1; + tio.New_Line; + tio.Put (" names:"); + + for k in 1 .. Integer (buffer (buffer'First)) loop + tio.Put (" " & GLuint'Image (buffer (j))); + j := j + 1; + end loop; + tio.New_Line; + end loop; + end if; + end ProcessHits; + + BUFSIZE : constant := 512; + + procedure PickRects (btn : Integer; state: Integer; x, y: Integer) is + selectBuf : array (1 .. BUFSIZE) of aliased GLuint; + hits : GLint; + viewport : array (0 .. 3) of aliased GLint; + begin + if state = GLUT_LEFT_BUTTON then + if state = GLUT_DOWN then + glGetIntegerv (GL_VIEWPORT, viewport (0)'Access); + + glSelectBuffer (BUFSIZE, selectBuf (1)'Access); + hits := glRenderMode (GL_SELECT); + + glInitNames; + glPushName (-1); + + glMatrixMode (GL_PROJECTION); + glPushMatrix; + glLoadIdentity; + gluPickMatrix (GLdouble (x), GLdouble (viewport (3) - GLint(y)), + 5.0, 5.0, viewport (0)'Access); + glOrtho (0.0, 8.0, 0.0, 8.0, -0.5, 2.5); + DrawRects (GL_SELECT); + glPopMatrix; + glFlush; + + hits := glRenderMode (GL_RENDER); + ProcessHits (hits, int_ar (selectBuf)); + end if; + end if; + end PickRects; + + procedure DoDisplay is + begin + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + DrawRects (GL_RENDER); + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + glOrtho (0.0, 8.0, 0.0, 8.0, -0.5, 2.5); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + end ReshapeCallback; +end PickDepth_Procs; diff --git a/lib/glut-3.7.6/progs/ada/pickdepth_procs.ads b/lib/glut-3.7.6/progs/ada/pickdepth_procs.ads new file mode 100644 index 0000000000..0fa9a26ddc --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/pickdepth_procs.ads @@ -0,0 +1,45 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package PickDepth_Procs is + procedure DoInit; + procedure DoDisplay; + procedure PickRects (btn: Integer; state: Integer; x, y: Integer); + procedure ReshapeCallback (w : Integer; h : Integer); +end PickDepth_Procs; diff --git a/lib/glut-3.7.6/progs/ada/scenebamb.adb b/lib/glut-3.7.6/progs/ada/scenebamb.adb new file mode 100644 index 0000000000..2d0034890b --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/scenebamb.adb @@ -0,0 +1,68 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Scenebamb_Procs; use Scenebamb_Procs; +with Interfaces.C.Strings; + +procedure Scenebamb is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize (500, 500); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL & Ada: scenebamb"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'ACCESS); + glutDisplayFunc (DoDisplay'ACCESS); + glutMainLoop; +end Scenebamb; diff --git a/lib/glut-3.7.6/progs/ada/scenebamb_procs.adb b/lib/glut-3.7.6/progs/ada/scenebamb_procs.adb new file mode 100644 index 0000000000..0a575d63c1 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/scenebamb_procs.adb @@ -0,0 +1,109 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; + +package body Scenebamb_Procs is + procedure DoInit is + ambient : array (0 .. 3) of aliased GLfloat := + (0.0, 0.0, 1.0, 1.0); + diffuse : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + specular : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + position : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 0.0); + begin + glLightfv (GL_LIGHT0, GL_AMBIENT, ambient (0)'access); + glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse (0)'access); + glLightfv (GL_LIGHT0, GL_POSITION, position (0)'access); + + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + end DoInit; + + procedure DoDisplay is + begin + -- 16#4100# = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT + glClear (GL_COLOR_BUFFER_BIT or 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; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + + if w <= h then + glOrtho (-2.5, 2.5, GLdouble (-2.5*Float (h)/ Float (w)), + GLdouble (2.5*Float (h)/Float (w)), -10.0, 10.0); + else + glOrtho (GLdouble (-2.5*Float (w)/Float (h)), + GLdouble (2.5*Float (w)/Float (h)), -2.5, 2.5, -10.0, 10.0); + end if; + + glMatrixMode (GL_MODELVIEW); + end ReshapeCallback; +end Scenebamb_Procs; diff --git a/lib/glut-3.7.6/progs/ada/scenebamb_procs.ads b/lib/glut-3.7.6/progs/ada/scenebamb_procs.ads new file mode 100644 index 0000000000..3310d5fbd4 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/scenebamb_procs.ads @@ -0,0 +1,42 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +package Scenebamb_Procs is + procedure DoInit; + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Scenebamb_Procs; diff --git a/lib/glut-3.7.6/progs/ada/teapots.adb b/lib/glut-3.7.6/progs/ada/teapots.adb new file mode 100644 index 0000000000..9e8864a5ba --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/teapots.adb @@ -0,0 +1,70 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Teapots_Procs; use Teapots_Procs; +with Interfaces.C.Strings; + +procedure Teapots is + package Tio renames Text_IO; + package C renames Interfaces.C; + + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize (500, 600); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL & Ada: teapots"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'Access); + glutDisplayFunc (DoDisplay'Access); + glutMainLoop; +end Teapots; diff --git a/lib/glut-3.7.6/progs/ada/teapots_procs.adb b/lib/glut-3.7.6/progs/ada/teapots_procs.adb new file mode 100644 index 0000000000..2865f0a089 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/teapots_procs.adb @@ -0,0 +1,178 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; + +package body Teapots_Procs is + procedure DoInit is + ambient : array (0 .. 3) of aliased GLfloat := + (0.0, 0.0, 0.0, 1.0); + diffuse : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + specular : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 1.0); + position : array (0 .. 3) of aliased GLfloat := + (0.0, 3.0, 3.0, 0.0); + + lmodel_ambient : array (0 .. 3) of aliased GLfloat := + (0.2, 0.2, 0.2, 1.0); + local_view : aliased GLfloat := 0.0; + begin + glLightfv (GL_LIGHT0, GL_AMBIENT, ambient (0)'Access); + glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse (0)'Access); + glLightfv (GL_LIGHT0, GL_POSITION, position (0)'Access); + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient (0)'Access); + glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, local_view'Access); + + glFrontFace (GL_CW); + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_AUTO_NORMAL); + glEnable (GL_NORMALIZE); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + end DoInit; + + procedure renderTeapot + (x : GLfloat; y : GLfloat; ambr : GLfloat; + ambg : GLfloat; ambb : GLfloat; difr : GLfloat; + difg : GLfloat; difb : GLfloat; specr : GLfloat; + specg : GLfloat; specb : GLfloat; shine : GLfloat) + is + mat : array (0 .. 3) of aliased GLfloat; + begin + 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 (0)'Access); + + mat (0) := difr; + mat (1) := difg; + mat (2) := difb; + glMaterialfv (GL_FRONT, GL_DIFFUSE, mat (0)'Access); + + mat (0) := specr; + mat (1) := specg; + mat (2) := specb; + glMaterialfv (GL_FRONT, GL_SPECULAR, mat (0)'Access); + + glMaterialf (GL_FRONT, GL_SHININESS, shine * 128.0); + + glutSolidTeapot (1.0); + glPopMatrix; + end renderTeapot; + + procedure DoDisplay is + begin + -- 16#4100# = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT + glClear (GL_COLOR_BUFFER_BIT or 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, 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, 0.25); + renderTeapot (10.0, 14.0, 0.0, 0.1, 0.06, 0.0, 0.50980392, 0.50980392, + 0.50196078, 0.50196078, 0.50196078, 0.25); + renderTeapot (10.0, 11.0, 0.0, 0.0, 0.0, + 0.1, 0.35, 0.1, 0.45, 0.55, 0.45, 0.25); + renderTeapot (10.0, 8.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, + 0.7, 0.6, 0.6, 0.25); + renderTeapot (10.0, 5.0, 0.0, 0.0, 0.0, 0.55, 0.55, 0.55, + 0.70, 0.70, 0.70, 0.25); + renderTeapot (10.0, 2.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, + 0.60, 0.60, 0.50, 0.25); + renderTeapot (14.0, 17.0, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01, + 0.4, 0.4, 0.4, 0.078125); + renderTeapot (14.0, 14.0, 0.0, 0.05, 0.05, 0.4, 0.5, 0.5, + 0.04, 0.7, 0.7, 0.078125); + renderTeapot (14.0, 11.0, 0.0, 0.05, 0.0, 0.4, 0.5, 0.4, + 0.04, 0.7, 0.04, 0.078125); + renderTeapot (14.0, 8.0, 0.05, 0.0, 0.0, 0.5, 0.4, 0.4, + 0.7, 0.04, 0.04, 0.078125); + renderTeapot (14.0, 5.0, 0.05, 0.05, 0.05, 0.5, 0.5, 0.5, + 0.7, 0.7, 0.7, 0.078125); + renderTeapot (14.0, 2.0, 0.05, 0.05, 0.0, 0.5, 0.5, 0.4, + 0.7, 0.7, 0.04, 0.078125); + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + + if w <= h then + glOrtho (0.0, 16.0, 0.0, GLdouble (16.0*Float (h)/Float (w)), + -10.0, 0.0); + else + glOrtho (0.0, GLdouble (16.0*Float (w)/Float (h)), + 0.0, 16.0, -10.0, 10.0); + end if; + + glMatrixMode (GL_MODELVIEW); + end ReshapeCallback; +end Teapots_Procs; diff --git a/lib/glut-3.7.6/progs/ada/teapots_procs.ads b/lib/glut-3.7.6/progs/ada/teapots_procs.ads new file mode 100644 index 0000000000..b7976d7f49 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/teapots_procs.ads @@ -0,0 +1,50 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Teapots_Procs is + procedure DoInit; + procedure renderTeapot + (x : GLfloat; y : GLfloat; ambr : GLfloat; + ambg : GLfloat; ambb : GLfloat; difr : GLfloat; + difg : GLfloat; difb : GLfloat; specr : GLfloat; + specg : GLfloat; specb : GLfloat; shine : GLfloat); + + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Teapots_Procs; diff --git a/lib/glut-3.7.6/progs/ada/texgen.adb b/lib/glut-3.7.6/progs/ada/texgen.adb new file mode 100644 index 0000000000..67a687c952 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texgen.adb @@ -0,0 +1,68 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Texgen_Procs; use Texgen_Procs; +with Interfaces.C.Strings; + +procedure Texgen is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize (300, 300); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL & Ada: texgen"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'ACCESS); + glutDisplayFunc (DoDisplay'ACCESS); + glutMainLoop; +end Texgen; diff --git a/lib/glut-3.7.6/progs/ada/texgen_procs.adb b/lib/glut-3.7.6/progs/ada/texgen_procs.adb new file mode 100644 index 0000000000..63856dc9d5 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texgen_procs.adb @@ -0,0 +1,121 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; + +package body Texgen_Procs is + stripeImage : array (0 .. 95) of aliased GLubyte; + + procedure makeStripeImage is + begin + for j in 0 .. 31 loop + if j <= 4 then stripeImage (3*j) := 255; + else stripeImage (3*j) := 0; + end if; + + if j > 4 then stripeImage (3*j+1) := 255; + else stripeImage (3*j+1) := 0; + end if; + + stripeImage (3*j+2) := 0; + end loop; + end makeStripeImage; + + sgenparams : array (0 .. 3) of aliased GLfloat := + (1.0, 1.0, 1.0, 0.0); + + procedure DoInit is + begin + glClearColor (0.0, 0.0, 0.0, 0.0); + + makeStripeImage; + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + 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); + glTexImage1D (GL_TEXTURE_1D, 0, 3, 32, 0, + GL_RGB, GL_UNSIGNED_BYTE, stripeImage(0)'Access); + + glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv (GL_S, GL_OBJECT_PLANE, sgenparams (0)'ACCESS); + + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + 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); + end DoInit; + + procedure DoDisplay is + begin + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + glPushMatrix; + glRotatef (45.0, 0.0, 0.0, 1.0); + glutSolidTeapot (2.0); + glPopMatrix; + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + + if w <= h then + glOrtho (-3.5, 3.5, GLdouble (-3.5*GLdouble (h)/GLdouble (w)), + GLdouble (3.5*GLdouble (h)/GLdouble (w)), -3.5, 3.5); + else + glOrtho ((-3.5*GLdouble (w)/GLdouble (h)), + GLdouble (3.5*GLdouble (w)/GLdouble (h)), -3.5, 3.5, -3.5, 3.5); + end if; + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + end ReshapeCallback; +end Texgen_Procs; diff --git a/lib/glut-3.7.6/progs/ada/texgen_procs.ads b/lib/glut-3.7.6/progs/ada/texgen_procs.ads new file mode 100644 index 0000000000..c07d8cfb67 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texgen_procs.ads @@ -0,0 +1,42 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +package Texgen_Procs is + procedure DoInit; + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Texgen_Procs; diff --git a/lib/glut-3.7.6/progs/ada/texturesurf.adb b/lib/glut-3.7.6/progs/ada/texturesurf.adb new file mode 100644 index 0000000000..6d9945e3d5 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texturesurf.adb @@ -0,0 +1,68 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; +with Glut; use Glut; +with Text_IO; +with Texturesurf_Procs; use Texturesurf_Procs; +with Interfaces.C.Strings; + +procedure Texturesurf is + package Tio renames Text_IO; + package ICS renames Interfaces.C.Strings; + + type chars_ptr_ptr is access ICS.chars_ptr; + + argc : aliased integer; + pragma Import (C, argc, "gnat_argc"); + + argv : chars_ptr_ptr; + pragma Import (C, argv, "gnat_argv"); + + foobar : Integer; +begin + glutInitWindowSize (300, 300); + glutInit (argc'access, argv); + glutInitDisplayMode(GLUT_RGB or GLUT_DEPTH or GLUT_SINGLE); + foobar := glutCreateWindow ("OpenGL & Ada: texturesurf"); + + DoInit; + + glutReshapeFunc (ReshapeCallback'ACCESS); + glutDisplayFunc (DoDisplay'ACCESS); + glutMainLoop; +end Texturesurf; diff --git a/lib/glut-3.7.6/progs/ada/texturesurf_procs.adb b/lib/glut-3.7.6/progs/ada/texturesurf_procs.adb new file mode 100644 index 0000000000..a47fc84542 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texturesurf_procs.adb @@ -0,0 +1,139 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with System; use System; +with GL; use GL; + +with Ada.Numerics; use Ada.Numerics; +with Ada.Numerics.Generic_Elementary_Functions; + +package body Texturesurf_Procs is + package GLdouble_GEF is new + Generic_Elementary_Functions (GLfloat); + + use GLdouble_GEF; + + ctrlpoints : array (0 .. 3, 0 .. 3, 0 .. 2) of aliased GLfloat := + (((-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))); + + texpts : array (0 .. 1, 0 .. 1, 0 .. 1) of aliased GLfloat := + (((0.0, 0.0), (0.0, 1.0)), ((1.0, 0.0), (1.0, 1.0))); + + imageWidth : constant := 64; + imageHeight : constant := 64; + image : array (Integer range 0 .. (3*imageWidth*imageHeight)) + of aliased GLubyte; + + procedure makeImage is + ti, tj : GLfloat; + begin + for i in 0 .. (imageWidth - 1) loop + ti := 2.0*Pi*GLfloat (i)/GLfloat (imageWidth); + for j in 0 .. (imageHeight - 1) loop + tj := 2.0*Pi*GLfloat (j)/GLfloat (imageHeight); + + image (3 * (imageHeight * i + j)) := + GLubyte (127.0 * (1.0 + Sin (ti))); + image (3 * (imageHeight * i + j) + 1) := + GLubyte (127.0 * (1.0 + Cos (2.0 * tj))); + image (3 * (imageHeight * i + j) + 2) := + GLubyte (127.0 * (1.0 + Cos (ti + tj))); + end loop; + end loop; + end makeImage; + + procedure DoInit is + begin + glMap2f (GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, + 0.0, 1.0, 12, 4, ctrlpoints (0, 0, 0)'Access); + glMap2f (GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 2, + 0.0, 1.0, 4, 2, texpts (0, 0, 0)'Access); + + glEnable (GL_MAP2_TEXTURE_COORD_2); + glEnable (GL_MAP2_VERTEX_3); + glMapGrid2f (20, 0.0, 1.0, 20, 0.0, 1.0); + makeImage; + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + 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, 3, imageWidth, imageHeight, 0, + GL_RGB, GL_UNSIGNED_BYTE, image(0)'Access); + + glEnable (GL_TEXTURE_2D); + glEnable (GL_DEPTH_TEST); + glEnable (GL_NORMALIZE); + glShadeModel (GL_FLAT); + end DoInit; + + procedure DoDisplay is + begin + glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + glColor3f (1.0, 1.0, 1.0); + glEvalMesh2 (GL_FILL, 0, 20, 0, 20); + glFlush; + end DoDisplay; + + + procedure ReshapeCallback (w : Integer; h : Integer) is + begin + glViewport (0, 0, GLsizei(w), GLsizei(h)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity; + + if w <= h then + glOrtho (-4.0, 4.0, GLdouble (-4.0*GLdouble (h)/GLdouble (w)), + GLdouble (4.0*GLdouble (h)/GLdouble (w)), -4.0, 4.0); + else + glOrtho ((-4.0*GLdouble (w)/GLdouble (h)), + GLdouble (4.0*GLdouble (w)/GLdouble (h)), -4.0, 4.0, -4.0, 4.0); + end if; + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity; + glRotatef (85.0, 1.0, 1.0, 1.0); + end ReshapeCallback; +end Texturesurf_Procs; diff --git a/lib/glut-3.7.6/progs/ada/texturesurf_procs.ads b/lib/glut-3.7.6/progs/ada/texturesurf_procs.ads new file mode 100644 index 0000000000..1491c3aa85 --- /dev/null +++ b/lib/glut-3.7.6/progs/ada/texturesurf_procs.ads @@ -0,0 +1,44 @@ +-- +-- (c) Copyright 1993,1994,1995,1996 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. +-- + +with GL; use GL; + +package Texturesurf_Procs is + procedure DoInit; + procedure DoDisplay; + procedure ReshapeCallback (w : Integer; h : Integer); +end Texturesurf_Procs; diff --git a/lib/glut-3.7.6/progs/advanced.dsw b/lib/glut-3.7.6/progs/advanced.dsw new file mode 100644 index 0000000000..16a01e5132 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced.dsw @@ -0,0 +1,659 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "_all"=".\advanced\_all.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name accumaa + End Project Dependency + Begin Project Dependency + Project_Dep_Name af_depthcue + End Project Dependency + Begin Project Dependency + Project_Dep_Name af_teapots + End Project Dependency + Begin Project Dependency + Project_Dep_Name boundary + End Project Dependency + Begin Project Dependency + Project_Dep_Name comp + End Project Dependency + Begin Project Dependency + Project_Dep_Name convolve + End Project Dependency + Begin Project Dependency + Project_Dep_Name csg + End Project Dependency + Begin Project Dependency + Project_Dep_Name decal + End Project Dependency + Begin Project Dependency + Project_Dep_Name dissolve + End Project Dependency + Begin Project Dependency + Project_Dep_Name envmap + End Project Dependency + Begin Project Dependency + Project_Dep_Name envphong + End Project Dependency + Begin Project Dependency + Project_Dep_Name field + End Project Dependency + Begin Project Dependency + Project_Dep_Name genmipmap + End Project Dependency + Begin Project Dependency + Project_Dep_Name haloed + End Project Dependency + Begin Project Dependency + Project_Dep_Name hello2rts + End Project Dependency + Begin Project Dependency + Project_Dep_Name hiddenline + End Project Dependency + Begin Project Dependency + Project_Dep_Name imgproc + End Project Dependency + Begin Project Dependency + Project_Dep_Name mipmap_lines + End Project Dependency + Begin Project Dependency + Project_Dep_Name motionblur + End Project Dependency + Begin Project Dependency + Project_Dep_Name multilight + End Project Dependency + Begin Project Dependency + Project_Dep_Name occlude + End Project Dependency + Begin Project Dependency + Project_Dep_Name pointburst + End Project Dependency + Begin Project Dependency + Project_Dep_Name projshadow + End Project Dependency + Begin Project Dependency + Project_Dep_Name projtex + End Project Dependency + Begin Project Dependency + Project_Dep_Name rasonly + End Project Dependency + Begin Project Dependency + Project_Dep_Name redblue_stereo + End Project Dependency + Begin Project Dependency + Project_Dep_Name sgiflag + End Project Dependency + Begin Project Dependency + Project_Dep_Name shadowfun + End Project Dependency + Begin Project Dependency + Project_Dep_Name shadowmap + End Project Dependency + Begin Project Dependency + Project_Dep_Name shadowvol + End Project Dependency + Begin Project Dependency + Project_Dep_Name silhouette + End Project Dependency + Begin Project Dependency + Project_Dep_Name softshadow + End Project Dependency + Begin Project Dependency + Project_Dep_Name tess + End Project Dependency + Begin Project Dependency + Project_Dep_Name textext + End Project Dependency + Begin Project Dependency + Project_Dep_Name textile + End Project Dependency + Begin Project Dependency + Project_Dep_Name textrim + End Project Dependency + Begin Project Dependency + Project_Dep_Name texwinalign + End Project Dependency + Begin Project Dependency + Project_Dep_Name tvertex + End Project Dependency + Begin Project Dependency + Project_Dep_Name videoresize + End Project Dependency + Begin Project Dependency + Project_Dep_Name vox + End Project Dependency + Begin Project Dependency + Project_Dep_Name warp + End Project Dependency + Begin Project Dependency + Project_Dep_Name zcomposite + End Project Dependency +}}} + +############################################################################### + +Project: "accumaa"=".\advanced\accumaa.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "af_depthcue"=".\advanced\af_depthcue.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "af_teapots"=".\advanced\af_teapots.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "boundary"=".\advanced\boundary.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "comp"=".\advanced\comp.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "convolve"=".\advanced\convolve.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "csg"=".\advanced\csg.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "decal"=".\advanced\decal.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "dissolve"=".\advanced\dissolve.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "envmap"=".\advanced\envmap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "envphong"=".\advanced\envphong.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "field"=".\advanced\field.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "genmipmap"=".\advanced\genmipmap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "haloed"=".\advanced\haloed.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "hello2rts"=".\advanced\hello2rts.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "hiddenline"=".\advanced\hiddenline.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "imgproc"=".\advanced\imgproc.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "mipmap_lines"=".\advanced\mipmap_lines.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "motionblur"=".\advanced\motionblur.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multilight"=".\advanced\multilight.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "occlude"=".\advanced\occlude.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pointburst"=".\advanced\pointburst.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "projshadow"=".\advanced\projshadow.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "projtex"=".\advanced\projtex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rasonly"=".\advanced\rasonly.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "redblue_stereo"=".\advanced\redblue_stereo.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sgiflag"=".\advanced\sgiflag.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "shadowfun"=".\advanced\shadowfun.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "shadowmap"=".\advanced\shadowmap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "shadowvol"=".\advanced\shadowvol.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "silhouette"=".\advanced\silhouette.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "softshadow"=".\advanced\softshadow.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tess"=".\advanced\tess.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "textext"=".\advanced\textext.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "textile"=".\advanced\textile.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "textrim"=".\advanced\textrim.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "texwinalign"=".\advanced\texwinalign.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tvertex"=".\advanced\tvertex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "videoresize"=".\advanced\videoresize.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "vox"=".\advanced\vox.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "warp"=".\advanced\warp.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zcomposite"=".\advanced\zcomposite.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/progs/advanced/Imakefile b/lib/glut-3.7.6/progs/advanced/Imakefile new file mode 100644 index 0000000000..f319f71188 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/Imakefile @@ -0,0 +1,83 @@ + +/* Copyright (c) Mark J. Kilgard, 1996, 1998. */ + +#include "../../Glut.cf" + +TARGETS = hiddenline haloed silhouette softshadow accumaa field convolve \ + shadowvol shadowmap projshadow tess textile comp csg dissolve envmap \ + envphong decal textext genmipmap imgproc mipmap_lines textrim tvertex \ + warp motionblur projtex zcomposite videoresize occlude af_depthcue \ + af_teapots multilight boundary shadowfun hello2rts rasonly sgiflag \ + pointburst redblue_stereo texwinalign + +SRCS = hiddenline.c haloed.c silhouette.c softshadow.c accumaa.c field.c \ + convolve.c shadowvol.c shadowmap.c projshadow.c sphere.c tess.c texture.c \ + textile.c comp.c csg.c dissolve.c envmap.c envphong.c decal.c textext.c \ + textmap.c genmipmap.c imgproc.c mipmap_lines.c izoom.c textrim.c tvertex.c \ + warp.c motionblur.c projtex.c zcomposite.c videoresize.c occlude.c \ + addfog.c af_depthcue.c af_teapots.c multilight.c boundary.c shadowfun.c \ + rts.c hello2rts.c rasonly.c sgiflag.c pointburst.c redblue_stereo.c \ + texwinalign.c nvidia_logo.c + +AllTarget($(TARGETS)) + +SimpleGlutProgramTarget(accumaa) +NormalGlutProgramTarget(af_depthcue,af_depthcue.o addfog.o) +NormalGlutProgramTarget(af_teapots,af_teapots.o addfog.o) +SimpleGlutProgramTarget(boundary) +NormalGlutProgramTarget(comp,comp.o texture.o) +SimpleGlutProgramTarget(csg) +SimpleGlutProgramTarget(convolve) +SimpleGlutProgramTarget(decal) +SimpleGlutProgramTarget(dissolve) +NormalGlutProgramTarget(envmap,envmap.o texture.o) +SimpleGlutProgramTarget(envphong) +SimpleGlutProgramTarget(field) +NormalGlutProgramTarget(genmipmap,genmipmap.o texture.o) +SimpleGlutProgramTarget(haloed) +NormalGlutProgramTarget(hello2rts,hello2rts.o rts.o nvidia_logo.o) +SimpleGlutProgramTarget(hiddenline) +NormalGlutProgramTarget(imgproc,imgproc.o texture.o) +NormalGlutProgramTarget(mipmap_lines,mipmap_lines.o izoom.o texture.o) +SimpleGlutProgramTarget(motionblur) +SimpleGlutProgramTarget(multilight) +SimpleGlutProgramTarget(occlude) +SimpleGlutProgramTarget(pointburst) +SimpleGlutProgramTarget(projshadow) +NormalGlutProgramTarget(projtex,projtex.o texture.o) +SimpleGlutProgramTarget(rasonly) +SimpleGlutProgramTarget(redblue_stereo) +SimpleGlutProgramTarget(sgiflag) +SimpleGlutProgramTarget(shadowfun) +SimpleGlutProgramTarget(shadowmap) +SimpleGlutProgramTarget(shadowvol) +SimpleGlutProgramTarget(silhouette) +SimpleGlutProgramTarget(softshadow) +NormalGlutProgramTarget(tess,tess.o sphere.o) +NormalGlutProgramTarget(textext,textext.o textmap.o texture.o) +NormalGlutProgramTarget(textrim,textrim.o texture.o) +NormalGlutProgramTarget(textile,textile.o texture.o) +SimpleGlutProgramTarget(texwinalign) +SimpleGlutProgramTarget(tvertex) +NormalGlutProgramTarget(videoresize,videoresize.o sphere.o) +SimpleGlutProgramTarget(vox) +NormalGlutProgramTarget(warp,warp.o texture.o) +SimpleGlutProgramTarget(zcomposite) + +DATA_LINKS = 00.rgb 02.rgb 04.rgb a.rgb mandrill.rgb 01.rgb 03.rgb 05.rgb b.rgb tree.rgb vox.bin.gz + +links: + for i in $(DATA_LINKS); do \ + /bin/rm -rf $$i ; \ + ln -s ../../data/$$i . ; \ + done + +#ifdef RemoveFiles +clean:: + RemoveFiles($(DATA_LINKS)) +#else +clean:: + $(RM) $(DATA_LINKS) +#endif + +DependTarget() diff --git a/lib/glut-3.7.6/progs/advanced/README b/lib/glut-3.7.6/progs/advanced/README new file mode 100644 index 0000000000..0bcb5d0f41 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/README @@ -0,0 +1,53 @@ + +This directory contains OpenGL examaples from the SIGGRAPH '96 course +titled "Programming with OpenGL: Advanced Rendering" taught by Tom +McReynolds (tomcat@sgi.com) and David Blythe (blythe@sgi.com), both +from SGI. These examples demonstrate interesting rendering techniques +that may not be obvious to the beginning OpenGL user. Think of OpenGL +as a powerful vocabulary for rendering, and you'll be surprised the +powerful expressions that you can devise. + +Information about the course is at: + + http://www.siggraph.org/conferences/siggraph96/core/conference/courses/23.html + +Material presented at the course can be found at: + + http://www.sgi.com/Technology/openGL/advanced_sig96.html + +The original source code for the course examples can be found at: + + http://www.sgi.com/Technology/openGL/advanced/programs.html + +In a few places, I've taken the liberty of adding GLUT popup menus and +disabling animation when the window is iconfied. Warnings and bugs I +found were fixed. In a few examples, the degree of tesselation and +default window size have been scaled down to perform better on low-end +graphics workstations and PCs. + +A number of SGI .rgb image files are used to supply texture data needed +by some of these examples. Since the files are large, I am not +including them in the GLUT distribution. Instead, they are provided in +a separate distribution called glut_data.tar.gz + +If you retrieve glut_data.tar.gz, it will generate a glut-3.3/data +directory where the images will be placed. Use the "make links" target +to make links in this directory into the glut-3.3/data directory. + +You can also get the files individually over the Internet from: + + http://www.sgi.com/Technology/openGL/advanced/blythe/00.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/01.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/02.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/03.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/04.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/05.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/a.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/b.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/flowers.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/mandrill.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/road.rgb + http://www.sgi.com/Technology/openGL/advanced/blythe/tree.rgb + +- Mark Kilgard + October 25, 1996. diff --git a/lib/glut-3.7.6/progs/advanced/Times-Italic.bw b/lib/glut-3.7.6/progs/advanced/Times-Italic.bw new file mode 100644 index 0000000000000000000000000000000000000000..be99f4a6d95bd8417ac134344b9bfe2eedd2c000 GIT binary patch literal 29864 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 OGBEJ`uVb)aU;qG*+9%Zj literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/advanced/_all.dsp b/lib/glut-3.7.6/progs/advanced/_all.dsp new file mode 100644 index 0000000000..6a4421548c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "_all___Win32_Debug" +# PROP BASE Intermediate_Dir "_all___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/accumaa.c b/lib/glut-3.7.6/progs/advanced/accumaa.c new file mode 100644 index 0000000000..278b697f8c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/accumaa.c @@ -0,0 +1,277 @@ + +/* accumaa.c - by Tom McReynolds, SGI */ + +/* Using the accumulation buffer for scene antialiasing. */ + +#include +#include +#include + +const GLdouble FRUSTDIM = 100.f; + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum { + SPHERE = 1, CONE +}; + +void +render(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(-80.f, -60.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -500.f); + glCallList(CONE); + glPopMatrix(); + + if (glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + +/* compute scale factor for window->object space transform could use + gluUnProject(), but probably too much trouble */ +void +computescale(GLfloat * sx, GLfloat * sy) +{ + enum { + XORG, YORG, WID, HT + }; + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + *sx = 2 * FRUSTDIM / viewport[WID]; + *sy = 2 * FRUSTDIM / viewport[WID]; +} + +enum { + NONE, AA +}; + +int rendermode = NONE; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + +/* Called when window needs to be redrawn */ +void +redraw(void) +{ + int i, j; + int min, max; + int count; + GLfloat invx, invy; + GLfloat scale, dx, dy; + + switch (rendermode) { + case NONE: + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + break; + case AA: + min = -2; + max = -min + 1; + count = -2 * min + 1; + count *= count; + + /* uniform scaling, less than one pixel wide */ + scale = -.9f / min; + + computescale(&invx, &invy); + + glClear(GL_ACCUM_BUFFER_BIT); + + for (j = min; j < max; j++) { + for (i = min; i < max; i++) { + dx = invx * scale * i; + dy = invy * scale * j; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM + dx, + FRUSTDIM + dy, + -FRUSTDIM + dx, + FRUSTDIM + dy, + 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + glAccum(GL_ACCUM, 1.f / count); + } + } + glAccum(GL_RETURN, 1.f); + break; + } + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + if (key == '\033') + exit(0); +} + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = + {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_ACCUM | GLUT_DOUBLE); + (void) glutCreateWindow("scene antialiasing"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("Aliased View", NONE); + glutAddMenuEntry("AntiAliased", AA); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glReadBuffer(GL_BACK); /* input to accum buffer */ + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/accumaa.dsp b/lib/glut-3.7.6/progs/advanced/accumaa.dsp new file mode 100644 index 0000000000..af9f9cab29 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/accumaa.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="accumaa" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=accumaa - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "accumaa.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "accumaa.mak" CFG="accumaa - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "accumaa - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "accumaa - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "accumaa - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "accumaa - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "accumaa - Win32 Release" +# Name "accumaa - Win32 Debug" +# Begin Source File + +SOURCE=.\accumaa.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/addfog.c b/lib/glut-3.7.6/progs/advanced/addfog.c new file mode 100644 index 0000000000..d860d169ed --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/addfog.c @@ -0,0 +1,296 @@ + +/* 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. */ + +/* addfog.c is a set of routines for adding OpenGL-style depth attenuated fog + to a scene as a final rendering pass. This may be useful if you are doing + multipass algorithms where attempting to enable fog within the passes + would screw up the rendering effect. + + The approach is to read back the depth buffer, then do an in-place draw + pixels of the depth buffer values back into the frame buffer as alpha. + OpenGL's standard pixel path is used to "blend in" fog. The Red, Green, + and Blue components are forced to the fog color; alpha is either scaled & + biased (for GL_LINEAR style fog) or remapped with OpenGL's "map color" + capability (for GL_EXP or GL_EXP style fog). The result is blended with + the current frame buffer contents. The result is almost identical to + OpenGL's fog. + + With this fogging technique, the fog pass time is always proportional to + the number of pixels in the window. This is in contrast to fogging the + entire scene standard OpenGL fog during rendering. With standard OpenGL + fog rendering, a scene with a depth complexity greater than 1 may end up + fogging many more pixels than are visible. If fog is not supported for + free in hardware and you are rendering a scene with high enough depth + complexity, this fogging technique could be faster than standard OpenGL + fog. + + As mentioned earlier, the technique may also be appropriate in multi-pass + rendering algorithms to avoid fog improperly interferring with the various + passes. Examples: reflections or shadows. + + A more sophisticated version of this technique could be used to simulate + "eye distance" attenuated fog instead of OpenGL's "depth" attenuated fog. + The technique could perform the depth to alpha read/write in tiles with a + pixel map set up to attenuate based on eye distance instead of simply + depth. + + This approach could be made more efficient with an extension to + glCopyPixels to support a copy of one frame buffer type to another + (specifically, depth to alpha). + + One side-effect of this approach is that it trashes your destination + alpha buffer (if you even have one). */ + +/** Using the "addfog" routines: + + 1) Given your near and far ranges (generally from glOrtho, glFrustum, or + gluPerspective), call: + + afEyeNearFar(near, far); + + Careful since "near" and "far" are reserved words on PC compilers. + + 2) Instead calling glFog to set fog parameters, use the corresponding + "addfog" routines as shown below: + + Instead of: + + glFogf(GL_FOG_START, start); glFogf(GL_FOG_END, end); + + Use: + + afFogStartEnd(start, end); + + Instead of: + + glFogi(GL_FOG_MODE, mode); + + Use: + + afFogMode(mode); + + Instead of: + + glFogf(GL_FOG_DENSITY, density); + + Use: + + afFogDensity(density); + + Instead of: + + GLfloat fogcolor[4] = { red, green, blue, alpha }; + glFogfv(GL_FOG_COLOR, fog_color); + + Use: + + afFogColor(red, green, blue); + + 3) Draw you scene *without* OpenGL fog enabled. + + 4) Assuming you want to fog the entire window of size width by + height, call: + + afDoFinalFogPass(0, 0, width, height); + + Note: x & y are OpenGL-style lower-left hand window coordinates. + + 5) Call glFinish or do a buffer swap. + + That's it. View your fogged scene. */ + +#ifdef __sgi /* SGI has a good alloca; many other machines don't. */ +#define HAS_ALLOCA +#endif + +#include +#ifdef HAS_ALLOCA +#include +#endif +#ifdef _WIN32 +#include +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#endif +#include +#include + +static GLfloat eye_near = 0.0, eye_far = 1.0; +static GLfloat fog_start = 0.0, fog_end = 1.0; +static GLenum fog_mode = GL_EXP; +static GLfloat fog_density = 1.0; +static int valid = 0; +static GLfloat fog_red, fog_green, fog_blue; + +void +afEyeNearFar(GLfloat fnear, GLfloat ffar) +{ + eye_near = fnear; + eye_far = ffar; + valid = 0; +} + +void +afFogStartEnd(GLfloat start, GLfloat end) +{ + fog_start = start; + fog_end = end; + valid = 0; +} + +void +afFogMode(GLenum mode) +{ + fog_mode = mode; + valid = 0; +} + +void +afFogDensity(GLfloat density) +{ + fog_density = density; + valid = 0; +} + +void +afFogColor(GLfloat red, GLfloat green, GLfloat blue) +{ + fog_red = red; + fog_green = green; + fog_blue = blue; +} + +#define LEN 256 + +void +afDoFinalFogPass(GLint x, GLint y, GLsizei width, GLsizei height) +{ + static GLfloat alpha_scale, alpha_bias; + static GLfloat fog_map[LEN]; + int i; + +#ifdef HAS_ALLOCA + void *buffer = alloca((unsigned int) sizeof(GLushort) * width * height); +#else + static void *buffer = NULL; + static int last_width, last_height; + + if (width * height != last_width * last_height) { + buffer = realloc(buffer, sizeof(GLushort) * width * height); + last_width = width; + last_height = height; + } +#endif + + if (!valid) { + switch (fog_mode) { + case GL_LINEAR: + /* Figure out linear fog blending from "f = (e-z)/(e-s)". */ + alpha_scale = (eye_far - eye_near) / (fog_end - fog_start); + alpha_bias = (eye_near - fog_start) / (fog_end - fog_start); + break; + case GL_EXP: + /* Setup fog_map to be "f = exp(-d*z)". */ + for (i = 0; i < LEN; i += 1) { + float fi, z, dz; + + fi = i * 1.0 / (LEN - 1); + z = eye_near + fi * (eye_far - eye_near); + dz = fog_density * z; + fog_map[i] = 1.0 - exp(-dz); + } + break; + case GL_EXP2: + /* Setup fog_map to be "f = exp(-(d*z)^2)". */ + for (i = 0; i < LEN; i += 1) { + float fi, z, dz; + + fi = i * 1.0 / (LEN - 1); + z = eye_near + fi * (eye_far - eye_near); + dz = fog_density * z; + fog_map[i] = 1.0 - exp(-dz * dz); + } + break; + default:; + /* Mesa makes GLenum an actual enumerant. Have a default + case to avoid all the gcc warnings from all the other + GLenum values that we are not handling. */ + } + } + + /* XXX Careful, afDoFinalFogPass makes no attempt to preserve your + pixel store state and assumes the initial pixel store state! */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + /* Preserve the current raster position, viewport, matrix mode, + blend function, enable state, and pixel path state. */ + /* XXX This is pretty expensive. A real application should just + "know" to reload all the OpenGL state mucked with by afDoFinalFogPass + and then you could get rid of all this glPushAttrib and glPopMatrix + garbage. */ + glPushAttrib(GL_PIXEL_MODE_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | + GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_CURRENT_BIT); + + /* Reposition the current raster position as location (x,y). */ + glMatrixMode(GL_MODELVIEW); + glViewport(x-1, y-1, 2, 2); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glRasterPos2i(0, 0); + + /* Definitely don't want fog or depth enabled. */ + glDisable(GL_FOG); + glDisable(GL_DEPTH_TEST); + + /* The alpha on the glDrawPixels after the pixel path transformation + will be "1 - f" where f is the blending factor described in Section + 3.9 of the OpenGL 1.1 specification. */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + switch (fog_mode) { + case GL_LINEAR: + /* Force red, green, and blue to the fog color. */ + glPixelTransferf(GL_RED_SCALE, 0); + glPixelTransferf(GL_GREEN_SCALE, 0); + glPixelTransferf(GL_BLUE_SCALE, 0); + glPixelTransferf(GL_RED_BIAS, fog_red); + glPixelTransferf(GL_GREEN_BIAS, fog_green); + glPixelTransferf(GL_BLUE_BIAS, fog_blue); + + glPixelTransferf(GL_ALPHA_SCALE, alpha_scale); + glPixelTransferf(GL_ALPHA_BIAS, alpha_bias); + break; + case GL_EXP: + case GL_EXP2: + /* Force red, green, and blue to the fog color. */ + glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 1, &fog_red); + glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 1, &fog_green); + glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 1, &fog_blue); + + glPixelMapfv(GL_PIXEL_MAP_A_TO_A, LEN, fog_map); + glPixelTransferi(GL_MAP_COLOR, GL_TRUE); + break; + } + + /* Read out the depth buffer... */ + glReadPixels(x, y, width, height, + GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, buffer); + + /* ... and write it back as alpha. */ + glDrawPixels(width, height, GL_ALPHA, + GL_UNSIGNED_SHORT, buffer); + + /* Restore state saved earlier. */ + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); +} diff --git a/lib/glut-3.7.6/progs/advanced/addfog.h b/lib/glut-3.7.6/progs/advanced/addfog.h new file mode 100644 index 0000000000..c200bb9362 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/addfog.h @@ -0,0 +1,8 @@ + +extern void afEyeNearFar(GLfloat fnear, GLfloat ffar); +extern void afFogStartEnd(GLfloat start, GLfloat end); +extern void afFogMode(GLenum mode); +extern void afFogDensity(GLfloat density); +extern void afFogColor(GLfloat red, GLfloat green, GLfloat blue); +extern void afDoFinalFogPass(GLint x, GLint y, GLsizei width, GLsizei height); + diff --git a/lib/glut-3.7.6/progs/advanced/af_depthcue.c b/lib/glut-3.7.6/progs/advanced/af_depthcue.c new file mode 100644 index 0000000000..e5f52bb399 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/af_depthcue.c @@ -0,0 +1,163 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +/* A version of the OpenGL Programming Guide's depthcue.c that + uses the "addfog" routines to add depth cueing as a post-rendering + pass. This is not a rather poor application for "addfog" but it + does demonstrate how it use "addfog". See "addfog.c" for details. */ + +/* + * (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 +#include "addfog.h" + +/* Initialize linear fog for depth cueing. + */ +void myinit(void) +{ + GLfloat fogColor[4] = {0.0, 0.0, 0.0, 1.0}; + + 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); + + afEyeNearFar(3.0, 5.0); + afFogStartEnd(3.0, 5.0); + afFogMode(GL_LINEAR); + afFogColor(0.0, 0.0, 0.0); +} + +int width, height; +int twopass = 1; + +/* display() draws an icosahedron. + */ +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (!twopass) { + glEnable(GL_FOG); + } else { + glDisable(GL_FOG); + } + + glColor3f (1.0, 1.0, 1.0); + glutWireIcosahedron(); + + if (twopass) { + afDoFinalFogPass(0, 0, width, height); + } + + glutSwapBuffers(); +} + +void myReshape(int w, int h) +{ + width = w; + height = 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 */ +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char c, int x, int y) +{ + switch(c) { + case 'T': + case 't': + twopass = 1 - twopass; + case ' ': + glutPostRedisplay(); + break; + } +} + +void +menu(int value) +{ + switch(value) { + case 1: + twopass = 0; + break; + case 2: + twopass = 1; + break; + } + glutPostRedisplay(); +} + +/* Main Loop + */ +int main(int argc, char** argv) +{ + glutInitWindowSize(380, 380); + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow("depthcuing by post-rendering pass"); + myinit(); + glutReshapeFunc(myReshape); + glutDisplayFunc(display); + glutKeyboardFunc(keyboard); + glutCreateMenu(menu); + glutAddMenuEntry("GL_LINEAR depthcueing", 1); + glutAddMenuEntry("\"add fog\" post-render depthcueing", 2); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + diff --git a/lib/glut-3.7.6/progs/advanced/af_depthcue.dsp b/lib/glut-3.7.6/progs/advanced/af_depthcue.dsp new file mode 100644 index 0000000000..4f74aaf559 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/af_depthcue.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="af_depthcue" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=af_depthcue - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "af_depthcue.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "af_depthcue.mak" CFG="af_depthcue - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "af_depthcue - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "af_depthcue - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "af_depthcue - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "af_depthcue - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "af_depthcue - Win32 Release" +# Name "af_depthcue - Win32 Debug" +# Begin Source File + +SOURCE=.\addfog.c +# End Source File +# Begin Source File + +SOURCE=.\addfog.h +# End Source File +# Begin Source File + +SOURCE=.\af_depthcue.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/af_teapots.c b/lib/glut-3.7.6/progs/advanced/af_teapots.c new file mode 100644 index 0000000000..63cab20abd --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/af_teapots.c @@ -0,0 +1,222 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +/** + * (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 + +#include "addfog.h" + +GLint fogMode; + +#define TPF_LINEAR 1 +#define TPF_EXP 2 +#define TPF_EXP2 3 + +int addfog = 0; + +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); + glEnable(GL_FOG); + addfog = 0; + glutPostRedisplay(); + break; + case TPF_LINEAR: + afFogStartEnd(0.0, 10.0); + afFogMode(GL_LINEAR); + glDisable(GL_FOG); + addfog = 1; + glutPostRedisplay(); + break; + case TPF_EXP: + afFogMode(GL_EXP); + glDisable(GL_FOG); + addfog = 1; + glutPostRedisplay(); + break; + case TPF_EXP2: + afFogMode(GL_EXP2); + glDisable(GL_FOG); + addfog = 1; + 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}; + GLfloat fogColor[4] = + {0.5, 0.5, 0.5, 1.0}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_FOG); + 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); + + fogMode = GL_EXP; + glFogi(GL_FOG_MODE, fogMode); + glFogfv(GL_FOG_COLOR, fogColor); + afFogColor(0.5, 0.5, 0.5); + glFogf(GL_FOG_DENSITY, 0.35); + afFogDensity(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(); +} + +int width, height; + + /* 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); + if (addfog) { + afDoFinalFogPass(0, 0, width, height); + } + glFlush(); +} + +void +myReshape(int w, int h) +{ + width = w; + height = 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(); + afEyeNearFar(0.0, 10.0); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(450, 150); + glutCreateWindow("fogged teapots via post-rendering pass"); + myinit(); + glutReshapeFunc(myReshape); + glutDisplayFunc(display); + glutCreateMenu(selectFog); + glutAddMenuEntry("Fog EXP", GL_EXP); + glutAddMenuEntry("Fog EXP2", GL_EXP2); + glutAddMenuEntry("Fog LINEAR", GL_LINEAR); + glutAddMenuEntry("Two Pass Fog EXP", TPF_EXP); + glutAddMenuEntry("Two Pass Fog EXP2", TPF_EXP2); + glutAddMenuEntry("Two Pass Fog LINEAR", TPF_LINEAR); + glutAddMenuEntry("Quit", 0); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/af_teapots.dsp b/lib/glut-3.7.6/progs/advanced/af_teapots.dsp new file mode 100644 index 0000000000..d9007592f3 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/af_teapots.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="af_teapots" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=af_teapots - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "af_teapots.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "af_teapots.mak" CFG="af_teapots - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "af_teapots - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "af_teapots - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "af_teapots - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "af_teapots - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "af_teapots - Win32 Release" +# Name "af_teapots - Win32 Debug" +# Begin Source File + +SOURCE=.\addfog.c +# End Source File +# Begin Source File + +SOURCE=.\af_teapots.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/boundary.c b/lib/glut-3.7.6/progs/advanced/boundary.c new file mode 100644 index 0000000000..b93a4c8634 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/boundary.c @@ -0,0 +1,349 @@ + +/* 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 shows how to use the GLU polygon tessellator to determine the + + 2D boundary of OpenGL rendered objects. The program uses OpenGL's + feedback mechanim to capture transformed polygons and then feeds them to + the GLU tesselator in GLU_TESS_WINDING_NONZERO and GLU_TESS_BOUNDARY_ONLY + mode. */ + +#include +#include +#include +#include + +#ifdef GLU_VERSION_1_2 + +#ifndef CALLBACK +#define CALLBACK +#endif + +enum { + M_TORUS, M_CUBE, M_SPHERE, M_ICO, M_TEAPOT, M_ANGLE, M_BOUNDARY +}; + +struct VertexHolder { + struct VertexHolder *next; + GLfloat v[2]; +}; + +int shape = M_TORUS; +int boundary = 1; +GLfloat angle = 0.0; + +GLfloat lightDiffuse[] = +{1.0, 0.0, 0.0, 1.0}; +GLfloat lightPosition[] = +{1.0, 1.0, 1.0, 0.0}; + +GLUtesselator *tess; +int width, height; + +static void CALLBACK +begin(GLenum type) +{ + assert(type == GL_LINE_LOOP); + glBegin(type); +} + +static void CALLBACK +vertex(void *data) +{ + GLfloat *v = data; + glVertex2fv(v); +} + +static void CALLBACK +end(void) +{ + glEnd(); +} + +static GLfloat *combineList = NULL; +static int combineListSize = 0; +static int combineNext = 0; +static struct VertexHolder *excessList = NULL; + +static void +freeExcessList(void) +{ + struct VertexHolder *holder, *next; + + holder = excessList; + while (holder) { + next = holder->next; + free(holder); + holder = next; + } + excessList = NULL; +} + +/* ARGSUSED1 */ +static void CALLBACK +combine(GLdouble coords[3], void *d[4], GLfloat w[4], void **dataOut) +{ + GLfloat *newCoords; + struct VertexHolder *holder; + + /* XXX Careful, some systems still don't understand realloc of NULL. */ + if (combineNext >= combineListSize) { + holder = (struct VertexHolder *) malloc(sizeof(struct VertexHolder)); + holder->next = excessList; + excessList = holder; + newCoords = holder->v; + } else { + newCoords = &combineList[combineNext * 2]; + } + + newCoords[0] = coords[0]; + newCoords[1] = coords[1]; + *dataOut = newCoords; + + combineNext++; +} + +static void CALLBACK +error(GLenum errno) +{ + printf("ERROR: %s\n", gluErrorString(errno)); +} + +void +reshape(int w, int h) +{ + width = w; + height = h; + glViewport(0, 0, width, height); +} + +void +processFeedback(GLint size, GLfloat * buffer) +{ + GLfloat *loc, *end; + GLdouble v[3]; + int token, nvertices, i; + + if (combineNext > combineListSize) { + freeExcessList(); + combineListSize = combineNext; + combineList = realloc(combineList, sizeof(GLfloat) * 2 * combineListSize); + } + combineNext = 0; + + gluTessBeginPolygon(tess, NULL); + loc = buffer; + end = buffer + size; + while (loc < end) { + token = *loc; + loc++; + switch (token) { + case GL_POLYGON_TOKEN: + nvertices = *loc; + loc++; + assert(nvertices >= 3); + gluTessBeginContour(tess); + for (i = 0; i < nvertices; i++) { + v[0] = loc[0]; + v[1] = loc[1]; + v[2] = 0.0; + gluTessVertex(tess, v, loc); + loc += 2; + } + gluTessEndContour(tess); + break; + default: + /* Ignore everything but polygons. */ + ; + } + } + gluTessEndPolygon(tess); +} + +int +determineBoundary(void (*renderFunc) (void), int probableSize) +{ + static GLfloat *feedbackBuffer = NULL; + static int bufferSize = 0; + GLint returned; + + if (bufferSize > probableSize) { + probableSize = bufferSize; + } +doFeedback: + + /* XXX Careful, some systems still don't understand realloc of NULL. */ + if (bufferSize < probableSize) { + bufferSize = probableSize; + feedbackBuffer = realloc(feedbackBuffer, bufferSize * sizeof(GLfloat)); + } + glFeedbackBuffer(bufferSize, GL_2D, feedbackBuffer); + + (void) glRenderMode(GL_FEEDBACK); + + (*renderFunc) (); + + returned = glRenderMode(GL_RENDER); +#if 0 + if (returned == -1) { +#else + /* XXX RealityEngine workaround. */ + if (returned == -1 || returned == probableSize) { +#endif + probableSize = probableSize + (probableSize >> 1); + goto doFeedback; /* Try again with larger feedback buffer. */ + } + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, width, 0, height); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + processFeedback(returned, feedbackBuffer); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + return returned; +} + +void +render(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective( /* field of view in degree */ 30.0, + /* aspect ratio */ 1.0, + /* Z near */ 1.0, /* Z far */ 20.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0, 0.0, 10.0, /* eye is at (0,0,5) */ + 0.0, 0.0, 0.0, /* center is at (0,0,0) */ + 0.0, 1.0, 0.); /* up is in postivie Y direction */ + + glPushMatrix(); + glRotatef(angle, 1.0, 0.3, 0.0); + switch (shape) { + case M_TORUS: + glutSolidTorus(0.275, 0.85, 8, 8); + break; + case M_CUBE: + glutSolidCube(1.0); + break; + case M_SPHERE: + glutSolidSphere(1.0, 10, 10); + break; + case M_ICO: + glutSolidIcosahedron(); + break; + case M_TEAPOT: + glutSolidTeapot(1.0); + break; + } + glPopMatrix(); +} + +void +display(void) +{ + if (boundary) { + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + determineBoundary(render, 250); + } else { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + render(); + } + glutSwapBuffers(); +} + +void +menu(int value) +{ + switch (value) { + case M_TORUS: + case M_CUBE: + case M_SPHERE: + case M_ICO: + case M_TEAPOT: + shape = value; + break; + case M_ANGLE: + angle += 10.0; + break; + case M_BOUNDARY: + boundary = !boundary; /* Toggle. */ + break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_UP: + angle += 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_DOWN: + angle -= 10.0; + glutPostRedisplay(); + break; + } +} + +int +main(int argc, char **argv) +{ + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutInit(&argc, argv); + + glutCreateWindow("boundary"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutSpecialFunc(special); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHT0); + + tess = gluNewTess(); + gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); + gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); + gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())begin); + gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())vertex); + gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK*)())end); + gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)())error); + gluTessCallback(tess, GLU_TESS_COMBINE, (void (CALLBACK*)())combine); + + glutCreateMenu(menu); + glutAddMenuEntry("Torus", M_TORUS); + glutAddMenuEntry("Cube", M_CUBE); + glutAddMenuEntry("Sphere", M_SPHERE); + glutAddMenuEntry("Icosahedron", M_ICO); + glutAddMenuEntry("Teapot", M_TEAPOT); + glutAddMenuEntry("Angle", M_ANGLE); + glutAddMenuEntry("Toggle boundary", M_BOUNDARY); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +#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 /* GLU_VERSION_1_2 */ diff --git a/lib/glut-3.7.6/progs/advanced/boundary.dsp b/lib/glut-3.7.6/progs/advanced/boundary.dsp new file mode 100644 index 0000000000..33a02b7e85 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/boundary.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="boundary" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=boundary - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "boundary.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "boundary.mak" CFG="boundary - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "boundary - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "boundary - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "boundary - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "boundary - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "boundary - Win32 Release" +# Name "boundary - Win32 Debug" +# Begin Source File + +SOURCE=.\boundary.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/comp.c b/lib/glut-3.7.6/progs/advanced/comp.c new file mode 100644 index 0000000000..e3b0a032e6 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/comp.c @@ -0,0 +1,182 @@ + +/* comp.c - by David Blythe, SGI */ + +/* Porter/Duff compositing operations using OpenGL alpha blending. */ + +/* NOTE: This program uses OpenGL blending functions that need the frame + buffer to retain a destination alpha component. Examples of such + hardware: O2, IMPACT, RealityEngine, and InfiniteReality. */ + +#include +#include +#include +#include +#include "texture.h" + +static int w = 640, h = 640; + +void +myReshape(int nw, int nh) +{ + w = nw, h = nh; + glClearColor(0, 0, 0, 0); + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static unsigned *a_data = 0, *b_data = 0; +static int a_width, a_height, b_width, b_height; + +void +init_tris(void) +{ + if (a_data) + free(a_data); + if (b_data) + free(b_data); + a_data = (unsigned *) malloc(w * h); + b_data = (unsigned *) malloc(w * h); + glViewport(0, 0, w / 2, h / 2); + glClear(GL_COLOR_BUFFER_BIT); + glColor4f(1, 0, 0, 1); + glBegin(GL_TRIANGLES); + glVertex2f(-1, -1); + glVertex2f(-1, 1); + glVertex2f(.5, 1); + glEnd(); + glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, a_data); + + glClear(GL_COLOR_BUFFER_BIT); + glColor4f(0, 1, 0, 1); + glBegin(GL_TRIANGLES); + glVertex2f(1, -1); + glVertex2f(1, 1); + glVertex2f(-.5, 1); + glEnd(); + glReadPixels(0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, b_data); + + a_width = b_width = w / 2, a_height = b_height = h / 2; +} + +void +init_images(void) +{ + int comp; + + a_data = read_texture("a.rgb", &a_width, &a_height, &comp); + printf("%dx%dx%d\n", a_width, a_height, comp); + b_data = read_texture("b.rgb", &b_width, &b_height, &comp); + printf("%dx%dx%d\n", b_width, b_height, comp); +} + +void +display(void) +{ + int i; + + glDrawBuffer(GL_FRONT_AND_BACK); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_BACK); + + glBlendFunc(GL_SRC_ALPHA, GL_ZERO); + /* image A */ + glViewport(0, 0, w / 2, h / 2); + glRasterPos2f(-1, -1); + glDrawPixels(a_width, a_height, GL_RGBA, GL_UNSIGNED_BYTE, + a_data); + glEnable(GL_BLEND); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDisable(GL_BLEND); + + /* image B */ + glViewport(w / 2, 0, w / 2, h / 2); + glRasterPos2f(-1, -1); + glDrawPixels(b_width, b_height, GL_RGBA, GL_UNSIGNED_BYTE, + b_data); + glEnable(GL_BLEND); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + + for (i = 0; i < 4; i++) { + glDisable(GL_BLEND); + switch (i) { + case 0: /* a over b */ + glViewport(0, 0, w / 2, h / 2); + glRasterPos2f(-1, -1); + glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); + glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR); + break; + case 1: /* a under b */ + glViewport(w / 2, 0, w / 2, h / 2); + glRasterPos2f(-1, -1); + glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR); + break; + case 2: /* b in a */ + glViewport(0, h / 2, w / 2, h / 2); + glRasterPos2f(-1, -1); + glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR); + glEnable(GL_BLEND); + glBlendFunc(GL_DST_ALPHA, GL_ZERO); + glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR); + break; + case 3: /* b out of a */ + glViewport(w / 2, h / 2, w / 2, h / 2); + glRasterPos2f(-1, -1); + glCopyPixels(0, 0, w / 2, h / 2, GL_COLOR); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); + glCopyPixels(w / 2, 0, w / 2, h / 2, GL_COLOR); + break; + } + } + glViewport(0, 0, w, h); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); + glColor4f(1., 1., 1., 0.); + glRectf(-1, -1, 1, 1); + glFlush(); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + if (key == '\033') + exit(0); +} + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(w, h); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); + if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) { + printf("comp: requires a frame buffer with destination alpha\n"); + exit(1); + } + glutCreateWindow("comp"); + + if (argc > 1) + init_images(); + else + init_tris(); + glutDisplayFunc(display); + glutReshapeFunc(myReshape); + glutKeyboardFunc(key); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/comp.dsp b/lib/glut-3.7.6/progs/advanced/comp.dsp new file mode 100644 index 0000000000..672d3e6226 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/comp.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="comp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=comp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "comp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "comp.mak" CFG="comp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "comp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "comp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "comp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "comp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "comp - Win32 Release" +# Name "comp - Win32 Debug" +# Begin Source File + +SOURCE=.\comp.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/convolve.c b/lib/glut-3.7.6/progs/advanced/convolve.c new file mode 100644 index 0000000000..3867d94ed7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/convolve.c @@ -0,0 +1,397 @@ + +/* convolve.c - by Tom McReynolds, SGI */ + +/* Using the accumulation buffer for fast convolutions. */ + +#include +#include +#include +#include + +/* convolution choices */ +enum {CONV_NONE, + CONV_BOX_3X3, + CONV_BOX_5X5, + CONV_SOBEL_X, + CONV_LAPLACE +}; + +/* Filter contents and size */ +typedef struct { + GLfloat scale; /* 1/scale applied to image to prevent overflow */ + GLfloat bias; /* for biasing images */ + int rows; + int cols; + GLfloat *array; +} Filter; + +Filter *curmat; /* current filter to use for redrawing */ + +/* identity filter */ +void +identity(Filter *mat) +{ + int n, size; + size = mat->rows * mat->cols; + + mat->array[0] = 1.f; + for(n = 1; n < size; n++) + mat->array[n] = 0.f; + + mat->scale = 1.f; + mat->bias = 0.f; +} + + +/* create a new filter with identity filter in it */ +Filter * +newfilter(int rows, int cols) +{ + Filter *mat; + + mat = (Filter *)malloc(sizeof(Filter)); + mat->rows = rows; + mat->cols = cols; + mat->array = (GLfloat *)malloc(rows * cols * sizeof(GLfloat)); + identity(mat); + + return mat; +} + + +/* doesn't re-initialize matrix */ +void +resize(Filter *mat, int rows, int cols) +{ + if(mat->rows != rows || + mat->cols != cols) { + free(mat->array); + mat->array = NULL; + mat->array = (GLfloat *)realloc(mat->array, rows * cols * sizeof(GLfloat)); + } + mat->rows = rows; + mat->cols = cols; +} + + +/* box filter blur */ +void +box(Filter *mat) +{ + int n, count; + GLfloat blur; + + count = mat->cols * mat->rows; + blur = 1.f/count; + for(n = 0; n < count; n++) + mat->array[n] = blur; + + mat->scale = 1.f; + mat->bias = 0.f; +} + +/* sobel filter */ + +void +sobel(Filter *mat) +{ + static GLfloat sobel[] = {-.5f, 0.f, .5f, + -1.f, 0.f, 1.f, + -.5f, 0.f, .5f}; + + /* sobel is fixed size */ + resize(mat, 3, 3); /* will do nothing if size is right already */ + + memcpy(mat->array, sobel, sizeof(sobel)); + + mat->scale = 2.f; + mat->bias = 0.f; +} + +/* laplacian filter */ +void +laplace(Filter *mat) +{ + static GLfloat laplace[] = { 0.f, -.25f, 0.f, + -.25f, 1.f, -.25f, + 0.f, -.25f, 0.f}; + + /* sobel is fixed size */ + resize(mat, 3, 3); /* will do nothing if size is right already */ + + memcpy(mat->array, laplace, sizeof(laplace)); + + mat->scale = 4.f; + mat->bias = .125f; +} + +/* add menu callback */ + +void menu(int filter) +{ + switch(filter) { + case CONV_NONE: + resize(curmat, 1,1); + identity(curmat); + break; + case CONV_BOX_3X3: + resize(curmat, 3, 3); + box(curmat); + break; + case CONV_BOX_5X5: + resize(curmat, 5, 5); + box(curmat); + break; + case CONV_SOBEL_X: + sobel(curmat); + break; + case CONV_LAPLACE: + laplace(curmat); + break; + } + glutPostRedisplay(); +} + +int winWidth = 0; +int winHeight = 0; + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glViewport(0, 0, wid, ht); + winWidth = wid; + winHeight = ht; +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {SPHERE = 1, CONE}; + +void +render(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + + glPushMatrix(); + glTranslatef(-80.f, -60.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -500.f); + glCallList(CONE); + glPopMatrix(); + +} + + + +void +convolve(void (*draw)(void), Filter *mat) +{ + int i, j; + int imax, jmax; + + imax = mat->cols; + jmax = mat->rows; + for(j = 0; j < jmax; j++) { + for(i = 0; i < imax; i++) { + glViewport(-i, -j, winWidth - i, winHeight - j); + draw(); + glAccum(GL_ACCUM, mat->array[i + j * imax]); + } + } +} + + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + glClearAccum(curmat->bias, + curmat->bias, + curmat->bias, + 1.0); + + glClear(GL_ACCUM_BUFFER_BIT); + + convolve(render, curmat); + + glViewport(0, 0, winWidth, winHeight); + + glAccum(GL_RETURN, curmat->scale); + + glutSwapBuffers(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); +} + + +const int TEXDIM = 256; + +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); + (void)glutCreateWindow("accumulation buffer convolve"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* make display lists for sphere and cone; for efficiency */ + + glNewList(SPHERE, GL_COMPILE); + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glutCreateMenu(menu); + glutAddMenuEntry("none", CONV_NONE); + glutAddMenuEntry("box filter (3x3 blur)", CONV_BOX_3X3); + glutAddMenuEntry("box filter (5x5 blur)", CONV_BOX_5X5); + glutAddMenuEntry("Sobel(x direction)", CONV_SOBEL_X); + glutAddMenuEntry("Laplace", CONV_LAPLACE); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + curmat = newfilter(1, 1); + identity(curmat); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/convolve.dsp b/lib/glut-3.7.6/progs/advanced/convolve.dsp new file mode 100644 index 0000000000..14356a3903 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/convolve.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="convolve" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=convolve - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "convolve.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "convolve.mak" CFG="convolve - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "convolve - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "convolve - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "convolve - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "convolve - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "convolve - Win32 Release" +# Name "convolve - Win32 Debug" +# Begin Source File + +SOURCE=.\convolve.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/csg.c b/lib/glut-3.7.6/progs/advanced/csg.c new file mode 100644 index 0000000000..c72c0a0ad1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/csg.c @@ -0,0 +1,343 @@ + +/* csg.c - by Tom McReynolds, SGI */ + +/* Doing constructive solid geometry (CSG) with stencil. */ + +#include +#include +#include + +enum { + CSG_A, CSG_B, CSG_A_OR_B, CSG_A_AND_B, CSG_A_SUB_B, CSG_B_SUB_A +}; + +/* just draw single object */ +void +one(void (*a) (void)) +{ + glEnable(GL_DEPTH_TEST); + a(); + glDisable(GL_DEPTH_TEST); +} + +/* "or" is easy; simply draw both objects with depth buffering on */ +void +or(void (*a) (void), void (*b) (void)) +{ + glEnable(GL_DEPTH_TEST); + a(); + b(); + glDisable(GL_DEPTH_TEST); +} + +/* Set stencil buffer to show the part of a (front or back face) that's + inside b's volume. Requirements: GL_CULL_FACE enabled, depth func GL_LESS + Side effects: depth test, stencil func, stencil op */ +void +firstInsideSecond(void (*a) (void), void (*b) (void), GLenum face, GLenum test) +{ + glEnable(GL_DEPTH_TEST); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glCullFace(face); /* controls which face of a to use */ + a(); /* draw a face of a into depth buffer */ + + /* use stencil plane to find parts of a in b */ + glDepthMask(GL_FALSE); + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glCullFace(GL_BACK); + b(); /* increment the stencil where the front face of b is + drawn */ + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); + glCullFace(GL_FRONT); + b(); /* decrement the stencil buffer where the back face + of b is drawn */ + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glStencilFunc(test, 0, 1); + glDisable(GL_DEPTH_TEST); + + glCullFace(face); + a(); /* draw the part of a that's in b */ +} + +void +fixDepth(void (*a) (void)) +{ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glEnable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDepthFunc(GL_ALWAYS); + a(); /* draw the front face of a, fixing the depth buffer */ + glDepthFunc(GL_LESS); +} + +/* "and" two objects together */ +void +and(void (*a) (void), void (*b) (void)) +{ + firstInsideSecond(a, b, GL_BACK, GL_NOTEQUAL); + + fixDepth(b); + + firstInsideSecond(b, a, GL_BACK, GL_NOTEQUAL); + + glDisable(GL_STENCIL_TEST); /* reset things */ +} + +/* subtract b from a */ +void +sub(void (*a) (void), void (*b) (void)) +{ + firstInsideSecond(a, b, GL_FRONT, GL_NOTEQUAL); + + fixDepth(b); + + firstInsideSecond(b, a, GL_BACK, GL_EQUAL); + + glDisable(GL_STENCIL_TEST); /* reset things */ +} + +enum { + SPHERE = 1, CONE +}; + +/* Draw a cone */ +GLfloat coneX = 0.f, coneY = 0.f, coneZ = 0.f; +void +cone(void) +{ + glPushMatrix(); + glTranslatef(coneX, coneY, coneZ); + glTranslatef(0.f, 0.f, -30.f); + glCallList(CONE); + glPopMatrix(); +} + +/* Draw a sphere */ +GLfloat sphereX = 0.f, sphereY = 0.f, sphereZ = 0.f; +void +sphere(void) +{ + glPushMatrix(); + glTranslatef(sphereX, sphereY, sphereZ); + glCallList(SPHERE); + glPopMatrix(); + +} + +int csg_op = CSG_A; + +/* add menu callback */ + +void +menu(int csgop) +{ + csg_op = csgop; + glutPostRedisplay(); +} + +GLfloat viewangle; + +void +redraw(void) +{ + /* clear stencil each time */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + glRotatef(viewangle, 0.f, 1.f, 0.f); + + switch (csg_op) { + case CSG_A: + one(cone); + break; + case CSG_B: + one(sphere); + break; + case CSG_A_OR_B: + or(cone, sphere); + break; + case CSG_A_AND_B: + and(cone, sphere); + break; + case CSG_A_SUB_B: + sub(cone, sphere); + break; + case CSG_B_SUB_A: + sub(sphere, cone); + break; + } + glPopMatrix(); + glutSwapBuffers(); +} + +/* animate scene by rotating */ +enum { + ANIM_LEFT, ANIM_RIGHT +}; +int animDirection = ANIM_LEFT; + +void +anim(void) +{ + if (animDirection == ANIM_LEFT) + viewangle -= 3.f; + else + viewangle += 3.f; + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +/* special keys, like array and F keys */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + glutIdleFunc(anim); + animDirection = ANIM_LEFT; + break; + case GLUT_KEY_RIGHT: + glutIdleFunc(anim); + animDirection = ANIM_RIGHT; + break; + case GLUT_KEY_UP: + case GLUT_KEY_DOWN: + glutIdleFunc(0); + break; + } +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'a': + viewangle -= 10.f; + glutPostRedisplay(); + break; + case 's': + viewangle += 10.f; + glutPostRedisplay(); + break; + case '\033': + exit(0); + } +} + +int picked_object; +int xpos = 0, ypos = 0; +int newxpos, newypos; +int startx, starty; + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_UP) { + picked_object = button; + xpos += newxpos; + ypos += newypos; + newxpos = 0; + newypos = 0; + } else { /* GLUT_DOWN */ + startx = x; + starty = y; + } +} + +#define DEGTORAD (2 * 3.1415 / 360) +void +motion(int x, int y) +{ + GLfloat r, objx, objy, objz; + + newxpos = x - startx; + newypos = starty - y; + + r = (newxpos + xpos) * 50.f / 512.f; + objx = r * cos(viewangle * DEGTORAD); + objy = (newypos + ypos) * 50.f / 512.f; + objz = r * sin(viewangle * DEGTORAD); + + switch (picked_object) { + case CSG_A: + coneX = objx; + coneY = objy; + coneZ = objz; + break; + case CSG_B: + sphereX = objx; + sphereY = objy; + sphereZ = objz; + break; + } + glutPostRedisplay(); +} + +int +main(int argc, char **argv) +{ + static GLfloat lightpos[] = + {25.f, 50.f, -50.f, 1.f}; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE); + (void) glutCreateWindow("csg"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glutCreateMenu(menu); + glutAddMenuEntry("A only", CSG_A); + glutAddMenuEntry("B only", CSG_B); + glutAddMenuEntry("A or B", CSG_A_OR_B); + glutAddMenuEntry("A and B", CSG_A_AND_B); + glutAddMenuEntry("A sub B", CSG_A_SUB_B); + glutAddMenuEntry("B sub A", CSG_B_SUB_A); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + /* make display lists for sphere and cone; for efficiency */ + + glNewList(SPHERE, GL_COMPILE); + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 64, 64); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 15., 64, 1); + gluCylinder(cone, 15., 0., 60., 64, 64); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glMatrixMode(GL_PROJECTION); + glOrtho(-50., 50., -50., 50., -50., 50.); + glMatrixMode(GL_MODELVIEW); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/csg.dsp b/lib/glut-3.7.6/progs/advanced/csg.dsp new file mode 100644 index 0000000000..5157a741d7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/csg.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="csg" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=csg - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "csg.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "csg.mak" CFG="csg - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "csg - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "csg - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "csg - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "csg - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "csg - Win32 Release" +# Name "csg - Win32 Debug" +# Begin Source File + +SOURCE=.\csg.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/decal.c b/lib/glut-3.7.6/progs/advanced/decal.c new file mode 100644 index 0000000000..17d27c02f8 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/decal.c @@ -0,0 +1,123 @@ + +/* decal.c - by Tom McReynolds, SGI */ + +/* An Example of decaling, using stencil */ + +#include +#include + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + } +} + +/* decal shape polygon onto base */ +void +decal_poly(void) +{ + glBegin(GL_QUADS); + glNormal3f(0.f, 0.f, -1.f); + glVertex3i(-2, 2, 0); + glVertex3i(-2, 3, 0); + glVertex3i(2, 3, 0); + glVertex3i(2, 2, 0); + + glVertex3f(-.5, -3.f, 0); + glVertex3f(-.5f, 2.f, 0); + glVertex3f(.5f, 2.f, 0); + glVertex3f(.5f, -3.f, 0); + glEnd(); +} + +int angle = 0; + +void +redraw(void) +{ + /* clear stencil each time */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glDepthFunc(GL_LESS); + + glPushMatrix(); + glColor3f(1.f, 0.f, 0.f); + glTranslatef(0.f, 0.f, -10.f); + glScalef(5.f, 5.f, 5.f); + glRotatef((GLfloat) angle, 0.f, 1.f, 0.f); + glEnable(GL_NORMALIZE); + glutSolidDodecahedron(); + glDisable(GL_NORMALIZE); + glPopMatrix(); + + glStencilFunc(GL_EQUAL, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDepthFunc(GL_ALWAYS); + + glPushMatrix(); + glTranslatef(0.f, 0.f, -10.f); + glRotatef((GLfloat) angle, 0.f, 1.f, 0.f); + glRotatef(58.285f, 0.f, 1.f, 0.f); + glTranslatef(0.f, 0.f, -7.265f); + glColor3f(0.f, 1.f, 0.f); + decal_poly(); + glPopMatrix(); + + glDisable(GL_STENCIL_TEST); + + glutSwapBuffers(); +} + +void +anim(void) +{ + angle = (angle + 1) % 360; + glutPostRedisplay(); +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(anim); + else + glutIdleFunc(NULL); +} + +int +main(int argc, char *argv[]) +{ + static GLfloat lightpos[] = + {10.f, 5.f, 0.f, 1.f}; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE); + (void) glutCreateWindow("decal"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutVisibilityFunc(visible); + glEnable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glOrtho(-10., 10., -10., 10., 0., 20.); + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/decal.dsp b/lib/glut-3.7.6/progs/advanced/decal.dsp new file mode 100644 index 0000000000..b0c8bccdd4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/decal.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="decal" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=decal - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "decal.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "decal.mak" CFG="decal - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "decal - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "decal - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "decal - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "decal - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "decal - Win32 Release" +# Name "decal - Win32 Debug" +# Begin Source File + +SOURCE=.\decal.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/dissolve.c b/lib/glut-3.7.6/progs/advanced/dissolve.c new file mode 100644 index 0000000000..db6b2aeed7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/dissolve.c @@ -0,0 +1,441 @@ + +/* dissolve.c - by Tom McReynolds, SGI */ + +/* An Example of dissolve, using stencil */ + +/* Drag with left mouse button to dissolve to the 3D background, + Drag with middle mouse button to dissolve to checkerboard, and + use right button for menu to clear stencil. */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#define random rand +#endif + +int winWidth = 512; +int winHeight = 512; + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum { + SPHERE = 1, CONE +}; + +GLfloat angle = 0.f; /* angle of rotating object in layer 0 */ + +enum { + X, Y +}; +GLboolean eraser = GL_FALSE; +GLint layer = 1; +GLint eraserpos[2] = +{512 / 8, 512 / 12}; + +/* draw eraser and erase what's underneath */ + +GLubyte *eraserpix = 0; +int erasersize = 0; +void +makeEraser(void) +{ + int i, skip; + + erasersize = 4 * winWidth / 4 * winHeight / 6; + eraserpix = (GLubyte *) realloc(eraserpix, erasersize * sizeof(GLubyte)); + + /* make it white */ + (void) memset(eraserpix, 255, erasersize * sizeof(GLubyte)); + + skip = (int) (random() % 8); + for (i = 0; i < erasersize; i++) { + if (!skip) { + eraserpix[i] = 0; + eraserpix[i + 1] = 0; + eraserpix[i + 2] = 0; + eraserpix[i + 3] = 0; + skip = (int) (random() % 8); + } else + skip--; + } + +} + +/* ARGSUSED2 */ +/* left button, first layer, middle button, second layer */ +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + eraser = GL_TRUE; + if (button == GLUT_LEFT_BUTTON) + layer = 1; + else /* GLUT_MIDDLE: GLUT_RIGHT is for menu */ + layer = 0; + } else { /* GLUT_UP */ + eraser = GL_FALSE; + } + glutPostRedisplay(); +} + +enum { + CLEAR +}; /* menu choices */ +GLboolean clearstencil = GL_TRUE; + +void +menu(int choice) +{ + switch (choice) { + case CLEAR: + clearstencil = GL_TRUE; + break; + } + glutPostRedisplay(); +} + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glViewport(0, 0, wid, ht); + winWidth = wid; + winHeight = ht; + clearstencil = GL_TRUE; + makeEraser(); + glutPostRedisplay(); +} + +void +draweraser(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, winWidth, 0, winHeight); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* replace with this layer */ + glStencilFunc(GL_ALWAYS, layer, 0); + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_NOTEQUAL, 0); + glRasterPos2i(eraserpos[X], eraserpos[Y]); + glBitmap(0, 0, 0.f, 0.f, -winWidth / 8.f, -winHeight / 12.f, 0); + glDrawPixels(winWidth / 4, winHeight / 6, GL_RGBA, GL_UNSIGNED_BYTE, eraserpix); + glDisable(GL_ALPHA_TEST); +} + +void +drawlayer2(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, winWidth, 0, winHeight); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(0, 0); + glTexCoord2i(1, 0); + glVertex2i(winWidth, 0); + glTexCoord2i(1, 1); + glVertex2i(winWidth, winHeight); + glTexCoord2i(0, 1); + glVertex2i(0, winHeight); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + if (glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); +} + +void +drawlayer1(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + static GLfloat lightpos[] = + {50.f, 50.f, -320.f, 1.f}; + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(-80.f, -80.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-20.f, -100.f, -500.f); + glCallList(CONE); + glPopMatrix(); + + if (glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); +} + +void +drawlayer0(void) +{ + static GLfloat lightpos[] = + {50.f, 50.f, 0.f, 1.f}; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-50.f, 50.f, -50.f, 50.f, 0.f, 100.f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.f, 0.f, -50.f); + glRotatef(angle, 0.f, 1.f, 0.f); + glRotatef(90.f, 0.f, 0.f, 1.f); + glTranslatef(0.f, -25.f, 0.f); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glCullFace(GL_BACK); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glCallList(CONE); + +} + +void +redraw(void) +{ + if (glutLayerGet(GLUT_NORMAL_DAMAGED) || + clearstencil == GL_TRUE) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + clearstencil = GL_FALSE; + } else + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glStencilFunc(GL_EQUAL, 2, ~0); + drawlayer2(); + + glStencilFunc(GL_EQUAL, 1, ~0); + drawlayer1(); + + glStencilFunc(GL_EQUAL, 0, ~0); + drawlayer0(); + + if (eraser) + draweraser(); + + glutSwapBuffers(); +} + +void +idle(void) +{ + angle += 1.f; + glutPostRedisplay(); +} + +void +passive(int x, int y) +{ + + eraserpos[X] = x; + eraserpos[Y] = winHeight - y; +} + +void +motion(int x, int y) +{ + + eraserpos[X] = x; + eraserpos[Y] = winHeight - y; + + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + } +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); +} + +const int TEXDIM = 256; +GLfloat *tex = 0; + +int +main(int argc, char *argv[]) +{ + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_STENCIL | GLUT_DEPTH); + (void) glutCreateWindow("dissolve"); + glutDisplayFunc(redraw); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutPassiveMotionFunc(passive); + glutKeyboardFunc(key); + glutVisibilityFunc(visible); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + glutAddMenuEntry("Clear Stencil", CLEAR); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + makeEraser(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glClearStencil(2); + glEnable(GL_STENCIL_TEST); /* used all the time */ + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/dissolve.dsp b/lib/glut-3.7.6/progs/advanced/dissolve.dsp new file mode 100644 index 0000000000..330ae94dbb --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/dissolve.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="dissolve" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dissolve - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dissolve.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dissolve.mak" CFG="dissolve - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dissolve - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dissolve - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dissolve - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "dissolve - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "dissolve - Win32 Release" +# Name "dissolve - Win32 Debug" +# Begin Source File + +SOURCE=.\dissolve.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/envmap.c b/lib/glut-3.7.6/progs/advanced/envmap.c new file mode 100644 index 0000000000..212ca0a508 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/envmap.c @@ -0,0 +1,1195 @@ + +/* envmap.c - David Blythe, SGI */ + +/* Texture environment mapping demo. */ + +#include +#include +#include +#ifndef _WIN32 +#include +#else +#define drand48() (((float) rand())/((float) RAND_MAX)) +#endif +#include +#include +#include "texture.h" + +#if defined(GL_VERSION_1_1) +/* Routines called directly. */ +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) +#define glCopyTexSubImage2D(A,B,C,D,E,F,G,H) glCopyTexSubImage2DEXT(A,B,C,D,E,F,G,H) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#define glDeleteTextures(A,B) +#define glCopyTexSubImage2D(A,B,C,D,E,F,G,H) +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define OB_CUBE 0 +#define OB_SPHERE 1 +#define OB_SQUARE 2 +#define OB_CYL 3 +#define OB_TORUS 4 +#define OB_HSPHERE 5 + +#define NOBJS 5 +#define TDRAW 10 + +#define LIST_BASE 100 +#define TOBJ_BASE 200 +#define TEXSIZE 256 /* default texture-size */ + +typedef struct _vector { + float x, y, z; +} vector_t; + +typedef struct _face { + char *filename; + unsigned *buf; + int width; + int height; + int components; + vector_t u, v, n, o; /* plane equation */ + float angle1; + vector_t axis1; /* for rotation */ + float angle2; + vector_t axis2; +} face_t; + +typedef struct _color { + float r, g, b; +} color_t; + +struct { /* command-line options */ + int use_spheremap; + char *spheremap_file; + int hw; + int size; + int samples; + int object; + char *outfile; + int tessellation; +} opts = { + + 0, 0, 0, TEXSIZE, 4, OB_TORUS, 0, 30 +}; /* default settings */ + +void display(void); +void init(void); +void build_lists(void); +unsigned *render_spheremap(int *width, int *height, + int *components, int doalloc); + +/* strdup is actually not a standard ANSI C or POSIX routine + so implement a private one. OpenVMS does not have a strdup; Linux's + standard libc doesn't declare strdup by default (unless BSD or SVID + interfaces are requested). */ +static char * +stralloc(const char *string) +{ + char *copy; + + copy = malloc(strlen(string) + 1); + if (copy == NULL) + return NULL; + strcpy(copy, string); + return copy; +} + +void +vadd(vector_t * a, vector_t * b, vector_t * sum) +{ + sum->x = a->x + b->x; + sum->y = a->y + b->y; + sum->z = a->z + b->z; +} + +void +vsub(vector_t * a, vector_t * b, vector_t * diff) +{ + diff->x = a->x - b->x; + diff->y = a->y - b->y; + diff->z = a->z - b->z; +} + +void +vscale(vector_t * v, float scale) +{ + v->x *= scale; + v->y *= scale; + v->z *= scale; +} + +float +vdot(vector_t * u, vector_t * v) +{ + return (u->x * v->x + u->y * v->y + u->z * v->z); +} + +void +vreflect(vector_t * axis, vector_t * v, vector_t * r) +{ + vector_t t = *axis; + + vscale(&t, 2 * vdot(axis, v)); + vsub(&t, v, r); +} + +int +intersect(vector_t * v) +{ + int f; + float x, y, z; + + x = fabs(v->x); + y = fabs(v->y); + z = fabs(v->z); + if (x >= y && x >= z) + f = (v->x > 0) ? 2 : 0; + else if (y >= x && y >= z) + f = (v->y > 0) ? 4 : 5; + else + f = (v->z > 0) ? 3 : 1; + + return f; +} + +face_t face[6] = +{ + {"../data/00.rgb", 0, 0, 0, 0, + {0, 0, -1}, + {0, 1, 0}, + {-1, 0, 0}, + {-0.5, -0.5, 0.5}, 90.0, + {0, 1, 0}, 0, + {0, 0, 0}}, + {"../data/01.rgb", 0, 0, 0, 0, + {1, 0, 0}, + {0, 1, 0}, + {0, 0, -1}, + {-0.5, -0.5, -0.5}, 180.0, + {0, 1, 0}, 0, + {0, 0, 0}}, + {"../data/02.rgb", 0, 0, 0, 0, + {0, 0, 1}, + {0, 1, 0}, + {1, 0, 0}, + {0.5, -0.5, -0.5}, 270.0, + {0, 1, 0}, 0, + {0, 0, 0}}, + {"../data/03.rgb", 0, 0, 0, 0, + {-1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + {0.5, -0.5, 0.5}, 0.0, + {0, 1, 0}, 0, + {0, 0, 0}}, + {"../data/04.rgb", 0, 0, 0, 0, + {1, 0, 0}, + {0, 0, 1}, + {0, 1, 0}, + {-0.5, 0.5, -0.5}, 90.0, + {1, 0, 0}, 180.0, + {0, 1, 0}}, + {"../data/05.rgb", 0, 0, 0, 0, + {1, 0, 0}, + {0, 0, -1}, + {0, -1, 0}, + {-0.5, -0.5, 0.5}, -90.0, + {1, 0, 0}, 180.0, + {0, 1, 0}} +}; + +void +sample(int facenum, float s, float t, color_t * c) +{ + face_t *f = &face[facenum]; + int xpos, ypos; + unsigned char *p; + + xpos = s * f->width; + ypos = t * f->height; + + p = (unsigned char *) &f->buf[ypos * f->width + xpos]; + c->r = p[0] / 255.0; + c->g = p[1] / 255.0; + c->b = p[2] / 255.0; +} + +unsigned * +construct_spheremap(int *width, int *height, + int *components) +{ + int i, j, x, y, f; + unsigned *spheremap; + unsigned char *lptr; + int size = opts.size; + color_t c, texel; + vector_t v, r, p; + float s, t, temp, k; + int samples; + + /* Read in the 6 faces of the environment */ + for (i = 0; i < 6; i++) { + face[i].buf = read_texture(face[i].filename, &face[i].width, + &face[i].height, &face[i].components); + if (!face[i].buf) { + fprintf(stderr, "Error: cannot load image %s\n", face[i].filename); + exit(1); + } + } + + *components = face[0].components; + *width = *height = size; + samples = opts.samples; + + spheremap = (unsigned *) malloc(size * size * sizeof(unsigned)); + if (!spheremap) { + perror("malloc"); + exit(1); + } + lptr = (unsigned char *) spheremap; + + /* Calculate sphere-map by rendering a perfectly reflective solid sphere. */ + + for (y = 0; y < size; y++) + for (x = 0; x < size; x++) { + + texel.r = texel.g = texel.b = 0.0; + for (j = 0; j < samples; j++) { + s = (x + (float) drand48()) / size - 0.5; + t = (y + (float) drand48()) / size - 0.5; + + temp = s * s + t * t; + if (temp >= 0.25) { /* point not on sphere */ + c.r = c.g = c.b = 0; + continue; + } + /* get point on sphere */ + p.x = s; + p.y = t; + p.z = sqrt(0.25 - temp); + vscale(&p, 2.0); + /* ray from infinity (eyepoint) to surface */ + v.x = 0.0; + v.y = 0.0; + v.z = 1.0; + + /* get reflected ray */ + vreflect(&p, &v, &r); + + /* Intersect reflected ray with cube */ + f = intersect(&r); + k = vdot(&face[f].o, &face[f].n) / vdot(&r, &face[f].n); + vscale(&r, k); + vsub(&r, &face[f].o, &v); + + /* Get texture map-indices */ + s = vdot(&v, &face[f].u); + t = vdot(&v, &face[f].v); + + /* Sample to get color */ + sample(f, s, t, &c); + + texel.r += c.r; + texel.g += c.g; + texel.b += c.b; + } + + lptr[0] = 255 * texel.r / samples; + lptr[1] = 255 * texel.g / samples; + lptr[2] = 255 * texel.b / samples; + lptr[3] = 0xff; + lptr += 4; + } + + return (unsigned *) spheremap; +} + +void +texture_init(void) +{ + unsigned *buf; + int width, height, components; + char filename[80]; + + if (opts.use_spheremap) { + strcpy(filename, opts.spheremap_file); + buf = read_texture(filename, &width, &height, &components); + if (components == 3) + components++; + if (!buf) { + fprintf(stderr, "Error: cannot load image %s\n", filename); + exit(1); + } + } else { + buf = (opts.hw) ? + render_spheremap(&width, &height, &components, 1) : + construct_spheremap(&width, &height, &components); + + if (!buf) { + fprintf(stderr, "Error: Cannot construct spheremap\n"); + exit(1); + } + } + + glBindTexture(GL_TEXTURE_2D, TOBJ_BASE + TDRAW); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + gluBuild2DMipmaps(GL_TEXTURE_2D, components, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, buf); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + free(buf); +} + +void +texture_init_from_spheremap(void) +{ + int w, h, components; + + render_spheremap(&w, &h, &components, 0); + + glReadBuffer(GL_BACK); + glBindTexture(GL_TEXTURE_2D, TOBJ_BASE + TDRAW); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); +} + +void +parse(int argc, char *argv[]) +{ + int i = 1; + char *usage = + "Usage: map [-size n] [-samples n] [-help] \n\ +\t[-sphere filename | -cubemap [0-5].rgb]\n\ +\n\ +\t-size n : specify size of sphere-map (when generated from cubemap)\n\ +\t-samples n : #samples to use per pixel of the spheremap\n\ +\t-sphere file.rgb : specify spheremap-image\n\ +\t-cubemap [0-5].rgb: specify 6 cubemap files\n\ +\t-out file.rgb: save generated spheremap to file\n\ +\t-hw : Use hardware texture mapping to create sphere-map\n\ +\t-help : print this message\n"; + +#define check_arg(i, n, str) \ + if (argc < i+n) { \ + fprintf(stderr, "%s needs an argument\n", str); \ + fprintf(stderr, usage); \ + exit(1); \ + } + + while (i < argc) { + if (!strcmp(argv[i], "-size")) { + check_arg(i, 1, "-size"); + opts.size = atoi(argv[++i]); + + } else if (!strcmp(argv[i], "-samples")) { + check_arg(i, 1, "-samples"); + opts.samples = atoi(argv[++i]); + + } else if (!strcmp(argv[i], "-out")) { + check_arg(i, 1, "-out"); + opts.outfile = stralloc(argv[++i]); + + } else if (!strcmp(argv[i], "-sphere")) { + opts.use_spheremap = 1; + + } else if (!strcmp(argv[i], "-cubemap")) { + int j; + check_arg(i, 6, "-cubemap"); + for (j = 0; j < 6; j++) + face[j].filename = stralloc(argv[++i]); + + } else if (!strcmp(argv[i], "-help")) { + fprintf(stderr, usage); + exit(0); + + } else if (!strcmp(argv[i], "-hw")) { + opts.hw = 1; + + } else { + if (opts.use_spheremap && !opts.spheremap_file) + opts.spheremap_file = stralloc(argv[i]); + else { + fprintf(stderr, "Error: unrecognized option %s\n", argv[i]); + fprintf(stderr, usage); + exit(1); + } + } + i++; + } /* end-while */ +} + +#ifdef use_copytex +static int currwidth = TEXSIZE; +static int currheight = TEXSIZE; +#else +static int currwidth = 400; +static int currheight = 400; +#endif + +static int do_spheremap = 0, do_alloc = 0; +static GLfloat rotv[] = +{0., 0., 0.}; +static GLfloat rots[] = +{0., 0., 0.}; +static GLfloat plane[4][3] = +{ + {1.0, -1.0, 0.0}, + {1.0, 1.0, 0.0}, + {-1.0, 1.0, 0.0}, + {-1.0, -1.0, 0.0} +}; + +static GLfloat cube[6][4][3] = +{ + { + {1.0, -1.0, -1.0}, /* counter-clockwise faces */ + {-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 norm[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} +}; + +void +reshape(int w, int h) +{ + currwidth = w; + currheight = h; + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w / (GLfloat) h, 1.0, 20.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 6, + 0, 0, 0, + 0, 1, 0); +} + +/* ARGSUSED1 */ +void +keys(unsigned char key, int x, int y) +{ + switch (key) { + + case 'o': /* switch between objects */ + opts.object = (opts.object + 1) % NOBJS; + glutPostRedisplay(); + break; + + case '+': /* change tessellation */ + opts.tessellation += 2; + build_lists(); + glutPostRedisplay(); + break; + + case '-': + opts.tessellation -= 2; + if (opts.tessellation < 4) + opts.tessellation = 4; + build_lists(); + glutPostRedisplay(); + break; + + case 's': /* toggle between spheremap generation */ + /* mode and display mode */ + do_spheremap ^= 1; + if (!do_spheremap) /* switch back to normal mode */ + do_alloc = 1; + glutPostRedisplay(); + break; + + case 'h': + case 'H': + printf("\nKey functions\n"); + printf("\to: switch objects\n"); + printf("\ts: switch to spheremap generation mode\n"); + printf("\t+: increase tessellation\n"); + printf("\t-: decrease tessellation\n"); + printf("\th: help\n"); + printf("\tESC: quit\n"); + printf("\tleft/right arrow-keys: Rotate around X axis\n"); + printf("\tup/down arrow-keys: Rotate around Y axis\n"); + printf("\tpage-up/pgdown arrow-keys: Rotate around Z axis\n"); + break; + + case 27: + exit(0); + } +} + +/* ARGSUSED1 */ +void +special_keys(int key, int x, int y) +{ + GLfloat *vect; + + if (do_spheremap) + vect = rots; + else + vect = rotv; + + switch (key) { + case GLUT_KEY_LEFT: + vect[1] -= 0.5; + glutPostRedisplay(); + break; + case GLUT_KEY_RIGHT: + vect[1] += 0.5; + glutPostRedisplay(); + break; + case GLUT_KEY_UP: + vect[0] -= 0.5; + glutPostRedisplay(); + break; + case GLUT_KEY_DOWN: + vect[0] += 0.5; + glutPostRedisplay(); + break; + case GLUT_KEY_PAGE_UP: + vect[2] -= 0.5; + glutPostRedisplay(); + break; + case GLUT_KEY_PAGE_DOWN: + vect[2] += 0.5; + glutPostRedisplay(); + break; + } +} + +/* Use mouse buttons to generate spheremap on the fly while the objects are + being displayed. */ +static void +motion(int x, int y) +{ + rots[1] = 180.0 * x / currwidth - 90.0; + rots[0] = 180.0 * y / currheight - 90.0; +#ifdef use_copytex + if (!do_spheremap) + texture_init_from_spheremap(); +#endif + glutPostRedisplay(); +} + +void +menu(int value) +{ + keys((unsigned char) value, 0, 0); +} + +#if defined(GL_VERSION_1_1) + +static int +supportsOneDotOne(void) +{ + const char *version; + int major, minor; + + version = (char *) glGetString(GL_VERSION); + if (sscanf(version, "%d.%d", &major, &minor) == 2) + return major >= 1 && minor >= 1; + return 0; /* OpenGL version string malformed! */ +} + +#endif + +int +main(int argc, char *argv[]) +{ + int hasExtendedTextures; + + parse(argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowSize(currwidth, currheight); + glutCreateWindow("Environment map"); + +#if defined(GL_VERSION_1_1) + hasExtendedTextures = supportsOneDotOne(); + if(!hasExtendedTextures) { + fprintf(stderr, + "envmap: This example requires OpenGL 1.1.\n"); + exit(1); + } +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) + hasExtendedTextures = glutExtensionSupported("GL_EXT_subtexture") + && glutExtensionSupported("GL_EXT_texture_object") + && glutExtensionSupported("GL_EXT_copy_texture"); + if(!hasExtendedTextures) { + fprintf(stderr, + "envmap: This example requires the OpenGL EXT_subtexture, EXT_texture_object, and EXT_copy_texture extensions.\n"); + exit(1); + } +#else + hasExtendedTextures = 0; + if(!hasExtendedTextures) { + fprintf(stderr, + "envmap: This example must be compiled with either OpenGL 1.1 or the OpenGL EXT_subtexture, EXT_texture_object, and EXT_copy_texture extensions.\n"); + exit(1); + } +#endif + + init(); + + glutReshapeFunc(reshape); + glutKeyboardFunc(keys); + glutSpecialFunc(special_keys); + if (opts.hw) + glutMotionFunc(motion); + glutDisplayFunc(display); + glutCreateMenu(menu); + glutAddMenuEntry("Switch object", 'o'); + glutAddMenuEntry("Up tessellation", '+'); + glutAddMenuEntry("Lower tessellation", '-'); + glutAddMenuEntry("Quit", 27); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +void +build_cube(void) +{ + int i; + + glNewList(LIST_BASE + OB_CUBE, GL_COMPILE); + for (i = 0; i < 6; i++) { + glBegin(GL_QUADS); + glNormal3fv(norm[i]); + glVertex3fv(cube[i][0]); + glVertex3fv(cube[i][1]); + glVertex3fv(cube[i][2]); + glVertex3fv(cube[i][3]); + glEnd(); + } + glEndList(); +} + +void +build_sphere(int tess) +{ + float r = 1.0, r1, r2, z1, z2; + float theta, phi; + int nlon = tess, nlat = tess; + int i, j; + + glNewList(LIST_BASE + OB_SPHERE, GL_COMPILE); + glBegin(GL_TRIANGLE_FAN); + theta = M_PI * 1.0 / nlat; + r2 = r * sin(theta); + z2 = r * cos(theta); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, r); + for (j = 0, phi = 0.0; j <= nlon; j++, phi = 2 * M_PI * j / nlon) { + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex3f(r2 * cos(phi), r2 * sin(phi), z2); /* top */ + } + glEnd(); + + for (i = 2; i < nlat; i++) { + theta = M_PI * i / nlat; + r1 = r * sin(M_PI * (i - 1) / nlat); + z1 = r * cos(M_PI * (i - 1) / nlat); + r2 = r * sin(theta); + z2 = r * cos(theta); + glBegin(GL_QUAD_STRIP); + for (j = 0, phi = 0; j <= nlat; j++, phi = 2 * M_PI * j / nlon) { + glNormal3f(r1 * cos(phi), r1 * sin(phi), z1); + glVertex3f(r1 * cos(phi), r1 * sin(phi), z1); + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex3f(r2 * cos(phi), r2 * sin(phi), z2); + } + glEnd(); + } + + glBegin(GL_TRIANGLE_FAN); + theta = M_PI * (nlat - 1) / nlat; + r2 = r * sin(theta); + z2 = r * cos(theta); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, -r); + for (j = nlon, phi = 0.0; j >= 0; j--, phi = 2 * M_PI * j / nlon) { + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex3f(r2 * cos(phi), r2 * sin(phi), z2); /* bottom */ + } + glEnd(); + glEndList(); +} + +/* Same as above routine except that we use homogeneous co-ordinates. Each + component (including w) is multiplied by z */ +void +build_special_sphere(int tess) +{ + float r = 1.0, r1, r2, z1, z2; + float theta, phi; + int nlon = tess, nlat = tess; + int i, j; + + glNewList(LIST_BASE + OB_HSPHERE, GL_COMPILE); + glBegin(GL_TRIANGLE_FAN); + theta = M_PI * 1.0 / nlat; + r2 = r * sin(theta); + z2 = r * cos(theta); + glNormal3f(0.0, 0.0, 1.0); + glVertex4f(0.0, 0.0, r * r, r); + for (j = 0, phi = 0.0; j <= nlon; j++, phi = 2 * M_PI * j / nlon) { + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex4f(r2 * cos(phi) * z2, r2 * sin(phi) * z2, z2 * z2, z2); /* top */ + } + glEnd(); + + for (i = 2; i < nlat; i++) { + theta = M_PI * i / nlat; + r1 = r * sin(M_PI * (i - 1) / nlat); + z1 = r * cos(M_PI * (i - 1) / nlat); + r2 = r * sin(theta); + z2 = r * cos(theta); + + if (fabs(z1) < 0.01 || fabs(z2) < 0.01) + break; + + glBegin(GL_QUAD_STRIP); + for (j = 0, phi = 0; j <= nlat; j++, phi = 2 * M_PI * j / nlon) { + glNormal3f(r1 * cos(phi), r1 * sin(phi), z1); + glVertex4f(r1 * cos(phi) * z1, r1 * sin(phi) * z1, z1 * z1, z1); + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex4f(r2 * cos(phi) * z2, r2 * sin(phi) * z2, z2 * z2, z2); + } + glEnd(); + } + + glBegin(GL_TRIANGLE_FAN); + theta = M_PI * (nlat - 1) / nlat; + r2 = r * sin(theta); + z2 = r * cos(theta); + glNormal3f(0.0, 0.0, -1.0); + glVertex4f(0.0, 0.0, -r * -r, -r); + for (j = nlon, phi = 0.0; j >= 0; j--, phi = 2 * M_PI * j / nlon) { + glNormal3f(r2 * cos(phi), r2 * sin(phi), z2); + glVertex4f(r2 * cos(phi) * z2, r2 * sin(phi) * z2, z2 * z2, z2); /* bottom + + */ + } + glEnd(); + glEndList(); +} + +void +build_square(void) +{ + glNewList(LIST_BASE + OB_SQUARE, GL_COMPILE); + glBegin(GL_POLYGON); + glNormal3f(0.0, 0.0, 1.0); + glVertex3fv(plane[0]); + glVertex3fv(plane[1]); + glVertex3fv(plane[2]); + glVertex3fv(plane[3]); + glEnd(); + glEndList(); +} + +void +build_cylinder(int tess) +{ + int slices = tess, stacks = tess; + int i, j; + GLfloat phi, z1, r, z2; + + glNewList(LIST_BASE + OB_CYL, GL_COMPILE); + z1 = 2.0; + r = 1.0; + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, z1); + for (i = 0; i <= slices; i++) { + phi = M_PI * 2.0 * i / slices; + glVertex3f(r * cos(phi), r * sin(phi), z1); + } + glEnd(); + + for (i = 0, z2 = 0.0, z1 = 2.0 / stacks; i < stacks; i++) { + glBegin(GL_QUAD_STRIP); + for (j = 0, phi = 0; j <= slices; j++, phi = M_PI * 2.0 * j / slices) { + glNormal3f(r * cos(phi), r * sin(phi), 0); + glVertex3f(r * cos(phi), r * sin(phi), z1); + glVertex3f(r * cos(phi), r * sin(phi), z2); + } + glEnd(); + z1 += 2.0 / stacks; + z2 += 2.0 / stacks; + } + + z2 = 0.0; + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, z2); + for (i = slices; i >= 0; i--) { + phi = M_PI * 2.0 * i / slices; + glVertex3f(r * cos(phi), r * sin(phi), z2); + } + glEnd(); + glEndList(); +} + +void +build_torus(int tess) +{ + int i, j, k, l; + int numg = 1.2 * tess; + int nums = tess; + GLfloat x, y, z; + GLfloat theta, phi; + const GLfloat twopi = 2.0 * M_PI; + const GLfloat rg = 2.0, rs = 1.0; + + glNewList(LIST_BASE + OB_TORUS, GL_COMPILE); + for (i = 0; i < numg; i++) { + + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= nums; j++) { + phi = twopi * j / nums; + + for (k = 0; k <= 1; k++) { + l = (i + k) % numg; + theta = twopi * l / numg; + + glNormal3f(rs * cos(phi) * cos(theta), + rs * cos(phi) * sin(theta), + rs * sin(phi)); + + x = (rg + rs * cos(phi)) * cos(theta); + y = (rg + rs * cos(phi)) * sin(theta); + z = rs * sin(phi); + glVertex3f(x, y, z); + } + } + glEnd(); + } + glEndList(); +} + +void +display(void) +{ + static int once = 0; + + if (!once && opts.hw) { + texture_init(); + once = 1; + } + if (do_spheremap || do_alloc) { + int w, h, comp; + if (do_alloc) { + texture_init(); + do_alloc = 0; + } else + render_spheremap(&w, &h, &comp, 0); + + } else { + + glPushMatrix(); + glBindTexture(GL_TEXTURE_2D, TOBJ_BASE + TDRAW); + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glRotatef(rotv[0], 1, 0, 0); + glRotatef(rotv[1], 0, 1, 0); + glRotatef(rotv[2], 0, 0, 1); + + switch (opts.object) { + + case OB_SQUARE: + case OB_CUBE: + case OB_SPHERE: + glCallList(LIST_BASE + opts.object); + break; + + case OB_CYL: + glTranslatef(0.0, 0.0, -1.0); + glCallList(LIST_BASE + OB_CYL); + break; + + case OB_TORUS: + glScalef(0.6, 0.6, 0.6); + glEnable(GL_NORMALIZE); + glCallList(LIST_BASE + OB_TORUS); + glDisable(GL_NORMALIZE); + break; + + default: + printf("Eh?\n"); + } + + glLineWidth(2.0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINES); + glColor3f(1.0, 0.0, 0.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(4.0, 0.0, 0.0); + + glColor3f(0.0, 1.0, 0.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.0, 4.0, 0.0); + + glColor3f(1.0, 1.0, 1.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.0, 0.0, 4.0); + glEnd(); + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glPopMatrix(); + } + + glutSwapBuffers(); +} + +void +build_lists(void) +{ + build_square(); + build_cube(); + build_sphere(opts.tessellation); + build_cylinder(opts.tessellation); + build_torus(opts.tessellation); + build_special_sphere(opts.tessellation + 10); +} + +void +init(void) +{ + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glClearColor(0.0, 0.0, 0.0, 1.0); + build_lists(); + texture_init(); +} + +void +err(void) +{ + printf("error=%#x\n", glGetError()); +} + +/* Use projective textures to generate sphere-map */ +unsigned * +render_spheremap(int *width, int *height, + int *components, int doalloc) +{ + int i, j, k; + GLfloat p[4]; + static unsigned *spheremap = NULL; + static int texread_done = 0; + + if (!opts.hw) /* shouldn't come here */ + return NULL; + + for (i = 0; i < 6; i++) { + if (!texread_done) { + face[i].buf = read_texture(face[i].filename, &face[i].width, + &face[i].height, &face[i].components); + if (!face[i].buf) { + fprintf(stderr, "Error: cannot load image %s\n", face[i].filename); + exit(1); + } + for (j = 0; j < face[i].height; j++) /* texture border hack!! */ + for (k = 0; k < face[i].width; k++) + if (j < 1 || k < 1 || + j > face[i].height - 2 || k > face[i].width - 2) { + unsigned char *p = (unsigned char *) &face[i].buf[face[i].width * j + k]; + p[3] = 0; /* zero out alpha */ + } + } + glBindTexture(GL_TEXTURE_2D, TOBJ_BASE + i); + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexImage2D(GL_TEXTURE_2D, 0, 4, + face[i].width, face[i].height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, face[i].buf); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + p[0] = 2.0; + p[1] = p[2] = p[3] = 0.0; /* 2zx */ + glTexGenfv(GL_S, GL_OBJECT_PLANE, p); + + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = 0.0; + p[1] = 2.0; + p[2] = p[3] = 0.0; /* 2zy */ + glTexGenfv(GL_T, GL_OBJECT_PLANE, p); + + glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = p[1] = 0.0; + p[2] = 0.0; + p[3] = 2.0; /* 2z */ + glTexGenfv(GL_R, GL_OBJECT_PLANE, p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + } + + texread_done = 1; + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + glColor4f(1.0, 1.0, 1.0, 1.0); + + /* Initialize sphere-map colors, and viewing transformations */ + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, 1.0, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 6, + 0, 0, 0, + 0, 1, 0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClearDepth(1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* Look at the sphere from the chosen viewing direction and render the + sphere at origin. */ + + for (i = 0; i < 6; i++) { /* for all faces */ + glBindTexture(GL_TEXTURE_2D, TOBJ_BASE + i); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.5, 0.5, 1.0); + glTranslatef(1.0, 1.0, 0.0); + glFrustum(-1.01, 1.01, -1.01, 1.01, 1.0, 100.0); + if (face[i].angle2 != 0.) { + glRotatef(face[i].angle2, + face[i].axis2.x, face[i].axis2.y, face[i].axis2.z); + } + glRotatef(face[i].angle1, + face[i].axis1.x, face[i].axis1.y, face[i].axis1.z); + glRotatef(rots[0], 1, 0, 0); + glRotatef(rots[1], 0, 1, 0); + glRotatef(rots[2], 0, 0, 1); + glTranslatef(0.0, 0.0, -1.00); + + glMatrixMode(GL_MODELVIEW); + glClear(GL_DEPTH_BUFFER_BIT); + glCallList(LIST_BASE + OB_HSPHERE); + } + + glDisable(GL_BLEND); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + if (doalloc) { + /* read in current image and return it to be used as the spheremap */ + unsigned *temp; + + temp = (unsigned *) + malloc(currwidth * currheight * sizeof(unsigned)); + spheremap = (unsigned *) + malloc(opts.size * opts.size * sizeof(unsigned)); + + glReadBuffer(GL_BACK); + glReadPixels(0, 0, currwidth, currheight, GL_RGBA, + GL_UNSIGNED_BYTE, temp); + gluScaleImage(GL_RGBA, + currwidth, currheight, GL_UNSIGNED_BYTE, temp, + opts.size, opts.size, GL_UNSIGNED_BYTE, spheremap); + free(temp); + } + *width = *height = opts.size; + *components = 4; + return (unsigned *) spheremap; +} + diff --git a/lib/glut-3.7.6/progs/advanced/envmap.dsp b/lib/glut-3.7.6/progs/advanced/envmap.dsp new file mode 100644 index 0000000000..56bcf5d1df --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/envmap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="envmap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=envmap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "envmap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "envmap.mak" CFG="envmap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "envmap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "envmap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "envmap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "envmap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "envmap - Win32 Release" +# Name "envmap - Win32 Debug" +# Begin Source File + +SOURCE=.\envmap.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/envphong.c b/lib/glut-3.7.6/progs/advanced/envphong.c new file mode 100644 index 0000000000..07ab1c1f64 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/envphong.c @@ -0,0 +1,671 @@ + +/* envphong.c - David G. Yu, SGI */ + +/** + ** Demonstrates a use of environment texture mapping for improved highlight + ** shading. + ** + ** Press mouse button one to move the object, press mouse button two to + ** move the light source. Pressing the key switches between using + ** regular lighting or texture mapping for the specular highlights. The + ** key will cycle through objects (sphere, cylinder, torus). Check + ** out the event loop code below for other keys which do will things. + ** + ** TBD + ** - improve accuracy of the highlight texture map + ** - reduce or eliminate grazing angle artifacts + ** - improve user interaction + ** + ** 1995 -- David G Yu + ** + ** cc -o envphong envphong.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm + **/ + +#include +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +int win, win2; +int needsLightUpdate = GL_TRUE; +int useLighting = GL_TRUE; +int useSpecularTexture = GL_FALSE; +int useTexture = GL_FALSE; +int useHighRes = GL_FALSE; +int usePattern = GL_FALSE; +int moveLight = GL_FALSE; +int moveObject = GL_FALSE; +int drawObj = 0, maxObj = 2; +GLfloat lightRotX, lightRotY; +GLfloat objectRotX, objectRotY; +int curx, cury, width, height; + +void +drawSphere(int numMajor, int numMinor, float radius) +{ + double majorStep = (M_PI / numMajor); + double minorStep = (2.0 * M_PI / numMinor); + int i, j; + + for (i = 0; i < numMajor; ++i) { + double a = i * majorStep; + double b = a + majorStep; + double r0 = radius * sin(a); + double r1 = radius * sin(b); + GLfloat z0 = radius * cos(a); + GLfloat z1 = radius * cos(b); + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) { + double c = j * minorStep; + GLfloat x = cos(c); + GLfloat y = sin(c); + + glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); + glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); + glVertex3f(x * r0, y * r0, z0); + + glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); + glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); + glVertex3f(x * r1, y * r1, z1); + } + glEnd(); + } +} + +void +drawCylinder(int numMajor, int numMinor, float height, float radius) +{ + double majorStep = height / numMajor; + double minorStep = 2.0 * M_PI / numMinor; + int i, j; + + for (i = 0; i < numMajor; ++i) { + GLfloat z0 = 0.5 * height - i * majorStep; + GLfloat z1 = z0 - majorStep; + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) { + double a = j * minorStep; + GLfloat x = radius * cos(a); + GLfloat y = radius * sin(a); + + glNormal3f(x / radius, y / radius, 0.0); + glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); + glVertex3f(x, y, z0); + + glNormal3f(x / radius, y / radius, 0.0); + glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); + glVertex3f(x, y, z1); + } + glEnd(); + } +} + +void +drawTorus(int numMajor, int numMinor, float majorRadius, float minorRadius) +{ + double majorStep = 2.0 * M_PI / numMajor; + double minorStep = 2.0 * M_PI / numMinor; + int i, j; + + for (i = 0; i < numMajor; ++i) { + double a0 = i * majorStep; + double a1 = a0 + majorStep; + GLfloat x0 = cos(a0); + GLfloat y0 = sin(a0); + GLfloat x1 = cos(a1); + GLfloat y1 = sin(a1); + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) { + double b = j * minorStep; + GLfloat c = cos(b); + GLfloat r = minorRadius * c + majorRadius; + GLfloat z = minorRadius * sin(b); + + glNormal3f(x0 * c, y0 * c, z / minorRadius); + glTexCoord2f(i / (GLfloat) numMajor, j / (GLfloat) numMinor); + glVertex3f(x0 * r, y0 * r, z); + + glNormal3f(x1 * c, y1 * c, z / minorRadius); + glTexCoord2f((i + 1) / (GLfloat) numMajor, j / (GLfloat) numMinor); + glVertex3f(x1 * r, y1 * r, z); + } + glEnd(); + } +} + +void +setNullTexture(void) +{ + GLubyte texPixel[4] = + {0xff, 0xff, 0xff, 0xff}; + 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, 4, 1, 1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texPixel); +} + +void +setCheckTexture(void) +{ + int texWidth = 64; + int texHeight = 64; + GLubyte *texPixels, *p; + int i, j; + + texPixels = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); + if (texPixels == NULL) { + return; + } + p = texPixels; + for (i = 0; i < texHeight; ++i) { + for (j = 0; j < texWidth; ++j) { + if ((i ^ j) & 8) { + p[0] = 0xff; + p[1] = 0xff; + p[2] = 0xff; + p[3] = 0xff; + } else { + p[0] = 0x08; + p[1] = 0x08; + p[2] = 0x08; + p[3] = 0xff; + } + p += 4; + } + } + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, texPixels); + free(texPixels); +} + +void +setLight(void) +{ + GLfloat light0Pos[4] = + {0.70, 0.70, 1.25, 0.00}; + GLfloat light0Amb[4] = + {0.00, 0.00, 0.00, 1.00}; + GLfloat light0Diff[4] = + {1.00, 1.00, 1.00, 1.00}; + GLfloat light0Spec[4] = + {1.00, 1.00, 1.00, 1.00}; + GLfloat light0SpotDir[3] = + {0.00, 0.00, -1.00}; + GLfloat light0SpotExp = 0.00; + GLfloat light0SpotCutoff = 180.00; + GLfloat light0Atten0 = 1.00; + GLfloat light0Atten1 = 0.00; + GLfloat light0Atten2 = 0.00; + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, light0Pos); + glLightfv(GL_LIGHT0, GL_AMBIENT, light0Amb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diff); + glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spec); + glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0SpotDir); + glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, light0SpotExp); + glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, light0SpotCutoff); + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, light0Atten0); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, light0Atten1); + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, light0Atten2); +} + +#define MAT_ALL 0 +#define MAT_NO_SPECULAR 1 +#define MAT_SPECULAR_ONLY 2 +#define MAT_SPECULAR_TEXTURE_ONLY 3 +#define MAT_GEN_SPECULAR_TEXTURE 4 + +void +setMaterial(int mode) +{ + static GLubyte *texPixels; + int texWidth = 128; + int texHeight = 128; + + GLfloat matZero[4] = + {0.00, 0.00, 0.00, 1.00}; + GLfloat matOne[4] = + {1.00, 1.00, 1.00, 1.00}; + GLfloat matEm[4] = + {0.00, 0.00, 0.00, 1.00}; + GLfloat matAmb[4] = + {0.01, 0.01, 0.01, 1.00}; + GLfloat matDiff[4] = + {0.02, 0.20, 0.16, 1.00}; + GLfloat matSpec[4] = + {0.50, 0.50, 0.50, 1.00}; + GLfloat matShine = 20.00; + + if ((mode == MAT_ALL) || (mode == MAT_NO_SPECULAR)) { + glMaterialfv(GL_FRONT, GL_EMISSION, matEm); + glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb); + glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff); + } else { + glMaterialfv(GL_FRONT, GL_EMISSION, matZero); + glMaterialfv(GL_FRONT, GL_AMBIENT, matZero); + glMaterialfv(GL_FRONT, GL_DIFFUSE, matZero); + } + + if ((mode == MAT_ALL) || (mode == MAT_SPECULAR_ONLY)) { + glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec); + glMaterialf(GL_FRONT, GL_SHININESS, matShine); + } else { + glMaterialfv(GL_FRONT, GL_SPECULAR, matZero); + glMaterialf(GL_FRONT, GL_SHININESS, 1); + } + + if (mode == MAT_SPECULAR_TEXTURE_ONLY) { + if (texPixels == NULL) { + return; + } + glMaterialfv(GL_FRONT, GL_SPECULAR, matOne); + glMaterialf(GL_FRONT, GL_SHININESS, 0); + + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, texPixels); + } + if (mode == MAT_GEN_SPECULAR_TEXTURE) { + if (texPixels == NULL) { + texPixels = (GLubyte *) + malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); + if (texPixels == NULL) { + return; + } + } + glPushAttrib(GL_ALL_ATTRIB_BITS); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + setMaterial(MAT_SPECULAR_ONLY); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, 1, 3); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(0, 0, -2); + + glPushMatrix(); + glRotatef(lightRotY, 0, 1, 0); + glRotatef(lightRotX, 1, 0, 0); + setLight(); + glPopMatrix(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + + glViewport(0, 0, 128, 128); + glClearColor(.25, .25, .25, .25); + glClear(GL_COLOR_BUFFER_BIT); + drawSphere(128, 128, 1.0); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glReadPixels(0, 0, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, texPixels); + + glPopAttrib(); + } +} + +void +initialize(void) +{ + glMatrixMode(GL_PROJECTION); + glFrustum(-0.50, 0.50, -0.50, 0.50, 1.0, 3.0); + glMatrixMode(GL_MODELVIEW); + glTranslatef(0.0, 0.0, -2.0); + + glDepthFunc(GL_LEQUAL); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); +} + +void +redraw(void) +{ + glClearColor(0.1, 0.1, 0.1, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBegin(GL_QUADS); + glColor3f(0.9, 0.0, 1.0); + glVertex3f(-2.0, -2.0, -1.0); + glColor3f(0.9, 0.0, 1.0); + glVertex3f(2.0, -2.0, -1.0); + glColor3f(0.0, 0.1, 0.1); + glVertex3f(2.0, 2.0, -1.0); + glColor3f(0.0, 0.1, 0.1); + glVertex3f(-2.0, 2.0, -1.0); + glEnd(); + + glEnable(GL_DEPTH_TEST); + + if (useLighting) { + glEnable(GL_LIGHTING); + glPushMatrix(); + glRotatef(lightRotY, 0, 1, 0); + glRotatef(lightRotX, 1, 0, 0); + setLight(); + glPopMatrix(); + } else { + glColor3f(0.2, 0.2, 0.2); + } + if (useTexture || useSpecularTexture) { + glEnable(GL_TEXTURE_2D); + } + if (useTexture) { + setCheckTexture(); + } else { + setNullTexture(); + } + if (useSpecularTexture) { + /* pass one */ + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ZERO); + setMaterial(MAT_NO_SPECULAR); + } else { + setMaterial(MAT_ALL); + } + glPushMatrix(); + glRotatef(objectRotY, 0, 1, 0); + glRotatef(objectRotX, 1, 0, 0); + if (useHighRes) { + switch (drawObj) { + case 0: + drawSphere(64, 64, 0.8); + break; + case 1: + drawCylinder(32, 64, 1.0, 0.4); + break; + case 2: + drawTorus(64, 64, 0.6, 0.2); + break; + default: + break; + } + } else { + switch (drawObj) { + case 0: + drawSphere(16, 32, 0.8); + break; + case 1: + drawCylinder(6, 16, 1.0, 0.4); + break; + case 2: + drawTorus(32, 16, 0.6, 0.2); + break; + default: + break; + } + } + glPopMatrix(); + + if (useSpecularTexture) { + /* pass two */ + if (!useLighting) { + glColor3f(1.0, 1.0, 1.0); + } + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + setMaterial(MAT_SPECULAR_TEXTURE_ONLY); + glPushMatrix(); + glRotatef(objectRotY, 0, 1, 0); + glRotatef(objectRotX, 1, 0, 0); + if (useHighRes) { + switch (drawObj) { + case 0: + drawSphere(64, 64, 0.8); + break; + case 1: + drawCylinder(32, 64, 1.0, 0.4); + break; + case 2: + drawTorus(64, 64, 0.6, 0.2); + break; + default: + break; + } + } else { + switch (drawObj) { + case 0: + drawSphere(16, 32, 0.8); + break; + case 1: + drawCylinder(6, 16, 1.0, 0.4); + break; + case 2: + drawTorus(32, 16, 0.6, 0.2); + break; + default: + break; + } + } + glPopMatrix(); + } + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); +} + +void +checkErrors(void) +{ + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); + } +} + +void +usage(char *name) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "usage: %s [ options ]\n", name); + fprintf(stderr, "\n"); + fprintf(stderr, " Options:\n"); + fprintf(stderr, " none\n"); + fprintf(stderr, "\n"); +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'l' - toggle lighting\n"); + printf("'o' - switch objects\n"); + printf("'r' - toggle resolution\n"); + printf("'s' - toggle two pass lighting\n"); + printf("'t' - toggle texturing\n"); + printf("left mouse - move object\n"); + printf("middle mouse - move light\n"); +} + +void +motion(int x, int y) +{ + if (moveLight || moveObject) { + GLfloat dx = (y - cury) * 360.0 / height; + GLfloat dy = (x - curx) * 360.0 / width; + if (moveLight) { + lightRotX += dx; + if (lightRotX > 360) + lightRotX -= 360; + if (lightRotX < 0) + lightRotX += 360; + lightRotY += dy; + if (lightRotY > 360) + lightRotY -= 360; + if (lightRotY < 0) + lightRotY += 360; + needsLightUpdate = GL_TRUE; + } else if (moveObject) { + objectRotX += dx; + if (objectRotX > 360) + objectRotX -= 360; + if (objectRotX < 0) + objectRotX += 360; + objectRotY += dy; + if (objectRotY > 360) + objectRotY -= 360; + if (objectRotY < 0) + objectRotY += 360; + } + curx = x; + cury = y; + } + glutPostRedisplay(); +} + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + moveObject = GL_TRUE; + motion(curx = x, cury = y); + break; + case GLUT_MIDDLE_BUTTON: + moveLight = GL_TRUE; + motion(curx = x, cury = y); + break; + } + } else if (state == GLUT_UP) { + switch (button) { + case GLUT_LEFT_BUTTON: + moveObject = GL_FALSE; + break; + case GLUT_MIDDLE_BUTTON: + moveLight = GL_FALSE; + break; + } + } +} + +void +display(void) +{ + if (useSpecularTexture && needsLightUpdate) { + setMaterial(MAT_GEN_SPECULAR_TEXTURE); + needsLightUpdate = GL_FALSE; + } + redraw(); + glFlush(); + glutSwapBuffers(); + checkErrors(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, width = w, height = h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'h': + help(); + break; + case ' ': + break; + case 'l': + useLighting = !useLighting; + break; + case 's': + useSpecularTexture = !useSpecularTexture; + needsLightUpdate = GL_TRUE; + break; + case 't': + useTexture = !useTexture; + break; + case 'r': + useHighRes = !useHighRes; + break; + case 'o': + ++drawObj; + if (drawObj > maxObj) + drawObj = 0; + break; + case '\033': + exit(0); + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +domenu(int value) +{ + key((unsigned char) value, 0, 0); +} + +int +main(int argc, char **argv) +{ + int i; + + glutInit(&argc, argv); + glutInitWindowSize(width = 300, height = 300); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); + + for (i = 1; i < argc; ++i) { + usage(argv[0]); + exit(1); + } + win = glutCreateWindow("envphong"); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutCreateMenu(domenu); + glutAddMenuEntry("Toggle lighting", 'l'); + glutAddMenuEntry("Toggle checker texture", 't'); + glutAddMenuEntry("Toggle two-pass textured specular", 's'); + glutAddMenuEntry("Toggle object resolution", 'r'); + glutAddMenuEntry("Switch object", 'o'); + glutAddMenuEntry("Print help", 'h'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + initialize(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/envphong.dsp b/lib/glut-3.7.6/progs/advanced/envphong.dsp new file mode 100644 index 0000000000..df4a2d73a3 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/envphong.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="envphong" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=envphong - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "envphong.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "envphong.mak" CFG="envphong - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "envphong - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "envphong - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "envphong - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "envphong - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "envphong - Win32 Release" +# Name "envphong - Win32 Debug" +# Begin Source File + +SOURCE=.\envphong.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/field.c b/lib/glut-3.7.6/progs/advanced/field.c new file mode 100644 index 0000000000..1019bd5699 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/field.c @@ -0,0 +1,258 @@ + +/* field.c - by Tom McReynolds, SGI */ + +/* Using the accumulation buffer for depth of field (camera focus blur). */ + +#include +#include +#include + +const GLdouble FRUSTDIM = 100.f; +const GLdouble FRUSTNEAR = 320.f; +const GLdouble FRUSTFAR = 660.f; + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {SPHERE = 1, CONE}; + +void +render(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -640.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -640.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -640.f); + glVertex3f(-100.f, 100.f, -640.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f( 100.f, -100.f, -640.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -640.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -640.f); + glVertex3f( 100.f, -100.f, -640.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f(-100.f, 100.f, -640.f); + glEnd(); + + + glPushMatrix(); + glTranslatef(-80.f, -60.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -600.f); + glCallList(CONE); + glPopMatrix(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + +enum {NONE, FIELD}; + +int rendermode = NONE; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + +GLdouble focus = 420.; + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + int i, j; + int min, max; + int count; + GLfloat scale, dx, dy; + + switch(rendermode) { + case NONE: + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); + glMatrixMode(GL_MODELVIEW); + render(); + break; + case FIELD: + min = -2; + max = -min + 1; + count = -2 * min + 1; + count *= count; + + scale = 2.f; + + glClear(GL_ACCUM_BUFFER_BIT); + + for(j = min; j < max; j++) { + for(i = min; i < max; i++) { + dx = scale * i * FRUSTNEAR/focus; + dy = scale * j * FRUSTNEAR/focus; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM + dx, + FRUSTDIM + dx, + -FRUSTDIM + dy, + FRUSTDIM + dy, + FRUSTNEAR, + FRUSTFAR); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(scale * i, scale * j, 0.f); + render(); + glAccum(GL_ACCUM, 1.f/count); + } + } + glAccum(GL_RETURN, 1.f); + break; + } + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); + (void)glutCreateWindow("depth of field"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("Normal", NONE); + glutAddMenuEntry("Depth of Field", FIELD); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + diff --git a/lib/glut-3.7.6/progs/advanced/field.dsp b/lib/glut-3.7.6/progs/advanced/field.dsp new file mode 100644 index 0000000000..df5cd253fa --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/field.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="field" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=field - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "field.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "field.mak" CFG="field - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "field - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "field - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "field - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "field - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "field - Win32 Release" +# Name "field - Win32 Debug" +# Begin Source File + +SOURCE=.\field.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/genmipmap.c b/lib/glut-3.7.6/progs/advanced/genmipmap.c new file mode 100644 index 0000000000..4eb49765c9 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/genmipmap.c @@ -0,0 +1,192 @@ + +/* genmipmap.c - by David Blythe, SGI */ + +/* Example of how to generate texture mipmap levels with the + accumulation buffer. */ + +/* Usage example: genmipmap [file.rgb] */ + +#include +#include +#include +#include +#include "texture.h" + +static int w = 512, h = 512; +static int pause; + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, 0, h, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void +init_textures(char *filename) +{ + unsigned *buf; + int width, height, components; + + if (filename) { + buf = read_texture(filename, &width, &height, &components); + if (buf == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(1); + } else { + printf("%d x %d texture loaded\n", width, height); + } + } else { + int i, j; + GLubyte *p; + components = 4; + width = height = 512; + buf = (unsigned *) malloc(width * height * sizeof(unsigned)); + p = (GLubyte *) buf; + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + if (i & 1) + p[4 * (i + j * width) + 0] = 0xff; + else + p[4 * (i + j * width) + 1] = 0xff; + if (j & 1) + p[4 * (i + j * width) + 2] = 0xff; + } + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + 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, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + buf); + free(buf); +} + +void +init(char *filename) +{ + glEnable(GL_TEXTURE_2D); + init_textures(filename); +} + +void +draw_rect(int w, int h) +{ + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(0, 0); + glTexCoord2f(1, 0); + glVertex2f(w, 0); + glTexCoord2f(1, 1); + glVertex2f(w, h); + glTexCoord2f(0, 1); + glVertex2f(0, h); + glEnd(); +} + +void +stop(void) +{ + if (pause) { + printf("? "); + fflush(stdout); + getchar(); + } +} + +void +acfilter(int width, int height) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + glMatrixMode(GL_TEXTURE); + + if (pause) { + draw_rect(width, height); + stop(); + glClear(GL_COLOR_BUFFER_BIT); + } + draw_rect(width / 2, height / 2); + stop(); + glAccum(GL_ACCUM, 0.25); + + glTranslatef(1.0 / width, 0, 0); + draw_rect(width / 2, height / 2); + stop(); + glAccum(GL_ACCUM, 0.25); + + glLoadIdentity(); + glTranslatef(0, 1.0 / height, 0); + draw_rect(width / 2, height / 2); + stop(); + glAccum(GL_ACCUM, 0.25); + + glLoadIdentity(); + glTranslatef(1.0 / width, 1.0 / height, 0); + draw_rect(width / 2, height / 2); + stop(); + glAccum(GL_ACCUM, 0.25); + + glAccum(GL_RETURN, 1.0); + glMatrixMode(GL_MODELVIEW); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + draw_rect(w, h); + acfilter(w, h); + glFlush(); +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'s' - toggle single step mode\n"); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'h': + help(); + break; + case 's': + pause ^= 1; + break; + case '\033': + exit(0); + break; + default: + glutPostRedisplay(); + } +} + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(w, h); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM); + (void) glutCreateWindow("genmipmap"); + if (argc > 1) + init(argv[1]); + else + init(0); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/genmipmap.dsp b/lib/glut-3.7.6/progs/advanced/genmipmap.dsp new file mode 100644 index 0000000000..81f0a44ca7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/genmipmap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="genmipmap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=genmipmap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "genmipmap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "genmipmap.mak" CFG="genmipmap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "genmipmap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "genmipmap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "genmipmap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "genmipmap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "genmipmap - Win32 Release" +# Name "genmipmap - Win32 Debug" +# Begin Source File + +SOURCE=.\genmipmap.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/haloed.c b/lib/glut-3.7.6/progs/advanced/haloed.c new file mode 100644 index 0000000000..211b47cc66 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/haloed.c @@ -0,0 +1,274 @@ + +/* haloed.c - by Tom McReynolds, SGI */ + +/* Draw haloed lines. */ + +#include +#include +#include +#include + +enum {CONE = 1}; + +/* Draw a cone */ +void +cone(void) +{ + glPushMatrix(); + glTranslatef(0.f, 0.f, -30.f); + glCallList(CONE); + glPopMatrix(); +} + +/* Draw a torus */ +void +torus(void) +{ + glutSolidTorus(10., 20., 16, 16); +} + +enum {FILL, WIRE, HALO, OFFSET_HALO, BACKFACE_HALO, TOGGLE}; + +int rendermode = FILL; + +void (*curobj)(void) = cone; + +void +menu(int mode) +{ + if(mode == TOGGLE) + if(curobj == cone) + curobj = torus; + else + curobj = cone; + else + rendermode = mode; + glutPostRedisplay(); +} + +int winWidth = 512; +int winHeight = 512; + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glViewport(0, 0, wid, ht); + winWidth = wid; + winHeight = ht; +} + +GLfloat viewangle; + + +void +redraw(void) +{ + /* clear stencil each time */ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + glRotatef(viewangle, 0.f, 1.f, 0.f); + + switch(rendermode) { + case FILL: + curobj(); + break; + case WIRE: + glDisable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glLineWidth(3.f); + curobj(); + glLineWidth(1.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_DEPTH_TEST); + break; + case HALO: + /* draw wide lines into depth buffer */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glLineWidth(9.f); + curobj(); + + /* draw narrow lines into color with depth test on */ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glLineWidth(3.f); + glDepthFunc(GL_LEQUAL); + curobj(); + glDepthFunc(GL_LESS); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + break; + case OFFSET_HALO: + /* draw wide lines into depth buffer */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glLineWidth(9.f); + curobj(); + + /* draw narrow lines into color with depth test on */ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glLineWidth(3.f); +#if GL_EXT_polygon_offset + glEnable(GL_POLYGON_OFFSET_EXT); + glPolygonOffsetEXT(-.5f, -.02f); +#endif + glDepthFunc(GL_LEQUAL); + curobj(); + glDepthFunc(GL_LESS); +#if GL_EXT_polygon_offset + glDisable(GL_POLYGON_OFFSET_EXT); +#endif + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + break; + case BACKFACE_HALO: /* cheat: only works on single non-intersecting obj */ + /* draw wide lines into depth buffer */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glLineWidth(3.f); + + curobj(); + + /* mask out borders of objects with wide gray lines */ + glCullFace(GL_BACK); + glLineWidth(9.f); + glDisable(GL_LIGHTING); + glColor3f(.7f, .7f, .7f); + + curobj(); + + /* draw front face narrow lines without depth test */ + glEnable(GL_LIGHTING); + glLineWidth(3.f); + glDisable(GL_DEPTH_TEST); + + curobj(); + + /* clean up */ + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glLineWidth(1.f); + break; + } + + glPopMatrix(); + glutSwapBuffers(); + + if(glGetError()) + printf("oops! Bad gl command!\n"); +} + +/* animate scene by rotating */ +enum {ANIM_LEFT, ANIM_RIGHT}; +int animDirection = ANIM_LEFT; + +void anim(void) +{ + if(animDirection == ANIM_LEFT) + viewangle -= 1.f; + else + viewangle += 1.f; + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +/* special keys, like array and F keys */ +void special(int key, int x, int y) +{ + switch(key) { + case GLUT_KEY_LEFT: + glutIdleFunc(anim); + animDirection = ANIM_LEFT; + break; + case GLUT_KEY_RIGHT: + glutIdleFunc(anim); + animDirection = ANIM_RIGHT; + break; + case GLUT_KEY_UP: + case GLUT_KEY_DOWN: + glutIdleFunc(0); + break; + } +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch(key) { + case 'a': + viewangle -= 10.f; + glutPostRedisplay(); + break; + case 's': + viewangle += 10.f; + glutPostRedisplay(); + break; + case '\033': + exit(0); + } +} + + +int picked_object; +int xpos = 0, ypos = 0; +int newxpos, newypos; +int startx, starty; + +int +main(int argc, char **argv) +{ + static GLfloat lightpos[] = {25.f, 50.f, -50.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_STENCIL|GLUT_DEPTH|GLUT_DOUBLE); + (void)glutCreateWindow("haloed lines"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + + glutCreateMenu(menu); + glutAddMenuEntry("Filled Object", FILL); + glutAddMenuEntry("Wireframe", WIRE); + glutAddMenuEntry("Haloed Wireframe", HALO); + glutAddMenuEntry("Pgon Offset Haloed Wireframe", OFFSET_HALO); + glutAddMenuEntry("Backface Haloed Wireframe", BACKFACE_HALO); + glutAddMenuEntry("Toggle Object", TOGGLE); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glClearColor(.7f, .7f, .7f, .7f); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + + /* make display list for cone; for efficiency */ + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 25., 8, 1); + gluCylinder(cone, 25., 0., 60., 8, 8); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glMatrixMode(GL_PROJECTION); + glOrtho(-50., 50., -50., 50., -50., 50.); + glMatrixMode(GL_MODELVIEW); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/haloed.dsp b/lib/glut-3.7.6/progs/advanced/haloed.dsp new file mode 100644 index 0000000000..af24378b1f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/haloed.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="haloed" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=haloed - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "haloed.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "haloed.mak" CFG="haloed - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "haloed - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "haloed - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "haloed - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "haloed - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "haloed - Win32 Release" +# Name "haloed - Win32 Debug" +# Begin Source File + +SOURCE=.\haloed.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/hello2rts.c b/lib/glut-3.7.6/progs/advanced/hello2rts.c new file mode 100644 index 0000000000..6bc26c6011 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/hello2rts.c @@ -0,0 +1,636 @@ + +/* Copyright (c) Mark J. Kilgard, 1997, 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 code demonstrates use of the OpenGL Real-time Shadowing (RTS) + routines. The program renders two objects with two light sources in a + scene with several other walls and curved surfaces. Objects cast shadows + on the walls and curved surfaces as well as each other. The shadowing + objects spin. See the rts.c and rtshadow.h source code for more details. */ + +#include +#include +#include +#include +#include + +#ifdef GLU_VERSION_1_2 + +#include "rtshadow.h" + +extern GLuint makeNVidiaLogo(GLuint dlistBase); + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +enum { + X, Y, Z +}; + +enum { + DL_NONE, DL_TORUS, DL_CUBE, DL_DOUBLE_TORUS, DL_SPHERE, DL_NVIDIA_LOGO +}; + +enum { + M_TORUS, M_CUBE, M_DOUBLE_TORUS, M_NVIDIA_LOGO, + M_NORMAL_VIEW, M_LIGHT1_VIEW, M_LIGHT2_VIEW, + M_START_MOTION, M_ROTATING, + M_TWO_BIT_STENCIL, M_ALL_STENCIL, + M_RENDER_SILHOUETTE, + M_ENABLE_STENCIL_HACK, M_DISABLE_STENCIL_HACK +}; + +#define OBJECT_1 0x8000 +#define OBJECT_2 0x4000 + +int fullscreen = 0, forceStencilHack = 0; +int lightView = M_NORMAL_VIEW; +int rotate1 = 1, rotate2 = 1; + +RTSscene *scene; +RTSlight *light; +RTSlight *light2; +RTSobject *object, *object2; + +GLfloat eyePos[3] = +{0.0, 0.0, 10.0}; +GLfloat lightPos[4] = +{-3.9, 5.0, 1.0, 1.0}; +GLfloat lightPos2[4] = +{4.0, 5.0, 0.0, 1.0}; +GLfloat objectPos[3] = +{-1.0, 1.0, 0.0}; +GLfloat objectPos2[3] = +{2.0, -2.0, 0.0}; + +GLfloat pink[4] = +{0.75, 0.5, 0.5, 1.0}; +GLfloat greeny[4] = +{0.5, 0.75, 0.5, 1.0}; + +int shape1 = M_TORUS, shape2 = M_CUBE; +int renderSilhouette1, renderSilhouette2; + +GLfloat angle1 = 75.0; +GLfloat angle2 = 75.0; +GLfloat viewAngle = 0.0; +int moving, begin; + +void +renderBasicObject(int shape) +{ + switch (shape) { + case M_TORUS: + glCallList(DL_TORUS); + break; + case M_CUBE: + glCallList(DL_CUBE); + break; + case M_DOUBLE_TORUS: + glCallList(DL_DOUBLE_TORUS); + break; + case M_NVIDIA_LOGO: + glCallList(DL_NVIDIA_LOGO); + break; + } +} + +/* ARGSUSED */ +void +renderObject(void *data) +{ + glPushMatrix(); + glTranslatef(objectPos[X], objectPos[Y], objectPos[Z]); + glRotatef(angle1, 1.0, 1.2, 0.0); + renderBasicObject(shape1); + glPopMatrix(); +} + +/* ARGSUSED */ +void +renderObject2(void *data) +{ + glPushMatrix(); + glTranslatef(objectPos2[X], objectPos2[Y], objectPos2[Z]); + glRotatef(-angle2, 1.3, 0.0, 1.0); + renderBasicObject(shape2); + glPopMatrix(); +} + +/* ARGSUSED1 */ +void +renderScene(GLenum castingLight, void *sceneData, RTSscene * scene) +{ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + switch (lightView) { + case M_NORMAL_VIEW: + gluLookAt(eyePos[X], eyePos[Y], eyePos[Z], + objectPos[X], objectPos[Y], objectPos[Z], + 0.0, 1.0, 0.0); + break; + case M_LIGHT1_VIEW: + gluLookAt(lightPos[X], lightPos[Y], lightPos[Z], + objectPos[X], objectPos[Y], objectPos[Z], + 0.0, 1.0, 0.0); + break; + case M_LIGHT2_VIEW: + gluLookAt(lightPos2[X], lightPos2[Y], lightPos2[Z], + objectPos[X], objectPos[Y], objectPos[Z], + 0.0, 1.0, 0.0); + break; + } + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glLightfv(GL_LIGHT1, GL_POSITION, lightPos2); + + glEnable(GL_NORMALIZE); + glPushMatrix(); + glTranslatef(0.0, 8.0, -5.0); + glScalef(3.0, 3.0, 3.0); + glCallList(DL_SPHERE); + glPopMatrix(); + glDisable(GL_NORMALIZE); + + glPushMatrix(); + glTranslatef(-5.0, 0.0, 0.0); + glCallList(DL_SPHERE); + glPopMatrix(); + + glBegin(GL_QUADS); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(-7.5, -7.5, -7.0); + glVertex3f(7.5, -7.5, -7.0); + glVertex3f(7.5, 7.5, -7.0); + glVertex3f(-7.5, 7.5, -7.0); + + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(5.0, -5.0, -5.0); + glVertex3f(5.0, -5.0, 5.0); + glVertex3f(5.0, 5.0, 5.0); + glVertex3f(5.0, 5.0, -5.0); + + glNormal3f(0.0, 1.0, 0.0); + glVertex3f(-5.0, -5.0, -5.0); + glVertex3f(-5.0, -5.0, 5.0); + glVertex3f(5.0, -5.0, 5.0); + glVertex3f(5.0, -5.0, -5.0); + + glEnd(); + + if (castingLight == GL_NONE) { + /* Rendering that is not affected by lighting should be drawn only once. + The time to render it is when no light is casting. */ + glDisable(GL_LIGHTING); + + glColor3fv(pink); + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + glutSolidSphere(0.3, 8, 8); + glPopMatrix(); + + glColor3fv(greeny); + glPushMatrix(); + glTranslatef(lightPos2[X], lightPos2[Y], lightPos2[Z]); + glutSolidSphere(0.3, 8, 8); + glPopMatrix(); + + glEnable(GL_LIGHTING); + } + renderObject(NULL); + renderObject2(NULL); +} + +void +reshape(int w, int h) +{ + GLfloat wf = w, hf = h; + + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(70.0, wf/hf, 0.5, 30.0); + glMatrixMode(GL_MODELVIEW); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + rtsRenderScene(scene, RTS_USE_SHADOWS); + if (renderSilhouette1) { + glColor3f(0.0, 1.0, 0.0); + rtsRenderSilhouette(scene, light, object); + glColor3f(0.0, 0.0, 1.0); + rtsRenderSilhouette(scene, light2, object); + } + if (renderSilhouette2) { + glColor3f(1.0, 0.0, 0.0); + rtsRenderSilhouette(scene, light, object2); + glColor3f(1.0, 1.0, 0.0); + rtsRenderSilhouette(scene, light2, object2); + } + glutSwapBuffers(); +} + +void +idle(void) +{ + if (rotate1) { + angle1 += 10; + rtsUpdateObjectShape(object); + } + if (rotate2) { + angle2 += 10; + rtsUpdateObjectShape(object2); + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int c, int x, int y) +{ + switch (c) { + case GLUT_KEY_UP: + lightPos[Y] += 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_DOWN: + lightPos[Y] -= 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_RIGHT: + lightPos[X] += 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_LEFT: + lightPos[X] -= 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_PAGE_UP: + lightPos[Z] += 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_PAGE_DOWN: + lightPos[Z] -= 0.5; + rtsUpdateLightPos(light, lightPos); + break; + case GLUT_KEY_HOME: + angle1 += 15; + angle2 += 15; + rtsUpdateObjectShape(object); + rtsUpdateObjectShape(object2); + break; + case GLUT_KEY_END: + angle1 -= 15; + angle2 -= 15; + rtsUpdateObjectShape(object); + rtsUpdateObjectShape(object2); + break; + case GLUT_KEY_F1: + lightView = !lightView; + break; + } + glutPostRedisplay(); +} + +void +updateIdleCallback(void) +{ + if (rotate1 || rotate2) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } +} + +/* ARGSUSED1 */ +void +menuHandler(int value) +{ + switch (value) { + case OBJECT_1 | M_TORUS: + case OBJECT_1 | M_CUBE: + case OBJECT_1 | M_DOUBLE_TORUS: + case OBJECT_1 | M_NVIDIA_LOGO: + shape1 = value & ~OBJECT_1; + rtsUpdateObjectShape(object); + glutPostRedisplay(); + break; + case OBJECT_2 | M_TORUS: + case OBJECT_2 | M_CUBE: + case OBJECT_2 | M_DOUBLE_TORUS: + case OBJECT_2 | M_NVIDIA_LOGO: + shape2 = value & ~OBJECT_2; + rtsUpdateObjectShape(object2); + glutPostRedisplay(); + break; + case M_NORMAL_VIEW: + case M_LIGHT1_VIEW: + case M_LIGHT2_VIEW: + lightView = value; + glutPostRedisplay(); + break; + case M_START_MOTION: + rotate1 = 1; + rotate2 = 1; + glutIdleFunc(idle); + break; + case OBJECT_1 | M_ROTATING: + rotate1 = !rotate1; + updateIdleCallback(); + break; + case OBJECT_2 | M_ROTATING: + rotate2 = !rotate2; + updateIdleCallback(); + break; + case M_ALL_STENCIL: + rtsUpdateUsableStencilBits(scene, ~0); + glutPostRedisplay(); + break; + case M_TWO_BIT_STENCIL: + rtsUpdateUsableStencilBits(scene, 0x3); + glutPostRedisplay(); + break; + case OBJECT_1 | M_RENDER_SILHOUETTE: + renderSilhouette1 = !renderSilhouette1; + glutPostRedisplay(); + break; + case OBJECT_2 | M_RENDER_SILHOUETTE: + renderSilhouette2 = !renderSilhouette2; + glutPostRedisplay(); + break; + case M_ENABLE_STENCIL_HACK: + rtsStencilRenderingInvariantHack(scene, GL_TRUE); + glutPostRedisplay(); + break; + case M_DISABLE_STENCIL_HACK: + rtsStencilRenderingInvariantHack(scene, GL_FALSE); + glutPostRedisplay(); + break; + } +} + +void +keyboard(unsigned char c, int x, int y) +{ + switch (c) { + case 27: + exit(0); + /* NOTREACHED */ + break; + case ' ': + if (rotate1 || rotate2) { + glutIdleFunc(NULL); + rotate1 = 0; + rotate2 = 0; + } else { + glutIdleFunc(idle); + rotate1 = 1; + rotate2 = 1; + } + break; + case '1': + menuHandler(OBJECT_1 | M_TORUS); + break; + case '2': + menuHandler(OBJECT_1 | M_CUBE); + break; + case '3': + menuHandler(OBJECT_1 | M_DOUBLE_TORUS); + break; + case '4': + menuHandler(OBJECT_1 | M_NVIDIA_LOGO); + break; + case '5': + menuHandler(OBJECT_2 | M_TORUS); + break; + case '6': + menuHandler(OBJECT_2 | M_CUBE); + break; + case '7': + menuHandler(OBJECT_2 | M_DOUBLE_TORUS); + break; + case '8': + menuHandler(OBJECT_2 | M_NVIDIA_LOGO); + break; + } +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + updateIdleCallback(); + else + glutIdleFunc(NULL); +} + +void +initMenu(void) +{ + glutCreateMenu(menuHandler); + + glutAddMenuEntry("1 Torus", OBJECT_1 | M_TORUS); + glutAddMenuEntry("1 Cube", OBJECT_1 | M_CUBE); + glutAddMenuEntry("1 Double torus", OBJECT_1 | M_DOUBLE_TORUS); + glutAddMenuEntry("1 NVIDIA logo", OBJECT_1 | M_NVIDIA_LOGO); + + glutAddMenuEntry("2 Torus", OBJECT_2 | M_TORUS); + glutAddMenuEntry("2 Cube", OBJECT_2 | M_CUBE); + glutAddMenuEntry("2 Double torus", OBJECT_2 | M_DOUBLE_TORUS); + glutAddMenuEntry("2 NVIDIA logo", OBJECT_2 | M_NVIDIA_LOGO); + + glutAddMenuEntry("Normal view", M_NORMAL_VIEW); + glutAddMenuEntry("View from light 1", M_LIGHT1_VIEW); + glutAddMenuEntry("View from light 2", M_LIGHT2_VIEW); + + glutAddMenuEntry("Start motion", M_START_MOTION); + glutAddMenuEntry("1 Toggle rotating", OBJECT_1 | M_ROTATING); + glutAddMenuEntry("2 Toggle rotating", OBJECT_2 | M_ROTATING); + + glutAddMenuEntry("Use all stencil", M_ALL_STENCIL); + glutAddMenuEntry("Use only 2 bits stencil", M_TWO_BIT_STENCIL); + + glutAddMenuEntry("1 Toggle silhouette", OBJECT_1 | M_RENDER_SILHOUETTE); + glutAddMenuEntry("2 Toggle silhouette", OBJECT_2 | M_RENDER_SILHOUETTE); + + glutAddMenuEntry("Enable stencil hack", M_ENABLE_STENCIL_HACK); + glutAddMenuEntry("Disable stencil hack", M_DISABLE_STENCIL_HACK); + + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +/* ARGSUSED2 */ +void +mouse(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + moving = 1; + begin = x; + } + if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + moving = 0; + } +} + +/* ARGSUSED1 */ +void +motion(int x, int y) +{ + if (moving) { + viewAngle = viewAngle + (x - begin); + eyePos[X] = sin(viewAngle * M_PI / 180.0) * 10.0; + eyePos[Z] = cos(viewAngle * M_PI / 180.0) * 10.0; + begin = x; + glutPostRedisplay(); + } +} + +/* XXX RIVA 128 board vendors may change their GL_VENDOR + and GL_RENDERER strings. */ +int +needsStencilRenderingInvariantHack(void) +{ + const char *renderer; + GLint bits; + + renderer = glGetString(GL_RENDERER); + /* Stencil rendering on RIVA 128 and RIVA 128 ZX + is not invariant with stencil-disabled rendering + in 16-bit hardware accelerated mode. */ + if (!strncmp("RIVA 128", renderer, 8)) { + glGetIntegerv(GL_INDEX_BITS, &bits); + return bits == 16; + } + /* Stencil rendering on RIVA 128 and RIVA 128 ZX + is not invariant with stencil-disabled rendering + in 16-bit hardware accelerated mode. 32-bit mode + is invariant (and hardware accelerated though!). */ + if (!strncmp("RIVA TNT", renderer, 8)) { + glGetIntegerv(GL_INDEX_BITS, &bits); + return bits == 16; + } + return 1; +} + +void +parseArgs(int argc, char **argv) +{ + int i; + + for (i=1; i=2 rgb depth samples"); + glutInitDisplayString("stencil>=2 rgb double depth samples"); + glutInit(&argc, argv); + + parseArgs(argc, argv); + + if (fullscreen) { + glutGameModeString("640x480:32@60"); + glutEnterGameMode(); + } else { + glutCreateWindow("Hello to Real Time Shadows"); + } + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutSpecialFunc(special); + glutKeyboardFunc(keyboard); + glutVisibilityFunc(visible); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + /* 0xffffffff means "use as much stencil as is available". */ + scene = rtsCreateScene(eyePos, 0xffffffff, renderScene, NULL); + + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, pink); + light = rtsCreateLight(GL_LIGHT0, lightPos, 1000.0); + glLightfv(GL_LIGHT1, GL_POSITION, lightPos2); + glLightfv(GL_LIGHT1, GL_DIFFUSE, greeny); + light2 = rtsCreateLight(GL_LIGHT1, lightPos2, 1000.0); + + object = rtsCreateObject(objectPos, 1.0, renderObject, NULL, 100); + object2 = rtsCreateObject(objectPos2, 1.0, renderObject2, NULL, 100); + + rtsAddLightToScene(scene, light); + rtsAddObjectToLight(light, object); + rtsAddObjectToLight(light, object2); + + rtsAddLightToScene(scene, light2); + rtsAddObjectToLight(light2, object); + rtsAddObjectToLight(light2, object2); + + if (forceStencilHack || needsStencilRenderingInvariantHack()) { + /* RIVA 128 and RIVA 128 ZX lack hardware stencil + support and the hardware rasterization path + (non-stenciled) and the software rasterization + path (with stenciling enabled) do not meet the + invariants. */ + rtsStencilRenderingInvariantHack(scene, GL_TRUE); + } + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + if (!fullscreen) { + initMenu(); + } + + glNewList(DL_TORUS, GL_COMPILE); + glutSolidTorus(0.2, 0.8, 10, 10); + glEndList(); + + glNewList(DL_CUBE, GL_COMPILE); + glutSolidCube(1.0); + glEndList(); + + glNewList(DL_DOUBLE_TORUS, GL_COMPILE); + glCallList(DL_TORUS); + glRotatef(90.0, 0.0, 1.0, 0.0); + glCallList(DL_TORUS); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glEndList(); + + glNewList(DL_SPHERE, GL_COMPILE); + glutSolidSphere(1.5, 20, 20); + glEndList(); + + makeNVidiaLogo(1000); + glNewList(DL_NVIDIA_LOGO, GL_COMPILE); + glPushMatrix(); + glScalef(.25, .25, .25); + glEnable(GL_NORMALIZE); + glCallList(1000); + glDisable(GL_NORMALIZE); + glPopMatrix(); + glEndList(); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +#else +int main(int argc, char** argv) +{ + fprintf(stderr, "This program requires 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 /* GLU_VERSION_1_2 */ diff --git a/lib/glut-3.7.6/progs/advanced/hello2rts.dsp b/lib/glut-3.7.6/progs/advanced/hello2rts.dsp new file mode 100644 index 0000000000..75628fc210 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/hello2rts.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="hello2rts" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=hello2rts - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "hello2rts.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "hello2rts.mak" CFG="hello2rts - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "hello2rts - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "hello2rts - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "hello2rts - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "hello2rts - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "hello2rts - Win32 Release" +# Name "hello2rts - Win32 Debug" +# Begin Source File + +SOURCE=.\hello2rts.c +# End Source File +# Begin Source File + +SOURCE=.\nvidia_logo.c +# End Source File +# Begin Source File + +SOURCE=.\rts.c +# End Source File +# Begin Source File + +SOURCE=.\rtshadow.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/hiddenline.c b/lib/glut-3.7.6/progs/advanced/hiddenline.c new file mode 100644 index 0000000000..1e04c9c524 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/hiddenline.c @@ -0,0 +1,335 @@ + +/* hiddenline.c - by Tom McReynolds, SGI */ + +/* Line Rendering: Hidden line techniques */ + +#include +#include +#include + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {FILL, WIRE, BACKFACE, FRONTLINES, DEPTH, STENCIL, FAT_STENCIL}; + +int rendermode = FILL; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + + +/* geometry display list names */ +enum {SPHERE = 1, CONE, FLOOR, WALLS}; + +void +drawscene(void) +{ + glEnable(GL_TEXTURE_2D); + glCallList(FLOOR); + glDisable(GL_TEXTURE_2D); + + glCallList(WALLS); + + glPushMatrix(); + glTranslatef(-40.f, -50.f, -400.f); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(20.f, -100.f, -420.f); + glCallList(CONE); + glPopMatrix(); +} + +/* do hidden line removal on an object in the scene */ +/* use display lists to represent objects */ +void +hiddenlineobj(GLint dlist) +{ + GLboolean tex2d; + + glGetBooleanv(GL_TEXTURE_2D, &tex2d); + if(tex2d) + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glColor3f(.7f, .7f, .7f); + + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0); /* clear stencil for this object */ + + glCallList(dlist); /* draw filled object in depth buffer */ + + glEnable(GL_LIGHTING); + if(tex2d) + glEnable(GL_TEXTURE_2D); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); /* turn off color */ + glDisable(GL_DEPTH_TEST); /* turn off depth */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + glCallList(dlist); /* draw lines into stencil buffer */ + + glStencilFunc(GL_EQUAL, 1 , 1); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glCallList(dlist); /* use lines in stencil to stencil out solid pgons */ + + /* clean up state */ + glDisable(GL_STENCIL_TEST); + glDepthFunc(GL_LESS); +} + +void +drawscenestencil(void) +{ + glEnable(GL_TEXTURE_2D); + hiddenlineobj(FLOOR); + glDisable(GL_TEXTURE_2D); + + hiddenlineobj(WALLS); + + glPushMatrix(); + glTranslatef(-40.f, -50.f, -400.f); + hiddenlineobj(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(20.f, -100.f, -420.f); + hiddenlineobj(CONE); + glPopMatrix(); +} + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + switch(rendermode) { + case FILL: + drawscene(); + break; + case WIRE: /* basic wireframe mode */ + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + drawscene(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case BACKFACE: /* use backface culling to clean things up */ + glEnable(GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + drawscene(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_CULL_FACE); + break; + case FRONTLINES: /* use polygon mode line on front, fill on back */ + glPolygonMode(GL_FRONT, GL_LINE); + drawscene(); + glPolygonMode(GL_FRONT, GL_FILL); + break; + case DEPTH: /* use depth buffer to remove hidden lines */ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + drawscene(); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDepthFunc(GL_LEQUAL); + drawscene(); + glDepthFunc(GL_LESS); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case STENCIL: /* use stencil to remove hidden lines */ + glEnable(GL_CULL_FACE); + drawscenestencil(); + glDisable(GL_CULL_FACE); + break; + case FAT_STENCIL: /* use stencil with fat lines to fix edges */ + glLineWidth(2.f); + glEnable(GL_CULL_FACE); + drawscenestencil(); + glDisable(GL_CULL_FACE); + glLineWidth(1.f); + break; + } + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + +const int TEXDIM = 256; + +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL); + (void)glutCreateWindow("hidden line removal survey"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("Solid Fill", FILL); + glutAddMenuEntry("Wireframe", WIRE); + glutAddMenuEntry("Backface Culling", BACKFACE); + glutAddMenuEntry("Frontface Lines", FRONTLINES); + glutAddMenuEntry("Depth Test", DEPTH); + glutAddMenuEntry("Stencil", STENCIL); + glutAddMenuEntry("Stencil: Fat Lines", FAT_STENCIL); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glClearColor(.7f, .7f, .7f, .7f); + + glCullFace(GL_BACK); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 50.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glPushMatrix(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 40., 20, 1); + gluCylinder(cone, 40., 0., 120., 20, 20); + glPopMatrix(); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glNewList(FLOOR, GL_COMPILE); + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + glEndList(); + + /* walls */ + + glNewList(WALLS, GL_COMPILE); + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glEndList(); + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + diff --git a/lib/glut-3.7.6/progs/advanced/hiddenline.dsp b/lib/glut-3.7.6/progs/advanced/hiddenline.dsp new file mode 100644 index 0000000000..ee1a591cfc --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/hiddenline.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="hiddenline" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=hiddenline - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "hiddenline.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "hiddenline.mak" CFG="hiddenline - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "hiddenline - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "hiddenline - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "hiddenline - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "hiddenline - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "hiddenline - Win32 Release" +# Name "hiddenline - Win32 Debug" +# Begin Source File + +SOURCE=.\hiddenline.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/imgproc.c b/lib/glut-3.7.6/progs/advanced/imgproc.c new file mode 100644 index 0000000000..771bb5263d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/imgproc.c @@ -0,0 +1,288 @@ + +/* imgproc.c - by David Blythe, SGI */ + +/* Examples of various image processing operations coded as OpenGL + accumulation buffer operations. This allows extremely fast + image processing on machines with hardware accumulation buffers + (RealityEngine, InfiniteReality, VGX). */ + +#include +#include +#include +#include +#include "texture.h" + +static unsigned *image, *null; +static int width, height, components; +static void (*func) (void); +static float alpha = 1.; +static float luma = .5; +static int reset = 1; +static int format = GL_RGBA; + +void +brighten(void) +{ + if (reset) { + memset(null, 0, width * height * sizeof *null); + reset = 0; + } + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image); + glAccum(GL_LOAD, alpha / 2.); + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null); + glAccum(GL_ACCUM, (1 - alpha) / 2.); + glAccum(GL_RETURN, 2.0); +} + +void +saturate(void) +{ + if (reset) { + memset(null, 0xff, width * height * sizeof *null); + reset = 0; + } + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image); + glAccum(GL_LOAD, alpha / 2.); + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null); + glAccum(GL_ACCUM, (1 - alpha) / 2.); + glAccum(GL_RETURN, 2.0); +} + +void +contrast(void) +{ + if (reset) { + memset(null, luma, width * height * sizeof *null); + reset = 0; + } + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image); + glAccum(GL_LOAD, alpha / 2.); + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null); + glAccum(GL_ACCUM, (1 - alpha) / 2.); + glAccum(GL_RETURN, 2.0); +} + +void +balance(void) +{ + if (reset) { + memset(null, luma, width * height * sizeof *null); + reset = 0; + } + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image); + glAccum(GL_LOAD, alpha / 2.); + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null); + glAccum(GL_ACCUM, (1 - alpha) / 2.); + glAccum(GL_RETURN, 2.0); +} + +void +sharpen(void) +{ + if (reset) { + gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image, + width / 4, height / 4, GL_UNSIGNED_BYTE, null); + gluScaleImage(format, width / 4, height / 4, GL_UNSIGNED_BYTE, null, + width, height, GL_UNSIGNED_BYTE, null); + reset = 0; + } + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, image); + glAccum(GL_LOAD, alpha / 2.); + glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, null); + glAccum(GL_ACCUM, (1 - alpha) / 2.); + glAccum(GL_RETURN, 2.0); +} + +void +set_brighten(void) +{ + func = brighten; + reset = 1; + printf("brighten\n"); +} + +void +set_saturate(void) +{ + func = saturate; + reset = 1; + printf("saturate\n"); +} + +void +set_contrast(void) +{ + func = contrast; + reset = 1; + printf("contrast\n"); +} + +void +set_balance(void) +{ + func = balance; + reset = 1; + printf("balance\n"); +} + +void +set_sharpen(void) +{ + func = sharpen; + reset = 1; + printf("sharpen\n"); +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'b' - brighten\n"); + printf("'s' - saturate\n"); + printf("'c' - contrast\n"); + printf("'z' - sharpen\n"); + printf("'a' - color balance\n"); + printf("left mouse - increase alpha\n"); + printf("middle mouse - decrease alpha\n"); +} + +void +init(char *filename) +{ + double l = 0; + int i; + + func = brighten; + + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(1); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components < 3 || components > 4) { + printf("must be RGB or RGBA image\n"); + exit(1); + } + } else { + int i, j; + components = 4; + width = height = 512; + image = (unsigned *) malloc(width * height * sizeof(unsigned)); + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + if (i & 1) + image[i + j * width] = 0xff; + else + image[i + j * width] = 0xff00; + if (j & 1) + image[i + j * width] |= 0xff0000; + } + + } + null = (unsigned *) malloc(width * height * sizeof *image); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glClearColor(.25, .25, .25, .25); + + /* compute luminance */ + for (i = 0; i < width * height; i++) { + GLubyte *p = (GLubyte *) (image + i); + double r = p[0] / 255.; + double g = p[1] / 255.; + double b = p[2] / 255.; + l += r * .3086 + g * .0820 + b * .114; + } + luma = l / (width * height); + printf("average luminance = %f\n", luma); +} + +void +display(void) +{ + printf("alpha = %f\n", alpha); + glClear(GL_COLOR_BUFFER_BIT); + (*func) (); + glutSwapBuffers(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0., (GLdouble) width, 0., (GLdouble) height, -1., 1.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'b': + set_brighten(); + break; + case 's': + set_saturate(); + break; + case 'c': + set_contrast(); + break; + case 'z': + set_sharpen(); + break; + case 'a': + set_balance(); + break; + case 'h': + help(); + break; + case '\033': + exit(0); + break; + default: + return; + } + glutPostRedisplay(); +} + +/* ARGSUSED2 */ +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + alpha += .1; + break; + case GLUT_MIDDLE_BUTTON: + alpha -= .1; + break; + case GLUT_RIGHT_BUTTON: + break; + } + } + glutPostRedisplay(); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_DOUBLE); + (void) glutCreateWindow("imgproc"); + init(argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/imgproc.dsp b/lib/glut-3.7.6/progs/advanced/imgproc.dsp new file mode 100644 index 0000000000..477c7a3a12 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/imgproc.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="imgproc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=imgproc - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "imgproc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "imgproc.mak" CFG="imgproc - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "imgproc - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "imgproc - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "imgproc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "imgproc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "imgproc - Win32 Release" +# Name "imgproc - Win32 Debug" +# Begin Source File + +SOURCE=.\imgproc.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/izoom.c b/lib/glut-3.7.6/progs/advanced/izoom.c new file mode 100644 index 0000000000..b0742dd32f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/izoom.c @@ -0,0 +1,671 @@ +/** + ** izoom- + ** Magnify or minify a picture with or without filtering. The + ** filtered method is one pass, uses 2-d convolution, and is optimized + ** by integer arithmetic and precomputation of filter coeffs. + ** + ** Paul Haeberli - 1988 + **/ +#include +#include +#include +#include +#include "izoom.h" + +#ifdef _WIN32 +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#endif + +typedef struct filtinteg { + float rad, min, max; + float *tab; +} filtinteg; + +float flerp(float f0, float f1, float p); + +#define GRIDTOFLOAT(pos,n) (((pos)+0.5)/(n)) +#define FLOATTOGRID(pos,n) ((pos)*(n)) +#define SHIFT 12 +#define ONE (1<rad) +#define FILTTABSIZE 250 + +static void makexmap(short *abuf, short *xmap[], int anx, int bnx); +static void setintrow(int *buf, int val, int n); +static void xscalebuf(short *xmap[], short *bbuf, int bnx); +static void addrow(int *iptr, short *sptr, int w, int n); +static void divrow(int *iptr, short *sptr, int tot, int n); +static FILTER *makefilt(short *abuf, int anx, int bnx, int *maxn); +static void freefilt(FILTER * filt, int n); +static void applyxfilt(short *bbuf, FILTER * xfilt, int bnx); +float filterinteg(float bmin, float bmax, float blurf); +static void mitchellinit(float b, float c); +static void clamprow(short *iptr, short *optr, int n); + +float filt_box(float x); +float filt_triangle(float x); +float filt_quadratic(float x); +float filt_mitchell(float x); +float filt_gaussian(float x); + +static int (*xfiltfunc) (short *, int); +static float blurfactor; +int izoomdebug; + +static filtinteg *shapeBOX; +static filtinteg *shapeTRIANGLE; +static filtinteg *shapeQUADRATIC; +static filtinteg *shapeMITCHELL; +static filtinteg *shapeGAUSSIAN; +static filtinteg *shape; + +static filtinteg * +integrate(float (*filtfunc) (float), float rad) +{ + int i; + float del, x, min, max; + double tot; + filtinteg *filt; + + min = -rad; + max = rad; + del = 2 * rad; + tot = 0.0; + filt = (filtinteg *) malloc(sizeof(filtinteg)); + filt->rad = rad; + filt->min = min; + filt->max = max; + filt->tab = (float *) malloc(FILTTABSIZE * sizeof(float)); + for (i = 0; i < FILTTABSIZE; i++) { + x = min + (del * i / (FILTTABSIZE - 1.0)); + tot = tot + filtfunc(x); + filt->tab[i] = tot; + } + for (i = 0; i < FILTTABSIZE; i++) + filt->tab[i] /= tot; + return filt; +} + +float +filterinteg(float bmin, float bmax, float blurf) +{ + int i1, i2; + float f1, f2; + float *tab; + float mult; + + bmin /= blurf; + bmax /= blurf; + tab = shape->tab; + mult = (FILTTABSIZE - 1.0) / (2.0 * shape->rad); + + f1 = ((bmin - shape->min) * mult); + i1 = floor(f1); + f1 = f1 - i1; + if (i1 < 0) + f1 = 0.0; + else if (i1 >= (FILTTABSIZE - 1)) + f1 = 1.0; + else + f1 = flerp(tab[i1], tab[i1 + 1], f1); + + f2 = ((bmax - shape->min) * mult); + i2 = floor(f2); + f2 = f2 - i2; + if (i2 < 0) + f2 = 0.0; + else if (i2 >= (FILTTABSIZE - 1)) + f2 = 1.0; + else + f2 = flerp(tab[i2], tab[i2 + 1], f2); + return f2 - f1; +} + +void +setfiltertype(int filttype) +{ + switch (filttype) { + case IMPULSE: + shape = 0; + break; + case BOX: + if (!shapeBOX) + shapeBOX = integrate(filt_box, 0.5); + shape = shapeBOX; + break; + case TRIANGLE: + if (!shapeTRIANGLE) + shapeTRIANGLE = integrate(filt_triangle, 1.0); + shape = shapeTRIANGLE; + break; + case QUADRATIC: + if (!shapeQUADRATIC) + shapeQUADRATIC = integrate(filt_quadratic, 1.5); + shape = shapeQUADRATIC; + break; + case MITCHELL: + if (!shapeMITCHELL) + shapeMITCHELL = integrate(filt_mitchell, 2.0); + shape = shapeMITCHELL; + break; + case GAUSSIAN: + if (!shapeGAUSSIAN) + shapeGAUSSIAN = integrate(filt_gaussian, 1.5); + shape = shapeGAUSSIAN; + break; + } +} + +void +copyimage(getfunc_t getfunc, getfunc_t putfunc, int nx, int ny) +{ + int y; + short *abuf; + + abuf = (short *) malloc(nx * sizeof(short)); + for (y = 0; y < ny; y++) { + getfunc(abuf, y); + putfunc(abuf, y); + } + free(abuf); +} + +/* general zoom follows */ +zoom * +newzoom(getfunc_t getfunc, int anx, int any, int bnx, int bny, int filttype, float blur) +{ + zoom *z; + int i; + + setfiltertype(filttype); + z = (zoom *) malloc(sizeof(zoom)); + z->getfunc = getfunc; + z->abuf = (short *) malloc(anx * sizeof(short)); + z->bbuf = (short *) malloc(bnx * sizeof(short)); + z->anx = anx; + z->any = any; + z->bnx = bnx; + z->bny = bny; + z->curay = -1; + z->y = 0; + z->type = filttype; + if (filttype == IMPULSE) { + if (z->anx != z->bnx) { + z->xmap = (short **) malloc(z->bnx * sizeof(short *)); + makexmap(z->abuf, z->xmap, z->anx, z->bnx); + } + } else { + blurfactor = blur; + if (filttype == MITCHELL) + z->clamp = 1; + else + z->clamp = 0; + z->tbuf = (short *) malloc(bnx * sizeof(short)); + z->xfilt = makefilt(z->abuf, anx, bnx, &z->nrows); + z->yfilt = makefilt(0, any, bny, &z->nrows); + z->filtrows = (short **) malloc(z->nrows * sizeof(short *)); + for (i = 0; i < z->nrows; i++) + z->filtrows[i] = (short *) malloc(z->bnx * sizeof(short)); + z->accrow = (int *) malloc(z->bnx * sizeof(int)); + z->ay = 0; + } + return z; +} + +void +getzoomrow(zoom * z, short *buf, int y) +{ + float fy; + int ay; + FILTER *f; + int i, max; + short *row; + + if (y == 0) { + z->curay = -1; + z->y = 0; + z->ay = 0; + } + if (z->type == IMPULSE) { + fy = GRIDTOFLOAT(z->y, z->bny); + ay = FLOATTOGRID(fy, z->any); + if (z->anx == z->bnx) { + if (z->curay != ay) { + z->getfunc(z->abuf, ay); + z->curay = ay; + if (xfiltfunc) + xfiltfunc(z->abuf, z->bnx); + } + memcpy(buf, z->abuf, z->bnx * sizeof(short)); + } else { + if (z->curay != ay) { + z->getfunc(z->abuf, ay); + xscalebuf(z->xmap, z->bbuf, z->bnx); + z->curay = ay; + if (xfiltfunc) + xfiltfunc(z->bbuf, z->bnx); + } + memcpy(buf, z->bbuf, z->bnx * sizeof(short)); + } + } else if (z->any == 1 && z->bny == 1) { + z->getfunc(z->abuf, z->ay++); + applyxfilt(z->filtrows[0], z->xfilt, z->bnx); + if (xfiltfunc) + xfiltfunc(z->filtrows[0], z->bnx); + if (z->clamp) { + clamprow(z->filtrows[0], z->tbuf, z->bnx); + memcpy(buf, z->tbuf, z->bnx * sizeof(short)); + } else { + memcpy(buf, z->filtrows[0], z->bnx * sizeof(short)); + } + } else { + f = z->yfilt + z->y; + max = (int) (sizeof(f->dat) / sizeof(short) + (f->n - 1)); + while (z->ay <= max) { + z->getfunc(z->abuf, z->ay++); + row = z->filtrows[0]; + for (i = 0; i < (z->nrows - 1); i++) + z->filtrows[i] = z->filtrows[i + 1]; + z->filtrows[z->nrows - 1] = row; + applyxfilt(z->filtrows[z->nrows - 1], z->xfilt, z->bnx); + if (xfiltfunc) + xfiltfunc(z->filtrows[z->nrows - 1], z->bnx); + } + if (f->n == 1) { + if (z->clamp) { + clamprow(z->filtrows[z->nrows - 1], z->tbuf, z->bnx); + memcpy(buf, z->tbuf, z->bnx * sizeof(short)); + } else { + memcpy(buf, z->filtrows[z->nrows - 1], z->bnx * sizeof(short)); + } + } else { + setintrow(z->accrow, f->halftotw, z->bnx); + for (i = 0; i < f->n; i++) + addrow(z->accrow, z->filtrows[i + (z->nrows - 1) - (f->n - 1)], + f->w[i], z->bnx); + divrow(z->accrow, z->bbuf, f->totw, z->bnx); + if (z->clamp) { + clamprow(z->bbuf, z->tbuf, z->bnx); + memcpy(buf, z->tbuf, z->bnx * sizeof(short)); + } else { + memcpy(buf, z->bbuf, z->bnx * sizeof(short)); + } + } + } + z->y++; +} + +static void +setintrow(int *buf, int val, int n) +{ + while (n >= 8) { + buf[0] = val; + buf[1] = val; + buf[2] = val; + buf[3] = val; + buf[4] = val; + buf[5] = val; + buf[6] = val; + buf[7] = val; + buf += 8; + n -= 8; + } + while (n--) + *buf++ = val; +} + +void +freezoom(zoom * z) +{ + int i; + + if (z->type == IMPULSE) { + if (z->anx != z->bnx) + free(z->xmap); + } else { + freefilt(z->xfilt, z->bnx); + freefilt(z->yfilt, z->bny); + free(z->tbuf); + for (i = 0; i < z->nrows; i++) + free(z->filtrows[i]); + free(z->filtrows); + free(z->accrow); + } + free(z->abuf); + free(z->bbuf); + free(z); + +} + +void +filterzoom(getfunc_t getfunc, getfunc_t putfunc, int anx, int any, int bnx, int bny, int filttype, float blur) +{ + zoom *z; + int y; + short *buf; + + buf = (short *) malloc(bnx * sizeof(short)); + z = newzoom(getfunc, anx, any, bnx, bny, filttype, blur); + for (y = 0; y < bny; y++) { + getzoomrow(z, buf, y); + putfunc(buf, y); + } + freezoom(z); + free(buf); +} + +/* impulse zoom utilities */ +static void +makexmap(short *abuf, short *xmap[], int anx, int bnx) +{ + int x, ax; + float fx; + + for (x = 0; x < bnx; x++) { + fx = GRIDTOFLOAT(x, bnx); + ax = FLOATTOGRID(fx, anx); + xmap[x] = abuf + ax; + } +} + +static void +xscalebuf(short *xmap[], short *bbuf, int bnx) +{ + while (bnx >= 8) { + bbuf[0] = *(xmap[0]); + bbuf[1] = *(xmap[1]); + bbuf[2] = *(xmap[2]); + bbuf[3] = *(xmap[3]); + bbuf[4] = *(xmap[4]); + bbuf[5] = *(xmap[5]); + bbuf[6] = *(xmap[6]); + bbuf[7] = *(xmap[7]); + bbuf += 8; + xmap += 8; + bnx -= 8; + } + while (bnx--) + *bbuf++ = *(*xmap++); +} + +void +zoomxfilt(int (*filtfunc) (short *, int)) +{ + xfiltfunc = filtfunc; +} + +/* filter zoom utilities */ +static void +addrow(int *iptr, short *sptr, int w, int n) +{ + while (n >= 8) { + iptr[0] += (w * sptr[0]); + iptr[1] += (w * sptr[1]); + iptr[2] += (w * sptr[2]); + iptr[3] += (w * sptr[3]); + iptr[4] += (w * sptr[4]); + iptr[5] += (w * sptr[5]); + iptr[6] += (w * sptr[6]); + iptr[7] += (w * sptr[7]); + iptr += 8; + sptr += 8; + n -= 8; + } + while (n--) + *iptr++ += (w * *sptr++); +} + +static void +divrow(int *iptr, short *sptr, int tot, int n) +{ + while (n >= 8) { + sptr[0] = iptr[0] / tot; + sptr[1] = iptr[1] / tot; + sptr[2] = iptr[2] / tot; + sptr[3] = iptr[3] / tot; + sptr[4] = iptr[4] / tot; + sptr[5] = iptr[5] / tot; + sptr[6] = iptr[6] / tot; + sptr[7] = iptr[7] / tot; + sptr += 8; + iptr += 8; + n -= 8; + } + while (n--) + *sptr++ = (*iptr++) / tot; +} + +static FILTER * +makefilt(short *abuf, int anx, int bnx, int *maxn) +{ + FILTER *f, *filter; + int x, n; + float bmin, bmax, bcent, brad; + float fmin, fmax, acent, arad; + int amin, amax; + float coverscale; + + if (izoomdebug) + fprintf(stderr, "makefilt\n"); + f = filter = (FILTER *) malloc(bnx * sizeof(FILTER)); + *maxn = 0; + if (bnx < anx) { + coverscale = ((float) anx / bnx * ONE) / 2.0; + brad = FILTERRAD / bnx; + for (x = 0; x < bnx; x++) { + bcent = ((float) x + 0.5) / bnx; + amin = floor((bcent - brad) * anx + EPSILON); + amax = floor((bcent + brad) * anx - EPSILON); + if (amin < 0) + amin = 0; + if (amax >= anx) + amax = anx - 1; + f->n = 1 + amax - amin; + f->dat = abuf + amin; + f->w = (short *) malloc(f->n * sizeof(short)); + f->totw = 0; + if (izoomdebug) + fprintf(stderr, "| "); + for (n = 0; n < f->n; n++) { + bmin = bnx * ((((float) amin + n) / anx) - bcent); + bmax = bnx * ((((float) amin + n + 1) / anx) - bcent); + f->w[n] = floor((coverscale * filterinteg(bmin, bmax, blurfactor)) + 0.5); + if (izoomdebug) + fprintf(stderr, "%d ", f->w[n]); + f->totw += f->w[n]; + } + f->halftotw = f->totw / 2; + if (f->n > *maxn) + *maxn = f->n; + f++; + } + } else { + coverscale = ((float) bnx / anx * ONE) / 2.0; + arad = FILTERRAD / anx; + for (x = 0; x < bnx; x++) { + bmin = ((float) x) / bnx; + bmax = ((float) x + 1.0) / bnx; + amin = floor((bmin - arad) * anx + (0.5 + EPSILON)); + amax = floor((bmax + arad) * anx - (0.5 + EPSILON)); + if (amin < 0) + amin = 0; + if (amax >= anx) + amax = anx - 1; + f->n = 1 + amax - amin; + f->dat = abuf + amin; + f->w = (short *) malloc(f->n * sizeof(short)); + f->totw = 0; + if (izoomdebug) + fprintf(stderr, "| "); + for (n = 0; n < f->n; n++) { + acent = (amin + n + 0.5) / anx; + fmin = anx * (bmin - acent); + fmax = anx * (bmax - acent); + f->w[n] = floor((coverscale * filterinteg(fmin, fmax, blurfactor)) + 0.5); + if (izoomdebug) + fprintf(stderr, "%d ", f->w[n]); + f->totw += f->w[n]; + } + f->halftotw = f->totw / 2; + if (f->n > *maxn) + *maxn = f->n; + f++; + } + } + if (izoomdebug) + fprintf(stderr, "|\n"); + return filter; +} + +static void +freefilt(FILTER * filt, int n) +{ + FILTER *f; + + f = filt; + while (n--) { + free(f->w); + f++; + } + free(filt); +} + +static void +applyxfilt(short *bbuf, FILTER * xfilt, int bnx) +{ + short *w; + short *dptr; + int n, val; + + while (bnx--) { + if ((n = xfilt->n) == 1) { + *bbuf++ = *xfilt->dat; + } else { + w = xfilt->w; + dptr = xfilt->dat; + val = xfilt->halftotw; + n = xfilt->n; + while (n--) + val += *w++ * *dptr++; + *bbuf++ = val / xfilt->totw; + } + xfilt++; + } +} + +/* filter shape functions follow */ +float +filt_box(float x) +{ + if (x < -0.5) + return 0.0; + if (x < 0.5) + return 1.0; + return 0.0; +} + +float +filt_triangle(float x) +{ + if (x < -1.0) + return 0.0; + if (x < 0.0) + return 1.0 + x; + if (x < 1.0) + return 1.0 - x; + return 0.0; +} + +float +filt_quadratic(float x) +{ + if (x < -1.5) + return 0.0; + if (x < -0.5) + return 0.5 * (x + 1.5) * (x + 1.5); + if (x < 0.5) + return 0.75 - (x * x); + if (x < 1.5) + return 0.5 * (x - 1.5) * (x - 1.5); + return 0.0; +} + +static float p0, p2, p3, q0, q1, q2, q3; + +/* see Mitchell&Netravali, "Reconstruction Filters in Computer Graphics", + SIGGRAPH 88. Mitchell code provided by Paul Heckbert. */ + +float +filt_mitchell(float x) +{ /* Mitchell & Netravali's two-param cubic */ + static int mitfirsted; + + if (!mitfirsted) { + mitchellinit(1.0f / 3.0f, 1.0f / 3.0f); + mitfirsted = 1; + } + if (x < -2.0) + return 0.0; + if (x < -1.0) + return (q0 - x * (q1 - x * (q2 - x * q3))); + if (x < 0.0) + return (p0 + x * x * (p2 - x * p3)); + if (x < 1.0) + return (p0 + x * x * (p2 + x * p3)); + if (x < 2.0) + return (q0 + x * (q1 + x * (q2 + x * q3))); + return 0.0; +} + +static void +mitchellinit(float b, float c) +{ + p0 = (6.0 - 2.0 * b) / 6.0; + p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0; + p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0; + q0 = (8.0 * b + 24.0 * c) / 6.0; + q1 = (-12.0 * b - 48.0 * c) / 6.0; + q2 = (6.0 * b + 30.0 * c) / 6.0; + q3 = (-b - 6.0 * c) / 6.0; +} + +#define NARROWNESS 1.5 + +float +filt_gaussian(float x) +{ + x = x * NARROWNESS; + return (1.0 / exp(x * x) - 1.0 / exp(1.5 * NARROWNESS * 1.5 * NARROWNESS)); +} + +float +flerp(float f0, float f1, float p) +{ + return ((f0 * (1.0 - p)) + (f1 * p)); +} + +#define DOCLAMP(iptr,optr) *(optr) = ((*(iptr)<0) ? 0 : (*(iptr)>255) ? 255 : *(iptr)) + +static void +clamprow(short *iptr, short *optr, int n) +{ + while (n >= 8) { + DOCLAMP(iptr + 0, optr + 0); + DOCLAMP(iptr + 1, optr + 1); + DOCLAMP(iptr + 2, optr + 2); + DOCLAMP(iptr + 3, optr + 3); + DOCLAMP(iptr + 4, optr + 4); + DOCLAMP(iptr + 5, optr + 5); + DOCLAMP(iptr + 6, optr + 6); + DOCLAMP(iptr + 7, optr + 7); + iptr += 8; + optr += 8; + n -= 8; + } + while (n--) { + DOCLAMP(iptr, optr); + iptr++; + optr++; + } +} diff --git a/lib/glut-3.7.6/progs/advanced/izoom.h b/lib/glut-3.7.6/progs/advanced/izoom.h new file mode 100644 index 0000000000..1c0f406872 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/izoom.h @@ -0,0 +1,49 @@ +#ifndef IZOOMDEF +#define IZOOMDEF + +/** + ** header for izoom- + ** Magnify or minify a picture with or without filtering. The + ** filtered method is one pass, uses 2-d convolution, and is optimized + ** by integer arithmetic and precomputation of filter coeffs. + ** + ** Paul Haeberli - 1988 + **/ + +#define IMPULSE 1 +#define BOX 2 +#define TRIANGLE 3 +#define QUADRATIC 4 +#define MITCHELL 5 +#define GAUSSIAN 6 + +typedef struct FILTER { + int n, totw, halftotw; + short *dat; + short *w; +} FILTER; + +typedef void (*getfunc_t) (short *, int); + +typedef struct zoom { + getfunc_t getfunc; + short *abuf; + short *bbuf; + int anx, any; + int bnx, bny; + short **xmap; + int type; + int curay; + int y; + FILTER *xfilt, *yfilt; /* stuff for fitered zoom */ + short *tbuf; + int nrows, clamp, ay; + short **filtrows; + int *accrow; +} zoom; + +zoom *newzoom(getfunc_t getfunc, int anx, int any, int bnx, int bny, int filttype, float blur); +float filterinteg(float bmin, float bmax, float blurf); +void filterzoom(getfunc_t getfunc, getfunc_t putfunc, int anx, int any, int bnx, int bny, int filttype, float blur); + +#endif diff --git a/lib/glut-3.7.6/progs/advanced/logopoints.h b/lib/glut-3.7.6/progs/advanced/logopoints.h new file mode 100644 index 0000000000..3925e76597 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/logopoints.h @@ -0,0 +1,33 @@ +/* + * logopoints.h + * + * contains the data for one-third of the complete SGI "box" logo. this + * data is centered at the origin. The complete logo is created by scaling, + * rotating and translating the initial data points specified here. + */ + +#define Ax 0.0 +#define Ay 0.104 + +#define Bx 0.231 +#define By 0.237 + +#define Cx 0.113 +#define Cy 0.3051 + +#define Dx 0.113 +#define Dy 0.192 + +#define Ex 0.023 +#define Ey 0.14 + +#define Fx 0.023 +#define Fy 0.461 + +#define Gx 0.411 +#define Gy 0.237 + +#define Z 0.0 + +/* Radius of round corners */ +#define LOGO_RADIUS .1 diff --git a/lib/glut-3.7.6/progs/advanced/mipmap_lines.c b/lib/glut-3.7.6/progs/advanced/mipmap_lines.c new file mode 100644 index 0000000000..64afdc4888 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/mipmap_lines.c @@ -0,0 +1,301 @@ + +/* mipmap_lines.c - by David Blythe, SGI */ + +/* Different mipmap filters. */ + +#include +#include +#include +#include +#include "texture.h" +#include "izoom.h" + +static int w = 1024, h = 512; + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w / (GLfloat) h, 1.0, 20.0); + + gluLookAt(0, 1, 3, + 0, 0, 0, + 0, 1, 0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +int original_width, reduced_width, global_comp; +unsigned *original, *reduced; + +void +getimgrow(short *buf, int y) +{ + int i; + unsigned *p = &original[y * original_width]; + int shift = global_comp * 8; + unsigned int mask = 0xff << shift; + + for (i = 0; i < original_width; i++) { + buf[i] = (p[i] & mask) >> shift; + } +} + +void +putimgrow(short *buf, int y) +{ + int i; + unsigned *p = &reduced[y * reduced_width]; + int shift = global_comp * 8; + unsigned int mask = 0xff << shift; + + for (i = 0; i < reduced_width; i++) { + p[i] = (p[i] & ~mask) | (buf[i] << shift); + } +} + +void +buildMitchellMipmaps(int components, int width, int height, unsigned + *buf) +{ + int level = 0; + + original_width = width; + original = buf; + glTexImage2D(GL_TEXTURE_2D, level, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + original); + while (width) { + reduced_width = width / 2; + for (global_comp = 0; global_comp < 4; global_comp++) { + filterzoom(getimgrow, putimgrow, width, height, width / 2, + height / 2, MITCHELL, 1.); + } + glTexImage2D(GL_TEXTURE_2D, ++level, components, width / 2, + height / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + reduced); + width /= 2, height /= 2; + memcpy(original, reduced, width * height * sizeof(unsigned)); + original_width = width; + printf("build level %d\n", level); + } +} + +int width = 256, height = 256; +int grid_space = 4; + +void +init_textures(char *filename) +{ + unsigned *buf; + int components; + + if (filename) { + buf = read_texture(filename, &width, &height, &components); + if (buf == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(1); + } else { + printf("%d x %d texture loaded\n", width, height); + } + } else { + int i, j; + components = 4; + buf = (unsigned *) malloc(width * height * sizeof(unsigned)); + for (i = 0; i < height; i++) + for (j = 0; j < width; j++) + if ((i % grid_space) && (j % grid_space)) + buf[i * width + j] = 0xffffffff; + else + buf[i * width + j] = 0; + } + +#ifdef GL_EXT_texture_object + glBindTextureEXT(GL_TEXTURE_2D, 1); +#else + glNewList(1001, GL_COMPILE); +#endif + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gluBuild2DMipmaps(GL_TEXTURE_2D, components, width, height, GL_RGBA, + GL_UNSIGNED_BYTE, buf); +#ifndef GL_EXT_texture_object + glEndList(); +#endif + +#ifdef GL_EXT_texture_object + glBindTextureEXT(GL_TEXTURE_2D, 2); +#else + glNewList(1002, GL_COMPILE); +#endif + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + reduced = (unsigned *) malloc(width * height * sizeof(unsigned)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + buildMitchellMipmaps(components, width, height, buf); +#ifndef GL_EXT_texture_object + glEndList(); +#endif + + free(buf); + free(reduced); +} + +void +init(char *filename) +{ + glEnable(GL_TEXTURE_2D); + init_textures(filename); + glNewList(1, GL_COMPILE); + glColor3f(1., 1., 1.); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); + glVertex3f(-4, 0, -10); + glTexCoord2f(1, 1); + glVertex3f(4, 0, -10); + glTexCoord2f(1, 0); + glVertex3f(4, 0, 3); + glTexCoord2f(0, 0); + glVertex3f(-4, 0, 3); + glEnd(); + glEndList(); + glClearColor(.2, 0, .9, 0); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, w / 2, h); +#ifdef GL_EXT_texture_object + glBindTextureEXT(GL_TEXTURE_2D, 1); +#else + glCallList(1001); +#endif + glCallList(1); + + glViewport(w / 2, 0, w / 2, h); +#ifdef GL_EXT_texture_object + glBindTextureEXT(GL_TEXTURE_2D, 2); +#else + glCallList(1002); +#endif + glCallList(1); + glutSwapBuffers(); +} + +void +idle(void) +{ + glRotatef(.1, 1, 0, 0); + glutPostRedisplay(); +} + +void +bidle(void) +{ + glRotatef(-.1, 1, 0, 0); + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + glutIdleFunc(idle); + break; + case GLUT_MIDDLE_BUTTON: + glutIdleFunc(bidle); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else { + glutIdleFunc(NULL); + } +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'g' - increase line spacing\n"); + printf("'G' - decrease line spacing\n"); + printf("'s' - double texture dimensions\n"); + printf("'S' - halve texture dimensions\n"); +} + +char *filename; + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'h': + help(); + break; + case 'g': + grid_space++; + init_textures(filename); + printf("grid spacing %d\n", grid_space); + break; + case 'G': + grid_space--; + if (grid_space <= 0) + grid_space = 1; + init_textures(filename); + printf("grid spacing %d\n", grid_space); + break; + case 's': + height = width *= 2; + if (height > 1024) + height = width = 1024; + init_textures(filename); + printf("texture size %d\n", height); + break; + case 'S': + height = width /= 2; + init_textures(filename); + printf("texture size %d\n", height); + break; + default: + return; + case '\033': + exit(0); + break; + } + glutPostRedisplay(); +} + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(w, h); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + (void) glutCreateWindow("Left: GLU mipmaps, Right: Mitchell mipmaps"); + if (argc > 1) + init(filename = argv[1]); + else + init(filename = 0); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/mipmap_lines.dsp b/lib/glut-3.7.6/progs/advanced/mipmap_lines.dsp new file mode 100644 index 0000000000..7237f55531 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/mipmap_lines.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="mipmap_lines" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mipmap_lines - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mipmap_lines.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mipmap_lines.mak" CFG="mipmap_lines - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mipmap_lines - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mipmap_lines - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mipmap_lines - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mipmap_lines - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mipmap_lines - Win32 Release" +# Name "mipmap_lines - Win32 Debug" +# Begin Source File + +SOURCE=.\izoom.c +# End Source File +# Begin Source File + +SOURCE=.\izoom.h +# End Source File +# Begin Source File + +SOURCE=.\mipmap_lines.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/motionblur.c b/lib/glut-3.7.6/progs/advanced/motionblur.c new file mode 100644 index 0000000000..1e9f3264b5 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/motionblur.c @@ -0,0 +1,241 @@ + +/* motionblur.c - by Tom McReynolds, SGI */ + +/* Using the accumulation buffer for motion blur. */ + +#include +#include +#include + +const GLdouble FRUSTDIM = 100.f; +const GLdouble FRUSTNEAR = 320.f; +const GLdouble FRUSTFAR = 660.f; + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {SPHERE = 1, CONE}; + +void +render(GLfloat dx, GLfloat dy, GLfloat dz) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -640.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -640.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -640.f); + glVertex3f(-100.f, 100.f, -640.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f( 100.f, -100.f, -640.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -640.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -640.f); + glVertex3f( 100.f, -100.f, -640.f); + glVertex3f( 100.f, 100.f, -640.f); + glVertex3f(-100.f, 100.f, -640.f); + glEnd(); + + + glPushMatrix(); + glTranslatef(-80.f + dx, -60.f + dy, -420.f + dz); + glCallList(SPHERE); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -600.f); + glCallList(CONE); + glPopMatrix(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + +enum {NONE, FIELD}; + +int rendermode = NONE; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + +GLdouble focus = 420.; + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + int i; + int max; + GLfloat dx, dy, dz; + + dx = .5f; + dy = 1.f; + dz = -2.f; + + glPushMatrix(); + switch(rendermode) { + case NONE: + render(0.f, 0.f, 0.f); + break; + case FIELD: + max = 16; + + glClear(GL_ACCUM_BUFFER_BIT); + + for(i = 0; i < max; i++) { + render(dx * i, dy * i, dz * i); + glAccum(GL_ACCUM, 1.f/max); + } + glAccum(GL_RETURN, 1.f); + break; + } + + glPopMatrix(); + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); + (void)glutCreateWindow("motion blur"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("Normal", NONE); + glutAddMenuEntry("Motion Blur", FIELD); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/motionblur.dsp b/lib/glut-3.7.6/progs/advanced/motionblur.dsp new file mode 100644 index 0000000000..6b91f41888 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/motionblur.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="motionblur" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=motionblur - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "motionblur.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "motionblur.mak" CFG="motionblur - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "motionblur - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "motionblur - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "motionblur - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "motionblur - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "motionblur - Win32 Release" +# Name "motionblur - Win32 Debug" +# Begin Source File + +SOURCE=.\motionblur.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/multilight.c b/lib/glut-3.7.6/progs/advanced/multilight.c new file mode 100644 index 0000000000..8d8272357a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/multilight.c @@ -0,0 +1,536 @@ + +/* 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 program demonstrates virtualization of OpenGL's lights. The idea is + that if an object is lit by many lights, it is computationally more + efficient to calculate the approximate lighting contribution of the + various lights per-object and only enable the "brightest" lights while + rendering the object. This also lets you render scenes with more lights + than the OpenGL implementation light (usually 8). Two approaches are + used: The "distance-based" approach only enables the 8 closest lights + based purely on distance. The "Lambertian-based" approach accounts for + diffuse lighting contributions and approximates the diffuse contribution. */ + +#include +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define MIN_VALUE(a,b) (((a)<(b))?(a):(b)) +#define MAX_VALUE(a,b) (((a)>(b))?(a):(b)) + +enum { + DL_LIGHT_SPHERE = 1, + DL_BIG_SPHERE = 2, + DL_ICO = 3 +}; + +enum { + M_SPHERE, M_ICO, M_LABELS, M_LINEAR, M_QUAD, M_REPORT_SIG, + M_LAMBERTIAN, M_DISTANCE, M_TIME +}; + +typedef struct _LightInfo { + GLfloat xyz[4]; + GLfloat *rgb; + int enable; +} LightInfo; + +typedef struct _LightBrightness { + int num; + GLfloat brightness; +} LightBrightness; + +static int animation = 1; +static int labelLights = 1; +static int reportLightSignificance = 0; +static int brightnessModel = M_LAMBERTIAN; +static int numActiveLights; +static int timeFrames = 0; +static int singleBuffer = 0; +/* *INDENT-OFF* */ + +static GLfloat modelAmb[4] = {0.1, 0.1, 0.1, 1.0}; +static GLfloat matAmb[4] = {0.2, 0.2, 0.2, 1.0}; +static GLfloat matDiff[4] = {0.8, 0.8, 0.8, 1.0}; +static GLfloat matSpec[4] = {0.4, 0.4, 0.4, 1.0}; +static GLfloat matEmission[4] = {0.0, 0.0, 0.0, 1.0}; + +GLfloat red[] = {1.0, 0.0, 0.0, 1.0}; +GLfloat green[] = {0.0, 1.0, 0.0, 1.0}; +GLfloat blue[] = {0.0, 0.0, 1.0, 1.0}; +GLfloat yellow[] = {1.0, 1.0, 0.0, 1.0}; +GLfloat magenta[] = {1.0, 0.0, 1.0, 1.0}; +GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat dim[] = {0.5, 0.5, 0.5, 1.0}; + +LightInfo linfo[] = { + { {-4.0, 0.0, -10.0, 1.0}, yellow}, + { {4.0, 0.0, -10.0, 1.0}, green}, + { {-4.0, 0.0, -6.0, 1.0}, red}, + { {4.0, 0.0, -6.0, 1.0}, blue}, + { {-4.0, 0.0, -2.0, 1.0}, green}, + { {4.0, 0.0, -2.0, 1.0}, yellow}, + { {-4.0, 0.0, 2.0, 1.0}, blue}, + { {4.0, 0.0, 2.0, 1.0}, red}, + { {-4.0, 0.0, 6.0, 1.0}, yellow}, + { {4.0, 0.0, 6.0, 1.0}, green}, + { {-4.0, 0.0, 10.0, 1.0}, red}, + { {4.0, 0.0, 10.0, 1.0}, blue}, +}; + +int lightState[8] = {1, 1, 1, 1, 1, 1, 1, 1}; +/* *INDENT-ON* */ + +#define MAX_LIGHTS (sizeof(linfo)/sizeof(linfo[0])) + +int moving = 0, begin; +GLfloat angle = 0.0; +int object = M_SPHERE; +int attenuation = M_QUAD; +GLfloat t = 0.0; + +void +initLight(int num) +{ + glLightf(GL_LIGHT0 + num, GL_CONSTANT_ATTENUATION, 0.0); + if (attenuation == M_LINEAR) { + glLightf(GL_LIGHT0 + num, GL_LINEAR_ATTENUATION, 0.4); + glLightf(GL_LIGHT0 + num, GL_QUADRATIC_ATTENUATION, 0.0); + } else { + glLightf(GL_LIGHT0 + num, GL_LINEAR_ATTENUATION, 0.0); + glLightf(GL_LIGHT0 + num, GL_QUADRATIC_ATTENUATION, 0.1); + } + glLightfv(GL_LIGHT0 + num, GL_SPECULAR, dim); +} + +/* Draw a sphere the same color as the light at the light position so it is + easy to tell where the positional light sources are. */ +void +drawLight(LightInfo * info) +{ + glPushMatrix(); + glTranslatef(info->xyz[0], info->xyz[1], info->xyz[2]); + glColor3fv(info->rgb); + glCallList(DL_LIGHT_SPHERE); + glPopMatrix(); +} + +/* Place the light's OpenGL light number next to the light's sphere. To + ensure a readable number with good contrast, a black version of the number + is drawn shifted a pixel to the left and right of the actual white number. + */ +void +labelLight(LightInfo * info, int num) +{ + GLubyte nothin = 0; + void *font = GLUT_BITMAP_HELVETICA_18; + int width = glutBitmapWidth(font, '0' + num); + + glPushMatrix(); + glColor3f(0.0, 0.0, 0.0); + glRasterPos3f(info->xyz[0], info->xyz[1], info->xyz[2]); + glBitmap(1, 1, 0, 0, 4, 5, ¬hin); + glutBitmapCharacter(font, '0' + num); + + glBitmap(1, 1, 0, 0, 2 - width, 0, ¬hin); + glutBitmapCharacter(font, '0' + num); + + if (lightState[num]) { + glColor3fv(white); + } else { + /* Draw disabled lights dimmer. */ + glColor3fv(dim); + } + glRasterPos3f(info->xyz[0], info->xyz[1], info->xyz[2]); + glBitmap(1, 1, 0, 0, 5, 5, ¬hin); + glutBitmapCharacter(font, '0' + num); + glPopMatrix(); +} + +/* Comparison routine used by qsort. */ +int +lightBrightnessCompare(const void *a, const void *b) +{ + LightBrightness *ld1 = (LightBrightness *) a; + LightBrightness *ld2 = (LightBrightness *) b; + GLfloat diff; + + /* The brighter lights get sorted close to top of the list. */ + diff = ld2->brightness - ld1->brightness; + + if (diff > 0) + return 1; + if (diff < 0) + return -1; + return 0; +} + +void +display(void) +{ + int i; + GLfloat x, y, z; + LightBrightness ld[MAX_LIGHTS]; + int start, end; + + if (timeFrames) { + start = glutGet(GLUT_ELAPSED_TIME); + } + x = cos(t * 12.3) * 2.0; + y = 0.0; + z = sin(t) * 7.0; + + for (i = 0; i < MAX_LIGHTS; i++) { + GLfloat dx, dy, dz; + GLfloat quadraticAttenuation; + + /* Calculate object to light position vector. */ + dx = (linfo[i].xyz[0] - x); + dy = (linfo[i].xyz[1] - y); + dz = (linfo[i].xyz[2] - z); + + quadraticAttenuation = dx * dx + dy * dy + dz * dz; + + if (brightnessModel == M_LAMBERTIAN) { + /* Lambertian surface-based brightness determination. */ + GLfloat ex, ey, ez; + GLfloat nx, ny, nz; + GLfloat distance; + GLfloat diffuseReflection; + + /* Determine eye point location (remember we can rotate by angle). */ + ex = 16.0 * sin(angle * M_PI / 180.0); + ey = 1.0; + ez = 16.0 * -cos(angle * M_PI / 180.0); + + /* Calculated normalized object to eye position direction (nx,ny,nz). */ + nx = (ex - x); + ny = (ey - y); + nz = (ez - z); + distance = sqrt(nx * nx + ny * ny + nz * nz); + nx = nx / distance; + ny = ny / distance; + nz = nz / distance; + + /* True distance needed, take square root. */ + distance = sqrt(quadraticAttenuation); + + /* Calculate normalized object to light postition direction (dx,dy,dz). + */ + dx = dx / distance; + dy = dy / distance; + dz = dz / distance; + + /* Dot product of object->eye and object->light source directions. + OpenGL's lighting equations actually force the diffuse contribution + to be zero if the dot product is less than zero. For our purposes, + that's too strict since we are approximating the entire object with + a single object-to-eye normal. */ + diffuseReflection = nx * dx + ny * dy + nz * dz; + if (attenuation == M_QUAD) { + /* Attenuate based on square of distance. */ + ld[i].brightness = diffuseReflection / quadraticAttenuation; + } else { + /* Attenuate based on linear distance. */ + ld[i].brightness = diffuseReflection / distance; + } + } else { + /* Distance-based brightness determination. */ + + /* In theory, we are really determining brightness based on just the + linear distance of the light source, but since we are just doing + comparisons, there is no reason to waste time doing a square root. */ + + /* Negation makes sure closer distances are "bigger" than further + distances for sorting. */ + ld[i].brightness = -quadraticAttenuation; + } + ld[i].num = i; + } + + /* Sort the lights so that the "brightest" are listed first. We really + want to just determine the first numActiveLights so a full sort is + overkill. */ + qsort(ld, MAX_LIGHTS, sizeof(ld[0]), lightBrightnessCompare); + + if (reportLightSignificance) { + printf("\n"); + for (i = 0; i < MAX_LIGHTS; i++) { + printf("%d: dist = %g\n", ld[i].num, ld[i].brightness); + } + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(angle, 0.0, 1.0, 0.0); + + glDisable(GL_LIGHTING); + for (i = 0; i < MAX_LIGHTS; i++) { + drawLight(&linfo[i]); + } + + /* After sorting, the first numActiveLights (ie, <8) light sources are the + light sources with the biggest contribution to the object's lighting. + Assign these "virtual lights of significance" to OpenGL's actual + available light sources. */ + + glEnable(GL_LIGHTING); + for (i = 0; i < numActiveLights; i++) { + if (lightState[i]) { + int num = ld[i].num; + + glLightfv(GL_LIGHT0 + i, GL_POSITION, linfo[num].xyz); + glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, linfo[num].rgb); + glEnable(GL_LIGHT0 + i); + } else { + glDisable(GL_LIGHT0 + i); + } + } + + glPushMatrix(); + glTranslatef(x, y, z); + switch (object) { + case M_SPHERE: + glCallList(DL_BIG_SPHERE); + break; + case M_ICO: + glCallList(DL_ICO); + break; + } + glPopMatrix(); + + if (labelLights) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + for (i = 0; i < numActiveLights; i++) { + labelLight(&linfo[ld[i].num], i); + } + glEnable(GL_DEPTH_TEST); + } + glPopMatrix(); + + if (timeFrames) { + glFinish(); + end = glutGet(GLUT_ELAPSED_TIME); + printf("Speed %.3g frames/sec (%d ms)\n", + 1000.0 / (end - start), end - start); + } + if (!singleBuffer) { + glutSwapBuffers(); + } +} + +void +idle(void) +{ + t += 0.005; + glutPostRedisplay(); +} + +/* When not visible, stop animating. Restart when visible again. */ +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) { + if (animation) + glutIdleFunc(idle); + } else { + if (!animation) + glutIdleFunc(NULL); + } +} + +/* Press any key to redraw; good when motion stopped and performance + reporting on. */ +/* ARGSUSED */ +static void +key(unsigned char c, int x, int y) +{ + int i; + + switch (c) { + case 27: + exit(0); /* IRIS GLism, Escape quits. */ + break; + case ' ': + animation = 1 - animation; + if (animation) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + lightState[c - '0'] = 1 - lightState[c - '0']; + break; + case 13: + for (i = 0; i < numActiveLights; i++) { + lightState[i] = 1; + } + break; + } + glutPostRedisplay(); +} + +/* ARGSUSED3 */ +void +mouse(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { + moving = 1; + begin = x; + } + if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { + moving = 0; + } +} + +/* ARGSUSED1 */ +void +motion(int x, int y) +{ + if (moving) { + angle = angle + (x - begin); + begin = x; + glutPostRedisplay(); + } +} + +void +menu(int value) +{ + int i; + + switch (value) { + case M_SPHERE: + object = M_SPHERE; + break; + case M_ICO: + object = M_ICO; + break; + case M_LABELS: + labelLights = 1 - labelLights; + break; + case M_LINEAR: + case M_QUAD: + attenuation = value; + for (i = 0; i < numActiveLights; i++) { + initLight(i); + } + break; + case M_REPORT_SIG: + reportLightSignificance = 1 - reportLightSignificance; + break; + case M_LAMBERTIAN: + brightnessModel = M_LAMBERTIAN; + glutSetWindowTitle("multilight (Lambertian-based)"); + break; + case M_DISTANCE: + brightnessModel = M_DISTANCE; + glutSetWindowTitle("multilight (Distance-based)"); + break; + case M_TIME: + timeFrames = 1 - timeFrames; + break; + case 666: + exit(0); + } + glutPostRedisplay(); +} + +int +main(int argc, char **argv) +{ + int i; + + glutInitWindowSize(400, 200); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutInit(&argc, argv); + + for (i = 1; i < argc; i++) { + if (!strcmp("-sb", argv[i])) { + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE); + singleBuffer = 1; + } + } + + glutCreateWindow("multilight"); + + glClearColor(0.0, 0.0, 0.0, 0.0); + + glMatrixMode(GL_PROJECTION); + gluPerspective(50.0, 2.0, 0.1, 100.0); + glMatrixMode(GL_MODELVIEW); + gluLookAt( + 0.0, 1.0, -16.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.); + + numActiveLights = MIN_VALUE(MAX_LIGHTS, 8); + for (i = 0; i < numActiveLights; i++) { + initLight(i); + } + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb); + glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb); + glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff); + glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec); + glMaterialfv(GL_FRONT, GL_EMISSION, matEmission); + glMaterialf(GL_FRONT, GL_SHININESS, 10.0); + + glNewList(DL_LIGHT_SPHERE, GL_COMPILE); + glutSolidSphere(0.2, 4, 4); + glEndList(); + + glNewList(DL_BIG_SPHERE, GL_COMPILE); + glutSolidSphere(1.5, 20, 20); + glEndList(); + + glNewList(DL_ICO, GL_COMPILE); + glutSolidIcosahedron(); + glEndList(); + + glutDisplayFunc(display); + glutVisibilityFunc(visible); + glutKeyboardFunc(key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glutCreateMenu(menu); + glutAddMenuEntry("Sphere", M_SPHERE); + glutAddMenuEntry("Icosahedron", M_ICO); + glutAddMenuEntry("Linear attenuation", M_LINEAR); + glutAddMenuEntry("Quadratic attenuation", M_QUAD); + glutAddMenuEntry("Toggle Light Number Labels", M_LABELS); + glutAddMenuEntry("Report Light Significance", M_REPORT_SIG); + glutAddMenuEntry("Lambertian-based Significance", M_LAMBERTIAN); + glutAddMenuEntry("Distance-based Significance", M_DISTANCE); + glutAddMenuEntry("Time Frames", M_TIME); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/multilight.dsp b/lib/glut-3.7.6/progs/advanced/multilight.dsp new file mode 100644 index 0000000000..df8f8cae53 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/multilight.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multilight" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multilight - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multilight.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multilight.mak" CFG="multilight - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multilight - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multilight - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multilight - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multilight - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multilight - Win32 Release" +# Name "multilight - Win32 Debug" +# Begin Source File + +SOURCE=.\multilight.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/nvidia_logo.c b/lib/glut-3.7.6/progs/advanced/nvidia_logo.c new file mode 100644 index 0000000000..0bd5836809 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/nvidia_logo.c @@ -0,0 +1,239 @@ + +/* Copyright (c) Mark J. Kilgard, 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 +#include + +GLfloat nvlogo0[][2] = { + { -0.474465, -1.259490 }, + { 0.115919, -1.113297 }, + { 0.588227, -0.899634 }, + { 0.942455, -0.652235 }, + { 1.296687, -0.348609 }, + { 1.690275, -0.033738 }, + { 1.926431, 0.269888 }, + { 2.123226, 0.494796 }, + { 1.847713, 0.832160 }, + { 1.532842, 1.124540 }, + { 1.178611, 1.394430 }, + { 0.706303, 1.709300 }, + { 0.076562, 1.967940 }, + { -0.395747, 2.080400 }, + { -1.064784, 2.058940 }, + { -1.064847, 2.811350 }, + { 3.973113, 2.811350 }, + { 3.973113, -2.811350 }, + { -1.025490, -2.811350 }, + { -1.025490, -2.159120 }, + { -0.474465, -2.159120 }, + { 0.155277, -2.102890 }, + { 0.706303, -1.979190 }, + { 1.178611, -1.833000 }, + { 1.690275, -1.653080 }, + { 2.201941, -1.450660 }, + { 2.674248, -1.214510 }, + { 3.107212, -0.955861 }, + { 3.343357, -0.719707 }, + { 2.438097, -0.179928 }, + { 2.005147, -0.517290 }, + { 1.690275, -0.820916 }, + { 1.296687, -1.079560 }, + { 0.863740, -1.338200 }, + { 0.273356, -1.585600 }, + { -0.198952, -1.709300 }, + { -1.025490, -1.731790 }, + { -1.025490, -1.248240 }, +}; +GLfloat nvlogo1[][2] = { + { -0.493508, 0.560265 }, + { -0.233835, 0.218981 }, + { -0.078033, -0.107463 }, + { 0.545180, 0.441557 }, + { 0.285509, 0.753164 }, + { -0.129966, 1.005420 }, + { -0.545442, 1.153800 }, + { -1.034999, 1.167860 }, + { -1.064784, 1.658310 }, + { -0.233835, 1.598950 }, + { 0.233576, 1.361540 }, + { 0.649050, 1.094450 }, + { 1.012591, 0.753164 }, + { 1.324197, 0.426719 }, + { 1.064524, 0.189305 }, + { 0.804852, -0.166817 }, + { 0.389378, -0.508100 }, + { -0.078033, -0.745515 }, + { -0.441573, -0.879060 }, + { -1.013530, -0.889070 }, + { -1.012851, 0.723487 }, +}; +GLfloat nvlogo2[][2] = { + { -1.025490, -2.159120 }, + { -1.843800, -1.962260 }, + { -2.415081, -1.635820 }, + { -2.934425, -1.205510 }, + { -3.297966, -0.760353 }, + { -3.609571, -0.315201 }, + { -3.869244, 0.204143 }, + { -3.973113, 0.545426 }, + { -3.505702, 0.960900 }, + { -2.830556, 1.435730 }, + { -2.051539, 1.851210 }, + { -1.064784, 2.058940 }, + { -1.064784, 1.658310 }, + { -1.791868, 1.495080 }, + { -2.363145, 1.183480 }, + { -2.830556, 0.842190 }, + { -3.194097, 0.471234 }, + { -3.090228, 0.055759 }, + { -2.830556, -0.315201 }, + { -2.570884, -0.760353 }, + { -2.103473, -1.220340 }, + { -1.584129, -1.531950 }, + { -1.025490, -1.731790 }, +}; +GLfloat nvlogo3[][2] = { + { -1.025490, -1.248240 }, + { -1.472016, -1.099371 }, + { -1.794030, -0.875934 }, + { -2.047038, -0.606495 }, + { -2.254046, -0.337056 }, + { -2.415053, -0.047902 }, + { -2.530060, 0.260968 }, + { -2.392054, 0.536978 }, + { -2.047038, 0.806418 }, + { -1.633023, 1.016710 }, + { -1.034999, 1.167860 }, + { -1.012851, 0.723487 }, + { -1.380012, 0.681555 }, + { -1.610022, 0.530407 }, + { -1.863033, 0.326685 }, + { -1.909033, 0.076960 }, + { -1.748027, -0.159620 }, + { -1.541019, -0.448774 }, + { -1.311010, -0.685355 }, + { -1.013530, -0.889070 }, +}; + +#define SIZE(a) (sizeof(a)/sizeof(a[0])) + +void +extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, + GLdouble thickness, GLuint side, GLuint edge, GLuint whole, + float breakAngle) +{ + static GLUtriangulatorObj *tobj = NULL; + GLdouble vertex[3], dx, dy, len; + GLdouble ndx, ndy, ondx, ondy, dot; + int i; + int count = (int) (dataSize / (2 * sizeof(GLfloat))); + + if (tobj == NULL) { + tobj = gluNewTess(); /* create and initialize a GLU + polygon tesselation object */ + gluTessCallback(tobj, GLU_BEGIN, glBegin); + gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ + gluTessCallback(tobj, GLU_END, glEnd); + } + glNewList(side, GL_COMPILE); + gluBeginPolygon(tobj); + for (i = 0; i < count; i++) { + vertex[0] = data[i][0]; + vertex[1] = data[i][1]; + vertex[2] = 0; + gluTessVertex(tobj, vertex, data[i]); + } + gluEndPolygon(tobj); + glEndList(); + glNewList(edge, GL_COMPILE); + glBegin(GL_QUAD_STRIP); + + dx = data[0][1] - data[-1 % count][1]; + dy = data[-1 % count][0] - data[0][0]; + len = sqrt(dx * dx + dy * dy); + ondx = dx / len; + ondy = dy / len; + + for (i = 0; i <= count; i++) { + /* mod function handles closing the edge */ + /* Calculate a unit normal by dividing by Euclidean + distance. We could be lazy and use + glEnable(GL_NORMALIZE) so we could pass in arbitrary + normals for a very slight performance hit. */ + dx = data[(i + 1) % count][1] - data[i % count][1]; + dy = data[i % count][0] - data[(i +1) % count][0]; + len = sqrt(dx * dx + dy * dy); + ndx = dx / len; + ndy = dy / len; + + dot = fabs(acos(ndx * ondx + ndy * ondy) * 180.0/3.14159); + + if (dot > breakAngle) { + glVertex3f(data[i % count][0], data[i % count][1], thickness); + glVertex3f(data[i % count][0], data[i % count][1], 0.0); + glNormal3f(ndx, ndy, 0.0); + } else { + GLdouble adx, ady, nadx, nady; + + adx = ndx + ondx; + ady = ndy + ondy; + len = sqrt(adx*adx + ady*ady); + nadx = adx / len; + nady = ady / len; + glNormal3f(nadx, nady, 0.0); + } + glVertex3f(data[i % count][0], data[i % count][1], thickness); + glVertex3f(data[i % count][0], data[i % count][1], 0.0); + + ondx = ndx; + ondy = ndy; + } + glEnd(); + glEndList(); + glNewList(whole, GL_COMPILE); + + glFrontFace(GL_CW); + glCallList(edge); + + glPushMatrix(); + glTranslatef(0.0, 0.0, thickness); + glFrontFace(GL_CW); + glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ + glCallList(side); + glPopMatrix(); + + glFrontFace(GL_CCW); + glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ + glCallList(side); + + glEndList(); +} + +GLuint +makeNVidiaLogo(GLuint dlistBase) +{ + const float extrudeWidth = 1.0; + const float breakAngle = 30.0; + + extrudeSolidFromPolygon(nvlogo0, sizeof(nvlogo0), extrudeWidth, + dlistBase+1, dlistBase+2, dlistBase+3, breakAngle); + extrudeSolidFromPolygon(nvlogo1, sizeof(nvlogo1), extrudeWidth, + dlistBase+4, dlistBase+5, dlistBase+6, breakAngle); + extrudeSolidFromPolygon(nvlogo2, sizeof(nvlogo2), extrudeWidth, + dlistBase+7, dlistBase+8, dlistBase+9, breakAngle); + extrudeSolidFromPolygon(nvlogo3, sizeof(nvlogo3), extrudeWidth, + dlistBase+10, dlistBase+11, dlistBase+12, breakAngle); + glNewList(dlistBase, GL_COMPILE); + glCallList(dlistBase+3); + glCallList(dlistBase+6); + glCallList(dlistBase+9); + glCallList(dlistBase+12); + glEndList(); + return dlistBase; +} + diff --git a/lib/glut-3.7.6/progs/advanced/occlude.c b/lib/glut-3.7.6/progs/advanced/occlude.c new file mode 100644 index 0000000000..994e59053f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/occlude.c @@ -0,0 +1,488 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 program demonstrates an OpenGL histogram extension based algorithm + for occlusion culling. Occlusion culling tries to speed rendering by + quickly determine what objects that are in the view frustrum are not + actually visible because they are occluded by other objects in the scene. + If object occlusion can be quickly determined, you can save time by simply + not rendering occluded objects. */ + +/* cc -o occlude occlude.c -lglut -lGL -lGLU -lXmu -lXext -lX11 -lm */ + +/* XXX Note that IMPACTs running IRIX 6.2 and earlier do not implement the + histogram extension over alpha correctly. The algorithm works correctly + on RealityEngine and InfiniteReality platforms. */ + +/* Hacked starting with the OpenGL programming Guide's scene.c */ + +#include +#include +#include +#include +#include + +#define TORUS 1 +#define TETRAHEDRON 2 +#define ICOSAHEDRON 3 + +int W = 250, H = 250; +int showBoxes = 0; +int single = 0; +int showHistogram = 0; +int showRate = 0; +int occlusionDectection = 1; +int nameOccludedTeapots = 1; +int noOcclude = 0; +int frames = 0; +int renderCount = 0, occludedCount = 0; + +void +output(GLfloat x, GLfloat y, char *format,...) +{ + va_list args; + char buffer[200], *p; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + glPushMatrix(); + glTranslatef(x, y, 0); + for (p = buffer; *p; p++) + glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); + glPopMatrix(); +} + +/* Initialize material property and light source. */ +void +myinit(void) +{ + GLfloat light_ambient[] = + {0.2, 0.2, 0.2, 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}; + + 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_LIGHT0); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + + glNewList(TORUS, GL_COMPILE); + glutSolidTorus(0.275, 0.85, 10, 15); + glEndList(); + glNewList(TETRAHEDRON, GL_COMPILE); + glutSolidTetrahedron(); + glEndList(); + glNewList(ICOSAHEDRON, GL_COMPILE); + glutSolidIcosahedron(); + glEndList(); + + /* Make sure we clear with alpha set to 1. */ + glClearColor(0, 0, 0, 1); + +#ifdef GL_EXT_histogram + /* Do a histogram on alpha with 8 bins; throw away the image data used when + computing the histogram. */ + glHistogramEXT(GL_HISTOGRAM_EXT, 8, GL_ALPHA, GL_TRUE); +#endif +} + +void +draw(void) +{ + glPushMatrix(); + glScalef(1.3, 1.3, 1.3); + glRotatef(23.0, 1.0, 0.0, 0.0); + + glPushMatrix(); + glTranslatef(-0.75, -0.5, 0.0); + glRotatef(270.0, 1.0, 0.0, 0.0); + glCallList(TETRAHEDRON); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-0.75, 0.5, 0.0); + glRotatef(90.0, 1.0, 0.0, 0.0); + glCallList(TORUS); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.75, 0.0, -1.0); + glCallList(ICOSAHEDRON); + glPopMatrix(); + + glPopMatrix(); +} + +void +myortho(void) +{ + 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); +} + +GLint turn = 90; +int dir = -3; + +void +idle(void) +{ + /* Make the angle alternate back and forth. */ + turn += dir; + if (turn > 50) + dir = -3; + if (turn <= 0) + dir = 3; + glutPostRedisplay(); +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); +} + +void +boundingBox(void) +{ + glScalef(1.9 * .6, 1.3 * .6, 1.2 * .6); + glutSolidCube(0.9); +} + +void +teapot(void) +{ + glutSolidTeapot(0.3); +} + +typedef void (*RenderFunc) (void); + +void +render1(RenderFunc func) +{ + glPushMatrix(); + glTranslatef(-0.75, 0.5, 0.0); + glRotatef(turn, 0.0, 1.0, 0.0); + glTranslatef(3.0, 0.0, 0.0); + glColor4f(0, 1, 0, .25); + func(); + glPopMatrix(); +} + +void +render2(RenderFunc func) +{ + glPushMatrix(); + glTranslatef(-0.75, 0.5, 0.0); + glRotatef(turn + 30, 0.0, 1.0, 0.0); + glTranslatef(3.0, 0.0, 0.0); + glColor4f(1, 0, 0, .5); + func(); + glPopMatrix(); +} + +void +render3(RenderFunc func) +{ + glPushMatrix(); + glTranslatef(-0.75, 0.5, 0.0); + glRotatef(turn + 60, 0.0, 1.0, 0.0); + glTranslatef(3.0, 0.0, 0.0); + glColor4f(0, 0, 1, .0); + func(); + glPopMatrix(); +} + +void +render4(RenderFunc func) +{ + glPushMatrix(); + glTranslatef(-0.75, -0.75, 0.0); + glRotatef(turn + 60, 0.0, 1.0, 0.0); + glTranslatef(3.0, 0.0, 0.0); + glColor4f(1, 1, 0, .75); + func(); + glPopMatrix(); +} + +void +render5(RenderFunc func) +{ + glPushMatrix(); + glTranslatef(-0.75, -0.25, 0.0); + glRotatef(turn + 45, 0.0, 1.0, 0.0); + glTranslatef(3.0, 0.0, 0.0); + glColor4f(1, 0, 1, .12); + func(); + glPopMatrix(); +} + +void +display(void) +{ + int teapot1, teapot2, teapot3, teapot4, teapot5; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + draw(); + + /* Draw all teapots. */ + teapot1 = teapot2 = teapot3 = teapot4 = teapot5 = 1; +#ifdef GL_EXT_histogram + if (occlusionDectection && !noOcclude) { + GLuint count_buffer[8]; + int i; + + glDisable(GL_LIGHTING); + if (!showBoxes) { + glDepthMask(GL_FALSE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + } + /* Render the bounding box for each teapot. */ + render1(boundingBox); + render2(boundingBox); + render3(boundingBox); + render4(boundingBox); + render5(boundingBox); + + glEnable(GL_HISTOGRAM_EXT); + /* Sort of cheat. I know all the teapots move in the center horizontal + half of the screen so only take the histogram over that area instead + of the full window. */ + glCopyPixels(0, H / 4, W, H / 2, GL_COLOR); + glGetHistogramEXT(GL_HISTOGRAM_EXT, GL_TRUE, + GL_ALPHA, GL_UNSIGNED_INT, count_buffer); + glDisable(GL_HISTOGRAM_EXT); + if (showHistogram) { + printf("%2d: ", turn); + for (i = 0; i < 8; i++) + printf(" %7d", count_buffer[i]); + printf("\n"); + } + /* Get the count from each histogram bucket for each teapot's bounding + box. */ + teapot1 = count_buffer[2]; + teapot2 = count_buffer[3]; + teapot3 = count_buffer[0]; + teapot4 = count_buffer[5]; + teapot5 = count_buffer[1]; + + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } +#endif + /* If each teapot needs to be drawn (ie, not occluded when occlusion + detection is enabled, draw it. */ + if (teapot1) { + render1(teapot); + renderCount++; + } else { + occludedCount++; + } + if (teapot2) { + render2(teapot); + renderCount++; + } else { + occludedCount++; + } + if (teapot3) { + render3(teapot); + renderCount++; + } else { + occludedCount++; + } + if (teapot4) { + render4(teapot); + renderCount++; + } else { + occludedCount++; + } + if (teapot5) { + render5(teapot); + renderCount++; + } else { + occludedCount++; + } + + /* To help see when occlusions take place, render the teapot number of each + + occluded teapot. */ + if (nameOccludedTeapots) { + if (!teapot1 || !teapot2 || !teapot3 || !teapot4 || !teapot5) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 3000, 0, 3000); + glMatrixMode(GL_MODELVIEW); + + glColor3f(1, 1, 0); /* Yellow text. */ + + if (!teapot1) { + glLoadIdentity(); + output(80, 2800, "1"); + } + if (!teapot2) { + glLoadIdentity(); + output(150, 2800, "2"); + } + if (!teapot3) { + glLoadIdentity(); + output(220, 2800, "3"); + } + if (!teapot4) { + glLoadIdentity(); + output(290, 2800, "4"); + } + if (!teapot5) { + glLoadIdentity(); + output(360, 2800, "5"); + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + } + if (!single) { + glutSwapBuffers(); + } else { + glFlush(); + } + frames++; +} + +void +reshape(int w, int h) +{ + W = w; + H = h; + glViewport(0, 0, W, H); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + myortho(); + glMatrixMode(GL_MODELVIEW); +} + +void +main_menu(int value) +{ + switch (value) { + case 666: + exit(0); + break; + case 0: + showBoxes = !showBoxes; + break; + case 1: + showHistogram = !showHistogram; + break; + case 2: + occlusionDectection = !occlusionDectection; + break; + case 3: + nameOccludedTeapots = !nameOccludedTeapots; + break; + case 4: + showRate = !showRate; + break; + case 5: + noOcclude = !noOcclude; + break; + } + glutPostRedisplay(); +} + +/* This timer callback will print out stats every three seconds of the frame + rate and precent of teapots occluded. */ +/* ARGSUSED */ +void +timer(int value) +{ + static int last = 0; + int now; + float time, total; + + now = glutGet(GLUT_ELAPSED_TIME); + time = (now - last) / 1000; + total = renderCount + occludedCount; + if (showRate) { + if (frames) { + if (occlusionDectection) { + printf("rate = %.1f (detection on) @ %%%.0f\n", + frames / time, occludedCount/total*100); + } else { + printf("rate = %.1f @ %%%.0f\n", + frames / time, occludedCount/total*100); + } + } + } + last = now; + frames = 0; + renderCount = 0; + occludedCount = 0; + glutTimerFunc(3000, timer, 0); +} + +int +main(int argc, char **argv) +{ + int has_histogram, has_logic_op; + + glutInit(&argc, argv); + glutInitWindowSize(W, H); + if (argc > 1 && !strcmp(argv[1], "-single")) { + single = 1; + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH | GLUT_ALPHA); + } else { + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_ALPHA); + } + glutCreateWindow(argv[0]); + has_histogram = glutExtensionSupported("GL_EXT_histogram"); + has_logic_op = glutExtensionSupported("GL_EXT_blend_logic_op"); + if (!has_histogram && !has_logic_op) { + fprintf(stderr, + "\nYour OpenGL implementation lacks support for\nEXT_histogram or EXT_blend_logic_op (or both).\n\n"); + exit(1); + } + myinit(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutCreateMenu(main_menu); + glutAddMenuEntry("Toggle occlusion detection", 2); + glutAddMenuEntry("Toggle bounding boxes", 0); + glutAddMenuEntry("Toggle histogram print", 1); + glutAddMenuEntry("Toggle name occluded teapots", 3); + glutAddMenuEntry("Toggle frame rate print", 4); + glutAddMenuEntry("Toggle histogram without occlusion", 5); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutVisibilityFunc(visible); + glutTimerFunc(3000, timer, 0); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/occlude.dsp b/lib/glut-3.7.6/progs/advanced/occlude.dsp new file mode 100644 index 0000000000..9ec526045b --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/occlude.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="occlude" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=occlude - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "occlude.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "occlude.mak" CFG="occlude - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "occlude - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "occlude - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "occlude - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "occlude - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "occlude - Win32 Release" +# Name "occlude - Win32 Debug" +# Begin Source File + +SOURCE=.\occlude.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/pointburst.c b/lib/glut-3.7.6/progs/advanced/pointburst.c new file mode 100644 index 0000000000..b6df5e3bc0 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/pointburst.c @@ -0,0 +1,567 @@ + +/* Copyright (c) Mark J. Kilgard, 1997, 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 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 SGIS_point_parameters + is present (supported on SGI's InfiniteReality hardware), the + particle size is attenuated based on eye distance. */ + +/* Now pointburst.c is extended to support the multi-vendor + EXT_point_parameters extension that has the same interface as the + SGIS extension (modulo the SGIS suffix/prefix). NVidia's Release 2 + OpenGL ICD driver supports the EXT_point_parameters extension. */ + +#include +#include +#include +#include /* for cos(), sin(), and sqrt() */ +#ifdef _WIN32 +#include /* for wglGetProcAddress */ +#endif +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#if 0 /* For debugging. */ +#undef GL_SGIS_point_parameters +#endif + +#if defined(GL_SGIS_point_parameters) && !defined(GL_EXT_point_parameters) +/* Use the EXT point parameters interface for the SGIS implementation. */ +#define GL_POINT_SIZE_MIN_EXT GL_POINT_SIZE_MIN_SGIS +#define GL_POINT_SIZE_MAX_EXT GL_POINT_SIZE_MAX_SGIS +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT GL_POINT_FADE_THRESHOLD_SIZE_SGIS +#define GL_DISTANCE_ATTENUATION_EXT GL_DISTANCE_ATTENUATION_SGIS +#define glPointParameterfEXT glPointParameterfSGIS +#define glPointParameterfvEXT glPointParameterfvSGIS +#define GL_EXT_point_parameters 1 +#endif + +#if !defined(GL_EXT_point_parameters) +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#if defined(_WIN32) && !defined(MESA) +/* Curse Microsoft for the insanity of wglGetProcAddress. */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +#define GL_EXT_point_parameters 1 +#endif +#endif + +#if defined(_WIN32) && !defined(MESA) +PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT; +PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT; +#endif + +int hasPointParameters; + +static GLfloat angle = -150; /* in degrees */ +static int spin = 0; +static int moving, begin; +static int newModel = 1; +static float time; +static int repeat = 1; +int useMipmaps = 1; +int linearFiltering = 1; +int useTexture = 1; + +#if GL_EXT_point_parameters +static GLfloat constant[3] = { 1/5.0, 0.0, 0.0 }; +static GLfloat linear[3] = { 0.0, 1/5.0, 0.0 }; +static GLfloat quadratic[3] = { 0.25, 0.0, 1/60.0 }; +#endif + +#define MAX_POINTS 2000 + +static int numPoints = 500; + +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; + } + time += 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; + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (newModel) + recalcModelView(); + + /* Draw the floor. */ + if (useTexture) { + 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_FALSE); + + if (useTexture) { + glDisable(GL_TEXTURE_2D); + } + glBegin(GL_POINTS); + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=pointburst - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pointburst.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pointburst.mak" CFG="pointburst - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pointburst - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "pointburst - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pointburst - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "pointburst - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pointburst - Win32 Release" +# Name "pointburst - Win32 Debug" +# Begin Source File + +SOURCE=.\pointburst.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/projshadow.c b/lib/glut-3.7.6/progs/advanced/projshadow.c new file mode 100644 index 0000000000..92fb6fa28f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/projshadow.c @@ -0,0 +1,377 @@ + +/* projshadow.c - by Tom McReynolds, SGI */ + +/* Rendering shadows using projective shadows. */ + +#include +#include + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum { + SPHERE = 1, CONE, LIGHT, LEFTWALL, FLOOR +}; + +enum { + X, Y, Z, W +}; +enum { + A, B, C, D +}; + +/* create a matrix that will project the desired shadow */ +void +shadowmatrix(GLfloat shadowMat[4][4], + GLfloat groundplane[4], + GLfloat lightpos[4]) +{ + GLfloat dot; + + /* find dot product between light position vector and ground plane normal */ + dot = groundplane[X] * lightpos[X] + + groundplane[Y] * lightpos[Y] + + groundplane[Z] * lightpos[Z] + + groundplane[W] * lightpos[W]; + + shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; + shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; + shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; + shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; + + shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; + shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; + shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; + shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; + + shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; + shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; + shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; + shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; + + shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; + shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; + shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; + shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; + +} + +/* find the plane equation given 3 points */ +void +findplane(GLfloat plane[4], + GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ + GLfloat vec0[3], vec1[3]; + + /* need 2 vectors to find cross product */ + vec0[X] = v1[X] - v0[X]; + vec0[Y] = v1[Y] - v0[Y]; + vec0[Z] = v1[Z] - v0[Z]; + + vec1[X] = v2[X] - v0[X]; + vec1[Y] = v2[Y] - v0[Y]; + vec1[Z] = v2[Z] - v0[Z]; + + /* find cross product to get A, B, and C of plane equation */ + plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; + plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); + plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + + plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} + +void +sphere(void) +{ + glPushMatrix(); + glTranslatef(60.f, -50.f, -360.f); + glCallList(SPHERE); + glPopMatrix(); +} + +void +cone(void) +{ + glPushMatrix(); + glTranslatef(-40.f, -40.f, -400.f); + glCallList(CONE); + glPopMatrix(); + +} + +enum { + NONE, SHADOW +}; + +int rendermode = NONE; + +void +menu(int mode) +{ + rendermode = mode; + glutPostRedisplay(); +} + +GLfloat leftwallshadow[4][4]; +GLfloat floorshadow[4][4]; + +GLfloat lightpos[] = +{50.f, 50.f, -320.f, 1.f}; + +void +redraw(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + if (rendermode == SHADOW) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(0.f, 0.f, 0.f); /* shadow color */ + + glPushMatrix(); + glMultMatrixf((GLfloat *) floorshadow); + cone(); + glPopMatrix(); + + glPushMatrix(); + glMultMatrixf((GLfloat *) floorshadow); + sphere(); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + /* walls */ + + if (rendermode == SHADOW) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + glEnd(); + + if (rendermode == SHADOW) { + glStencilFunc(GL_EQUAL, 1, 1); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(0.f, 0.f, 0.f); /* shadow color */ + glDisable(GL_DEPTH_TEST); + glPushMatrix(); + glMultMatrixf((GLfloat *) leftwallshadow); + cone(); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + glBegin(GL_QUADS); + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + glDisable(GL_LIGHTING); + glColor3f(1.f, 1.f, .7f); + glCallList(LIGHT); + glEnable(GL_LIGHTING); + glPopMatrix(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + cone(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + sphere(); + + glutSwapBuffers(); /* high end machines may need this */ +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + if (key == '\033') + exit(0); +} + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ + +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + GLUquadricObj *sphere, *cone, *base; + GLfloat plane[4]; + GLfloat v0[3], v1[3], v2[3]; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE); + (void) glutCreateWindow("projection shadows"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("No Shadows", NONE); + glutAddMenuEntry("Shadows", SHADOW); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* make shadow matricies */ + + /* 3 points on floor */ + v0[X] = -100.f; + v0[Y] = -100.f; + v0[Z] = -320.f; + v1[X] = 100.f; + v1[Y] = -100.f; + v1[Z] = -320.f; + v2[X] = 100.f; + v2[Y] = -100.f; + v2[Z] = -520.f; + + findplane(plane, v0, v1, v2); + shadowmatrix(floorshadow, plane, lightpos); + + /* 3 points on left wall */ + v0[X] = -100.f; + v0[Y] = -100.f; + v0[Z] = -320.f; + v1[X] = -100.f; + v1[Y] = -100.f; + v1[Z] = -520.f; + v2[X] = -100.f; + v2[Y] = 100.f; + v2[Z] = -520.f; + + findplane(plane, v0, v1, v2); + shadowmatrix(leftwallshadow, plane, lightpos); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* make display lists for sphere and cone; for efficiency */ + + glNewList(SPHERE, GL_COMPILE); + sphere = gluNewQuadric(); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(LIGHT, GL_COMPILE); + sphere = gluNewQuadric(); + gluSphere(sphere, 5.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glNewList(FLOOR, GL_COMPILE); + glEndList(); + + glNewList(LEFTWALL, GL_COMPILE); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/projshadow.dsp b/lib/glut-3.7.6/progs/advanced/projshadow.dsp new file mode 100644 index 0000000000..d385ea6dc2 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/projshadow.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="projshadow" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=projshadow - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "projshadow.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "projshadow.mak" CFG="projshadow - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "projshadow - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "projshadow - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "projshadow - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "projshadow - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "projshadow - Win32 Release" +# Name "projshadow - Win32 Debug" +# Begin Source File + +SOURCE=.\projshadow.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/projtex.c b/lib/glut-3.7.6/progs/advanced/projtex.c new file mode 100644 index 0000000000..766916fa42 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/projtex.c @@ -0,0 +1,916 @@ + +/* projtex.c - by David Yu and David Blythe, SGI */ + +/** + ** Demonstrates simple projective texture mapping. + ** + ** Button1 changes view, Button2 moves texture. + ** + ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli + ** "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92) + ** + ** 1994,1995 -- David G Yu + ** + ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm + **/ + +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +int winWidth, winHeight; + +GLboolean redrawContinuously = GL_FALSE; + +float angle, axis[3]; +enum MoveModes { + MoveNone, MoveView, MoveObject, MoveTexture +}; +enum MoveModes mode = MoveNone; + +GLfloat objectXform[4][4]; +GLfloat textureXform[4][4]; + +void (*drawObject) (void); +void (*loadTexture) (void); +GLboolean textureEnabled = GL_TRUE; +GLboolean showProjection = GL_TRUE; +GLboolean linearFilter = GL_TRUE; + +char *texFilename = NULL; + +GLfloat zoomFactor = 1.0; + +/*****************************************************************/ + +/* matrix = identity */ +void +matrixIdentity(GLfloat matrix[16]) +{ + matrix[0] = 1.0; + matrix[1] = 0.0; + matrix[2] = 0.0; + matrix[3] = 0.0; + matrix[4] = 0.0; + matrix[5] = 1.0; + matrix[6] = 0.0; + matrix[7] = 0.0; + matrix[8] = 0.0; + matrix[9] = 0.0; + matrix[10] = 1.0; + matrix[11] = 0.0; + matrix[12] = 0.0; + matrix[13] = 0.0; + matrix[14] = 0.0; + matrix[15] = 1.0; +} + +/* matrix2 = transpose(matrix1) */ +void +matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16]) +{ + matrix2[0] = matrix1[0]; + matrix2[1] = matrix1[4]; + matrix2[2] = matrix1[8]; + matrix2[3] = matrix1[12]; + + matrix2[4] = matrix1[1]; + matrix2[5] = matrix1[5]; + matrix2[6] = matrix1[9]; + matrix2[7] = matrix1[13]; + + matrix2[8] = matrix1[2]; + matrix2[9] = matrix1[6]; + matrix2[10] = matrix1[10]; + matrix2[11] = matrix1[14]; + + matrix2[12] = matrix1[3]; + matrix2[13] = matrix1[7]; + matrix2[14] = matrix1[14]; + matrix2[15] = matrix1[15]; +} + +/*****************************************************************/ + +/* load SGI .rgb image (pad with a border of the specified width and color) */ +static void +imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], + int *wOut, int *hOut, GLubyte ** imgOut) +{ + int border = borderIn; + int width, height; + int w, h; + GLubyte *image, *img, *p; + int i, j, components; + + image = (GLubyte *) read_texture(filenameIn, &width, &height, &components); + w = width + 2 * border; + h = height + 2 * border; + img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char)); + + p = img; + for (j = -border; j < height + border; ++j) { + for (i = -border; i < width + border; ++i) { + if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { + p[0] = image[4 * (j * width + i) + 0]; + p[1] = image[4 * (j * width + i) + 1]; + p[2] = image[4 * (j * width + i) + 2]; + p[3] = 0xff; + } else { + p[0] = borderColorIn[0] * 0xff; + p[1] = borderColorIn[1] * 0xff; + p[2] = borderColorIn[2] * 0xff; + p[3] = borderColorIn[3] * 0xff; + } + p += 4; + } + } + free(image); + *wOut = w; + *hOut = h; + *imgOut = img; +} + +/*****************************************************************/ + +/* Load the image file specified on the command line as the current texture */ +void +loadImageTexture(void) +{ + static int texWidth, texHeight; + static GLubyte *texData; + GLfloat borderColor[4] = + {1.0, 1.0, 1.0, 1.0}; + + if (!texData && texFilename) { + imgLoad(texFilename, 2, borderColor, &texWidth, &texHeight, &texData); + } + if (linearFilter) { + 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); + } + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, texData); +} + +/* Create a simple spotlight pattern and make it the current texture */ +void +loadSpotlightTexture(void) +{ + static int texWidth = 64, texHeight = 64; + static GLubyte *texData; + GLfloat borderColor[4] = + {0.1, 0.1, 0.1, 1.0}; + + if (!texData) { + GLubyte *p; + int i, j; + + texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte)); + + p = texData; + for (j = 0; j < texHeight; ++j) { + float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5); + + for (i = 0; i < texWidth; ++i) { + float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5); + float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy)); + float c; + + r = (r < 0) ? 0 : r * r; + c = 0xff * (r + borderColor[0]); + p[0] = (c <= 0xff) ? c : 0xff; + c = 0xff * (r + borderColor[1]); + p[1] = (c <= 0xff) ? c : 0xff; + c = 0xff * (r + borderColor[2]); + p[2] = (c <= 0xff) ? c : 0xff; + c = 0xff * (r + borderColor[3]); + p[3] = (c <= 0xff) ? c : 0xff; + p += 4; + } + } + } + if (linearFilter) { + 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); + } + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, texData); +} + +/*****************************************************************/ + +void +checkErrors(void) +{ + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); + } +} + +void +drawCube(void) +{ + glBegin(GL_QUADS); + + glNormal3f(-1.0, 0.0, 0.0); + glColor3f(0.80, 0.50, 0.50); + glVertex3f(-0.5, -0.5, -0.5); + glVertex3f(-0.5, -0.5, 0.5); + glVertex3f(-0.5, 0.5, 0.5); + glVertex3f(-0.5, 0.5, -0.5); + + glNormal3f(1.0, 0.0, 0.0); + glColor3f(0.50, 0.80, 0.50); + glVertex3f(0.5, 0.5, 0.5); + glVertex3f(0.5, -0.5, 0.5); + glVertex3f(0.5, -0.5, -0.5); + glVertex3f(0.5, 0.5, -0.5); + + glNormal3f(0.0, -1.0, 0.0); + glColor3f(0.50, 0.50, 0.80); + glVertex3f(-0.5, -0.5, -0.5); + glVertex3f(0.5, -0.5, -0.5); + glVertex3f(0.5, -0.5, 0.5); + glVertex3f(-0.5, -0.5, 0.5); + + glNormal3f(0.0, 1.0, 0.0); + glColor3f(0.50, 0.80, 0.80); + glVertex3f(0.5, 0.5, 0.5); + glVertex3f(0.5, 0.5, -0.5); + glVertex3f(-0.5, 0.5, -0.5); + glVertex3f(-0.5, 0.5, 0.5); + + glNormal3f(0.0, 0.0, -1.0); + glColor3f(0.80, 0.50, 0.80); + glVertex3f(-0.5, -0.5, -0.5); + glVertex3f(-0.5, 0.5, -0.5); + glVertex3f(0.5, 0.5, -0.5); + glVertex3f(0.5, -0.5, -0.5); + + glNormal3f(0.0, 0.0, 1.0); + glColor3f(1.00, 0.80, 0.50); + glVertex3f(0.5, 0.5, 0.5); + glVertex3f(-0.5, 0.5, 0.5); + glVertex3f(-0.5, -0.5, 0.5); + glVertex3f(0.5, -0.5, 0.5); + glEnd(); +} + +void +drawDodecahedron(void) +{ +#define A (0.5 * 1.61803) /* (sqrt(5) + 1) / 2 */ +#define B (0.5 * 0.61803) /* (sqrt(5) - 1) / 2 */ +#define C (0.5 * 1.0) + GLfloat vertexes[20][3] = + { + {-A, 0.0, B}, + {-A, 0.0, -B}, + {A, 0.0, -B}, + {A, 0.0, B}, + {B, -A, 0.0}, + {-B, -A, 0.0}, + {-B, A, 0.0}, + {B, A, 0.0}, + {0.0, B, -A}, + {0.0, -B, -A}, + {0.0, -B, A}, + {0.0, B, A}, + {-C, -C, C}, + {-C, -C, -C}, + {C, -C, -C}, + {C, -C, C}, + {-C, C, C}, + {-C, C, -C}, + {C, C, -C}, + {C, C, C}, + }; +#undef A +#undef B +#undef C + GLint polygons[12][5] = + { + {0, 12, 10, 11, 16}, + {1, 17, 8, 9, 13}, + {2, 14, 9, 8, 18}, + {3, 19, 11, 10, 15}, + {4, 14, 2, 3, 15}, + {5, 12, 0, 1, 13}, + {6, 17, 1, 0, 16}, + {7, 19, 3, 2, 18}, + {8, 17, 6, 7, 18}, + {9, 14, 4, 5, 13}, + {10, 12, 5, 4, 15}, + {11, 19, 7, 6, 16}, + }; + int i; + + glColor3f(0.75, 0.75, 0.75); + for (i = 0; i < 12; ++i) { + GLfloat *p0, *p1, *p2, d; + GLfloat u[3], v[3], n[3]; + + p0 = &vertexes[polygons[i][0]][0]; + p1 = &vertexes[polygons[i][1]][0]; + p2 = &vertexes[polygons[i][2]][0]; + + u[0] = p2[0] - p1[0]; + u[1] = p2[1] - p1[1]; + u[2] = p2[2] - p1[2]; + + v[0] = p0[0] - p1[0]; + v[1] = p0[1] - p1[1]; + v[2] = p0[2] - p1[2]; + + 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]; + + d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); + n[0] *= d; + n[1] *= d; + n[2] *= d; + + glBegin(GL_POLYGON); + glNormal3fv(n); + glVertex3fv(p0); + glVertex3fv(p1); + glVertex3fv(p2); + glVertex3fv(vertexes[polygons[i][3]]); + glVertex3fv(vertexes[polygons[i][4]]); + glEnd(); + } +} + +void +drawSphere(void) +{ + int numMajor = 24; + int numMinor = 32; + float radius = 0.8; + double majorStep = (M_PI / numMajor); + double minorStep = (2.0 * M_PI / numMinor); + int i, j; + + glColor3f(0.50, 0.50, 0.50); + for (i = 0; i < numMajor; ++i) { + double a = i * majorStep; + double b = a + majorStep; + double r0 = radius * sin(a); + double r1 = radius * sin(b); + GLfloat z0 = radius * cos(a); + GLfloat z1 = radius * cos(b); + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j <= numMinor; ++j) { + double c = j * minorStep; + GLfloat x = cos(c); + GLfloat y = sin(c); + + glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius); + glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor); + glVertex3f(x * r0, y * r0, z0); + + glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius); + glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor); + glVertex3f(x * r1, y * r1, z1); + } + glEnd(); + } +} + +/*****************************************************************/ + +float xmin = -0.035, xmax = 0.035; +float ymin = -0.035, ymax = 0.035; +float nnear = 0.1; +float ffar = 1.9; +float distance = -1.0; + +static void +loadTextureProjection(GLfloat m[16]) +{ + GLfloat mInverse[4][4]; + + /* Should use true inverse, but since m consists only of rotations, we can + just use the transpose. */ + matrixTranspose((GLfloat *) mInverse, m); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(0.5, 0.5, 0.0); + glScalef(0.5, 0.5, 1.0); + glFrustum(xmin, xmax, ymin, ymax, nnear, ffar); + glTranslatef(0.0, 0.0, distance); + glMultMatrixf((GLfloat *) mInverse); + glMatrixMode(GL_MODELVIEW); +} + +static void +drawTextureProjection(void) +{ + float t = ffar / nnear; + GLfloat n[4][3]; + GLfloat f[4][3]; + + n[0][0] = xmin; + n[0][1] = ymin; + n[0][2] = -(nnear + distance); + + n[1][0] = xmax; + n[1][1] = ymin; + n[1][2] = -(nnear + distance); + + n[2][0] = xmax; + n[2][1] = ymax; + n[2][2] = -(nnear + distance); + + n[3][0] = xmin; + n[3][1] = ymax; + n[3][2] = -(nnear + distance); + + f[0][0] = xmin * t; + f[0][1] = ymin * t; + f[0][2] = -(ffar + distance); + + f[1][0] = xmax * t; + f[1][1] = ymin * t; + f[1][2] = -(ffar + distance); + + f[2][0] = xmax * t; + f[2][1] = ymax * t; + f[2][2] = -(ffar + distance); + + f[3][0] = xmin * t; + f[3][1] = ymax * t; + f[3][2] = -(ffar + distance); + + glColor3f(1.0, 1.0, 0.0); + glBegin(GL_LINE_LOOP); + glVertex3fv(n[0]); + glVertex3fv(n[1]); + glVertex3fv(n[2]); + glVertex3fv(n[3]); + glVertex3fv(f[3]); + glVertex3fv(f[2]); + glVertex3fv(f[1]); + glVertex3fv(f[0]); + glVertex3fv(n[0]); + glVertex3fv(n[1]); + glVertex3fv(f[1]); + glVertex3fv(f[0]); + glVertex3fv(f[3]); + glVertex3fv(f[2]); + glVertex3fv(n[2]); + glVertex3fv(n[3]); + glEnd(); +} + +/*****************************************************************/ + +void +initialize(void) +{ + GLfloat light0Pos[4] = + {0.3, 0.3, 0.0, 1.0}; + GLfloat matAmb[4] = + {0.01, 0.01, 0.01, 1.00}; + GLfloat matDiff[4] = + {0.65, 0.65, 0.65, 1.00}; + GLfloat matSpec[4] = + {0.30, 0.30, 0.30, 1.00}; + GLfloat matShine = 10.0; + GLfloat eyePlaneS[] = + {1.0, 0.0, 0.0, 0.0}; + GLfloat eyePlaneT[] = + {0.0, 1.0, 0.0, 0.0}; + GLfloat eyePlaneR[] = + {0.0, 0.0, 1.0, 0.0}; + GLfloat eyePlaneQ[] = + {0.0, 0.0, 0.0, 1.0}; + + /* Setup Misc. */ + glClearColor(0.41, 0.41, 0.31, 0.0); + + glEnable(GL_DEPTH_TEST); + + glLineWidth(2.0); + + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + + glMatrixMode(GL_PROJECTION); + glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3); + glMatrixMode(GL_MODELVIEW); + glTranslatef(0, 0, -2); + + matrixIdentity((GLfloat *) objectXform); + matrixIdentity((GLfloat *) textureXform); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glRasterPos2i(0, 0); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + /* Setup Lighting */ + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine); + + glEnable(GL_COLOR_MATERIAL); + + glLightfv(GL_LIGHT0, GL_POSITION, light0Pos); + glEnable(GL_LIGHT0); + + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glEnable(GL_LIGHTING); + + /* Setup Texture */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + (*loadTexture) (); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS); + + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT); + + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR); + + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (textureEnabled) { + if (mode == MoveTexture || mode == MoveView) { + /* Have OpenGL compute the new transformation (simple but slow). */ + glPushMatrix(); + glLoadIdentity(); + glRotatef(angle, axis[0], axis[1], axis[2]); + glMultMatrixf((GLfloat *) textureXform); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform); + glPopMatrix(); + } + loadTextureProjection((GLfloat *) textureXform); + + if (showProjection) { + glPushMatrix(); + glMultMatrixf((GLfloat *) textureXform); + glDisable(GL_LIGHTING); + drawTextureProjection(); + glEnable(GL_LIGHTING); + glPopMatrix(); + } + glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_GEN_Q); + } + if (mode == MoveObject || mode == MoveView) { + /* Have OpenGL compute the new transformation (simple but slow). */ + glPushMatrix(); + glLoadIdentity(); + glRotatef(angle, axis[0], axis[1], axis[2]); + glMultMatrixf((GLfloat *) objectXform); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform); + glPopMatrix(); + } + glPushMatrix(); + glMultMatrixf((GLfloat *) objectXform); + (*drawObject) (); + glPopMatrix(); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + glDisable(GL_TEXTURE_GEN_Q); + + if (zoomFactor > 1.0) { + glDisable(GL_DEPTH_TEST); + glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR); + glEnable(GL_DEPTH_TEST); + } + glFlush(); + glutSwapBuffers(); + checkErrors(); +} + +/*****************************************************************/ + +/* simple trackball-like motion control */ +float lastPos[3]; +int lastTime; + +void +ptov(int x, int y, int width, int height, float v[3]) +{ + float d, a; + + /* project x,y onto a hemi-sphere centered within width, height */ + v[0] = (2.0 * x - width) / width; + v[1] = (height - 2.0 * y) / height; + d = sqrt(v[0] * v[0] + v[1] * v[1]); + v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0)); + a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] *= a; + v[1] *= a; + v[2] *= a; +} + +void +startMotion(int x, int y, int but, int time) +{ + if (but == GLUT_LEFT_BUTTON) { + mode = MoveView; + } else if (but == GLUT_MIDDLE_BUTTON) { + mode = MoveTexture; + } else { + return; + } + + lastTime = time; + ptov(x, y, winWidth, winHeight, lastPos); +} + +void +animate(void) +{ + glutPostRedisplay(); +} + +void +vis(int visible) +{ + if (visible == GLUT_VISIBLE) { + if (redrawContinuously) + glutIdleFunc(animate); + } else { + if (redrawContinuously) + glutIdleFunc(NULL); + } +} + +void +stopMotion(int but, int time) +{ + if ((but == GLUT_LEFT_BUTTON && mode == MoveView) || + (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) { + } else { + return; + } + + if (time == lastTime) { + redrawContinuously = GL_TRUE; + glutIdleFunc(animate); + } else { + angle = 0.0; + redrawContinuously = GL_FALSE; + glutIdleFunc(0); + } + if (!redrawContinuously) { + mode = MoveNone; + } +} + +void +trackMotion(int x, int y) +{ + float curPos[3], dx, dy, dz; + + ptov(x, y, winWidth, winHeight, curPos); + + dx = curPos[0] - lastPos[0]; + dy = curPos[1] - lastPos[1]; + dz = curPos[2] - lastPos[2]; + angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); + + axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1]; + axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2]; + axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0]; + + lastTime = glutGet(GLUT_ELAPSED_TIME); + lastPos[0] = curPos[0]; + lastPos[1] = curPos[1]; + lastPos[2] = curPos[2]; + glutPostRedisplay(); +} + +/*****************************************************************/ + +void +object(void) +{ + static int object; + + object++; + object %= 3; + switch (object) { + case 0: + drawObject = drawCube; + break; + case 1: + drawObject = drawDodecahedron; + break; + case 2: + drawObject = drawSphere; + break; + default: + break; + } +} + +static void +nop(void) +{ +} + +void +texture(void) +{ + static int texture = 0; + + texture++; + texture %= 3; + if (texture == 1 && texFilename == NULL) { + /* Skip file texture if not loaded. */ + texture++; + } + switch (texture) { + case 0: + loadTexture = nop; + textureEnabled = GL_FALSE; + break; + case 1: + loadTexture = loadImageTexture; + (*loadTexture) (); + textureEnabled = GL_TRUE; + break; + case 2: + loadTexture = loadSpotlightTexture; + (*loadTexture) (); + textureEnabled = GL_TRUE; + break; + default: + break; + } +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'l' - toggle linear/nearest filter\n"); + printf("'s' - toggle projection frustum\n"); + printf("'t' - toggle projected texture\n"); + printf("'o' - toggle object\n"); + printf("'z' - increase zoom factor\n"); + printf("'Z' - decrease zoom factor\n"); + printf("left mouse - move view\n"); + printf("middle mouse - move projection\n"); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + break; + case 'l': + linearFilter = !linearFilter; + (*loadTexture) (); + break; + case 's': + showProjection = !showProjection; + break; + case 't': + texture(); + break; + case 'o': + object(); + break; + case 'z': + zoomFactor += 1.0; + glPixelZoom(zoomFactor, zoomFactor); + glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); + break; + case 'Z': + zoomFactor -= 1.0; + if (zoomFactor < 1.0) + zoomFactor = 1.0; + glPixelZoom(zoomFactor, zoomFactor); + glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor); + break; + case 'h': + help(); + break; + } + glutPostRedisplay(); +} + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) + startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP) + stopMotion(button, glutGet(GLUT_ELAPSED_TIME)); + glutPostRedisplay(); +} + +void +reshape(int w, int h) +{ + winWidth = w; + winHeight = h; + glViewport(0, 0, w / zoomFactor, h / zoomFactor); +} + +void +usage(char *name) +{ + fprintf(stderr, "usage: %s \n", name); + fprintf(stderr, "\n"); +} + +void +menu(int selection) +{ + if (selection == 666) { + exit(0); + } + key((unsigned char) selection, 0, 0); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); + (void) glutCreateWindow("projtex"); + if (argc > 2) { + usage(argv[0]); + exit(1); + } + if (argc > 1) { + texFilename = argv[1]; + } + loadTexture = loadImageTexture; + drawObject = drawCube; + initialize(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(trackMotion); + glutVisibilityFunc(vis); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle showing projection", 's'); + glutAddMenuEntry("Switch texture", 't'); + glutAddMenuEntry("Switch object", 'o'); + glutAddMenuEntry("Toggle filtering", 'l'); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + texture(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/projtex.dsp b/lib/glut-3.7.6/progs/advanced/projtex.dsp new file mode 100644 index 0000000000..ed88e0922f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/projtex.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="projtex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=projtex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "projtex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "projtex.mak" CFG="projtex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "projtex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "projtex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "projtex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "projtex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "projtex - Win32 Release" +# Name "projtex - Win32 Debug" +# Begin Source File + +SOURCE=.\projtex.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/rasonly.c b/lib/glut-3.7.6/progs/advanced/rasonly.c new file mode 100644 index 0000000000..9ffce8f8c7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/rasonly.c @@ -0,0 +1,326 @@ +/* + * rasonly.c - + * Demonstrates the use of OpenGL for rasterization-only, with + * perspective-correct texture mapping. + * + * Michael I. Gold + * Silicon Graphics Computer Systems, May 1997 + * + * Since current low-end 3D accelerators support only rasterization in + * hardware, a number of developers have expressed interested in using + * OpenGL as an interface to rasterization hardware while retaining + * control of transformations and lighting in the application code. + * Many OpenGL implementations detect and optimize for identity xforms, + * so this approach is entirely reasonable. + * + * Setting up rasterization-only is fairly straightforward. The projection + * matrix is set up as a one-to-one mapping between eye and clip coordinates, + * and the modelview matrix is set up as identity, e.g. object coordinates + * map directly to eye coordinates. This can be achieved as follows: + * + * glMatrixMode(GL_PROJECTION); + * glLoadIdentity(); + * glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f); + * glMatrixMode(GL_MODELVIEW); + * glLoadIdentity(); + * glViewport(0, 0, width, height); + * + * where (width, height) represent the window dimensions. + * + * Now transformed geometry may be specified directly through the standard + * interfaces (e.g. glVertex*()). The only tricky part that remains is + * specifying texture coordinates such that perspective correction may + * occur. The answer is to use glTexCoord4*(), and perform the perspective + * divide on the texture coordinates directly. + */ + +#include +#include +#include + +GLboolean motion = GL_TRUE; + +/* Matrices */ +GLfloat rot = 0.0f; +GLfloat ModelView[16]; +GLfloat Projection[16]; +GLfloat Viewport[4]; + +/* Sample geometry */ +GLfloat quadV[][4] = { + { -1.0f, 0.0f, -1.0f, 1.0f }, + { 1.0f, 0.0f, -1.0f, 1.0f }, + { 1.0f, 0.5f, -0.2f, 1.0f }, + { -1.0f, 0.5f, -0.2f, 1.0f }, +}; + +GLfloat quadC[][3] = { + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f }, +}; + +GLfloat quadT[][2] = { + { 0.0f, 0.0f }, + { 0.0f, 1.0f }, + { 1.0f, 1.0f }, + { 1.0f, 0.0f }, +}; + +/********************************************************************* + * Utility functions + */ + +int texWidth = 128; +int texHeight = 128; + +/* Create and download the application texture map */ +static void +setCheckedTexture(void) +{ + int texSize; + void *textureBuf; + GLubyte *p; + int i,j; + + /* malloc for rgba as worst case */ + texSize = texWidth*texHeight*4; + + textureBuf = malloc(texSize); + if (NULL == textureBuf) return; + + p = (GLubyte *)textureBuf; + for (i=0; i < texWidth; i++) { + for (j=0; j < texHeight; j++) { + if ((i ^ j) & 8) { + p[0] = 0xff; p[1] = 0xff; p[2] = 0xff; p[3] = 0xff; + } else { + p[0] = 0x08; p[1] = 0x08; p[2] = 0x08; p[3] = 0xff; + } + p += 4; + } + } + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight, + GL_RGBA, GL_UNSIGNED_BYTE, textureBuf); + free(textureBuf); +} + +/* Perform one transform operation */ +static void +Transform(GLfloat *matrix, GLfloat *in, GLfloat *out) +{ + int ii; + + for (ii=0; ii<4; ii++) { + out[ii] = + in[0] * matrix[0*4+ii] + + in[1] * matrix[1*4+ii] + + in[2] * matrix[2*4+ii] + + in[3] * matrix[3*4+ii]; + } +} + +/* Transform a vertex from object coordinates to window coordinates. + * Lighting is left as an exercise for the reader. + */ +static void +DoTransform(GLfloat *in, GLfloat *out) +{ + GLfloat tmp[4]; + GLfloat invW; /* 1/w */ + + /* Modelview xform */ + Transform(ModelView, in, tmp); + + /* Lighting calculation goes here! */ + + /* Projection xform */ + Transform(Projection, tmp, out); + + if (out[3] == 0.0f) /* do what? */ + return; + + invW = 1.0f / out[3]; + + /* Perspective divide */ + out[0] *= invW; + out[1] *= invW; + out[2] *= invW; + + /* Map to 0..1 range */ + out[0] = out[0] * 0.5f + 0.5f; + out[1] = out[1] * 0.5f + 0.5f; + out[2] = out[2] * 0.5f + 0.5f; + + /* Map to viewport */ + out[0] = out[0] * Viewport[2] + Viewport[0]; + out[1] = out[1] * Viewport[3] + Viewport[1]; + + /* Store inverted w for performance */ + out[3] = invW; +} + +/********************************************************************* + * Application code begins here + */ + +/* For the sake of brevity, I'm use OpenGL to compute my matrices. */ +void UpdateModelView(void) +{ + glPushMatrix(); + glLoadIdentity(); + gluLookAt(0.0f, 1.0f, -4.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f); + glRotatef(rot, 0.0f, 1.0f, 0.0f); + /* Retrieve the matrix */ + glGetFloatv(GL_MODELVIEW_MATRIX, ModelView); + glPopMatrix(); +} + +void InitMatrices(void) +{ + /* Calculate projection matrix */ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPerspective(45.0f, 1.0f, 1.0f, 100.0f); + /* Retrieve the matrix */ + glGetFloatv(GL_PROJECTION_MATRIX, Projection); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + UpdateModelView(); +} + +void Init(void) +{ + glClearColor(0.2f, 0.2f, 0.6f, 1.0f); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + setCheckedTexture(); + + InitMatrices(); +} + +void Redraw(void) +{ + GLfloat tmp[4]; + int ii; + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glBegin(GL_QUADS); + + for (ii = 0; ii < 4; ii++) { + + /* Transform a vertex from object to window coordinates. + * 1/w is returned as tmp[3] for perspective-correcting + * the texture coordinates. + */ + DoTransform(quadV[ii], tmp); + + /* Ideally the colors will be computed by the lighting equation, + * but I've hard-coded values for this example. + */ + glColor3fv(quadC[ii]); + + /* Scale by 1/w (stored in tmp[3]) */ + glTexCoord4f(quadT[ii][0] * tmp[3], + quadT[ii][1] * tmp[3], 0.0f, tmp[3]); + + /* Note I am using Vertex3, not Vertex4, since we have already + * performed the perspective divide. + */ + glVertex3fv(tmp); + } + + glEnd(); + + glutSwapBuffers(); +} + +void Motion(void) +{ + rot += 3.0f; + if (rot >= 360.0f) rot -= 360.0f; + UpdateModelView(); + Redraw(); +} + +/* ARGSUSED1 */ +void Key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + case 'm': + motion = !motion; + glutIdleFunc(motion ? Motion : NULL); + break; + } +} + +/* ARGSUSED1 */ +void Button(int button, int state, int x, int y) +{ + switch (button) { + case GLUT_LEFT_BUTTON: + if (state == GLUT_DOWN) { + rot -= 15.0f; + UpdateModelView(); + Redraw(); + } + break; + case GLUT_RIGHT_BUTTON: + if (state == GLUT_DOWN) { + rot += 15.0f; + UpdateModelView(); + Redraw(); + } + break; + } +} + +void Reshape(int width, int height) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glViewport(0, 0, width, height); + + Viewport[0] = Viewport[1] = 0.0f; + Viewport[2] = (GLfloat) width; + Viewport[3] = (GLfloat) height; +} + +int +main(int argc, char *argv[]) +{ + char *t; + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); + glutInitWindowSize(400, 400); + glutCreateWindow((t=strrchr(argv[0], '\\')) != NULL ? t+1 : argv[0]); + + Init(); + + glutDisplayFunc(Redraw); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutMouseFunc(Button); + glutIdleFunc(Motion); + + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced/rasonly.dsp b/lib/glut-3.7.6/progs/advanced/rasonly.dsp new file mode 100644 index 0000000000..5803d3848a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/rasonly.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="rasonly" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rasonly - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rasonly.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rasonly.mak" CFG="rasonly - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rasonly - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "rasonly - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rasonly - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "rasonly - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rasonly - Win32 Release" +# Name "rasonly - Win32 Debug" +# Begin Source File + +SOURCE=.\rasonly.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/redblue_stereo.c b/lib/glut-3.7.6/progs/advanced/redblue_stereo.c new file mode 100644 index 0000000000..902a0298d2 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/redblue_stereo.c @@ -0,0 +1,289 @@ + +/* redblue_stereo.c - demo of stereo for red/blue filter stereo glasses */ + +/* by Walter Vannini (walterv@jps.net, waltervannini@hotmail.com) */ + +/* In stereo mode, the object is drawn in red for the left eye + and blue for the right eye. Viewing the scene with red/blue + filter stereo glasses should give a sense of stereo 3D. + glColorMask is used to control update of the red and blue + channel. glFrustum is used to setup two different view frustums + for each eye based on eye separation. */ + +/* Copyright (c) Walter Vannini, 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 +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void init(void); +void KeyboardFunc(unsigned char key, int x, int y); +void MenuFunc(int value); +void IdleFunc(void); +void ReshapeFunc(int w, int h); +void DisplayFunc(void); + + +struct ProgramState +{ + int w; + int h; + GLdouble RotationY; + double eye; + double zscreen; + double znear; + double zfar; + double RotationIncrement; + int solidmode; +}; +struct ProgramState ps; + +const double PIXELS_PER_INCH = 100.0; + +void init(void) +{ + GLfloat mat_ambient[] = {0.2,0.0,0.2,1.0} ; + GLfloat mat_diffuse[] = {0.7,0.0,0.7,1.0} ; + GLfloat mat_specular[] = {0.1,0.0,0.1,1.0} ; + GLfloat mat_shininess[]={20.0}; + + GLfloat light_position[]={0.0,5.0,20.0,1.0}; + + GLfloat light_ambient0[]= {1.0,0.0,0.0,1.0}; + GLfloat light_diffuse0[]= {1.0,0.0,0.0,1.0}; + GLfloat light_specular0[]={1.0,0.0,0.0,1.0}; + + GLfloat light_ambient1[]= {0.0,0.0,1.0,1.0}; + GLfloat light_diffuse1[]= {0.0,0.0,1.0,1.0}; + GLfloat light_specular1[]={0.0,0.0,1.0,1.0}; + + glDisable(GL_DITHER); + glClearColor(0.0, 0.0, 0.0, 1.0); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glEnable(GL_CULL_FACE); + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + + + 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, light_position); + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient0); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular0); + + glLightfv(GL_LIGHT1, GL_POSITION, light_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient1); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1); + glEnable(GL_LIGHTING); + + ps.eye=0.80; + ps.zscreen = 10.0; + ps.znear = 7.0; + ps.zfar = 13.0; + ps.RotationY = 0.0; + ps.RotationIncrement = 4.0; + ps.solidmode = 1; +} + +void KeyboardFunc(unsigned char key, int x, int y) +{ + switch(key) + { + case 27: /* escape */ + case 'q': + case 'Q': + exit(0); + break; + case 's': /* stereo */ + ps.eye = 0.80; + break; + case '1': + ps.solidmode = 1; + glFrontFace(GL_CCW); + break; + case '2': + ps.solidmode = 2; + glFrontFace(GL_CCW); + break; + case '3': + ps.solidmode = 3; + /* The teapot polygons face the wrong way. Sigh. */ + glFrontFace(GL_CW); + break; + case '4': + ps.solidmode = 4; + glFrontFace(GL_CCW); + break; + case 'm': /* mono */ + ps.eye = 0.0; + break; + } +} + +void MenuFunc(int value) +{ + KeyboardFunc((unsigned char) value, 0, 0); +} + +void IdleFunc(void) +{ + ps.RotationY += ps.RotationIncrement; + glutPostRedisplay(); +} + +void ReshapeFunc(int w, int h) +{ + glViewport(0,0, w, h); + ps.w = w; + ps.h = h; +} + +void DisplayFunc(void) +{ + double xfactor=1.0, yfactor=1.0; + double Eye =0.0; + int i; + + if(ps.w < ps.h) + { + xfactor = 1.0; + yfactor = ps.h/ps.w; + } + else if(ps.h < ps.w) + { + xfactor = ps.w/ps.h; + yfactor = 1.0; + } + + glClear(GL_COLOR_BUFFER_BIT); + for(i=0;i<2;i++) + { + glEnable(GL_LIGHT0 + i); + glClear(GL_DEPTH_BUFFER_BIT); + if(i==0) /* left eye - RED */ + { + Eye = ps.eye; + glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE); + } + else /* if(i==1) right eye - BLUE */ + { + Eye = -ps.eye; + glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_TRUE); + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum( + (-(ps.w/(2.0*PIXELS_PER_INCH))+Eye) *(ps.znear/ps.zscreen)*xfactor, + (ps.w/(2.0*PIXELS_PER_INCH)+Eye) *(ps.znear/ps.zscreen)*xfactor, + -(ps.h/(2.0*PIXELS_PER_INCH))*(ps.znear/ps.zscreen)*yfactor, + (ps.h/(2.0*PIXELS_PER_INCH))*(ps.znear/ps.zscreen)*yfactor, + ps.znear, ps.zfar); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(Eye,0.0,0.0); + glTranslated(0,0,-ps.zscreen); + + switch(ps.solidmode) + { + case 1: + { + glTranslated(cos(ps.RotationY*M_PI/180.0), + 0, -sin(ps.RotationY*M_PI/180.0) ); + glRotated(ps.RotationY, 0.0,0.1,0.0); + glPushMatrix(); + glScalef(0.5,0.5,0.5); + glutSolidDodecahedron(); + glPopMatrix(); + break; + } + case 2: + { + glTranslated(cos(ps.RotationY*M_PI/180.0), + 0, -sin(ps.RotationY*M_PI/180.0) ); + glRotated(ps.RotationY, 0.0,0.1,0.0); + glutSolidIcosahedron(); + break; + } + case 3: + { + glRotated(60.0, 1 , 0, 0); + glTranslated(cos(ps.RotationY*M_PI/180.0), + 0, -sin(ps.RotationY*M_PI/180.0) ); + glRotated(ps.RotationY, 0.0,0.1,0.0); + glutSolidTeapot(1.0); + break; + } + case 4: + { + double SunRadius = 0.2; + double SunToEarth = 1.0; + double EarthRadius = 0.15; + + glutSolidSphere(SunRadius, 20, 16); /* draw sun */ + glRotated(60.0, 1 , 0, 0); + glPushMatrix(); + glRotated(90.0, 1 , 0, 0); + glutSolidTorus(0.01,SunToEarth, 10,50); + glPopMatrix(); + glRotated(ps.RotationY, 0.0,0.1,0.0); + glTranslatef (SunToEarth, 0.0, 0.0); + glutSolidSphere(EarthRadius, 10, 8); /* draw earth */ + break; + } + } + glDisable(GL_LIGHT0 + i); + } + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glutSwapBuffers(); +} +void +VisibilityFunc(int vis) +{ + if (vis == GLUT_VISIBLE) { + glutIdleFunc(IdleFunc); + } else { + glutIdleFunc(NULL); + } +} +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA ); + ps.w = 512; + ps.h = 512; + glutInitWindowSize(ps.w, ps.h); + glutInitWindowPosition(100,100); + + glutCreateWindow(argv[0]); + init(); + glutVisibilityFunc(VisibilityFunc); + glutDisplayFunc(DisplayFunc); + glutReshapeFunc(ReshapeFunc); + glutKeyboardFunc(KeyboardFunc); + glutCreateMenu(MenuFunc); + glutAddMenuEntry("Stereo", 's'); + glutAddMenuEntry("Mono", 'm'); + glutAddMenuEntry("Dodecahedron", '1'); + glutAddMenuEntry("Icosahedron", '2'); + glutAddMenuEntry("Teapot", '3'); + glutAddMenuEntry("Solar system", '4'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced/redblue_stereo.dsp b/lib/glut-3.7.6/progs/advanced/redblue_stereo.dsp new file mode 100644 index 0000000000..6c52f55d14 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/redblue_stereo.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="redblue_stereo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=redblue_stereo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "redblue_stereo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "redblue_stereo.mak" CFG="redblue_stereo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "redblue_stereo - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "redblue_stereo - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "redblue_stereo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "redblue_stereo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "redblue_stereo - Win32 Release" +# Name "redblue_stereo - Win32 Debug" +# Begin Source File + +SOURCE=.\redblue_stereo.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/rts.c b/lib/glut-3.7.6/progs/advanced/rts.c new file mode 100644 index 0000000000..226e896718 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/rts.c @@ -0,0 +1,2168 @@ + +/* Copyright (c) Mark J. Kilgard, 1997, 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. */ + +/* Real-time Shadowing library, Version 0.97 */ + +/* XXX This is library is not fully implemented yet, but still quite + functional. */ + +/* XXX This code _does_ assume that you that your realloc can realloc NULL + (as specified by ANSI C). You also should have the 1.2 version of the + OpenGL Utility (GLU) library. SGI users need IRIX 6.2 (or higher) or IRIX + 5.3 with patch 1449 installed. */ + +/* This code will use multiple CPUs if available in its SGI version + using IRIX's Shared Parallel Arena facility. The generation of + silhouettes with the GLU 1.2 tessellator is farmed out to a gang for + tessellation threads. */ + +/* This code will use Win32's multithreading and multiple CPUs if + available when compiled with the Visual C++ "/MT" option. Just + like with the IRIX multiprocessor support, the generation of + silhouettes with the GLU 1.2 tessellator is farmed out to a gang + of tessellation threads. -mjk July 28, 1998. */ + +/* Please do not naively assume that enabling the multiprocessor + code will make rts-based programs run any faster if you do not + have multiple CPUs. Indeed, the extra thread overhead will in + fact likely make the program slightly slower. */ + +#ifdef __sgi +# define MP +#endif + +#ifdef _WIN32 +# include /* for wglGetProcAddress */ +# ifdef _MT /* If Visual C++ "/MT" compiler switch specified. */ +# define MP +# endif +#endif + +#ifndef NDEBUG +#define NDEBUG /* No assertions for best performance. */ +#endif + +#include +#include +#include +#include +#include +#ifdef MP +# ifdef __sgi +# include +# include +# include +# include +# include +# endif +# ifdef _WIN32 +# include +# endif +#endif + +#include "rtshadow.h" + +/* The "real time shadows" (RTS) library code requires the GLU 1.2 + polygon tessellator's boundary return capability to work. */ +#ifdef GLU_VERSION_1_2 + +/* Win32 calling conventions. */ +#ifndef CALLBACK +#define CALLBACK +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* For testing... */ +#if 0 +#undef GL_VERSION_1_1 +#undef GL_EXT_vertex_array +#endif + +#if defined(GL_VERSION_1_1) || defined(GL_EXT_vertex_array) +static int hasVertexArray = 0; +#else +static const int hasVertexArray = 0; +#endif + +#ifdef GL_EXT_blend_subtract +static int hasBlendSubtract = 0; +#if defined(_WIN32) && !defined(MESA) +PFNGLBLENDEQUATIONEXTPROC glBlendEquationEXT = NULL; +#endif +#else +static const int hasBlendSubtract = 0; +#endif + +/* Coordinates. */ +enum { + X, Y, Z +}; + +struct VertexHolder2D { + struct VertexHolder2D *next; + GLfloat v[2]; +}; + +struct VertexHolder3D { + struct VertexHolder3D *next; + GLfloat v[3]; +}; + +#ifndef MP + +# define NUM_CONTEXTS 1 +# define MP_ASSERT(assertion) + +# define ARENA_VARIABLE(arena) +# define SEMA_VARIABLE(sema) +# define LOCK_VARIABLE(lock) +# define THREAD_VARIABLE(thread) +# define INITSEMA(arena) +# define WAIT(sema) +# define SIGNAL(sema) +# define INITLOCK(arena) +# define LOCK(lock) +# define UNLOCK(lock) +# define PRIVATE_MALLOC(size) malloc(size) +# define PRIVATE_FREE(ptr) free(ptr) +# define PRIVATE_REALLOC(ptr, size) realloc(ptr, size) +# define SHARED_MALLOC(size) malloc(size) +# define SHARED_FREE(ptr) free(ptr) +# define SHARED_REALLOC(ptr, size) realloc(ptr, size) + +#else + +# define NUM_CONTEXTS 4 +# define MP_ASSERT(assertion) assert(assertion) + +# ifdef __sgi + +# define ARENA_VARIABLE(arena) usptr_t *arena; +# define SEMA_VARIABLE(sema) usema_t *sema; +# define LOCK_VARIABLE(lock) ulock_t lock; +# define THREAD_VARIABLE(thread) pid_t thread; + +# define INITSEMA(arena, value) usnewsema(arena, value) +# define WAIT(sema) uspsema(sema) +# define SIGNAL(sema) usvsema(sema) +# define SAMPLE(sema) ustestsema(sema) + +# define INITLOCK(arena) usnewlock(arena) +# define LOCK(lock) ussetlock(lock) +# define UNLOCK(lock) usunsetlock(lock) + +# define PRIVATE_MALLOC(size) malloc(size) +# define PRIVATE_FREE(ptr) free(ptr) +# define PRIVATE_REALLOC(ptr, size) realloc(ptr, size) + +# define SHARED_MALLOC(size) usmalloc(size, arena) +# define SHARED_FREE(ptr) usfree(ptr, arena) +# define SHARED_REALLOC(ptr, size) usrealloc(ptr, size, arena) + +# endif /* __sgi */ + +# ifdef _WIN32 + +# define ARENA_VARIABLE(arena) HANDLE arena; +# define SEMA_VARIABLE(sema) HANDLE sema; +# define LOCK_VARIABLE(lock) HANDLE lock; +# define THREAD_VARIABLE(thread) HANDLE thread; + +# define INITSEMA(arena, value) CreateSemaphore(NULL, value, NUM_CONTEXTS, NULL) +# define WAIT(sema) WaitForSingleObject(sema, INFINITE) +# define SIGNAL(sema) ReleaseSemaphore(sema, 1, NULL) + + /* Does Win32 have something cheaper than a mutex for locking? */ +# define INITLOCK(arena) CreateMutex(NULL, FALSE, NULL) +# define LOCK(lock) WaitForSingleObject(lock, INFINITE) +# define UNLOCK(lock) ReleaseMutex(lock) + +# define PRIVATE_MALLOC(size) malloc(size) +# define PRIVATE_FREE(ptr) free(ptr) +# define PRIVATE_REALLOC(ptr, size) realloc(ptr, size) + +# define SHARED_MALLOC(size) malloc(size) +# define SHARED_FREE(ptr) free(ptr) +# define SHARED_REALLOC(ptr, size) realloc(ptr, size) + +# endif /* _WIN32 */ + +typedef enum { + CS_UNUSED, CS_CAPTURING, CS_QUEUED, CS_GENERATING +} ContextState; + +#endif + +typedef struct ShadowVolumeState ShadowVolumeState; + +typedef struct TessellationContext { +#ifdef MP + ContextState state; +#endif + RTSscene *scene; + RTSlight *light; + RTSobject *object; + ShadowVolumeState *svs; + + GLUtesselator *tess; + + /* For managing memory allocated by the GLU tessellator's + combine callback. */ + GLfloat *combineList; + int combineListSize; + int combineNext; + struct VertexHolder2D *excessList2D; + + int saveFirst; + GLfloat *firstVertex; + + GLfloat *feedbackBuffer; + int feedbackBufferSize; + int feedbackBufferReturned; + + GLfloat shadowProjectionDistance; + GLfloat extentScale; + + int nextVertex; + int *header; + struct VertexHolder3D *excessList3D; +} TessellationContext; + +const float uniquePassThroughValue = 34567.0; + +#define SmallerOf(a,b) ((a) < (b) ? (a) : (b)) + +ARENA_VARIABLE(arena) +SEMA_VARIABLE(contextAvailable) +LOCK_VARIABLE(accessQueue) +SEMA_VARIABLE(silhouetteNeedsGeneration) + +static TessellationContext *context[NUM_CONTEXTS]; + +struct RTSscene { + GLfloat eyePos[3]; + GLbitfield usableStencilBits; + int numStencilBits; + char bitList[32]; + void (*renderSceneFunc) (GLenum castingLight, void *sceneData, RTSscene * scene); + void *sceneData; + + SEMA_VARIABLE(silhouetteGenerationDone) + THREAD_VARIABLE(*workerPids) +#ifdef MP + ShadowVolumeState *waitingForSVS; +#endif + + GLfloat viewScale; + GLint stencilBits; + int stencilValidateNeeded; + + GLfloat sceneAmbient[4]; + + int lightListSize; + RTSlight **lightList; + + GLboolean stencilRenderingInvariantHack; +}; + +struct ShadowVolumeState { + int lightSernum; + int objectSernum; +#ifdef MP + int generationDone; +#endif + + int silhouetteSize; + GLfloat *silhouette; + + GLfloat angle; + GLfloat axis[3]; + + GLfloat topScale; +}; + +struct RTSlight { + int refcnt; + int sernum; + + GLenum glLight; + GLfloat lightPos[3]; + GLfloat radius; + + int state; + + int sceneListSize; + RTSscene **sceneList; + + int objectListSize; + RTSobject **objectList; + ShadowVolumeState *shadowVolumeList; +}; + +struct RTSobject { + int refcnt; + int sernum; + + GLfloat objectPos[3]; + GLfloat maxRadius; + void (*renderObject) (void *objectData); + void *objectData; + + int feedbackBufferSizeGuess; + + int state; + + int lightListSize; + RTSlight **lightList; +}; + +#if defined(GL_VERSION_1_1) +static int +supportsOneDotOne(void) +{ + const char *version; + int major, minor; + + version = (char *) glGetString(GL_VERSION); + if (sscanf(version, "%d.%d", &major, &minor) == 2) + return major >= 1 && minor >= 1; + return 0; /* OpenGL version string malformed! */ +} +#endif + +static int +extensionSupported(const char *extension) +{ + static const GLubyte *extensions = NULL; + const GLubyte *start; + GLubyte *where, *terminator; + + /* Extension names should not have spaces. */ + where = (GLubyte *) strchr(extension, ' '); + if (where || *extension == '\0') + return 0; + + if (!extensions) + extensions = glGetString(GL_EXTENSIONS); + /* It takes a bit of care to be fool-proof about parsing the OpenGL + extensions string. Don't be fooled by sub-strings, etc. */ + start = extensions; + for (;;) { + where = (GLubyte *) strstr((const char *) start, extension); + if (!where) + break; + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { + return 1; + } + } + start = terminator; + } + return 0; +} + +static GLfloat * +nextVertexHolder3D(TessellationContext * context) +{ + struct VertexHolder3D *holder; + ShadowVolumeState *svs; + GLfloat *newHolder; + + svs = context->svs; + if (context->nextVertex >= svs->silhouetteSize) { + holder = (struct VertexHolder3D *) PRIVATE_MALLOC(sizeof(struct VertexHolder3D)); + if (holder == NULL) { + printf("holder alloc problem\n"); + } + holder->next = context->excessList3D; + context->excessList3D = holder; + newHolder = holder->v; + } else { + newHolder = &svs->silhouette[context->nextVertex * 3]; + } + context->nextVertex++; + return newHolder; +} + +/* ARGSUSED */ +static void CALLBACK +begin(GLenum type, void *polyData) +{ + TessellationContext *context = polyData; + GLfloat *newHolder; + + assert(type == GL_LINE_LOOP); + context->saveFirst = 1; + + context->header = (int *) nextVertexHolder3D(context); + context->header[0] = context->nextVertex; + context->header[1] = 0xdeadbabe; /* Aid assertion testing. */ + context->header[2] = 0xdeadbeef; /* Non-termintor token. */ + + newHolder = nextVertexHolder3D(context); + newHolder[X] = 0.0; + newHolder[Y] = 0.0; + newHolder[Z] = 0.0; +} + +static void CALLBACK +vertex(void *data, void *polyData) +{ + TessellationContext *context = polyData; + GLfloat *v = data; + GLfloat *newHolder; + + newHolder = nextVertexHolder3D(context); + newHolder[X] = context->extentScale * v[X]; + newHolder[Y] = context->extentScale * v[Y]; + newHolder[Z] = context->shadowProjectionDistance; + if (context->saveFirst) { + context->firstVertex = newHolder; + context->saveFirst = 0; + } +} + +static void CALLBACK +end(void *polyData) +{ + TessellationContext *context = polyData; + GLfloat *newHolder; + + newHolder = nextVertexHolder3D(context); + newHolder[X] = context->firstVertex[X]; + newHolder[Y] = context->firstVertex[Y]; + newHolder[Z] = context->firstVertex[Z]; + assert(context->firstVertex[Z] == context->shadowProjectionDistance); + + assert(context->header[1] == 0xdeadbabe); + assert(context->header[2] == 0xdeadbeef); + context->header[1] = context->nextVertex - context->header[0]; +} + +static void +freeExcessList(TessellationContext * context) +{ + struct VertexHolder2D *holder, *next; + + holder = context->excessList2D; + while (holder) { + next = holder->next; + PRIVATE_FREE(holder); + holder = next; + } + context->excessList2D = NULL; +} + +/* The GLU tessellator's combine callback is called to create a + new vertex when tessellation detects an intersection or wishes + to merge features. + + The memory for the new vertex must be allocated by the GLU + tessellator caller. The caller is also responsible for this + memory's deletion. The combineList is an array for the memory + for these combined vertices. The array is of size combineListSize. + combineNext decides how many vertices are in use on the combineList. + + The combineList is of finite size. When this list is exhausted, + individual vertex memory is allocated via malloc in a linked list. + This is the excessList2D linked list. After tessellation, the + combineList will be expanded by how many vertices had to be + added to the excessList2D list. The idea is that next time the + shadow volume tessellation is done, the combineList should + hopefully be large enough. + +/* ARGSUSED1 */ +static void CALLBACK +combine(GLdouble coords[3], void *d[4], GLfloat w[4], + void **dataOut, void *polyData) +{ + TessellationContext *context = polyData; + struct VertexHolder2D *holder; + GLfloat *newHolder; + + if (context->combineNext >= context->combineListSize) { + holder = (struct VertexHolder2D *) PRIVATE_MALLOC(sizeof(struct VertexHolder2D)); + if (holder == NULL) { + printf("got no holder alloc\n"); + } + holder->next = context->excessList2D; + context->excessList2D = holder; + newHolder = holder->v; + } else { + newHolder = &context->combineList[context->combineNext * 2]; + } + + newHolder[0] = (GLfloat) coords[0]; + newHolder[1] = (GLfloat) coords[1]; + *dataOut = newHolder; + + context->combineNext++; +} + +static void CALLBACK +error(GLenum errno) +{ + fprintf(stderr, "ERROR: %s\n", gluErrorString(errno)); +} + +#ifdef DEBUG + +/* These verify routines are useful for asserting the sanity of + the silhouette data structures. */ + +static void +verifySilhouette(ShadowVolumeState * svs) +{ + int *infoPtr = (int *) svs->silhouette; + int *info = infoPtr; + int fan; + + if (info[0] == 0) { + printf("2 ZERO\n"); + } + if (info ==0) { + printf("ZERO\n"); + } + fan = 0; + for (;;) { + if(info[2] == 0xdeadbeef || info[2] == 0xcafecafe) { + if (info[2] == 0xcafecafe) { + return; + } + info += ((1 + info[1]) * 3); + fan++; + } else { + printf("Corrupted silhouette! (svs=0x%x, silhouette=0x%x, fan=%d)\n", + svs, svs->silhouette, fan); + abort(); + } + } +} + +static void +verifySilhouettesOfScene(RTSscene *scene) +{ + int i, obj; + RTSlight *light; + + for (i = 0; i < scene->lightListSize; i++) { + light = scene->lightList[i]; + if (light) { + for (obj = 0; obj < light->objectListSize; obj++) { + ShadowVolumeState *svs; + + svs = &light->shadowVolumeList[obj]; + if (svs && svs->generationDone) { + verifySilhouette(svs); + } + } + } + } +} + +#endif + +static void +generateSilhouette(TessellationContext * context) +{ + ShadowVolumeState * svs; + GLfloat *start, *end, *loc; + GLfloat *eyeLoc; + GLdouble v[3]; + int token, nvertices, i; + GLfloat passThroughToken; + int watchingForEyePos; + struct VertexHolder3D *holder, *next; + + assert(context->excessList2D == NULL); + assert(context->excessList3D == NULL); + + svs = context->svs; + + context->nextVertex = 0; + + watchingForEyePos = 0; + eyeLoc = NULL; + + gluTessBeginPolygon(context->tess, context); + start = context->feedbackBuffer; + end = start + context->feedbackBufferReturned; + for (loc = start; loc < end;) { + token = *loc; + loc++; + switch (token) { + case GL_POLYGON_TOKEN: + nvertices = *loc; + loc++; + assert(nvertices >= 3); + gluTessBeginContour(context->tess); + for (i = 0; i < nvertices; i++) { + v[0] = loc[0]; + v[1] = loc[1]; + v[2] = 0.0; + gluTessVertex(context->tess, v, loc); + loc += 2; + } + gluTessEndContour(context->tess); + break; + case GL_PASS_THROUGH_TOKEN: + passThroughToken = *loc; + if (passThroughToken == uniquePassThroughValue) { + watchingForEyePos = !watchingForEyePos; + } else { + /* Ignore everything else. */ + fprintf(stderr, "WARNING: Unexpected feedback token 0x%x (%d).\n", + token, token); + } + loc++; + break; + case GL_POINT_TOKEN: + if (watchingForEyePos) { + fprintf(stderr, + "WARNING: Eye point possibly within the shadow volume.\n"); + fprintf(stderr, + " Program should be improved to handle this.\n"); + /* XXX Write code to handle this case. You would need to determine + if the point was instead any of the returned boundary polyons. + Once you found that you were really in the clipping volume, then I + haven't quite thought about what you do. */ + eyeLoc = loc; + watchingForEyePos = 0; + } else { + /* Ignore everything else. */ + fprintf(stderr, "WARNING: Unexpected feedback token 0x%x (%d).\n", + token, token); + } + loc += 2; + break; + default: + /* Ignore everything else. */ + fprintf(stderr, "WARING: Unexpected feedback token 0x%x (%d).\n", + token, token); + } + } + gluTessEndPolygon(context->tess); + + /* Free any memory that got allocated due to the combine callback during + tessellation and then enlarge the combineList so we hopefully don't need + the combine list next time. */ + if (context->combineNext > context->combineListSize) { + freeExcessList(context); + context->combineListSize = context->combineNext; + SHARED_FREE(context->combineList); + context->combineList = SHARED_MALLOC(sizeof(GLfloat) * 2 * context->combineListSize); + if (context->combineList == NULL) { + printf("problem alloc context->combineList\n"); + } + } + context->combineNext = 0; + + context->header[2] = 0xcafecafe; /* Terminating token. */ + + if (context->excessList3D) { +#ifndef NDEBUG + int oldSize; + + oldSize = svs->silhouetteSize; +#endif + assert(context->nextVertex > svs->silhouetteSize); + svs->silhouetteSize = context->nextVertex; + svs->silhouette = SHARED_REALLOC(svs->silhouette, + svs->silhouetteSize * sizeof(GLfloat) * 3); + if (svs->silhouette == NULL) { + fprintf(stderr, "libRTS: generateSilhouette: out of memory\n"); + abort(); + } + holder = context->excessList3D; + while (holder) { + context->nextVertex--; + svs->silhouette[context->nextVertex * 3] = holder->v[0]; + svs->silhouette[context->nextVertex * 3 + 1] = holder->v[1]; + svs->silhouette[context->nextVertex * 3 + 2] = holder->v[2]; + next = holder->next; + PRIVATE_FREE(holder); + holder = next; + } + assert(context->nextVertex == oldSize); + context->excessList3D = NULL; + } + + /* Validate shadow volume state's serial numbers. */ + svs->lightSernum = context->light->sernum; + svs->objectSernum = context->object->sernum; +} + +static int +listBits(GLbitfield usableStencilBits, char bitList[32]) +{ + int num = 0, bit = 0; + + while (usableStencilBits) { + if (usableStencilBits & 0x1) { + bitList[num] = bit; + num++; + } + bit++; + usableStencilBits >>= 1; + } + return num; +} + +/* Three element vector dot product. */ +static GLfloat +vdot(const GLfloat * v1, const GLfloat * v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +/* Three element vector cross product. */ +static void +vcross(const GLfloat * v1, const GLfloat * v2, GLfloat * cross) +{ + assert(v1 != cross && v2 != cross); + cross[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + cross[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + cross[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); +} + +static GLfloat +getViewScale(RTSscene * scene) +{ + if (scene->viewScale == 0.0) { + GLfloat maxViewSize[2]; + + glGetFloatv(GL_MAX_VIEWPORT_DIMS, maxViewSize); + scene->viewScale = SmallerOf(maxViewSize[0], maxViewSize[1]) / 2.0; + + /* Other stuff piggy backs on viewScale to ensure initialization. */ + + glGetIntegerv(GL_STENCIL_BITS, &scene->stencilBits); + +#if defined(GL_VERSION_1_1) + hasVertexArray = supportsOneDotOne(); +#elif defined(GL_EXT_vertex_array) + hasVertexArray = extensionSupported("GL_EXT_vertex_array"); +#endif + +#ifdef GL_EXT_blend_subtract + hasBlendSubtract = extensionSupported("GL_EXT_blend_subtract"); +#if defined(_WIN32) && !defined(MESA) + if (hasBlendSubtract) { + glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) wglGetProcAddress("glBlendEquationEXT"); + if (glBlendEquationEXT == NULL) { + hasBlendSubtract = 0; + } + } +#endif + + /* XXX RealityEngine workaround. */ + if (!strcmp((char *) glGetString(GL_VENDOR), "SGI")) { + if (!strncmp((char *) glGetString(GL_RENDERER), "RE", 2)) { + fprintf(stderr, "WARNING: RealityEngine workaround forcing additive blending.\n"); + hasBlendSubtract = 0; + } + } +#endif + } + return scene->viewScale; +} + +static void +captureLightView(RTSscene * scene, RTSlight * light, RTSobject * object, + ShadowVolumeState * svs, TessellationContext * context) +{ + static GLfloat unit[3] = + {0.0, 0.0, 1.0}; + int feedbackBufferSizeGuess; + GLfloat lightDelta[3], eyeDelta[3]; + GLfloat lightDistance, eyeDistance, fieldOfViewRatio, viewScale; + GLdouble fieldOfViewAngle; + GLdouble nnear, ffar; /* Avoid x86 C keywords. Grumble. */ + GLint returned; + + MP_ASSERT(context->state == CS_CAPTURING); + viewScale = getViewScale(scene); + +#ifdef MP + svs->generationDone = 0; +#endif + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + /* Calculate the light's distance from the object being shadowed. */ + lightDelta[X] = object->objectPos[X] - light->lightPos[X]; + lightDelta[Y] = object->objectPos[Y] - light->lightPos[Y]; + lightDelta[Z] = object->objectPos[Z] - light->lightPos[Z]; + lightDistance = (GLfloat) sqrt(lightDelta[X] * lightDelta[X] + + lightDelta[Y] * lightDelta[Y] + lightDelta[Z] * lightDelta[Z]); + + /* Determine the appropriate field of view. We want to use as narrow a + field of view as possible to not waste resolution, but not narrower than + the object. Add 50% extra slop. */ + fieldOfViewRatio = object->maxRadius / lightDistance; + if (fieldOfViewRatio > 0.99) { + fprintf(stderr, + "WARNING: Clamping FOV to 164 degrees for determining shadow.\n"); + fprintf(stderr, + " Light distance = %g, object maxmium radius = %g\n", + lightDistance, object->maxRadius); + + /* 2*asin(0.99) ~= 164 degrees. */ + fieldOfViewRatio = 0.99; + } + /* Pre-compute scaling factors for the near and far extent of the shadow + volume. */ + context->extentScale = light->radius * fieldOfViewRatio / viewScale; + context->shadowProjectionDistance = light->radius; + + nnear = 0.5 * (lightDistance - object->maxRadius); + if (nnear < 0.0001) { + fprintf(stderr, + "WARNING: Clamping near clip plane to 0.0001 because light source too near.\n"); + fprintf(stderr, + " Light distance = %g, object maxmium radius = %g\n", + lightDistance, object->maxRadius); + nnear = 0.0001; + } + ffar = 2.0 * (lightDistance + object->maxRadius); + + eyeDelta[X] = scene->eyePos[X] - light->lightPos[X]; + eyeDelta[Y] = scene->eyePos[Y] - light->lightPos[Y]; + eyeDelta[Z] = scene->eyePos[Z] - light->lightPos[Z]; + eyeDistance = 1.05 * + sqrt(eyeDelta[X] * eyeDelta[X] + eyeDelta[Y] * eyeDelta[Y] + + eyeDelta[Z] * eyeDelta[Z]); + if (eyeDistance > ffar) { + ffar = eyeDistance; + } + fieldOfViewAngle = 2.0 * asin(fieldOfViewRatio) * 180 / M_PI; + gluPerspective(fieldOfViewAngle, 1.0, nnear, ffar); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + /* XXX Look up vector needs adjusting. */ + gluLookAt(light->lightPos[X], light->lightPos[Y], light->lightPos[Z], + object->objectPos[X], object->objectPos[Y], object->objectPos[Z], + 0.0, 1.0, 0.0); /* up is in positive Y direction */ + + glPushAttrib(GL_VIEWPORT_BIT); + glViewport(-viewScale, -viewScale, 2 * viewScale, 2 * viewScale); + + feedbackBufferSizeGuess = object->feedbackBufferSizeGuess; + +doFeedback: + + if (feedbackBufferSizeGuess > context->feedbackBufferSize) { + context->feedbackBufferSize = feedbackBufferSizeGuess; + object->feedbackBufferSizeGuess = feedbackBufferSizeGuess; + + /* A "free & malloc" is better than a "realloc" below because we + do not care for the previous buffer contents to be preserved. */ + /* XXX Add 32 words of slop (an extra cache line) to end for buggy + hardware that uses DMA to return feedback results but that sometimes + overrun the buffer. Yuck. */ + SHARED_FREE(context->feedbackBuffer); + context->feedbackBuffer = (GLfloat *) + SHARED_MALLOC(context->feedbackBufferSize * sizeof(GLfloat) + 32 * 4); + if (context->feedbackBuffer == NULL) { + fprintf(stderr, "libRTS: captureLightView: out of memory\n"); + abort(); + } + } + glFeedbackBuffer(context->feedbackBufferSize, + GL_2D, context->feedbackBuffer); + + (void) glRenderMode(GL_FEEDBACK); + + /* Render the eye position. The eye position is "bracketed" by unique pass + through tokens. These bracketing pass through tokens let us determine if + the eye position was clipped or not. This helps us determine whether the + eye position is possibly within the shadow volume or not. If the point is + clipped, the eye position is not in the shadow volume. If the point is + not clipped, a more complicated test is necessary to determine if the eye + position is really in the shadow volume or not. See generateSilhouette. */ + glPassThrough(uniquePassThroughValue); + glBegin(GL_POINTS); + glVertex3fv(scene->eyePos); + glEnd(); + glPassThrough(uniquePassThroughValue); + + (object->renderObject) (object->objectData); + + returned = glRenderMode(GL_RENDER); + assert(returned <= context->feedbackBufferSize); +#if 0 + if (returned == -1) { +#else + /* XXX RealityEngine workaround. */ + if (returned == -1 || returned == context->feedbackBufferSize) { +#endif + feedbackBufferSizeGuess = context->feedbackBufferSize + + (context->feedbackBufferSize >> 1); + goto doFeedback; /* Try again with larger feedback buffer. */ + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); /* Restore viewport. */ + + vcross(unit, lightDelta, svs->axis); + svs->angle = (GLfloat) acos(vdot(unit, lightDelta) / lightDistance) * 180.0 / M_PI; + svs->topScale = (lightDistance + object->maxRadius) / light->radius; + + context->feedbackBufferReturned = returned; + + context->scene = scene; + context->light = light; + context->object = object; + context->svs = svs; +} + +static TessellationContext * +createTessellationContext(void) +{ + TessellationContext *context; + GLUtesselator *tess; + + context = (TessellationContext *) SHARED_MALLOC(sizeof(TessellationContext)); + if (context == NULL) { + printf("TessellationContext alloc failed\n"); + return NULL; + } + tess = gluNewTess(); + if (tess == NULL) { + SHARED_FREE(context); + return NULL; + } + gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); + gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); + gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) &begin); + gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (CALLBACK*)()) &vertex); + gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (CALLBACK*)()) &combine); + gluTessCallback(tess, GLU_TESS_END_DATA, (void (CALLBACK*)()) &end); + gluTessCallback(tess, GLU_TESS_ERROR, error); + context->tess = tess; + +#ifdef MP + context->state = CS_UNUSED; +#endif + context->combineListSize = 0; + context->combineList = NULL; + context->combineNext = 0; + context->excessList2D = NULL; + + context->feedbackBufferSize = 0; + context->feedbackBuffer = NULL; + + context->excessList3D = NULL; + + return context; +} + +#ifdef MP + +static void +work(void) +{ + TessellationContext *workContext; + RTSscene *scene; + int i; + + WAIT(silhouetteNeedsGeneration); + + LOCK(accessQueue); + workContext = NULL; + for (i=0; istate == CS_QUEUED) { + workContext = context[i]; + break; + } + } + assert(workContext); + workContext->state = CS_GENERATING; + UNLOCK(accessQueue); + + generateSilhouette(workContext); + + LOCK(accessQueue); + assert(workContext->state == CS_GENERATING); + workContext->state = CS_UNUSED; + workContext->svs->generationDone = 1; + scene = workContext->scene; + + /* If the main thread is sleeping on this particular + shadow volume, wake up the main thread. */ + if (workContext->svs == scene->waitingForSVS) { + scene->waitingForSVS = NULL; + SIGNAL(scene->silhouetteGenerationDone); + } + UNLOCK(accessQueue); + SIGNAL(contextAvailable); +} + +static void +waitForSilhouetteGenerationDone(RTSscene * scene, ShadowVolumeState *svs) +{ + LOCK(accessQueue); + + if (svs->generationDone == 0) { + scene->waitingForSVS = svs; + UNLOCK(accessQueue); + WAIT(scene->silhouetteGenerationDone); + assert(svs->generationDone); + } else { + UNLOCK(accessQueue); + } +} + +#ifdef __sgi + +static void +worker(void) +{ + signal(SIGHUP, SIG_DFL); + prctl(PR_TERMCHILD); + usadd(arena); + for (;;) { + work(); + } +} + +static void +setupArena(int numWorkers) +{ + static int beenhere = 0; + int i; + THREAD_VARIABLE(pid) + + if (beenhere) { + return; + } + beenhere = 1; + + usconfig(CONF_INITUSERS, 1 + numWorkers); + usconfig(CONF_ARENATYPE, US_SHAREDONLY); + usconfig(CONF_INITSIZE, 1024 * 1024); + arena = usinit("/dev/zero"); + if (arena == NULL) { + fprintf(stderr, "libRTS: could not create arena.\n"); + exit(1); + } + + for (i=0; isilhouetteGenerationDone = INITSEMA(arena, 0); + scene->waitingForSVS = NULL; +#endif + + scene->eyePos[X] = eyePos[X]; + scene->eyePos[Y] = eyePos[Y]; + scene->eyePos[Z] = eyePos[Z]; + scene->usableStencilBits = usableStencilBits; + scene->renderSceneFunc = renderSceneFunc; + scene->sceneData = sceneData; + + scene->viewScale = 0.0; /* 0.0 means "to be determined". */ + scene->stencilValidateNeeded = 1; + + scene->sceneAmbient[0] = 0.2; + scene->sceneAmbient[1] = 0.2; + scene->sceneAmbient[2] = 0.2; + scene->sceneAmbient[3] = 1.0; + + scene->lightListSize = 0; + scene->lightList = NULL; + + scene->stencilRenderingInvariantHack = GL_FALSE; + + return scene; +} + +RTSlight * +rtsCreateLight( + GLenum glLight, + GLfloat lightPos[3], + GLfloat radius) +{ + RTSlight *light; + + light = (RTSlight *) SHARED_MALLOC(sizeof(RTSlight)); + if (light == NULL) { + printf("rtsCreateLight failed\n"); + return NULL; + } + light->refcnt = 1; + light->sernum = 1; + + light->glLight = glLight; + light->lightPos[X] = lightPos[X]; + light->lightPos[Y] = lightPos[Y]; + light->lightPos[Z] = lightPos[Z]; + light->radius = radius; + + light->state = RTS_SHINING_AND_CASTING; + + light->sceneListSize = 0; + light->sceneList = NULL; + + light->objectListSize = 0; + light->objectList = NULL; + light->shadowVolumeList = NULL; + + return light; +} + +RTSobject * +rtsCreateObject( + GLfloat objectPos[3], + GLfloat maxRadius, + void (*renderObject) (void *objectData), + void *objectData, + int feedbackBufferSizeGuess) +{ + RTSobject *object; + + object = (RTSobject *) SHARED_MALLOC(sizeof(RTSobject)); + if (object == NULL) { + printf("rtsCreateObject failed\n"); + return NULL; + } + object->refcnt = 1; + object->sernum = 1; + + object->objectPos[X] = objectPos[X]; + object->objectPos[Y] = objectPos[Y]; + object->objectPos[Z] = objectPos[Z]; + object->maxRadius = maxRadius; + object->renderObject = renderObject; + object->objectData = objectData; + object->feedbackBufferSizeGuess = feedbackBufferSizeGuess; +#ifdef __sgi + /* XXX Impact/Octane feedback bug work around. If the feedback + buffer on Impact/Octane is less than 2048 entries, a buggy + hardware accelerated path is used. Make sure at least 2049 + entries for the feedback buffer; this forces Impact/Octane to use + the (bug free) software feedback path. This bug is fixed in IRIX + 6.5. */ + if (object->feedbackBufferSizeGuess < 2048) { + object->feedbackBufferSizeGuess = 2048; + } +#endif + + object->state = RTS_SHADOWING; + + object->lightListSize = 0; + object->lightList = NULL; + + return object; +} + +void +rtsAddLightToScene( + RTSscene * scene, + RTSlight * light) +{ + int i; + + for (i = 0; i < light->sceneListSize; i++) { + if (light->sceneList[i] == scene) { + return; + } + if (light->sceneList[i] == NULL) { + goto addToSceneList; + } + } + light->sceneListSize++; + light->sceneList = (RTSscene **) SHARED_REALLOC(light->sceneList, + light->sceneListSize * sizeof(RTSscene *)); + if (light->sceneList == NULL) { + fprintf(stderr, "rtsAddLightToScene: out of memory\n"); + abort(); + } +addToSceneList: + + light->sceneList[i] = scene; + + for (i = 0; i < scene->lightListSize; i++) { + if (scene->lightList[i] == light) { + fprintf(stderr, "rtsAddLightToScene: inconsistent lists\n"); + abort(); + } + if (scene->lightList[i] == NULL) { + goto addToLightList; + } + } + scene->lightListSize++; + scene->lightList = (RTSlight **) SHARED_REALLOC(scene->lightList, + scene->lightListSize * sizeof(RTSlight *)); + if (scene->lightList == NULL) { + fprintf(stderr, "rtsAddLightToScene: out of memory\n"); + abort(); + } +addToLightList: + + scene->lightList[i] = light; + + light->refcnt++; +} + +static void +initShadowVolumeState(ShadowVolumeState * svs) +{ + svs->lightSernum = 0; + svs->objectSernum = 0; + svs->silhouette = NULL; + svs->silhouetteSize = 0; +#ifdef MP + svs->generationDone = 0; +#endif +} + +void +rtsAddObjectToLight( + RTSlight * light, + RTSobject * object) +{ + int i; + + for (i = 0; i < object->lightListSize; i++) { + if (object->lightList[i] == light) { + return; + } + if (object->lightList[i] == NULL) { + goto addToLightList; + } + } + object->lightListSize++; + object->lightList = (RTSlight **) SHARED_REALLOC(object->lightList, + object->lightListSize * sizeof(RTSlight *)); + if (object->lightList == NULL) { + fprintf(stderr, "rtsAddObjectToLight: out of memory\n"); + abort(); + } +addToLightList: + object->lightList[i] = light; + + for (i = 0; i < light->objectListSize; i++) { + if (light->objectList[i] == object) { + fprintf(stderr, "rtsAddObjectToLight: inconsistent lists\n"); + abort(); + } + if (light->objectList[i] == NULL) { + goto addToObjectList; + } + } + + /* Extend object list. */ + light->objectListSize++; + light->objectList = (RTSobject **) SHARED_REALLOC(light->objectList, + light->objectListSize * sizeof(RTSscene *)); + if (light->objectList == NULL) { + fprintf(stderr, "rtsAddObjectToLight: out of memory\n"); + abort(); + } + /* Extend shadow volume list. */ + light->shadowVolumeList = (ShadowVolumeState *) + SHARED_REALLOC(light->shadowVolumeList, + light->objectListSize * sizeof(ShadowVolumeState)); + if (light->shadowVolumeList == NULL) { + fprintf(stderr, "rtsAddObjectToLight: out of memory\n"); + abort(); + } +addToObjectList: + + initShadowVolumeState(&light->shadowVolumeList[i]); + + light->objectList[i] = object; + + light->refcnt++; + object->refcnt++; +} + +void +rtsSetLightState( + RTSlight * light, + RTSlightState state) +{ + light->state = state; +} + +void +rtsSetObjectState( + RTSobject * object, + RTSobjectState state) +{ + object->state = state; +} + +void +rtsUpdateEyePos( + RTSscene * scene, + GLfloat eyePos[3]) +{ + scene->eyePos[X] = eyePos[X]; + scene->eyePos[Y] = eyePos[Y]; + scene->eyePos[Z] = eyePos[Z]; +} + +void +rtsUpdateUsableStencilBits( + RTSscene * scene, + GLbitfield usableStencilBits) +{ + scene->usableStencilBits = usableStencilBits; + scene->stencilValidateNeeded = 1; +} + +void +rtsUpdateLightPos( + RTSlight * light, + GLfloat lightPos[3]) +{ + light->lightPos[X] = lightPos[X]; + light->lightPos[Y] = lightPos[Y]; + light->lightPos[Z] = lightPos[Z]; + light->sernum++; +} + +void +rtsUpdateLightRadius( + RTSlight * light, + GLfloat radius) +{ + light->radius = radius; + light->sernum++; +} + +void +rtsUpdateObjectPos( + RTSobject * object, + GLfloat objectPos[3]) +{ + object->objectPos[X] = objectPos[X]; + object->objectPos[Y] = objectPos[Y]; + object->objectPos[Z] = objectPos[Z]; + object->sernum++; +} + +void +rtsUpdateObjectShape( + RTSobject * object) +{ + object->sernum++; +} + +void +rtsUpdateObjectMaxRadius( + RTSobject * object, + GLfloat maxRadius) +{ + object->maxRadius = maxRadius; + object->sernum++; +} + +#if defined(GL_EXT_vertex_array) && !defined(GL_VERSION_1_1) +/* Only needed if has vertex array extension, but no OpenGL 1.1. */ +static void +setupVertexArray(ShadowVolumeState * svs, int numCoordinates) +{ + glDisable(GL_EDGE_FLAG_ARRAY_EXT); + glEnable(GL_VERTEX_ARRAY_EXT); + glDisable(GL_NORMAL_ARRAY_EXT); + glDisable(GL_COLOR_ARRAY_EXT); + glDisable(GL_TEXTURE_COORD_ARRAY_EXT); + glDisable(GL_EDGE_FLAG_ARRAY_EXT); + glVertexPointerEXT(numCoordinates, GL_FLOAT, 3 * sizeof(GLfloat), svs->silhouetteSize, svs->silhouette); +} +#endif + +static void +renderSilhouette(ShadowVolumeState * svs) +{ + int *infoPtr = (int *) svs->silhouette; + int *info = infoPtr; + int end, i; + + /* CONSTANTCONDITION */ + assert(sizeof(GLfloat) == sizeof(GLint)); + + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glInterleavedArrays(GL_V2F, 3 * sizeof(GLfloat), svs->silhouette); +#elif defined(GL_EXT_vertex_array) + setupVertexArray(svs, 2); +#endif + } + for (;;) { + assert(info[2] == 0xdeadbeef || info[2] == 0xcafecafe); + /* Two fewer vertices get rendered in the renderSilhouette case (compared + to renderShadowVolumeBase) because because a line loop does not need + the initial fan center or the final repeated first vertex. */ + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glDrawArrays(GL_LINE_LOOP, info[0] + 1, info[1] - 2); +#elif defined(GL_EXT_vertex_array) + glDrawArraysEXT(GL_LINE_LOOP, info[0] + 1, info[1] - 2); +#endif + } else { + glBegin(GL_LINE_LOOP); + end = info[0] + info[1] - 2; + for (i = info[0] + 1; i < end; i++) { + glVertex2fv(&svs->silhouette[i * 3]); + } + glEnd(); + } + if (info[2] == 0xcafecafe) { + return; + } + info += ((1 + info[1]) * 3); + } +} + +static void +renderShadowVolumeBase(ShadowVolumeState * svs) +{ + int *infoPtr = (int *) svs->silhouette; + int *info = infoPtr; + int end, i; + int fan; + + fan = 0; + /* CONSTANTCONDITION */ + assert(sizeof(GLfloat) == sizeof(GLint)); + glRotatef(svs->angle, svs->axis[X], svs->axis[Y], svs->axis[Z]); + for (;;) { + assert((info[2] == 0xdeadbeef || info[2] == 0xcafecafe) && info[1] > 0); + if (hasVertexArray) { + /* Note: assumes that glInterleavedArrays has already been called. */ +#if defined(GL_VERSION_1_1) + glDrawArrays(GL_TRIANGLE_FAN, info[0], info[1]); +#elif defined(GL_EXT_vertex_array) + glDrawArraysEXT(GL_TRIANGLE_FAN, info[0], info[1]); +#endif + } else { + glBegin(GL_TRIANGLE_FAN); + end = info[0] + info[1]; + for (i = info[0]; i < end; i++) { + glVertex3fv(&svs->silhouette[i * 3]); + } + glEnd(); + } + if (info[2] == 0xcafecafe) { + return; + } + assert(info[1] > 0); + info += ((1 + info[1]) * 3); + fan++; + } +} + +static void +renderShadowVolume(ShadowVolumeState * svs, GLfloat lightPos[3]) +{ + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + renderShadowVolumeBase(svs); + glPopMatrix(); +} + +static void +renderShadowVolumeTop(ShadowVolumeState * svs, GLfloat lightPos[3]) +{ + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + glScalef(svs->topScale, svs->topScale, svs->topScale); + renderShadowVolumeBase(svs); + glPopMatrix(); +} + +static void +validateShadowVolume(RTSscene * scene, RTSlight * light, + RTSobject * object, ShadowVolumeState * svs) +{ + /* Serial number mismatch indicates light or object has changed since last + shadow volume generation. If mismatch, regenerate the shadow volume. */ + if (light->sernum != svs->lightSernum + || object->sernum != svs->objectSernum) { + TessellationContext *workContext; +#ifdef MP + int i; + + WAIT(contextAvailable); + + LOCK(accessQueue); + workContext = NULL; + for (i=0; istate == CS_UNUSED) { + workContext = context[i]; + break; + } + } + assert(workContext); + workContext->state = CS_CAPTURING; + UNLOCK(accessQueue); + + captureLightView(scene, light, + object, svs, workContext); + + workContext->state = CS_QUEUED; + SIGNAL(silhouetteNeedsGeneration); + +#else + workContext = context[0]; + captureLightView(scene, light, + object, svs, workContext); + + generateSilhouette(workContext); +#endif + } +} + +void +rtsRenderScene( + RTSscene * scene, + RTSmode mode) +{ + static GLfloat totalDarkness[4] = + {0.0, 0.0, 0.0, 0.0}; + int i, obj, bit; + int numStencilBits, numCastingLights, numShadowingObjects; + RTSlight *firstLight, *prevLight, *light; + RTSobject *object; + GLbitfield fullStencilMask; + + /* Expect application (caller) to do the glClear (including stencil). */ + /* Expect application (caller) to enable depth testing. */ + + if (mode != RTS_NO_SHADOWS) { + /* Validate shadow volumes, count casting lights, and stash the first + light. */ + numCastingLights = 0; + firstLight = NULL; + for (i = 0; i < scene->lightListSize; i++) { + light = scene->lightList[i]; + if (light) { + if (light->state != RTS_OFF) { + if (light->state == RTS_SHINING_AND_CASTING) { + + if (numCastingLights == 0) { + /* Count number of shadowing objects. */ + numShadowingObjects = 0; + for (obj = 0; obj < light->objectListSize; obj++) { + if (light->objectList[obj]->state == RTS_SHADOWING) { + numShadowingObjects++; + } + } + if (numShadowingObjects == 0) { + /* Not casting on any object; skip it. */ + continue; + } + assert(firstLight == NULL); + firstLight = light; + } + numCastingLights++; + if (numCastingLights == 1 || hasBlendSubtract) { + glEnable(light->glLight); + } else { + glDisable(light->glLight); + } + + for (obj = 0; obj < light->objectListSize; obj++) { + object = light->objectList[obj]; + if (object->state == RTS_SHADOWING) { + ShadowVolumeState *svs; + + svs = &light->shadowVolumeList[obj]; + validateShadowVolume(scene, light, object, svs); + } + } + } else if (light->state == RTS_SHINING_AND_CASTING) { + glEnable(light->glLight); + } + } else { + glDisable(light->glLight); + } + } + } + } + glEnable(GL_LIGHTING); + glEnable(GL_CULL_FACE); + if (scene->stencilRenderingInvariantHack) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } else { + /* XXX Note that the non-hack case does not enable or + disable stencil. The hack case enables stencil + testing but sets up the stencil modes so that stencil + testing is effectively disabled. If you wanted + stencil testing on during the renderSceneFunc, you won't + need to have the hack enabled though! */ + } + scene->renderSceneFunc(GL_NONE, scene->sceneData, scene); + + if (mode == RTS_NO_SHADOWS) { + return; + } + if (numCastingLights == 0) { + /* No lights, no shadows. */ + return; + } + assert(firstLight); + assert(numShadowingObjects > 0); + + /* Determine exactly which stencil bits usable for shadowing. */ + if (scene->stencilValidateNeeded) { + GLbitfield shadowStencilBits; + + shadowStencilBits = scene->usableStencilBits & ((1 << scene->stencilBits) - 1); + scene->numStencilBits = listBits(shadowStencilBits, scene->bitList); + if (scene->numStencilBits == 0) { + fprintf(stderr, + "WARNING: No stencil bits available for shadowing, expect bad results.\n"); + fprintf(stderr, + " Frame buffer stencil bits = %d, usable stencil bits = 0x%x.\n", + scene->stencilBits, scene->usableStencilBits); + } + scene->stencilValidateNeeded = 0; + } + numStencilBits = scene->numStencilBits; + + /* The first light is easier than the rest since we need subtractive + blending for two or more lights. Do the first light the fast way. */ + + bit = 0; + assert(scene->stencilValidateNeeded == 0); + + glDisable(firstLight->glLight); + glEnable(GL_STENCIL_TEST); + glDepthMask(GL_FALSE); + + obj = 0; + while (firstLight->objectList[obj]->state == RTS_NOT_SHADOWING) { + obj++; + } + + do { + assert(bit < numStencilBits); + assert(firstLight->objectList[obj]->state == RTS_SHADOWING); + assert(obj < firstLight->objectListSize); + + fullStencilMask = 0; + + glDisable(GL_LIGHTING); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDisable(GL_CULL_FACE); + glStencilFunc(GL_ALWAYS, 0, 0); + do { + +#ifdef MP + waitForSilhouetteGenerationDone(scene, &firstLight->shadowVolumeList[obj]); +#endif + + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glInterleavedArrays(GL_V3F, 0, + firstLight->shadowVolumeList[obj].silhouette); +#elif defined(GL_EXT_vertex_array) + setupVertexArray(&firstLight->shadowVolumeList[obj], 3); +#endif + } + fullStencilMask |= 1 << scene->bitList[bit]; + glStencilMask(1 << scene->bitList[bit]); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + renderShadowVolume(&firstLight->shadowVolumeList[obj], + firstLight->lightPos); + + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + renderShadowVolumeTop(&firstLight->shadowVolumeList[obj], + firstLight->lightPos); + + bit++; + do { + obj++; + } while (obj < firstLight->objectListSize + && firstLight->objectList[obj]->state == RTS_NOT_SHADOWING); + + } while (bit < numStencilBits && obj < firstLight->objectListSize); + + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthFunc(GL_EQUAL); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NOTEQUAL, 0, fullStencilMask); + glEnable(GL_LIGHTING); + scene->renderSceneFunc(firstLight->glLight, scene->sceneData, scene); + if (obj < firstLight->objectListSize) { + glStencilMask(~0); + glClear(GL_STENCIL_BUFFER_BIT); + glDepthFunc(GL_LESS); /* XXX needed? */ + bit = 0; + } + } while (obj < firstLight->objectListSize); + + if (numCastingLights == 1) { + glStencilMask(~0); + glCullFace(GL_BACK); /* XXX Needed? */ + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + if (scene->stencilRenderingInvariantHack) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } else { + glDisable(GL_STENCIL_TEST); + } + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glDisableClientState(GL_VERTEX_ARRAY); +#elif defined(GL_EXT_vertex_array) + glDisable(GL_VERTEX_ARRAY_EXT); +#endif + } + return; + } + /* Get ready to subtract out the particular contribution for each light + source in regions shadowed by the light source's shadowing objects. */ + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, totalDarkness); + glDepthFunc(GL_LESS); +#ifdef GL_EXT_blend_subtract + if (hasBlendSubtract) { + glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); + } +#endif + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + + prevLight = firstLight; + + for (i = 1; i < scene->lightListSize; i++) { + light = scene->lightList[i]; + if (light) { + if (light->state == RTS_SHINING_AND_CASTING) { + + /* Count number of shadowing objects. */ + numShadowingObjects = 0; + for (obj = 0; obj < light->objectListSize; obj++) { + if (light->objectList[obj]->state == RTS_SHADOWING) { + numShadowingObjects++; + } + } + + if (numShadowingObjects > 0) { + int reservedStencilBit; + + assert(scene->stencilValidateNeeded == 0); + + /* Switch off the last light; switch on the current light (all + other lights should be disabled). */ + glDisable(prevLight->glLight); + glEnable(light->glLight); + + /* Complicated logic to try to figure out the stencil clear + strategy. Tries hard to conserve stencil bit planes and scene + re-renders. */ + if (numStencilBits < numShadowingObjects) { + if (numStencilBits == 1) { + fprintf(stderr, "WARNING: 1 bit of stencil not enough to reserve a bit.\n"); + fprintf(stderr, " Skipping lights beyond the first.\n"); + continue; + } + /* Going to require one or more stencil clears; this requires + reserving a bit of stencil to avoid double subtracts. */ + reservedStencilBit = 1 << scene->bitList[0]; + bit = 1; + glStencilMask(~0); + glClear(GL_STENCIL_BUFFER_BIT); + glDepthFunc(GL_LESS); /* XXX Needed? */ + } else { + /* Faster cases. All the objects can be rendered each to a + distinct available stencil plane. No need to reserve a + stencil bit to avoid double blending since only one scene + render required. */ + reservedStencilBit = 0; + if (numShadowingObjects <= numStencilBits - bit) { + /* Best case: Enough stencil bits available to not even + require a stencil clear for this light. Keep "bit" as is. */ + } else { + /* Not enough left over bitplanes to subtract out this light + with what's currently available, so clear the stencil buffer + to get enough. */ + glStencilMask(~0); + glClear(GL_STENCIL_BUFFER_BIT); + bit = 0; + } + } + + obj = 0; + while (light->objectList[obj]->state == RTS_NOT_SHADOWING) { + obj++; + } + + do { + assert(bit < numStencilBits); + assert(light->objectList[obj]->state == RTS_SHADOWING); + assert(obj < light->objectListSize); + + fullStencilMask = reservedStencilBit; + + glDisable(GL_LIGHTING); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilFunc(GL_ALWAYS, 0, 0); + glDisable(GL_CULL_FACE); + do { + +#ifdef MP + waitForSilhouetteGenerationDone(scene, + &light->shadowVolumeList[obj]); +#endif + + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glInterleavedArrays(GL_V3F, 0, + light->shadowVolumeList[obj].silhouette); +#elif defined(GL_EXT_vertex_array) + setupVertexArray(&light->shadowVolumeList[obj], 3); +#endif + } + fullStencilMask |= 1 << scene->bitList[bit]; + glStencilMask(1 << scene->bitList[bit]); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + renderShadowVolume(&light->shadowVolumeList[obj], + light->lightPos); + + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + renderShadowVolumeTop(&light->shadowVolumeList[obj], + light->lightPos); + + bit++; + do { + obj++; + } while (obj < light->objectListSize + && light->objectList[obj]->state == RTS_NOT_SHADOWING); + + } while (bit < scene->numStencilBits && obj < light->objectListSize); + + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthFunc(GL_EQUAL); + if (reservedStencilBit) { + glStencilMask(reservedStencilBit); + glStencilOp(GL_KEEP, GL_KEEP, GL_ONE); + if (hasBlendSubtract) { + /* Subtract lighting contribution inside of shadow; prevent + double drawing via stencil */ + glStencilFunc(GL_GREATER, reservedStencilBit, fullStencilMask); + } else { + /* Add lighting contribution outside of shadow; prevent + double drawing via stencil. */ + glStencilFunc(GL_EQUAL, 0, fullStencilMask); + } + } else { + if (hasBlendSubtract) { + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilFunc(GL_NOTEQUAL, 0, fullStencilMask); + } else { + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilFunc(GL_EQUAL, 0, fullStencilMask); + } + } + glEnable(GL_LIGHTING); + scene->renderSceneFunc(light->glLight, scene->sceneData, scene); + + if (obj < light->objectListSize) { + assert(reservedStencilBit); + glStencilMask(~0); + glClear(GL_STENCIL_BUFFER_BIT); + glDepthFunc(GL_LESS); /* XXX Needed? */ + bit = 1; + } + } while (obj < light->objectListSize); + + prevLight = light; + } + } + } + } + + glStencilMask(~0); + glCullFace(GL_BACK); /* XXX needed? */ + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + if (scene->stencilRenderingInvariantHack) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } else { + glDisable(GL_STENCIL_TEST); + } + glDisable(GL_BLEND); + if (hasVertexArray) { +#if defined(GL_VERSION_1_1) + glDisableClientState(GL_VERTEX_ARRAY); +#elif defined(GL_EXT_vertex_array) + glDisable(GL_VERTEX_ARRAY_EXT); +#endif + } + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, scene->sceneAmbient); +} + +void +rtsRenderSilhouette( + RTSscene * scene, + RTSlight * light, + RTSobject * object) +{ + GLfloat lightDelta[3]; + GLfloat lightDistance, viewScale, fieldOfViewRatio, extentScale; + ShadowVolumeState svsRec, *svs; + int obj; + int anonymousShadowVolumeState; + + /* Calculate the light's distance from the object being shadowed. */ + lightDelta[X] = object->objectPos[X] - light->lightPos[X]; + lightDelta[Y] = object->objectPos[Y] - light->lightPos[Y]; + lightDelta[Z] = object->objectPos[Z] - light->lightPos[Z]; + lightDistance = sqrt(lightDelta[X] * lightDelta[X] + + lightDelta[Y] * lightDelta[Y] + lightDelta[Z] * lightDelta[Z]); + + viewScale = getViewScale(scene); + fieldOfViewRatio = object->maxRadius / lightDistance; + extentScale = light->radius * fieldOfViewRatio / viewScale; + + for (obj = 0; obj < light->objectListSize; obj++) { + if (light->objectList[obj] == object) { + svs = &light->shadowVolumeList[obj]; + anonymousShadowVolumeState = 0; + goto gotShadowVolumeState; + } + } + + /* It probably makes sense to have the object on the light's object list + already since then we would have a ShadowVolumeState structure ready to + use and likely to have a reasonably sized silhouette vertex array. Plus, + we'd validate the light and object's shadow volume. + + Anyway, rtsRenderSilhouette will still handle the case where the object + is not already added to the specified light for generality (but not + economy). Use an "anonymous" ShadowVolumeState data structure that only + lives during this routine. */ + + svs = &svsRec; + anonymousShadowVolumeState = 1; + initShadowVolumeState(svs); + +gotShadowVolumeState: + + validateShadowVolume(scene, light, object, svs); + + glPushAttrib(GL_ENABLE_BIT); + /* Disable a few things likely to screw up the rendering of the + silhouette. */ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); +#if 0 + glDisable(GL_STENCIL_TEST); +#else + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 0, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +#endif + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(-viewScale, viewScale, -viewScale, viewScale); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glScalef(1.0 / extentScale, 1.0 / extentScale, 1.0 / extentScale); + + renderSilhouette(svs); + +#if 0 + glColor3f(0.0, 1.0, 0.0); + glPointSize(7.0); + glBegin(GL_POINTS); + glVertex2fv(eyeLoc); + glEnd(); +#endif + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + + if (anonymousShadowVolumeState) { + /* Deallocate "anonymous" ShadowVolumeState's silhouette vertex array. */ + SHARED_FREE(svs->silhouette); + } +} + +void +rtsStencilRenderingInvariantHack(RTSscene * scene, GLboolean enableHack) +{ + scene->stencilRenderingInvariantHack = enableHack; +} + +/* XXX These free routines are not complete. */ + +#if 0 +static void +freeTessellationContext(TessellationContext *context) +{ + gluDeleteTess(context->tess); + free(context->feedbackBuffer); + free(context); +} +#endif + +void +rtsFreeScene( + RTSscene * scene) +{ + int i; + + for (i=0; i < scene->lightListSize; i++) { + if (scene->lightList[i]) { + rtsFreeLight(scene->lightList[i]); + } + } + free(scene->lightList); + free(scene); +} + +void +rtsFreeLight( + RTSlight * light) +{ + int i; + + for (i=0; isceneListSize; i++) { + if (light->sceneList[i]) { + rtsFreeScene(light->sceneList[i]); + } + } + free(light); +} + +void +rtsFreeObject( + RTSobject * object) +{ + free(object); +} + +#endif /* GLU_VERSION_1_2 */ diff --git a/lib/glut-3.7.6/progs/advanced/rtshadow.h b/lib/glut-3.7.6/progs/advanced/rtshadow.h new file mode 100644 index 0000000000..014539e0c0 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/rtshadow.h @@ -0,0 +1,182 @@ +#ifndef __rtshadow_h__ +#define __rtshadow_h__ + +/* Copyright (c) Mark J. Kilgard, 1997, 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. */ + +/* Real-time Shadowing library, Version 0.96 */ + +#if defined(_WIN32) + +/* Try to avoid including to avoid name space + pollution, but Win32's needs APIENTRY and + WINGDIAPI defined properly. */ +# if 0 +# define WIN32_LEAN_AND_MEAN +# include +# else + /* This is from Win32's */ +# ifndef APIENTRY +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif +# ifndef CALLBACK + /* This is from Win32's */ +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* This is from Win32's and */ +# ifndef WINGDIAPI +# define WINGDIAPI __declspec(dllimport) +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ + +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + RTS_ERROR_OUT_OF_MEMORY, + RTS_WARNING_EYE_IN_SHADOW, + RTS_WARNING_LIGHT_TOO_CLOSE +}; + +typedef enum { + RTS_OFF, + RTS_SHINING, + RTS_SHINING_AND_CASTING +} RTSlightState; + +typedef enum { + RTS_NOT_SHADOWING, + RTS_SHADOWING +} RTSobjectState; + +typedef enum { + RTS_NO_SHADOWS, + RTS_USE_SHADOWS, + RTS_USE_SHADOWS_NO_OVERLAP +} RTSmode; + +typedef struct RTSscene RTSscene; +typedef struct RTSlight RTSlight; +typedef struct RTSobject RTSobject; + +typedef void (*RTSerrorHandler)(int error, char *message); +typedef void (*RTSrenderSceneFunc)(GLenum castingLight, void *sceneData, RTSscene *scene); + +extern RTSscene *rtsCreateScene( + GLfloat eyePos[3], + GLbitfield usableStencilBits, + RTSrenderSceneFunc func, + void *sceneData); +extern RTSlight *rtsCreateLight( + GLenum glLight, + GLfloat lightPos[3], + GLfloat radius); +extern RTSobject *rtsCreateObject( + GLfloat objectPos[3], + GLfloat maxRadius, + void (*renderObject) (void *objectData), + void *objectData, + int feedbackBufferSizeGuess); + +extern void rtsAddLightToScene( + RTSscene * scene, + RTSlight * light); +extern void rtsAddObjectToLight( + RTSlight * light, + RTSobject * object); + +extern void rtsRemoveLightFromScene( + RTSscene * scene, + RTSlight * light); +extern void rtsRemoveObjectFromLight( + RTSlight * light, + RTSobject * object); + +extern void rtsSetLightState( + RTSlight * light, + RTSlightState state); +extern void rtsSetObjectState( + RTSobject * object, + RTSobjectState state); + +extern void rtsUpdateEyePos( + RTSscene * scene, + GLfloat eyePos[3]); +extern void rtsUpdateUsableStencilBits( + RTSscene * scene, + GLbitfield usableStencilBits); + +extern void rtsUpdateLightPos( + RTSlight * light, + GLfloat lightPos[3]); +extern void rtsUpdateLightRadius( + RTSlight * light, + GLfloat lightRadius); + +extern void rtsUpdateObjectPos( + RTSobject * object, + GLfloat objectPos[3]); +extern void rtsUpdateObjectShape( + RTSobject * object); +extern void rtsUpdateObjectMaxRadius( + RTSobject * object, + GLfloat maxRadius); + +extern void rtsFreeScene( + RTSscene * scene); +extern void rtsFreeLight( + RTSlight * light); +extern void rtsFreeObject( + RTSobject * object); + +extern int rtsTriviallyOutsideShadowVolume( + RTSscene * scene, + GLfloat objectPos[3], + GLfloat maxRadius); + +extern void rtsRenderScene( + RTSscene * scene, + RTSmode mode); + +extern void rtsRenderSilhouette( + RTSscene * scene, + RTSlight * light, + RTSobject * object); + +extern RTSerrorHandler rtsSetErrorHandler( + RTSerrorHandler handler); + +extern void rtsStencilRenderingInvariantHack( + RTSscene * scene, + GLboolean enableHack); + +#ifdef __cplusplus +} + +#endif +#endif /* __rtshadow_h__ */ diff --git a/lib/glut-3.7.6/progs/advanced/sgiflag.c b/lib/glut-3.7.6/progs/advanced/sgiflag.c new file mode 100644 index 0000000000..e0873e8ee1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/sgiflag.c @@ -0,0 +1,488 @@ + +/* + * sgiflag.c: + * + * This program displays a waving flag with an SGI logo trimmed out of + * it. The flag is a single nurbs surface (bicubic, bezier). It "waves" + * by making it control point oscillate on a sine wave. + * + * The logo is cut from the flag using a combination of piecewise-linear + * and bezier trim curves. + * + * Howard Look - December 1990 + * David Blythe - June 1995 + */ + +#include + +#include +#include + +#include +#include "sgiflag.h" +#include "logopoints.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* Knot sequences for cubic bezier surface and trims */ +Knot sknots[S_NUMKNOTS] = {0., 0., 0., 0., 1., 1., 1., 1.}; +Knot tknots[T_NUMKNOTS] = {0., 0., 0., 0., 1., 1., 1., 1.}; +Knot trimknots[S_NUMKNOTS] = {0., 0., 0., 0., 1., 1., 1., 1.}; + +/* Control points for the flag. The Z values are modified to make it wave */ +Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = { + { {0., 3., 0.}, {1., 3., 0.}, {2., 3., 0}, {3., 3., 0.}}, + { {0., 2., 0.}, {1., 2., 0.}, {2., 2., 0}, {3., 2., 0.}}, + { {0., 1., 0.}, {1., 1., 0.}, {2., 1., 0}, {3., 1., 0.}}, + { {0., 0., 0.}, {1., 0., 0.}, {2., 0., 0}, {3., 0., 0.}} +}; + +/* Trim the whole exterior of the, counter clockwise. Necessary to do + * internal trimming + */ +TrimCurve *whole; +TrimCurve ccl_path; +TrimPiece ccl_square[] = { + { + PWL, + 11, + { + {0., 0.}, {.25, 0.}, {.5, 0.}, {.75, 0.}, {1., 0.}, + {1., 1.}, {.75, 1.}, {.5, 1.}, {.25, 1.}, {0., 1.}, {0., 0.} + } + } +}; + +/* Three paths for three parts of the logo */ +TrimCurve *path[3]; + +/* Initial one-third of the logo, centered at origin */ +TrimCurve initial_path; +TrimPiece initial_pieces[] = { + { + PWL, /* 0 */ + 6, + {{Ax,Ay},{Bx,By},{Cx,Cy},{Dx,Dy},{Ex,Ey},{0.,0.}} + }, + { + CURVE, /* 1 */ + 4, + {{0.,0.},{Fx,Fy},{Fx,Fy},{0.,0.}} + }, + { + PWL, /* 2 */ + 2, + {{Gx, Gy},{Gx,Gy}} + }, + { + CURVE, /* 3 */ + 4, + {{0.,0.},{Gx,Gy},{Gx,Gy},{0.,0.}} + }, + { + PWL, /* 4 */ + 3, + {{0., 0.},{Z,Z},{0.,0.}} + }, + { + CURVE, /* 5 */ + 4, + {{0.,0.},{-Gx,Gy},{-Gx,Gy},{0.,0.}} + }, + { + PWL, /* 6 */ + 2, + {{-Fx, Fy},{-Fx,Fy}} + }, + { + CURVE, /* 7 */ + 4, + {{0.,0.},{-Fx,Fy},{-Fx,Fy},{0.,0.}} + }, + { + PWL, /* 8 */ + 6, + {{0.,0.},{-Ex,Ey},{-Dx,Dy},{-Cx,Cy},{-Bx,By},{Ax,Ay}} + } +}; + +static GLUnurbsObj *nurbsflag; + +static GLboolean trimming = GL_TRUE, filled = GL_TRUE, hull = GL_TRUE; +static int mousex = 248, mousey = 259, mstate; + +/* Given endpoints of the line a and b, the distance d from point a, + * returns a new point (in result) that is on that line. + */ +void interp(TrimPoint a, TrimPoint b, GLfloat d, TrimPoint result) { + + GLfloat l; + + l = sqrt((a[0] - b[0])*(a[0] - b[0]) + (a[1] - b[1])*(a[1] - b[1])); + + result[0] = a[0] + (b[0] - a[0])*d/l; + result[1] = a[1] + (b[1] - a[1])*d/l; + +} + +/* Given two trim pieces, coerces the endpoint of the first and the + * start point of the second to be indentical. + * + * The two trims must be of opposite types, PWL or CURVE. + */ +void join_trims(TrimPiece *trim1, TrimPiece *trim2, GLfloat radius) { + + int last; + TrimPoint result; + + last = trim1->points - 1; + + if (trim1->type == PWL) + interp(trim2->point[1], trim1->point[last - 1], radius, result); + else /* trim1 is CURVE */ + interp(trim1->point[last-1], trim2->point[0], radius, result); + + trim1->point[last][0] = trim2->point[0][0] = result[0]; + trim1->point[last][1] = trim2->point[0][1] = result[1]; +} + +/* Translates each point in the trim piece by tx and ty */ +void translate_trim(TrimPiece *trim, GLfloat tx, GLfloat ty) { + + int i; + + for (i=0; ipoints; i++) { + trim->point[i][0] += tx; + trim->point[i][1] += ty; + } +} + +/* Scales each point in the trim piece by sx and sy */ +void scale_trim(TrimPiece *trim, GLfloat sx, GLfloat sy) { + + int i; + + for (i=0; ipoints; i++) { + trim->point[i][0] *= sx; + trim->point[i][1] *= sy; + } +} + +/* Rotates each point in the trim piece by angle radians about the origin */ +void rotate_trim(TrimPiece *trim, GLfloat angle) { + + int i; + GLfloat s,c; + TrimPoint t; + + s = sin(angle); + c = cos(angle); + + for (i=0; ipoints; i++) { + t[0] = trim->point[i][0]; + t[1] = trim->point[i][1]; + + trim->point[i][0] = c*t[0] - s*t[1]; + trim->point[i][1] = s*t[0] + c*t[1]; + } +} + +/* Creates storage space for dst and copies the contents of src into dst */ +void copy_path(TrimCurve *src, TrimCurve **dst) { + + int i,j; + + *dst = (TrimCurve *) malloc(sizeof(TrimCurve)); + (*dst)->pieces = src->pieces; + (*dst)->trim = (TrimPiece *) malloc((src->pieces)*sizeof(TrimPiece)); + + for(i=0; i < src->pieces; i++) { + (*dst)->trim[i].type = src->trim[i].type; + (*dst)->trim[i].points = src->trim[i].points; + + for (j=0; j < src->trim[i].points; j++) { + (*dst)->trim[i].point[j][0] = src->trim[i].point[j][0]; + (*dst)->trim[i].point[j][1] = src->trim[i].point[j][1]; + } + } +} + +/* Initializes the outer whole trim plus the three trimming paths + * required to trim the logo. + */ +void init_trims(void) { + + int i; + + /* whole outer path, counter clockwise, so NuRB is not trimmed */ + whole = &ccl_path; + whole->pieces = 1; + whole->trim = ccl_square; + + /* initial third of logo, centered at origin */ + path[0] = &initial_path; + path[0]->pieces = ELEMENTS(initial_pieces); + path[0]->trim = initial_pieces; + for(i=0; i < path[0]->pieces - 1; i++) + join_trims(&path[0]->trim[i], &path[0]->trim[i+1], LOGO_RADIUS); + + /* copy other to other two thirds */ + copy_path(path[0],&path[1]); + copy_path(path[0],&path[2]); + + /* scale and translate first third */ + for (i=0; ipieces; i++) { + scale_trim(&path[0]->trim[i],0.5,1.0); + translate_trim(&path[0]->trim[i],0.5,0.52); + } + + /* rotate, scale and translate second third */ + for (i=0; ipieces; i++) { + rotate_trim(&path[1]->trim[i],2.0*M_PI/3.0); + scale_trim(&path[1]->trim[i],0.5,1.0); + translate_trim(&path[1]->trim[i],0.49,0.5); + } + + /* rotate, scale and translate last third */ + for (i=0; ipieces; i++) { + rotate_trim(&path[2]->trim[i],2.0*2.0*M_PI/3.0); + scale_trim(&path[2]->trim[i],0.5,1.0); + translate_trim(&path[2]->trim[i],0.51,0.5); + } +} + +/* Opens a square window, and initializes the window, interesting devices, + * viewing volume, material, and lights. + */ +static void +initialize(void) { + + GLfloat mat_diffuse[] = { .8, .1, .8, 1. }; + GLfloat mat_specular[] = { .6, .6, .6, 1. }; + GLfloat mat_ambient[] = { .1, .1, .1, 1. }; + + glClearColor(.58, .58, .58, 0.); + glClearDepth(1.); + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + gluPerspective(60,1.0,1.0,10.0); + glMatrixMode(GL_MODELVIEW); + glTranslatef(0., 0., -6.); + + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + + nurbsflag = gluNewNurbsRenderer(); + gluNurbsProperty(nurbsflag, GLU_SAMPLING_TOLERANCE, 100.0); + gluNurbsProperty(nurbsflag, GLU_DISPLAY_MODE, GLU_FILL); + + init_trims(); +} + + +/* Draw the nurb, possibly with trimming */ +void draw_nurb(GLboolean trimming) { + + static GLfloat angle = 0.0; + int i,j; + + + /* wave the flag by rotating Z coords though a sine wave */ + for (i=1; i<4; i++) + for (j=0; j<4; j++) + ctlpoints[i][j][2] = sin((GLfloat)i+angle); + + angle += 0.1; + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + glTranslatef(2.5,-1.0,0.0); + glScalef(1.5,1.0,1.0); + glRotatef(90,0.,0.,1.); + glRotatef(mousey/10.,1.,0.,0.); + glRotatef(mousex/10.,0.,1.,0.); + + gluBeginSurface(nurbsflag); + gluNurbsSurface(nurbsflag,S_NUMKNOTS, sknots, T_NUMKNOTS, tknots, + 3 * T_NUMPOINTS, 3, + &ctlpoints[0][0][0], T_ORDER, S_ORDER, GL_MAP2_VERTEX_3); + if (trimming) { + dotrim(whole); + dotrim(path[0]); + dotrim(path[1]); + dotrim(path[2]); + } + gluEndSurface(nurbsflag); + + if (hull) draw_hull(ctlpoints); + + glPopMatrix(); + +} + +/* Draw the convex hull of the control points */ +void draw_hull(Point cpoints[S_NUMPOINTS][T_NUMPOINTS]) { + + int s,t; + + glDisable(GL_LIGHTING); + glColor3f(0.,1.,0.); + + glBegin(GL_LINES); + for (s=0; spieces; i++) { + + if (trim_curve->trim[i].type == PWL) { + gluPwlCurve(nurbsflag, trim_curve->trim[i].points, + &trim_curve->trim[i].point[0][0], + 2, GLU_MAP1_TRIM_2); + } else { + gluNurbsCurve(nurbsflag, ELEMENTS(trimknots),trimknots, + 2,&trim_curve->trim[i].point[0][0], + trim_curve->trim[i].points, GLU_MAP1_TRIM_2); + } + } + gluEndTrim(nurbsflag); +} + + +/* ARGSUSED1 */ +static void +Key(unsigned char c, int x, int y) +{ + switch(c) { + case 27: /* Escape */ + exit(0); + break; + default: + break; + } +} + +static void +Button(int button, int down, int x, int y) +{ + if (down) { + if (button == GLUT_LEFT_BUTTON) { + mstate = 1; + mousex = x; + mousey = y; + } + } else { + if (button == GLUT_LEFT_BUTTON) + mstate = 0; + } + if (mstate) { + mousex = x; + mousey = y; + } +} + +static void +resize(int width, int height) +{ + glViewport(0, 0, width, height); +} + + +static void +expose(void) +{ + draw_nurb(trimming); + glutSwapBuffers(); +} + +static void +idle(void) +{ + glutPostRedisplay(); +} + +static void +visibility(int state) +{ + if (state == GLUT_VISIBLE) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } +} + +static void +Menu(int value) +{ + switch (value) { + case 1: + trimming ^= 1; break; + case 2: + filled ^= 1; + gluNurbsProperty(nurbsflag, GLU_DISPLAY_MODE, + filled ? GLU_FILL : GLU_OUTLINE_POLYGON); + break; + case 3: + hull ^= 1; break; + case 4: + exit(0); break; + default: + break; + } +} + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutInitWindowSize(400, 400); + glutCreateWindow("NURBS Surface"); + glutDisplayFunc(expose); + glutReshapeFunc(resize); + glutKeyboardFunc(Key); + glutMouseFunc(Button); + + glutCreateMenu(Menu); + glutAddMenuEntry("Trim", 1); + glutAddMenuEntry("Fill", 2); + glutAddMenuEntry("Hull", 3); + glutAddMenuEntry("Exit", 4); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutVisibilityFunc(visibility); + + initialize(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced/sgiflag.dsp b/lib/glut-3.7.6/progs/advanced/sgiflag.dsp new file mode 100644 index 0000000000..9115e23a21 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/sgiflag.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="sgiflag" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sgiflag - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sgiflag.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sgiflag.mak" CFG="sgiflag - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sgiflag - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sgiflag - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sgiflag - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sgiflag - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sgiflag - Win32 Release" +# Name "sgiflag - Win32 Debug" +# Begin Source File + +SOURCE=.\sgiflag.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/sgiflag.h b/lib/glut-3.7.6/progs/advanced/sgiflag.h new file mode 100644 index 0000000000..5f3c143fea --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/sgiflag.h @@ -0,0 +1,67 @@ +/* + * sgiflag.h + * + */ + +/* useful for lmdef, nurbssurface, nurbscurve, and more */ +#define ELEMENTS(x) (sizeof(x)/sizeof(x[0])) + +/* Define nurbs surface properties */ +#define S_NUMPOINTS 4 +#define S_ORDER 4 /* cubic, degree 3 */ +#define S_NUMKNOTS (S_NUMPOINTS + S_ORDER) +#define S_NUMCOORDS 3 + +#define T_NUMPOINTS 4 +#define T_ORDER 4 +#define T_NUMKNOTS (T_NUMPOINTS + T_ORDER) +#define T_NUMCOORDS 3 + +typedef GLfloat Knot; +typedef GLfloat Point[3]; +typedef GLfloat TrimPoint[2]; + +/* Trimming curves are either piecewise linear or nurbscurve */ +enum TrimType {PWL, CURVE}; + + +/* A trimming curve is made up of one or more trimming pieces. + * A trimming piece may be of PWL or CURVE. If a trim piece is PWL, + * it has at least two trim points, with each trim point composing + * the endpoints of the line segments. If a trim piece is CURVE, it + * has four trim points defining the cubic bezier trim. + */ + +#define MAX_PIECES 20 + +struct TrimPieceStruct { + enum TrimType type; /* type of the trim */ + int points; /* # of points in the trim piece */ + TrimPoint point[MAX_PIECES]; /* pointer to first trim point */ +}; +typedef struct TrimPieceStruct TrimPiece; + +struct TrimCurveStruct { + int pieces; + TrimPiece *trim; +}; +typedef struct TrimCurveStruct TrimCurve; + + +struct teststruct { + int a, b, c[2]; +}; +typedef struct teststruct Test; + +/* function prototypes */ +static void interp(TrimPoint a, TrimPoint b, GLfloat d, TrimPoint result); +static void join_trims(TrimPiece *trim1, TrimPiece *trim2, GLfloat radius); +static void translate_trim(TrimPiece *trim, GLfloat tx, GLfloat ty); +static void scale_trim(TrimPiece *trim, GLfloat sx, GLfloat sy); +static void rotate_trim(TrimPiece *trim, GLfloat angle); +static void copy_path(TrimCurve *src, TrimCurve **dst); +static void init_trims(void); +static void initialize(void); +static void draw_nurb(GLboolean); +static void draw_hull(Point cpoints[S_NUMPOINTS][T_NUMPOINTS]); +static void dotrim(TrimCurve *curve); diff --git a/lib/glut-3.7.6/progs/advanced/shadowfun.c b/lib/glut-3.7.6/progs/advanced/shadowfun.c new file mode 100644 index 0000000000..593dad8dc2 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowfun.c @@ -0,0 +1,1163 @@ + +/* 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. */ + +/* Unix compile line: cc -o shadowfun shadowfun.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ + +/* THIS PROGRAM REQUIRES GLU 1.2. If you have IRIX 5.3, you need patch 1449 + (the IRIX 5.3 GLU 1.2 functionality patch) or its successor to use this + program. GLU 1.2 is standard on IRIX 6.2 and later. */ + +/* This program demonstrates a light source and object of arbitrary geometry + casing a shadow on arbitary geometry. The program uses OpenGL's feedback, + stencil, and boundary tessellation support. */ + +#include +#include +#include +#include +#include + +#ifdef GLU_VERSION_1_2 + +/* Win32 calling conventions. */ +#ifndef CALLBACK +#define CALLBACK +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +const float uniquePassThroughValue = 34567.0; + +#define SmallerOf(a,b) ((a) < (b) ? (a) : (b)) + +int stencilBits; + +/* Display list names. */ +enum { + /* Display lists should start at 1, not 0. */ + DL_BALL = 1, DL_CONE, DL_LIGHT, DL_SHADOW_VOLUME, DL_SPHERE, + DL_ICO, DL_TORUS, DL_CUBE, DL_SHADOW_VOLUME_TOP, DL_BASE_SHADOW_VOLUME +}; + +/* Menu option names. */ +enum { + /* Important for objectMaxRadius array that the shape enums appear first in + this list. */ + M_TORUS, M_CUBE, M_SPHERE, M_ICO, M_DOUBLE_TORUS, M_ANGLE, M_BOUNDARY, + M_NO_SHADOW, M_NO_LIGHT, M_FRONT_VOLUME, M_BACK_VOLUME, M_SHADOW, + M_LIGHT_SOURCE_VIEW, M_NORMAL_VIEW, M_SPIN, M_SWING, M_STOP +}; + +/* Coordinates. */ +enum { + X, Y, Z +}; + +const int TEXDIM = 64; + +int shape; +GLfloat maxRadius; +int renderMode = M_SHADOW; +int view = M_NORMAL_VIEW; +int renderBoundary = 0; +GLfloat angle = 0.0; +int frontFace = 1; +int rotatingObject = 1; +int swingingLight = 1; +float swingTime = M_PI / 2.0; + +GLfloat lightDiffuse[4] = +{1.0, 0.0, 0.0, 1.0}; +GLfloat lightPos[4] = +{60.0, 50.0, -350.0, 1.0}; +GLfloat objectPos[4] = +{40.0, 30.0, -360.0, 1.0}; +GLfloat sceneEyePos[4] = +{0.0, 0.0, 0.0, 0.0}; + +struct VertexHolder { + struct VertexHolder *next; + GLfloat v[2]; +}; + +typedef struct _ShadowVolumeMemoryPool { + /* Reference count because ShadowVolumeMemoryPool's can be shared between + multiple ShadowVolumeState's. */ + int refcnt; + + GLUtesselator *tess; + GLfloat viewScale; + + /* Memory used for GLU tessellator combine callbacks. */ + GLfloat *combineList; + int combineListSize; + int combineNext; + struct VertexHolder *excessList; +} ShadowVolumeMemoryPool; + +typedef struct _ShadowVolumeState { + ShadowVolumeMemoryPool *pool; + + GLfloat shadowProjectionDistance; + GLfloat extentScale; + + /* Scratch variables used during GLU tessellator callbacks. */ + int saveFirst; + GLfloat *firstVertex; +} ShadowVolumeState; + +ShadowVolumeState *svs; + +static void CALLBACK +begin(GLenum type, void *shadowVolumeState) +{ + ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; + + assert(type == GL_LINE_LOOP); + if (renderBoundary) { + glBegin(type); + } else { + svs->saveFirst = 1; + glBegin(GL_TRIANGLE_FAN); + glColor3f(0, 1, 0); + glVertex3f(0.0, 0.0, 0.0); + } +} + +static void CALLBACK +vertex(void *data, void *shadowVolumeState) +{ + ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; + GLfloat *v = data; + + if (renderBoundary) { + glVertex2fv(v); + } else { + if (svs->saveFirst) { + svs->firstVertex = v; + svs->saveFirst = 0; + } + glColor3f(0, 0, 1); + glVertex3f(svs->extentScale * v[X], svs->extentScale * v[Y], + svs->shadowProjectionDistance); + } +} + +static void CALLBACK +end(void *shadowVolumeState) +{ + ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; + + if (!renderBoundary) { + glColor3f(0, 0, 1); + glVertex3f(svs->extentScale * svs->firstVertex[X], svs->extentScale * svs->firstVertex[Y], + svs->shadowProjectionDistance); + } + glEnd(); +} + +static void +freeExcessList(ShadowVolumeMemoryPool * pool) +{ + struct VertexHolder *holder, *next; + + holder = pool->excessList; + while (holder) { + next = holder->next; + free(holder); + holder = next; + } + pool->excessList = NULL; +} + +/* ARGSUSED1 */ +static void CALLBACK +combine(GLdouble coords[3], void *d[4], GLfloat w[4], void **dataOut, void *shadowVolumeState) +{ + ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; + ShadowVolumeMemoryPool *pool = svs->pool; + struct VertexHolder *holder; + GLfloat *newCoords; + + if (pool->combineNext >= pool->combineListSize) { + holder = (struct VertexHolder *) malloc(sizeof(struct VertexHolder)); + holder->next = pool->excessList; + pool->excessList = holder; + newCoords = holder->v; + } else { + newCoords = &pool->combineList[pool->combineNext * 2]; + } + + newCoords[0] = coords[0]; + newCoords[1] = coords[1]; + *dataOut = newCoords; + + pool->combineNext++; +} + +static void CALLBACK +error(GLenum errno) +{ + printf("ERROR: %s\n", gluErrorString(errno)); +} + +static void +processFeedback(GLint size, GLfloat * buffer, ShadowVolumeState * svs) +{ + ShadowVolumeMemoryPool *pool = svs->pool; + GLfloat *loc, *end, *eyeLoc; + GLdouble v[3]; + int token, nvertices, i; + GLfloat passThroughToken; + int watchingForEyePos; + + if (pool->combineNext > pool->combineListSize) { + freeExcessList(pool); + pool->combineListSize = pool->combineNext; + pool->combineList = realloc(pool->combineList, sizeof(GLfloat) * 2 * pool->combineListSize); + } + pool->combineNext = 0; + + watchingForEyePos = 0; + eyeLoc = NULL; + + glColor3f(1, 1, 1); + gluTessBeginPolygon(pool->tess, svs); + loc = buffer; + end = buffer + size; + while (loc < end) { + token = *loc; + loc++; + switch (token) { + case GL_POLYGON_TOKEN: + nvertices = *loc; + loc++; + assert(nvertices >= 3); + gluTessBeginContour(pool->tess); + for (i = 0; i < nvertices; i++) { + v[0] = loc[0]; + v[1] = loc[1]; + v[2] = 0.0; + gluTessVertex(pool->tess, v, loc); + loc += 2; + } + gluTessEndContour(pool->tess); + break; + case GL_PASS_THROUGH_TOKEN: + passThroughToken = *loc; + if (passThroughToken == uniquePassThroughValue) { + watchingForEyePos = !watchingForEyePos; + } else { + /* Ignore everything else. */ + fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", token, token); + } + loc++; + break; + case GL_POINT_TOKEN: + if (watchingForEyePos) { + fprintf(stderr, "WARNING: Eye point possibly within the shadow volume.\n"); + fprintf(stderr, " Program should be improved to handle this.\n"); + /* XXX Write code to handle this case. You would need to determine + if the point was instead any of the returned boundary polyons. + Once you found that you were really in the clipping volume, then I + haven't quite thought about what you do. */ + eyeLoc = loc; + watchingForEyePos = 0; + } else { + /* Ignore everything else. */ + fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", + token, token); + } + loc += 2; + break; + default: + /* Ignore everything else. */ + fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", + token, token); + } + } + gluTessEndPolygon(pool->tess); + + if (eyeLoc && renderBoundary) { + glColor3f(0, 1, 0); + glPointSize(7.0); + glBegin(GL_POINTS); + glVertex2fv(eyeLoc); + glEnd(); + } +} + +/* Three element vector dot product. */ +static GLfloat +vdot(const GLfloat * v1, const GLfloat * v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +/* Three element vector cross product. */ +static void +vcross(const GLfloat * v1, const GLfloat * v2, GLfloat * cross) +{ + assert(v1 != cross && v2 != cross); + cross[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + cross[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + cross[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); +} + +void +svsFreeShadowVolumeState(ShadowVolumeState * svs) +{ + if (svs->pool) { + svs->pool->refcnt--; + if (svs->pool->refcnt == 0) { + if (svs->pool->excessList) { + freeExcessList(svs->pool); + } + if (svs->pool->combineList) { + free(svs->pool->combineList); + } + if (svs->pool->tess) { + gluDeleteTess(svs->pool->tess); + } + free(svs->pool); + } + } + free(svs); +} + +ShadowVolumeState * +svsCreateShadowVolumeState(GLfloat shadowProjectionDistance, + ShadowVolumeState * shareSVS) +{ + ShadowVolumeState *svs; + ShadowVolumeMemoryPool *pool; + GLUtesselator *tess; + + svs = (ShadowVolumeState *) malloc(sizeof(ShadowVolumeState)); + if (svs == NULL) { + return NULL; + } + svs->pool = NULL; + + if (shareSVS == NULL) { + pool = (ShadowVolumeMemoryPool *) malloc(sizeof(ShadowVolumeMemoryPool)); + if (pool == NULL) { + svsFreeShadowVolumeState(svs); + return NULL; + } + pool->refcnt = 1; + pool->excessList = NULL; + pool->combineList = NULL; + pool->combineListSize = 0; + pool->combineNext = 0; + pool->tess = NULL; + svs->pool = pool; + + tess = gluNewTess(); + if (tess == NULL) { + svsFreeShadowVolumeState(svs); + return NULL; + } + gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); + gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); + gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) begin); + gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (CALLBACK*)()) vertex); + gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (CALLBACK*)()) combine); + gluTessCallback(tess, GLU_TESS_END_DATA, (void (CALLBACK*)()) end); + gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)()) error); + pool->tess = tess; + } else { + pool = shareSVS->pool; + pool->refcnt++; + } + + svs->pool = pool; + svs->shadowProjectionDistance = shadowProjectionDistance; + + return svs; +} + +int +svsGenerateShadowVolume(ShadowVolumeState * svs, + void (*renderFunc) (void), int feedbackBufferSizeGuess, + GLfloat maxRadius, + GLfloat lightPos[3], GLfloat objectPos[3], GLfloat eyePos[3]) +{ + static GLfloat unit[3] = + {0.0, 0.0, 1.0}; + static GLfloat *feedbackBuffer = NULL; + static int bufferSize = 0; + GLfloat axis[3], lightDelta[3], eyeDelta[3]; + GLfloat nnear, ffar; /* Avoid Intel C keywords. Grumble. */ + GLfloat lightDistance, eyeDistance, angle, fieldOfViewRatio, fieldOfViewAngle, + topScale, viewScale; + GLint returned; + + if (svs->pool->viewScale == 0.0) { + GLfloat maxViewSize[2]; + + glGetFloatv(GL_MAX_VIEWPORT_DIMS, maxViewSize); + printf("max viewport = %gx%g\n", maxViewSize[0], maxViewSize[1]); + svs->pool->viewScale = SmallerOf(maxViewSize[0], maxViewSize[1]) / 2.0; + } + viewScale = svs->pool->viewScale; + + if (bufferSize > feedbackBufferSizeGuess) { + feedbackBufferSizeGuess = bufferSize; + } + /* Calculate the light's distance from the object being shadowed. */ + lightDelta[X] = objectPos[X] - lightPos[X]; + lightDelta[Y] = objectPos[Y] - lightPos[Y]; + lightDelta[Z] = objectPos[Z] - lightPos[Z]; + lightDistance = sqrt(lightDelta[X] * lightDelta[X] + + lightDelta[Y] * lightDelta[Y] + lightDelta[Z] * lightDelta[Z]); + + /* Determine the appropriate field of view. We want to use as narrow a + field of view as possible to not waste resolution, but not narrower than + the object. Add 50% extra slop. */ + fieldOfViewRatio = maxRadius / lightDistance; + if (fieldOfViewRatio > 0.99) { + fprintf(stderr, "WARNING: Clamping FOV to 164 degrees for determining shadow boundary.\n"); + fprintf(stderr, " Light distance = %g, object maxmium radius = %g\n", + lightDistance, maxRadius); + + /* 2*asin(0.99) ~= 164 degrees. */ + fieldOfViewRatio = 0.99; + } + /* Pre-compute scaling factors for the near and far extent of the shadow + volume. */ + svs->extentScale = svs->shadowProjectionDistance * fieldOfViewRatio / viewScale; + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + nnear = 0.5 * (lightDistance - maxRadius); + if (nnear < 0.0001) { + fprintf(stderr, "WARNING: Clamping near clip plane to 0.0001 because light source too near.\n"); + fprintf(stderr, " Light distance = %g, object maxmium radius = %g\n", + lightDistance, maxRadius); + nnear = 0.0001; + } + ffar = 2.0 * (lightDistance + maxRadius); + if (eyePos) { + eyeDelta[X] = eyePos[X] - lightPos[X]; + eyeDelta[Y] = eyePos[Y] - lightPos[Y]; + eyeDelta[Z] = eyePos[Z] - lightPos[Z]; + eyeDistance = 1.05 * sqrt(eyeDelta[X] * eyeDelta[X] + eyeDelta[Y] * eyeDelta[Y] + eyeDelta[Z] * eyeDelta[Z]); + if (eyeDistance > ffar) { + ffar = eyeDistance; + } + } + fieldOfViewAngle = 2.0 * asin(fieldOfViewRatio) * 180 / M_PI; + gluPerspective(fieldOfViewAngle, 1.0, nnear, ffar); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + /* XXX Need to update "up vector". Degenerate when light directly above or + below the object. */ + gluLookAt(lightPos[X], lightPos[Y], lightPos[Z], + objectPos[X], objectPos[Y], objectPos[Z], + 0.0, 1.0, 0.0); /* up is in positive Y direction */ + + glPushAttrib(GL_VIEWPORT_BIT); + glViewport(-viewScale, -viewScale, 2 * viewScale, 2 * viewScale); + +doFeedback: + + /* XXX Careful, some systems still don't understand realloc of NULL. */ + if (bufferSize < feedbackBufferSizeGuess) { + bufferSize = feedbackBufferSizeGuess; + /* XXX Add 32 words of slop (an extra cache line) to end for buggy + hardware that uses DMA to return feedback results but that sometimes + overrun the buffer. Yuck. */ + feedbackBuffer = realloc(feedbackBuffer, bufferSize * sizeof(GLfloat) + 32 * 4); + } + glFeedbackBuffer(bufferSize, GL_2D, feedbackBuffer); + + (void) glRenderMode(GL_FEEDBACK); + + (*renderFunc) (); + + /* Render the eye position. The eye position is "bracketed" by unique pass + through tokens. These bracketing pass through tokens let us determine + if the eye position was clipped or not. This helps us determine whether + the eye position is possibly within the shadow volume or not. If the + point is clipped, the eye position is not in the shadow volume. If the + point is not clipped, a more complicated test is necessary to determine + if the eye position is really in the shadow volume or not. See + processFeedback. */ + if (eyePos) { + glPassThrough(uniquePassThroughValue); + glBegin(GL_POINTS); + glVertex3fv(eyePos); + glEnd(); + glPassThrough(uniquePassThroughValue); + } + returned = glRenderMode(GL_RENDER); +#if 0 + if (returned == -1) { +#else + /* XXX RealityEngine workaround. */ + if (returned == -1 || returned == feedbackBufferSizeGuess) { +#endif + feedbackBufferSizeGuess = feedbackBufferSizeGuess + (feedbackBufferSizeGuess >> 1); + goto doFeedback; /* Try again with larger feedback buffer. */ + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); /* Restore viewport. */ + + if (renderBoundary) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-viewScale, viewScale, -viewScale, viewScale); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + processFeedback(returned, feedbackBuffer, svs); + } else { + glNewList(DL_BASE_SHADOW_VOLUME, GL_COMPILE); + vcross(unit, lightDelta, axis); + angle = acos(vdot(unit, lightDelta) / lightDistance) * 180.0 / M_PI; + glRotatef(angle, axis[X], axis[Y], axis[Z]); + processFeedback(returned, feedbackBuffer, svs); + glEndList(); + + glNewList(DL_SHADOW_VOLUME, GL_COMPILE); + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + glCallList(DL_BASE_SHADOW_VOLUME); + glPopMatrix(); + glEndList(); + + glNewList(DL_SHADOW_VOLUME_TOP, GL_COMPILE); + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + topScale = (lightDistance + maxRadius) / svs->shadowProjectionDistance; + glScalef(topScale, topScale, topScale); + glCallList(DL_BASE_SHADOW_VOLUME); + glPopMatrix(); + glEndList(); + } + return returned; +} + +GLfloat objectMaxRadius[] = +{ + 8.0 + 2.0, /* M_TORUS */ + 12.0 / 2.0 * 1.142, /* M_CUBE */ + 8.0, /* M_SPHERE */ + 8.0, /* M_ICO */ + 8.0 + 2.0, /* M_DOUBLE_TORUS */ +}; + +void +renderShadowingObject(void) +{ + static int torusList = 0, cubeList = 0, sphereList = 0, icoList = 0; + + glPushMatrix(); + glTranslatef(objectPos[X], objectPos[Y], objectPos[Z]); + glRotatef(angle, 1.0, 0.3, 0.0); + switch (shape) { + case M_TORUS: + if (torusList) { + glCallList(torusList); + } else { + torusList = DL_TORUS; + glNewList(torusList, GL_COMPILE_AND_EXECUTE); + glutSolidTorus(2.0, 8.0, 8, 15); + glEndList(); + } + break; + case M_CUBE: + if (cubeList) { + glCallList(cubeList); + } else { + cubeList = DL_CUBE; + glNewList(cubeList, GL_COMPILE_AND_EXECUTE); + glutSolidCube(12.0); + glEndList(); + } + break; + case M_SPHERE: + if (sphereList) { + glCallList(sphereList); + } else { + sphereList = DL_SPHERE; + glNewList(sphereList, GL_COMPILE_AND_EXECUTE); + glutSolidSphere(8.0, 10, 10); + glEndList(); + } + break; + case M_ICO: + if (icoList) { + glCallList(icoList); + } else { + icoList = DL_ICO; + glNewList(icoList, GL_COMPILE_AND_EXECUTE); + glEnable(GL_NORMALIZE); + glPushMatrix(); + glScalef(8.0, 8.0, 8.0); + glutSolidIcosahedron(); + glPopMatrix(); + glDisable(GL_NORMALIZE); + glEndList(); + } + break; + case M_DOUBLE_TORUS: + if (torusList) { + glCallList(torusList); + } else { + torusList = DL_TORUS; + glNewList(torusList, GL_COMPILE_AND_EXECUTE); + glutSolidTorus(2.0, 8.0, 8, 15); + glEndList(); + } + glRotatef(90, 0, 1, 0); + glCallList(torusList); + break; + } + glPopMatrix(); +} + +void +sphere(void) +{ + glPushMatrix(); + glTranslatef(60.0, -50.0, -400.0); + glCallList(DL_BALL); + glPopMatrix(); +} + +void +cone(void) +{ + glPushMatrix(); + glTranslatef(-40.0, -40.0, -400.0); + glCallList(DL_CONE); + glPopMatrix(); +} + +void +scene(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.0, 1.0, 1.0, 1.0}; + static GLfloat shad_mat[] = + {1.0, 0.1, 0.1, 1.0}; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (view == M_LIGHT_SOURCE_VIEW) { + gluPerspective(45.0, 1.0, 0.5, 600.0); + } else { + gluPerspective(33.0, 1.0, 10.0, 600.0); + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if (view == M_LIGHT_SOURCE_VIEW) { + gluLookAt(lightPos[X], lightPos[Y], lightPos[Z], + objectPos[X], objectPos[Y], objectPos[Z], + 0.0, 1.0, 0.); /* up is in positive Y direction */ + } else { + gluLookAt(0.0, 0.0, 0.0, + 0.0, 0.0, -100.0, + 0.0, 1.0, 0.); /* up is in positive Y direction */ + } + /* Place light 0 in the right place. */ + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* Floor with checkerboard texture. */ + glEnable(GL_TEXTURE_2D); + + glColor3f(0, 0, 0); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2i(0, 0); + glVertex3f(-100.0, -100.0, -320.0); + glTexCoord2i(4, 0); + glVertex3f(100.0, -100.0, -320.0); + glTexCoord2i(4, 4); + glVertex3f(100.0, -100.0, -520.0); + glTexCoord2i(0, 4); + glVertex3f(-100.0, -100.0, -520.0); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* Walls. */ + + glBegin(GL_QUADS); + /* Left wall. */ + glNormal3f(1.0, 0.0, 0.0); + glVertex3f(-100.0, -100.0, -320.0); + glVertex3f(-100.0, -100.0, -520.0); + glVertex3f(-100.0, 100.0, -520.0); + glVertex3f(-100.0, 100.0, -320.0); + + /* Right wall. */ + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(100.0, -100.0, -320.0); + glVertex3f(100.0, 100.0, -320.0); + glVertex3f(100.0, 100.0, -520.0); + glVertex3f(100.0, -100.0, -520.0); + + /* Ceiling. */ + glNormal3f(0.0, -1.0, 0.0); + glVertex3f(-100.0, 100.0, -320.0); + glVertex3f(-100.0, 100.0, -520.0); + glVertex3f(100.0, 100.0, -520.0); + glVertex3f(100.0, 100.0, -320.0); + + /* Back wall. */ + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(-100.0, -100.0, -520.0); + glVertex3f(100.0, -100.0, -520.0); + glVertex3f(100.0, 100.0, -520.0); + glVertex3f(-100.0, 100.0, -520.0); + glEnd(); + + cone(); + + sphere(); + + glPushMatrix(); + glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); + glCallList(DL_LIGHT); + glPopMatrix(); + + /* Draw shadowing object. */ + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, shad_mat); + + renderShadowingObject(); +} + +void +generateShadowVolume(void) +{ + GLfloat *eyePos; + + if (view == M_LIGHT_SOURCE_VIEW) { + eyePos = lightPos; + } else { + eyePos = sceneEyePos; + } + /* XXX The 2048 feedbackBufferGuessSize is large enough to + workaround the Octane/Impact bug where if the feedback + buffer is under 2048 entries, a buggy hardware feedback + path is used. 2048 forces the (bug free) software path. + This bug is fixed in IRIX 6.5. */ + svsGenerateShadowVolume(svs, renderShadowingObject, 2048, maxRadius, + lightPos, objectPos, eyePos); +} + +void +display(void) +{ + if (renderBoundary) { + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + generateShadowVolume(); + glEnable(GL_LIGHTING); + } else { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + switch (renderMode) { + case M_NO_SHADOW: + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + scene(); + break; + case M_NO_LIGHT: + /* Render scene without the light source enabled (conceptually, the + entire scene is "in the shadow"). */ + glEnable(GL_DEPTH_TEST); + glDisable(GL_LIGHT0); + scene(); + break; + case M_FRONT_VOLUME: + case M_BACK_VOLUME: + generateShadowVolume(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + scene(); + if (frontFace) { + glFrontFace(GL_CW); + } else { + glFrontFace(GL_CCW); + } + glCallList(DL_SHADOW_VOLUME); + glFrontFace(GL_CCW); + break; + case M_SHADOW: + /* Construct DL_SHADOW_VOLUME display list for the scene's current + shadow volume. */ + generateShadowVolume(); + + /* 1st scene pass. */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + scene(); + + /* 1st shadow volume pass: Enable stencil to increment the stencil + value of pixels that pass the depth test when drawing the front + facing polygons of the shadow volume. Do not update the depth + buffer while rendering the shadow volume. */ + glDisable(GL_LIGHTING); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glEnable(GL_STENCIL_TEST); + glDepthMask(GL_FALSE); + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + glCullFace(GL_FRONT); + glCallList(DL_SHADOW_VOLUME); + + /* 2nd shadow volume pass: Now, draw the back facing polygons of the + shadow volume except decrement pixels that pass the depth test. + Again, do not update the depth buffer. */ + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + glCullFace(GL_BACK); + glCallList(DL_SHADOW_VOLUME); + + glDisable(GL_CULL_FACE); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glCallList(DL_SHADOW_VOLUME_TOP); + glEnable(GL_CULL_FACE); + + /* Now, pixels that lie within the shadow volume are tagged with a one + stencil value. Empty shadowed regions of the shadow volume get + incremented, then decremented, to resolve to a net zero stencil + value. */ + + /* 2nd scene pass (render shadowed region): Re-enable update of the + depth and color buffer (use GL_LEQUAL for depth buffer so we can + over-write depth values again with color. Switch back to backface + culling and disable the light source. Only update pixels with a + stencil value of one (shadowed). */ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +#if 0 + glDepthFunc(GL_EQUAL); +#else + glDepthMask(GL_TRUE); + glDepthFunc(GL_LEQUAL); +#endif + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 1, 1); + glDisable(GL_LIGHT0); + glEnable(GL_LIGHTING); + scene(); + + /* Put state back to sane modes. */ + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + break; + } + } + glutSwapBuffers(); +} + +void +idle(void) +{ + if (rotatingObject) { + angle += 10.0; + } + if (swingingLight) { + swingTime += 0.05; + lightPos[X] += 2 * cos(swingTime); + } + glutPostRedisplay(); +} + +void +menu(int value) +{ + switch (value) { + case M_TORUS: + case M_CUBE: + case M_SPHERE: + case M_ICO: + case M_DOUBLE_TORUS: + shape = value; + maxRadius = objectMaxRadius[value]; + glutPostRedisplay(); + break; + case M_ANGLE: + angle += 10.0; + glutPostRedisplay(); + break; + case M_BOUNDARY: + renderBoundary = 1; + glutPostRedisplay(); + break; + case M_FRONT_VOLUME: + case M_BACK_VOLUME: + frontFace = (value == M_FRONT_VOLUME); + /* FALLTHROUGH */ + case M_NO_SHADOW: + case M_NO_LIGHT: + case M_SHADOW: + renderBoundary = 0; + renderMode = value; + glutPostRedisplay(); + break; + case M_LIGHT_SOURCE_VIEW: + case M_NORMAL_VIEW: + view = value; + glutPostRedisplay(); + break; + case M_STOP: + swingingLight = 0; + rotatingObject = 0; + glutIdleFunc(NULL); + break; + case M_SPIN: + rotatingObject = 1; + glutIdleFunc(idle); + break; + case M_SWING: + swingingLight = 1; + glutIdleFunc(idle); + break; + case 666: + svsFreeShadowVolumeState(svs); + exit(0); + /* NOTREACHED */ + break; + } +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE && swingingLight && rotatingObject) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } +} + +/* ARGSUSED1 */ +void +key(unsigned char c, int x, int y) +{ + switch (c) { + case 27: /* Escape. */ + svsFreeShadowVolumeState(svs); + exit(0); + break; + case 13: /* Return. */ + swingingLight = !swingingLight; + swingTime = M_PI / 2.0; + break; + case ' ': /* Space. */ + if (rotatingObject || swingingLight) { + rotatingObject = 0; + swingingLight = 0; + glutIdleFunc(NULL); + } else { + rotatingObject = 1; + swingingLight = 1; + glutIdleFunc(idle); + } + break; + } +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_HOME: + frontFace = !frontFace; + glutPostRedisplay(); + break; + case GLUT_KEY_UP: + lightPos[Y] += 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_DOWN: + lightPos[Y] -= 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_PAGE_UP: + lightPos[Z] += 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_PAGE_DOWN: + lightPos[Z] -= 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_RIGHT: + lightPos[X] += 10.0; + glutPostRedisplay(); + break; + case GLUT_KEY_LEFT: + lightPos[X] -= 10.0; + glutPostRedisplay(); + break; + } +} + +/* Create a single component checkboard texture map. */ +GLfloat * +makeTexture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +void +initScene(void) +{ + GLfloat *tex; + GLUquadricObj *qobj; + static GLfloat sphere_mat[] = + {1.0, 0.5, 0.0, 1.0}; + static GLfloat cone_mat[] = + {0.0, 0.5, 1.0, 1.0}; + + /* Turn on features. */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_CULL_FACE); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + /* Make display lists for sphere and cone; for efficiency. */ + + qobj = gluNewQuadric(); + + glNewList(DL_BALL, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qobj, 20.0, 20, 20); + glEndList(); + + glNewList(DL_CONE, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + glRotatef(-90.0, 1.0, 0.0, 0.0); + gluDisk(qobj, 0.0, 20.0, 20, 1); + gluCylinder(qobj, 20.0, 0.0, 60.0, 20, 20); + glEndList(); + + glNewList(DL_LIGHT, GL_COMPILE); + glDisable(GL_LIGHTING); + glColor3f(0.9, 0.9, 0.6); + gluSphere(qobj, 5.0, 20, 20); + glEnable(GL_LIGHTING); + glEndList(); + + gluDeleteQuadric(qobj); + + /* load pattern for current 2d texture */ + tex = makeTexture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); +} + +int +main(int argc, char **argv) +{ + int shapeMenu, viewMenu, actionMenu, renderModeMenu; + + svs = svsCreateShadowVolumeState(1000.0, NULL); + + glutInitDisplayString("stencil>=1 rgb double depth samples"); + glutInit(&argc, argv); + + glutCreateWindow("shadowfun"); + + stencilBits = glutGet(GLUT_WINDOW_STENCIL_SIZE); + printf("bits of stencil = %d\n", stencilBits); + + glutDisplayFunc(display); + glutVisibilityFunc(visible); + glutSpecialFunc(special); + glutKeyboardFunc(key); + + initScene(); + + shapeMenu = glutCreateMenu(menu); + glutAddMenuEntry("Torus", M_TORUS); + glutAddMenuEntry("Cube", M_CUBE); + glutAddMenuEntry("Sphere", M_SPHERE); + glutAddMenuEntry("Icosahedron", M_ICO); + glutAddMenuEntry("Double Torus", M_DOUBLE_TORUS); + + viewMenu = glutCreateMenu(menu); + glutAddMenuEntry("Normal view", M_NORMAL_VIEW); + glutAddMenuEntry("Light source view", M_LIGHT_SOURCE_VIEW); + + renderModeMenu = glutCreateMenu(menu); + glutAddMenuEntry("With shadow", M_SHADOW); + glutAddMenuEntry("With front shadow volume", M_FRONT_VOLUME); + glutAddMenuEntry("With back shadow volume", M_BACK_VOLUME); + glutAddMenuEntry("Without shadow", M_NO_SHADOW); + glutAddMenuEntry("Without light", M_NO_LIGHT); + glutAddMenuEntry("2D shadow boundary", M_BOUNDARY); + + actionMenu = glutCreateMenu(menu); + glutAddMenuEntry("Spin object", M_SPIN); + glutAddMenuEntry("Swing light", M_SWING); + glutAddMenuEntry("Stop", M_STOP); + + glutCreateMenu(menu); + glutAddSubMenu("Object shape", shapeMenu); + glutAddSubMenu("Viewpoint", viewMenu); + glutAddSubMenu("Render mode", renderModeMenu); + glutAddSubMenu("Action", actionMenu); + glutAddMenuEntry("Step rotate", M_ANGLE); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + menu(M_DOUBLE_TORUS); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +#else +int main(int argc, char** argv) +{ + fprintf(stderr, "This program requires 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 /* GLU_VERSION_1_2 */ diff --git a/lib/glut-3.7.6/progs/advanced/shadowfun.dsp b/lib/glut-3.7.6/progs/advanced/shadowfun.dsp new file mode 100644 index 0000000000..5721465d59 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowfun.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="shadowfun" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=shadowfun - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "shadowfun.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "shadowfun.mak" CFG="shadowfun - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "shadowfun - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "shadowfun - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "shadowfun - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "shadowfun - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "shadowfun - Win32 Release" +# Name "shadowfun - Win32 Debug" +# Begin Source File + +SOURCE=.\shadowfun.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/shadowmap.c b/lib/glut-3.7.6/progs/advanced/shadowmap.c new file mode 100644 index 0000000000..3255d30d1b --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowmap.c @@ -0,0 +1,447 @@ + +/* shadowmap.c - by Tom McReynolds, SGI */ + +/* Shadows: Shadow volumes. */ + +#include +#include +#include +#include + +/* This program demonstrates shadows on IR using single pass projective + texture method. 1. Render the scene with light position as the viewpoint + and save the depth-map into texture image. 2. Use texgen to generate + texture co-ordinates which are identical to vertex co-ordinates. The + texture matrix then transforms each pixel coods back to light co-ods. The + 'z' or the depth-value is now available in the 'r' texture co-ordinate. + + 3. Render the normal scene enabling texgen and shadow texture comparison. + Left mouse button: controls rotation of the scene + + Right mouse button: controls light (and shadow position) */ + +#define SCENE 10 +enum { + M_NORMAL, M_SHADOW, M_PROJTEX, M_LIGHT +}; + +GLfloat rotv[] = +{0.0, 0.0, 0.0}; /* rotation vector for scene */ +GLfloat rotl[] = +{0.0, 0.0, 0.0}; /* rotation vector for light */ +GLfloat lv[] = +{10.0, 10.0, 10.0, 1.0}; /* default light position */ + +GLfloat perspective_mat[16], modelview_mat[16], temp[16]; +int width = 512, height = 512; +int mouse_button, mouse_state; +static int do_light = 0; +static int do_proj = 0; /* Use projective textures instead of shadows */ +/* are shadow extensions supported? */ +GLboolean shadows_supported = GL_FALSE; +GLboolean ambient_shadows = GL_FALSE; +GLboolean depth_texture = GL_FALSE; + +static void generate_shadow_map(void); + +static void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); + width = w; + height = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w / (GLfloat) h, 2.0, 30.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 15, + 0, 0, 0, + 0, 1, 0); +} + +/* ARGSUSED1 */ +static void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + } +} + +/* ARGSUSED2 */ +static void +mouse(int button, int state, int x, int y) +{ + mouse_button = button; + mouse_state = state; +} + +static void +motion(int x, int y) +{ + if (mouse_state == GLUT_UP) + return; + + switch (mouse_button) { + case GLUT_LEFT_BUTTON: + rotv[1] = 180.0 * x / 400.0 - 90.0; + rotv[0] = 180.0 * y / 400.0 - 90.0; + break; + case GLUT_MIDDLE_BUTTON: + rotl[0] = 180.0 * x / 400.0 - 90.0; + rotl[1] = 180.0 * y / 400.0 - 90.0; + break; + } + glutPostRedisplay(); +} + +static void +display(void) +{ + /* Render the scene with the light source as the viewpoint and save the + depth values in the texture map. */ + generate_shadow_map(); + + /* Now render the normal scene using projective textures to get the depth + value from the light's point of view into the r-cood of the texture. */ + glEnable(GL_TEXTURE_2D); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glGetFloatv(GL_PROJECTION_MATRIX, perspective_mat); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(0.5, 0.5, 0.4994); + glScalef(0.5, 0.5, 0.5); + glMultMatrixf(perspective_mat); + glMultMatrixf(modelview_mat); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glRotatef(rotv[0], 1, 0, 0); + glRotatef(rotv[1], 0, 1, 0); + glRotatef(rotv[2], 0, 0, 1); + glCallList(SCENE); + + glPopMatrix(); + glutSwapBuffers(); +} + +static void +render_normal_view(void) +{ + glDisable(GL_TEXTURE_2D); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + gluLookAt(0, 0, 15, + 0, 0, 0, + 0, 1, 0); + glRotatef(rotv[0], 1, 0, 0); + glRotatef(rotv[1], 0, 1, 0); + glRotatef(rotv[2], 0, 0, 1); + glCallList(SCENE); + + glPopMatrix(); + glutSwapBuffers(); +} + +static void +render_light_view(void) +{ + glDisable(GL_TEXTURE_2D); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + gluLookAt(lv[0], lv[1], lv[2], + 0, 0, 0, + 0, 1, 0); + glRotatef(rotl[0], 1, 0, 0); + glRotatef(rotl[1], 0, 1, 0); + glRotatef(rotl[2], 0, 0, 1); + glGetFloatv(GL_MODELVIEW_MATRIX, modelview_mat); + + glCallList(SCENE); + glPopMatrix(); + if (do_light) + glutSwapBuffers(); +} + +static void +generate_shadow_map(void) +{ + int x, y; + GLfloat log2 = log(2.0); + + x = 1 << ((int) (log((float) width) / log2)); + y = 1 << ((int) (log((float) height) / log2)); + glViewport(0, 0, x, y); + render_light_view(); + + /* Read in frame-buffer into a depth texture map */ +#if defined(GL_EXT_subtexture) && defined(GL_EXT_copy_texture) +#ifdef GL_SGIX_depth_texture + if (do_proj && depth_texture) +#endif + glCopyTexImage2DEXT(GL_TEXTURE_2D, 0, GL_RGBA, + 0, 0, x, y, 0); +#ifdef GL_SGIX_depth_texture + else + glCopyTexImage2DEXT(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_SGIX, + 0, 0, x, y, 0); +#endif +#endif + glViewport(0, 0, width, height); +} + +static void +menu(int mode) +{ + switch (mode) { + case M_NORMAL: + do_light = 0; + do_proj = 0; +#ifdef GL_SGIX_shadow + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_FALSE); +#endif + glutDisplayFunc(render_normal_view); + break; + case M_SHADOW: +#ifdef GL_SGIX_shadow + do_light = 0; + do_proj = 0; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_TRUE); + glutDisplayFunc(display); +#endif + break; + case M_PROJTEX: + do_light = 0; + do_proj = 1; +#ifdef GL_SGIX_shadow + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_FALSE); +#endif + glutDisplayFunc(display); + break; + case M_LIGHT: + do_light = 1; + if (do_light) + glutDisplayFunc(render_light_view); + else + glutDisplayFunc(display); + break; + } + glutPostRedisplay(); +} + +#define XFORM(cmds) \ + glMatrixMode(GL_TEXTURE); \ + cmds; \ + glMatrixMode(GL_MODELVIEW); \ + cmds + +static void +create_scene(void) +{ + GLfloat floor_col[] = + {0.7, 0.7, 0.7}; + GLfloat floor_norm[] = + {0.0, 0.0, 1.0}; + GLfloat floor_verts[4][3] = + { + {4.0, 4.0, 0.0}, + {-4.0, 4.0, 0.0}, + {-4.0, -4.0, 0.0}, + {4.0, -4.0, 0.0}}; + GLfloat sphere_col[] = + {0.7, 0.1, 0.2}; + GLfloat box_col[] = + {0.1, 0.2, 0.7}; + GLfloat box_verts[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}}}; + GLfloat box_norm[6][3] = + { + {0, 0, -1}, + {1, 0, 0}, + {0, 0, 1}, + {-1, 0, 0}, + {0, 1, 0}, + {0, -1, 0}}; + GLUquadricObj *q; + int i; + + glNewList(SCENE, GL_COMPILE); + + glBegin(GL_QUADS); /* draw the floor */ + glNormal3fv(floor_norm); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, floor_col); + for (i = 0; i < 4; i++) + glVertex3fv(floor_verts[i]); + glEnd(); + + q = gluNewQuadric(); + XFORM(glPushMatrix(); + glTranslatef(1.0, 1.0, 1.01)); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_col); + gluSphere(q, 1.0, 40, 40); + XFORM(glPopMatrix()); + + XFORM(glPushMatrix(); + glTranslatef(-1.0, -1.0, 1.01)); + for (i = 0; i < 6; i++) { + glBegin(GL_QUADS); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, box_col); + glNormal3fv(box_norm[i]); + glVertex3fv(box_verts[i][0]); + glVertex3fv(box_verts[i][1]); + glVertex3fv(box_verts[i][2]); + glVertex3fv(box_verts[i][3]); + glEnd(); + } + XFORM(glPopMatrix()); + glEndList(); +} + +static void +init(void) +{ + GLfloat ambient[] = + {0.1, 0.1, 0.1, 1.0}; + GLfloat diffuse[] = + {0.8, 0.7, 0.8, 1.0}; + GLfloat specular[] = + {0.5, 0.6, 0.8, 1.0}; + GLfloat p[4]; + + create_scene(); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClearDepth(1.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_POLYGON_SMOOTH); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lv); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (shadows_supported) { +#ifdef GL_SGIX_shadow_ambient + if (ambient_shadows) + glTexParameterf(GL_TEXTURE_2D, GL_SHADOW_AMBIENT_SGIX, 0.6); +#endif +#ifdef GL_SGIX_shadow + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_TRUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_OPERATOR_SGIX, + GL_TEXTURE_LEQUAL_R_SGIX); +#endif + } + /* Enable texgen to get texture-coods (x, y, z, w) at every point.These + texture co-ordinates are then transformed by the texture matrix. */ + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + p[0] = 1.0; + p[1] = p[2] = p[3] = 0.0; + glTexGenfv(GL_S, GL_OBJECT_PLANE, p); + + p[0] = 0.0; + p[1] = 1.0; + p[2] = p[3] = 0.0; + glTexGenfv(GL_T, GL_OBJECT_PLANE, p); + + p[0] = p[1] = 0.0; + p[2] = 1.0, p[3] = 0.0; + glTexGenfv(GL_R, GL_OBJECT_PLANE, p); + + p[0] = p[1] = p[2] = 0.0; + p[3] = 1.0; + glTexGenfv(GL_Q, GL_OBJECT_PLANE, p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_GEN_Q); +} + +int +main(int argc, char *argv[]) +{ + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowSize(width, height); + glutCreateWindow("Shadow Map"); + + if (glutExtensionSupported("GL_SGIX_shadow") && + glutExtensionSupported("GL_EXT_subtexture") && + glutExtensionSupported("GL_EXT_copy_texture")) { + shadows_supported = GL_TRUE; + ambient_shadows = glutExtensionSupported("GL_SGIX_shadow_ambient"); + depth_texture = glutExtensionSupported("GL_SGIX_depth_texture"); + } else { + fprintf(stderr, "shadowmap: uses several OpenGL extensions to operate fully:\n"); + fprintf(stderr, " GL_SGIX_shadow\n"); + fprintf(stderr, " GL_SGIX_shadow_ambient\n"); + fprintf(stderr, " GL_SGIS_depth_texture\n"); + fprintf(stderr, " GL_EXT_subtexture\n"); + fprintf(stderr, " GL_EXT_copy_texture\n"); + } + + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMotionFunc(motion); + glutMouseFunc(mouse); + glutKeyboardFunc(key); + glutCreateMenu(menu); + glutAddMenuEntry("Normal view", M_NORMAL); + glutAddMenuEntry("Light view", M_LIGHT); + glutAddMenuEntry("Projective textures", M_PROJTEX); + if (shadows_supported) + glutAddMenuEntry("Shadows", M_SHADOW); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/shadowmap.dsp b/lib/glut-3.7.6/progs/advanced/shadowmap.dsp new file mode 100644 index 0000000000..904a49afac --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowmap.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="shadowmap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=shadowmap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "shadowmap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "shadowmap.mak" CFG="shadowmap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "shadowmap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "shadowmap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "shadowmap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "shadowmap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "shadowmap - Win32 Release" +# Name "shadowmap - Win32 Debug" +# Begin Source File + +SOURCE=.\shadowmap.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/shadowvol.c b/lib/glut-3.7.6/progs/advanced/shadowvol.c new file mode 100644 index 0000000000..e4c0c44c03 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowvol.c @@ -0,0 +1,373 @@ + +/* shadowvol.c - by Tom McReynolds, SGI */ + +/* Shadows: Shadow maps */ + +#include +#include + +/* Demonstrate shadow volumes */ + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum { + SPHERE = 1, CONE, LIGHT, SHADOWVOL +}; + +typedef struct { + GLfloat *verticies; + GLfloat *normal; + int n; /* number of verticies */ +} ShadObj; + +GLfloat shadVerts[] = +{30.f, 30.f, -350.f, + 60.f, 20.f, -340.f, + 40.f, 40.f, -400.f}; + +GLfloat shadNormal[] = +{1.f, 1.f, 1.f}; +ShadObj shadower; + +enum { + X, Y, Z +}; + +/* simple way to extend a point to build shadow volume */ +void +extend(GLfloat new[3], GLfloat light[3], GLfloat vertex[3], GLfloat t) +{ + GLfloat delta[3]; + + delta[X] = vertex[X] - light[X]; + delta[Y] = vertex[Y] - light[Y]; + delta[Z] = vertex[Z] - light[Z]; + + new[X] = light[X] + delta[X] * t; + new[Y] = light[Y] + delta[Y] * t; + new[Z] = light[Z] + delta[Z] * t; +} + +/* Create a shadow volume in a display list */ +/* XXX light should have 4 compoents */ +void +makeShadowVolume(ShadObj * shadower, GLfloat light[3], + GLfloat t, GLint dlist) +{ + int i; + GLfloat newv[3]; + + glNewList(dlist, GL_COMPILE); + glDisable(GL_LIGHTING); + glBegin(GL_QUADS); + /* for debugging */ + glColor3f(.2f, .8f, .4f); + for (i = 0; i < shadower->n; i++) { + glVertex3fv(&shadower->verticies[i * 3]); + extend(newv, light, &shadower->verticies[i * 3], t); + glVertex3fv(newv); + extend(newv, light, &shadower->verticies[((i + 1) % shadower->n) * 3], + t); + glVertex3fv(newv); + glVertex3fv(&shadower->verticies[((i + 1) % shadower->n) * 3]); + } + glEnd(); + glEnable(GL_LIGHTING); + glEndList(); +} + +void +sphere(void) +{ + glPushMatrix(); + glTranslatef(60.f, -50.f, -360.f); + glCallList(SPHERE); + glPopMatrix(); +} + +void +cone(void) +{ + glPushMatrix(); + glTranslatef(-40.f, -40.f, -400.f); + glCallList(CONE); + glPopMatrix(); + +} + +enum { + NONE, NOLIGHT, VOLUME, SHADOW +}; + +int rendermode = NONE; + +void +menu(int mode) +{ + rendermode = mode; + glutPostRedisplay(); +} + +GLfloat leftwallshadow[4][4]; +GLfloat floorshadow[4][4]; + +GLfloat lightpos[] = +{50.f, 50.f, -340.f, 1.f}; + +/* render while jittering the shadows */ +void +render(ShadObj * obj) +{ + static GLfloat shad_mat[] = + {1.f, .1f, .1f, 1.f}; + GLfloat *v; /* vertex pointer */ + int i; + + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + cone(); + + sphere(); + + glCallList(LIGHT); + + /* draw shadowing object */ + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, shad_mat); + glBegin(GL_POLYGON); + glNormal3fv(obj->normal); + for (v = obj->verticies, i = 0; i < obj->n; i++) { + glVertex3fv(v); + v += 3; + } + glEnd(); + +} + +void +redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + switch (rendermode) { + case NONE: + render(&shadower); + break; + case NOLIGHT: + glDisable(GL_LIGHT0); + render(&shadower); + glEnable(GL_LIGHT0); + break; + case VOLUME: + render(&shadower); + glCallList(SHADOWVOL); + break; + case SHADOW: + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + render(&shadower); /* render scene in depth buffer */ + + glEnable(GL_STENCIL_TEST); + glDepthMask(GL_FALSE); + glStencilFunc(GL_ALWAYS, 0, 0); + + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glCullFace(GL_BACK); /* increment using front face of shadow volume */ + glCallList(SHADOWVOL); + + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); + glCullFace(GL_FRONT); /* increment using front face of shadow volume */ + glCallList(SHADOWVOL); + + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glCullFace(GL_BACK); + glDepthFunc(GL_LEQUAL); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glStencilFunc(GL_EQUAL, 1, 1); /* draw shadowed part */ + glDisable(GL_LIGHT0); + render(&shadower); + + glStencilFunc(GL_EQUAL, 0, 1); /* draw lit part */ + glEnable(GL_LIGHT0); + render(&shadower); + + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + break; + } + + glutSwapBuffers(); /* high end machines may need this */ +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + if (key == '\033') + exit(0); +} + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + GLUquadricObj *sphere, *cone, *base; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE); + (void) glutCreateWindow("shadow volumes"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("No Shadows", NONE); + glutAddMenuEntry("No Light", NOLIGHT); + glutAddMenuEntry("Show Volume", VOLUME); + glutAddMenuEntry("Shadows", SHADOW); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_CULL_FACE); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* make display lists for sphere and cone; for efficiency */ + + glNewList(SPHERE, GL_COMPILE); + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + glRotatef(-90.f, 1.f, 0.f, 0.f); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glNewList(LIGHT, GL_COMPILE); + sphere = gluNewQuadric(); + glPushMatrix(); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + glDisable(GL_LIGHTING); + glColor3f(.9f, .9f, .6f); + gluSphere(sphere, 5.f, 20, 20); + glEnable(GL_LIGHTING); + glPopMatrix(); + gluDeleteQuadric(sphere); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + shadower.verticies = shadVerts; + shadower.normal = shadNormal; + shadower.n = sizeof(shadVerts) / (3 * sizeof(GLfloat)); + + makeShadowVolume(&shadower, lightpos, 10.f, SHADOWVOL); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/shadowvol.dsp b/lib/glut-3.7.6/progs/advanced/shadowvol.dsp new file mode 100644 index 0000000000..160d81e537 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/shadowvol.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="shadowvol" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=shadowvol - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "shadowvol.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "shadowvol.mak" CFG="shadowvol - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "shadowvol - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "shadowvol - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "shadowvol - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "shadowvol - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "shadowvol - Win32 Release" +# Name "shadowvol - Win32 Debug" +# Begin Source File + +SOURCE=.\shadowvol.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/silhouette.c b/lib/glut-3.7.6/progs/advanced/silhouette.c new file mode 100644 index 0000000000..8e5f208837 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/silhouette.c @@ -0,0 +1,248 @@ + +/* silhouette.c - by Tom McReynolds, SGI */ + +/* Doing Silhouette Edges with stencil */ + +#include +#include +#include + +enum { + CONE = 1 +}; + +/* Draw a cone */ +void +cone(void) +{ + glPushMatrix(); + glTranslatef(0.f, 0.f, -30.f); + glCallList(CONE); + glPopMatrix(); +} + +/* Draw a torus */ +void +torus(void) +{ + glutSolidTorus(10., 20., 20, 20); +} + +enum { + SIL, OBJ, SIL_AND_OBJ, TOGGLE +}; + +int rendermode = OBJ; + +void (*curobj) (void) = cone; + +void +menu(int mode) +{ + switch (mode) { + case SIL: + case OBJ: + case SIL_AND_OBJ: + rendermode = mode; + break; + case TOGGLE: + if (curobj == cone) + curobj = torus; + else + curobj = cone; + break; + } + glutPostRedisplay(); +} + +int winWidth = 512; +int winHeight = 512; + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glViewport(0, 0, wid, ht); + winWidth = wid; + winHeight = ht; + glutPostRedisplay(); +} + +GLfloat viewangle; + +void +drawsilhouette(void) +{ + int i; + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glDisable(GL_DEPTH_TEST); /* so the depth buffer doesn't change */ + for (i = -1; i < 2; i += 2) { /* set stencil around object */ + glViewport(i, 0, winWidth + i, winHeight); + curobj(); + } + for (i = -1; i < 2; i += 2) { + glViewport(0, i, winWidth, winHeight + i); + curobj(); + } + + /* cut out stencil where object is */ + glViewport(0, 0, winWidth, winHeight); + glStencilFunc(GL_ALWAYS, 0, 0); + curobj(); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glStencilFunc(GL_EQUAL, 1, 1); + + glDisable(GL_LIGHTING); + glColor3f(1.f, 0.f, 0.f); /* draw silhouette red */ + glRotatef(-viewangle, 0.f, 1.f, 0.f); + glRecti(-50, -50, 50, 50); + glRotatef(viewangle, 0.f, 1.f, 0.f); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glDisable(GL_STENCIL_TEST); +} + +void +redraw(void) +{ + /* clear stencil each time */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + glRotatef(viewangle, 0.f, 1.f, 0.f); + + switch (rendermode) { + case SIL: + drawsilhouette(); + break; + case SIL_AND_OBJ: + drawsilhouette(); + curobj(); + break; + case OBJ: + curobj(); + break; + } + + glPopMatrix(); + glutSwapBuffers(); +} + +/* animate scene by rotating */ +enum { + ANIM_LEFT, ANIM_RIGHT +}; +int animDirection = ANIM_LEFT; + +void +anim(void) +{ + if (animDirection == ANIM_LEFT) + viewangle -= 1.f; + else + viewangle += 1.f; + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +/* special keys, like array and F keys */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + glutIdleFunc(anim); + animDirection = ANIM_LEFT; + break; + case GLUT_KEY_RIGHT: + glutIdleFunc(anim); + animDirection = ANIM_RIGHT; + break; + case GLUT_KEY_UP: + case GLUT_KEY_DOWN: + glutIdleFunc(0); + break; + } +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'a': + viewangle -= 10.f; + glutPostRedisplay(); + break; + case 's': + viewangle += 10.f; + glutPostRedisplay(); + break; + case '\033': + exit(0); + } +} + +int picked_object; +int xpos = 0, ypos = 0; +int newxpos, newypos; +int startx, starty; + +int +main(int argc, char **argv) +{ + static GLfloat lightpos[] = + {25.f, 50.f, -50.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE); + (void) glutCreateWindow("silhouette edges"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + glutAddMenuEntry("Object", OBJ); + glutAddMenuEntry("Silhouette Only", SIL); + glutAddMenuEntry("Object and Silhouette", SIL_AND_OBJ); + glutAddMenuEntry("Toggle Object", TOGGLE); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + /* make display list for cone; for efficiency */ + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 15., 32, 1); + gluCylinder(cone, 15., 0., 60., 32, 32); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glMatrixMode(GL_PROJECTION); + glOrtho(-50., 50., -50., 50., -50., 50.); + glMatrixMode(GL_MODELVIEW); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/silhouette.dsp b/lib/glut-3.7.6/progs/advanced/silhouette.dsp new file mode 100644 index 0000000000..9ad7ee1b93 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/silhouette.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="silhouette" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=silhouette - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "silhouette.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "silhouette.mak" CFG="silhouette - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "silhouette - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "silhouette - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "silhouette - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "silhouette - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "silhouette - Win32 Release" +# Name "silhouette - Win32 Debug" +# Begin Source File + +SOURCE=.\silhouette.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/softshadow.c b/lib/glut-3.7.6/progs/advanced/softshadow.c new file mode 100644 index 0000000000..0dbd651fb4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/softshadow.c @@ -0,0 +1,405 @@ + +/* softshadow.c - by Tom McReynolds, SGI */ + +/* Using the accumulation buffer for soft shadows. */ + +#include +#include + +/* Demonstrate the use of accumulation buffer to create soft shadows */ + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum { + SPHERE = 1, CONE, LIGHT, LEFTWALL, FLOOR +}; + +/* create a matrix that will project the desired shadow */ +void +shadowmatrix(GLfloat shadowMat[4][4], + GLfloat groundplane[4], + GLfloat lightpos[4]) +{ + GLfloat dot; + + /* find dot product between light position vector and ground plane normal */ + dot = groundplane[0] * lightpos[0] + + groundplane[1] * lightpos[1] + + groundplane[2] * lightpos[2] + + groundplane[3] * lightpos[3]; + + shadowMat[0][0] = dot - lightpos[0] * groundplane[0]; + shadowMat[1][0] = 0.f - lightpos[0] * groundplane[1]; + shadowMat[2][0] = 0.f - lightpos[0] * groundplane[2]; + shadowMat[3][0] = 0.f - lightpos[0] * groundplane[3]; + + shadowMat[0][1] = 0.f - lightpos[1] * groundplane[0]; + shadowMat[1][1] = dot - lightpos[1] * groundplane[1]; + shadowMat[2][1] = 0.f - lightpos[1] * groundplane[2]; + shadowMat[3][1] = 0.f - lightpos[1] * groundplane[3]; + + shadowMat[0][2] = 0.f - lightpos[2] * groundplane[0]; + shadowMat[1][2] = 0.f - lightpos[2] * groundplane[1]; + shadowMat[2][2] = dot - lightpos[2] * groundplane[2]; + shadowMat[3][2] = 0.f - lightpos[2] * groundplane[3]; + + shadowMat[0][3] = 0.f - lightpos[3] * groundplane[0]; + shadowMat[1][3] = 0.f - lightpos[3] * groundplane[1]; + shadowMat[2][3] = 0.f - lightpos[3] * groundplane[2]; + shadowMat[3][3] = dot - lightpos[3] * groundplane[3]; + +} + +enum { + X, Y, Z +}; +enum { + A, B, C, D +}; + +/* find the plane equation given 3 points */ +void +findplane(GLfloat plane[4], + GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ + GLfloat vec0[3], vec1[3]; + + /* need 2 vectors to find cross product */ + vec0[X] = v1[X] - v0[X]; + vec0[Y] = v1[Y] - v0[Y]; + vec0[Z] = v1[Z] - v0[Z]; + + vec1[X] = v2[X] - v0[X]; + vec1[Y] = v2[Y] - v0[Y]; + vec1[Z] = v2[Z] - v0[Z]; + + /* find cross product to get A, B, and C of plane equation */ + plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; + plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); + plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + + plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} + +void +sphere(void) +{ + glPushMatrix(); + glTranslatef(60.f, -50.f, -360.f); + glCallList(SPHERE); + glPopMatrix(); +} + +void +cone(void) +{ + glPushMatrix(); + glTranslatef(-40.f, -40.f, -400.f); + glCallList(CONE); + glPopMatrix(); + +} + +enum { + NONE, SHADOW +}; + +int rendermode = NONE; + +void +menu(int mode) +{ + rendermode = mode; + glutPostRedisplay(); +} + +GLfloat leftwallshadow[4][4]; +GLfloat floorshadow[4][4]; + +GLfloat lightpos[] = +{50.f, 50.f, -320.f, 1.f}; + +/* render while jittering the shadows */ +void +render(GLfloat dx, GLfloat dy, GLfloat dz) +{ + + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + if (rendermode == SHADOW) { + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(0.f, 0.f, 0.f); /* shadow color */ + + glPushMatrix(); + glMultMatrixf((GLfloat *) floorshadow); + glTranslatef(dx, dy, dz); + cone(); + glPopMatrix(); + + glPushMatrix(); + glMultMatrixf((GLfloat *) floorshadow); + glTranslatef(dx, dy, dz); + sphere(); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + /* walls */ + + if (rendermode == SHADOW) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + glEnd(); + + if (rendermode == SHADOW) { + glStencilFunc(GL_EQUAL, 1, 1); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glColor3f(0.f, 0.f, 0.f); /* shadow color */ + glDisable(GL_DEPTH_TEST); + glPushMatrix(); + glMultMatrixf((GLfloat *) leftwallshadow); + glTranslatef(dx, dy, dz); + cone(); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + glBegin(GL_QUADS); + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + glDisable(GL_LIGHTING); + glColor3f(1.f, 1.f, .7f); + glCallList(LIGHT); + glEnable(GL_LIGHTING); + glPopMatrix(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + cone(); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + sphere(); + +} + +void +redraw(void) +{ + int dx, dy, dz; + + dy = 0; + /* jitter the light around */ + if (rendermode == SHADOW) { + glClear(GL_ACCUM_BUFFER_BIT); + for (dz = -4; dz < 5; dz += 2) { + for (dx = -4; dx < 5; dx += 2) { + render((GLfloat) dx, (GLfloat) dy, (GLfloat) dz); + glAccum(GL_ACCUM, 1.f / 25); + } + } + glAccum(GL_RETURN, 1.f); + } else + render(0.f, 0.f, 0.f); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + if (key == '\033') + exit(0); +} + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + GLUquadricObj *sphere, *cone, *base; + GLfloat plane[4]; + GLfloat v0[3], v1[3], v2[3]; + + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE | GLUT_ACCUM); + (void) glutCreateWindow("soft shadows"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("No Shadows", NONE); + glutAddMenuEntry("Shadows", SHADOW); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* make shadow matricies */ + + /* 3 points on floor */ + v0[X] = -100.f; + v0[Y] = -100.f; + v0[Z] = -320.f; + v1[X] = 100.f; + v1[Y] = -100.f; + v1[Z] = -320.f; + v2[X] = 100.f; + v2[Y] = -100.f; + v2[Z] = -520.f; + + findplane(plane, v0, v1, v2); + shadowmatrix(floorshadow, plane, lightpos); + + /* 3 points on left wall */ + v0[X] = -100.f; + v0[Y] = -100.f; + v0[Z] = -320.f; + v1[X] = -100.f; + v1[Y] = -100.f; + v1[Z] = -520.f; + v2[X] = -100.f; + v2[Y] = 100.f; + v2[Z] = -520.f; + + findplane(plane, v0, v1, v2); + shadowmatrix(leftwallshadow, plane, lightpos); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* make display lists for sphere and cone; for efficiency */ + + glNewList(SPHERE, GL_COMPILE); + sphere = gluNewQuadric(); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(LIGHT, GL_COMPILE); + sphere = gluNewQuadric(); + gluSphere(sphere, 5.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + glNewList(FLOOR, GL_COMPILE); + glEndList(); + + glNewList(LEFTWALL, GL_COMPILE); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/softshadow.dsp b/lib/glut-3.7.6/progs/advanced/softshadow.dsp new file mode 100644 index 0000000000..e107cf310a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/softshadow.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="softshadow" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=softshadow - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "softshadow.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "softshadow.mak" CFG="softshadow - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "softshadow - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "softshadow - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "softshadow - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "softshadow - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "softshadow - Win32 Release" +# Name "softshadow - Win32 Debug" +# Begin Source File + +SOURCE=.\softshadow.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/sphere.c b/lib/glut-3.7.6/progs/advanced/sphere.c new file mode 100644 index 0000000000..b02271c41e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/sphere.c @@ -0,0 +1,187 @@ + +/* sphere.c - by David Blythe, SGI */ + +/* Instead of tessellating a sphere by lines of longitude and latitude + (a technique that over tessellates the poles and under tessellates + the equator of the sphere), tesselate based on regular solids for a + more uniform tesselation. + + This approach is arguably better than the gluSphere routine's + approach using slices and stacks (latitude and longitude). -mjk */ + +#include +#include +#include + +typedef struct { + float x, y, z; +} point; + +typedef struct { + point pt[3]; +} triangle; + +/* six equidistant points lying on the unit sphere */ +#define XPLUS { 1, 0, 0 } /* X */ +#define XMIN { -1, 0, 0 } /* -X */ +#define YPLUS { 0, 1, 0 } /* Y */ +#define YMIN { 0, -1, 0 } /* -Y */ +#define ZPLUS { 0, 0, 1 } /* Z */ +#define ZMIN { 0, 0, -1 } /* -Z */ + +/* for icosahedron */ +#define CZ (0.89442719099991) /* 2/sqrt(5) */ +#define SZ (0.44721359549995) /* 1/sqrt(5) */ +#define C1 (0.951056516) /* cos(18), */ +#define S1 (0.309016994) /* sin(18) */ +#define C2 (0.587785252) /* cos(54), */ +#define S2 (0.809016994) /* sin(54) */ +#define X1 (C1*CZ) +#define Y1 (S1*CZ) +#define X2 (C2*CZ) +#define Y2 (S2*CZ) + +#define Ip0 {0., 0., 1.} +#define Ip1 {-X2, -Y2, SZ} +#define Ip2 {X2, -Y2, SZ} +#define Ip3 {X1, Y1, SZ} +#define Ip4 {0, CZ, SZ} +#define Ip5 {-X1, Y1, SZ} + +#define Im0 {-X1, -Y1, -SZ} +#define Im1 {0, -CZ, -SZ} +#define Im2 {X1, -Y1, -SZ} +#define Im3 {X2, Y2, -SZ} +#define Im4 {-X2, Y2, -SZ} +#define Im5 {0., 0., -1.} + +/* vertices of a unit icosahedron */ +static triangle icosahedron[20]= { + /* front pole */ + { {Ip0, Ip1, Ip2}, }, + { {Ip0, Ip5, Ip1}, }, + { {Ip0, Ip4, Ip5}, }, + { {Ip0, Ip3, Ip4}, }, + { {Ip0, Ip2, Ip3}, }, + + /* mid */ + { {Ip1, Im0, Im1}, }, + { {Im0, Ip1, Ip5}, }, + { {Ip5, Im4, Im0}, }, + { {Im4, Ip5, Ip4}, }, + { {Ip4, Im3, Im4}, }, + { {Im3, Ip4, Ip3}, }, + { {Ip3, Im2, Im3}, }, + { {Im2, Ip3, Ip2}, }, + { {Ip2, Im1, Im2}, }, + { {Im1, Ip2, Ip1}, }, + + /* back pole */ + { {Im3, Im2, Im5}, }, + { {Im4, Im3, Im5}, }, + { {Im0, Im4, Im5}, }, + { {Im1, Im0, Im5}, }, + { {Im2, Im1, Im5}, }, +}; + +/* normalize point r */ +static void +normalize(point *r) { + float mag; + + mag = r->x * r->x + r->y * r->y + r->z * r->z; + if (mag != 0.0f) { + mag = 1.0f / sqrt(mag); + r->x *= mag; + r->y *= mag; + r->z *= mag; + } +} + +/* linearly interpolate between a & b, by fraction f */ +static void +lerp(point *a, point *b, float f, point *r) { + r->x = a->x + f*(b->x-a->x); + r->y = a->y + f*(b->y-a->y); + r->z = a->z + f*(b->z-a->z); +} + +void +sphere(int maxlevel) { + int nrows = 1 << maxlevel; + int s; + + /* iterate over the 20 sides of the icosahedron */ + for(s = 0; s < 20; s++) { + int i; + triangle *t = &icosahedron[s]; + for(i = 0; i < nrows; i++) { + /* create a tstrip for each row */ + /* number of triangles in this row is number in previous +2 */ + /* strip the ith trapezoid block */ + point v0, v1, v2, v3, va, vb; + int j; + lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0); + lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1); + lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2); + lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3); + glBegin(GL_TRIANGLE_STRIP); +#define V(v) { point x; x = v; normalize(&x); glNormal3fv(&x.x); glVertex3fv(&x.x); } + V(v0); + V(v1); + for(j = 0; j < i; j++) { + /* calculate 2 more vertices at a time */ + lerp(&v0, &v2, (float)(j+1)/(i+1), &va); + lerp(&v1, &v3, (float)(j+1)/i, &vb); + V(va); + V(vb); + } + V(v2); +#undef V + glEnd(); + } + } +} + +float * +sphere_tris(int maxlevel) { + int nrows = 1 << maxlevel; + int s, n; + float *buf, *b; + + n = 20*(1 << (maxlevel * 2)); + b = buf = (float *)malloc(n*3*3*sizeof(float)); + + /* iterate over the 20 sides of the icosahedron */ + for(s = 0; s < 20; s++) { + int i; + triangle *t = &icosahedron[s]; + for(i = 0; i < nrows; i++) { + /* create a tstrip for each row */ + /* number of triangles in this row is number in previous +2 */ + /* strip the ith trapezoid block */ + point v0, v1, v2, v3, va, vb, x1, x2; + int j; + lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0); + lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1); + lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2); + lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3); +#define V(a, c, v) { point x = v; normalize(&a); normalize(&c); normalize(&x); \ + b[0] = a.x; b[1] = a.y; b[2] = a.z; \ + b[3] = c.x; b[4] = c.y; b[5] = c.z; \ + b[6] = x.x; b[7] = x.y; b[8] = x.z; b+=9; } + x1 = v0; + x2 = v1; + for(j = 0; j < i; j++) { + /* calculate 2 more vertices at a time */ + lerp(&v0, &v2, (float)(j+1)/(i+1), &va); + lerp(&v1, &v3, (float)(j+1)/i, &vb); + V(x1,x2,va); x1 = x2; x2 = va; + V(vb,x2,x1); x1 = x2; x2 = vb; + } + V(x1, x2, v2); +#undef V + } + } + return buf; +} diff --git a/lib/glut-3.7.6/progs/advanced/tess.c b/lib/glut-3.7.6/progs/advanced/tess.c new file mode 100644 index 0000000000..8cb504c4d9 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/tess.c @@ -0,0 +1,206 @@ + +/* tess.c - by David Blythe, SGI */ + +#include +#include +#include + +static GLfloat spin = 0; +static int level = 4; +static int model = 0; +static GLfloat rotx, roty; +static int ox = -1, oy = -1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +movelight(int x, int y) { + spin += (y-oy); + ox = x; oy = y; + if (spin > 360.) spin -= 360.; + if (spin < -360.) spin -= -360.; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) movelight(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void togglewire(void) { + static int toggle = 0; + toggle ^= 1; + glPolygonMode(GL_FRONT_AND_BACK, toggle ? GL_LINE : GL_FILL); +} + +void genmodel(void) { + extern void sphere(int level); + + glNewList(1, GL_COMPILE); + if (model) { + GLUquadricObj *q = gluNewQuadric(); + + gluSphere(q, 1.0, 10*level, 10*level); + gluDeleteQuadric(q); + } else { + sphere(level-1); + } + glEndList(); +} + +void togglemodel(void) { + model ^= 1; + genmodel(); +} + +void levelup(void) { + level += 1; + if (level > 7) level = 7; + genmodel(); +} + +void leveldown(void) { + level -= 1; + if (level <= 0) level = 1; + genmodel(); +} + +void help(void) { + printf("'h' - help\n"); + printf("'t' - tessellation style\n"); + printf("'UP' - increase tessellation\n"); + printf("'DOWN' - decrease tessellation\n"); + printf("left mouse - rotate sphere\n"); + printf("middle mouse - move light\n"); +} + +void init(void) { + GLfloat specular[4] = { 1., 1., 1., 1. }; + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + genmodel(); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30); +} + +void display(void) { + GLfloat position[] = { 0.0, 0.0, 3.5, 1.0 }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPushMatrix(); + glTranslatef(0.0, 0.0, -5.0); + + glPushMatrix(); + glRotatef(spin, 1.0, 0.0, 0.0); + glRotatef(0.0, 1.0, 0.0, 0.0); + glLightfv(GL_LIGHT0, GL_POSITION, position); + + glPopMatrix(); + + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glCallList(1); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); + glMatrixMode(GL_MODELVIEW); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 't': togglemodel(); break; + case 'w': togglewire(); break; + case 'h': help(); break; + case '\033': exit(0); + default: break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: levelup(); break; + case GLUT_KEY_DOWN: leveldown(); break; + } + glutPostRedisplay(); +} + +void +menu(int value) +{ + if(value<0) + special(-value,0,0); + else + key((unsigned char) value,0,0); +} + +int main(int argc, char** argv) { + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow("Quality of sphere tesselation"); + init(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle sphere model", 't'); + glutAddMenuEntry("Toggle solid/wireframe", 'w'); + glutAddMenuEntry("Increase tessellation", -GLUT_KEY_UP); + glutAddMenuEntry("Decrease tessellation", -GLUT_KEY_DOWN); + glutAddMenuEntry("Print help message", 'h'); + glutAddMenuEntry("Quit", '\033'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/tess.dsp b/lib/glut-3.7.6/progs/advanced/tess.dsp new file mode 100644 index 0000000000..1daf5a7044 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/tess.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="tess" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tess - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tess.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tess.mak" CFG="tess - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tess - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tess - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tess - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "tess - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "tess - Win32 Release" +# Name "tess - Win32 Debug" +# Begin Source File + +SOURCE=.\sphere.c +# End Source File +# Begin Source File + +SOURCE=.\tess.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/textext.c b/lib/glut-3.7.6/progs/advanced/textext.c new file mode 100644 index 0000000000..44f8f18f48 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textext.c @@ -0,0 +1,186 @@ + +/* textext.c - by David Blythe, SGI */ + +/* Example of using texturing for 3D transformable fonts. */ + +#include +#include +#include +#include +#include "texture.h" +#include "textmap.h" + +static float scale = .03; +static char *string = "OpenGL rules"; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) +{ + transx += (x - ox) / 500.; + transy -= (y - oy) / 500.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) +{ + rotx += x - ox; + if (rotx > 360.) + rotx -= 360.; + else if (rotx < -360.) + rotx += 360.; + roty += y - oy; + if (roty > 360.) + roty -= 360.; + else if (roty < -360.) + roty += 360.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + if (mot == PAN) + pan(x, y); + else if (mot == ROT) + rotate(x, y); +} + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void +up(void) +{ + scale += .0025; +} + +void +down(void) +{ + scale -= .0025; +} + +void +help(void) +{ + printf("Usage: textext [string]\n"); + printf("'h' - help\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void +init(void) +{ + texfntinit("Times-Italic.bw"); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90., 1., .1, 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0., 0., -1.5); +} + +void +display(void) +{ + float width = texstrwidth(string); + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(scale, scale, 0.); + glTranslatef(-width * 5, 0.f, 0.f); + texfntstroke(string, 0.f, 0.f); + glPopMatrix(); + glutSwapBuffers(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'h': + help(); + break; + case '\033': + exit(1); + break; + default: + break; + } +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_UP: + up(); + break; + case GLUT_KEY_DOWN: + down(); + break; + } + glutPostRedisplay(); +} + +int +main(int argc, char **argv) +{ + if (argc > 1) + string = argv[1]; + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + (void) glutCreateWindow("textext"); + init(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/textext.dsp b/lib/glut-3.7.6/progs/advanced/textext.dsp new file mode 100644 index 0000000000..ff40e187d7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textext.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="textext" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=textext - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "textext.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "textext.mak" CFG="textext - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "textext - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "textext - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "textext - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "textext - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "textext - Win32 Release" +# Name "textext - Win32 Debug" +# Begin Source File + +SOURCE=.\textext.c +# End Source File +# Begin Source File + +SOURCE=.\textmap.c +# End Source File +# Begin Source File + +SOURCE=.\textmap.h +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/textile.c b/lib/glut-3.7.6/progs/advanced/textile.c new file mode 100644 index 0000000000..272ebeff6e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textile.c @@ -0,0 +1,427 @@ + +/* textile.c - by David Blythe, SGI */ + +/* The idea behind texture tiling is that OpenGL's texture modes, + particularly its support for a texture border make it possible to "tile" + together small textures with a result identical to if a much larger + texture was supported. OpenGL allows implementations to limit the maximum + size of a texture image (often this limit reflects size limitations within + fast texturing hardware). Texture tiling lets you work around otherwise + limited texture image sizes. + + Try textile with tiling enabled and linear filtering enabled. As long as + you have texture borders enabled, you won't see any seams. If you disable + texture borders with linear filtering enabled, you'll get seams at the + boundaries of the tiles. The seams can be detected whether the texture + wrap mode is either clamped or wrapped. + + If you disable texture tiling in textile, textile acts as if your maximum + texture image size was 32x32 (no matter what your OpenGL implementation + really supports) to mimic how the image would look on a system with a very + limited texture image size. When the display window is large, the + textured rectangle should look very blurry at this limited texture image + size. -mjk */ + +#include +#include +#include +#include +#include +#include "texture.h" + +int maxTextureSize; +int maxTextureLevel; + +int imageWidth, imageHeight; +GLubyte *imageData; + +int texWidthLevel0, texHeightLevel0; +int texWidthTiles, texHeightTiles; +GLubyte **texImageLevel; + +GLboolean useBorder = GL_TRUE; +GLboolean useClamp = GL_TRUE; +GLboolean useLinear = GL_TRUE; +GLboolean useMipmap = GL_TRUE; +GLboolean useTextureTiling = GL_TRUE; + +/* (int)floor(log2(a)) */ +static int +iflog2(unsigned int a) +{ + int x = 0; + while (a >>= 1) + ++x; + return x; +} + +static void +initialize(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-0.5, 0.5, -0.5, 0.5, 0.5, 1.5); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -0.90); + glRotatef(45.0, 0, 1, 0); + glTranslatef(-0.5, -0.5, 0.0); + +#if 0 + /* A real program would query the real maximum supported texture size, but + program is an example. Even better would be to use OpenGL 1.1's texture + proxy mechanism. */ + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); +#else + /* Assume that the OpenGL implemenatation does not support anything larger + than 32x32 texture images. */ + maxTextureSize = 32; +#endif + maxTextureLevel = iflog2(maxTextureSize); + + texImageLevel = (GLubyte **) calloc(maxTextureLevel + 1, sizeof(GLubyte *)); + if (texImageLevel == NULL) { + fprintf(stderr, "texture level image allocation failed\n"); + exit(1); + } + glClearColor(0.1, 0.1, 0.1, 0.1); +} + +static void +imgLoad(char *filename_in, int *w_out, int *h_out, GLubyte ** img_out) +{ + int comp; + + *img_out = (GLubyte *) read_texture(filename_in, w_out, h_out, &comp); + if (*img_out == NULL) { + fprintf(stderr, "unable to read %s\n", filename_in); + exit(1); + } + if (comp != 3 && comp != 4) { + fprintf(stderr, "%s: image is not RGB or RGBA\n", filename_in); + exit(1); + } +} + +static void +buildMipmaps(void) +{ + int level, levelWidth, levelHeight; + + if (useTextureTiling) { + int width2 = iflog2(imageWidth); + int height2 = iflog2(imageHeight); + + width2 = (width2 > maxTextureLevel) ? width2 : maxTextureLevel; + height2 = (height2 > maxTextureLevel) ? height2 : maxTextureLevel; + + texWidthLevel0 = 1 << width2; + texHeightLevel0 = 1 << height2; + texWidthTiles = texWidthLevel0 >> maxTextureLevel; + texHeightTiles = texHeightLevel0 >> maxTextureLevel; + } else { + texWidthLevel0 = maxTextureSize; + texHeightLevel0 = maxTextureSize; + texWidthTiles = 1; + texHeightTiles = 1; + } + + texImageLevel[0] = (GLubyte *) + calloc(1, (texWidthLevel0 + 2) * (texHeightLevel0 + 2) * 4 * sizeof(GLubyte)); + + glPixelStorei(GL_PACK_ROW_LENGTH, texWidthLevel0 + 2); + glPixelStorei(GL_PACK_SKIP_PIXELS, 1); + glPixelStorei(GL_PACK_SKIP_ROWS, 1); + + gluScaleImage(GL_RGBA, imageWidth, imageHeight, + GL_UNSIGNED_BYTE, imageData, + texWidthLevel0, texHeightLevel0, + GL_UNSIGNED_BYTE, texImageLevel[0]); + + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 1); + + levelWidth = texWidthLevel0; + levelHeight = texHeightLevel0; + for (level = 0; level < maxTextureLevel; ++level) { + int newLevelWidth = (levelWidth > 1) ? levelWidth / 2 : 1; + int newLevelHeight = (levelHeight > 1) ? levelHeight / 2 : 1; + + texImageLevel[level + 1] = (GLubyte *) + calloc(1, (newLevelWidth + 2) * (newLevelHeight + 2) * 4 * sizeof(GLubyte)); + + glPixelStorei(GL_PACK_ROW_LENGTH, newLevelWidth + 2); + glPixelStorei(GL_UNPACK_ROW_LENGTH, levelWidth + 2); + + gluScaleImage(GL_RGBA, levelWidth, levelHeight, + GL_UNSIGNED_BYTE, texImageLevel[level], + newLevelWidth, newLevelHeight, + GL_UNSIGNED_BYTE, texImageLevel[level + 1]); + + levelWidth = newLevelWidth; + levelHeight = newLevelHeight; + } + + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); +} + +static void +freeMipmaps(void) +{ + int i; + + for (i = 0; i <= maxTextureLevel; ++i) { + if (texImageLevel[i] != NULL) { + free(texImageLevel[i]); + texImageLevel[i] = NULL; + } + } +} + +static void +loadTile(int row, int col) +{ + int border = useBorder ? 1 : 0; + int level, levelWidth, levelHeight; + + levelWidth = texWidthLevel0; + levelHeight = texHeightLevel0; + for (level = 0; level <= maxTextureLevel; ++level) { + int tileWidth = levelWidth / texWidthTiles; + int tileHeight = levelHeight / texHeightTiles; + int skipPixels = col * tileWidth + (1 - border); + int skipRows = row * tileHeight + (1 - border); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, levelWidth + 2); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skipPixels); + glPixelStorei(GL_UNPACK_SKIP_ROWS, skipRows); + + glTexImage2D(GL_TEXTURE_2D, level, 4, + tileWidth + 2 * border, tileHeight + 2 * border, + border, GL_RGBA, GL_UNSIGNED_BYTE, texImageLevel[level]); + + if (levelWidth > 1) + levelWidth = levelWidth / 2; + if (levelHeight > 1) + levelHeight = levelHeight / 2; + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); +} + +static void +redraw(void) +{ + GLenum minFilterMode, magFilterMode, wrapMode; + char *minFilterName, *magFilterName, *wrapName; + int i, j; + + if (useLinear) { + if (useMipmap) { + minFilterMode = GL_LINEAR_MIPMAP_LINEAR; + minFilterName = "LINEAR_MIPMAP_LINEAR"; + } else { + minFilterMode = GL_LINEAR; + minFilterName = "LINEAR"; + } + magFilterMode = GL_LINEAR; + magFilterName = "LINEAR"; + } else { + if (useMipmap) { + minFilterMode = GL_NEAREST_MIPMAP_LINEAR; + minFilterName = "NEAREST_MIPMAP_LINEAR"; + } else { + minFilterMode = GL_NEAREST; + minFilterName = "NEAREST"; + } + magFilterMode = GL_NEAREST; + magFilterName = "NEAREST"; + } + + if (useClamp) { + wrapMode = GL_CLAMP; + wrapName = "CLAMP"; + } else { + wrapMode = GL_REPEAT; + wrapName = "REPEAT"; + } + + fprintf(stderr, "tile(%s) ", useTextureTiling ? "yes" : "no"); + fprintf(stderr, "border(%s) ", useBorder ? "yes" : "no"); + fprintf(stderr, "filter(%s, %s) ", minFilterName, magFilterName); + fprintf(stderr, "wrap(%s) ", wrapName); + fprintf(stderr, "\n"); + + glClear(GL_COLOR_BUFFER_BIT); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilterMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilterMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + + buildMipmaps(); + + glEnable(GL_TEXTURE_2D); + + for (i = 0; i < texHeightTiles; ++i) { + float ySize = 1.0 / texHeightTiles; + float y0 = i * ySize; + float y1 = y0 + ySize; + + for (j = 0; j < texWidthTiles; ++j) { + float xSize = 1.0 / texWidthTiles; + float x0 = j * xSize; + float x1 = x0 + xSize; + + loadTile(i, j); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.0, 1.0); + glVertex2f(x0, y1); + glTexCoord2f(0.0, 0.0); + glVertex2f(x0, y0); + glTexCoord2f(1.0, 1.0); + glVertex2f(x1, y1); + glTexCoord2f(1.0, 0.0); + glVertex2f(x1, y0); + glEnd(); + } + } + + glDisable(GL_TEXTURE_2D); + + freeMipmaps(); +} + +static void +usage(char *name) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "usage: %s [ options ] filename\n", name); + fprintf(stderr, "\n"); + fprintf(stderr, " Demonstrates using texture borders\n"); + fprintf(stderr, " to tile a large texture\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " Options:\n"); + fprintf(stderr, " -sb single buffered\n"); + fprintf(stderr, " -db double buffered\n"); + fprintf(stderr, "\n"); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + break; + case 'b': + useBorder = !useBorder; + break; + case 'w': + useClamp = !useClamp; + break; + case 'l': + useLinear = !useLinear; + break; + case 'm': + useMipmap = !useMipmap; + break; + case 't': + useTextureTiling = !useTextureTiling; + break; + default: + return; + } + glutPostRedisplay(); +} + +void +menu(int value) +{ + key((unsigned char) value, 0, 0); +} + +int doubleBuffered = GL_FALSE; + +void +display(void) +{ + GLenum error; + redraw(); + if (doubleBuffered) + glutSwapBuffers(); + else + glFlush(); + while ((error = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); + } +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); +} + +int +main(int argc, char *argv[]) +{ + char *name = "Texture Tiling Test"; + int width = 300, height = 300; + char *filename = NULL; + int i; + + for (i = 1; i < argc; ++i) { + if (!strcmp("-sb", argv[i])) { + doubleBuffered = GL_FALSE; + + } else if (!strcmp("-db", argv[i])) { + doubleBuffered = GL_TRUE; + + } else if (argv[i][0] != '-' && i == argc - 1) { + filename = argv[i]; + + } else { + usage(argv[0]); + exit(1); + } + } + + if (filename == NULL) { + usage(argv[0]); + exit(1); + } + imgLoad(filename, &imageWidth, &imageHeight, &imageData); + + glutInitWindowSize(width, height); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | (doubleBuffered ? GLUT_DOUBLE : 0)); + glutCreateWindow(name); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + initialize(); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle texture tiling", 't'); + glutAddMenuEntry("Toggle clamping", 'w'); + glutAddMenuEntry("Toggle linear filtering", 'l'); + glutAddMenuEntry("Toggle mipmap usage", 'm'); + glutAddMenuEntry("Toggle texture border", 'b'); + glutAddMenuEntry("Quit", '\033'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/textile.dsp b/lib/glut-3.7.6/progs/advanced/textile.dsp new file mode 100644 index 0000000000..c00ee3e91f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textile.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="textile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=textile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "textile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "textile.mak" CFG="textile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "textile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "textile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "textile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "textile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "textile - Win32 Release" +# Name "textile - Win32 Debug" +# Begin Source File + +SOURCE=.\textile.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/textmap.c b/lib/glut-3.7.6/progs/advanced/textmap.c new file mode 100644 index 0000000000..2e2fd59481 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textmap.c @@ -0,0 +1,328 @@ + +/* textmap.c - by David Blythe, SGI */ + +/* Helper routines used by textext.c for texture mapped fonts. */ + +#include +#include +#include +#include "textmap.h" +#include "texture.h" + +/* byte swap a 32-bit value */ +#define SWAPL(x, n) { \ + n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[3];\ + ((char *) (x))[3] = n;\ + n = ((char *) (x))[1];\ + ((char *) (x))[1] = ((char *) (x))[2];\ + ((char *) (x))[2] = n; } + +/* byte swap a short */ +#define SWAPS(x, n) { \ + n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[1];\ + ((char *) (x))[1] = n; } + +static texfnt *curtfnt; +static unsigned char *fb; +static unsigned char *gptr; + +/* get metric data into image */ +static void +initget(void) +{ + gptr = fb; +} + +static void +getbytes(void *pbuf, int n) +{ + char *buf = pbuf; + while (n--) { + *buf++ = *gptr++; + } +} + +static void +fixrow(unsigned short *sptr, int n) +{ + while (n--) { + /* *sptr = *sptr + (0xff<<8); */ + /* *sptr = (*sptr<<8) | 0xff; */ + sptr++; + } +} + +int +doSwap(void) +{ + int i = 0xffff0000; + char *cptr = (char*) &i; + + if (cptr[0] == 0) { + return 1; /* little endian (x86, alpha) */ + } else { + return 0; /* big endian (SGI, 68000, VAX, SPARC) */ + } +} + +texfnt * +readtexfont(char *name) +{ + texfnt *tfnt; + unsigned *image; + unsigned char *cptr; + unsigned short *sbuf, *sptr; + short advancecell, xadvance; + short llx, lly, urx, ury, ox, oy; + int i, y, extralines; + texchardesc *cd; + int xsize, ysize, components; + int swap = doSwap(); + int tmp; + + tfnt = (texfnt *) malloc(sizeof(texfnt)); + image = read_texture(name, &xsize, &ysize, &components); + if (!image) { + fprintf(stderr, "textmap: can't open font image %s\n", name); + return 0; + } + extralines = ysize - xsize; + if (extralines < 1) { + fprintf(stderr, "textmap: bad input font!!\n"); + return 0; + } + fb = (unsigned char *) malloc(xsize * extralines); + sbuf = (unsigned short *) malloc(xsize * sizeof(short)); + cptr = fb; + for (y = xsize; y < ysize; y++) { + int x; + for (x = 0; x < xsize; x++) + cptr[x] = image[y * xsize + x] >> 16; + cptr += xsize; + } + initget(); + tfnt->rasxsize = xsize; + tfnt->rasysize = xsize; + getbytes(&tfnt->charmin, sizeof(short)); + getbytes(&tfnt->charmax, sizeof(short)); + getbytes(&tfnt->pixhigh, sizeof(float)); + getbytes(&advancecell, sizeof(short)); + if (swap) { + SWAPS(&tfnt->charmin, tmp); + SWAPS(&tfnt->charmax, tmp); + SWAPL(&tfnt->pixhigh, tmp); + SWAPS(&advancecell, tmp); + } + tfnt->nchars = tfnt->charmax - tfnt->charmin + 1; + tfnt->chars = (texchardesc *) malloc(tfnt->nchars * sizeof(texchardesc)); + tfnt->rasdata = (unsigned short *) malloc(tfnt->rasxsize * tfnt->rasysize * sizeof(long)); + sptr = tfnt->rasdata; + for (y = 0; y < tfnt->rasysize; y++) { + int x; + for (x = 0; x < xsize; x++) + sptr[x] = image[y * xsize + x] >> 16; + fixrow(sptr, tfnt->rasxsize); + sptr += tfnt->rasxsize; + } + + cd = tfnt->chars; + for (i = 0; i < tfnt->nchars; i++) { + getbytes(&xadvance, sizeof(short)); + getbytes(&llx, sizeof(short)); + getbytes(&lly, sizeof(short)); + getbytes(&urx, sizeof(short)); + getbytes(&ury, sizeof(short)); + getbytes(&ox, sizeof(short)); + getbytes(&oy, sizeof(short)); + if (swap) { + SWAPS(&xadvance, tmp); + SWAPS(&llx, tmp); + SWAPS(&lly, tmp); + SWAPS(&urx, tmp); + SWAPS(&ury, tmp); + SWAPS(&ox, tmp); + SWAPS(&oy, tmp); + } + cd->movex = xadvance / (float) advancecell; + + if (llx >= 0) { + cd->haveimage = 1; + cd->llx = (llx - ox) / tfnt->pixhigh; + cd->lly = (lly - oy) / tfnt->pixhigh; + cd->urx = (urx - ox + 1) / tfnt->pixhigh; + cd->ury = (ury - oy + 1) / tfnt->pixhigh; + cd->tllx = llx / (float) tfnt->rasxsize; + cd->tlly = lly / (float) tfnt->rasysize; + cd->turx = (urx + 1) / (float) tfnt->rasxsize; + cd->tury = (ury + 1) / (float) tfnt->rasysize; + cd->data[0] = cd->tllx; + cd->data[1] = cd->tlly; + + cd->data[2] = cd->llx; + cd->data[3] = cd->lly; + + cd->data[4] = cd->turx; + cd->data[5] = cd->tlly; + + cd->data[6] = cd->urx; + cd->data[7] = cd->lly; + + cd->data[8] = cd->turx; + cd->data[9] = cd->tury; + + cd->data[10] = cd->urx; + cd->data[11] = cd->ury; + + cd->data[12] = cd->tllx; + cd->data[13] = cd->tury; + + cd->data[14] = cd->llx; + cd->data[15] = cd->ury; + + cd->data[16] = cd->llx; + cd->data[17] = cd->lly; + cd->data[18] = cd->urx; + cd->data[19] = cd->lly; + + cd->data[20] = cd->urx; + cd->data[21] = cd->ury; + cd->data[22] = cd->llx; + cd->data[23] = cd->ury; + + } else { + cd->haveimage = 0; + } + cd++; + } + free(fb); + free(sbuf); + free(image); + return tfnt; +} + +void +texfont(texfnt * tfnt) +{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 2, tfnt->rasxsize, tfnt->rasysize, 0, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tfnt->rasdata); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + curtfnt = tfnt; +} + +float +texstrwidth(char *str) +{ + unsigned int c; + unsigned int charmin, tnchars; + texfnt *tfnt; + texchardesc *cdbase, *cd; + float xpos; + + tfnt = curtfnt; + if (!tfnt) { + fprintf(stderr, "texstrwidth: no texfont set!!\n"); + return 0; + } + charmin = tfnt->charmin; + tnchars = tfnt->nchars; + cdbase = tfnt->chars; + xpos = 0.0; + while (*str) { + c = *str - charmin; + if (c < tnchars) { + cd = cdbase + c; + xpos += cd->movex; + } + str++; + } + return xpos; +} + +void +texcharstr(char *str) +{ + unsigned int c; + unsigned int charmin, tnchars; + texfnt *tfnt; + texchardesc *cdbase, *cd; + float *fdata, xpos; + + tfnt = curtfnt; + if (!tfnt) { + fprintf(stderr, "texcharstr: no texfont set!!\n"); + return; + } + charmin = tfnt->charmin; + tnchars = tfnt->nchars; + cdbase = tfnt->chars; + xpos = 0.0; +#if 0 + texbind(TX_TEXTURE_0, LETTER_INDEX); /* bind letter texture */ + tevbind(TV_ENV0, LETTER_INDEX); +#endif + while (*str) { + c = *str - charmin; + if (c < tnchars) { + cd = cdbase + c; + if (cd->haveimage) { + fdata = cd->data; + fdata[16] = fdata[2] + xpos; + fdata[18] = fdata[6] + xpos; + fdata[20] = fdata[10] + xpos; + fdata[22] = fdata[14] + xpos; + glBegin(GL_POLYGON); + glTexCoord2fv(&fdata[0]); + glVertex2fv(&fdata[16]); + glTexCoord2fv(&fdata[4]); + glVertex2fv(&fdata[18]); + glTexCoord2fv(&fdata[8]); + glVertex2fv(&fdata[20]); + glTexCoord2fv(&fdata[12]); + glVertex2fv(&fdata[22]); + glEnd(); + } + xpos += cd->movex; + } + str++; + } +} + +int +texfntinit(char *file) +{ + static int once = 0; + static texfnt *tfnt; + if (!once) { + tfnt = readtexfont(file); + if (!tfnt) { + fprintf(stderr, "texfntinit: can't open input font %s\n", file); + return -1; + } + texfont(tfnt); + once = 1; + } + return 0; +} + +float +texfntwidth(char *str) +{ + return texstrwidth(str) * 12.5 / 6.; +} + +void +texfntstroke(char *s, float xoffset, float yoffset) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPushMatrix(); + glTranslatef(xoffset, yoffset, 0.0); + glScalef(12.5, 12.5, 12.5); + texcharstr(s); + glPopMatrix(); + glDisable(GL_BLEND); +} diff --git a/lib/glut-3.7.6/progs/advanced/textmap.h b/lib/glut-3.7.6/progs/advanced/textmap.h new file mode 100644 index 0000000000..8e9c0055e4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textmap.h @@ -0,0 +1,30 @@ +#ifndef TEXTMAPDEF +#define TEXTMAPDEF + +#define LETTER_INDEX 1 + +typedef struct texchardesc { + float movex; /* advance */ + int haveimage; + float llx, lly; /* geometry box */ + float urx, ury; + float tllx, tlly; /* texture box */ + float turx, tury; + float data[3 * 8]; +} texchardesc; + +typedef struct texfnt { + short charmin, charmax; + short nchars; + float pixhigh; + texchardesc *chars; + short rasxsize, rasysize; + unsigned short *rasdata; +} texfnt; + +texfnt *readtexfont(char *name); +float texstrwidth(char *str); +int texfntinit(char *file); +void texfntstroke(char *s, float xoffset, float yoffset); + +#endif diff --git a/lib/glut-3.7.6/progs/advanced/textrim.c b/lib/glut-3.7.6/progs/advanced/textrim.c new file mode 100644 index 0000000000..10cc3b8359 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textrim.c @@ -0,0 +1,285 @@ + +/* textrim.c - by David Blythe, SGI */ + +/* Trimming textures: demonstrates how alpha blending or alpha testing + can be used to "trim" the shape of textures to arbitrary shapes. + Alpha testing is generally cheaper than alpha blending, but + blending permits antialiased edges. */ + +/* Try: "textrim tree.rgb" where tree.rgb is a SGI .rgb file including + an alpha component. */ + +#include +#include +#include +#include +#include "texture.h" + +static float scale = 1.4; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) +{ + transx += (x - ox) / 500.; + transy -= (y - oy) / 500.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) +{ + rotx += x - ox; + if (rotx > 360.) + rotx -= 360.; + else if (rotx < -360.) + rotx += 360.; + roty += y - oy; + if (roty > 360.) + roty -= 360.; + else if (roty < -360.) + roty += 360.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + if (mot == PAN) + pan(x, y); + else if (mot == ROT) + rotate(x, y); +} + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void +afunc(void) +{ + static int state; + if (state ^= 1) { + glAlphaFunc(GL_GREATER, .01); + glEnable(GL_ALPHA_TEST); + } else { + glDisable(GL_ALPHA_TEST); + } +} + +void +bfunc(void) +{ + static int state; + if (state ^= 1) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } else { + glDisable(GL_BLEND); + } +} + +void +up(void) +{ + scale += .1; +} + +void +down(void) +{ + scale -= .1; +} + +void +help(void) +{ + printf("Usage: textrim [image]\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void +init(char *filename) +{ + static unsigned *image; + static int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(1); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 4) { + printf("must be an RGBA image\n"); + exit(1); + } + } else { + int i, j; + unsigned char *img; + components = 4; + width = height = 512; + image = (unsigned *) malloc(width * height * sizeof(unsigned)); + img = (unsigned char *) image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width / 2, h2 = height / 2; + if (i & 32) + img[4 * (i + j * width) + 0] = 0xff; + else + img[4 * (i + j * width) + 1] = 0xff; + if (j & 32) + img[4 * (i + j * width) + 2] = 0xff; + if ((i - w2) * (i - w2) + (j - h2) * (j - h2) > 64 * 64 && + (i - w2) * (i - w2) + (j - h2) * (j - h2) < 300 * 300) + img[4 * (i + j * width) + 3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50., 1., .1, 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0., 0., -5.5); + glClearColor(.25f, .25f, .25f, .25f); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(scale, scale, 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(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'A': + case 'a': + afunc(); + break; + case 'B': + case 'b': + bfunc(); + break; + case 'H': + case 'h': + help(); + break; + case '\033': + exit(0); + break; + default: + break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_UP: + up(); + break; + case GLUT_KEY_DOWN: + down(); + break; + default: + return; + } + glutPostRedisplay(); +} + +void +menu(int value) +{ + key((unsigned char) value, 0, 0); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + (void) glutCreateWindow("textrim"); + init(argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle alpha testing", 'a'); + glutAddMenuEntry("Toggle alpha blending", 'b'); + glutAddMenuEntry("Quit", '\033'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/textrim.dsp b/lib/glut-3.7.6/progs/advanced/textrim.dsp new file mode 100644 index 0000000000..335b3b354f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/textrim.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="textrim" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=textrim - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "textrim.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "textrim.mak" CFG="textrim - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "textrim - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "textrim - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "textrim - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "textrim - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "textrim - Win32 Release" +# Name "textrim - Win32 Debug" +# Begin Source File + +SOURCE=.\textrim.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/texture.c b/lib/glut-3.7.6/progs/advanced/texture.c new file mode 100644 index 0000000000..c53763507f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/texture.c @@ -0,0 +1,245 @@ + +/* texture.c - by David Blythe, SGI */ + +/* read_texture is a simplistic routine for reading an SGI .rgb image file. */ + +#include +#include +#include + +void +bwtorgba(unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = 0xff; + l += 4; b++; + } +} + +void +rgbtorgba(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] = 0xff; + l += 4; r++; g++; b++; + } +} + +void +rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l[3] = a[0]; + l += 4; r++; g++; b++; a++; + } +} + +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, *tmpR, *tmpG, *tmpB; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +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) { + perror(fileName); + exit(1); + } + + fread(image, 1, 12, image->file); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + image->tmp = (unsigned char *)malloc(image->xsize*256); + image->tmpR = (unsigned char *)malloc(image->xsize*256); + image->tmpG = (unsigned char *)malloc(image->xsize*256); + image->tmpB = (unsigned char *)malloc(image->xsize*256); + if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL || + image->tmpB == NULL) { + fprintf(stderr, "Out 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, "Out 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->tmpR); + free(image->tmpG); + free(image->tmpB); + 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); + } +} + +unsigned * +read_texture(char *name, int *width, int *height, int *components) { + unsigned *base, *lptr; + unsigned char *rbuf, *gbuf, *bbuf, *abuf; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if(!image) + return NULL; + (*width)=image->xsize; + (*height)=image->ysize; + (*components)=image->zsize; + base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned)); + 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) + return NULL; + lptr = 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); + rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==3) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else { + ImageGetRow(image,rbuf,y,0); + bwtorgba(rbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } + } + ImageClose(image); + free(rbuf); + free(gbuf); + free(bbuf); + free(abuf); + + return (unsigned *) base; +} diff --git a/lib/glut-3.7.6/progs/advanced/texture.h b/lib/glut-3.7.6/progs/advanced/texture.h new file mode 100644 index 0000000000..c1e720c881 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/texture.h @@ -0,0 +1,7 @@ + +/* texture.h - by David Blythe, SGI */ + +/* Simple SGI .rgb image file loader routine. */ + +unsigned * +read_texture(char *name, int *width, int *height, int *components); diff --git a/lib/glut-3.7.6/progs/advanced/texwinalign.c b/lib/glut-3.7.6/progs/advanced/texwinalign.c new file mode 100644 index 0000000000..18452c92e5 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/texwinalign.c @@ -0,0 +1,354 @@ + +/* Copyright (c) Mark J. Kilgard, 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 program demonstrates how to use the texture matrix + and texture coordinate generation (texgen) to generate + window space texture coordinates for arbitrary 3D geometry. + The basic technique is to generate texture coordinates + directly matching the object coordinates and using the + texture matrix to mimic the viewport, projection, and + modelview transformations to convert the texture coordinates + into window coordinates identically to how the actual + object coordinates are transformed into window space. It + is important to have perspective correct texturing if you + want perspective projections to look right. */ + +#include +#include + +GLfloat lightDiffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */ +GLfloat lightPosition[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ + +GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */ + {-1.0, 0.0, 0.0}, {0.0, 1.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, -1.0} }; +GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */ + {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4}, + {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} }; +GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */ + +GLfloat angle = -20.0; +int animating = 1; + +#define TEX_WIDTH 16 +#define TEX_HEIGHT 16 + +/* Nice circle texture tiling pattern. */ +static char *circles[] = { + "....xxxx........", + "..xxxxxxxx......", + ".xxxxxxxxxx.....", + ".xxx....xxx.....", + "xxx......xxx....", + "xxx......xxx....", + "xxx......xxx....", + "xxx......xxx....", + ".xxx....xxx.....", + ".xxxxxxxxxx.....", + "..xxxxxxxx......", + "....xxxx........", + "................", + "................", + "................", + "................", +}; + +/* Nice grid texture tiling pattern. */ +static char *grid[] = { + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "..............xx", + "xxxxxxxxxxxxxxxx", + "xxxxxxxxxxxxxxxx", +}; + +static void +makeTexture(char *pattern[]) +{ + GLubyte floorTexture[TEX_WIDTH][TEX_HEIGHT][3]; + GLubyte *loc; + int s, t; + + /* Setup RGB image for the texture. */ + loc = (GLubyte*) floorTexture; + for (t = 0; t < TEX_HEIGHT; t++) { + for (s = 0; s < TEX_WIDTH; s++) { + if (pattern[t][s] == 'x') { + /* Nice green. */ + loc[0] = 0x6f; + loc[1] = 0x8f; + loc[2] = 0x1f; + } else { + /* Light gray. */ + loc[0] = 0xaa; + loc[1] = 0xaa; + loc[2] = 0xaa; + } + loc += 3; + } + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_WIDTH, TEX_HEIGHT, 0, + GL_RGB, GL_UNSIGNED_BYTE, floorTexture); +} + +void +drawBox(void) +{ + int i; + + for (i = 0; i < 6; i++) { + glBegin(GL_QUADS); + glNormal3fv(&n[i][0]); + glVertex3fv(&v[faces[i][0]][0]); + glVertex3fv(&v[faces[i][1]][0]); + glVertex3fv(&v[faces[i][2]][0]); + glVertex3fv(&v[faces[i][3]][0]); + glEnd(); + } +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPushMatrix(); + glRotatef(angle, 0.0, 0.0, 1.0); + drawBox(); + glPopMatrix(); + glutSwapBuffers(); +} + +int windowWidth; +int windowHeight; +int slideX = 0, slideY = 0; + +void +configTextureMatrix(void) +{ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + /* Shift texture in pixel units (slideX,slideY). You could use this + to copensate for a viewport origin different from the window + origin. */ + glTranslatef(slideX/(GLfloat)TEX_WIDTH, + slideY/(GLfloat)TEX_HEIGHT, + 0.0); + /* Scale based on the window size in pixel. */ + glScalef(windowWidth/(GLfloat)TEX_WIDTH, + windowHeight/(GLfloat)TEX_HEIGHT, + 1.0); + /* Mimic the scene's projection matrix setup. */ + gluPerspective( /* field of view in degree */ 40.0, + /* aspect ratio */ 1.0, + /* Z near */ 1.0, /* Z far */ 10.0); + /* Mimic the scene's view matrix setup. */ + gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ + 0.0, 0.0, 0.0, /* center is at (0,0,0) */ + 0.0, 1.0, 0.); /* up is in positive Y direction */ + /* Mimic the scene's model matrix setup. */ + /* Adjust cube position to be aesthetic angle. */ + glTranslatef(0.0, 0.0, -1.0); + glRotatef(60, 1.0, 0.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + /* Switch back to the modelview matrix. */ + glMatrixMode(GL_MODELVIEW); + +} + +void +idle(void) +{ + /* Slowly rotate object. */ + angle += 0.5; + if (angle > 360.0) { + angle -= 360.0; + } + /* Make sure the texture matrix mimics the changing + modelview matrix. */ + configTextureMatrix(); + glutPostRedisplay(); +} + +void +keyboard(unsigned char c, int x, int y) +{ + switch(c) { + case 27: /* Escape */ + exit(0); + break; + case 'h': + slideX--; + break; + case 'j': + slideY--; + break; + case 'k': + slideY++; + break; + case 'l': + slideX++; + break; + case 'r': + angle += 10; + break; + case 'a': + animating = !animating; + if (animating) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } + break; + } + configTextureMatrix(); + glutPostRedisplay(); +} + +void +reshape(int width, int height) +{ + windowWidth = width; + windowHeight = height; + glViewport(0, 0, width, height); + configTextureMatrix(); +} + +void +init(void) +{ + static GLfloat sPlane[4] = { 1.0, 0.0, 0.0, 0.0 }; + static GLfloat tPlane[4] = { 0.0, 1.0, 0.0, 0.0 }; + static GLfloat rPlane[4] = { 0.0, 0.0, 1.0, 0.0 }; + static GLfloat qPlane[4] = { 0.0, 0.0, 0.0, 1.0 }; + + /* Setup cube vertex data. */ + v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; + v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; + v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; + v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; + v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; + v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; + + /* Use depth buffering for hidden surface elimination. */ + glEnable(GL_DEPTH_TEST); + + /* Enable a single OpenGL light. */ + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHT0); + + /* Setup the view of the cube. */ + glMatrixMode(GL_PROJECTION); + gluPerspective( /* field of view in degree */ 40.0, + /* aspect ratio */ 1.0, + /* Z near */ 1.0, /* Z far */ 10.0); + glMatrixMode(GL_MODELVIEW); + gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ + 0.0, 0.0, 0.0, /* center is at (0,0,0) */ + 0.0, 1.0, 0.); /* up is in positive Y direction */ + + /* Texgen that maps object coordinates directly to texture + coordinates. */ + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane); + glTexGenfv(GL_R, GL_OBJECT_PLANE, rPlane); + glTexGenfv(GL_Q, GL_OBJECT_PLANE, qPlane); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_GEN_Q); + + /* Enable texturing. Perspective correct texturing is + important to this demo! */ + glEnable(GL_TEXTURE_2D); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + /* Adjust cube position to be aesthetic orientation. */ + glTranslatef(0.0, 0.0, -1.0); + glRotatef(60, 1.0, 0.0, 0.0); +} + +void +menu(int selection) +{ + switch (selection) { + case 1: + glEnable(GL_LIGHTING); + glutPostRedisplay(); + break; + case 2: + glDisable(GL_LIGHTING); + glutPostRedisplay(); + break; + case 3: + keyboard('a', 0, 0); + break; + case 4: + makeTexture(circles); + break; + case 5: + makeTexture(grid); + break; + case 666: + exit(0); + } +} + +void +visibility(int state) +{ + if (state == GLUT_VISIBLE) { + if (animating) { + glutIdleFunc(idle); + } + } else { + glutIdleFunc(NULL); + } +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow("window space aligned textures"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutVisibilityFunc(visibility); + init(); + makeTexture(grid); + glutCreateMenu(menu); + glutAddMenuEntry("Enable lighting", 1); + glutAddMenuEntry("Disable lighting", 2); + glutAddMenuEntry("Animating", 3); + glutAddMenuEntry("Circles", 4); + glutAddMenuEntry("Grid", 5); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/texwinalign.dsp b/lib/glut-3.7.6/progs/advanced/texwinalign.dsp new file mode 100644 index 0000000000..894fb24e80 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/texwinalign.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="texwinalign" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=texwinalign - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "texwinalign.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texwinalign.mak" CFG="texwinalign - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texwinalign - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "texwinalign - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texwinalign - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "texwinalign - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "texwinalign - Win32 Release" +# Name "texwinalign - Win32 Debug" +# Begin Source File + +SOURCE=.\texwinalign.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/tvertex.c b/lib/glut-3.7.6/progs/advanced/tvertex.c new file mode 100644 index 0000000000..9211fd37ec --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/tvertex.c @@ -0,0 +1,281 @@ + +/* tvertex.c - by David Blythe (with help from Mark Kilgard), SGI */ + +/* T-vertex artifacts example. The moral: Avoid vertex edge junctions that + make a T-shape. */ + +#include +#include +#include +#include + +static float scale = 1.; +static float transx = 0, transy = 0; +static float rotx = 29, roty = -21; /* Initially askew. */ +static int ox = -1, oy = -1; +static int show_t = 1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) +{ + transx += (x - ox) / 500.; + transy -= (y - oy) / 500.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) +{ + rotx += x - ox; + if (rotx > 360.) + rotx -= 360.; + else if (rotx < -360.) + rotx += 360.; + roty += y - oy; + if (roty > 360.) + roty -= 360.; + else if (roty < -360.) + roty += 360.; + ox = x; + oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + if (mot == PAN) + pan(x, y); + else if (mot == ROT) + rotate(x, y); +} + +void +mouse(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN) { + switch (button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void +toggle_t(void) +{ + show_t ^= 1; +} + +void +wire(void) +{ + static int w; + + if (w ^= 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void +light(void) +{ + static int l = 1; + + if (l ^= 1) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); +} + +void +up(void) +{ + scale += .1; +} + +void +down(void) +{ + scale -= .1; +} + +void +help(void) +{ + printf("Usage: tvertex\n"); + printf("'h' - help\n"); + printf("'l' - toggle lighting\n"); + printf("'t' - toggle T vertex\n"); + printf("'w' - toggle wireframe\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void +init(void) +{ + GLfloat pos[4] = + {0.0, 0.0, 1.0, 1.0}; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50., 1., .1, 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0., 0., -3.5); + + /* The default light is "infinite"; a local light is important to ensure + varying lighting color calculations at the vertices. */ + glLightfv(GL_LIGHT0, GL_POSITION, pos); + + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(scale, scale, 1.); + if (show_t) { + glBegin(GL_QUADS); + glVertex2f(-1., 0.); + glVertex2f(0., 0.); + glVertex2f(0., 1.); + glVertex2f(-1., 1.); + + glVertex2f(0., 0.); + glVertex2f(1., 0.); + glVertex2f(1., 1.); + glVertex2f(0., 1.); + + glVertex2f(-1., -1.); + glVertex2f(1., -1.); + glVertex2f(1., 0.); + glVertex2f(-1., 0.); + glEnd(); + } else { + glBegin(GL_QUADS); + glVertex2f(-1., 0.); + glVertex2f(0., 0.); + glVertex2f(0., 1.); + glVertex2f(-1., 1.); + + glVertex2f(0., 0.); + glVertex2f(1., 0.); + glVertex2f(1., 1.); + glVertex2f(0., 1.); + + glVertex2f(-1., -1.); + glVertex2f(0., -1.); + glVertex2f(0., 0.); + glVertex2f(-1., 0.); + + glVertex2f(0., -1.); + glVertex2f(1., -1.); + glVertex2f(1., 0.); + glVertex2f(0., 0.); + glEnd(); + } + glPopMatrix(); + glutSwapBuffers(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 'l': + light(); + break; + case 't': + toggle_t(); + break; + case 'w': + wire(); + break; + case 'h': + help(); + break; + case '\033': + exit(0); + break; + default: + return; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_UP: + up(); + break; + case GLUT_KEY_DOWN: + down(); + break; + default: + return; + } + glutPostRedisplay(); +} + +void +menu(int value) +{ + key((unsigned char) value, 0, 0); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + (void) glutCreateWindow("T vertex artifact demo"); + init(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle T vertex", 't'); + glutAddMenuEntry("Toggle wireframe/solid", 'w'); + glutAddMenuEntry("Toggle lighting", 'l'); + glutAddMenuEntry("Quit", '\033'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/tvertex.dsp b/lib/glut-3.7.6/progs/advanced/tvertex.dsp new file mode 100644 index 0000000000..4086336a8d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/tvertex.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="tvertex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tvertex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tvertex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tvertex.mak" CFG="tvertex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tvertex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tvertex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tvertex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "tvertex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "tvertex - Win32 Release" +# Name "tvertex - Win32 Debug" +# Begin Source File + +SOURCE=.\tvertex.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/videoresize.c b/lib/glut-3.7.6/progs/advanced/videoresize.c new file mode 100644 index 0000000000..b78b1e4c9c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/videoresize.c @@ -0,0 +1,617 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* 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 demo shows off InfiniteReality's "dynamic video resize" (DVR) + capability. Dynamic video resizing let's you maintain a constant frame + rate even when the view becomes limited by your hardware's pixel fill + rate. The idea is simple: Draw the fill-limited frame into a smaller + area (ie, touch less pixels) and then have the video hardware "zoom" up + the image to fill the video screen. This trick does require special + hardware. + + As written with no command line options, this demo works well on a 1RM + InfiniteReality. It keeps a scene containing colored large orbs that + rotate around the viewer at a constant 60 frames/sec, even though the + number of viewable orbs is changing (hence the required fullscreen pixel + fill rate is changing too). The demo adapts the rendered image size and + video resizing based on the last frame to keep a constant frame rate. */ + +/**************************************************************** + +Command line arguments: + + -window ... run in a window instead of full screen and will not use + hardware resizing even if the hardware supports it. Good for + demos. + + -novidresize ... start without using video resize hardware even though + the system might really support video resizing. + + -debug ... output frame size to stdout. + + -target # ... sets the target frame rate in increments of 60th of + a second; the default is 1. + + -twosnaps ... sample the last frame rate as the average of the last + two frames; the default is to simply use the last frame. + + -nice ... better tesselate the orbs; nice if you have transformation + rate to burn (ie, use an InfiniteReality). + + -orbs # ... an initial number of orbs to populate the viewing space; + the default is 80. + +Example command lines: + + Because this program's behavior depends on adapting to the speed of the + system it is running at, a good demonstration of this program may depend + on the system performance. Adjust the command line options accordingly, + particularly -target and -orbs. + + InfiniteReality (1RM) ... "videoresize" + + (For the hardware listed below, you won't get actual video resizing + since the hardware lacks the support.) + + Indigo^2 XL 200Mhz ... "videoresize -geometry 800x600 -target 5 -orbs 40 -window" + +Key controls: + + ESC or q ... exit the demo. + + n ... disable dynamic video resizing. + + r ... enable dynamic video resizing (the default if hardware video + resizing is detected; otherwise no video resizing is the + default). + + NOTE: you can enable dynamic video resizing even without the + hardware and the demo will show you how the rendered area would + vary as if the feature were supported. + + h ... toggle use of hardware video resizing (only if in fullscreen + mode and the hardware supports the feature). + + m ... toggle display of the frame meter. Enabled by default. + + c ... toggle display of the cursor. Sometimes it is nice to see the + cursor when video resizing so that you can see the effect of the + video resizing since the cursor resizes too, but in general a + resizing cursor is quite distracting. The cursor is enabled if + hardware video resizing is to be used. + + Up arrow ... add 10 more orbs. + + Down arrow ... subtract 10 less orbs. + + Spacebar ... regenerate the set of viewing orbs. + + Right arrow ... increase rightward rotation. + + Left arrow ... increase rightward rotation. + +Frame meter: + + The frame meter shows how long each frame takes to render. It + operates differently depending on if video resizing is being + demonstrated or not. + + The meter line is BLUE when video resizing is not being demonstrated. + + When video resizing is being demonstrated, a GREEN meter line + indicates the frame is being shown at full (non-resized) resolution. + YELLOW indicates the frame is being video resized. RED indicates the + frame is being resized so much that dropping a frame is better than + the resulting poor resize quality (the demo won't zoom anymore than 8 + to 1). A smaller MAGENTA line shows a calculation of the + "unadjusted" frame rate for the displayed scene. When the MAGENTA + line is longer than the base line, it is showing a relative measure + of how much resizing was needed to keep the frame at a sustained + frame rate. + +Bugs: + + This program assumes a frame rate of 60 Hz. + + This program should use InfiniteReality's SGIX_instruments + extension for better fill rate measurement. + +*****************************************************************/ + +#include +#include +#include +#include +#include +#if !defined(_WIN32) +#include +#else +#define lrand48() (0) +#define srand48(x) (0) +#define getpid() (0) +#endif + +#define OVERLOAD 0 +#define ZOOMED 1 +#define UNZOOMED 2 +#define STATIC 3 +GLfloat state_colors[4][3] = +{ + {1.0, 0.0, 0.0}, + {0.8, 0.8, 0.0}, + {0.0, 0.7, 0.0}, + {0.3, 0.3, 0.8}, +}; +int state; + +extern void sphere(int level); + +GLdouble angle, speed = 0.5; + +GLfloat light0_ambient[] = +{0.1, 0.1, 0.1, 1.0}; +GLfloat light0_diffuse[] = +{0.5, 0.5, 0.5, 1.0}; +GLfloat light0_position[] = +{0.0, 0.0, 0.0, 1.0}; + +typedef struct { + GLfloat offset; + GLfloat distance; + GLfloat size; + GLfloat *color; +} Orb; + +Orb *orbs = NULL; +int num_orbs = 80; /* Good default for 1 RM InfiniteReality. */ +int fullscreen = 1; +int debug = 0; +int video_resizing = 1; +int hw_video_resizing = 1; /* Assume we have it until told otherwise. */ +int hw_exists = 0; +int frame_time = 15; +int sphere_quality = 1; +int max_w, max_h; +GLfloat W, H; +int delta_w_resize = 1, delta_h_resize = 1; +GLfloat target_frame_time = 1000.0 / 60.0; +int show_cursor = 1, show_meter = 1; + +#define NUM_SNAPS 2 +int snap[NUM_SNAPS] = +{0}; +int num_snaps = 1; +int frame = 0; + +GLfloat color[][3] = +{ + {0.0, 0.5, 0.0}, + {0.5, 0.5, 0.0}, + {1.0, 0.0, 0.5}, + {0.0, 1.0, 0.5}, + {1.0, 0.0, 0.0}, + {1.0, 0.0, 1.0}, + {0.0, 0.0, 0.8}, + {0.0, 0.2, 0.5}, + {1.0, 1.0, 0.0}, + {1.0, 1.0, 1.0}, + {0.3, 0.3, 0.3}, +}; +int num_colors = sizeof(color) / (sizeof(GLfloat) * 3); + +void +calculate_frame_rate(int delta) +{ + int sum, count, i; + + snap[frame] = delta; + frame += 1; + frame %= num_snaps; + + sum = 0; + count = 0; + for (i = 0; i < num_snaps; i++) { + if (snap[i] != 0) { + sum += snap[i]; + count++; + } + } + frame_time = sum / count; +} + +void +advancedAnimation(void) +{ + angle = (GLfloat) fmod(angle + speed, 360.0); + glutPostRedisplay(); +} + +void +resize(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, (GLfloat) w / (GLfloat) h, 1.0, 100.0); + glMatrixMode(GL_MODELVIEW); +} + +void +reshape(int w, int h) +{ + max_w = w; + max_h = h; + W = w; + H = h; + resize(w, h); +} + +void +do_video_resize_logic(void) +{ + GLfloat frame_ratio, adjusted_area, dimension_scale; + GLfloat area; + int Wint, Hint; + + if (frame_time > (target_frame_time * 0.92)) { + /* Shrink case. */ + frame_ratio = (target_frame_time * 0.92) / frame_time; + area = W * H; + adjusted_area = area * frame_ratio; + dimension_scale = sqrt(adjusted_area) / sqrt(area); + W = dimension_scale * W; + H = dimension_scale * H; + if (W < max_w / 8 || H < max_h / 8) { + W = max_w / 8; + H = max_h / 8; + state = OVERLOAD; + } else { + state = ZOOMED; + } + Wint = (((int) W) / delta_w_resize) * delta_w_resize; + Hint = (((int) H) / delta_h_resize) * delta_h_resize; + if (video_resizing) { + if (hw_video_resizing) + glutVideoResize(0, 0, -Wint, -Hint); + resize(Wint, Hint); + } + } else if (frame_time < (target_frame_time * 0.82)) { + /* Grow case. */ + frame_ratio = (target_frame_time * 0.82) / frame_time; + area = W * H; + adjusted_area = area * frame_ratio; + dimension_scale = sqrt(adjusted_area) / sqrt(area); + + /* Be a bit conservative about our growth. As Allan Greenspan would say, + "You don't want to overheat the economy; put on the brakes." */ + dimension_scale = (dimension_scale - 1.0) * 0.75 + 1.0; + if (dimension_scale > 1.5) { + dimension_scale = 1.5; + } + W = dimension_scale * W; + H = dimension_scale * H; + if (W > max_w || H > max_h) { + W = max_w; + H = max_h; + state = UNZOOMED; + } else { + state = ZOOMED; + } + Wint = (((int) W) / delta_w_resize) * delta_w_resize; + Hint = (((int) H) / delta_h_resize) * delta_h_resize; + if (video_resizing) { + if (hw_video_resizing) + glutVideoResize(0, 0, -Wint, -Hint); + resize(Wint, Hint); + } + } else { + if (!hw_video_resizing) { + /* We keep the meter constant size, so we must keep restoring our + viewport. */ + Wint = (((int) W) / delta_w_resize) * delta_w_resize; + Hint = (((int) H) / delta_h_resize) * delta_h_resize; + glViewport(0, 0, Wint, Hint); + } + } + if (debug) + printf("%gx%g\n\n", W, H); +} + +void +display(void) +{ + int i, start, stop; + + if (video_resizing) + do_video_resize_logic(); + + start = glutGet(GLUT_ELAPSED_TIME); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -1.0); + + for (i = 0; i < num_orbs; i++) { + glPushMatrix(); + glRotatef(angle + orbs[i].offset, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, orbs[i].distance); + glScalef(orbs[i].size, orbs[i].size, orbs[i].size); + glColor3fv(orbs[i].color); + glCallList(1); + glPopMatrix(); + } + + if (show_meter) { + if (!hw_video_resizing) { + /* Make sure the meter stays constant size in window mode. */ + glViewport(0, 0, max_w, max_h); + } + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 3000, 0, 3000); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glColor3fv(state_colors[state]); + glRecti(100, 100, 100 + frame_time * 8, 200); + if (video_resizing) { + float render_area = W * H, full_area = max_w * max_h; + float advantage = sqrt(full_area / render_area); + + glColor3f(1.0, 0.0, 1.0); + glRecti(100, 140, 100 + frame_time * advantage * 8, 160); + } + glColor3f(1.0, 1.0, 1.0); + glBegin(GL_LINES); + for (i = 0; i < 21; i++) { + glVertex2f(100 + i * 16.6 * 8, 80); + glVertex2f(100 + i * 16.6 * 8, 220); + } + glEnd(); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + } + glFinish(); + stop = glutGet(GLUT_ELAPSED_TIME); + + glutSwapBuffers(); + + calculate_frame_rate(stop - start); +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(advancedAnimation); + else + glutIdleFunc(NULL); +} + +void +set_cursor(int on) +{ + if (on) { + glutSetCursor(GLUT_CURSOR_INHERIT); + } else { + glutSetCursor(GLUT_CURSOR_NONE); + } +} + +void +generate_orbs(void) +{ + int i, r, angle, chance, delta, d; + + if (orbs) + free(orbs); + orbs = (Orb *) malloc(num_orbs * sizeof(Orb)); + + i = 0; + angle = 0; + while (i < num_orbs) { + angle += 37; + angle %= 360; + r = (int) lrand48(); + chance = abs(r % 360 - 180); + delta = chance - abs(angle - 180); + if (delta > 0) { + orbs[i].color = color[lrand48() % num_colors]; + orbs[i].offset = angle; + d = (r % 20) + (delta / 180.0) * 10; + orbs[i].distance = d + 3.0; + orbs[i].size = 1.4 * exp(d / 8.0) / exp(1.0); + i++; + } + } +} + +/* ARGSUSED */ +void +keyboard(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + case 'q': + case 'Q': + exit(0); + break; + case 'R': + case 'r': + video_resizing = 1; + break; + case 'H': + case 'h': + if (hw_exists) { + hw_video_resizing = 1 - hw_video_resizing; + if (!hw_video_resizing) { + glutVideoResize(0, 0, max_w, max_h); + resize(max_w, max_h); + } + } + break; + case 'N': + case 'n': + video_resizing = 0; + if (hw_video_resizing) + glutVideoResize(0, 0, max_w, max_h); + resize(max_w, max_h); + state = STATIC; + break; + case 'D': + case 'd': + debug = 1; + break; + case 'M': + case 'm': + show_meter = 1 - show_meter; + break; + case ' ': + generate_orbs(); + break; + case 'C': + case 'c': + show_cursor = 1 - show_cursor; + set_cursor(show_cursor); + break; + } +} + +/* ARGSUSED */ +void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_RIGHT: + speed -= 0.25; + break; + case GLUT_KEY_LEFT: + speed += 0.25; + break; + case GLUT_KEY_UP: + num_orbs += 10; + generate_orbs(); + break; + case GLUT_KEY_DOWN: + num_orbs -= 10; + generate_orbs(); + break; + } +} + +int +main(int argc, char **argv) +{ + int i; + + glutInit(&argc, argv); + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-orbs")) { + i++; + if (i >= argc) { + fprintf(stderr, "videoresize: need number of orbs\n"); + exit(1); + } + num_orbs = atoi(argv[i]); + if (num_orbs < 1) { + fprintf(stderr, "videoresize: number of orbs must be 1 or more\n"); + exit(1); + } + } else if (!strcmp(argv[i], "-target")) { + i++; + if (i >= argc) { + fprintf(stderr, "videoresize: need target number of frames\n"); + exit(1); + } + target_frame_time = atoi(argv[i]) * 1000.0 / 60.0; + if (target_frame_time <= 0.0) { + fprintf(stderr, "videoresize: target frames must be 1 or more\n"); + exit(1); + } + } else if (!strcmp(argv[i], "-novidresize")) { + hw_video_resizing = 0; + } else if (!strcmp(argv[i], "-debug")) { + debug = 1; + } else if (!strcmp(argv[i], "-window")) { + fullscreen = 0; + } else if (!strcmp(argv[i], "-twosnaps")) { + num_snaps = 2; + } else if (!strcmp(argv[i], "-nice")) { + sphere_quality = 2; + } else { + printf("usage: videoresize [-window] [-twosnaps] [-nice] [-target #] [-orbs #]\n"); + printf(" -target # = target number of frame intervals to stay under (default=%g)\n", target_frame_time); + printf(" -orbs # = number of orbs to randomly position (default=%d)\n", num_orbs); + printf(" -window = do not go fullscreen\n"); + printf(" -nice = use better tesselated spheres\n"); + printf(" -novidresize = even if videoresizing is supported, don't use it\n"); + printf(" -twosnaps = averages over last two frames instead of just estimating\n"); + printf(" based on the last frame\n"); + exit(1); + } + } + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutCreateWindow("Dynamic video resizing for constant frame rates"); + if (fullscreen) { + glutFullScreen(); + if (glutVideoResizeGet(GLUT_VIDEO_RESIZE_POSSIBLE)) { + delta_w_resize = glutVideoResizeGet(GLUT_VIDEO_RESIZE_WIDTH_DELTA); + delta_h_resize = glutVideoResizeGet(GLUT_VIDEO_RESIZE_HEIGHT_DELTA); + show_cursor = 0; + glutSetupVideoResizing(); + hw_exists = 1; + } else { + hw_video_resizing = 0; + } + } else { + hw_video_resizing = 0; + } + if (video_resizing) { + state = UNZOOMED; + } else { + state = STATIC; + } + glutReshapeFunc(reshape); + glDisable(GL_CULL_FACE); /* Makes us more fill limited. */ + glEnable(GL_LIGHT0); + glColorMaterial(GL_FRONT, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_NORMALIZE); + glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, light0_position); + + glNewList(1, GL_COMPILE); + sphere(sphere_quality); + glEndList(); + + srand48(getpid() * 16 + glutGet(GLUT_ELAPSED_TIME)); + generate_orbs(); + + glutDisplayFunc(display); + glutVisibilityFunc(visible); + glutKeyboardFunc(keyboard); + glutSpecialFunc(special); + set_cursor(show_cursor); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/videoresize.dsp b/lib/glut-3.7.6/progs/advanced/videoresize.dsp new file mode 100644 index 0000000000..1fc4f307dd --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/videoresize.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="videoresize" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=videoresize - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "videoresize.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "videoresize.mak" CFG="videoresize - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "videoresize - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "videoresize - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "videoresize - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "videoresize - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "videoresize - Win32 Release" +# Name "videoresize - Win32 Debug" +# Begin Source File + +SOURCE=.\sphere.c +# End Source File +# Begin Source File + +SOURCE=.\videoresize.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/vox.c b/lib/glut-3.7.6/progs/advanced/vox.c new file mode 100644 index 0000000000..bc20efb417 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/vox.c @@ -0,0 +1,892 @@ +/** + * + * vox.c : GLUT example for volume rendering + * + * Author : Yusuf Attarwala + * SGI - Applications + * + * Mods by Mark Kilgard. + * + * cc vox.c -o vox -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm + * + * Voxel Head is a simple volume rendering example using OpenGL 3d textures. + * This version has limited features (intentional), to keep the code simple. + * + * i.e. - there is no control for changing alpha values. + * - it just deals with one block of texture (no tiling) + * - there are no clipping planes + * - it only works with one data set, so it assumes that texture data + * is in powers of 2. + * + * Some of these features will be implemented in future releases. + * + * The technique to create polygonal slices thru voxel space is as + * follows: + * + * Instead of recomputing polygonal slices perpendicular to every + * viewing vector, it uses the same set of polygonal slices for a + * range of -45 to 45 degrees. Outside this range, it recomputes + * another set of slices and so on. + * + * These slices are then rendered back to front with 3d texture and + * blending enabled. + * + * It uses GLUT for handling events, windows etc. + * + * This program runs with good performance on RealityEngine, VTX, + * InfiniteReality, or Maximum IMPACT. In IRIX 6.2, a software + * implementation of OpenGL's 3D texture mapping extension is + * available, but performance is very poor. If you are on a slow + * machine, you can run "vox -sb" and still get a good feel for how + * the program performs volume rendering since you can see the 3D + * slices be rendered back to front with blending. + * + */ + +#include +#include +#ifndef _WIN32 +#include +#else +#define R_OK 04 /* Win32 doesn't define this */ +/* Win32 defines these, but with a leading _ */ +#define pclose _pclose +#define popen _popen +/* Win32 doesn't have a re-entrand rand() */ +#define rand_r(x) rand() +#endif +#include +#include + +#include + +#define ABS(a) (((a) >= 0) ? (a) : -(a)) +#define _XY 1 +#define _YZ 2 +#define _ZX 3 +#define _MXY 4 +#define _MYZ 5 +#define _MZX 6 + +/* pop up menu entries */ +#define SPIN_ON 1 +#define SPIN_OFF 2 +#define MENU_HELP 3 +#define MENU_EXIT 4 + +/* global variables */ + +int width, height; /* window width, height */ +float left, right, bottom, top, nnear, ffar; /* ortho, view volume */ +float vol_width, vol_height, vol_depth; /* volume dimensions */ +float bminx, bmaxx, bminy, bmaxy, bminz, bmaxz, bdiag; /* bounding box */ +int n_slices; /* number of slices */ +int tex3dSupported = 1; +float slice_poly[3][4][3]; +float slice_tcoord[3][4][3]; +float anglex, angley, anglez; + +unsigned char *voxels; + +void +readVoxelData(void) +{ + FILE *file; + int i, j, k, using_pipe; + unsigned char *vptr; + unsigned char *vp, *vx; + + /* see if the hardware supports 3d texture */ +#ifdef GL_EXT_texture3D + if (!glutExtensionSupported("GL_EXT_texture3D")) { + printf("\n==================================================================\n"); + printf("This hardware (%s) does not support 3d texture extentions\n", + (char *) (glGetString(GL_RENDERER))); + printf("==================================================================\n"); + + tex3dSupported = 0; + } +#else + printf("\n==================================================================\n"); + printf("Not API support for GL_EXT_texture3D extension when compiled.\n"); + printf("==================================================================\n"); +#endif + /* open vox.bin data file */ + if ((file = fopen("vox.bin", "r")) == NULL) { +#ifndef _WIN32 + if (!access("vox.bin.gz", R_OK)) { + if ((file = popen("gzcat vox.bin.gz", "r")) == NULL) { + fprintf(stderr, "cannot popen input file vox.bin.gz (missing gzcat?)\n"); + exit(1); + } + } else if (!access("vox.bin.Z", R_OK)) { + if ((file = popen("zcat vox.bin.Z", "r")) == NULL) { + fprintf(stderr, "cannot popen input file vox.bin.Z (missing zcat?)\n"); + exit(1); + } + } else { + fprintf(stderr, "cannot find vox.bin, vox.bin.gz, or vox.bin.Z\n"); + exit(1); + } + using_pipe = 1; +#else + fprintf(stderr, "cannot find vox.bin\n"); + exit(1); +#endif + } else { + using_pipe = 0; + } + vol_width = 128; /* hard coded for demo */ + vol_height = 128; + vol_depth = 64; + n_slices = 128; + + if (tex3dSupported) { + unsigned long size = (unsigned long) (vol_width * vol_height * vol_depth); + + vptr = (unsigned char *) malloc(size); + + fread(vptr, sizeof(char), size, file); + if (using_pipe) { + pclose(file); + } else { + fclose(file); + } + + /* size of voxels is twice as the size of vptr, to duplicate alpha value + = intensity */ + voxels = (unsigned char *) malloc(2 * size); + + /* for now duplicate, alpha value = intensity */ + vx = voxels; + vp = vptr; + for (i = 0; i < vol_width; i++) + for (j = 0; j < vol_height; j++) + for (k = 0; k < vol_depth; k++) { + *vx++ = *vp; + *vx++ = *vp++; + } + + free(vptr); + } + /* compute bounding box extents */ + + bminx = -(float) vol_width / 2.0; + bmaxx = (float) vol_width / 2.0; + bminy = -(float) vol_height / 2.0; + bmaxy = (float) vol_height / 2.0; + bminz = -(float) vol_depth / 2.0; + bmaxz = (float) vol_depth / 2.0; + + bdiag = sqrt((bmaxx) * (bmaxx) + (bmaxy) * (bmaxy) + (bmaxz) * (bmaxz)); + + /* compute view volume extents */ + + left = -1.1 * bdiag; + right = 1.1 * bdiag; + bottom = -1.1 * bdiag; + top = 1.1 * bdiag; + nnear = -1.0 * bdiag; + ffar = 2 * 1.1 * bdiag; + + /* define the polygon dimensions on which the texture will be mapped */ + /* xy plane */ + slice_poly[0][0][0] = -vol_width / 2.0; + slice_poly[0][0][1] = -vol_height / 2.0; + slice_poly[0][0][2] = 0.0; + + slice_poly[0][1][0] = vol_width / 2.0; + slice_poly[0][1][1] = -vol_height / 2.0; + slice_poly[0][1][2] = 0.0; + + slice_poly[0][2][0] = vol_width / 2.0; + slice_poly[0][2][1] = vol_height / 2.0; + slice_poly[0][2][2] = 0.0; + + slice_poly[0][3][0] = -vol_width / 2.0; + slice_poly[0][3][1] = vol_height / 2.0; + slice_poly[0][3][2] = 0.0; + + /* yz plane */ + slice_poly[1][0][0] = 0.0; + slice_poly[1][0][1] = -vol_height / 2.0; + slice_poly[1][0][2] = -vol_depth / 2.0; + + slice_poly[1][1][0] = 0.0; + slice_poly[1][1][1] = vol_height / 2.0; + slice_poly[1][1][2] = -vol_depth / 2.0; + + slice_poly[1][2][0] = 0.0; + slice_poly[1][2][1] = vol_height / 2.0; + slice_poly[1][2][2] = vol_depth / 2.0; + + slice_poly[1][3][0] = 0.0; + slice_poly[1][3][1] = -vol_height / 2.0; + slice_poly[1][3][2] = vol_depth / 2.0; + + /* zx plane */ + slice_poly[2][0][0] = -vol_width / 2.0; + slice_poly[2][0][1] = 0.0; + slice_poly[2][0][2] = -vol_depth / 2.0; + + slice_poly[2][1][0] = -vol_width / 2.0; + slice_poly[2][1][1] = 0.0; + slice_poly[2][1][2] = vol_depth / 2.0; + + slice_poly[2][2][0] = vol_width / 2.0; + slice_poly[2][2][1] = 0.0; + slice_poly[2][2][2] = vol_depth / 2.0; + + slice_poly[2][3][0] = vol_width / 2.0; + slice_poly[2][3][1] = 0.0; + slice_poly[2][3][2] = -vol_depth / 2.0; + + /* texture coordinates */ + + slice_tcoord[0][0][0] = 0.0; + slice_tcoord[0][0][1] = 0.0; + slice_tcoord[0][1][0] = 1.0; + slice_tcoord[0][1][1] = 0.0; + slice_tcoord[0][2][0] = 1.0; + slice_tcoord[0][2][1] = 1.0; + slice_tcoord[0][3][0] = 0.0; + slice_tcoord[0][3][1] = 1.0; + + slice_tcoord[1][0][1] = 0.0; + slice_tcoord[1][0][2] = 1.0; + slice_tcoord[1][1][1] = 1.0; + slice_tcoord[1][1][2] = 1.0; + slice_tcoord[1][2][1] = 1.0; + slice_tcoord[1][2][2] = 0.0; + slice_tcoord[1][3][1] = 0.0; + slice_tcoord[1][3][2] = 0.0; + + slice_tcoord[2][0][2] = 0.0; + slice_tcoord[2][0][0] = 0.0; + slice_tcoord[2][1][2] = 1.0; + slice_tcoord[2][1][0] = 0.0; + slice_tcoord[2][2][2] = 1.0; + slice_tcoord[2][2][0] = 1.0; + slice_tcoord[2][3][2] = 0.0; + slice_tcoord[2][3][0] = 1.0; + +} + +void +randomTick(void) +{ + static unsigned int seed = 0; + static int changeSeed = 25; + float fltran; + + if (changeSeed++ >= 25) { + seed++; + if (seed > 256) + seed = 0; + changeSeed = 0; + } + fltran = (float) (rand_r(&seed) / 30000.0); + + anglex = (anglex > 360.0) ? 0.0 : (anglex + fltran); + angley = (angley > 360.0) ? 0.0 : (angley + fltran); + anglez = (anglez > 360.0) ? 0.0 : (anglez + fltran); +} + +void +animate(void) +{ + randomTick(); + glutPostRedisplay(); +} + +void +printCheatSheet(void) +{ + printf("\n\n-------------------------\n"); + printf("OpenGL 3d texture example\n\n"); + + printf("Keyboard shortcuts\n"); + printf("s key : zoom out (small)\n"); + printf("l key : zoom in (large)\n"); + printf("x key : rotate about screen x\n"); + printf("y key : rotate about screen y\n"); + printf("z key : rotate about screen z\n"); + printf("esc key : quit\n"); +} + +void +menu(int choice) +{ + /* simple GLUT popup menu stuff */ + switch (choice) { + case SPIN_ON: + glutChangeToMenuEntry(1, "Random Spin OFF", SPIN_OFF); + glutIdleFunc(animate); + break; + case SPIN_OFF: + glutChangeToMenuEntry(1, "Random Spin ON", SPIN_ON); + glutIdleFunc(NULL); + break; + case MENU_HELP: + printCheatSheet(); + break; + case MENU_EXIT: + exit(0); + break; + } +} + +void +setMatrix(void) +{ + /* feel like using ortho projection */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(left, right, bottom, top, nnear, ffar); + + /* boring view matrix */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void +load3DTexture(void) +{ + printf("setting up 3d textures...\n"); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +#ifdef GL_EXT_texture3D + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT); + + glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_LUMINANCE8_ALPHA8_EXT, + vol_width, vol_height, vol_depth, + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, voxels); +#endif + + if (tex3dSupported) { + /* enable texturing, blending etc */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + setMatrix(); +} + +void +init(void) +{ + /* angle of rotation about coordinate axes */ + anglex = angley = anglez = 0.0; +} + +void +invert4d(float from[4][4], float to[4][4]) +{ + + /* 4x4 matrix inversion routine */ + + float wtemp[4][8]; + register float m0, m1, m2, m3, s; + register float *r0, *r1, *r2, *r3, *rtemp; + + r0 = wtemp[0]; + r1 = wtemp[1]; + r2 = wtemp[2]; + r3 = wtemp[3]; + r0[0] = from[0][0]; /* build up [A][I] */ + r0[1] = from[0][1]; + r0[2] = from[0][2]; + r0[3] = from[0][3]; + r0[4] = 1.0; + r0[5] = 0.0; + r0[6] = 0.0; + r0[7] = 0.0; + r1[0] = from[1][0]; + r1[1] = from[1][1]; + r1[2] = from[1][2]; + r1[3] = from[1][3]; + r1[4] = 0.0; + r1[5] = 1.0; + r1[6] = 0.0; + r1[7] = 0.0; + r2[0] = from[2][0]; + r2[1] = from[2][1]; + r2[2] = from[2][2]; + r2[3] = from[2][3]; + r2[4] = 0.0; + r2[5] = 0.0; + r2[6] = 1.0; + r2[7] = 0.0; + r3[0] = from[3][0]; + r3[1] = from[3][1]; + r3[2] = from[3][2]; + r3[3] = from[3][3]; + r3[4] = 0.0; + r3[5] = 0.0; + r3[6] = 0.0; + r3[7] = 1.0; + if (r0[0] == 0.0) { /* swap rows if needed */ + if (r1[0] == 0.0) { + if (r2[0] == 0.0) { + if (r3[0] == 0.0) + goto singular; + rtemp = r0; + r0 = r3; + r3 = rtemp; + } else { + rtemp = r0; + r0 = r2; + r2 = rtemp; + } + } else { + rtemp = r0; + r0 = r1; + r1 = rtemp; + } + } + m1 = r1[0] / r0[0]; /* eliminate first variable */ + m2 = r2[0] / r0[0]; + m3 = r3[0] / r0[0]; + s = r0[1]; + r1[1] = r1[1] - m1 * s; + r2[1] = r2[1] - m2 * s; + r3[1] = r3[1] - m3 * s; + s = r0[2]; + r1[2] = r1[2] - m1 * s; + r2[2] = r2[2] - m2 * s; + r3[2] = r3[2] - m3 * s; + s = r0[3]; + r1[3] = r1[3] - m1 * s; + r2[3] = r2[3] - m2 * s; + r3[3] = r3[3] - m3 * s; + s = r0[4]; + if (s != 0.0) { + r1[4] = r1[4] - m1 * s; + r2[4] = r2[4] - m2 * s; + r3[4] = r3[4] - m3 * s; + } + s = r0[5]; + if (s != 0.0) { + r1[5] = r1[5] - m1 * s; + r2[5] = r2[5] - m2 * s; + r3[5] = r3[5] - m3 * s; + } + s = r0[6]; + if (s != 0.0) { + r1[6] = r1[6] - m1 * s; + r2[6] = r2[6] - m2 * s; + r3[6] = r3[6] - m3 * s; + } + s = r0[7]; + if (s != 0.0) { + r1[7] = r1[7] - m1 * s; + r2[7] = r2[7] - m2 * s; + r3[7] = r3[7] - m3 * s; + } + if (r1[1] == 0.0) { /* swap rows if needed */ + if (r2[1] == 0.0) { + if (r3[1] == 0.0) + goto singular; + rtemp = r1; + r1 = r3; + r3 = rtemp; + } else { + rtemp = r1; + r1 = r2; + r2 = rtemp; + } + } + m2 = r2[1] / r1[1]; /* eliminate second variable */ + m3 = r3[1] / r1[1]; + r2[2] = r2[2] - m2 * r1[2]; + r3[2] = r3[2] - m3 * r1[2]; + r3[3] = r3[3] - m3 * r1[3]; + r2[3] = r2[3] - m2 * r1[3]; + s = r1[4]; + if (s != 0.0) { + r2[4] = r2[4] - m2 * s; + r3[4] = r3[4] - m3 * s; + } + s = r1[5]; + if (s != 0.0) { + r2[5] = r2[5] - m2 * s; + r3[5] = r3[5] - m3 * s; + } + s = r1[6]; + if (s != 0.0) { + r2[6] = r2[6] - m2 * s; + r3[6] = r3[6] - m3 * s; + } + s = r1[7]; + if (s != 0.0) { + r2[7] = r2[7] - m2 * s; + r3[7] = r3[7] - m3 * s; + } + if (r2[2] == 0.0) { /* swap last 2 rows if needed */ + if (r3[2] == 0.0) + goto singular; + rtemp = r2; + r2 = r3; + r3 = rtemp; + } + m3 = r3[2] / r2[2]; /* eliminate third variable */ + r3[3] = r3[3] - m3 * r2[3]; + r3[4] = r3[4] - m3 * r2[4]; + r3[5] = r3[5] - m3 * r2[5]; + r3[6] = r3[6] - m3 * r2[6]; + r3[7] = r3[7] - m3 * r2[7]; + if (r3[3] == 0.0) + goto singular; + s = 1.0 / r3[3]; /* now back substitute row 3 */ + r3[4] = r3[4] * s; + r3[5] = r3[5] * s; + r3[6] = r3[6] * s; + r3[7] = 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] = (r1[4] - r3[4] * m1); + r1[5] = (r1[5] - r3[5] * m1); + r1[6] = (r1[6] - r3[6] * m1); + r1[7] = (r1[7] - r3[7] * m1); + m0 = r0[3]; + r0[4] = (r0[4] - r3[4] * m0); + r0[5] = (r0[5] - r3[5] * m0); + r0[6] = (r0[6] - r3[6] * m0); + r0[7] = (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] = (r0[4] - r2[4] * m0); + r0[5] = (r0[5] - r2[5] * m0); + r0[6] = (r0[6] - r2[6] * m0); + r0[7] = (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); + to[0][0] = r0[4]; /* copy results back */ + to[0][1] = r0[5]; + to[0][2] = r0[6]; + to[0][3] = r0[7]; + to[1][0] = r1[4]; + to[1][1] = r1[5]; + to[1][2] = r1[6]; + to[1][3] = r1[7]; + to[2][0] = r2[4]; + to[2][1] = r2[5]; + to[2][2] = r2[6]; + to[2][3] = r2[7]; + to[3][0] = r3[4]; + to[3][1] = r3[5]; + to[3][2] = r3[6]; + to[3][3] = r3[7]; + return; +singular: + printf("ERROR : non_invertable transform\n"); + return; +} + +void +normalize(float *xn, float *yn, float *zn) +{ + double denom; + + denom = sqrt((double) ((*xn * *xn) + (*yn * *yn) + (*zn * *zn))); + + *xn = *xn / denom; + *yn = *yn / denom; + *zn = *zn / denom; +} + +int +getViewAxis(void) +{ + float viewDir[3]; + float mat[4][4], vinv[4][4]; + float maxf, xy, yz, zx; + int im; + + /* out of 3 orthogonal set of planes in world coords, find out which one + has maximum angle from the line of sight. + + we will use these set of planes for creating polygonal slices thru the + voxel space */ + + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) mat); + invert4d(mat, vinv); + + viewDir[0] = -vinv[2][0]; + viewDir[1] = -vinv[2][1]; + viewDir[2] = -vinv[2][2]; + + normalize(&viewDir[0], &viewDir[1], &viewDir[2]); + + xy = viewDir[2]; /* simplified because 0*xx + 0*yy + 1*zz */ + yz = viewDir[0]; + zx = viewDir[1]; + + maxf = ABS(xy); + im = (xy < 0.0) ? _XY : _MXY; + + if (maxf <= ABS(yz)) { + maxf = ABS(yz); + im = (yz < 0.0) ? _YZ : _MYZ; + } + if (maxf <= ABS(zx)) { + maxf = ABS(zx); + im = (zx < 0.0) ? _ZX : _MZX; + } + return (im); +} + +#define DRAW_SLICE \ + if (tex3dSupported) {\ + glBegin(GL_POLYGON);\ + for (p=0;p<4;p++) {\ + glTexCoord3fv(slice_tcoord[myaxis][p]);\ + glVertex3fv(slice_poly[myaxis][p]);\ + }\ + glEnd();\ + } \ + else {\ + glBegin(GL_LINE_LOOP);\ + for (p=0;p<4;p++){\ + glVertex3fv(slice_poly[myaxis][p]);\ + }\ + glEnd();\ + } + +void +drawScene(void) +{ + + int i, p; + float tc; + int viewAxis, myaxis; + int sign; + + static int myaxis_lut[] = + {0, 0, 1, 2, 0, 1, 2}; + + /* clear background, z buffer etc */ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + + /* apply all the modeling transformations */ + glTranslatef(0.0, 0.0, -bdiag); + glRotatef(anglex, 1.0, 0.0, 0.0); + glRotatef(angley, 0.0, 1.0, 0.0); + glRotatef(anglez, 0.0, 0.0, 1.0); + + /* getViewAxis(), determines which set of polygons need to be used for + texturing, depending upon the viewing direction */ + + viewAxis = getViewAxis(); + myaxis = myaxis_lut[viewAxis]; + + glColor3f(1.0, 1.0, 1.0); + +#ifdef GL_EXT_texture3D + if (tex3dSupported) + glEnable(GL_TEXTURE_3D_EXT); +#endif + + switch (viewAxis) { + case _XY: + case _MXY: + + sign = (viewAxis == _XY) ? 1 : -1; + tc = (viewAxis == _XY) ? 0.0 : 1.0; + + glTranslatef(0.0, 0.0, -sign * vol_depth / 2.0); + for (i = 0; i < n_slices; i++) { + + slice_tcoord[0][0][2] = slice_tcoord[0][1][2] = + slice_tcoord[0][2][2] = slice_tcoord[0][3][2] = tc; + + tc += sign * 1.0 / n_slices; + glTranslatef(0.0, 0.0, sign * vol_depth / (n_slices + 1.0)); + + DRAW_SLICE; + } + break; + case _YZ: + case _MYZ: + + sign = (viewAxis == _YZ) ? 1 : -1; + tc = (viewAxis == _YZ) ? 0.0 : 1.0; + + glTranslatef(-sign * vol_width / 2.0, 0.0, 0.0); + for (i = 0; i < n_slices; i++) { + + slice_tcoord[1][0][0] = slice_tcoord[1][1][0] = + slice_tcoord[1][2][0] = slice_tcoord[1][3][0] = tc; + + tc += sign * 1.0 / n_slices; + glTranslatef(sign * vol_width / (n_slices + 1.0), 0.0, 0.0); + + DRAW_SLICE; + } + break; + case _ZX: + case _MZX: + + sign = (viewAxis == _ZX) ? 1 : -1; + tc = (viewAxis == _ZX) ? 0.0 : 1.0; + + glTranslatef(0.0, -sign * vol_height / 2.0, 0.0); + for (i = 0; i < n_slices; i++) { + + slice_tcoord[2][0][1] = slice_tcoord[2][1][1] = + slice_tcoord[2][2][1] = slice_tcoord[2][3][1] = tc; + + tc += sign * 1.0 / n_slices; + glTranslatef(0.0, sign * vol_height / (n_slices + 1.0), 0.0); + + DRAW_SLICE; + + } + break; + } + +#ifdef GL_EXT_texture3D + if (tex3dSupported) + glDisable(GL_TEXTURE_3D_EXT); +#endif + + glPopMatrix(); + + glutSwapBuffers(); +} + +void +resize(int w, int h) +{ + /* things you do, when the user resizes the window */ + + width = w; + height = h; + + glViewport(0, 0, w, h); + setMatrix(); +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char c, int x, int y) +{ + /* handle key board input */ + + switch (c) { + case 27: + exit(0); + break; + case 'x': + anglex += 1.0; + drawScene(); + break; + case 'y': + angley += 1.0; + drawScene(); + break; + case 'z': + anglez += 1.0; + drawScene(); + break; + case 'm': + n_slices++; + drawScene(); + break; + case 'e': + n_slices--; + if (n_slices < 4) + n_slices = 4; + drawScene(); + break; + case 's': + if (left < right + 10.0) { + left -= 1.0; + right += 1.0; + bottom -= 1.0; + top += 1.0; + setMatrix(); + drawScene(); + } + break; + case 'l': + left += 1.0; + right -= 1.0; + bottom += 1.0; + top -= 1.0; + setMatrix(); + drawScene(); + break; + default: + break; + } +} + +void +main(int argc, char **argv) +{ + int i, mode = GLUT_DOUBLE; + + glutInit(&argc, argv); + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-no3Dtex")) { + tex3dSupported = 0; + } else if (!strcmp(argv[i], "-sb")) { + mode = GLUT_SINGLE; + } + } + + /* let glut do all the X Stuff */ + glutInitDisplayMode(GLUT_RGB | mode); + glutCreateWindow("Voxel Head"); + + /* init our variables, etc */ + init(); + + /* read texture data from a file */ + readVoxelData(); + + /* set up OpenGL texturing */ + if (tex3dSupported) + load3DTexture(); + + /* register specific routines to glut */ + glutDisplayFunc(drawScene); + glutReshapeFunc(resize); + glutKeyboardFunc(keyboard); + + /* create popup menu for glut */ + glutCreateMenu(menu); + + glutAddMenuEntry("Random Spin ON", SPIN_ON); + glutAddMenuEntry("Help", MENU_HELP); + glutAddMenuEntry("Exit", MENU_EXIT); + + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* loop for ever */ + glutMainLoop(); +} diff --git a/lib/glut-3.7.6/progs/advanced/vox.dsp b/lib/glut-3.7.6/progs/advanced/vox.dsp new file mode 100644 index 0000000000..0039ea4f50 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/vox.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="vox" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=vox - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vox.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vox.mak" CFG="vox - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vox - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "vox - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vox - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "vox - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "vox - Win32 Release" +# Name "vox - Win32 Debug" +# Begin Source File + +SOURCE=.\vox.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/warp.c b/lib/glut-3.7.6/progs/advanced/warp.c new file mode 100644 index 0000000000..d6f4b1ef1d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/warp.c @@ -0,0 +1,284 @@ + +/* warp.c - by David Blythe, SGI */ + +/* Image warping operations can be done via OpenGL texture mapping. */ + +#include +#include +#include +#include +#include "texture.h" + +static unsigned *image; +static int width, height, components; +static float incr = .05, dir = 1.0; + +#define MAXMESH 32 + +float Ml[4 * 2 * (MAXMESH + 1) * 2 * (MAXMESH + 1)]; + +float N = 1.5; +float B = -1.5; + +void +mesh1(float x0, float x1, float y0, float y1, + float s0, float s1, float t0, float t1, float z, int nx, int ny) +{ + float y, x, s, t, dx, dy, ds, dt, vb[3], tb[2]; + float v; + float *mp = Ml; + + dx = (x1 - x0) / nx; + dy = (y1 - y0) / ny; + ds = (s1 - s0) / nx; + dt = (t1 - t0) / ny; + y = y0; + t = t0; + vb[2] = z; + while (y < y1) { + x = x0; + s = s0; + while (x <= x1) { + tb[0] = s; + tb[1] = t; + vb[0] = x; + vb[1] = y; + v = N * N - x * x - y * y; + if (v < 0.0) + v = 0.0; + vb[2] = sqrt(v) + B; + if (vb[2] < 0.) + vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + tb[1] = t + dt; + vb[1] = y + dy; + v = N * N - x * x - (y + dy) * (y + dy); + if (v < 0.0) + v = 0.0; + vb[2] = sqrt(v) + B; + if (vb[2] < 0.) + vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + x += dx; + s += ds; + } + y += dy; + t += dt; + } +} + +void +drawmesh(int nx, int ny) +{ + float *mp = Ml; + int i, j; + + glColor4f(1, 1, 1, 1); + for (i = ny + 1; i; i--) { + glBegin(GL_TRIANGLE_STRIP); + for (j = nx + 1; j; j--) { + glTexCoord2fv(mp); + glVertex3fv(mp + 4); + glTexCoord2fv(mp + 8); + glVertex3fv(mp + 12); + mp += 16; + } + glEnd(); + } +} + +void +move(void) +{ + if (N > 2.1 || N < 1.5) + dir = -dir; + N += incr * dir; + mesh1(-1.5, 1.5, -1.5, 1.5, 0.0, 1.0, 0.0, 1.0, 0.0, MAXMESH, MAXMESH); + glutPostRedisplay(); +} + +void +alphaup(void) +{ + incr += .01; + if (incr > .1) + incr = .1; + glutPostRedisplay(); +} + +void +alphadown(void) +{ + incr -= .01; + if (incr < 0) + incr = 0; + glutPostRedisplay(); +} + +void +wire(void) +{ + static int wire_mode; + if (wire_mode ^= 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void +help(void) +{ + printf("'h' - help\n"); + printf("'w' - wire frame\n"); + printf("UP - faster\n"); + printf("DOWN - slower\n"); +} + +void +init(char *filename) +{ + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(1); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components < 3 || components > 4) { + printf("must be RGB or RGBA image\n"); + exit(1); + } + } else { + int i, j; + components = 4; + width = height = 512; + image = (unsigned *) malloc(width * height * sizeof(unsigned)); + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + if (i & 64) + image[i + j * width] = 0xff; + else + image[i + j * width] = 0xff00; + if (j & 64) + image[i + j * width] |= 0xff0000; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90., 1., .1, 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0., 0., -1.5); + glClearColor(.25, .25, .25, 0.); + +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + drawmesh(MAXMESH, MAXMESH); + glutSwapBuffers(); +} + +void +reshape(int w, int h) +{ + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case '\033': + exit(0); + break; + case 'h': + help(); + break; + case 'w': + wire(); + break; + } +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_UP: + alphaup(); + break; + case GLUT_KEY_DOWN: + alphadown(); + break; + } +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(move); + else + glutIdleFunc(NULL); +} + +void +menu(int value) +{ + if(value < 0) + special(-value, 0, 0); + else + key((unsigned char) value, 0, 0); +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); + (void) glutCreateWindow("warp"); + init(argv[1]); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutVisibilityFunc(visible); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle wireframe", 'w'); + glutAddMenuEntry("Quicken warping", -GLUT_KEY_UP); + glutAddMenuEntry("Slow warping", -GLUT_KEY_DOWN); + glutAddMenuEntry("Quit", '\033'); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/warp.dsp b/lib/glut-3.7.6/progs/advanced/warp.dsp new file mode 100644 index 0000000000..d6d9d5c0d5 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/warp.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="warp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=warp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "warp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "warp.mak" CFG="warp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "warp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "warp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "warp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "warp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "warp - Win32 Release" +# Name "warp - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\warp.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced/zcomposite.c b/lib/glut-3.7.6/progs/advanced/zcomposite.c new file mode 100644 index 0000000000..3bce5ebdaf --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/zcomposite.c @@ -0,0 +1,437 @@ + +/* zcomposite.c - by Tom McReynolds, SGI */ + +/* Compositing images that include depth information. */ + +/* To use this program, you select a region of the "room" scene by + rubber-banding the region with the left mouse button. Once a + region is selected, position the region with the middle mouse + button. The region will be composited using the region image and + the region's depth information. With the right mouse button, you + can shift the region's depth values nearer or further away. */ + +#include +#include +#include + +/* Create a single component texture map */ +GLfloat * +make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +GLboolean stencil = GL_TRUE; + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 't': /* toggle using stencil */ + if (stencil == GL_TRUE) + stencil = GL_FALSE; + else + stencil = GL_TRUE; + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + } +} + +enum { + SPHERE = 1, CONE +}; +enum { + X, Y, Z +}; + +int startx, starty; +int wid, ht; +int oldwid = 0, oldht = 0; + +const int WINDIM = 512; +const GLfloat FRUSTDIM = 110.f; +const GLfloat FRUSTNEAR = 320.f; +const GLfloat FRUSTFAR = 540.f; +const GLfloat FRUSTDIFF = 540.f - 320.f; + +GLboolean drawmode = GL_FALSE; +GLboolean depthmode = GL_FALSE; +GLboolean rubberbandmode = GL_FALSE; +GLfloat *color; +GLfloat *depth; +GLfloat depthbias = 0.f; +GLfloat raspos[] = +{0.f, 0.f, -430.f}; + +int winWidth = 512; +int winHeight = 512; + +GLfloat sx = 0; +GLfloat sy = 0; + +/* Overlay Stuff */ +int transparent; +int red; +int overlaySupport = 0; + +void +setRasterPosXY(int x, int y) +{ + raspos[X] = (x - winWidth / 2) * sx; + raspos[Y] = (y - winHeight / 2) * sy; + + glRasterPos3fv(raspos); + + glutPostRedisplay(); +} + +void +setRasterPosZ(int y) +{ + raspos[Z] = -(FRUSTNEAR + y * FRUSTDIFF / winHeight); + + depthbias = (y - winHeight / 2.f) / winHeight; + + glRasterPos3fv(raspos); + + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + y = winHeight - y; + if (drawmode) + setRasterPosXY(x, y); + + if (rubberbandmode) { + wid = x - startx; + ht = y - starty; + if (overlaySupport) glutPostOverlayRedisplay(); + } + if (depthmode) + setRasterPosZ(y); +} + +/* redraw function for overlay: used to show selected region */ +void +overlay(void) +{ + if (glutLayerGet(GLUT_OVERLAY_DAMAGED)) { + glClear(GL_COLOR_BUFFER_BIT); + } else { + glIndexi(transparent); + glBegin(GL_LINE_LOOP); + glVertex2i(startx, starty); + glVertex2i(startx + oldwid, starty); + glVertex2i(startx + oldwid, starty + oldht); + glVertex2i(startx, starty + oldht); + glEnd(); + } + + glIndexi(red); + glBegin(GL_LINE_LOOP); + glVertex2i(startx, starty); + glVertex2i(startx + wid, starty); + glVertex2i(startx + wid, starty + ht); + glVertex2i(startx, starty + ht); + glEnd(); + + oldwid = wid; + oldht = ht; + + glFlush(); +} + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + if (overlaySupport) { + glutUseLayer(GLUT_OVERLAY); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, wid, 0, ht); /* 1 to 1 with window */ + glMatrixMode(GL_MODELVIEW); + glViewport(0, 0, wid, ht); + } + + glutUseLayer(GLUT_NORMAL); + glViewport((GLint) (-wid * .1), (GLint) (-ht * .1), + (GLuint) (wid * 1.2), (GLuint) (ht * 1.2)); + + winWidth = wid; + winHeight = ht; + + sx = 2 * FRUSTDIM / (winWidth * 1.2); + sy = 2 * FRUSTDIM / (winHeight * 1.2); +} + +void +mouse(int button, int state, int x, int y) +{ + y = winHeight - y; /* flip y orientation */ + if (state == GLUT_DOWN) + switch (button) { + case GLUT_LEFT_BUTTON: /* select an image */ + startx = x; + starty = y; + wid = 0; + ht = 0; + rubberbandmode = GL_TRUE; + if (overlaySupport) glutShowOverlay(); + break; + case GLUT_MIDDLE_BUTTON: + glutUseLayer(GLUT_NORMAL); + if (color && depth) { + drawmode = GL_TRUE; + setRasterPosXY(x, y); + } + break; + case GLUT_RIGHT_BUTTON: /* change depth */ + glutUseLayer(GLUT_NORMAL); + if (color && depth) { + depthmode = GL_TRUE; + setRasterPosZ(y); + } + break; + } else /* GLUT_UP */ + switch (button) { + case GLUT_LEFT_BUTTON: + rubberbandmode = GL_FALSE; + if (overlaySupport) glutHideOverlay(); + wid = x - startx; + ht = y - starty; + if (wid < 0) { + wid = -wid; + startx = x; + } + if (ht < 0) { + ht = -ht; + starty = y; + } + color = (GLfloat *) realloc(color, wid * ht * 3 * sizeof(GLfloat)); + depth = (GLfloat *) realloc(depth, wid * ht * sizeof(GLfloat)); + + glutUseLayer(GLUT_NORMAL); + glReadPixels(startx, starty, wid, ht, GL_RGB, GL_FLOAT, color); + glReadPixels(startx, starty, wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT, + depth); + break; + case GLUT_MIDDLE_BUTTON: + drawmode = GL_FALSE; + break; + case GLUT_RIGHT_BUTTON: /* change depth */ + depthmode = GL_FALSE; + break; + } +} + +/* Called when window needs to be redrawn */ +void +redraw(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = + {1.f, 1.f, 1.f, 1.f}; + + glutUseLayer(GLUT_NORMAL); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + /* Note: wall verticies are ordered so they are all front facing this lets + me do back face culling to speed things up. */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* Since we want to turn texturing on for floor only, we have to make floor + a separate glBegin()/glEnd() sequence. You can't turn texturing on and + off between begin and end calls */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f(100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f(100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f(100.f, -100.f, -320.f); + glVertex3f(100.f, 100.f, -320.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(100.f, -100.f, -520.f); + glVertex3f(100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(-80.f, -80.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-20.f, -100.f, -500.f); + glCallList(CONE); + glPopMatrix(); + + if (stencil) { + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glPixelTransferf(GL_DEPTH_BIAS, depthbias); + + glDrawPixels(wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT, depth); + + glPixelTransferf(GL_DEPTH_BIAS, 0.f); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glStencilFunc(GL_EQUAL, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDisable(GL_DEPTH_TEST); + + glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + } else + glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color); + + glutSwapBuffers(); +} + +const int TEXDIM = 256; + +/* Parse arguments, and set up interface between OpenGL and window system */ +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = + {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = + {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = + {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *obj; + + glutInit(&argc, argv); + glutInitWindowSize(WINDIM, WINDIM); + + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE); + (void) glutCreateWindow("compositing images with depth"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutReshapeFunc(reshape); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + obj = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(obj, 20.f, 20, 20); + glEndList(); + + glNewList(CONE, GL_COMPILE); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(obj, GLU_INSIDE); + gluDisk(obj, 0., 20., 20, 1); + gluQuadricOrientation(obj, GLU_OUTSIDE); + gluCylinder(obj, 20., 0., 60., 20, 20); + glEndList(); + + gluDeleteQuadric(obj); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + /* storage for saved image */ + color = 0; + depth = 0; + + glReadBuffer(GL_FRONT); /* so glReadPixel() always get the right image */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX); + if (glutLayerGet(GLUT_OVERLAY_POSSIBLE)) { + glutEstablishOverlay(); + glutHideOverlay(); + transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX); + glClearIndex(transparent); + red = (transparent + 1) % glutGet(GLUT_WINDOW_COLORMAP_SIZE); + glutSetColor(red, 1.0, 0.0, 0.0); /* Red. */ + glutOverlayDisplayFunc(overlay); + overlaySupport = 1; + } else { + printf("Running without overlay rubber banding support.\n"); + } + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced/zcomposite.dsp b/lib/glut-3.7.6/progs/advanced/zcomposite.dsp new file mode 100644 index 0000000000..f034111046 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced/zcomposite.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="zcomposite" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=zcomposite - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zcomposite.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zcomposite.mak" CFG="zcomposite - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zcomposite - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "zcomposite - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "zcomposite - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "zcomposite - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "zcomposite - Win32 Release" +# Name "zcomposite - Win32 Debug" +# Begin Source File + +SOURCE=.\zcomposite.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97.dsw b/lib/glut-3.7.6/progs/advanced97.dsw new file mode 100644 index 0000000000..c9bcfffdb5 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97.dsw @@ -0,0 +1,779 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "_all"=".\advanced97\_all.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name accconvolve + End Project Dependency + Begin Project Dependency + Project_Dep_Name accumaa + End Project Dependency + Begin Project Dependency + Project_Dep_Name alphablend + End Project Dependency + Begin Project Dependency + Project_Dep_Name alphablendnosort + End Project Dependency + Begin Project Dependency + Project_Dep_Name billboard + End Project Dependency + Begin Project Dependency + Project_Dep_Name bubble + End Project Dependency + Begin Project Dependency + Project_Dep_Name bump + End Project Dependency + Begin Project Dependency + Project_Dep_Name chromakey + End Project Dependency + Begin Project Dependency + Project_Dep_Name chromakey_fancy + End Project Dependency + Begin Project Dependency + Project_Dep_Name cloud + End Project Dependency + Begin Project Dependency + Project_Dep_Name cloudl + End Project Dependency + Begin Project Dependency + Project_Dep_Name complexity + End Project Dependency + Begin Project Dependency + Project_Dep_Name csg + End Project Dependency + Begin Project Dependency + Project_Dep_Name decal + End Project Dependency + Begin Project Dependency + Project_Dep_Name dissolve + End Project Dependency + Begin Project Dependency + Project_Dep_Name explode + End Project Dependency + Begin Project Dependency + Project_Dep_Name fire + End Project Dependency + Begin Project Dependency + Project_Dep_Name genspheremap + End Project Dependency + Begin Project Dependency + Project_Dep_Name highlight + End Project Dependency + Begin Project Dependency + Project_Dep_Name interp + End Project Dependency + Begin Project Dependency + Project_Dep_Name lightmap + End Project Dependency + Begin Project Dependency + Project_Dep_Name lightp + End Project Dependency + Begin Project Dependency + Project_Dep_Name line + End Project Dependency + Begin Project Dependency + Project_Dep_Name multiaccumaa + End Project Dependency + Begin Project Dependency + Project_Dep_Name multialphablend + End Project Dependency + Begin Project Dependency + Project_Dep_Name multialphablendnosort + End Project Dependency + Begin Project Dependency + Project_Dep_Name multimirror + End Project Dependency + Begin Project Dependency + Project_Dep_Name multiscreendoor + End Project Dependency + Begin Project Dependency + Project_Dep_Name multispheremap + End Project Dependency + Begin Project Dependency + Project_Dep_Name noise + End Project Dependency + Begin Project Dependency + Project_Dep_Name nthsurfdemo + End Project Dependency + Begin Project Dependency + Project_Dep_Name paint + End Project Dependency + Begin Project Dependency + Project_Dep_Name projtex + End Project Dependency + Begin Project Dependency + Project_Dep_Name sbias + End Project Dependency + Begin Project Dependency + Project_Dep_Name screendoor + End Project Dependency + Begin Project Dependency + Project_Dep_Name smoke + End Project Dependency + Begin Project Dependency + Project_Dep_Name softshadow2 + End Project Dependency + Begin Project Dependency + Project_Dep_Name spectral + End Project Dependency + Begin Project Dependency + Project_Dep_Name tess + End Project Dependency + Begin Project Dependency + Project_Dep_Name usespheremap + End Project Dependency + Begin Project Dependency + Project_Dep_Name vapor + End Project Dependency + Begin Project Dependency + Project_Dep_Name volume + End Project Dependency + Begin Project Dependency + Project_Dep_Name warp + End Project Dependency + Begin Project Dependency + Project_Dep_Name water + End Project Dependency + Begin Project Dependency + Project_Dep_Name zcomposite + End Project Dependency + Begin Project Dependency + Project_Dep_Name texmovie + End Project Dependency + Begin Project Dependency + Project_Dep_Name texpage + End Project Dependency + Begin Project Dependency + Project_Dep_Name textile + End Project Dependency + Begin Project Dependency + Project_Dep_Name underwater + End Project Dependency + Begin Project Dependency + Project_Dep_Name texgen + End Project Dependency +}}} + +############################################################################### + +Project: "accconvolve"=".\advanced97\accconvolve.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "accumaa"=".\advanced97\accumaa.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alphablend"=".\advanced97\alphablend.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alphablendnosort"=".\advanced97\alphablendnosort.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "billboard"=".\advanced97\billboard.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bubble"=".\advanced97\bubble.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bump"=".\advanced97\bump.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "chromakey"=".\advanced97\chromakey.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "chromakey_fancy"=".\advanced97\chromakey_fancy.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "cloud"=".\advanced97\cloud.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "cloudl"=".\advanced97\cloudl.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "complexity"=".\advanced97\complexity.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "csg"=".\advanced97\csg.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "decal"=".\advanced97\decal.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "dissolve"=".\advanced97\dissolve.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "explode"=".\advanced97\explode.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "fire"=".\advanced97\fire.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "genspheremap"=".\advanced97\genspheremap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "highlight"=".\advanced97\highlight.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "interp"=".\advanced97\interp.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lightmap"=".\advanced97\lightmap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lightp"=".\advanced97\lightp.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "line"=".\advanced97\line.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multiaccumaa"=".\advanced97\multiaccumaa.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multialphablend"=".\advanced97\multialphablend.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multialphablendnosort"=".\advanced97\multialphablendnosort.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multimirror"=".\advanced97\multimirror.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multiscreendoor"=".\advanced97\multiscreendoor.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multispheremap"=".\advanced97\multispheremap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "noise"=".\advanced97\noise.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "nthsurfdemo"=".\advanced97\nthsurfdemo.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "paint"=".\advanced97\paint.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "projtex"=".\advanced97\projtex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sbias"=".\advanced97\sbias.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "screendoor"=".\advanced97\screendoor.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "smoke"=".\advanced97\smoke.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "softshadow2"=".\advanced97\softshadow2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "spectral"=".\advanced97\spectral.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tess"=".\advanced97\tess.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "texgen"=".\advanced97\texgen.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "texmovie"=".\advanced97\texmovie.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "texpage"=".\advanced97\texpage.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "textile"=".\advanced97\textile.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "underwater"=".\advanced97\underwater.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "usespheremap"=".\advanced97\usespheremap.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "vapor"=".\advanced97\vapor.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "volume"=".\advanced97\volume.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "warp"=".\advanced97\warp.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "water"=".\advanced97\water.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zcomposite"=".\advanced97\zcomposite.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/progs/advanced97/Imakefile b/lib/glut-3.7.6/progs/advanced97/Imakefile new file mode 100644 index 0000000000..694bdd4d5e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/Imakefile @@ -0,0 +1,77 @@ + +/* Copyright (c) Mark J. Kilgard, 1998. */ + +#include "../../Glut.cf" + +TARGETS = accconvolve alphablend alphablendnosort billboard \ + bubble bump chromakey chromakey_fancy cloud cloudl complexity csg decal dissolve \ + explode fire genspheremap highlight interp lightmap lightp line \ + multiaccumaa multialphablend multialphablendnosort multimirror \ + multiscreendoor multispheremap noise nthsurfdemo paint projtex sbias \ + screendoor smoke softshadow2 spectral tess texgen texmovie texpage \ + textile underwater usespheremap vapor volume warp water zcomposite + +SRCS = accconvolve.c accumaa.c alphablend.c alphablendnosort.c \ + billboard.c bubble.c bump.c chromakey.c chromakey_fancy.c cloud.c \ + cloudl.c complexity.c csg.c d.c decal.c dissolve.c explode.c fire.c genspheremap.c \ + highlight.c interp.c lightmap.c lightp.c line.c multiaccumaa.c \ + multialphablend.c multialphablendnosort.c multimirror.c \ + multiscreendoor.c multispheremap.c noise.c nthsurfdemo.c paint.c \ + projtex.c sbias.c screendoor.c sm.c smoke.c softshadow2.c spectral.c \ + sphere.c tess.c texgen.c texmovie.c texpage.c textile.c texture.c \ + underwater.c usespheremap.c vapor.c volume.c warp.c water.c \ + zcomposite.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(accconvolve,accconvolve.o texture.o) +SimpleGlutProgramTarget(alphablend) +SimpleGlutProgramTarget(alphablendnosort) +NormalGlutProgramTarget(billboard,billboard.o texture.o) +NormalGlutProgramTarget(bubble,bubble.o texture.o) +NormalGlutProgramTarget(bump,bump.o texture.o) +NormalGlutProgramTarget(chromakey,chromakey.o texture.o) +NormalGlutProgramTarget(chromakey_fancy,chromakey_fancy.o texture.o) +NormalGlutProgramTarget(cloud,cloud.o texture.o) +NormalGlutProgramTarget(cloudl,cloudl.o texture.o) +SimpleGlutProgramTarget(complexity) +SimpleGlutProgramTarget(csg) +SimpleGlutProgramTarget(decal) +SimpleGlutProgramTarget(dissolve) +NormalGlutProgramTarget(explode,explode.o texture.o) +NormalGlutProgramTarget(fire,fire.o texture.o sm.o d.o) +NormalGlutProgramTarget(genspheremap,genspheremap.o texture.o) +NormalGlutProgramTarget(highlight,highlight.o texture.o) +NormalGlutProgramTarget(interp,interp.o texture.o) +NormalGlutProgramTarget(lightmap,lightmap.o texture.o) +NormalGlutProgramTarget(lightp,lightp.o texture.o) +SimpleGlutProgramTarget(line) +SimpleGlutProgramTarget(multiaccumaa) +SimpleGlutProgramTarget(multialphablend) +SimpleGlutProgramTarget(multialphablendnosort) +SimpleGlutProgramTarget(multimirror) +SimpleGlutProgramTarget(multiscreendoor) +NormalGlutProgramTarget(multispheremap,multispheremap.o texture.o) +SimpleGlutProgramTarget(noise) +SimpleGlutProgramTarget(nthsurfdemo) +NormalGlutProgramTarget(paint,paint.o texture.o) +NormalGlutProgramTarget(projtex,projtex.o texture.o) +NormalGlutProgramTarget(sbias,sbias.o texture.o) +SimpleGlutProgramTarget(screendoor) +NormalGlutProgramTarget(smoke,smoke.o texture.o) +SimpleGlutProgramTarget(softshadow2) +SimpleGlutProgramTarget(spectral) +NormalGlutProgramTarget(tess,tess.o sphere.o) +SimpleGlutProgramTarget(texgen) +NormalGlutProgramTarget(texmovie,texmovie.o texture.o) +NormalGlutProgramTarget(texpage,texpage.o texture.o) +NormalGlutProgramTarget(textile,textile.o texture.o) +NormalGlutProgramTarget(underwater,underwater.o texture.o) +NormalGlutProgramTarget(usespheremap,usespheremap.o texture.o) +NormalGlutProgramTarget(vapor,vapor.o texture.o) +NormalGlutProgramTarget(volume,volume.o texture.o) +NormalGlutProgramTarget(warp,warp.o texture.o) +NormalGlutProgramTarget(water,water.o texture.o) +SimpleGlutProgramTarget(zcomposite) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/advanced97/_all.dsp b/lib/glut-3.7.6/progs/advanced97/_all.dsp new file mode 100644 index 0000000000..6a4421548c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "_all___Win32_Debug" +# PROP BASE Intermediate_Dir "_all___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/accconvolve.c b/lib/glut-3.7.6/progs/advanced97/accconvolve.c new file mode 100644 index 0000000000..528d037d08 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/accconvolve.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +static char defaultFile[] = "../data/mandrill.rgb"; +GLuint *img; +GLsizei w, h; +GLint comp; + +GLfloat kernScale; + +/* a few filters... */ +GLfloat horizontalEdge3x3[] = { + -1, -1, -1, + 2, 2, 2, + -1, -1, -1, +}; + +GLfloat verticalEdge3x3[] = { + -1, 2, -1, + -1, 2, -1, + -1, 2, -1, +}; + +GLfloat allEdge3x3[] = { + -2, 1, -2, + 1, 4, 1, + -2, 1, -2, +}; + +GLfloat smooth3x3[] = { + 1, 2, 1, + 2, 4, 2, + 1, 2, 1, +}; + +GLfloat highpass3x3[] = { + -1, -1, -1, + -1, 9, -1, + -1, -1, -1, +}; + +GLfloat laplacian5x5[] = { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 24, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, +}; + +GLfloat box3x3[] = { + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, +}; + +GLfloat box5x5[] = { + 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, +}; + +struct Kernel { + const char *name; + GLfloat *kern; + GLsizei w, h; +} filters[] = { + {"horizontal edge detect", horizontalEdge3x3, 3, 3}, + {"vertical edge detect", verticalEdge3x3, 3, 3}, + {"all edge detect", allEdge3x3, 3, 3}, + {"3x3 smooth", smooth3x3, 3, 3}, + {"3x3 highpass", highpass3x3, 3, 3}, + {"5x5 laplacian", laplacian5x5, 5, 5}, + {"3x3 box", box3x3, 3, 3}, + {"5x5 box", box5x5, 5, 5}, +}; +struct Kernel *kern; + +void kern_normalize(void) +{ + GLfloat total, scale, *k; + int i; + + k = kern->kern; + total = 0; + for (i = 0; i < kern->w*kern->h; i++) { + total += *k++; + } + + if (!total) { + /* kernel sums to 0... */ + return; + } else { + scale = 1. / total; + k = kern->kern; + for (i = 0; i < kern->w * kern->h; i++) { + *k *= scale; + k++; + } + } +} + +GLfloat acc_kern_scale(void) +{ + GLfloat minPossible = 0, maxPossible = 1; + GLfloat *k; + int i; + + k = kern->kern; + for (i = 0; i < kern->w*kern->h; i++) { + if (*k < 0) { + minPossible += *k; + } else { + maxPossible += *k; + } + k++; + } + + return(1. / ((-minPossible > maxPossible) ? -minPossible : maxPossible)); +} + +void init(void) +{ + kern = &filters[4]; + kern_normalize(); + kernScale = acc_kern_scale(); +} + +void load_img(const char *fname) +{ + img = read_texture(fname, &w, &h, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, w, h); + glLoadIdentity(); + glOrtho(0, winW, 0, winH, 0, 5); +} + +void acc_convolve(void) +{ + int x, y; + + for (y = 0; y < kern->h; y++) { + for (x = 0; x < kern->w; x++) { + glRasterPos2i(0, 0); + glBitmap(0, 0, 0, 0, -x, -y, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img); + glAccum(GL_ACCUM, kern->kern[y*kern->w + x]*kernScale); + } + } + glAccum(GL_RETURN, 1./kernScale); +} + +void draw(void) +{ + GLenum err; + + glutSetCursor(GLUT_CURSOR_WAIT); + + glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + + acc_convolve(); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSetCursor(GLUT_CURSOR_INHERIT); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if (key == 27) exit(0); +} + +void menu(int val) +{ + kern = &filters[val]; + kern_normalize(); + kernScale= acc_kern_scale(); + draw(); +} + +main(int argc, char *argv[]) +{ + int i; + + glutInit(&argc, argv); + if (argc > 1) { + load_img(argv[1]); + } else { + load_img(defaultFile); + } + glutInitWindowSize(w, h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_ACCUM); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) { + glutAddMenuEntry(filters[i].name, i); + } + glutAttachMenu(GLUT_RIGHT_BUTTON); + + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/accconvolve.dsp b/lib/glut-3.7.6/progs/advanced97/accconvolve.dsp new file mode 100644 index 0000000000..24abc52754 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/accconvolve.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="accconvolve" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=accconvolve - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "accconvolve.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "accconvolve.mak" CFG="accconvolve - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "accconvolve - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "accconvolve - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "accconvolve - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "accconvolve - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "accconvolve - Win32 Release" +# Name "accconvolve - Win32 Debug" +# Begin Source File + +SOURCE=.\accconvolve.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/accumaa.c b/lib/glut-3.7.6/progs/advanced97/accumaa.c new file mode 100644 index 0000000000..ba1591ba31 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/accumaa.c @@ -0,0 +1,272 @@ +#include +#include +#include + +const GLdouble FRUSTDIM = 100.f; + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {SPHERE = 1, CONE}; + +void +render(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + + glPushMatrix(); + glTranslatef(-80.f, -60.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -500.f); + glCallList(CONE); + glPopMatrix(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + +/* compute scale factor for window->object space transform */ +/* could use gluUnProject(), but probably too much trouble */ +void +computescale(GLfloat *sx, GLfloat *sy) +{ + enum {XORG, YORG, WID, HT}; + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + *sx = 2 * FRUSTDIM/viewport[WID]; + *sy = 2 * FRUSTDIM/viewport[WID]; +} + +enum {NONE, AA}; + +int rendermode = NONE; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + int i, j; + int min, max; + int count; + GLfloat invx, invy; + GLfloat scale, dx, dy; + + switch(rendermode) { + case NONE: + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + break; + case AA: + min = -2; + max = -min + 1; + count = -2 * min + 1; + count *= count; + + /* uniform scaling, less than one pixel wide */ + scale = -.9f/min; + + computescale(&invx, &invy); + + glutSetCursor(GLUT_CURSOR_WAIT); + + glClear(GL_ACCUM_BUFFER_BIT); + + for(j = min; j < max; j++) { + for(i = min; i < max; i++) { + printf("pass %d of %d\n", + (j-min)*(max-min)+i-min+1,(max-min)*(max-min)); + dx = invx * scale * i; + dy = invy * scale * j; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM + dx, + FRUSTDIM + dy, + -FRUSTDIM + dx, + FRUSTDIM + dy, + 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + glAccum(GL_ACCUM, 1.f/count); + } + } + glAccum(GL_RETURN, 1.f); + glutSetCursor(GLUT_CURSOR_INHERIT); + break; + } + + glutSwapBuffers(); +} + +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); + (void)glutCreateWindow("Anti-aliasing with Accum"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + + glutCreateMenu(menu); + glutAddMenuEntry("Aliased View", NONE); + glutAddMenuEntry("AntiAliased", AA); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glReadBuffer(GL_BACK); /* input to accum buffer */ + + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/accumaa.dsp b/lib/glut-3.7.6/progs/advanced97/accumaa.dsp new file mode 100644 index 0000000000..af9f9cab29 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/accumaa.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="accumaa" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=accumaa - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "accumaa.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "accumaa.mak" CFG="accumaa - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "accumaa - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "accumaa - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "accumaa - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "accumaa - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "accumaa - Win32 Release" +# Name "accumaa - Win32 Debug" +# Begin Source File + +SOURCE=.\accumaa.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/alphablend.c b/lib/glut-3.7.6/progs/advanced97/alphablend.c new file mode 100644 index 0000000000..1fb6c2cad8 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/alphablend.c @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include + +GLUquadricObj *cone, *base, *qsphere; + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + gluQuadricOrientation(base, GLU_INSIDE); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluCylinder(cone, .3, 0, 1.25, 20, 1); + gluDisk(base, 0., .3, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(0, 0, .6); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME)/1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_room(); + draw_cone(); + + secs = get_secs(); + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + draw_sphere(secs * 360. / 10.); + glCullFace(GL_BACK); + draw_sphere(secs * 360. / 10.); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + if (key == 27) exit(0); + idle = (idle == 0); + if (idle) { + glutIdleFunc(draw); + } else { + glutIdleFunc(0); + } +} + +main(int argc, char *argv[]) +{ + glutInitWindowSize(512, 512); + glutInitWindowPosition(0, 0); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/alphablend.dsp b/lib/glut-3.7.6/progs/advanced97/alphablend.dsp new file mode 100644 index 0000000000..a72842f590 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/alphablend.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="alphablend" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=alphablend - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alphablend.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alphablend.mak" CFG="alphablend - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alphablend - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "alphablend - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alphablend - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "alphablend - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alphablend - Win32 Release" +# Name "alphablend - Win32 Debug" +# Begin Source File + +SOURCE=.\alphablend.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/alphablendnosort.c b/lib/glut-3.7.6/progs/advanced97/alphablendnosort.c new file mode 100644 index 0000000000..883dc6e8ef --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/alphablendnosort.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +GLUquadricObj *cone, *base, *qsphere; + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + gluQuadricOrientation(base, GLU_INSIDE); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluCylinder(cone, .3, 0, 1.25, 20, 1); + gluDisk(base, 0., .3, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(0, 0, .6); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_room(); + draw_cone(); + + glEnable(GL_BLEND); + secs = get_secs(); + draw_sphere(secs * 360. / 10.); + glDisable(GL_BLEND); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + if (key == 27) exit(0); + idle = (idle == 0); + if (idle) { + glutIdleFunc(draw); + } else { + glutIdleFunc(0); + } +} + +main(int argc, char *argv[]) +{ + glutInitWindowSize(512, 512); + glutInitWindowPosition(0, 0); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/alphablendnosort.dsp b/lib/glut-3.7.6/progs/advanced97/alphablendnosort.dsp new file mode 100644 index 0000000000..1d086ea450 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/alphablendnosort.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="alphablendnosort" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=alphablendnosort - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alphablendnosort.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alphablendnosort.mak" CFG="alphablendnosort - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alphablendnosort - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "alphablendnosort - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alphablendnosort - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "alphablendnosort - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alphablendnosort - Win32 Release" +# Name "alphablendnosort - Win32 Debug" +# Begin Source File + +SOURCE=.\alphablendnosort.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/billboard.c b/lib/glut-3.7.6/progs/advanced97/billboard.c new file mode 100644 index 0000000000..1f46ee3512 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/billboard.c @@ -0,0 +1,339 @@ +#include +#include +#include +#include "texture.h" +#include + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf sin +#define cosf cos +#define atan2f atan2 +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static int billboard = 1, texture = 1; +static float scale = 1.; +static float transx = 1.0, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(const int x, const int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(const int x, const int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void afunc(void) { + static int state; + if (state ^= 1) { + glAlphaFunc(GL_GREATER, .01); + glEnable(GL_ALPHA_TEST); + } else { + glDisable(GL_ALPHA_TEST); + } +} + +void demofunc(void) { + static float deltax = -.03; + static float deltay = 2.; + + transx += deltax; + if (transx > 2.0 || transx < -2.0) deltax = -deltax; + + rotx += deltay; + if (rotx > 360.f || rotx < 0.f) deltay = -deltay; + glutPostRedisplay(); +} + +void dfunc(void) { + static int demo; + if (demo ^= 1) { + glutIdleFunc(demofunc); + } else { + glutIdleFunc(0); + } +} + +void bfunc(void) { + static int state; + if (state ^= 1) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } else { + glDisable(GL_BLEND); + } +} + +void ffunc(void) { + billboard ^= 1; +} + +void tfunc(void) { + texture ^= 1; +} + +void up(void) { scale += .1; } +void down(void) { scale -= .1; } + +void help(void) { + printf("Usage: billboard [image]\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'d' - toggle demo mode\n"); + printf("'f' - toggle fixed mode\n"); + printf("'t' - toggle texturing\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(char *filename) { + static unsigned *image; + static int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 4) { + printf("must be an RGBA image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 256; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if ((i & 32) ^ (j & 32)) { + img[4*(i+j*width)+0] = 0xff; + img[4*(i+j*width)+1] = 0xff; + img[4*(i+j*width)+2] = 0xff; + } else { + img[4*(i+j*width)+0] = 0x0; + img[4*(i+j*width)+1] = 0x0; + img[4*(i+j*width)+2] = 0x0; + } + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + 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_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + glClearColor(.25f, .25f, .25f, .25f); + glEnable(GL_DEPTH_TEST); +} + +static void calcMatrix(void); + +void display(void) { +#if NATE + float mat[16]; +#endif + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); +#define RAD(x) (((x)*M_PI)/180.) + gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.); + +#if NATE + glGetFloatv(GL_MODELVIEW_MATRIX, mat); +#endif + /* floor */ + glDisable(GL_TEXTURE_2D); + glColor4f(0.2, 0.8, 0.2, 1.); + glBegin(GL_POLYGON); + glVertex3f(-2.0, -1.0, -2.0); + glVertex3f( 2.0, -1.0, -2.0); + glVertex3f( 2.0, -1.0, 2.0); + glVertex3f(-2.0, -1.0, 2.0); + glEnd(); + + glPushMatrix(); +#if 0 + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); +#endif + glTranslatef(0.f, 0.f, -transx); + if (billboard) calcMatrix(); + glScalef(scale,scale,1.); + if (texture) glEnable(GL_TEXTURE_2D); + glColor4f(1.f, 1.f, 1.f, 1.f); + 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(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'a': afunc(); break; + case 'd': dfunc(); break; + case 'b': bfunc(); break; + case 'f': ffunc(); break; + case 't': tfunc(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow("billboard"); + init(argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} + +void +buildRot(float theta, float x, float y, float z, float m[16]) { + float d = x*x + y*y + z*z; + float ct = cosf(RAD(theta)), st = sinf(RAD(theta)); + + /* normalize */ + if (d > 0) { + d = 1/d; + x *= d; + y *= d; + z *= d; + } + + m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; + m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; + m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; + m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; + + /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S + * + * S = 0 -z y u' = (x, y, z) + * z 0 -x + * -y x 0 + */ + + m[0] = x*x + ct*(1-x*x) + st*0; + m[4] = x*y + ct*(0-x*y) + st*-z; + m[8] = x*z + ct*(0-x*z) + st*y; + + m[1] = y*x + ct*(0-y*x) + st*z; + m[5] = y*y + ct*(1-y*y) + st*0; + m[9] = y*z + ct*(0-y*z) + st*-x; + + m[2] = z*x + ct*(0-z*x) + st*-y; + m[6] = z*y + ct*(0-z*y) + st*x; + m[10]= z*z + ct*(1-z*z) + st*0; +} + +static void +calcMatrix(void) { + float mat[16]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat); + glMultMatrixf(mat); +} diff --git a/lib/glut-3.7.6/progs/advanced97/billboard.dsp b/lib/glut-3.7.6/progs/advanced97/billboard.dsp new file mode 100644 index 0000000000..cf025d1e7a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/billboard.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="billboard" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=billboard - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "billboard.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "billboard.mak" CFG="billboard - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "billboard - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "billboard - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "billboard - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "billboard - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "billboard - Win32 Release" +# Name "billboard - Win32 Debug" +# Begin Source File + +SOURCE=.\billboard.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/bubble.c b/lib/glut-3.7.6/progs/advanced97/bubble.c new file mode 100644 index 0000000000..8665c2ca28 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/bubble.c @@ -0,0 +1,450 @@ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf(x) ((float)sin((x))) +#define cosf(x) ((float)cos((x))) +#endif + +static float transp = .5f; +static int normals; +static float phase = .05; +static int tess = 10; +static float freq = 10.f, scale = .03; +static float transx = 1.0, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(const int x, const int y) { + transx += (x-ox)/5.; + transy -= (y-oy)/5.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(const int x, const int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void init(char *fname) { + int width, height, components; + GLubyte *image; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + + if (!(image = (GLubyte *)read_texture(fname, &width, &height, &components))) { + perror(fname); + exit(EXIT_FAILURE); + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + 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_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); + glFrontFace(GL_CW); + glCullFace(GL_BACK); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); +#if 1 + glMaterialf (GL_FRONT, GL_SHININESS, 64.0); + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + { + GLfloat pos[4] = { 0, 0, 1, 1}; + glLightfv(GL_LIGHT0, GL_POSITION, pos); + } +#endif + { int e; if (e = glGetError()) printf("error %x\n", e); } + +#if 0 + glClearColor(.2,.2f,.58f,1.f); +#endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable(GL_BLEND); +} + +#if 0 +cube(void) { + glBegin(GL_QUAD_STRIP); + glVertex3f(-1.,-1.,-1.); + glVertex3f(-1., 1.,-1.); + glVertex3f( 1.,-1.,-1.); + glVertex3f( 1., 1.,-1.); + glVertex3f(-1.,-1.,-1.); + glVertex3f(-1.,-1.,-1.); + glVertex3f(-1.,-1.,-1.); + glEnd(); +} +#endif + +/* + * bilinear (longitude/lattitude) tesselation + * x = cos(theta)*cos(phi) + * y = sin(phi) + * z = sin(theta)*cos(phi) + */ + +float *normalize(float *v) { + static float vv[3]; + float len; + + len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; + vv[0] = v[0]/len; vv[1] = v[1]/len; vv[2] = v[2]/len; + return vv; +} + +void +bubble(float rad) { + float v[3],s; + float phi, mod; + static float off; + int i, j; +#define N tess + off += phase; +#if 0 + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif +#if 1 + /* top cap */ + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.f, 1.f, 0.f); + glVertex3f(0.f, 1.f, 0.f); + v[1] = rad*sinf(phi = M_PI*(N+2)/(2*N)); + mod = 1+scale*sinf(freq*v[1]+off); + s = cosf(phi)*rad*mod; + for(i = 0; i <= 2*N; i++) { + v[0] = s*cosf((M_PI/N)*i); + v[2] = s*sinf((M_PI/N)*i); + glNormal3fv(v); + glVertex3fv(v); + } + glEnd(); +#endif +#if 1 + for(i = 1; i < N-1; i++) { + float v0[3], v1[3], s0, s1; + v0[1] = rad*sinf(phi=M_PI/2+M_PI/N*i); s0 = rad*cosf(phi); + mod = mod = 1+scale*sin(freq*v0[1]+off); s0 *= mod; + v1[1] = rad*sinf(phi=M_PI/2+M_PI/N*(i+1)); s1 = rad*cosf(phi); + mod = mod = 1+scale*sin(freq*v1[1]+off); s1 *= mod; + glBegin(GL_TRIANGLE_STRIP); + for(j = 0; j <= 2*N; j++) { + float x, z; + v0[0] = s0*(x = sinf(M_PI/N*j)); + v0[2] = s0*(z = cosf(M_PI/N*j)); + v1[0] = s1*x; v1[2] = s1*z; + glNormal3fv(normalize(v1)); + glVertex3fv(v1); + glNormal3fv(normalize(v0)); + glVertex3fv(v0); + } + glEnd(); +#if 1 + if (normals) { + float nscale = 1.2; + /*glDisable(GL_LIGHTING);*/ + glBegin(GL_LINES); + /*glColor3f(1.f, 1.f, 0.f);*/ + for(j = 0; j <= 2*N; j++) { + GLfloat x[3], x1, z1, *vv; + v0[0] = s0*(x1 = sinf(M_PI/N*j)); + v0[2] = s0*(z1 = cosf(M_PI/N*j)); + glVertex3fv(vv = normalize(v0)); + x[0] = nscale*vv[0]; x[1] = nscale*vv[1]; x[2] = nscale*vv[2]; + glVertex3fv(x); + + v1[0] = s1*x1; v1[2] = s1*z1; + glVertex3fv(vv = normalize(v1)); + x[0] = nscale*vv[0]; x[1] = nscale*vv[1]; x[2] = nscale*vv[2]; + glVertex3fv(x); + } + glEnd(); + /*glEnable(GL_LIGHTING);*/ + } +#endif + } +#endif +#if 1 + /* bottom cap */ + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(0.f, -1.f, 0.f); + v[1] = -rad*sinf(phi=M_PI*(N+2)/(2*N)); + mod = 1+scale*sin(freq*v[1]+off); + s = cosf(phi)*rad*mod; + for(i = 2*N; i >= 0; --i) { + v[0] = s*cosf((M_PI/N)*i); + v[2] = s*sinf((M_PI/N)*i); + glNormal3fv(v); + glVertex3fv(v); + } + glEnd(); +#endif +} + +void display(void) { +#if 0 + static float phase; +#endif + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +#if 0 + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + s = sinf(phase); t = s; phase += M_PI/25.f; + if (phase > 2*M_PI) phase -= 2*M_PI; + glTranslatef(.5f, -0.5f, 0.f); + glScalef(.1f, .1f, 1.f); + glTranslatef(s, t, 0.f); + glMatrixMode(GL_MODELVIEW); +#endif + + glPushMatrix(); + glTranslatef(0., 0., -100.+transx); + glRotatef(roty, 1.0, 0.0, 0.0); + glScalef(10.f, 10.f, 10.f); + glColor4f(1.f,1.f,1.f,transp); + bubble(1.0f); + glPopMatrix (); +#if 0 + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +#endif + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#if 0 + if (w <= h) + glOrtho (-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, + 3.5*(GLfloat)h/(GLfloat)w, -3.5, 10.5); + else + glOrtho (-3.5*(GLfloat)w/(GLfloat)h, + 3.5*(GLfloat)w/(GLfloat)h, -3.5, 3.5, -3.5, 10.5); +#endif + gluPerspective(40., 1.0, 10.0, 200000.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void ffunc(void) { + static int state = 1; + if (state ^= 1) + glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); + else + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void tfunc(void) { + static int state = 1; + if (state ^= 1) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); +} + +void lfunc(void) { + static int state = 1; + if (state ^= 1) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); +} + +void bfunc(void) { + static int state = 1; + if (state ^= 1) { + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } else { + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } +} + +void cfunc(void) { + static int state = 1; + if (state ^= 1) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + +void wfunc(void) { + static int state; + glPolygonMode(GL_FRONT_AND_BACK, (state ^= 1) ? GL_LINE : GL_FILL); +} + +void ufunc(void) { + tess *= 2; + if (tess > 160) tess = 160; +} +void Ufunc(void) { + tess /= 2; + if (tess < 10) tess = 10; +} + +void pfunc(void) { + phase += .01; +} + +void Pfunc(void) { + phase -= .01; +} + +void nfunc(void) { + normals ^= 1; +} + +void xfunc(void) { + transp += .1; +} + +void Xfunc(void) { + transp -= .1; +} + +void yfunc(void) { + static int state; + if (state ^= 1) + /*glClearColor(.2,.2f,.58f,0.f);*/ + glClearColor(.0,.0f,.65,0.f); + else + glClearColor(0.f, 0.f, 0.f, 0.f); +} + +void up(void) { + scale += .01f; +} +void down(void) { + scale -= .01f; +} +void left(void) { + freq -= 1.f; +} +void right(void) { + freq += 1.f; +} + +/*ARGSUSED1*/ +void key (unsigned char key, int x, int y) { + switch (key) { + case 'b': bfunc(); break; + case 'c': cfunc(); break; + case 'l': lfunc(); break; + case 't': tfunc(); break; + case 'f': ffunc(); break; + case 'n': nfunc(); break; + case 'u': ufunc(); break; + case 'U': Ufunc(); break; + case 'p': pfunc(); break; + case 'P': Pfunc(); break; + case 'w': wfunc(); break; + case 'x': xfunc(); break; + case 'X': Xfunc(); break; + case 'y': yfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } +} + +void animate(void) { + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(100, 100); + glutCreateWindow (argv[0]); + init(argc > 1 ? argv[1] : "../data/spheremap.rgb"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(animate); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/bubble.dsp b/lib/glut-3.7.6/progs/advanced97/bubble.dsp new file mode 100644 index 0000000000..eff920522d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/bubble.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="bubble" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=bubble - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bubble.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bubble.mak" CFG="bubble - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bubble - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bubble - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bubble - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "bubble - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bubble - Win32 Release" +# Name "bubble - Win32 Debug" +# Begin Source File + +SOURCE=.\bubble.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/bump.c b/lib/glut-3.7.6/progs/advanced97/bump.c new file mode 100644 index 0000000000..8684f713ed --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/bump.c @@ -0,0 +1,879 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define sqrtf(x) (float)sqrt((x)) +#define cosf(x) (float)cos((x)) +#define sinf(x) (float)sin((x)) +#endif + +#ifdef GL_EXT_blend_subtract +#if defined(_WIN32) && !defined(MESA) +#include +PFNGLBLENDEQUATIONEXTPROC glBlendEquationEXT = NULL; +#endif +static int hasBlendSubtract = 0; +#else +static const int hasBlendSubtract = 0; +#endif + +int winWidth = 512; +int winHeight = 512; + +#ifndef FALSE +enum {FALSE, TRUE}; +#endif +enum {S, T}; /* make array indexing more intuitive */ +enum {X, Y, Z, W}; +enum {R, G, B, A}; +enum {DEFAULT_TEX, ACCUM_TEX, ADD_TEX, SUB_TEX}; /* texture names */ +enum {LIGHT_XY, LIGHT_Z, PGON}; /* what should move */ + +int dblbuf = TRUE; +int accum = FALSE; +int color = FALSE; +int wire = FALSE; +int textureOnly = FALSE; +int lightOnly = FALSE; +int bindtex = FALSE; +int embossed = FALSE; +int steps_xz = 20, steps_y = 20; + +int texture_width; +int texture_height; + +/* is bumpmap shifting on? */ +int bumpEnabled = FALSE; + +int move = LIGHT_XY; + +/* current tangent vector */ +GLfloat curTangent[3]; + +/* current texture coordinate */ +GLfloat curTex[2]; + + +/* current normal */ +GLfloat curNormal[3]; + +/* current light position */ +GLfloat curLight[3]; +GLfloat lightpos[4] = {100.f, 100.f, 100.f, 1.f}; +GLfloat angles[2]; /* x and y angle */ + +unsigned *bumptex; /* pointer to bumpmap texture */ +GLfloat bumpscale = .39f; /* scale down bumpmap texture (a smidgen under .4) */ + +/* TEST PROGRAM */ + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +#define CHECK_ERROR(str) \ +{ \ + GLenum error; \ + if(error = glGetError()) \ + printf("GL Error: %s (%s)\n", gluErrorString(error), str); \ +} + +void +bumpEnable(void) +{ + bumpEnabled = TRUE; +} + +void +bumpDisable(void) +{ + bumpEnabled = FALSE; +} + +void +reshape(int wid, int ht) +{ + winWidth = wid; + winHeight = ht; + glViewport(0, 0, wid, ht); +} + + + +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* move the light */ + move = LIGHT_XY; + lightpos[X] = (x - winWidth/2) * 300.f/winWidth; + lightpos[Y] = (winHeight/2 - y) * 300.f/winHeight; + glutPostRedisplay(); + break; + case GLUT_MIDDLE_BUTTON: + move = PGON; + angles[X] = (x - winWidth/2) * 180.f/winWidth; + angles[Y] = (y - winHeight/2) * 180.f/winHeight; + glutPostRedisplay(); + break; + case GLUT_RIGHT_BUTTON: /* move the polygon */ + move = LIGHT_Z; + lightpos[Z] = (winHeight/2 - y) * 300.f/winWidth; + glutPostRedisplay(); + break; + } +} + +void +motion(int x, int y) +{ + switch(move) + { + case LIGHT_XY: + lightpos[X] = (x - winWidth/2) * 300.f/winWidth; + lightpos[Y] = (winHeight/2 - y) * 300.f/winHeight; + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glutPostRedisplay(); + break; + case LIGHT_Z: + lightpos[Z] = (winHeight/2 - y) * 300.f/winWidth; + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glutPostRedisplay(); + break; + case PGON: + angles[X] = (x - winWidth/2) * 180.f/winWidth; + angles[Y] = (y - winHeight/2) * 180.f/winHeight; + glutPostRedisplay(); + break; + } +} + + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + GLfloat *texture; + + /* assumed format; LUMINANCE */ + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 3) & 0x1) ^ ((t >> 3) & 0x1); + } + } + return texture; +} + +/* get current light position in object space */ +void +bumpLightPos(GLfloat *x, GLfloat *y, GLfloat *z) +{ + GLdouble mvmatrix[16]; + GLint viewport[4]; + static GLdouble projmatrix[16]; /* to make them zero */ + GLfloat light[4]; + GLdouble Ex, Ey, Ez; + GLdouble Ox, Oy, Oz; + + CHECK_ERROR("bumpLightPos"); + glGetLightfv(GL_LIGHT0, GL_POSITION, light); + Ex = light[X]; Ey = light[Y]; Ez = (light[Z] + 1)/2.; + + CHECK_ERROR("bumpLightPos"); + glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); + + /* identity projection matrix */ + projmatrix[0] = projmatrix[5] = projmatrix[10] = projmatrix[15] = 1.; + + /* identity viewport */ + viewport[0] = viewport[1] = -1; + viewport[2] = viewport[3] = 2; + + /* + ** use the inverse of the modelview matrix to + ** transform light from eye to object space + */ + gluUnProject(Ex, Ey, Ez, mvmatrix, projmatrix, viewport, &Ox, &Oy, &Oz); + + *x = Ox; *y = Oy; *z = Oz; + CHECK_ERROR("bumpLightPos"); +} + + +/* compute binormal from current normal and tangent vector, using cross prod */ +/* assuming normal and tangent are already normalized */ +void +biNormal(GLfloat *x, GLfloat *y, GLfloat *z) +{ + /* normal tangent = binormal */ + + *x = curNormal[Y] * curTangent[Z] - curNormal[Z] * curTangent[Y]; + *y = curNormal[Z] * curTangent[X] - curNormal[X] * curTangent[Z]; + *z = curNormal[X] * curTangent[Y] - curNormal[Y] * curTangent[X]; +} + +void +Normalize2f(GLfloat *x, GLfloat *y) +{ + GLfloat len; + len = *x * *x + *y * *y; + len = sqrtf(len); + + *x /= len; + *y /= len; +} + +/* rotate point by supplied rotatation matrix */ +void +Rotate(GLfloat *rot, GLfloat *light, GLfloat *s, GLfloat *t) +{ + GLfloat r; + r = rot[3] * light[X] + rot[4] * light[Y] + rot[5] * light[Z]; + if(r < 0.f) /* light below surface */ + { + *s = 0.f; + *t = 0.f; + return; + } + *s = rot[0] * light[X] + rot[1] * light[Y] + rot[2] * light[Z]; + *t = rot[6] * light[X] + rot[7] * light[Y] + rot[8] * light[Z]; + Normalize2f(s, t); +} + + +/* find out where the current normal is */ +void +bumpNormal3f(GLfloat x, GLfloat y, GLfloat z) +{ + curNormal[X] = x; + curNormal[Y] = y; + curNormal[Z] = z; + glNormal3f(x, y, z); +} + +void +bumpTangent3f(GLfloat x, GLfloat y, GLfloat z) +{ + curTangent[X] = x; + curTangent[Y] = y; + curTangent[Z] = z; +} + +/* save the texture coordinate call; will shift to do bumpmapping */ +void +bumpTexCoord2f(GLfloat s, GLfloat t) +{ + curTex[S] = s; + curTex[T] = t; +} + +/* +** use current tangent vector to compute texture coordinate shift +** then apply it by passing through vertex call +*/ +void +bumpVertex3f(GLfloat x, GLfloat y, GLfloat z) +{ + + GLfloat Light[3]; /* light in tangent space */ + GLfloat length; + GLfloat s, t; /* tranformed light, used to shift */ + GLfloat rot[9]; /* rotation matrix (just enought for x and y */ + GLfloat Bx, By, Bz; /* binormal axis */ + + if(bumpEnabled) + { + + /* get current light position */ + Light[X] = curLight[X]; + Light[Y] = curLight[Y]; + Light[Z] = curLight[Z]; + + /* find light vector from vertex */ + Light[X] -= x; Light[Y] -= y; Light[Z] -= z; + + length = 1.f/ sqrtf(Light[X] * Light[X] + + Light[Y] * Light[Y] + + Light[Z] * Light[Z]); + + Light[X] *= length; Light[Y] *= length; Light[Z] *= length; + + /* create rotation matrix (rotate into tangent space) */ + + biNormal(&Bx, &By, &Bz); /* find binormal axis */ + + rot[0] = curTangent[X]; rot[1] = curTangent[Y]; rot[2] = curTangent[Z]; + rot[3] = curNormal[X]; rot[4] = curNormal[Y]; rot[5] = curNormal[Z]; + rot[6] = Bx; rot[7] = By; rot[8] = Bz; + + Rotate(rot, Light, &s, &t); + + /* shift coordinates in opposite direction of desired texture shift */ + glTexCoord2f(curTex[S] - s/texture_width, curTex[T] - t/texture_height); + } + else + glTexCoord2f(curTex[S], curTex[T]); + + glVertex3f(x, y, z); /* pass on the vertex call */ +} + +void +bumpBegin(GLenum prim) +{ + if(bumpEnabled) + { + /* get light position; map back from eye to object space */ + bumpLightPos(&curLight[X], &curLight[Y], &curLight[Z]); + } + glBegin(prim); +} + +void draw(void) +{ + int i, j; + GLfloat Vx, Vy, Vz; /* vertex */ + GLfloat Tx, Ty, Tz; /* tangent */ + GLfloat Nx, Ny, Nz; /* normal */ + GLfloat c, s; /* cos, sin */ + + CHECK_ERROR("start of draw()"); + + + Ny = 0.f; + Ty = 0.f; + /* v(i, j) v(i+1, j), v(i+1, j+1), v(i, j+1) */ + bumpBegin(GL_QUADS); + for(j = 0; j < steps_y; j ++) + for(i = 0; i < steps_xz; i++) /* 180 -> 0 degrees */ + { + /* v(i, j) */ + c = cosf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1))); + s = sinf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1))); + Vx = 100 * c; + Vy = j * 200.f/steps_y - 100.f; + Vz = 100 * s - 100.f; + Nx = c; + Nz = s; + Tx = s; + Ty = -c; + Tz = 0; + bumpNormal3f(Nx, Ny, Nz); + bumpTangent3f(Tx, Ty, Tz); + bumpTexCoord2f(i/(GLfloat)steps_xz, j/(GLfloat)steps_y); + bumpVertex3f(Vx, Vy, Vz); + + /* v(i+1, j) */ + c = cosf(M_PI * (1.f - (GLfloat)(i + 1)/(steps_xz - 1))); + s = sinf(M_PI * (1.f - (GLfloat)(i + 1)/(steps_xz - 1))); + Vx = 100 * c; + Vz = 100 * s - 100.f; + Nx = c; + Nz = s; + Tx = s; + Ty = -c; + bumpNormal3f(Nx, Ny, Nz); + bumpTangent3f(Tx, Ty, Tz); + bumpTexCoord2f((i + 1)/(GLfloat)steps_xz, j/(GLfloat)steps_y); + bumpVertex3f(Vx, Vy, Vz); + + /* v(i+1, j+1) */ + Vy = (j + 1) * 200.f/steps_y - 100.f; + bumpNormal3f(Nx, Ny, Nz); + bumpTangent3f(Tx, Ty, Tz); + bumpTexCoord2f((i + 1)/(GLfloat)steps_xz, (j + 1)/(GLfloat)steps_y); + bumpVertex3f(Vx, Vy, Vz); + + /* v(i, j+1) */ + c = cosf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1))); + s = sinf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1))); + Vx = 100 * c; + Vz = 100 * s - 100.f; + Nx = c; + Nz = s; + Tx = s; + Ty = -c; + bumpNormal3f(Nx, Ny, Nz); + bumpTangent3f(Tx, Ty, Tz); + bumpTexCoord2f(i/(GLfloat)steps_xz, (j + 1)/(GLfloat)steps_y); + bumpVertex3f(Vx, Vy, Vz); + } + glEnd(); + + CHECK_ERROR("end of draw()"); +} + + + +/* Called when window needs to be redrawn */ +void redraw_blendext(void) +{ + GLUquadricObj *obj; + void draw(void); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + + glLoadIdentity(); + + gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + glPushMatrix(); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + obj = gluNewQuadric(); + gluSphere(obj, 7., 10, 10); + gluDeleteQuadric(obj); + glPopMatrix(); + + glRotatef(angles[X], 0.f, 1.f, 0.f); + glRotatef(angles[Y], 1.f, 0.f, 0.f); + + if(textureOnly) + { + glEnable(GL_TEXTURE_2D); + draw(); + glDisable(GL_TEXTURE_2D); + } + else if(lightOnly) + { + /* draw "z" diffuse component */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + draw(); + glDisable(GL_LIGHTING); + } + else /* bumpmapping */ + { + + /* find N dot L */ + + /* draw "z" diffuse component */ + /* also do ambient here */ + if(!embossed) + { + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + draw(); + glDisable(GL_LIGHTING); + } + /* add in shifted values */ + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + bumpEnable(); /* shift texture coords */ + draw(); + bumpDisable(); + +#ifdef GL_EXT_blend_subtract + if (hasBlendSubtract) { + /* subtract unshifted */ + glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); + draw(); + glBlendEquationEXT(GL_FUNC_ADD_EXT); + } +#endif + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + + if(color) + { + /* Modulate the color texture with N dot L */ + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_ZERO); + glBindTexture(GL_TEXTURE_2D, 1); /* use color texture */ + draw(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + } + + } + + /* scale up the image */ + + glPixelTransferf(GL_RED_SCALE, 2.f); + glPixelTransferf(GL_GREEN_SCALE, 2.f); + glPixelTransferf(GL_BLUE_SCALE, 2.f); + glCopyPixels(0, 0, winWidth, winHeight, GL_COLOR); + + CHECK_ERROR("OpenGL Error in redraw()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +/* Called when window needs to be redrawn */ +void redraw_accum(void) +{ + GLUquadricObj *obj; + void draw(void); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + + glLoadIdentity(); + + gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + glRotatef(angles[X], 0.f, 1.f, 0.f); + glRotatef(angles[Y], 1.f, 0.f, 0.f); + + if(textureOnly) + { + glEnable(GL_TEXTURE_2D); + draw(); + glDisable(GL_TEXTURE_2D); + } + else if(lightOnly) + { + /* draw "z" diffuse component */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + draw(); + glDisable(GL_LIGHTING); + } + else /* bumpmapping */ + { + + CHECK_ERROR("start"); + /* draw "z" diffuse component */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + draw(); + glAccum(GL_LOAD, .5f); + CHECK_ERROR("load"); + glDisable(GL_LIGHTING); + + /* draw shifted */ + glEnable(GL_TEXTURE_2D); + bumpEnable(); + draw(); + glAccum(GL_ACCUM, .5f); + bumpDisable(); + + /* subtract unshifted */ + draw(); + glAccum(GL_ACCUM, -.5f); + + glDisable(GL_TEXTURE_2D); + glAccum(GL_RETURN, 2.f); + + if(color) + { + /* Modulate the color texture with N dot L */ + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_ZERO); + glBindTexture(GL_TEXTURE_2D, 1); /* use color texture */ + draw(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + } + + } + + + + CHECK_ERROR("OpenGL Error in redraw()"); + + glPushMatrix(); + glLoadIdentity(); + gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + obj = gluNewQuadric(); + gluSphere(obj, 7., 10, 10); + gluDeleteQuadric(obj); + glPopMatrix(); + + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) + { + case 't': + if(textureOnly) + textureOnly = FALSE; + else + textureOnly = TRUE; + glutPostRedisplay(); + break; + case 'l': + if(lightOnly) + lightOnly = FALSE; + else + lightOnly = TRUE; + glutPostRedisplay(); + break; + case 'e': + if(embossed) + embossed = FALSE; + else + embossed = TRUE; + glutPostRedisplay(); + break; + case 'B': /* make bumps taller */ + bumpscale += .01f; + printf("bump map scale = %.2f\n", bumpscale); + glPixelTransferf(GL_RED_SCALE, bumpscale); + glPixelTransferf(GL_GREEN_SCALE, bumpscale); + glPixelTransferf(GL_BLUE_SCALE, bumpscale); + + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, + texture_width, texture_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, bumptex); + glutPostRedisplay(); + break; + case 'b': /* make bumps flatter */ + bumpscale -= .01f; + if(bumpscale < 0.f) + bumpscale = 0.f; + printf("bump map scale = %.2f\n", bumpscale); + glPixelTransferf(GL_RED_SCALE, bumpscale); + glPixelTransferf(GL_GREEN_SCALE, bumpscale); + glPixelTransferf(GL_BLUE_SCALE, bumpscale); + + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, + texture_width, texture_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, bumptex); + glutPostRedisplay(); + break; + case 'c': + if(color == TRUE) + color = FALSE; + else + color = TRUE; + glutPostRedisplay(); + break; + case 'w': + if(wire == TRUE) + { + glPolygonMode(GL_FRONT, GL_FILL); + wire = FALSE; + } + else + { + glPolygonMode(GL_FRONT, GL_LINE); + wire = TRUE; + } + glutPostRedisplay(); + break; + case 'x': + steps_xz -= 2; + if(steps_xz < 1) + steps_xz = 1; + glutPostRedisplay(); + break; + case 'X': + steps_xz += 2; + glutPostRedisplay(); + break; + case 'y': + steps_y -= 2; + if(steps_y < 1) + steps_y = 1; + glutPostRedisplay(); + break; + case 'Y': + steps_y += 2; + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + case 'h': + case '?': + default: + fprintf(stderr, + "Keyboard commands:\n" + "t-texture only\n" + "l-light only\n" + "c-color texture\n" + "e-embossed (horizontal part)\n" + "w-toggle wireframe\n" + "B-increase bumps b-decrease bumps\n"); + break; + } + +} + + + +main(int argc, char *argv[]) +{ + unsigned *tex; + GLfloat lightpos[4]; + GLfloat diffuse[4]; + GLboolean valid; + int texcomps, texwid, texht; + const char *version; + char varray[32]; + + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + if(argc > 1) + { + char *args = argv[1]; + int done = FALSE; + while(!done) + { + switch(*args) + { + case 's': /* single buffer */ + printf("Single Buffered\n"); + dblbuf = FALSE; + break; + case 'a': /* use accumulation buffer */ + printf("Use accumulation buffer\n"); + accum = TRUE; + break; + case '-': /* do nothing */ + break; + case 0: + done = TRUE; + break; + } + args++; + } + } + if(dblbuf) + if(accum) + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ACCUM); + else + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + else + if(accum) + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM); + else + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH); + + (void)glutCreateWindow("bump mapping example program"); + if(accum) + glutDisplayFunc(redraw_accum); + else + glutDisplayFunc(redraw_blendext); + + glutKeyboardFunc(key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutReshapeFunc(reshape); + + + + version = (char *) glGetString(GL_VERSION); + strncpy(varray, version, strcspn(version, " ")); + printf("%s\n", version); + if(atof(varray) > 1.f) + bindtex = TRUE; + else + bindtex = FALSE; + + glRasterPos3i(-1, -1, -1); + glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); + if(!valid) + printf("invalid raster position!\n"); + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-150., 150., -150., 150., 500., 800.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + + diffuse[R] = diffuse[G] = diffuse[B] = .4f; + diffuse[A] = 1.f; + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); + bumptex = read_texture("../data/opengl.bw", &texture_width, + &texture_height, &texcomps); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + if(!accum) + { + /* scale to match maximum z (default Kd = .8, default Ld = 1. */ + /* divide by 2 to stay in range of 0 to 1 */ + glPixelTransferf(GL_RED_SCALE, bumpscale); + glPixelTransferf(GL_GREEN_SCALE, bumpscale); + glPixelTransferf(GL_BLUE_SCALE, bumpscale); + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, + texture_width, texture_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, bumptex); + + tex = read_texture("../data/plank.rgb", &texwid, &texht, &texcomps); + + glBindTexture(GL_TEXTURE_2D, 1); /* for color */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glPixelTransferf(GL_RED_SCALE, 1.f); + glPixelTransferf(GL_GREEN_SCALE, 1.f); + glPixelTransferf(GL_BLUE_SCALE, 1.f); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + texwid, texht, 0, GL_RGBA, + GL_UNSIGNED_BYTE, tex); + + glBindTexture(GL_TEXTURE_2D, 0); + + free(tex); + + lightpos[X] = lightpos[Y] = 0.f; + lightpos[Z] = -90.f; + lightpos[W] = 1.f; + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_DITHER); + + CHECK_ERROR("end of main"); + +#ifdef GL_EXT_blend_subtract + if(!glutExtensionSupported("GL_EXT_blend_subtract")) { + fprintf(stderr, + "bump: requires OpenGL blend subtract extension to operate correctly.\n"); + hasBlendSubtract = 0; + } else { + hasBlendSubtract = 1; +#if defined(_WIN32) && !defined(MESA) + glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) wglGetProcAddress("glBlendEquationEXT"); + if (glBlendEquationEXT == NULL) { + hasBlendSubtract = 0; + } +#endif + } +#endif + + key('?', 0, 0); /* startup message */ + glutMainLoop(); + return(0); +} diff --git a/lib/glut-3.7.6/progs/advanced97/bump.dsp b/lib/glut-3.7.6/progs/advanced97/bump.dsp new file mode 100644 index 0000000000..f50d90f323 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/bump.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="bump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=bump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bump.mak" CFG="bump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "bump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bump - Win32 Release" +# Name "bump - Win32 Debug" +# Begin Source File + +SOURCE=.\bump.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/chromakey.c b/lib/glut-3.7.6/progs/advanced97/chromakey.c new file mode 100644 index 0000000000..4479227a05 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/chromakey.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +static char defaultFile0[] = "../data/sgi.bw"; +static char defaultFile1[] = "../data/mandrill.rgb"; +static char defaultFile2[] = "../data/brick.rgb"; +GLuint *img0, *img1, *img2; +GLsizei w, h; +GLsizei w0, w1, w2, h0, h1, h2; +GLint comp; +GLfloat key[3] = {0, 0, 0}; + +#define RW 0.3086 +#define GW 0.6094 +#define BW 0.0820 + +void init(void) +{ +} + +GLuint *load_img(const char *fname, GLsizei *imgW, GLsizei *imgH) +{ + GLuint *img; + + img = read_texture(fname, imgW, imgH, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + return img; +} + +GLuint * +resize_img(GLuint *img, GLsizei curW, GLsizei curH) +{ + + glPixelZoom((float)w / (float)curW, (float)h / (float)curH); + glRasterPos2i(0, 0); + glDrawPixels(curW, curH, GL_RGBA, GL_UNSIGNED_BYTE, img); + free(img); + img = (GLuint *)malloc(w * h * sizeof(GLuint)); + if (!img) { + fprintf(stderr, "Malloc of %d bytes failed.\n", + curW * curH * sizeof(GLuint)); + exit(1); + } + glPixelZoom(1, 1); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img); + + return img; +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, 2*w, 2*h); + glLoadIdentity(); + glOrtho(0, 2*w, 0, 2*h, 0, 5); +} + +void compute_matte(void) +{ + glClear(GL_ACCUM_BUFFER_BIT); + + /* draw rectangle in (key color + 1) / 2 */ + glBegin(GL_QUADS); + glColor3f(key[0], key[1], key[2]); + glVertex2f(0, 0); + glVertex2f(w, 0); + glVertex2f(w, h); + glVertex2f(0, h); + glEnd(); + glFlush(); + + /* negate & accumulate */ + glAccum(GL_LOAD, -1); + + /* compute & return (image - key) */ + glRasterPos2f(0, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0); + glAccum(GL_ACCUM, 1); + glAccum(GL_RETURN, 1); + + /* move to right hand side of window */ + glRasterPos2f(w, 0); + glCopyPixels(0, 0, w, h, GL_COLOR); + + /* compute & return (key - image) */ + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, w, h); + glAccum(GL_MULT, -1); + glAccum(GL_RETURN, 1); + glScissor(0, 0, 2*w, h); + glDisable(GL_SCISSOR_TEST); + + /* assemble to get fabs(key - image) */ + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + glRasterPos2i(0, 0); + glCopyPixels(w, 0, w, h, GL_COLOR); + glDisable(GL_BLEND); + + /* assemble into alpha channel */ + { + GLfloat mat[] = { + RW, RW, RW, RW, + GW, GW, GW, GW, + BW, BW, BW, BW, + 0, 0, 0, 0, + }; + glMatrixMode(GL_COLOR); + glLoadMatrixf(mat); + + glRasterPos2i(w, 0); + glCopyPixels(0, 0, w, h, GL_COLOR); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + } + + /* copy matte to right */ + glRasterPos2i(0, 0); + glCopyPixels(w, 0, w, h, GL_COLOR); + + /* draw the third image */ + glColorMask(1, 1, 1, 0); + glRasterPos2i(w, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img2); + glColorMask(1, 1, 1, 1); + + glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); + glEnable(GL_BLEND); + glRasterPos2i(w, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img1); + + /* this is for matte display... */ + glColor3f(1, 1, 1); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(w, 0); + glVertex2f(w, h); + glVertex2f(0, h); + glEnd(); + + glDisable(GL_BLEND); +} + +void draw(void) +{ + GLenum err; + static int first = 1; + + if (first) { + printf("Scaling images to %d by %d\n", w, h); + + + if (w0 != w || h0 != h) { + img0 = resize_img(img0, w0, h0); + + } + if (w1 != w || h1 != h) { + img1 = resize_img(img1, w1, h1); + } + if (w2 != w || h2 != h) { + img2 = resize_img(img2, w2, h2); + } + first = 0; + } + + + glClear(GL_COLOR_BUFFER_BIT); + compute_matte(); + + glRasterPos2i(w/2, h); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); +} + +/* ARGSUSED */ +void button(int button, int state, int xpos, int ypos) +{ + if (state != GLUT_UP) return; + + ypos = 2*h - ypos; + glReadPixels(xpos, ypos, 1, 1, GL_RGB, GL_FLOAT, key); + printf("Key is (%f %f %f)\n", key[0], key[1], key[2]); + draw(); +} + +/* ARGSUSED1 */ +void keyPress(unsigned char whichKey, int x, int y) +{ + if (whichKey == 27) exit(0); +} + +void show_usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "chromakey mattefile file0 file1 [matteR matteG matteB]\n"); + fprintf(stderr, "chromakey mattefileAndfile0 file1 [matteR matteG matteB]\n"); +} + +main(int argc, char *argv[]) +{ + char *fileName0 = defaultFile0, *fileName1 = defaultFile1, + *fileName2 = defaultFile2; + + glutInit(&argc, argv); + if (argc > 1) { + fileName0 = fileName1 = argv[1]; + } + if (argc > 2) { + fileName2 = argv[2]; + } + if (argc > 3) { + fileName1 = fileName2; + fileName2 = argv[3]; + } + if (argc > 4) { + if (argc == 6 || argc == 7) { + key[0] = atof(argv[argc-3]); + key[1] = atof(argv[argc-2]); + key[2] = atof(argv[argc-1]); + } else { + show_usage(); + exit(1); + } + } + + printf("Matte file is %s\n", fileName0); + printf("Image file 1 is %s\n", fileName1); + printf("Image file 2 is %s\n", fileName2); + printf("Key is (%f %f %f)\n", key[0], key[1], key[2]); + img0 = load_img(fileName0, &w0, &h0); + img1 = load_img(fileName1, &w1, &h1); + img2 = load_img(fileName2, &w2, &h2); + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + w = MAX(MAX(w0, w1), w2); + h = MAX(MAX(h0, h1), h2); + + glutInitWindowSize(2*w, 2*h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_ALPHA); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(keyPress); + glutReshapeFunc(reshape); + glutMouseFunc(button); + + + init(); + + reshape(w, h); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/chromakey.dsp b/lib/glut-3.7.6/progs/advanced97/chromakey.dsp new file mode 100644 index 0000000000..b3ef23f7ca --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/chromakey.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="chromakey" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=chromakey - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "chromakey.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "chromakey.mak" CFG="chromakey - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "chromakey - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "chromakey - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "chromakey - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "chromakey - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "chromakey - Win32 Release" +# Name "chromakey - Win32 Debug" +# Begin Source File + +SOURCE=.\chromakey.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.c b/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.c new file mode 100644 index 0000000000..ab42afb3b0 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.c @@ -0,0 +1,325 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +static char defaultFile0[] = "../data/swamp.rgb"; +static char defaultFile1[] = "../data/swamp.rgb"; +static char defaultFile2[] = "../data/mandrill.rgb"; +GLuint *img0, *img1, *img2; +GLsizei w, h; +GLsizei w0, w1, w2, h0, h1, h2; +GLint comp; +GLfloat key[3] = {0, 0, 0}; + +#define RW 0.3086 +#define GW 0.6094 +#define BW 0.0820 + +/* key values less than or equal to lower fudge map to totally + * transparent... */ +GLfloat lowerfudge = .2; +GLfloat upperfudge = .8; + +void init(void) +{ +} + +GLuint *load_img(const char *fname, GLsizei *imgW, GLsizei *imgH) +{ + GLuint *img; + + img = read_texture(fname, imgW, imgH, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + return img; +} + +GLuint * +resize_img(GLuint *img, GLsizei curW, GLsizei curH) +{ + + glPixelZoom((float)w / (float)curW, (float)h / (float)curH); + glRasterPos2i(0, 0); + glDrawPixels(curW, curH, GL_RGBA, GL_UNSIGNED_BYTE, img); + free(img); + img = (GLuint *)malloc(w * h * sizeof(GLuint)); + if (!img) { + fprintf(stderr, "Malloc of %d bytes failed.\n", + curW * curH * sizeof(GLuint)); + exit(1); + } + glPixelZoom(1, 1); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img); + + return img; +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, 2*w, 2*h); + glLoadIdentity(); + glOrtho(0, 2*w, 0, 2*h, 0, 5); +} + +void compute_matte(void) +{ + glClear(GL_ACCUM_BUFFER_BIT); + + /* draw rectangle in (key color + 1) / 2 */ + glBegin(GL_QUADS); + glColor3f(key[0], key[1], key[2]); + glVertex2f(0, 0); + glVertex2f(w, 0); + glVertex2f(w, h); + glVertex2f(0, h); + glEnd(); + glFlush(); + + /* negate & accumulate */ + glAccum(GL_LOAD, -1); + + /* compute & return (image - key) */ + glRasterPos2f(0, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0); + glAccum(GL_ACCUM, 1); + glAccum(GL_RETURN, 1); + + /* move to right hand side of window */ + glRasterPos2f(w, 0); + glCopyPixels(0, 0, w, h, GL_COLOR); + + /* compute & return (key - image) */ + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, w, h); + glAccum(GL_MULT, -1); + glAccum(GL_RETURN, 1); + glScissor(0, 0, 2*w, h); + glDisable(GL_SCISSOR_TEST); + + /* assemble to get fabs(key - image) */ + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + glRasterPos2i(0, 0); + glCopyPixels(w, 0, w, h, GL_COLOR); + glDisable(GL_BLEND); + + /* assemble into alpha channel */ + { + GLfloat mat[] = { + RW, RW, RW, RW, + GW, GW, GW, GW, + BW, BW, BW, BW, + 0, 0, 0, 0, + }; + glMatrixMode(GL_COLOR); + glLoadMatrixf(mat); + + glRasterPos2i(w, 0); + glCopyPixels(0, 0, w, h, GL_COLOR); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + /* do a second copy because sbias comes after color matrix in the + * transfer pipeline. could avoid this by using the post color matrix + * scale bias... */ + if (upperfudge - lowerfudge) { + glPixelTransferf(GL_ALPHA_SCALE, 1./(upperfudge - lowerfudge)); + glPixelTransferf(GL_ALPHA_BIAS, -lowerfudge/(upperfudge - lowerfudge)); + } else { + /* move such that upper/lowerfudge maps to .5, then quantize with + * 2-entry pixel map. */ + GLushort quantize[] = {0, 0xffff}; + glPixelTransferf(GL_ALPHA_BIAS, .5 - upperfudge); + glPixelMapusv(GL_PIXEL_MAP_A_TO_A, 2, quantize); + glPixelTransferi(GL_MAP_COLOR, 1); + } + glRasterPos2i(w, 0); + glCopyPixels(w, 0, w, h, GL_COLOR); + glPixelTransferf(GL_ALPHA_SCALE, 1); + glPixelTransferf(GL_ALPHA_BIAS, 0); + glPixelTransferi(GL_MAP_COLOR, 0); + } + + + /* copy matte to right */ + glRasterPos2i(0, 0); + glCopyPixels(w, 0, w, h, GL_COLOR); + + /* draw the third image */ + glColorMask(1, 1, 1, 0); + glRasterPos2i(w, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img2); + glColorMask(1, 1, 1, 1); + + glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); + glEnable(GL_BLEND); + glRasterPos2i(w, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img1); + + /* this is for matte display... */ + glColor3f(1, 1, 1); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(w, 0); + glVertex2f(w, h); + glVertex2f(0, h); + glEnd(); + + glDisable(GL_BLEND); +} + +void draw(void) +{ + GLenum err; + static int first = 1; + + if (first) { + printf("Scaling images to %d by %d\n", w, h); + + + if (w0 != w || h0 != h) { + img0 = resize_img(img0, w0, h0); + + } + if (w1 != w || h1 != h) { + img1 = resize_img(img1, w1, h1); + } + if (w2 != w || h2 != h) { + img2 = resize_img(img2, w2, h2); + } + first = 0; + } + + + glClear(GL_COLOR_BUFFER_BIT); + compute_matte(); + + glRasterPos2i(w/2, h); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); +} + +/* ARGSUSED */ +void button(int button, int state, int xpos, int ypos) +{ + if (state != GLUT_UP) return; + + ypos = 2*h - ypos; + glReadPixels(xpos, ypos, 1, 1, GL_RGB, GL_FLOAT, key); + printf("Key is (%f %f %f)\n", key[0], key[1], key[2]); + draw(); +} + +/* ARGSUSED1 */ +void keyPress(unsigned char whichKey, int x, int y) +{ + if (whichKey == 27) exit(0); +} + +void change_lower_fudge(int val) +{ + lowerfudge = (float)val / 100.; + if (upperfudge < lowerfudge) upperfudge = lowerfudge; + draw(); +} + +void change_upper_fudge(int val) +{ + upperfudge = (float)val / 100.; + if (lowerfudge > upperfudge) lowerfudge = upperfudge; + draw(); +} + +void show_usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "chromakey mattefile file0 file1 [matteR matteG matteB]\n"); + fprintf(stderr, "chromakey mattefileAndfile0 file1 [matteR matteG matteB]\n"); +} + +main(int argc, char *argv[]) +{ + char *fileName0 = defaultFile0, *fileName1 = defaultFile1, + *fileName2 = defaultFile2; + + glutInit(&argc, argv); + if (argc > 1) { + fileName0 = fileName1 = argv[1]; + } + if (argc > 2) { + fileName2 = argv[2]; + } + if (argc > 3) { + fileName1 = fileName2; + fileName2 = argv[3]; + } + if (argc > 4) { + if (argc == 6 || argc == 7) { + key[0] = atof(argv[argc-3]); + key[1] = atof(argv[argc-2]); + key[2] = atof(argv[argc-1]); + } else { + show_usage(); + exit(1); + } + } + + printf("Matte file is %s\n", fileName0); + printf("Image file 1 is %s\n", fileName1); + printf("Image file 2 is %s\n", fileName2); + printf("Key is (%f %f %f)\n", key[0], key[1], key[2]); + printf("Transparent boundary is %f\n", lowerfudge); + printf("Opaque boundary is %f\n", upperfudge); + img0 = load_img(fileName0, &w0, &h0); + img1 = load_img(fileName1, &w1, &h1); + img2 = load_img(fileName2, &w2, &h2); + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + w = MAX(MAX(w0, w1), w2); + h = MAX(MAX(h0, h1), h2); + + glutInitWindowSize(2*w, 2*h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_ALPHA); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(keyPress); + glutReshapeFunc(reshape); + glutMouseFunc(button); + + { + int lowerFudgeMenu, upperFudgeMenu; + lowerFudgeMenu = glutCreateMenu(change_lower_fudge); + glutAddMenuEntry("0", 0); + glutAddMenuEntry(".1", 20); + glutAddMenuEntry(".25", 20); + glutAddMenuEntry(".5", 50); + glutAddMenuEntry(".75", 75); + upperFudgeMenu = glutCreateMenu(change_upper_fudge); + glutAddMenuEntry(".25", 20); + glutAddMenuEntry(".5", 50); + glutAddMenuEntry(".75", 75); + glutAddMenuEntry(".9", 90); + glutAddMenuEntry("1", 100); + glutCreateMenu(0); + glutAddSubMenu("Transparent boundary", lowerFudgeMenu); + glutAddSubMenu("Opaque boundary", upperFudgeMenu); + glutAttachMenu(GLUT_RIGHT_BUTTON); + } + + init(); + + reshape(w, h); + glutMainLoop(); + return 0; +} + + diff --git a/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.dsp b/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.dsp new file mode 100644 index 0000000000..503ddc01ed --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/chromakey_fancy.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="chromakey_fancy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=chromakey_fancy - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "chromakey_fancy.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "chromakey_fancy.mak" CFG="chromakey_fancy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "chromakey_fancy - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "chromakey_fancy - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "chromakey_fancy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "chromakey_fancy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "chromakey_fancy - Win32 Release" +# Name "chromakey_fancy - Win32 Debug" +# Begin Source File + +SOURCE=.\chromakey_fancy.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/cloud.c b/lib/glut-3.7.6/progs/advanced97/cloud.c new file mode 100644 index 0000000000..2cfc6b65ae --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/cloud.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include +#include "texture.h" + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define expf(x) ((float)exp((x))) +#endif + +static float ttrans[2]; +static float scale = 1.; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +#if NATE +void +wire(void) { + static int w; + if (w ^= 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} +#endif + +void up(void) { scale += .1; } +void down(void) { scale -= .1; } + +void +animate(void) { + ttrans[0] += .01; + if (ttrans[0] == 1.0) ttrans[0] = 0; + ttrans[1] += .005; + if (ttrans[1] == 1.0) ttrans[1] = 0; + glutPostRedisplay(); +} + +void help(void) { + printf("Usage: cloud [image]\n"); + printf("'h' - help\n"); +#if NATE + printf("'w' - toggle wireframe\n"); +#endif + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(char *filename) { + GLfloat cloud_color[4] = { 1., 1., 1., 0., }; + GLfloat fog_color[4], fog_density = 0.05, density, far_cull; + unsigned *image; + int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 1) { + printf("must be a bw image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cloud_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,far_cull = 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + + density = 1.- expf(-5.5 * fog_density * fog_density * + far_cull * far_cull); + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + density = MAX(MIN(density, 1.), 0.); + + fog_color[0] = .23 + density *.57; + fog_color[1] = .35 + density *.45; + fog_color[2] = .78 + density *.22; + + glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f); + + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fog_density); + glFogfv(GL_FOG_COLOR, fog_color); + if (fog_density > 0) + glEnable(GL_FOG); +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(scale,scale,1.); + glScalef(10,1,10); + glColor3f(.19, .25, .70); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glTranslatef(ttrans[0], ttrans[1], 0.); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1., 1., -1.); + glTexCoord2f(0, 5); glVertex3f(-1., 1., 1.); + glTexCoord2f(5, 5); glVertex3f( 1., 1., 1.); + glTexCoord2f(5, 0); glVertex3f( 1., 1., -1.); + glEnd(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { +#if NATE + case 'w': wire(); break; +#endif + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + } +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/clouds.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/cloud.dsp b/lib/glut-3.7.6/progs/advanced97/cloud.dsp new file mode 100644 index 0000000000..13b30cd56d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/cloud.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="cloud" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=cloud - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cloud.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cloud.mak" CFG="cloud - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cloud - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "cloud - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cloud - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "cloud - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "cloud - Win32 Release" +# Name "cloud - Win32 Debug" +# Begin Source File + +SOURCE=.\cloud.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/cloudl.c b/lib/glut-3.7.6/progs/advanced97/cloudl.c new file mode 100644 index 0000000000..8e001c2900 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/cloudl.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include "texture.h" + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define expf(x) ((float)exp((x))) +#endif + +static float ttrans[2]; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void +animate(void) { + ttrans[0] += .010f; + if (ttrans[0] == 1.0f) ttrans[0] = 0.0f; + ttrans[1] -= .020f; + if (ttrans[1] <= 0.0f) ttrans[1] = 1.0f; + glutPostRedisplay(); +} + +void xfunc(void) { + static state = 1; + glutIdleFunc((state ^= 1) ? animate : NULL); +} + +void help(void) { + printf("Usage: cloudl [image]\n"); + printf("'h' - help\n"); + printf("'x' - toggle cloud motion\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void init(char *filename) { + GLfloat fog_color[4], fog_density = 0.05, density, far_cull; + unsigned *image; + int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 1 && components != 2) { + printf("must be a l or la image\n"); + exit(EXIT_FAILURE); + } + if (components == 1) { + /* hack for RE */ + int i; + GLubyte *p = (GLubyte *)image; + for(i = 0; i < width*height; i++) { + p[i*4+3] = p[i*4+0]; + } + components = 2; + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + /*glEnable(GL_TEXTURE_2D);*/ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,far_cull = 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + + density = 1.- expf(-5.5 * fog_density * fog_density * + far_cull * far_cull); + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + density = MAX(MIN(density, 1.), 0.); + + fog_color[0] = .23*.2 + density *.57*.2; + fog_color[1] = .35*.2 + density *.45*.2; + fog_color[2] = .78*.5 + density *.22*.2; + + glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f); + + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fog_density); + glFogfv(GL_FOG_COLOR, fog_color); + if (fog_density > 0) + glEnable(GL_FOG); + glLineWidth(2.0f); + glEnable(GL_LINE_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPointSize(10.f); + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); +} + +void draw_base(void) { + glColor4f(.1, .3, .1, 1.0); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); +} + +void draw_runway(void) { + glColor4f(.1, .1, .1, 1.0); + glPushMatrix(); + glScalef(.1f, 1.f, 1.f); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); + glPopMatrix(); +} + +void draw_lights(void) { + int i; + + glEnable(GL_BLEND); + glColor4f(.7f, .7f, .1f, 1.0); + glPushMatrix(); + glScalef(.1f, 1.f, 1.f); + glEnable(GL_POINT_SMOOTH); + for(i = 0; i <= 20; i++) { + glPointSize((float)i/2.); + glBegin(GL_POINTS); + glVertex3f(-1.f, 0.f, -1.f+2.f/20*i); + glVertex3f( 1.f, 0.f, -1.f+2.f/20*i); + glEnd(); + } + glPopMatrix(); + glDisable(GL_BLEND); +} + +void +draw_clouds(void) { + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glTranslatef(ttrans[0], ttrans[1], 0.); + glColor4f(1.f, 1.f, 1.f, 1.0); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1., .2, -1.); + glTexCoord2f(0, 5); glVertex3f(-1., .2, 1.); + glTexCoord2f(5, 5); glVertex3f( 1., .2, 1.); + glTexCoord2f(5, 0); glVertex3f( 1., .2, -1.); + glEnd(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(10,1,10); + glTranslatef(0.f,-1.f,0.f); + draw_base(); + draw_runway(); + draw_lights(); + draw_clouds(); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'x': xfunc(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/clouds.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/cloudl.dsp b/lib/glut-3.7.6/progs/advanced97/cloudl.dsp new file mode 100644 index 0000000000..c32a3d43a4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/cloudl.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="cloudl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=cloudl - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cloudl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cloudl.mak" CFG="cloudl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cloudl - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "cloudl - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cloudl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "cloudl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "cloudl - Win32 Release" +# Name "cloudl - Win32 Debug" +# Begin Source File + +SOURCE=.\cloudl.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/complexity.c b/lib/glut-3.7.6/progs/advanced97/complexity.c new file mode 100644 index 0000000000..8f334b2c20 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/complexity.c @@ -0,0 +1,234 @@ +/* This program demonstrates how to use the stencil buffer to visualize +** the depth complexity of a scene. +*/ + +#include +#include +#include + +/* show contents of stencil buffer */ +int winwid = 512; +int winht = 512; +GLubyte *stencil = 0; /* so realloc works the first time */ + +void resize(int wid, int ht) +{ + winwid = wid; + winht = ht; + stencil = (GLubyte *)realloc((void*)stencil, + winwid * winht * sizeof(GLubyte)); + glViewport(0, 0, wid, ht); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + +int rotate = 0; +GLfloat udangle = 0.f; +GLfloat lrangle = 0.f; + +void motion(int x, int y) +{ + if(rotate) + { + udangle = (y - winht/2) * 360./winht; + lrangle = (x - winwid/2) * 360./winwid; + } + glutPostRedisplay(); +} + +void mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* rotate the scene up and down */ + case GLUT_MIDDLE_BUTTON: /* rotate the scene left and right */ + rotate = 1; + motion(x, y); + break; + } + else + rotate = 0; /* overkill; cover right button too */ +} + + +/* read back stencil buffer, store in memory, draw back colorized */ +void showstencil(void) +{ + glReadPixels(0, 0, winwid, winht, GL_STENCIL_INDEX, + GL_UNSIGNED_BYTE, stencil); + + glRasterPos2i(-1, -1); + glDrawPixels(winwid, winht, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, stencil); +} + + +int showdepth = 0; +int depthtest = 1; +/* Called when window needs to be redrawn */ +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + glEnable(GL_STENCIL_TEST); + if(depthtest) + glEnable(GL_DEPTH_TEST); + + glPushMatrix(); + glRotatef(lrangle, 0.f, 1.f, 0.f); + glRotatef(udangle, 1.f, 0.f, 0.f); + glCallList(1); /* draw scene */ + glPopMatrix(); + + glDisable(GL_STENCIL_TEST); + glFlush(); /* high end machines may need this */ + + if(depthtest) + glDisable(GL_DEPTH_TEST); + + if(showdepth) + showstencil(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + glutSwapBuffers(); +} + +/* menu entries mapped to actions */ +enum {RENDER, SHOW_STENCIL, DEPTH_TEST}; +void menu(int choice) +{ + switch(choice) + { + case RENDER: + showdepth = 0; + break; + case SHOW_STENCIL: + showdepth = 1; + break; + case DEPTH_TEST: + depthtest = !depthtest; + if(depthtest) + /* show how many pixels were discarded by depth test */ + glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); + else + /* show how many pixels were written to frame buffer */ + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + break; + } + glutPostRedisplay(); +} + +typedef struct { + GLfloat r; + GLfloat g; + GLfloat b; +} Color; + +/* color map to indicate different depth complexities */ +Color map[] = { + {0.f, 0.f, 0.f,}, + {0.f, .25f, 0.f,}, + {0.f, .5f, 0.f,}, + {0.f, .75f, 0.f,}, + {0.f, 1.f, 0.f,}, + {.25f, 1.f, 0.f,}, + {.5f, 1.f, 0.f,}, + {.75f, 1.f, 0.f,}, + {1.f, 1.f, 0.f,}, + {1.f, .75f, 0.f,}, + {1.f, .5f, 0.f,}, + {1.f, .25f, 0.f,}, + {1.f, .0f, 0.f,}, + {1.f, .0f, 0.f,}, + {1.f, .0f, 0.f,}, + {1.f, .0f, 0.f,} +}; + +/* mapsize should be a power of two */ +#define mapsize 16 +GLfloat lightpos[4] = {.5f, .5f, -1.f, 1.f}; +main(int argc, char *argv[]) +{ + GLfloat rmap[mapsize], gmap[mapsize], bmap[mapsize]; + int i; + + glutInit(&argc, argv); + glutInitWindowSize(winwid, winht); + glutInitDisplayMode(GLUT_RGBA|GLUT_STENCIL|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow("visualizing depth complexity"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutReshapeFunc(resize); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glutCreateMenu(menu); + glutAddMenuEntry("Draw Scene", RENDER); + glutAddMenuEntry("Show Stencil", SHOW_STENCIL); + glutAddMenuEntry("Toggle Depth Test", DEPTH_TEST); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glStencilFunc(GL_ALWAYS, ~0, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + + /* draw an interesting scene */ + glNewList(1, GL_COMPILE); + /* center */ + glPushMatrix(); + glScalef(.2f, .2f, .2f); + glutSolidTetrahedron(); + glPopMatrix(); + /* right */ + glTranslatef(.4f, 0.f, 0.f); + glutSolidSphere(.25, 8, 8); + /* left */ + glTranslatef(-.8f, 0.f, 0.f); + glutSolidSphere(.25, 8, 8); + /* bottom */ + glTranslatef(.4f, -.4f, 0.f); + glutSolidSphere(.25, 8, 8); + /* top */ + glTranslatef(0.f, .8f, 0.f); + glutSolidSphere(.25, 8, 8); + + /* lefttop */ + glTranslatef(-.5f, .1f, 0.f); + glutSolidCube(.3); + /* righttop */ + glTranslatef(1.f, 0.f, 0.f); + glutSolidCube(.3); + /* rightbot */ + glTranslatef(0.f, -1.f, 0.f); + glutSolidCube(.3); + /* rightbot */ + glTranslatef(-1.f, 0.f, 0.f); + glutSolidCube(.3); + glEndList(); + + /* color ramp to show increasing complexity */ + /* black shading to green to yellow to red */ + for(i = 0; i < mapsize; i++) + { + rmap[i] = map[i].r; + gmap[i] = map[i].g; + bmap[i] = map[i].b; + } + + glPixelMapfv(GL_PIXEL_MAP_I_TO_R, mapsize, rmap); + glPixelMapfv(GL_PIXEL_MAP_I_TO_G, mapsize, gmap); + glPixelMapfv(GL_PIXEL_MAP_I_TO_B, mapsize, bmap); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/complexity.dsp b/lib/glut-3.7.6/progs/advanced97/complexity.dsp new file mode 100644 index 0000000000..f507b449e9 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/complexity.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="complexity" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=complexity - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "complexity.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "complexity.mak" CFG="complexity - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "complexity - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "complexity - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "complexity - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "complexity - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "complexity - Win32 Release" +# Name "complexity - Win32 Debug" +# Begin Source File + +SOURCE=.\complexity.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/csg.c b/lib/glut-3.7.6/progs/advanced97/csg.c new file mode 100644 index 0000000000..ab10611141 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/csg.c @@ -0,0 +1,1408 @@ +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define TRUE 1 +#define FALSE 0 + +/* + * #define the following symbol if you know your glClear honors the + * stencil mask. The O2 workstation stencil clear doesn't appear + * to honor the mask, so we use a workaround. The workaround may work + * on any other OpenGL which has this clear bug. + */ +#undef CLEAR_HONORS_STENCIL_MASK + + +GLUquadricObj *quadric; + + +int doCSG = 0; +int whereToStop = -1; +typedef enum {CONTINUE, STOP} progressEnum; +int whichTree = 0; +int showSurfaces = 1; +int showOnlyCurrent = 0; +int stenSize; +enum {COLOR, DEPTH, STENCILVALUES, STENCILPLANES} bufferInterest = COLOR; + + +void drawFace(void) +{ + glBegin(GL_QUADS); + glNormal3i(0, 0, 1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glEnd(); +} + + +void drawBox(void) +{ + glPushMatrix(); + + drawFace(); + + glRotatef(90, 1, 0, 0); + drawFace(); + + glRotatef(90, 1, 0, 0); + drawFace(); + + glRotatef(90, 1, 0, 0); + drawFace(); + + glPopMatrix(); + + glPushMatrix(); + + glRotatef(90, 0, 1, 0); + drawFace(); + + glRotatef(180, 0, 1, 0); + drawFace(); + + glPopMatrix(); +} + + +void drawCylinder(void) +{ + glPushMatrix(); + + glTranslatef(0, 0, -.5); + gluCylinder(quadric, 1, 1, 1, 30, 5); + + glRotatef(180, 0, 1, 0); + gluDisk(quadric, 0, 1, 30, 2); + + glPopMatrix(); + + glPushMatrix(); + + glTranslatef(0, 0, .5); + gluDisk(quadric, 0, 1, 30, 2); + + glPopMatrix(); +} + + +void drawCone(void) +{ + glPushMatrix(); + + glTranslatef(0, 0, -.5); + gluCylinder(quadric, 1, 0, 1, 30, 5); + + glRotatef(180, 0, 1, 0); + gluDisk(quadric, 0, 1, 30, 2); + + glPopMatrix(); +} + + +void drawSphere(void) +{ + gluSphere(quadric, 1, 30, 20); +} + + +struct transformation { + float translation[3]; + float rotation[4]; + float scale[3]; +}; + + +struct primitive { + float color[4]; + void (*draw)(void); + struct transformation xform; +}; + + +struct transformation globalXform = { + 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1 +}; + + +struct primitive prims[20] = { + { + {.5, .5, 1}, + drawBox, + { + -3, 0, 0, + 1, 0, 0, 0, + 1, 1, 1 + } + }, + { + {1, .5, .5}, + drawCylinder, + { + -1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1 + } + }, + { + {.5, 1, .5}, + drawCone, + { + 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1 + } + }, + { + {1, .5, 1}, + drawSphere, + { + 3, 0, 0, + 1, 0, 0, 0, + 1, 1, 1 + } + } +}; + + +int numPrims = 4; +int curPrim = 0; + + +void drawXform(struct transformation *xform, int applyScale) +{ + glTranslatef(xform->translation[0], xform->translation[1], xform->translation[2]); + glRotatef(xform->rotation[3] / M_PI * 180, xform->rotation[0], xform->rotation[1], xform->rotation[2]); + if(applyScale) + glScalef(xform->scale[0], xform->scale[1], xform->scale[2]); +} + + +int magicTranspHack = 0; + + +void drawPrim(int i) +{ + struct primitive *p = &prims[i]; + struct transformation *xform = &p->xform; + + if(magicTranspHack) + { + float c[4]; + c[0] = p->color[0]; + c[1] = p->color[1]; + c[2] = p->color[2]; + c[3] = .25; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, c); + } + else + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, p->color); + glPushMatrix(); + drawXform(xform, TRUE); + p->draw(); + glPopMatrix(); +} + + +struct product { + int targetPrim; + int frontFace; + int whichSurface; + int numTrimPrims; + int *trimmingPrims; + int *isComplemented; +}; + + +int prodAtrimmingPrims1[] = {1}; +int prodAisComplemented1[] = {1}; +int prodBtrimmingPrims1[] = {0}; +int prodBisComplemented1[] = {0}; + + +int prodAtrimmingPrims2[] = {1}; +int prodAisComplemented2[] = {0}; +int prodBtrimmingPrims2[] = {0}; +int prodBisComplemented2[] = {1}; + + +int prodAtrimmingPrims3[] = {1}; +int prodAisComplemented3[] = {0}; +int prodBtrimmingPrims3[] = {0}; +int prodBisComplemented3[] = {0}; + + +int prodAtrimmingPrims4[] = {1, 2, 3}; +int prodAisComplemented4[] = {0, 1, 1}; +int prodBtrimmingPrims4[] = {1, 0, 2}; +int prodBisComplemented4[] = {0, 0, 1}; +int prodCtrimmingPrims4[] = {1, 0, 3}; +int prodCisComplemented4[] = {0, 0, 1}; +int prodDtrimmingPrims4[] = {0, 2, 3}; +int prodDisComplemented4[] = {0, 1, 1}; + + +struct product products[][4] = { + { /* A - B */ + { + 0, 1, 0, + 1, + prodAtrimmingPrims1, + prodAisComplemented1, + }, + { + 1, 0, 0, + 1, + prodBtrimmingPrims1, + prodBisComplemented1, + }, + }, + + { /* B - A */ + { + 0, 0, 0, + 1, + prodAtrimmingPrims2, + prodAisComplemented2, + }, + { + 1, 1, 0, + 1, + prodBtrimmingPrims2, + prodBisComplemented2, + }, + }, + + { /* A and B */ + { + 0, 1, 0, + 1, + prodAtrimmingPrims3, + prodAisComplemented3, + }, + { + 1, 1, 0, + 1, + prodBtrimmingPrims3, + prodBisComplemented3, + }, + }, + + { /* A and B - D - C */ + { + 0, 1, 0, + 3, + prodAtrimmingPrims4, + prodAisComplemented4, + }, + { + 3, 0, 0, + 3, + prodBtrimmingPrims4, + prodBisComplemented4, + }, + { + 2, 0, 0, + 3, + prodCtrimmingPrims4, + prodCisComplemented4, + }, + { + 1, 1, 0, + 3, + prodDtrimmingPrims4, + prodDisComplemented4, + }, + }, +}; + + +int numProducts[4] = {2, 2, 2, 4}; + + +int winWidth, winHeight; +GLfloat *depthSave = NULL; +GLubyte *stencilSave = NULL; +GLubyte *colorSave = NULL; + + +void resizeBuffers(void) +{ + if(colorSave != NULL) + free(colorSave); + colorSave = malloc(winWidth * winHeight * 4 * sizeof(GLubyte)); + if(depthSave != NULL) + free(depthSave); + depthSave = malloc(winWidth * winHeight * sizeof(GLfloat)); + stencilSave = (GLubyte *)depthSave; +} + + +void pushOrthoView(float left, float right, float bottom, float top, + float znear, float zfar) +{ + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(left, right, bottom, top, znear, zfar); +} + + +void popView(void) +{ + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + + +void copyDepthToColor(GLenum whichColorBuffer) +{ + int x, y; + GLfloat max, min; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, + depthSave); + + /* I'm sure this could be done much better with OpenGL */ + max = 0; + min = 1; + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] < min) + min = depthSave[winWidth * y + x]; + if(depthSave[winWidth * y + x] > max && depthSave[winWidth * y + x] < .999) + max = depthSave[winWidth * y + x]; + } + + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] <= max) + depthSave[winWidth * y + x] = 1 - (depthSave[winWidth * y + x] - min) / (max - min); + else + depthSave[winWidth * y + x] = 0; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_LUMINANCE , GL_FLOAT, depthSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +unsigned char stencilValueToColorMap[][3] = +{ + {255, 0, 0}, /* red */ + {255, 218, 0}, /* yellow */ + {72, 255, 0}, /* yellowish green */ + {0, 255, 145}, /* bluish cyan */ + {0, 145, 255}, /* cyanish blue */ + {72, 0, 255}, /* purplish blue */ + {255, 0, 218}, /* reddish purple */ +}; + + +void copyStencilValuesToColor(GLenum whichColorBuffer) +{ + int x, y; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, + stencilSave); + + /* I'm sure this could be done much better with OpenGL */ + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + int stencilValue; + + stencilValue = stencilSave[winWidth * y + x]; + + colorSave[(winWidth * y + x) * 3 + 0] = + stencilValueToColorMap[stencilValue % 7][0]; + colorSave[(winWidth * y + x) * 3 + 1] = + stencilValueToColorMap[stencilValue % 7][1]; + colorSave[(winWidth * y + x) * 3 + 2] = + stencilValueToColorMap[stencilValue % 7][2]; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, colorSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +/* + * XXX This function should make colors that identify individual bits in + * the stencil buffer, but it seems like too hard a problem to solve + * in five minutes. Fix later. + */ +void copyStencilPlanesToColor(GLenum whichColorBuffer) +{ + int x, y; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, + stencilSave); + + /* I'm sure this could be done much better with OpenGL */ + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + /* Have to think of something clever to do here */ + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, colorSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +void copyInterest(void) +{ + switch(bufferInterest) { + case COLOR: + break; /* Well, that's already there. */ + + case STENCILVALUES: + copyStencilValuesToColor(GL_BACK); + break; + + case STENCILPLANES: + copyStencilPlanesToColor(GL_BACK); + break; + + case DEPTH: + copyDepthToColor(GL_BACK); + break; + } +} + + +void axisamountToMat(float aa[], float mat[]) +{ + float c, s, t; + + c = (float)cos(aa[3]); + s = (float)sin(aa[3]); + t = 1.0f - c; + + mat[0] = t * aa[0] * aa[0] + c; + mat[1] = t * aa[0] * aa[1] + s * aa[2]; + mat[2] = t * aa[0] * aa[2] - s * aa[1]; + mat[3] = t * aa[0] * aa[1] - s * aa[2]; + mat[4] = t * aa[1] * aa[1] + c; + mat[5] = t * aa[1] * aa[2] + s * aa[0]; + mat[6] = t * aa[0] * aa[2] + s * aa[1]; + mat[7] = t * aa[1] * aa[2] - s * aa[0]; + mat[8] = t * aa[2] * aa[2] + c; +} + + +void matToAxisamount(float mat[], float aa[]) +{ + float c; + float s; + + c = (mat[0] + mat[4] + mat[8] - 1.0f) / 2.0f; + aa[3] = (float)acos(c); + s = (float)sin(aa[3]); + if(fabs(s / M_PI - (int)(s / M_PI)) < .0000001) + { + aa[0] = 0.0f; + aa[1] = 1.0f; + aa[2] = 0.0f; + } + else + { + aa[0] = (mat[5] - mat[7]) / (2.0f * s); + aa[1] = (mat[6] - mat[2]) / (2.0f * s); + aa[2] = (mat[1] - mat[3]) / (2.0f * s); + } +} + + +void multMat(float m1[], float m2[], float r[]) +{ + float t[9]; + int i; + + t[0] = m1[0] * m2[0] + m1[1] * m2[3] + m1[2] * m2[6]; + t[1] = m1[0] * m2[1] + m1[1] * m2[4] + m1[2] * m2[7]; + t[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2] * m2[8]; + t[3] = m1[3] * m2[0] + m1[4] * m2[3] + m1[5] * m2[6]; + t[4] = m1[3] * m2[1] + m1[4] * m2[4] + m1[5] * m2[7]; + t[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5] * m2[8]; + t[6] = m1[6] * m2[0] + m1[7] * m2[3] + m1[8] * m2[6]; + t[7] = m1[6] * m2[1] + m1[7] * m2[4] + m1[8] * m2[7]; + t[8] = m1[6] * m2[2] + m1[7] * m2[5] + m1[8] * m2[8]; + for(i = 0; i < 9; i++) + { + r[i] = t[i]; + } +} + + +void rotateTrackball(int dx, int dy, float rotation[4]) +{ + float dist; + float oldMat[9]; + float rotMat[9]; + float newRot[4]; + + dist = (float)sqrt((double)(dx * dx + dy * dy)); + if(fabs(dist) < 0.99) + return; + + newRot[0] = (float) dy / dist; + newRot[1] = (float) dx / dist; + newRot[2] = 0.0f; + newRot[3] = (float)M_PI * dist / winWidth; + + axisamountToMat(rotation, oldMat); + axisamountToMat(newRot, rotMat); + multMat(oldMat, rotMat, oldMat); + matToAxisamount(oldMat, rotation); + + dist = (float)sqrt(rotation[0] * rotation[0] + rotation[1] * rotation[1] + + rotation[2] * rotation[2]); + + rotation[0] /= dist; + rotation[1] /= dist; + rotation[2] /= dist; +} + + +struct transformation *curXform; + + +void init(void) +{ + glMatrixMode(GL_PROJECTION); + glFrustum(-.33, .33, -.33, .33, .5, 40); + + glMatrixMode(GL_MODELVIEW); + gluLookAt(0, 0, 7, 0, 0, 0, 0, 1, 0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_NORMALIZE); + + quadric = gluNewQuadric(); + + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + curXform = &prims[0].xform; +} + + +void setupLight(void) +{ + static GLfloat lightpos[] = {0, 1, 0, 0}; + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); +} + + +void redrawNoCSG(void) +{ + int i; + + glDisable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + drawXform(&globalXform, FALSE); + + for(i = 0; i < numPrims; i++) + { + if(i == curPrim || !showOnlyCurrent) + drawPrim(i); + } + + glPopMatrix(); + + copyInterest(); + + glutSwapBuffers(); +} + + +int whereSoFar; + + +GLfloat *depthResults = NULL; + + +void saveDepth(void) +{ + depthResults = realloc(depthResults, winWidth * winHeight * + sizeof(GLfloat)); + glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, + depthResults); +} + + +void restoreDepth(void) +{ + glStencilMask(0); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + + glDrawPixels(winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, + depthResults); + + popView(); +} + + +#define COPY_AND_RETURN_IF_DONE(s) \ + { \ + if(whereSoFar++ == whereToStop) { \ + printf("%s\n", s); \ + return(STOP); \ + } \ + } + + +#define COPY_AND_GOTO_IF_DONE(s) \ + { \ + if(whereSoFar++ == whereToStop) { \ + printf("%s\n", s); \ + goto doneWithFrame; \ + } \ + } + + +int sCountMask = 0x01; /* 1-convexity maximum */ +int sCountShift = 0; +int sPMask = 1; +int sPShift = 0; + + +void drawFarRect(void) +{ + pushOrthoView(0, 1, 0, 1, 0, 1); + + /* Can I just draw & let be clipped? */ + glBegin(GL_QUADS); + glVertex3f(0, 0, -1); + glVertex3f(1, 0, -1); + glVertex3f(1, 1, -1); + glVertex3f(0, 1, -1); + glEnd(); + + popView(); +} + + +progressEnum renderPrimDepths(int targetPrim, int frontFace, int whichSurface) +{ + glClear(GL_DEPTH_BUFFER_BIT); + + + glDepthFunc(GL_ALWAYS); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilMask(sCountMask); + +#ifndef CLEAR_HONORS_STENCIL_MASK /* see comment at beginning of source */ + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + drawFarRect(); + + COPY_AND_RETURN_IF_DONE("After clearing p bit in stencil"); + +#else + + glClearStencil(0); + glClear(GL_STENCIL_BUFFER_BIT); + +#endif + + glEnable(GL_CULL_FACE); + if(frontFace) + glCullFace(GL_BACK); + else + glCullFace(GL_FRONT); + + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + + glStencilFunc(GL_EQUAL, whichSurface, sCountMask); + glStencilOp(GL_INCR, GL_INCR, GL_INCR); + + drawPrim(targetPrim); + + return(CONTINUE); +} + + +progressEnum trimWithPrimitive(int trimPrim, int isComplemented) +{ + glDepthFunc(GL_LESS); + glEnable(GL_STENCIL_TEST); + glDepthMask(GL_FALSE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilMask(sPMask); + glDisable(GL_CULL_FACE); + +#ifndef CLEAR_HONORS_STENCIL_MASK /* see comment at beginning of source */ + + glDisable(GL_DEPTH_TEST); + + glStencilFunc(GL_ALWAYS, isComplemented ? (1 << sPShift) : 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + drawFarRect(); + +#else + + glClearStencil(isComplemented ? (1 << sPShift) : 0); + glClear(GL_STENCIL_BUFFER_BIT); + +#endif + + glEnable(GL_DEPTH_TEST); + glStencilFunc(GL_ALWAYS, 0, 0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); + drawPrim(trimPrim); + + COPY_AND_RETURN_IF_DONE("After setting stencil to mark depths " + "inside trimming primitive"); + + /* stencil == 0 where pixels were not inside */ + /* so now set Z to far where stencil == 0, everywhere pixels trimmed */ + + glStencilFunc(GL_EQUAL, 0, sPMask); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDepthMask(1); + glDepthFunc(GL_ALWAYS); + glDisable(GL_LIGHTING); + drawFarRect(); + glEnable(GL_LIGHTING); + + COPY_AND_RETURN_IF_DONE("After clearing depths where target outside " + "trimming primitive"); + + return(CONTINUE); +} + + +progressEnum markProductPixels(int product, int accumBit) +{ + int i; + + struct product *p; + + p = &products[whichTree][product]; + + if(renderPrimDepths(p->targetPrim, p->frontFace, p->whichSurface) == STOP) + return(STOP); + + COPY_AND_RETURN_IF_DONE("After rendering target depths"); + + for(i = 0; i < p->numTrimPrims; i++) + { + if(trimWithPrimitive(p->trimmingPrims[i], p->isComplemented[i]) == STOP) + return(STOP); + } + + COPY_AND_RETURN_IF_DONE("After target has been trimmed by all " + "trimming primitives"); + + /* set accumulator stencil bit for this primitive everywhere depth != far */ + glStencilFunc(GL_ALWAYS, 1 << accumBit, 0); + glStencilOp(GL_KEEP, GL_ZERO, GL_REPLACE); + glStencilMask(1 << accumBit); + glDepthMask(0); + glDepthFunc(GL_GREATER); + glDisable(GL_LIGHTING); + drawFarRect(); + glEnable(GL_LIGHTING); + + COPY_AND_RETURN_IF_DONE("After setting accumulator where depths != far"); + + return(CONTINUE); +} + + +progressEnum drawProduct(int product, int accumBit) +{ + struct product *p; + p = &products[whichTree][product]; + + glEnable(GL_CULL_FACE); + if(p->frontFace) + glCullFace(GL_BACK); + else + glCullFace(GL_FRONT); + + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_EQUAL, 1 << accumBit, 1 << accumBit); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + drawPrim(p->targetPrim); + + COPY_AND_RETURN_IF_DONE("After drawing target color and depth"); + + return(CONTINUE); +} + + +void redrawCSG(void) +{ + int i; + int accumBit; + int firstProduct; + int lastProduct; + + whereSoFar = 0; + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT); + + /* Only have to do this if you're going to look at the stencil buffer */ + glClearStencil(0); + glStencilMask((1 << stenSize) - 1); + glClear(GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + + drawXform(&globalXform, FALSE); + + firstProduct = 0; + + while(firstProduct != numProducts[whichTree]) { + + /* + * set lastProduct so that accum bits for first to last fit in + * stencil buffer minus bits needed for surface counting bits + */ + lastProduct = firstProduct + (stenSize - 1) - 1; + if(lastProduct >= numProducts[whichTree]) + lastProduct = numProducts[whichTree] - 1; + + if(firstProduct > 0) /* know depth is clear before 1st group */ + saveDepth(); + + accumBit = 1; /* first available after counting bits */ + + for(i = firstProduct; i <= lastProduct; i++) + if(markProductPixels(i, accumBit++) == STOP) + goto doneWithFrame; + + COPY_AND_GOTO_IF_DONE("After marking \"inside\" target accumulators"); + + if(firstProduct > 0) /* know depth was clear before first group */ + restoreDepth(); + else { + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + } + + accumBit = 1; /* first available after counting bits */ + + for(i = firstProduct; i <= lastProduct; i++) + if(drawProduct(i, accumBit++) == STOP) + goto doneWithFrame; + + COPY_AND_GOTO_IF_DONE("After drawing all target colors and depths"); + + firstProduct = lastProduct + 1; + } + + if(showSurfaces) { + glDisable(GL_STENCIL_TEST); + glDepthMask(GL_FALSE); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glEnable(GL_BLEND); + magicTranspHack = 1; + for(i = 0; i < numProducts[whichTree]; i++) + { + struct product *p; + p = &products[whichTree][i]; + + if(i == curPrim || !showOnlyCurrent) + drawPrim(p->targetPrim); + } + magicTranspHack = 0; + glDisable(GL_BLEND); + } + +doneWithFrame: + + glPopMatrix(); + + copyInterest(); + glutSwapBuffers(); +} + + +enum trackballModeEnum { + ROTATE, + TRANSLATEXY, + TRANSLATEZ, + SCALEX, + SCALEY, + SCALEZ +} trackballMode = ROTATE; + + +/* ARGSUSED1 */ +void special(int thing, int x, int y) +{ + switch(thing) { + case GLUT_KEY_F1: + prims[curPrim].draw = drawBox; + glutPostRedisplay(); + break; + + case GLUT_KEY_F2: + prims[curPrim].draw = drawCylinder; + glutPostRedisplay(); + break; + + case GLUT_KEY_F3: + prims[curPrim].draw = drawCone; + glutPostRedisplay(); + break; + + case GLUT_KEY_F4: + prims[curPrim].draw = drawSphere; + glutPostRedisplay(); + break; + } +} + +/* ARGSUSED1 */ +void keyboard(unsigned char key, int x, int y) +{ + switch(key) + { + case '1': + case '2': + case '3': + case '4': + whichTree = key - '1'; + glutPostRedisplay(); + break; + + case 'r': + trackballMode = ROTATE; + break; + + case 't': + trackballMode = TRANSLATEXY; + break; + + case 'T': + trackballMode = TRANSLATEZ; + break; + + case 'x': + trackballMode = SCALEX; + break; + + case 'y': + trackballMode = SCALEY; + break; + + case 'z': + trackballMode = SCALEZ; + break; + + case 'q': case 'Q': case '\033': + exit(0); + break; + + case '<': case ',': + if(curXform != &globalXform) + { + curPrim = (curPrim - 1 + numPrims) % numPrims; + curXform = &prims[curPrim].xform; + printf("Manipulating transformation for object %d\n", curPrim); + } + else + { + printf("Have to toggle out of global mode first\n"); + } + glutPostRedisplay(); + break; + + case '>': case '.': + if(curXform != &globalXform) + { + curPrim = (curPrim + 1) % numPrims; + curXform = &prims[curPrim].xform; + printf("Manipulating transformation for object %d\n", curPrim); + } + else + { + printf("Have to toggle out of global mode first\n"); + } + break; + + case 'g': + if(curXform == &globalXform){ + curXform = &prims[curPrim].xform; + printf("Manipulating transformation for object %d\n", curPrim); + }else{ + curXform = &globalXform; + printf("Manipulating global transformation\n"); + } + break; + + case '+': case '=': + whereToStop++; + glutPostRedisplay(); + break; + + case '-': case '_': + whereToStop--; + glutPostRedisplay(); + break; + + case 's': + glutPostRedisplay(); + showSurfaces = !showSurfaces; + break; + + case 'c': + doCSG = ! doCSG; + if(doCSG) + glutDisplayFunc(redrawCSG); + else + glutDisplayFunc(redrawNoCSG); + glutPostRedisplay(); + break; + + case ' ': + showOnlyCurrent = !showOnlyCurrent; + glutPostRedisplay(); + break; + } +} + + +static int ox, oy; + +/* ARGSUSED */ +void button(int b, int state, int x, int y) +{ + ox = x; + oy = y; +} + +void motion(int x, int y) +{ + int dx, dy; + + dx = x - ox; + dy = y - oy; + + ox = x; + oy = y; + + switch(trackballMode) { + case ROTATE: + rotateTrackball(dx, dy, curXform->rotation); + break; + + case SCALEX: + curXform->scale[0] += (dx + dy) / 40.0f; + if(curXform->scale[0] < 1/40.0) + curXform->scale[0] = 1/40.0; + break; + + case SCALEY: + curXform->scale[1] += (dx + dy) / 40.0f; + if(curXform->scale[1] < 1/40.0) + curXform->scale[1] = 1/40.0; + break; + + case SCALEZ: + curXform->scale[2] += (dx + dy) / 40.0f; + if(curXform->scale[2] < 1/40.0) + curXform->scale[2] = 1/40.0; + break; + + case TRANSLATEXY: + curXform->translation[0] += dx / 40.0f; + curXform->translation[1] -= dy / 40.0f; + break; + + case TRANSLATEZ: + curXform->translation[2] += (dx + dy) / 40.0f; + break; + } + glutPostRedisplay(); +} + + +void reshape(int width, int height) +{ + glViewport(0, 0, width, height); + winWidth = width; + winHeight = height; + resizeBuffers(); + glutPostRedisplay(); +} + + +int mainMenu; + + +void mainMenuFunc(int choice) +{ + switch(choice) + { + case 1: + doCSG = !doCSG; + if(doCSG) { + printf("CSG expression on\n"); + glutDisplayFunc(redrawCSG); + glutChangeToMenuEntry(1, "Turn off CSG", 0); + } + else { + printf("CSG expression off\n"); + glutDisplayFunc(redrawNoCSG); + glutChangeToMenuEntry(1, "Turn on CSG", 0); + } + glutPostRedisplay(); + break; + case 2: + showSurfaces = !showSurfaces; + if(showSurfaces) { + printf("Transparent surfaces on\n"); + glutChangeToMenuEntry(2, "(s) Don't show objects transparent in CSG", 2); + } + else { + printf("Transparent surfaces off\n"); + glutChangeToMenuEntry(2, "(s) Show objects transparent in CSG", 2); + } + glutPostRedisplay(); + break; + } +} + + +void interestBufferFunc(int data) +{ + char *s; + + bufferInterest = data; + + switch(data) { + case COLOR: + s = "color"; + break; + + case STENCILVALUES: + s = "stencil values"; + break; + + case STENCILPLANES: + s = "individual stencil plane converage"; + break; + + case DEPTH: + s = "depth"; + break; + } + printf("Now displaying %s data\n", s); + glutPostRedisplay(); +} + + +void csgMenuFunc(int data) +{ + whichTree = data; + glutPostRedisplay(); +} + + +void whichObjectFunc(int data) +{ + switch(data) + { + case 0: + case 1: + case 2: + case 3: + curPrim = data; + curXform = &prims[curPrim].xform; + printf("Editing object %d\n", data); + break; + + case 4: + curXform = &globalXform; + printf("Editing global transformation %d\n", data); + break; + } +} + + +void morphMenuFunc(int data) +{ + switch(data) { + case 0: + prims[curPrim].draw = drawBox; + glutPostRedisplay(); + break; + + case 1: + prims[curPrim].draw = drawCylinder; + glutPostRedisplay(); + break; + + case 2: + prims[curPrim].draw = drawCone; + glutPostRedisplay(); + break; + + case 3: + prims[curPrim].draw = drawSphere; + glutPostRedisplay(); + break; + } +} + + +void helpFakeFunc(int d) +{ +} + + +int main(int argc, char **argv) +{ + int bufferMenu; + int csgMenu; + int whichObjectMenu; + int morphMenu; + int helpFakeMenu; + + glutInitWindowSize(512,512); + glutInit(&argc, argv); + glutInitDisplayString("samples stencil>=3 rgb double depth"); + /* glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_DEPTH|GLUT_RGBA); */ + (void)glutCreateWindow("csg using stencil"); + glutDisplayFunc(redrawNoCSG); + glutKeyboardFunc(keyboard); + glutSpecialFunc(special); + glutMotionFunc(motion); + glutMouseFunc(button); + glutReshapeFunc(reshape); + + glGetIntegerv(GL_STENCIL_BITS, &stenSize); + printf("%d bits of stencil available in this visual\n", stenSize); + + printf("Hit 'S' to turn stencil on/off\n"); + + bufferMenu = glutCreateMenu(interestBufferFunc); + glutAddMenuEntry("Color data", COLOR); + glutAddMenuEntry("Stencil values", STENCILVALUES); + glutAddMenuEntry("Coverage in each stencil plane", STENCILPLANES); + glutAddMenuEntry("Depth data", DEPTH); + + csgMenu = glutCreateMenu(csgMenuFunc); + glutAddMenuEntry("(1) obj 1 MINUS obj 2", 0); + glutAddMenuEntry("(2) obj 2 MINUS obj 1", 1); + glutAddMenuEntry("(3) obj 1 AND obj 2", 2); + glutAddMenuEntry("(4) (obj 1 AND obj 2) MINUS (obj 3 or obj 4)", 3); + + whichObjectMenu = glutCreateMenu(whichObjectFunc); + glutAddMenuEntry("Object 1 (blue)", 0); + glutAddMenuEntry("Object 2 (peach)", 1); + glutAddMenuEntry("Object 3 (green)", 2); + glutAddMenuEntry("Object 4 (purple)", 3); + glutAddMenuEntry("(g) Toggle between global and local", 4); + + morphMenu = glutCreateMenu(morphMenuFunc); + glutAddMenuEntry("(F1) Box", 0); + glutAddMenuEntry("(F2) Cylinder", 1); + glutAddMenuEntry("(F3) Cone", 2); + glutAddMenuEntry("(F4) Sphere", 3); + + helpFakeMenu = glutCreateMenu(helpFakeFunc); + glutAddMenuEntry("Click the left mouse button and drag to manipulate\n", 0); + glutAddMenuEntry("Push 'r' to rotate like a trackball\n", 0); + glutAddMenuEntry("Push 't' to translate in the X-Y plane\n", 0); + glutAddMenuEntry("Push 'T' to translate in the Z axis\n", 0); + glutAddMenuEntry("Push 'X' to scale in X\n", 0); + glutAddMenuEntry("Push 'X' to scale in Y\n", 0); + glutAddMenuEntry("Push 'Z' to scale in Z\n", 0); + + mainMenu = glutCreateMenu(mainMenuFunc); + glutAddMenuEntry("(c) Turn on CSG", 1); + glutAddMenuEntry("(s) Show objects transparent in CSG", 2); + glutAddSubMenu("Buffer of interest", bufferMenu); + glutAddSubMenu("Which CSG expression", csgMenu); + glutAddSubMenu("Object for manipulation", whichObjectMenu); + glutAddSubMenu("Turn current object into...", morphMenu); + glutAddSubMenu("Help with moving and rotating:", helpFakeMenu); + glutAttachMenu(GLUT_RIGHT_BUTTON); + init(); + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/csg.dsp b/lib/glut-3.7.6/progs/advanced97/csg.dsp new file mode 100644 index 0000000000..5157a741d7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/csg.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="csg" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=csg - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "csg.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "csg.mak" CFG="csg - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "csg - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "csg - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "csg - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "csg - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "csg - Win32 Release" +# Name "csg - Win32 Debug" +# Begin Source File + +SOURCE=.\csg.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/d.c b/lib/glut-3.7.6/progs/advanced97/d.c new file mode 100644 index 0000000000..ff0cd8b335 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/d.c @@ -0,0 +1,129 @@ +#include +#include "stdlib.h" +#include "math.h" + +typedef enum { + RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE, + LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR +} displayLists; + +/* *INDENT-OFF* */ +GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5}, + {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16}, + {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2}, + {1, 2} }; +GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9}, + {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10}, + {13, 9}, {11, 11}, {9, 11} }; +GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0}, + {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} }; +GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15}, + {9.6, 15.25}, {9, 15.25} }; +GLfloat lightZeroPosition[] = {10.0, 4.0, 10.0, 1.0}; +GLfloat lightZeroColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */ +GLfloat lightOnePosition[] = {-1.0, -2.0, 1.0, 0.0}; +GLfloat lightOneColor[] = {0.6, 0.3, 0.2, 1.0}; /* red-tinted */ +GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0}; +/* *INDENT-ON* */ + +void +extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, + GLdouble thickness, GLuint side, GLuint edge, GLuint whole) +{ + static GLUtriangulatorObj *tobj = NULL; + GLdouble vertex[3], dx, dy, len; + int i; + int count = dataSize / (int) (2 * sizeof(GLfloat)); + + if (tobj == NULL) { + tobj = gluNewTess(); /* create and initialize a GLU + polygon tesselation object */ + gluTessCallback(tobj, GLU_BEGIN, glBegin); + gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ + gluTessCallback(tobj, GLU_END, glEnd); + } + glNewList(side, GL_COMPILE); + glShadeModel(GL_SMOOTH); /* smooth minimizes seeing + tessellation */ + gluBeginPolygon(tobj); + for (i = 0; i < count; i++) { + vertex[0] = data[i][0]; + vertex[1] = data[i][1]; + vertex[2] = 0; + gluTessVertex(tobj, vertex, data[i]); + } + gluEndPolygon(tobj); + glEndList(); + glNewList(edge, GL_COMPILE); + glShadeModel(GL_FLAT); /* flat shade keeps angular hands + from being "smoothed" */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= count; i++) { + /* mod function handles closing the edge */ + glVertex3f(data[i % count][0], data[i % count][1], 0.0); + glVertex3f(data[i % count][0], data[i % count][1], thickness); + /* Calculate a unit normal by dividing by Euclidean + distance. We * could be lazy and use + glEnable(GL_NORMALIZE) so we could pass in * arbitrary + normals for a very slight performance hit. */ + dx = data[(i + 1) % count][1] - data[i % count][1]; + dy = data[i % count][0] - data[(i + 1) % count][0]; + len = sqrt(dx * dx + dy * dy); + glNormal3f(dx / len, dy / len, 0.0); + } + glEnd(); + glEndList(); + glNewList(whole, GL_COMPILE); + glFrontFace(GL_CW); + glCallList(edge); + glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ + glCallList(side); + glPushMatrix(); + glTranslatef(0.0, 0.0, thickness); + glFrontFace(GL_CCW); + glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ + glCallList(side); + glPopMatrix(); + glEndList(); +} + +void +makeDinosaur(void) +{ + GLfloat bodyWidth = 3.0; + + extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, + BODY_SIDE, BODY_EDGE, BODY_WHOLE); + extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4, + ARM_SIDE, ARM_EDGE, ARM_WHOLE); + extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2, + LEG_SIDE, LEG_EDGE, LEG_WHOLE); + extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, + EYE_SIDE, EYE_EDGE, EYE_WHOLE); + glNewList(DINOSAUR, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); + glCallList(BODY_WHOLE); + glPushMatrix(); + glTranslatef(0.0, 0.0, bodyWidth); + glCallList(ARM_WHOLE); + glCallList(LEG_WHOLE); + glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); + glCallList(ARM_WHOLE); + glTranslatef(0.0, 0.0, -bodyWidth / 4); + glCallList(LEG_WHOLE); + glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); + glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); + glCallList(EYE_WHOLE); + glPopMatrix(); + glEndList(); +} + +void +drawDinosaur(void) { + static int first = 1; + if (first) { + makeDinosaur(); + first = 0; + } + glCallList(DINOSAUR); +} diff --git a/lib/glut-3.7.6/progs/advanced97/decal.c b/lib/glut-3.7.6/progs/advanced97/decal.c new file mode 100644 index 0000000000..6dc6c5726d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/decal.c @@ -0,0 +1,611 @@ +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +GLUquadricObj *quadric; +GLfloat black[] = {0, 0, 0, 1}; +GLfloat white[] = {1, 1, 1, 1}; + + +int winWidth, winHeight; +GLfloat *depthSave = NULL; +GLubyte *stencilSave = NULL; +GLubyte *colorSave = NULL; + + +void resizeBuffers(void) +{ + colorSave = realloc(colorSave, winWidth * winHeight * 4 * sizeof(GLubyte)); + depthSave = realloc(depthSave, winWidth * winHeight * 4 * sizeof(GLfloat)); + stencilSave = (GLubyte *)depthSave; +} + + +void pushOrthoView(float left, float right, float bottom, float top, + float znear, float zfar) +{ + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(left, right, bottom, top, znear, zfar); +} + + +void popView(void) +{ + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + + +void copyDepthToColor(GLenum whichColorBuffer) +{ + int x, y; + GLfloat max, min; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, + depthSave); + + /* I'm sure this could be done much better with OpenGL */ + max = 0; + min = 1; + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] < min) + min = depthSave[winWidth * y + x]; + if(depthSave[winWidth * y + x] > max && depthSave[winWidth * y + x] < .999) + max = depthSave[winWidth * y + x]; + } + + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] <= max) + depthSave[winWidth * y + x] = 1 - (depthSave[winWidth * y + x] - min) / (max - min); + else + depthSave[winWidth * y + x] = 0; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_LUMINANCE , GL_FLOAT, depthSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +unsigned char colors[][3] = +{ + {255, 0, 0}, /* red */ + {255, 218, 0}, /* yellow */ + {72, 255, 0}, /* yellowish green */ + {0, 255, 145}, /* bluish cyan */ + {0, 145, 255}, /* cyanish blue */ + {72, 0, 255}, /* purplish blue */ + {255, 0, 218}, /* reddish purple */ +}; + + +void copyStencilToColor(GLenum whichColorBuffer) +{ + int x, y; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, + stencilSave); + + /* I'm sure this could be done much better with OpenGL */ + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + int stencilValue; + + stencilValue = stencilSave[winWidth * y + x]; + + colorSave[(winWidth * y + x) * 3 + 0] = colors[stencilValue % 7][0]; + colorSave[(winWidth * y + x) * 3 + 1] = colors[stencilValue % 7][1]; + colorSave[(winWidth * y + x) * 3 + 2] = colors[stencilValue % 7][2]; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, colorSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +int useStencil = 0; +int stage = 6; +typedef enum {COLOR, DEPTH, STENCIL} DataChoice; +DataChoice dataChoice = COLOR; + +void init(void) +{ + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + quadric = gluNewQuadric(); + + glMatrixMode(GL_PROJECTION); + glFrustum(-.33, .33, -.33, .33, .5, 40); + + glMatrixMode(GL_MODELVIEW); + gluLookAt(-4, 10, 6, 0, 0, 0, 0, 1, 0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_NORMALIZE); + + /* + * only need this to clear stencil and only need to clear stencil + * when you're looking at it; the algorithm works without it. + */ + glClearStencil(5); +} + + +void setupLight(void) +{ + static GLfloat lightpos[] = {0, 1, 0, 0}; + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); +} + + +void setupNormalDrawingState(void) +{ + glDisable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + glDepthMask(1); +} + +void setupBasePolygonState(int maxDecal) +{ + glEnable(GL_DEPTH_TEST); + if(useStencil) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, maxDecal + 1, 0xff); + glStencilOp(GL_KEEP, GL_REPLACE, GL_ZERO); + } +} + + +void setupDecalState(int decalNum) +{ + if(useStencil) { + glDisable(GL_DEPTH_TEST); + glDepthMask(0); + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_GREATER, decalNum, 0xff); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } +} + + +void drawAirplane(void) +{ + GLfloat airplaneColor[4] = {.75, .75, .75, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, airplaneColor); + + glDisable(GL_CULL_FACE); + + glPushMatrix(); + glTranslatef(0, 0, -2.5); + + gluCylinder(quadric, .5, .5, 5, 10, 10); + + glPushMatrix(); + glTranslatef(0, 0, 5); + gluCylinder(quadric, .5, 0, 1, 10, 10); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0, 0, 3); + glScalef(3, .1, 1); + gluSphere(quadric, 1, 10, 10); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0, 0, .5); + glScalef(2, .1, .5); + gluSphere(quadric, 1, 10, 10); + glPopMatrix(); + + glEnable(GL_CULL_FACE); + + glBegin(GL_TRIANGLES); + glNormal3f(1, 0, 0); + glVertex3f(0, 1.5, 0); + glVertex3f(0, .5, 1); + glVertex3f(0, .5, 0); + glNormal3f(-1, 0, 0); + glVertex3f(0, 1.5, 0); + glVertex3f(0, .5, 0); + glVertex3f(0, .5, 1); + glEnd(); + + glDisable(GL_CULL_FACE); + + glRotatef(180, 0, 1, 0); + gluDisk(quadric, 0, .5, 10, 10); + + glPopMatrix(); + + glEnable(GL_CULL_FACE); +} + + +void drawGround(void) +{ + GLfloat groundColor[4] = {.647, .165, .165, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, groundColor); + + glBegin(GL_QUADS); + glNormal3i(0, 1, 0); + glVertex3f(10, 0, 10); + glVertex3f(10, 0, -10); + glVertex3f(-10, 0, -10); + glVertex3f(-10, 0, 10); + glEnd(); +} + + +void drawAsphalt(void) +{ + GLfloat asphaltColor[4] = {.25, .25, .25, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, asphaltColor); + + glBegin(GL_QUADS); + glNormal3i(0, 1, 0); + glVertex3f(5, 0, 9.5); + glVertex3f(5, 0, -9.5); + glVertex3f(-5, 0, -9.5); + glVertex3f(-5, 0, 9.5); + glEnd(); +} + + +int numStripes = 5; +float stripeGap = .66; + + +void drawStripes(void) +{ + GLfloat stripeColor[4] = {1, 1, 0, 1}; + int i; + float stripeLength; + + stripeLength = (16 - stripeGap * (numStripes - 1)) / numStripes; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, stripeColor); + + glBegin(GL_QUADS); + + glNormal3i(0, 1, 0); + + glVertex3f(4.5, 0, 8.5); + glVertex3f(4.5, 0, -8.5); + glVertex3f(3.5, 0, -8.5); + glVertex3f(3.5, 0, 8.5); + + glVertex3f(-3.5, 0, 8.5); + glVertex3f(-3.5, 0, -8.5); + glVertex3f(-4.5, 0, -8.5); + glVertex3f(-4.5, 0, 8.5); + + for(i = 0; i < numStripes; i++) { + glVertex3f(.5, 0, 8 - i * (stripeLength + stripeGap)); + glVertex3f(.5, 0, 8 - i * (stripeLength + stripeGap) - stripeLength); + glVertex3f(-.5, 0, 8 - i * (stripeLength + stripeGap) - stripeLength); + glVertex3f(-.5, 0, 8 - i * (stripeLength + stripeGap)); + } + glEnd(); +} + + +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* Only need this if you care to look at the stencil buffer */ + if(dataChoice == STENCIL) + glClear(GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + glScalef(.5, .5, .5); + + if(stage == 1) + goto doneWithFrame; + + setupLight(); + + setupNormalDrawingState(); + glPushMatrix(); + glTranslatef(0, 1, 4); + glRotatef(135, 0, 1, 0); + drawAirplane(); + glPopMatrix(); + + if(stage == 2) + goto doneWithFrame; + + setupBasePolygonState(3); /* 2 decals */ + drawGround(); + + if(stage == 3) + goto doneWithFrame; + + setupDecalState(1); /* decal # 1 = the runway asphalt */ + drawAsphalt(); + + if(stage == 4) + goto doneWithFrame; + + setupDecalState(2); /* decal # 2 = yellow paint on the runway */ + drawStripes(); + + if(stage == 5) + goto doneWithFrame; + + setupDecalState(3); /* decal # 3 = the plane's shadow */ + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glPushMatrix(); + glColor4f(0, 0, 0, .5); + glTranslatef(0, 0, 4); + glRotatef(135, 0, 1, 0); + glScalef(1, 0, 1); + drawAirplane(); + glPopMatrix(); + glDisable(GL_BLEND); + glEnable(GL_LIGHTING); + +doneWithFrame: + + setupNormalDrawingState(); + + glPopMatrix(); + + switch(dataChoice) { + case COLOR: + break; /* color already in back buffer */ + + case STENCIL: + copyStencilToColor(GL_BACK); + break; + + case DEPTH: + copyDepthToColor(GL_BACK); + break; + } + + glutSwapBuffers(); +} + + +void reshape(int width, int height) +{ + glViewport(0, 0, width, height); + winWidth = width; + winHeight = height; + resizeBuffers(); + glutPostRedisplay(); +} + + +static int ox, oy; +static int mode; + + +/* ARGSUSED */ +void button(int b, int state, int x, int y) +{ + ox = x; + oy = y; + mode = b; +} + + +void motion(int x, int y) +{ + static float ang = 0; + static float height = 10; + float eyex, eyez; + + if(mode == GLUT_LEFT_BUTTON) + { + ang += (x - ox) / 512.0 * M_PI; + height += (y - oy) / 512.0 * 10; + eyex = cos(ang) * 7; + eyez = sin(ang) * 7; + glLoadIdentity(); + gluLookAt(eyex, height, eyez, 0, 0, 0, 0, 1, 0); + glutPostRedisplay(); + ox = x; + oy = y; + } +} + + +void changeData(int data) +{ + char *s; + + dataChoice = data; + glutPostRedisplay(); + + switch(data) { + case COLOR: + s = "color"; + break; + + case STENCIL: + s = "stencil"; + break; + + case DEPTH: + s = "depth"; + break; + } + printf("Now displaying %s data\n", s); +} + + +void changeStage(int data) +{ + char *s; + + stage = data; + glutPostRedisplay(); + switch(data) { + case 1: + s = "clearing"; + break; + + case 2: + s = "drawing airplane"; + break; + + case 3: + s = "drawing ground"; + break; + + case 4: + s = "drawing asphalt"; + break; + + case 5: + s = "drawing paint"; + break; + + case 6: + s = "drawing shadow"; + break; + } + printf("Now displaying frame after %s\n", s); +} + + +int mainMenu; + +void stencilDecalEnable(int enabled) +{ + glutSetMenu(mainMenu); + if(enabled){ + glutChangeToMenuEntry(1, "Turn off stencil decal", 0); + printf("Stencil decaling turned on\n"); + glutPostRedisplay(); + } else { + glutChangeToMenuEntry(1, "Turn on stencil decal", 1); + printf("Stencil decaling turned off\n"); + glutPostRedisplay(); + } + useStencil = enabled; +} + + +/* + * Basically shortcuts for menu items + */ +/* ARGSUSED1 */ +void keyboard(unsigned char key, int x, int y) +{ + switch(key) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + changeStage(key - '0'); + break; + + case 's': case 'S': + stencilDecalEnable(! useStencil); + break; + + case 'q': case 'Q': case '\033': + exit(0); + break; + + default: + fprintf(stderr, "Push right mouse button for menu\n"); + break; + } +} + + +int main(int argc, char **argv) +{ + int bufferMenu; + int finishMenu; + int stenSize; + + glutInitWindowSize(winWidth = 512, winHeight = 512); + glutInit(&argc, argv); + glutInitDisplayString("samples stencil>=3 rgb double depth"); + /* glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_DEPTH|GLUT_ALPHA); */ + (void)glutCreateWindow("decaling using stencil"); + glutDisplayFunc(redraw); + glutKeyboardFunc(keyboard); + glutMotionFunc(motion); + glutMouseFunc(button); + glutReshapeFunc(reshape); + + resizeBuffers(); + glGetIntegerv(GL_STENCIL_BITS, &stenSize); + fprintf(stderr, "(%d bits of stencil available in this visual)\n", stenSize); + + fprintf(stderr, "Hit 'h' for help message\n"); + + finishMenu = glutCreateMenu(changeStage); + glutAddMenuEntry("Clearing screen", 1); + glutAddMenuEntry("Drawing airplane", 2); + glutAddMenuEntry("Drawing ground ", 3); + glutAddMenuEntry("Drawing asphalt", 4); + glutAddMenuEntry("Drawing paint", 5); + glutAddMenuEntry("Drawing shadow", 6); + + bufferMenu = glutCreateMenu(changeData); + glutAddMenuEntry("Color data", COLOR); + glutAddMenuEntry("Stencil data", STENCIL); + glutAddMenuEntry("Depth data", DEPTH); + + mainMenu = glutCreateMenu(stencilDecalEnable); + glutAddMenuEntry("Turn on stencil decal", 1); + glutAddSubMenu("Visible buffer", bufferMenu); + glutAddSubMenu("Finish frame after...", finishMenu); + glutAttachMenu(GLUT_RIGHT_BUTTON); + init(); + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/decal.dsp b/lib/glut-3.7.6/progs/advanced97/decal.dsp new file mode 100644 index 0000000000..b0c8bccdd4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/decal.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="decal" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=decal - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "decal.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "decal.mak" CFG="decal - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "decal - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "decal - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "decal - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "decal - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "decal - Win32 Release" +# Name "decal - Win32 Debug" +# Begin Source File + +SOURCE=.\decal.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/dissolve.c b/lib/glut-3.7.6/progs/advanced97/dissolve.c new file mode 100644 index 0000000000..a09011cc62 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/dissolve.c @@ -0,0 +1,443 @@ +/* +** An Example of dissolve, using stencil +*/ +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#define drand48() ((double)rand()/RAND_MAX) +#endif + +int winWidth = 512; +int winHeight = 512; + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +enum {SPHERE = 1, CONE}; + + + + +GLfloat angle = 0.f; /* angle of rotating object in layer 0 */ + +enum {X, Y}; +GLboolean eraser = GL_FALSE; +GLint layer = 1; +GLint eraserpos[2] = {512/8, 512/12}; + +/* draw eraser and erase what's underneath */ + +GLubyte *eraserpix = 0; +int erasersize = 0; +int eraserWidth; +int eraserHeight; +void +makeEraser(void) +{ + int i; + int x, y; + int dx, dy; + float d; + + eraserWidth = winWidth / 6; + eraserHeight = winHeight / 6; + erasersize = 4 * eraserWidth * eraserHeight; + eraserpix = (GLubyte *)realloc(eraserpix, erasersize * sizeof(GLubyte)); + + + /* make it not erase */ + (void)memset(eraserpix, 0, erasersize * sizeof(GLubyte)); + + i = 0; + for(y = 0; y < eraserHeight; y++) + for(x = 0; x < eraserWidth; x++) + { + dx = x - eraserWidth / 2; + dy = y - eraserHeight / 2; + d = sqrt(dx * dx + dy * dy); + if(pow(drand48(), .75) * eraserWidth / 2 > d) + { + eraserpix[i + 0] = 255; + eraserpix[i + 1] = 255; + eraserpix[i + 2] = 255; + eraserpix[i + 3] = 255; + } + i += 4; + } +} + + +/* left button, first layer, middle button, second layer */ +/* ARGSUSED */ +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) { + eraser = GL_TRUE; + if(button == GLUT_LEFT_BUTTON) + layer = 1; + else /* GLUT_MIDDLE: GLUT_RIGHT is for menu */ + layer = 0; + } else { /* GLUT_UP */ + eraser = GL_FALSE; + } + glutPostRedisplay(); +} + + +enum {CLEAR}; /* menu choices */ +GLboolean clearstencil = GL_TRUE; + +void +menu(int choice) +{ + switch(choice) { + case CLEAR: + clearstencil = GL_TRUE; + break; + } + glutPostRedisplay(); +} + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glViewport(0, 0, wid, ht); + winWidth = wid; + winHeight = ht; + clearstencil = GL_TRUE; + makeEraser(); + glutPostRedisplay(); +} + + + +void +draweraser(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, winWidth, 0, winHeight); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* replace with this layer */ + glStencilFunc(GL_ALWAYS, layer, 0); + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_NOTEQUAL, 0); + glRasterPos2i(eraserpos[X], eraserpos[Y]); + glBitmap(0, 0, 0.f, 0.f, -winWidth/8.f, -winHeight/12.f, 0); + glDrawPixels(eraserWidth, eraserHeight, GL_RGBA, GL_UNSIGNED_BYTE, eraserpix); + glDisable(GL_ALPHA_TEST); +} + + +void +drawlayer2(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, winWidth, 0, winHeight); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(0, 0); + glTexCoord2i(1, 0); + glVertex2i(winWidth, 0); + glTexCoord2i(1, 1); + glVertex2i(winWidth, winHeight); + glTexCoord2i(0, 1); + glVertex2i(0, winHeight); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + +} + +void +drawlayer1(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-100., 100., -100., 100., 320., 640.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(-80.f, -80.f, -420.f); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-20.f, -100.f, -500.f); + glCallList(CONE); + glPopMatrix(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); +} + + +void +drawlayer0(void) +{ + static GLfloat lightpos[] = {50.f, 50.f, 0.f, 1.f}; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-50.f, 50.f, -50.f, 50.f, 0.f, 100.f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.f, 0.f, -50.f); + glRotatef(angle, 0.f, 1.f, 0.f); + glRotatef(90.f, 0.f, 0.f, 1.f); + glTranslatef(0.f, -25.f, 0.f); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glCullFace(GL_BACK); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glCallList(CONE); + +} + +void +redraw(void) +{ + if(glutLayerGet(GLUT_NORMAL_DAMAGED) || + clearstencil == GL_TRUE) { + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + clearstencil = GL_FALSE; + } else + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glStencilFunc(GL_EQUAL, 2, (unsigned)~0); + drawlayer2(); + + glStencilFunc(GL_EQUAL, 1, (unsigned)~0); + drawlayer1(); + + glStencilFunc(GL_EQUAL, 0, (unsigned)~0); + drawlayer0(); + + if(eraser) + draweraser(); + + glutSwapBuffers(); +} + +void +idle(void) +{ + angle += 1.f; + glutPostRedisplay(); +} + + +void +passive(int x, int y) +{ + + eraserpos[X] = x; + eraserpos[Y] = winHeight - y; +} + + +void +motion(int x, int y) +{ + + eraserpos[X] = x; + eraserpos[Y] = winHeight - y; + + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) { + case '\033': + exit(0); + } +} + +const int TEXDIM = 256; +GLfloat *tex = 0; + +main(int argc, char *argv[]) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_DEPTH); + (void)glutCreateWindow("dissolve"); + glutDisplayFunc(redraw); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutPassiveMotionFunc(passive); + glutKeyboardFunc(key); + glutIdleFunc(idle); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + glutAddMenuEntry("Clear Stencil", CLEAR); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + makeEraser(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glClearStencil(2); + glEnable(GL_STENCIL_TEST); /* used all the time */ + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/dissolve.dsp b/lib/glut-3.7.6/progs/advanced97/dissolve.dsp new file mode 100644 index 0000000000..330ae94dbb --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/dissolve.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="dissolve" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dissolve - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dissolve.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dissolve.mak" CFG="dissolve - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dissolve - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dissolve - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dissolve - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "dissolve - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "dissolve - Win32 Release" +# Name "dissolve - Win32 Debug" +# Begin Source File + +SOURCE=.\dissolve.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/explode.c b/lib/glut-3.7.6/progs/advanced97/explode.c new file mode 100644 index 0000000000..3efac37974 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/explode.c @@ -0,0 +1,388 @@ +#include +#include +#include +#include +#include "texture.h" + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf sin +#define cosf cos +#define atan2f atan2 +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +static int texture = 1; +static float rot = 0; +static float opacity = 1.0; +static float intensity = 1.0; +static float size = .001, delta = 0; +static float scale = 1.; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void afunc(void) { + static int state; + if (state ^= 1) { + glAlphaFunc(GL_GREATER, .01); + glEnable(GL_ALPHA_TEST); + } else { + glDisable(GL_ALPHA_TEST); + } +} + +void bfunc(void) { + static int state; + if (state ^= 1) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } else { + glDisable(GL_BLEND); + } +} + +void tfunc(void) { + texture ^= 1; +} + +void up(void) { scale += .1; } +void down(void) { scale -= .1; } +void left(void) { intensity -= .05f; if (intensity < 0.f) intensity = 0.0f; } +void right(void) { intensity += .05f; if (intensity > 1.f) intensity = 1.0f; } + +void help(void) { + printf("Usage: explode [image]\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'t' - toggle texturing\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("'LEFT' - darken\n"); + printf("'RIGHT' - brighten\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(char *filename) { + static unsigned *image; + static int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 2 && components != 4) { + printf("must be an RGBA or LA image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,20.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + glClearColor(.25f, .25f, .75f, .25f); + + glAlphaFunc(GL_GREATER, 0.016); + glEnable(GL_ALPHA_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_LIGHT0); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_NORMALIZE); +} + +void +animate(void) { + if (delta > 10) { + delta = 0.f; + size = 0.f; + opacity = 1.f; + rot = 0.f; + } + size += .08f; + delta += .07f; + rot += .9f; + opacity -= .005f; + + glutPostRedisplay(); +} + +void +cube(void) { + glBegin(GL_QUADS); + glNormal3f(0.f, 0.f, -1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); + + glNormal3f(0.f, 0.f, 1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, -1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + + glNormal3f( 1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + + glNormal3f(-1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + glEnd(); +} + +static void calcMatrix(void); + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); +#define RAD(x) (((x)*M_PI)/180.) + gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.); + + /* floor */ + glColor4f(0.f,.2f,0.f,1.f); + glBegin(GL_POLYGON); + glVertex3f(-4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, 4.0); + glVertex3f(-4.0, -1.0, 4.0); + glEnd(); + + glEnable(GL_LIGHTING); + glPushMatrix(); + glColor3f(.3f,.3f,.3f); + glPushMatrix(); + glTranslatef(-1.f, -1.+.2f, -1.5f); + glScalef(.2f,.2f, .2f); + cube(); + glPopMatrix(); + glDisable(GL_LIGHTING); + + glTranslatef(-1.f, -1.f, -1.5f); + calcMatrix(); + glScalef(size,size,1.); + if (texture) glEnable(GL_TEXTURE_2D); + glColor4f(intensity, intensity, intensity, opacity); + glDepthMask(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(); + glDepthMask(1); + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'a': afunc(); break; + case 'b': bfunc(); break; + case 'h': help(); break; + case 't': tfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/explosion.rgba" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} + +void +printmat(float *m) { + int i; + for(i = 0; i < 4; i++) { + printf("%f %f %f %f\n", m[4*i+0], m[4*i+1], m[4*i+2], m[4*i+3]); + } +} + +void +buildRot(float theta, float x, float y, float z, float m[16]) { + float d = x*x + y*y + z*z; + float ct = cosf(RAD(theta)), st = sinf(RAD(theta)); + + /* normalize */ + if (d > 0) { + d = 1/d; + x *= d; + y *= d; + z *= d; + } + + m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; + m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; + m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; + m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; + + /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S + * + * S = 0 -z y u' = (x, y, z) + * z 0 -x + * -y x 0 + */ + + m[0] = x*x + ct*(1-x*x) + st*0; + m[4] = x*y + ct*(0-x*y) + st*-z; + m[8] = x*z + ct*(0-x*z) + st*y; + + m[1] = y*x + ct*(0-y*x) + st*z; + m[5] = y*y + ct*(1-y*y) + st*0; + m[9] = y*z + ct*(0-y*z) + st*-x; + + m[2] = z*x + ct*(0-z*x) + st*-y; + m[6] = z*y + ct*(0-z*y) + st*x; + m[10]= z*z + ct*(1-z*z) + st*0; +} + +static void +calcMatrix(void) { + float mat[16]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat); + glMultMatrixf(mat); +} diff --git a/lib/glut-3.7.6/progs/advanced97/explode.dsp b/lib/glut-3.7.6/progs/advanced97/explode.dsp new file mode 100644 index 0000000000..8eaa598178 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/explode.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="explode" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=explode - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "explode.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "explode.mak" CFG="explode - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "explode - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "explode - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "explode - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "explode - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "explode - Win32 Release" +# Name "explode - Win32 Debug" +# Begin Source File + +SOURCE=.\explode.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/fire.c b/lib/glut-3.7.6/progs/advanced97/fire.c new file mode 100644 index 0000000000..983191ee4d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/fire.c @@ -0,0 +1,480 @@ +#include +#include +#include +#include +#include "texture.h" +#include "sm.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf(x) ((float)sin((x))) +#define cosf(x) ((float)cos((x))) +#define atan2f(y, x) ((float)atan2((y), (x))) +#endif + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +static void *smoke; +static int marshmallow; +static int the_texture; +static int texture_count; +static int texture = 1; +static float rot = 0; +static float opacity = 1.0; +static float intensity = 1.0; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void afunc(void) { + static int state; + if (state ^= 1) + glEnable(GL_ALPHA_TEST); + else + glDisable(GL_ALPHA_TEST); +} + +void bfunc(void) { + static int state; + if (state ^= 1) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); +} + +void mfunc(void) { + marshmallow += 1; + if (marshmallow > 2) marshmallow = 0; +} + +void sfunc(void) { + the_texture++; + if (the_texture >= texture_count) the_texture = 0; +} + +void tfunc(void) { + static int state; + if (state ^= 1) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +void fourfunc(void) { + static int state; + GLenum wrap; + int i; + + glMatrixMode(GL_TEXTURE); + if (state ^= 1) { + wrap = GL_REPEAT; + glScalef(4.f, 4.f, 1.f); + } else { + wrap = GL_CLAMP; + glLoadIdentity(); + } + glMatrixMode(GL_MODELVIEW); + + for(i = 0; i < texture_count; i++) { + glBindTexture(GL_TEXTURE_2D, i+1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + } +} + +void help(void) { + printf("Usage: fire image0 ... imagen\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'s' - single step\n"); + printf("'t' - toggle MODULATE or REPLACE\n"); + printf("'m' - marshmallow\n"); + printf("'x' - toggle animation\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(int argc, char *argv[]) { + unsigned *image; + int i, width, height, components; + GLfloat pos[] = { 0.f, 1.f, 1.f, 0.f}; + + glEnable(GL_TEXTURE_2D); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + for(i = 0; i < argc; i++) { + image = read_texture(argv[i], &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + argv[i]); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + glBindTexture(GL_TEXTURE_2D, i+1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + texture_count++; + } + + glBindTexture(GL_TEXTURE_2D, 1+texture_count); + image = read_texture("../data/smoke.bw", &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", "smoke.la"); + exit(EXIT_FAILURE); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + smoke = new_smoke(0.f, 0.f, 0.f, .0f, 2.5f, 0.f, 25, .4f, 1+texture_count); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + glClearColor(.25f, .25f, .25f, .25f); + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,20.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + glClearColor(.25f, .25f, .75f, .25f); + + glAlphaFunc(GL_GREATER, 0.016f); + glEnable(GL_ALPHA_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); +} + +void +animate(void) { + static int cnt; + if (cnt++ == 2) { + the_texture++; + if (the_texture >= texture_count) the_texture = 0; + cnt = 0; + } + update_smoke(smoke, .003); + glutPostRedisplay(); +} + +void +xfunc(void) { + static int state = 1; + glutIdleFunc((state ^= 1) ? animate : NULL); +} + +void +cube(void) { + glBegin(GL_QUADS); + glNormal3f(0.f, 0.f, -1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); + + glNormal3f(0.f, 0.f, 1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, -1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + + glNormal3f( 1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + + glNormal3f(-1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + glEnd(); +} + +void +logs(void) { + static GLUquadricObj *quadric; + + if (!quadric) { + quadric = gluNewQuadric(); + glNewList(100, GL_COMPILE); + gluQuadricOrientation(quadric, GLU_OUTSIDE); + glTranslatef(0.f, 0.f, -2.f); + gluCylinder(quadric, .5, .5, 4., 5, 1); + glTranslatef(0.f, 0.f, 4.f); + gluDisk(quadric, 0., .5, 10, 1); + glTranslatef(0.f, 0.f, -4.f); + gluQuadricOrientation(quadric, GLU_INSIDE); + gluDisk(quadric, 0., .5, 10, 1); + glEndList(); + } + glPushMatrix(); + glTranslatef(0.f, -.5f, 0.f); + glColor3f(.55f, .14f, .14f); + glPushMatrix(); + glRotatef(55., 0., 1., 0.); + glCallList(100); + glPopMatrix(); + glPushMatrix(); + glRotatef(-55., 0., 1., 0.); + glCallList(100); + glPopMatrix(); + if (marshmallow) { + glPushMatrix(); + glColor4f(1.f, 1.f, 1.f, 1.f); + glTranslatef(0.f, 1.7f, 0.f); + glRotatef(45.f, 0.f, 0.f, 1.f); + glRotatef(90.f, 0.f, 1.f, 0.f); + glScalef(1., 1., .25f); + glCallList(100); + glPopMatrix(); + + glPushMatrix(); + glColor4f(.1f, .1f, .1f, 1.f); + glTranslatef(1.5f, 3.4f, 0.f); + glRotatef(45.f, 0.f, 0.f, 1.f); + glRotatef(90.f, 0.f, 1.f, 0.f); + glScalef(.2f, .2f, 1.f); + glCallList(100); + glPopMatrix(); + + if (marshmallow == 2) { + extern void drawDinosaur(void); + glDisable(GL_COLOR_MATERIAL); + glPushMatrix(); + glTranslatef(10.f, 0.f, 0.f); + glRotatef(180.f, 0.f, 1.f, 0.f); + glScalef(.5f, .5f, .5f); + drawDinosaur(); + glPopMatrix(); + } + } + glPopMatrix(); +} +static void calcMatrix(void); + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); +#define RAD(x) (((x)*M_PI)/180.) + gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.); + + glTranslatef(0.f, 0.f, transx*10.f); + + /* floor */ + glColor4f(0.f,.2f,0.f,1.f); + glBegin(GL_POLYGON); + glVertex3f(-4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, 4.0); + glVertex3f(-4.0, -1.0, 4.0); + glEnd(); + + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glColor3f(.1f,.1f,.1f); + glPushMatrix(); + glTranslatef(-1.f, -1.+.2f, -1.5f); + glScalef(.2f,.2f, .2f); + logs(); + /*cube();*/ + glDisable(GL_LIGHTING); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-1.f, -1.f+.2f, -1.5f); + calcMatrix(); + draw_smoke(smoke); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(/*(delta/2.f*/-1.f, /*delta*/-.25f, -1.5f); + calcMatrix(); + glScalef(1.f,1.f,1.); + if (texture) { + glBindTexture(GL_TEXTURE_2D, the_texture+1); + glEnable(GL_TEXTURE_2D); + } + glColor4f(intensity, intensity, intensity, opacity); + glRotatef(rot, 0., 0., 1.); + glDepthMask(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(); + glDepthMask(1); + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'a': afunc(); break; + case 'b': bfunc(); break; + case 'h': help(); break; + case 'm': mfunc(); break; + case 's': sfunc(); break; + case 't': tfunc(); break; + case 'x': xfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow(argv[0]); + init(argc-1, argv+1); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} + +void +buildRot(float theta, float x, float y, float z, float m[16]) { + float d = x*x + y*y + z*z; + float ct = cosf(RAD(theta)), st = sinf(RAD(theta)); + + /* normalize */ + if (d > 0) { + d = 1/d; + x *= d; + y *= d; + z *= d; + } + + m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; + m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; + m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; + m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; + + /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S + * + * S = 0 -z y u' = (x, y, z) + * z 0 -x + * -y x 0 + */ + + m[0] = x*x + ct*(1-x*x) + st*0; + m[4] = x*y + ct*(0-x*y) + st*-z; + m[8] = x*z + ct*(0-x*z) + st*y; + + m[1] = y*x + ct*(0-y*x) + st*z; + m[5] = y*y + ct*(1-y*y) + st*0; + m[9] = y*z + ct*(0-y*z) + st*-x; + + m[2] = z*x + ct*(0-z*x) + st*-y; + m[6] = z*y + ct*(0-z*y) + st*x; + m[10]= z*z + ct*(1-z*z) + st*0; +} + +static void +calcMatrix(void) { + float mat[16]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat); + glMultMatrixf(mat); +} diff --git a/lib/glut-3.7.6/progs/advanced97/fire.dsp b/lib/glut-3.7.6/progs/advanced97/fire.dsp new file mode 100644 index 0000000000..6cc12662de --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/fire.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fire" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=fire - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fire.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fire.mak" CFG="fire - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fire - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "fire - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fire - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "fire - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "fire - Win32 Release" +# Name "fire - Win32 Debug" +# Begin Source File + +SOURCE=.\d.c +# End Source File +# Begin Source File + +SOURCE=.\fire.c +# End Source File +# Begin Source File + +SOURCE=.\sm.c +# End Source File +# Begin Source File + +SOURCE=.\sm.h +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/genspheremap.c b/lib/glut-3.7.6/progs/advanced97/genspheremap.c new file mode 100644 index 0000000000..259dbac5ea --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/genspheremap.c @@ -0,0 +1,291 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef _WIN32 +#include +#define sleep(x) Sleep((x*1000)) +#else +#include +#endif + +#include + +const char defaultBaseName[] = "../data/"; + +GLuint *faces[6]; +GLsizei faceW[6], faceH[6]; + +GLfloat angle1[6] = {90, 180, 270, 0, 90, -90}; +GLfloat axis1[6][3] = {{0,1,0}, {0,1,0}, {0,1,0}, {0,1,0}, {1,0,0}, {1,0,0}}; +GLfloat angle2[6] = {0, 0, 0, 0, 180, 180}; +GLfloat axis2[6][3] = {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, {0,1,0}}; + +GLuint *load_texture(const char *fname, GLsizei *w, GLsizei *h) +{ + int comps; + GLuint *img; + int i; + + img = read_texture(fname, w, h, &comps); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + for (i = 0; i < *w * *h; i++) { + img[i] |= 0xff; + } + + return img; +} + +void set_texture_border(GLuint val, GLuint mask, + GLsizei w, GLsizei h, GLuint *pix) +{ + int x, y; + + val &= mask; + mask = ~mask; + + /* top & bottom rows */ + for (x = 0; x < w; x++) { + pix[x] = (pix[x] & mask) | val; + pix[x + (h-1)*w] = (pix[x + (h-1)*w] & mask) | val; + } + + for (y = 0; y < h; y++) { + pix[y*w] = (pix[y*w] & mask) | val; + pix[y*w + (w-1)] = (pix[y*w + (w-1)] & mask) | val; + } +} + +void init(void) +{ + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + glLoadIdentity(); + glOrtho(-2, 2, -2, 2, 0, 5); +} + +void draw_special_sphere(int tess) +{ + float r = 1.0, r1, r2, z1, z2; + float theta, phi; + int nlon = tess, nlat = tess; + int i, j; + + glBegin(GL_TRIANGLE_FAN); + theta = M_PI*1.0/nlat; + r2 = r*sin(theta); z2 = r*cos(theta); + glNormal3f(0.0, 0.0, 1.0); + glVertex4f(0.0, 0.0, r*r, r); + for (j = 0, phi = 0.0; j <= nlon; j++, phi = 2*M_PI*j/nlon) { + glNormal3f(r2*cos(phi), r2*sin(phi), z2); + glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2); /* top */ + } + glEnd(); + + for (i = 2; i < nlat; i++) { + theta = M_PI*i/nlat; + r1 = r*sin(M_PI*(i-1)/nlat); z1 = r*cos(M_PI*(i-1)/nlat); + r2 = r*sin(theta); z2 = r*cos(theta); + + if (fabs(z1) < 0.01 || fabs(z2) < 0.01) + break; + + glBegin(GL_QUAD_STRIP); + for (j = 0, phi = 0; j <= nlat; j++, phi = 2*M_PI*j/nlon) { + glNormal3f(r1*cos(phi), r1*sin(phi), z1); + glVertex4f(r1*cos(phi)*z1, r1*sin(phi)*z1, z1*z1, z1); + glNormal3f(r2*cos(phi), r2*sin(phi), z2); + glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2); + } + glEnd(); + } +} + +void render_spheremap(int width, int height) +{ + GLfloat p[4]; + int i; + + glColor4f(1, 1, 1, 1); + + glEnable(GL_TEXTURE_2D); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + p[0] = 2.0; p[1] = p[2] = p[3] = 0.0; /* 2zx */ + glTexGenfv(GL_S, GL_OBJECT_PLANE, p); + + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = 0.0; p[1] = 2.0; p[2] = p[3] = 0.0; /* 2zy */ + glTexGenfv(GL_T, GL_OBJECT_PLANE, p); + + glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = p[1] = 0.0; p[2] = 0.0; p[3] = 2.0; /* 2z */ + glTexGenfv(GL_R, GL_OBJECT_PLANE, p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, 1.0, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 6, + 0, 0, 0, + 0, 1, 0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClearDepth(1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + for (i = 0; i < 6; i++) { + glTexImage2D(GL_TEXTURE_2D, 0, 4, faceW[i], faceH[i], 0, + GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)faces[i]); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.5, 0.5, 1.0); + glTranslatef(1.0, 1.0, 0.0); + glFrustum(-1.01, 1.01, -1.01, 1.01, 1.0, 100.0); + if (angle2[i]) { + glRotatef(angle2[i], axis2[i][0], axis2[i][1], axis2[i][2]); + } + glRotatef(angle1[i], axis1[i][0], axis1[i][1], axis1[i][2]); + + /* XXX atul does another angle thing here... */ + /* XXX atul does a third angle thing here... */ + + glTranslatef(0.0, 0.0, -1.00); + + glMatrixMode(GL_MODELVIEW); + glClear(GL_DEPTH_BUFFER_BIT); + draw_special_sphere(20); + + sleep(1); + } + + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + + glDisable(GL_TEXTURE_2D); +} + +void draw(void) +{ + GLenum err; + + glClear(GL_COLOR_BUFFER_BIT); + + render_spheremap(256, 256); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if (key == 27) exit(0); +} + +void show_usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "genspheremap -- use default files" + "(%s00.rgb through %s05.rgb)\n", defaultBaseName, defaultBaseName); + fprintf(stderr, "genspheremap baseName -- use files of the form " + "baseName0.rgb through baseName5.rgb\n"); + fprintf(stderr, "genspheremap f0.rgb f1.rgb f2.rgb f3.rgb f4.rgb f5.rgb\n"); +} + +main(int argc, char *argv[]) +{ + const char *baseName; + char fname[128]; + int i; + + glutInitWindowSize(512, 512); + glutInitWindowPosition(0, 0); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + if (argc == 1 || argc == 2) { + if (argc == 1) baseName = defaultBaseName; + else baseName = argv[1]; + assert(strlen(baseName) < 128 - (strlen("0.rgb") + 1)); + for (i = 0; i < 6; i++) { + sprintf(fname, "%s%02d.rgb", baseName, i); + faces[i] = load_texture(fname, &faceW[i], &faceH[i]); + } + } else if (argc == 7) { + for (i = 0; i < 6; i++) { + faces[i] = load_texture(fname, &faceW[i], &faceH[i]); + } + } else { + show_usage(); + exit(1); + } + + for (i = 0; i < 6; i++) { + set_texture_border(0x00, 0xff, faceW[i], faceH[i], faces[i]); + } + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/genspheremap.dsp b/lib/glut-3.7.6/progs/advanced97/genspheremap.dsp new file mode 100644 index 0000000000..cde6871fbe --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/genspheremap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="genspheremap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=genspheremap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "genspheremap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "genspheremap.mak" CFG="genspheremap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "genspheremap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "genspheremap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "genspheremap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "genspheremap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "genspheremap - Win32 Release" +# Name "genspheremap - Win32 Debug" +# Begin Source File + +SOURCE=.\genspheremap.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/highlight.c b/lib/glut-3.7.6/progs/advanced97/highlight.c new file mode 100644 index 0000000000..591e66c08a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/highlight.c @@ -0,0 +1,704 @@ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +#define CHECK_ERROR(str) \ +{ \ + GLenum error; \ + if(error = glGetError()) \ + printf("GL Error: %s (%s)\n", gluErrorString(error), str); \ +} + +#ifndef FALSE +enum {FALSE, TRUE}; +#endif +enum {X, Y, Z, W}; +enum {OBJ_ANGLE, LIGHT_ANGLE, OBJ_TRANSLATE}; +enum {SURF_TEX, HIGHLIGHT_TEX}; + +/* window dimensions */ +int winWidth = 512; +int winHeight = 512; +int active; +int dblbuf = TRUE; +int highlight = TRUE; +int gouraud = FALSE; +int texmap = FALSE; +int notex = FALSE; /* don't texture gouraud */ + +int object = 2; +int maxobject = 2; + +GLfloat lightangle[2] = {0.f, 0.f}; +GLfloat objangle[2] = {0.f, 0.f}; +GLfloat objpos[2] = {0.f, 0.f}; + +GLfloat color[4] = {1.f, 1.f, 1.f, 1.f}; +GLfloat zero[4] = {0.f, 0.f, 0.f, 1.f}; +GLfloat one[4] = {1.f, 1.f, 1.f, 1.f}; + +int texdim = 128; +GLfloat *lighttex = 0; +GLfloat lightpos[4] = {0.f, 0.f, 1.f, 0.f}; +GLboolean lightchanged[2] = {GL_TRUE, GL_TRUE}; +enum {UPDATE_OGL, UPDATE_TEX}; + + +/* draw a highly tesselated sphere with a specular highlight */ +void +makeHighlight(int shinyness) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); /* starts as modelview */ + glLoadIdentity(); + glTranslatef(0.f, 0.f, -texdim/2.f); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-texdim/2., texdim/2., -texdim/2., texdim/2., 0., texdim/2.); + + glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT); + glViewport(0, 0, texdim, texdim); + glEnable(GL_LIGHTING); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, zero); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* light direction */ + + /* XXX TODO, range check an report errors */ + glMateriali(GL_FRONT, GL_SHININESS, shinyness); /* cosine power */ + glMaterialfv(GL_FRONT, GL_AMBIENT, zero); + glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); + glMaterialfv(GL_FRONT, GL_SPECULAR, color); + glDisable(GL_TEXTURE_2D); + + glCallList(1); + + glEnable(GL_TEXTURE_2D); + glPopAttrib(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glReadPixels(0, 0, texdim, texdim, GL_RGB, GL_FLOAT, lighttex); + + glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texdim, texdim, 0, GL_RGB, + GL_FLOAT, lighttex); +} + +void +reshape(int wid, int ht) +{ + winWidth = wid; + winHeight = ht; + glViewport(0, 0, wid, ht); +} + + +void +motion(int x, int y) +{ + + switch(active) + { + case OBJ_ANGLE: + objangle[X] = (x - winWidth/2) * 360./winWidth; + objangle[Y] = (y - winHeight/2) * 360./winHeight; + glutPostRedisplay(); + break; + case LIGHT_ANGLE: + lightangle[X] = (x - winWidth/2) * 2 * M_PI/winWidth; + lightangle[Y] = (winHeight/2 - y) * 2 * M_PI/winHeight; + + lightpos[Y] = sin(lightangle[Y]); + lightpos[X] = cos(lightangle[Y]) * sin(lightangle[X]); + lightpos[Z] = cos(lightangle[Y]) * cos(lightangle[X]); + lightpos[W] = 0.; + lightchanged[UPDATE_OGL] = GL_TRUE; + lightchanged[UPDATE_TEX] = GL_TRUE; + glutPostRedisplay(); + break; + case OBJ_TRANSLATE: + objpos[X] = (x - winWidth/2) * 100./winWidth; + objpos[Y] = (winHeight/2 - y) * 100./winHeight; + glutPostRedisplay(); + break; + } +} + +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* move the light */ + active = OBJ_ANGLE; + motion(x, y); + break; + case GLUT_MIDDLE_BUTTON: + active = LIGHT_ANGLE; + motion(x, y); + break; + case GLUT_RIGHT_BUTTON: /* move the polygon */ + active = OBJ_TRANSLATE; + motion(x, y); + break; + } +} + +/* draw the object unlit without surface texture */ +void redraw_white(void) +{ + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + /* draw the specular highlight */ + + glCallList(object); + + glEnable(GL_TEXTURE_2D); + + glPopMatrix(); /* assuming modelview */ + + CHECK_ERROR("OpenGL Error in redraw_tex()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +/* just draw textured highlight */ +void redraw_tex_highlight(void) +{ + if(lightchanged[UPDATE_TEX]) + { + makeHighlight(128); + lightchanged[UPDATE_TEX] = GL_FALSE; + } + + + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + glClearColor(.1f, .1f, .1f, 1.f); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glClearColor(0.f, 0.f, 0.f, 1.f); + + /* draw the specular highlight */ + glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glCallList(object); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + + glPopMatrix(); /* assuming modelview */ + + CHECK_ERROR("OpenGL Error in redraw_tex()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* just draw opengl highlight */ +void redraw_gouraud_highlight(void) +{ + if(lightchanged[UPDATE_OGL]) + { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + lightchanged[UPDATE_OGL] = GL_FALSE; + } + + glPushAttrib(GL_LIGHTING); + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + glClearColor(.1f, .1f, .1f, 1.f); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glClearColor(0.f, 0.f, 0.f, 1.f); + + /* draw the specular highlight */ + + glEnable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + + glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */ + glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */ + glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */ + + /* draw the specular highlight */ + glCallList(object); + + glEnable(GL_TEXTURE_2D); + glPopMatrix(); /* assuming modelview */ + glPopAttrib(); + + CHECK_ERROR("OpenGL Error in redraw_tex()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + + +/* show highlight texture map */ +void redraw_map(void) +{ + if(lightchanged[UPDATE_TEX]) + { + makeHighlight(128); + lightchanged[UPDATE_TEX] = GL_FALSE; + } + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX); + glDisable(GL_LIGHTING); + + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(-1, -1); + + glTexCoord2i(1, 0); + glVertex2i(1, -1); + + glTexCoord2i(1, 1); + glVertex2i(1, 1); + + glTexCoord2i(0, 1); + glVertex2i(-1, 1); + glEnd(); + + glEnable(GL_LIGHTING); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + CHECK_ERROR("OpenGL Error in redraw_map()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + + +/* multipass, use texture to make highlight */ +void redraw_tex(void) +{ + if(lightchanged[UPDATE_TEX]) + { + makeHighlight(128); + lightchanged[UPDATE_TEX] = GL_FALSE; + } + if(lightchanged[UPDATE_OGL]) + { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + lightchanged[UPDATE_OGL] = GL_FALSE; + } + + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + /* draw the diffuse portion of the light */ + glEnable(GL_LIGHTING); + + glBindTexture(GL_TEXTURE_2D, SURF_TEX); + + if(notex) + glDisable(GL_TEXTURE_2D); + glCallList(object); + if(notex) + glEnable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + + /* draw the specular highlight */ + glEnable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glDepthFunc(GL_LEQUAL); + + glCallList(object); + + glDepthFunc(GL_LESS); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_BLEND); + + glPopMatrix(); /* assuming modelview */ + + CHECK_ERROR("OpenGL Error in redraw_tex()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* multipass; use opengl to make highlight */ +void redraw_phong(void) +{ + if(lightchanged[UPDATE_OGL]) + { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + lightchanged[UPDATE_OGL] = GL_FALSE; + } + + glPushAttrib(GL_LIGHTING); + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + /* draw the diffuse portion of the light */ + glEnable(GL_LIGHTING); + + glBindTexture(GL_TEXTURE_2D, SURF_TEX); + + if(notex) + glDisable(GL_TEXTURE_2D); + glCallList(object); + if(notex) + glEnable(GL_TEXTURE_2D); + + /* turn off texturing so phong highlight color is pure */ + glDisable(GL_TEXTURE_2D); + + glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */ + glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */ + glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */ + + /* draw the specular highlight */ + glEnable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + + glCallList(object); + + glEnable(GL_TEXTURE_2D); + glDepthFunc(GL_LESS); + glDisable(GL_BLEND); + + glPopMatrix(); /* assuming modelview */ + glPopAttrib(); + + CHECK_ERROR("OpenGL Error in redraw_tex()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +/* Use OpenGL lighting to get highlight */ +void redraw_original(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + if(lightchanged[UPDATE_OGL]) + { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + lightchanged[UPDATE_OGL] = GL_FALSE; + } + + glEnable(GL_LIGHTING); + + glBindTexture(GL_TEXTURE_2D, SURF_TEX); + glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */ + if(notex) + glDisable(GL_TEXTURE_2D); + glCallList(object); + if(notex) + glEnable(GL_TEXTURE_2D); + glMaterialfv(GL_FRONT, GL_SPECULAR, zero); + + glDisable(GL_LIGHTING); + + glPopMatrix(); /* assuming modelview */ + + CHECK_ERROR("OpenGL Error in redraw()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* Draw with no highlight */ +void redraw_diffuse(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + + glPushMatrix(); /* assuming modelview */ + glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + + if(lightchanged[UPDATE_OGL]) + { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + lightchanged[UPDATE_OGL] = GL_FALSE; + } + + /* draw the diffuse portion of the light */ + glEnable(GL_LIGHTING); + + glBindTexture(GL_TEXTURE_2D, SURF_TEX); + glCallList(object); + + glDisable(GL_LIGHTING); + + glPopMatrix(); /* assuming modelview */ + + CHECK_ERROR("OpenGL Error in redraw()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) + { + case 'u': /* unmodified highlight */ + printf("Use unmodified gouraud highlight\n"); + glutDisplayFunc(redraw_original); + glutPostRedisplay(); + break; + case 'd': + printf("Draw diffuse only\n"); + glutDisplayFunc(redraw_diffuse); + glutPostRedisplay(); + break; + case 'g': /* separate gouraud shaded highlight */ + printf("Use separate gouraud shaded highlight\n"); + glutDisplayFunc(redraw_phong); + glutPostRedisplay(); + break; + case 't': /* separate textured highlight */ + printf("Use separate texture highlight\n"); + glutDisplayFunc(redraw_tex); + glutPostRedisplay(); + break; + case 'o': + /* toggle object type */ + object++; + if(object > maxobject) + object = 2; + glutPostRedisplay(); + break; + case 'm': + /* show highlight texture map */ + printf("Show highlight texture map\n"); + glutDisplayFunc(redraw_map); + glutPostRedisplay(); + break; + case 'n': + if(notex) + notex = FALSE; + else + notex = TRUE; + glutPostRedisplay(); + break; + case 'h': + printf("Show textured phong highlight\n"); + glutDisplayFunc(redraw_tex_highlight); + glutPostRedisplay(); + break; + case 'p': + printf("Show gouraud-shaded phong highlight\n"); + glutDisplayFunc(redraw_gouraud_highlight); + glutPostRedisplay(); + break; + case 'w': + printf("Show white object\n"); + glutDisplayFunc(redraw_white); + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + default: + fprintf(stderr, "Keyboard commands:\n\n" + "u - (unmodified opengl lighting)\n" + "d - diffuse only\n" + "g - multipass gouraud highlight\n" + "t - multipass texture highlight\n" + "o - toggle object\n" + "m - show highlight texture map\n" + "n - toggle surface texturing\n" + "h - show textured phong highlight\n" + "p - show gouraud-shaded phong highlight\n" + "w - show unlit white object\n"); + break; + } + +} + + + +main(int argc, char *argv[]) +{ + GLuint *tex; + int texwid, texht, texcomps; + + GLUquadricObj *quadric; + + glutInitWindowSize(winWidth, winHeight); + glutInit(&argc, argv); + if(argc > 1) + { + char *args = argv[1]; + int done = FALSE; + while(!done) + { + switch(*args) + { + case 's': /* single buffer */ + printf("Single Buffered\n"); + dblbuf = FALSE; + break; + case '-': /* do nothing */ + break; + case 0: + done = TRUE; + break; + } + args++; + } + } + if(dblbuf) + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); + else + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH); + (void)glutCreateWindow("example program"); + glutDisplayFunc(redraw_original); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutKeyboardFunc(key); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 300., 600.); + glMatrixMode(GL_MODELVIEW); + /* look at scene from (0, 0, 450) */ + gluLookAt(0., 0., 450., 0., 0., 0., 0., 1., 0.); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glMateriali(GL_FRONT, GL_SHININESS, 128); /* cosine power */ + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + glBlendFunc(GL_ONE, GL_ONE); + + lightchanged[UPDATE_TEX] = GL_TRUE; + lightchanged[UPDATE_OGL] = GL_TRUE; + + /* load pattern for current 2d texture */ + + tex = read_texture("../data/wood.rgb", &texwid, &texht, &texcomps); + + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texwid, texht, GL_RGBA, + GL_UNSIGNED_BYTE, tex); + free(tex); + CHECK_ERROR("end of main"); + + lighttex = (GLfloat *)malloc(texdim * texdim * sizeof(GL_FLOAT) * 3); + + + + /* XXX TODO use display list to avoid retesselating */ + glNewList(1, GL_COMPILE); + glutSolidSphere((GLdouble)texdim/2., 50, 50); + glEndList(); + + + glNewList(2, GL_COMPILE); + glutSolidTeapot(70.); + glEndList(); + + quadric = gluNewQuadric(); + gluQuadricTexture(quadric, GL_TRUE); + + glNewList(3, GL_COMPILE); + gluSphere(quadric, 70., 20, 20); + glEndList(); + + gluDeleteQuadric(quadric); + maxobject = 3; + + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/highlight.dsp b/lib/glut-3.7.6/progs/advanced97/highlight.dsp new file mode 100644 index 0000000000..73006c38a6 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/highlight.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="highlight" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=highlight - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "highlight.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "highlight.mak" CFG="highlight - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "highlight - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "highlight - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "highlight - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "highlight - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "highlight - Win32 Release" +# Name "highlight - Win32 Debug" +# Begin Source File + +SOURCE=.\highlight.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/interp.c b/lib/glut-3.7.6/progs/advanced97/interp.c new file mode 100644 index 0000000000..49e64511ea --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/interp.c @@ -0,0 +1,261 @@ +#include +#include +#include +#include +#include +#include +#include "texture.h" + +static char defaultFile[] = "../data/mandrill.rgb"; +GLuint *img, *black, *avgLum, *lum; +GLsizei w, h; +GLint comp; +GLboolean isIR; + +#define RW 0.3086 +#define GW 0.6094 +#define BW 0.0820 + +GLuint *in0, *in1; +GLfloat x = 1.; + +#define BRIGHTNESS 0 +#define CONTRAST 1 +#define SATURATION 2 +int nOperations = 3; +int operation = 0; + + +void set_img_pointers(void) +{ + switch(operation) { + case CONTRAST: + in0 = avgLum; + printf("modifying contrast\n"); + break; + case SATURATION: + in0 = lum; + printf("modifying saturation\n"); + break; + case BRIGHTNESS: + in0 = black; + printf("modifying brightness\n"); + break; + default: + assert(0); + } +} + +void init(void) +{ + const char *renderer; + + set_img_pointers(); + + renderer = (char*) glGetString(GL_RENDERER); + isIR = (renderer[0] == 'I' && renderer[1] == 'R'); +} + +GLuint *alloc_image(void) +{ + GLuint *ptr; + + ptr = (GLuint *)malloc(w * h * sizeof(GLuint)); + if (!ptr) { + fprintf(stderr, "malloc of %d bytes failed.\n", w * h * sizeof(GLuint)); + } + return ptr; +} + +void load_img(const char *fname) +{ + int i; + GLubyte *src, *dst; + GLfloat pix, avg; + + img = read_texture(fname, &w, &h, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + black = alloc_image(); + memset(black, 0, w * h * sizeof(GLuint)); + + lum = alloc_image(); + src = (GLubyte *)img; + dst = (GLubyte *)lum; + avg = 0.; + /* compute average luminance at same time that we set luminance image. + * note that little care is taken to avoid mathematical error when + * computing overall average... */ + for (i = 0; i < w * h; i++) { + pix = (float)src[0]*RW + (float)src[1]*GW + (float)src[2]*BW; + if (pix > 255) pix = 255; + dst[0] = dst[1] = dst[2] = pix; + avg += pix / 255.; + src += 4; + dst += 4; + } + + avgLum = alloc_image(); + pix = avg * 255. / (float)(w*h); + dst = (GLubyte *)avgLum; + for (i = 0; i < w * h; i++) { + dst[0] = dst[1] = dst[2] = pix; + dst += 4; + } +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, w, h); + glLoadIdentity(); + glOrtho(0, winW, 0, winH, 0, 5); +} + +void draw(void) +{ + GLenum err; + GLfloat s, absx, abs1minusx; + + glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + glRasterPos2i(0, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in0); + + absx = fabs(x); + abs1minusx = fabs(1.-x); + s = absx > abs1minusx ? absx : abs1minusx; + + if (!isIR) { + glAccum(GL_ACCUM, (1. - x) / s); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1); + glAccum(GL_ACCUM, x/s); + glAccum(GL_RETURN, s); + } else { + if (fabs(x) < 1. && fabs(1. - x) < 1) { + glAccum(GL_ACCUM, 1. - x); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1); + glAccum(GL_ACCUM, x); + glAccum(GL_RETURN, 1); + } else { + absx = fabs(x); + abs1minusx = fabs(1.-x); + s = absx > abs1minusx ? absx : abs1minusx; + + glAccum(GL_ACCUM, .8 * ((1. - x) / s)); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, in1); + glAccum(GL_ACCUM, .8 * x/s); + glAccum(GL_RETURN, 1.2 * s); + } + } + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int xpos, int ypos) +{ + if (key == 27) exit(0); + + operation = (operation + 1) % nOperations; + set_img_pointers(); + draw(); +} + +int mouseOriginX; +int moveCalled = 0; +float deltaSinceDraw = 0.; + +void idle(void); + +void clamp_x(void) +{ + if (x > 3.99 && isIR) x = 3.99; + else if (x < -4. && isIR) x = -4.; +} + +/* ARGSUSED */ +void button(int button, int state, int xpos, int ypos) +{ + if (state == GLUT_DOWN) { + mouseOriginX = xpos; + deltaSinceDraw = 0; + glutIdleFunc(idle); + return; + } + + if (!moveCalled) { + if (button == GLUT_MIDDLE_BUTTON) x = 1.; + else x = (float)xpos / ((float)w / 2.); + clamp_x(); + deltaSinceDraw = 100000.; + } + moveCalled = 0; + if (deltaSinceDraw) draw(); + printf("x = %f\n", x); + glutIdleFunc(NULL); +} + +void menu(int val) +{ + operation = val; + set_img_pointers(); + draw(); +} + +void idle(void) +{ + if (deltaSinceDraw) { + x += deltaSinceDraw; + clamp_x(); + draw(); + deltaSinceDraw = 0; + } +} + +/* ARGSUSED */ +void motion(int xpos, int ypos) +{ + float delta = xpos - mouseOriginX; + mouseOriginX = xpos; + moveCalled = 1; + delta /= w/2.; + deltaSinceDraw += delta; +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + if (argc > 1) { + load_img(argv[1]); + } else { + load_img(defaultFile); + } + in0 = black; + in1 = img; + operation = BRIGHTNESS; + glutInitWindowSize(w, h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_ACCUM | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutMotionFunc(motion); + glutMouseFunc(button); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + glutAddMenuEntry("Change brightness", 0); + glutAddMenuEntry("Change contrast", 1); + glutAddMenuEntry("Change saturation", 2); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/interp.dsp b/lib/glut-3.7.6/progs/advanced97/interp.dsp new file mode 100644 index 0000000000..48b1ae41e0 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/interp.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="interp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=interp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "interp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "interp.mak" CFG="interp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "interp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "interp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "interp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "interp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "interp - Win32 Release" +# Name "interp - Win32 Debug" +# Begin Source File + +SOURCE=.\interp.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/lightmap.c b/lib/glut-3.7.6/progs/advanced97/lightmap.c new file mode 100644 index 0000000000..e4a073d8e2 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/lightmap.c @@ -0,0 +1,1052 @@ +#include +#include +#include +#include "texture.h" +#include + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define sqrtf(x) (float)sqrt((x)) +#endif + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +#define CHECK_ERROR(str) \ +{ \ + GLenum error; \ + if(error = glGetError()) \ + printf("GL Error: %s (%s)\n", gluErrorString(error), str); \ +} + +/* display lists */ +enum {SPHERE = 1, CONE, LIGHT, DISK, FLOOR, BACK, LEFT, RIGHT, CEIL}; + +/* texture objects */ +enum {DEFAULT, LIGHTMAP, SURFMAP}; + +enum {NONE, LIGHT_XY, LIGHT_Z, LIGHT_INTENS}; + +#ifndef TRUE +enum {FALSE, TRUE}; +#endif +enum {X, Y, Z, W}; +enum {R, G, B, A}; + +GLfloat staticlightpos[] = {50.f, 70.f, -10.f, 1.f}; +GLfloat lightpos[] = {50.f, 70.f, -10.f, 1.f}; +GLfloat intensity = 1.f; +GLfloat nearScale = .49f, farScale = .0001f; + +int dblbuf = TRUE; +int action = NONE; +int winWidth = 512; +int winHeight = 512; +int curtess = 1; /* current tessellation level */ +int lasttess = 1; /* last set tessellation level */ + +void +reshape(int wid, int ht) +{ + winWidth = wid; + winHeight = ht; + glViewport(0, 0, wid, ht); +} + +void +motion(int x, int y) +{ + switch(action) + { + case LIGHT_XY: + lightpos[X] = (x - winWidth/2) * 200.f/winWidth; + lightpos[Y] = (winHeight/2 - y) * 200.f/winHeight; + glutPostRedisplay(); + break; + case LIGHT_Z: + lightpos[Z] = (winHeight/2 - y) * 200.f/winWidth; + glutPostRedisplay(); + break; + case LIGHT_INTENS: + intensity = x/(GLfloat)winWidth; + glutPostRedisplay(); + break; + } +} + +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* move the light */ + action = LIGHT_XY; + motion(x, y); + break; + case GLUT_MIDDLE_BUTTON: + action = LIGHT_INTENS; + motion(x, y); + break; + case GLUT_RIGHT_BUTTON: /* move the polygon */ + action = LIGHT_Z; + motion(x, y); + break; + } +} + + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 3) & 0x1) ^ ((t >> 3) & 0x1); + } + } + return texture; +} + +/* make tesselated surface for display list dlist */ +/* normal tells you surface position and orientation */ +/* count = tesselation count */ +void +tess_surface(GLuint dlist, int count) +{ + int i, j; + GLfloat x0, y0, z0; + GLfloat over[3], up[3]; /* axes */ + int Sindex, Tindex; /* active texture axes */ + + glNewList(dlist, GL_COMPILE); + glBegin(GL_QUADS); + + switch(dlist) + { + case FLOOR: + glNormal3f( 0.f, 1.f, 0.f); + x0 = -100.f; y0 = -100.f; z0 = 100.f; + over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f; + up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count; + Sindex = X; Tindex = Z; + break; + case CEIL: + glNormal3f( 0.f, -1.f, 0.f); + x0 = -100.f; y0 = 100.f; z0 = 100.f; + over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count; + up[X] = 1.f/count; up[Y] = 0.f; up[Z] = 0.f; + Sindex = X; Tindex = Z; + break; + case LEFT: + glNormal3f( 1.f, 0.f, 0.f); + x0 = -100.f; y0 = -100.f; z0 = 100.f; + over[X] = 0.f; over[Y] = 0.f; over[Z] = -1.f/count; + up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f; + Sindex = Z; Tindex = Y; + break; + case RIGHT: + glNormal3f(-1.f, 0.f, 0.f); + x0 = 100.f; y0 = -100.f; z0 = 100.f; + over[X] = 0.f; over[Y] = 1.f/count; over[Z] = 0.f; + up[X] = 0.f; up[Y] = 0.f; up[Z] = -1.f/count; + Sindex = Z; Tindex = Y; + break; + case BACK: + glNormal3f( 0.f, 0.f, 1.f); + x0 = -100.f; y0 = -100.f; z0 = -100.f; + over[X] = 1.f/count; over[Y] = 0.f; over[Z] = 0.f; + up[X] = 0.f; up[Y] = 1.f/count; up[Z] = 0.f; + Sindex = X; Tindex = Y; + break; + default: + fprintf(stderr, "tess_surface(): bad display list argument %d\n", + dlist); + glEnd(); + glEndList(); + return; + } + + for(j = 0; j < count; j++) + for(i = 0; i < count; i++) + { + glTexCoord2f(i * over[Sindex], j * up[Tindex]); + glVertex3f(x0 + i * 200 * over[X] + j * 200 * up[X], + y0 + i * 200 * over[Y] + j * 200 * up[Y], + z0 + i * 200 * over[Z] + j * 200 * up[Z]); + glTexCoord2f((i + 1) * over[Sindex], j * up[Tindex]); + glVertex3f(x0 + (i + 1) * 200 * over[X] + j * 200 * up[X], + y0 + (i + 1) * 200 * over[Y] + j * 200 * up[Y], + z0 + (i + 1) * 200 * over[Z] + j * 200 * up[Z]); + glTexCoord2f((i + 1) * over[Sindex], (j + 1) * up[Tindex]); + glVertex3f(x0 + (i + 1) * 200 * over[X] + (j + 1) * 200 * up[X], + y0 + (i + 1) * 200 * over[Y] + (j + 1) * 200 * up[Y], + z0 + (i + 1) * 200 * over[Z] + (j + 1) * 200 * up[Z]); + glTexCoord2f(i * over[Sindex], (j + 1) * up[Tindex]); + glVertex3f(x0 + i * 200 * over[X] + (j + 1) * 200 * up[X], + y0 + i * 200 * over[Y] + (j + 1) * 200 * up[Y], + z0 + i * 200 * over[Z] + (j + 1) * 200 * up[Z]); + } + glEnd(); + glEndList(); +} + + + + + +static GLfloat zero[] = {0.f, 0.f, 0.f, 1.f}; +static GLfloat one[] = {1.f, 1.f, 1.f, 1.f}; +static GLfloat diff[] = {.25f, .25f, .25f, .25f}; + + +/* create a lightmap simulating a local light with attenuation */ +void +make_lightmap(GLenum light, int dim) +{ + GLfloat quadratic, linear, constant; + GLfloat diffuse[4], ambient[4]; /* light color */ + GLfloat *texture; + GLfloat dist, scale, edge; + int size; + int i, j; + + glPushAttrib(GL_TEXTURE_BIT); + /* get from light to simplify api */ + glGetLightfv(light, GL_QUADRATIC_ATTENUATION, &quadratic); + glGetLightfv(light, GL_LINEAR_ATTENUATION, &linear); + glGetLightfv(light, GL_CONSTANT_ATTENUATION, &constant); + + glGetLightfv(light, GL_AMBIENT, ambient); + glGetLightfv(light, GL_DIFFUSE, diffuse); + + size = dim + 2; + texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * size * size); + + dist = dim/2; /* 1 in from border */ + edge = 1.f/(constant + linear * dist + quadratic * dist * dist); + + for(j = 0; j < size; j++) + for(i = 0; i < size; i++) + { + dist = sqrtf((float)((size/2.f - i) * (size/2.f - i) + + (size/2.f - j) * (size/2.f - j))); + scale = 1.f/(constant + linear * dist + quadratic * dist * dist); + if(dist >= dim/2) + { + texture[3 * (i + size * j) + 0] = + diffuse[R] * edge + ambient[R]; + texture[3 * (i + size * j) + 1] = + diffuse[G] * edge + ambient[G]; + texture[3 * (i + size * j) + 2] = + diffuse[B] * edge + ambient[B]; + } + else + { + texture[3 * (i + size * j) + 0] = + diffuse[R] * scale + ambient[R]; + texture[3 * (i + size * j) + 1] = + diffuse[G] * scale + ambient[G]; + texture[3 * (i + size * j) + 2] = + diffuse[B] * scale + ambient[B]; + } + } + + glBindTexture(GL_TEXTURE_2D, LIGHTMAP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + size, size, 1, GL_RGB, GL_FLOAT, texture); + free(texture); + glPopAttrib(); +} + +/* draw a highly tesselated disk with local light */ +void +draw_lightmap(int dim, int dist) +{ + GLUquadricObj *qobj; + GLfloat *texture; + GLfloat light[4] = {0.f, 0.f, 1.f, 1.f}; + + texture = (GLfloat *)malloc(sizeof(GLfloat) * 3 * dim * dim); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); /* starts as modelview */ + glLoadIdentity(); + glTranslatef(0.f, 0.f, -dist); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-dim/2., dim/2., -dim/2., dim/2., 0., (double)dist); + + glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT); + glViewport(0, 0, dim, dim); + glEnable(GL_LIGHTING); + + light[Z] = dist; + glLightfv(GL_LIGHT0, GL_POSITION, light); /* light position */ + + /* XXX TODO, range check an report errors */ + glDisable(GL_TEXTURE_2D); + + qobj = gluNewQuadric(); + gluDisk(qobj, 0., dim/2. * sqrt(2.), dim/4, dim/4); + gluDeleteQuadric(qobj); + + glEnable(GL_TEXTURE_2D); + glPopAttrib(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glReadPixels(0, 0, dim, dim, GL_RGB, GL_FLOAT, texture); + + glBindTexture(GL_TEXTURE_2D, LIGHTMAP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dim, dim, 0, GL_RGB, + GL_FLOAT, texture); + + free(texture); +} + + +int texdim = 256; + + +/* draw the lightmap texture */ +void redraw_lightmap(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT); + + /* assume GL_MODELVIEW */ + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, LIGHTMAP); + glDisable(GL_LIGHTING); + + glColor3f(1.f, 1.f, 1.f); + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(-1, -1); + + glTexCoord2i(1, 0); + glVertex2i(1, -1); + + glTexCoord2i(1, 1); + glVertex2i(1, 1); + + glTexCoord2i(0, 1); + glVertex2i(-1, 1); + glEnd(); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); + + CHECK_ERROR("OpenGL Error in redraw_map()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* draw the lightmap texture */ +void redraw_combomap(void) +{ + GLfloat scale; + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT|GL_COLOR_BUFFER_BIT| + GL_DEPTH_BUFFER_BIT); + + /* assume GL_MODELVIEW */ + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + + + glBindTexture(GL_TEXTURE_2D, SURFMAP); + + glColor3f(intensity, intensity, intensity); + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(-1, -1); + + glTexCoord2i(5, 0); + glVertex2i(1, -1); + + glTexCoord2i(5, 5); + glVertex2i(1, 1); + + glTexCoord2i(0, 5); + glVertex2i(-1, 1); + glEnd(); + + glEnable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, LIGHTMAP); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glTranslatef(.5f, .5f, 0.f); + scale = .25f + (lightpos[Z] + 100.f) * 3.75f/200.f; + glScalef(scale, scale, 0.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f); + + glColor3f(1.f, 1.f, 1.f); + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex2i(-1, -1); + + glTexCoord2i(1, 0); + glVertex2i(1, -1); + + glTexCoord2i(1, 1); + glVertex2i(1, 1); + + glTexCoord2i(0, 1); + glVertex2i(-1, 1); + glEnd(); + + /* GL_TEXTURE */ + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); + + CHECK_ERROR("OpenGL Error in redraw_combomap()"); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +/* draw the openGL scene with lighting off */ +void render_scene(int tess) +{ + /* material properties for objects in scene */ + + /* update tessellation if it changed */ + if(tess != lasttess) + { + tess_surface(FLOOR, tess); + tess_surface(CEIL, tess); + tess_surface(LEFT, tess); + tess_surface(RIGHT, tess); + tess_surface(BACK, tess); + lasttess = tess; + } + glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT); + + /* floor */ + glColor3f(.5f, .35f, .35f); /* reddish */ + glEnable(GL_TEXTURE_2D); + glCallList(FLOOR); + glDisable(GL_TEXTURE_2D); + + /* ceiling */ + glColor3f(.35f, .5f, .35f); /* greenish */ + glCallList(CEIL); + + /* right wall */ + glColor3f(.35f, .35f, .5f); /* bluish */ + glCallList(RIGHT); + + /* left wall */ + glCallList(LEFT); + + /* back wall */ + glCallList(BACK); + + /* draw the sphere */ + + glCallList(SPHERE); + + /* draw the cone */ + glCallList(CONE); + + /* draw the light */ + glPushMatrix(); + glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]); + glCallList(LIGHT); + glPopMatrix(); + + glPopAttrib(); + CHECK_ERROR("OpenGL Error in render_unlit()"); +} + +void +redraw_opengl(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glPushAttrib(GL_LIGHTING_BIT); + + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */ + + + render_scene(curtess); + + glPopAttrib(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +void +redraw_unlit(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glPushAttrib(GL_LIGHTING_BIT); + + glDisable(GL_LIGHTING); + render_scene(1); + + glPopAttrib(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +/* draw the scene white, modulated by lightmap */ +/* unlit, uncolored simulated by lighting */ +/* texgen overrides texture coords */ +void render_white(void) +{ + GLfloat scale; + + /* texgen used to override texure coords */ + static GLfloat XZs[] = {1/200.f, 0.f, 0.f, .5f}; + static GLfloat XZt[] = {0.f, 0.f, 1/200.f, .5f}; + + static GLfloat YZs[] = {0.f, 0.f, 1/200.f, .5f}; + static GLfloat YZt[] = {0.f, 1/200.f, 0.f, .5f}; + + static GLfloat XYs[] = {1/200.f, 0.f, 0.f, .5f}; + static GLfloat XYt[] = {0.f, 1/200.f, 0.f, .5f}; + + /* material properties for objects in scene */ + + glPushAttrib(GL_LIGHTING_BIT|GL_TEXTURE_BIT); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + glEnable(GL_LIGHTING); + + /* simulate unlit, color = white */ + glLightfv(GL_LIGHT0, GL_AMBIENT, diff); + glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); + glColorMaterial(GL_FRONT, GL_AMBIENT); + glEnable(GL_COLOR_MATERIAL); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, LIGHTMAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, XZs); + glTexGenfv(GL_T, GL_OBJECT_PLANE, XZt); + + glLoadIdentity(); + glTranslatef(.5f, .5f, 0.f); + scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Y]); + glScalef(scale, scale, 1.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f); + /* add intensity (colorchange) */ + + scale = lightpos[Y] + 100; + scale /= 200.f; + scale *= scale; + scale = 1.f/(1.f + scale); + scale = 1.f; + glColor3f(scale, scale, scale); + + /* floor */ + glCallList(FLOOR); + + glLoadIdentity(); + glTranslatef(.5f, .5f, 0.f); + scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[Y]); + glScalef(scale, scale, 1.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[X]/200.f, -lightpos[Z]/200.f, 0.f); + + scale = 100 - lightpos[Y]; + scale /= 100.f; + scale *= scale; + scale = 1.f/(1.f + scale); + scale = 1.f; + glColor3f(scale, scale, scale); + + /* ceiling */ + glCallList(CEIL); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, YZs); + glTexGenfv(GL_T, GL_OBJECT_PLANE, YZt); + glLoadIdentity(); + glTranslatef(.5f, .5f, 0.f); + scale = nearScale - (nearScale - farScale)/200.f * (100.f - lightpos[X]); + glScalef(scale, scale, 1.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f); + + scale = 100 - lightpos[X]; + scale /= 100.f; + scale *= scale; + scale = 1.f/(1.f + scale); + scale = 1.f; + glColor3f(scale, scale, scale); + + /* right wall */ + glCallList(RIGHT); + + glLoadIdentity(); + glTranslatef(.5f, .5f, 0.f); + scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[X]); + glScalef(scale, scale, 1.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[Z]/200.f, -lightpos[Y]/200.f, 0.f); + + scale = lightpos[X] + 100; + scale /= 100.f; + scale *= scale; + scale = 1.f/(1.f + scale); + scale = 1.f; + glColor3f(scale, scale, scale); + + /* left wall */ + glCallList(LEFT); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, XYs); + glTexGenfv(GL_T, GL_OBJECT_PLANE, XYt); + glLoadIdentity(); + glTranslatef(.5f, .5f, 0.f); + scale = nearScale - (nearScale - farScale)/200.f * (100.f + lightpos[Z]); + glScalef(scale, scale, 1.f); + glTranslatef(-.5f, -.5f, 0.f); + glTranslatef(-lightpos[X]/200.f, -lightpos[Y]/200.f, 0.f); + + scale = lightpos[Z] + 100; + scale /= 100.f; + scale *= scale; + scale = 1.f/(1.f + scale); + scale = 1.f; + glColor3f(scale, scale, scale); + + /* back wall */ + glCallList(BACK); + + /* done with texture matrix */ + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + /* no contribution to highly tesselated objects */ + glMaterialfv(GL_FRONT, GL_AMBIENT, zero); + glLightfv(GL_LIGHT0, GL_AMBIENT, zero); + + /* draw the sphere */ + + glCallList(SPHERE); + + /* draw the cone */ + glCallList(CONE); + + glPopAttrib(); + CHECK_ERROR("OpenGL Error in render_white()"); +} + +void +redraw_white(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + render_white(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + +void +redraw_lightmapped(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + render_scene(1); + glEnable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glDepthFunc(GL_LEQUAL); + render_white(); + glPopAttrib(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +void +redraw_maponly(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + render_scene(1); + glEnable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glDepthFunc(GL_LEQUAL); + render_white(); + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_LIGHTING); /* add in unlit scene again */ + render_scene(1); + + glPopAttrib(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + +void +redraw_complete(void) +{ + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* opengl lit */ + glDisable(GL_LIGHTING); + render_scene(1); + glEnable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glDepthFunc(GL_LEQUAL); + render_white(); + glBlendFunc(GL_ONE, GL_ONE); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + render_scene(1); + + glPopAttrib(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); +} + + + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) + { + case 'l': /* show lightmap */ + glutDisplayFunc(redraw_lightmap); + glutPostRedisplay(); + break; + case 'w': /* show white scene modulated by lightmap */ + glutDisplayFunc(redraw_white); + glutPostRedisplay(); + break; + case 'm': /* unlit scene modified by lightmap */ + glutDisplayFunc(redraw_lightmapped); + glutPostRedisplay(); + break; + case 'u': /* draw scene without lighting */ + glutDisplayFunc(redraw_unlit); + glutPostRedisplay(); + break; + case 'o': /* draw scene lit using OpenGL */ + glutDisplayFunc(redraw_opengl); + glutPostRedisplay(); + break; + case 'a': /* show scene lit with OpenGL and lightmaps */ + glutDisplayFunc(redraw_complete); + glutPostRedisplay(); + break; + case 'p': /* show scene lit with pure lightmaps */ + glutDisplayFunc(redraw_maponly); + glutPostRedisplay(); + break; + case 'x': /* surface texture with lightmap combined */ + glutDisplayFunc(redraw_combomap); + glutPostRedisplay(); + break; + case 'T': /* surface texture with lightmap combined */ + curtess++; + glutPostRedisplay(); + break; + case 't': /* surface texture with lightmap combined */ + curtess--; + if(curtess < 1) + curtess = 1; + glutPostRedisplay(); + break; + case '1': /* surface texture with lightmap combined */ + curtess = 1; + glutPostRedisplay(); + break; + case 'y': + farScale -= .0001f; + if(farScale < .0001f) + farScale = .0001f; + printf("farScale = %.4f\n", farScale); + glutPostRedisplay(); + break; + case 'Y': + farScale += .0001f; + printf("farScale = %.4f\n", farScale); + glutPostRedisplay(); + break; + case 'z': + nearScale -= .01f; + if(nearScale < .01f) + nearScale = .01f; + printf("nearScale = %.2f\n", nearScale); + glutPostRedisplay(); + break; + case 'Z': + nearScale += .01f; + printf("nearScale = %.2f\n", nearScale); + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + case '?': + case 'h': + default: + fprintf(stderr, + "Keyboard Commands\n" + "l - draw lightmap\n" + "w - draw white scene modulated by lightmap\n" + "m - draw unlit scene modified by lightmap\n" + "u - draw unlit scene\n" + "o - draw scene lit by OpenGL\n" + "a - draw scene lit by OpenGL (tess = 1) + lightmaps\n" + "p - draw scene lit only by lightmaps\n" + "x - interactive lightmap on brick wall\n" + "T - increase surface tessellation\n" + "t - decrease surface tessellation\n" + "1 - set tessellation to one\n" + "y - decrease far scale for lightmaps\n" + "Y - increase far scale for lightmaps\n" + "z - decrease near scale for lightmaps\n" + "Z - increase near scale for lightmaps\n"); + break; + } + glutPostRedisplay(); +} + + + + +main(int argc, char *argv[]) +{ + GLfloat *tex; + + GLUquadricObj *qobj; + + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + if(argc > 1) + { + char *args = argv[1]; + int done = FALSE; + while(!done) + { + switch(*args) + { + case 's': /* single buffer */ + printf("Single Buffered\n"); + dblbuf = FALSE; + break; + case '-': /* do nothing */ + break; + case 0: + done = TRUE; + break; + } + args++; + } + } + + if(dblbuf) + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); + else + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH); + + + (void)glutCreateWindow("example program"); + glutDisplayFunc(redraw_opengl); + glutKeyboardFunc(key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutReshapeFunc(reshape); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-100., 100., -100., 100., 300., 501.); + glMatrixMode(GL_MODELVIEW); + /* look at scene from (0, 0, 400) */ + gluLookAt(0., 0., 400., 0., 0., 0., 0., 1., 0.); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, staticlightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + + /* make a display list containing a sphere */ + glNewList(SPHERE, GL_COMPILE); + { + glPushMatrix(); + glTranslatef(0.f, -80.f, -80.f); + qobj = gluNewQuadric(); + gluQuadricTexture(qobj, GL_TRUE); + glColor3f(.5f, .25f, 0.f); + gluSphere(qobj, 20.f, 20, 20); + gluDeleteQuadric(qobj); + glPopMatrix(); + } + glEndList(); + + /* make a display list containing a sphere */ + glNewList(LIGHT, GL_COMPILE); + { + qobj = gluNewQuadric(); + glColor3f(1.f, 1.f, 1.f); + glPushAttrib(GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + gluSphere(qobj, 3.f, 20, 20); + glPopAttrib(); + gluDeleteQuadric(qobj); + } + glEndList(); + + /* create a display list containing a cone */ + glNewList(CONE, GL_COMPILE); + { + glPushMatrix(); + glTranslatef(-60.f, -100.f, -5.f); + + qobj = gluNewQuadric(); + gluQuadricTexture(qobj, GL_TRUE); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glColor3f(0.f, .25f, .5f); + + gluCylinder(qobj, 20., 0., 60., 20, 20); + gluDeleteQuadric(qobj); + + qobj = gluNewQuadric(); + gluQuadricOrientation(qobj, GLU_INSIDE); + gluDisk(qobj, 0., 20., 20, 1); + gluDeleteQuadric(qobj); + glPopMatrix(); + } + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(128, 128); + + /* makes texturing faster, and looks better than GL_LINEAR */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 1, 128, 128, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + { + GLuint *surftex; + int texwid, texht, texcomps; + surftex = read_texture("../data/brick.rgb", &texwid, &texht, &texcomps); + + glBindTexture(GL_TEXTURE_2D, SURFMAP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texwid, texht, 0, GL_RGBA, + GL_UNSIGNED_BYTE, surftex); + + } + + glBindTexture(GL_TEXTURE_2D, DEFAULT); + + tess_surface(FLOOR, 1); + tess_surface(CEIL, 1); + tess_surface(LEFT, 1); + tess_surface(RIGHT, 1); + tess_surface(BACK, 1); + + /* 1/80 intensity at edges */ + glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 100.f/(texdim * texdim/4)); + /* 1/2 intensity at edges */ + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 1.f/texdim/2); + glLightfv(GL_LIGHT1, GL_DIFFUSE, one); + + make_lightmap(GL_LIGHT1, 128); + + key('?', 0, 0); + + CHECK_ERROR("end of main"); + + glutMainLoop(); + + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/lightmap.dsp b/lib/glut-3.7.6/progs/advanced97/lightmap.dsp new file mode 100644 index 0000000000..350cbd1406 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/lightmap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="lightmap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=lightmap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lightmap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lightmap.mak" CFG="lightmap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lightmap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "lightmap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lightmap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "lightmap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lightmap - Win32 Release" +# Name "lightmap - Win32 Debug" +# Begin Source File + +SOURCE=.\lightmap.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/lightp.c b/lib/glut-3.7.6/progs/advanced97/lightp.c new file mode 100644 index 0000000000..4f35585694 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/lightp.c @@ -0,0 +1,315 @@ +#include +#include +#include +#include "texture.h" +#include + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define expf(x) ((float)exp((x))) +#define fabsf(x) ((float)fabs((x))) +#endif + +static int pstyle = 3; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void pfunc(void) { pstyle = (pstyle+1) % 4; } + +void help(void) { + printf("Usage: lightp [image]\n"); + printf("'h' - help\n"); + printf("'p' - toggle point mode\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(char *filename) { + GLfloat fog_color[4], fog_density = 0.05, density, far_cull; + unsigned *image; + int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 1 && components != 2) { + printf("must be a l or la image\n"); + exit(EXIT_FAILURE); + } + if (components == 1) { + /* hack for RE */ + int i; + GLubyte *p = (GLubyte *)image; + for(i = 0; i < width*height; i++) { + p[i*4+3] = p[i*4+0]; + } + components = 2; + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + /*glEnable(GL_TEXTURE_2D);*/ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,far_cull = 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + + density = 1.- expf(-5.5 * fog_density * fog_density * + far_cull * far_cull); + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + density = MAX(MIN(density, 1.), 0.); + + fog_color[0] = .23*.19 + density *.57*.19; + fog_color[1] = .35*.19 + density *.45*.19; + fog_color[2] = .78*.19 + density *.22*.19; + + glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f); + + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fog_density); + glFogfv(GL_FOG_COLOR, fog_color); + if (fog_density > 0) + glEnable(GL_FOG); + glLineWidth(2.0f); + glEnable(GL_LINE_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPointSize(10.f); + glEnable(GL_POINT_SMOOTH); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); +} + +void draw_base(void) { + glColor4f(.1, .3, .1, 1.0); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); +} + +void draw_runway(void) { + glColor4f(.1, .1, .1, 1.0); + glPushMatrix(); + glScalef(.1f, 1.f, 1.f); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); + glPopMatrix(); +} + +/* v0 = v1*mat */ +void xform(float *v0, float *mat, float *v1) { + v0[0] = v1[0]*mat[0] + v1[1]*mat[4] + v1[2]*mat[8] + v1[3]*mat[12]; + v0[1] = v1[1]*mat[1] + v1[1]*mat[5] + v1[2]*mat[9] + v1[3]*mat[13]; + v0[2] = v1[2]*mat[2] + v1[1]*mat[6] + v1[2]*mat[10] + v1[3]*mat[14]; + v0[3] = v1[3]*mat[3] + v1[1]*mat[7] + v1[2]*mat[11] + v1[3]*mat[15]; +} + +/* m0 = m1*m2 */ +void xformm(float *m0, float *m1, float *m2) { + int i, j; + for(i = 0; i < 4; i++) { + for(j = 0; j < 4; j++) { + m0[4*i+j] = m1[4*i+0]*m2[4*0+j] + m1[4*i+1]*m2[4*1+j] + m1[4*i+2]*m2[4*2+j] + m1[4*i+3]*m2[4*3+j]; + } + } +} + +void draw_quad(float x, float y, float z) { + glPushMatrix(); + glTranslatef(x, y, z); + glRotatef(90.f, 1.f, 0.f, 0.f); + glScalef(.03f, .03f, .03f); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); + glPopMatrix(); +} + +void draw_lights(void) { + int i; + GLfloat mat[16], matv[16], matp[16]; + float v0[4], v1[4], v[4]; + + glEnable(GL_BLEND); + glColor4f(1.f, 1.f, 1.f, 1.0); + glPushMatrix(); + if (pstyle != 3) { + glScalef(.1f, 1.f, 1.f); + if (pstyle == 0) glDisable(GL_POINT_SMOOTH); + else glEnable(GL_POINT_SMOOTH); + if (pstyle == 1) glPointSize(13.f); + glGetFloatv(GL_MODELVIEW_MATRIX, matv); + glGetFloatv(GL_PROJECTION_MATRIX, matp); + xformm(mat, matv, matp); + v[0] = -1.f; + v[1] = 0.0f; + v[3] = 1.0f; + for(i = 0; i <= 20; i++) { + if (pstyle == 2) { + float s; + v[2] = -1.f+2.f/20*i; + v[0] -= 1.; + xform(v0, mat, v); + v[0] += 2.; + xform(v1, mat, v); + v[0] -= 1.; + s = fabsf(v0[0]/v0[3] - v1[0]/v1[3]); + glPointSize(10.f*s); + } + glBegin(GL_POINTS); + glVertex3f(-1.f, 0.f, -1.f+2.f/20*i); + glVertex3f( 1.f, 0.f, -1.f+2.f/20*i); + glEnd(); + } + } else { + glEnable(GL_TEXTURE_2D); + glScalef(1.f, 10.f, 1.f); + for(i = 0; i <= 20; i++) { + float v = -1.f+2.f/20*i; + draw_quad(-.1f, 0.f, v); + draw_quad( .1f, 0.f, v); + } + glDisable(GL_TEXTURE_2D); + } + glPopMatrix(); + glDisable(GL_BLEND); +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(10.f,1.f,10.f); + glTranslatef(0.f,-.4f,0.f); + draw_base(); + draw_runway(); + draw_lights(); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'p': pfunc(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/light.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/lightp.dsp b/lib/glut-3.7.6/progs/advanced97/lightp.dsp new file mode 100644 index 0000000000..2c14fee20a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/lightp.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="lightp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=lightp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lightp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lightp.mak" CFG="lightp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lightp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "lightp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lightp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "lightp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lightp - Win32 Release" +# Name "lightp - Win32 Debug" +# Begin Source File + +SOURCE=.\lightp.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/line.c b/lib/glut-3.7.6/progs/advanced97/line.c new file mode 100644 index 0000000000..c757f64abb --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/line.c @@ -0,0 +1,224 @@ +#include +#include +#include + +#define CHECK_ERROR(str) \ +{ \ + GLenum error; \ + if(error = glGetError()) \ + printf("GL Error: %s (%s)\n", gluErrorString(error), str); \ +} + +int winWidth = 512; +int winHeight = 512; +GLboolean smooth = GL_FALSE; +GLboolean dblbuf = GL_TRUE; +GLfloat objangle[2] = {0.f, 0.f}; +GLfloat scale = 1.f; +int active; + +enum {X, Y, Z}; +enum {OBJ_ANGLE, OBJ_SCALE}; +enum {NOLIST, PLANE}; /* display lists */ + +/* load data structure from file */ +enum {VERTS, END}; + + +void +reshape(int wid, int ht) +{ + winWidth = wid; + winHeight = ht; + glViewport(0, 0, wid, ht); +} + +void +motion(int x, int y) +{ + + switch(active) + { + case OBJ_ANGLE: + objangle[X] = (x - winWidth/2) * 360./winWidth; + objangle[Y] = (y - winHeight/2) * 360./winHeight; + glutPostRedisplay(); + break; + case OBJ_SCALE: + scale = x * 5./winWidth; + objangle[Y] = (y - winHeight/2) * 360./winHeight; + glutPostRedisplay(); + break; + } +} + +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* rotate the object */ + active = OBJ_ANGLE; + motion(x, y); + break; + case GLUT_RIGHT_BUTTON: /* scale the object */ + active = OBJ_SCALE; + motion(x, y); + break; + } +} + + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) + { + case 's': /* toggle line smoothing */ + if(smooth) + { + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + smooth = GL_FALSE; + printf("Turn off OpenGL line smoothing\n"); + } + else + { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + printf("Turn on OpenGL line smoothing\n"); + smooth = GL_TRUE; + } + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + case '?': + case 'h': + case 'H': + default: + fprintf(stderr, "Keyboard commands:\n\n" + "s - toggle smooth line mode\n"); + break; + } + +} + + +void +loader(char *fname) +{ + FILE *fp; + GLfloat x, y, z; + int state = END; + int read; + + fp = fopen(fname, "r"); + if (!fp) { + printf("can't open file %s\n", fname); + exit(1); + } + + glNewList(PLANE, GL_COMPILE); + while(!feof(fp)) + { + switch(state) + { + case END: + read = fscanf(fp, " v"); + if(read < 0) /* hit eof */ + break; + state = VERTS; + glBegin(GL_LINE_STRIP); + break; + case VERTS: + read = fscanf(fp, " %f %f %f", &x, &y, &z); + if(read == 3) + glVertex3f(x, y, z); + else + { + fscanf(fp, " e"); + glEnd(); + state = END; + } + break; + } + } + glEndList(); + fclose(fp); +} + +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */ + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + glScalef(scale, scale, scale); + + glCallList(PLANE); + + glPopMatrix(); + + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); + + CHECK_ERROR("OpenGL Error in redraw()"); +} + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + if(argc > 1) + { + char *args = argv[1]; + GLboolean done = GL_FALSE; + while(!done) + { + switch(*args) + { + case 's': /* single buffer */ + printf("Single Buffered\n"); + dblbuf = GL_FALSE; + break; + case '-': /* do nothing */ + break; + case 0: + done = GL_TRUE; + break; + } + args++; + } + } + if(dblbuf) + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + else + glutInitDisplayMode(GLUT_RGBA); + + (void)glutCreateWindow("load and draw a wireframe image"); + glutDisplayFunc(redraw); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutMotionFunc(motion); + glutMouseFunc(mouse); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1., 1., -1., 1., -5., 5.); + glMatrixMode(GL_MODELVIEW); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + + loader("../data/f15.data"); + + CHECK_ERROR("OpenGL Error in main()"); + + key('?', 0, 0); /* print usage message */ + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced97/line.dsp b/lib/glut-3.7.6/progs/advanced97/line.dsp new file mode 100644 index 0000000000..e5375ba63a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/line.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="line" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=line - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "line.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "line.mak" CFG="line - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "line - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "line - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "line - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "line - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "line - Win32 Release" +# Name "line - Win32 Debug" +# Begin Source File + +SOURCE=.\line.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multiaccumaa.c b/lib/glut-3.7.6/progs/advanced97/multiaccumaa.c new file mode 100644 index 0000000000..092c4c9aa4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multiaccumaa.c @@ -0,0 +1,436 @@ +#include +#include + +#ifdef _WIN32 +#include +#define sleep(x) Sleep(1000*x) +#else +#include +#endif + +#include + +const GLdouble FRUSTDIM = 100.f; +int win_width = 256; +int win_height = 256; +int show_results = GL_TRUE; +int object_offset, font_offset; + +enum {SPHERE, CONE}; + +/*{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},*/ +GLubyte rasters[][13] = { +{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c}, +{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18}, +{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e}, +{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e}, +{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c}, +{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, +{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, +{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff}, +{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, +{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, +}; + +GLfloat mults[] = {1., 1./2., 2./3., 3./4., 4./5., 5./6., 6./7., 7./8., 8./9., 9./10.}; + + +/* +** Create a single component texture map +*/ + +void make_font(void) +{ + GLuint i; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + font_offset = glGenLists (10); + for (i = 0; i < 10; i++) { + glNewList(i+font_offset, GL_COMPILE); + glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, rasters[i]); + glEndList(); + } +} + +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +void print_frame_number(GLuint frame) +{ + GLuint f1, f2; + + glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho (0.0, win_width, 0.0, win_height, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + + glColor3f(1.0, 0.0, 0.0); + + f1 = frame/10; + if (f1 > 0) { + glRasterPos2i(50, win_height - 50); + glCallList(font_offset + f1); + } + else + glRasterPos2i(60, win_height - 50); + f2 = frame - f1*10; + glCallList(font_offset + f2); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +} + +void +render(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + + glPushMatrix(); + glTranslatef(-80.f, -60.f, -420.f); + glCallList(object_offset + SPHERE); + glPopMatrix(); + + + glPushMatrix(); + glTranslatef(-20.f, -80.f, -500.f); + glCallList(object_offset + CONE); + glPopMatrix(); + + if(glGetError()) /* to catch programming errors; should never happen */ + printf("Oops! I screwed up my OpenGL calls somewhere\n"); + + glFlush(); /* high end machines may need this */ +} + +/* compute scale factor for window->object space transform */ +/* could use gluUnProject(), but probably too much trouble */ +void +computescale(GLfloat *sx, GLfloat *sy) +{ + enum {XORG, YORG, WID, HT}; + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + *sx = 2 * FRUSTDIM/viewport[WID]; + *sy = 2 * FRUSTDIM/viewport[WID]; +} + +enum {NONE, AA, AA_NEW}; + +int rendermode = NONE; + +void +menu(int selection) +{ + rendermode = selection; + glutPostRedisplay(); +} + + + +/* Called when window needs to be redrawn */ +void redraw(void) +{ + GLfloat invx, invy; + GLfloat scale, dx, dy; + int i, j; + int min, max; + int count, nframes; + + switch(rendermode) { + case NONE: + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + glutSwapBuffers(); + break; + case AA: + min = -1; + max = -min + 1; + count = -2 * min + 1; + count *= count; + /* uniform scaling, less than one pixel wide */ + scale = -.9f/min; + + computescale(&invx, &invy); + + glClear(GL_ACCUM_BUFFER_BIT); + + for(j = min, nframes = 1; j < max; j++) { + for(i = min; i < max; i++, nframes++) { + dx = invx * scale * i; + dy = invy * scale * j; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM + dx, + FRUSTDIM + dy, + -FRUSTDIM + dx, + FRUSTDIM + dy, + 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + glAccum(GL_ACCUM, 1.f/count); + + if (show_results) { + if (nframes == 1) { + glutSwapBuffers(); + glDrawBuffer(GL_FRONT); + } else if (nframes == 2) { + glDrawBuffer(GL_FRONT); + glAccum(GL_RETURN, 3.99); + } else { + glDrawBuffer(GL_FRONT); + glAccum(GL_RETURN, (GLfloat)count/(GLfloat)nframes); + } + print_frame_number(nframes); + glFlush(); + printf("frame number %d\n",nframes); + glDrawBuffer(GL_BACK); + sleep(3); + } + } + } + if (!show_results) { + glAccum(GL_RETURN, 1.f); + glutSwapBuffers(); + } + break; + case AA_NEW: + min = -2; + max = -min + 1; + count = -2 * min + 1; + count *= count; + /* uniform scaling, less than one pixel wide */ + scale = -.9f/min; + + computescale(&invx, &invy); + + glClear(GL_ACCUM_BUFFER_BIT); + + for(j = min, nframes = 1; j < max; j++) { + for(i = min; i < max; i++, nframes++) { + dx = invx * scale * i; + dy = invy * scale * j; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-FRUSTDIM + dx, + FRUSTDIM + dy, + -FRUSTDIM + dx, + FRUSTDIM + dy, + 320., 640.); + glMatrixMode(GL_MODELVIEW); + render(); + if (nframes == 1) + glAccum(GL_ACCUM, 1.); + else + glAccum(GL_ACCUM, .5); + + if (show_results) { + glDrawBuffer(GL_FRONT); + glAccum(GL_RETURN, 1.); + print_frame_number(nframes); + glFlush(); + printf("frame number %d\n",nframes); + glDrawBuffer(GL_BACK); + sleep(3); + } + + if (nframes < count) { + glAccum(GL_RETURN, 1.); + glAccum(GL_LOAD, .5); + } + + } + } + if (!show_results) { + glAccum(GL_RETURN, 1.f); + glutSwapBuffers(); + } + break; + } + +} + +void reshape(int w, int h) +{ + if (w < h) { + win_height = win_width = w; + } else { + win_height = win_width = h; + } + glViewport(0, 0, win_width, win_height); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if(key == '\033') + exit(0); +} + + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(win_width, win_height); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); + (void)glutCreateWindow("Accum antialias"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + + glutCreateMenu(menu); + glutAddMenuEntry("Aliased View", NONE); + glutAddMenuEntry("AntiAliased View", AA); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + make_font(); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + object_offset = glGenLists(2); + glNewList(object_offset + SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(object_offset + CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + glReadBuffer(GL_BACK); /* input to accum buffer */ + + glutMainLoop(); + + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/multiaccumaa.dsp b/lib/glut-3.7.6/progs/advanced97/multiaccumaa.dsp new file mode 100644 index 0000000000..062a308191 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multiaccumaa.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multiaccumaa" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multiaccumaa - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multiaccumaa.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multiaccumaa.mak" CFG="multiaccumaa - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multiaccumaa - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multiaccumaa - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multiaccumaa - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multiaccumaa - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multiaccumaa - Win32 Release" +# Name "multiaccumaa - Win32 Debug" +# Begin Source File + +SOURCE=.\multiaccumaa.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multialphablend.c b/lib/glut-3.7.6/progs/advanced97/multialphablend.c new file mode 100644 index 0000000000..a9548540f4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multialphablend.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include + +GLUquadricObj *cone, *base, *qsphere; + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + + /* base is coplanar with floor, so turn off depth testing */ + glDisable(GL_DEPTH_TEST); + gluDisk(base, 0., .3, 20, 1); + glEnable(GL_DEPTH_TEST); + + gluCylinder(cone, .3, 0, 1.25, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(.6, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs, degrees; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* one revolution every 10 seconds... */ + secs = get_secs(); + secs = secs - 10.*trunc(secs / 10.); + degrees = (secs/10.) * (360.); + + draw_room(); + + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + if (degrees < 180) { + /* sphere behind cone */ + glCullFace(GL_FRONT); + draw_sphere(degrees); + draw_cone(); + glCullFace(GL_BACK); + draw_sphere(degrees); + draw_cone(); + } else { + /* cone behind sphere */ + glCullFace(GL_FRONT); + draw_cone(); + draw_sphere(degrees); + glCullFace(GL_BACK); + draw_cone(); + draw_sphere(degrees); + } + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + if (key == 27) exit(0); + idle = (idle == 0); + if (idle) { + glutIdleFunc(draw); + } else { + glutIdleFunc(0); + } + +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/multialphablend.dsp b/lib/glut-3.7.6/progs/advanced97/multialphablend.dsp new file mode 100644 index 0000000000..101aa76f2a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multialphablend.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multialphablend" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multialphablend - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multialphablend.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multialphablend.mak" CFG="multialphablend - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multialphablend - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multialphablend - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multialphablend - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multialphablend - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multialphablend - Win32 Release" +# Name "multialphablend - Win32 Debug" +# Begin Source File + +SOURCE=.\multialphablend.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.c b/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.c new file mode 100644 index 0000000000..d97a5464f6 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include + +GLUquadricObj *cone, *base, *qsphere; + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + + /* base is coplanar with floor, so turn off depth testing */ + glDisable(GL_DEPTH_TEST); + gluDisk(base, 0., .3, 20, 1); + glEnable(GL_DEPTH_TEST); + + gluCylinder(cone, .3, 0, 1.25, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, .5f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(.6, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs, degrees; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* one revolution every 10 seconds... */ + secs = get_secs(); + secs = secs - 10.*trunc(secs / 10.); + degrees = (secs/10.) * (360.); + + draw_room(); + + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + draw_cone(); + draw_sphere(degrees); + glCullFace(GL_BACK); + draw_cone(); + draw_sphere(degrees); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + if (key == 27) exit(0); + idle = (idle == 0); + if (idle) { + glutIdleFunc(draw); + } else { + glutIdleFunc(0); + } +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.dsp b/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.dsp new file mode 100644 index 0000000000..4d0980b9f1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multialphablendnosort.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multialphablendnosort" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multialphablendnosort - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multialphablendnosort.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multialphablendnosort.mak" CFG="multialphablendnosort - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multialphablendnosort - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multialphablendnosort - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multialphablendnosort - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multialphablendnosort - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multialphablendnosort - Win32 Release" +# Name "multialphablendnosort - Win32 Debug" +# Begin Source File + +SOURCE=.\multialphablendnosort.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multimirror.c b/lib/glut-3.7.6/progs/advanced97/multimirror.c new file mode 100644 index 0000000000..c8401613ec --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multimirror.c @@ -0,0 +1,367 @@ +#include +#include +#include +#include +#include + +GLUquadricObj *cone, *base, *qsphere; + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +int draw_passes = 8; + +int headsUp = 0; + +typedef struct { + GLfloat verts[4][3]; + GLfloat scale[3]; + GLfloat trans[3]; +} Mirror; + +Mirror mirrors[] = { + /* mirror on the left wall */ + {{{-1., -.75, -.75}, {-1., .75, -.75}, {-1., .75, .75}, {-1, -.75, .75}}, + {-1, 1, 1}, {2, 0, 0}}, + + /* mirror on right wall */ + {{{1., -.75, .75}, {1., .75, .75}, {1., .75, -.75}, {1., -.75, -.75}}, + {-1, 1, 1}, {-2, 0, 0}}, +}; +int nMirrors = 2; + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + glEnable(GL_CULL_FACE); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + cone = gluNewQuadric(); + qsphere = gluNewQuadric(); +} + +void make_viewpoint(void) +{ + if (headsUp) { + float width = (1 + 2*(draw_passes/nMirrors)) * 1.25; + float height = (width / tan((30./360.) * (2.*M_PI))) + 1; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, height - 3, height + 3); + gluLookAt(0, height, 0, + 0, 0, 0, + 0, 0, 1); + } else { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 4 + 2*(draw_passes / nMirrors)); + gluLookAt(-2, 0, .75, + 0, 0, 0, + 0, 1, 0); + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + make_viewpoint(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, 1, -1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, -1, 1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, -1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, 1, -1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + /* back wall */ + glNormal3f(0, 0, -1); + glVertex3f(-1, 1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(-1, -1, 1); + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + + gluCylinder(cone, .3, 0, 1.25, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble secs) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + GLfloat angle; + + /* one revolution every 10 seconds... */ + secs = secs - 10.*trunc(secs / 10.); + angle = (secs/10.) * (360.); + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(.6, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw_mirror(Mirror *m) +{ + glBegin(GL_QUADS); + glVertex3fv(m->verts[0]); + glVertex3fv(m->verts[1]); + glVertex3fv(m->verts[2]); + glVertex3fv(m->verts[3]); + glEnd(); +} + +/* A note on matrix management: it would be easier to use push and + * pop to save and restore the matrices, but the projection matrix stack + * is very shallow, so we just undo what we did. In the extreme this + * could lead to mathematic error. */ + +GLenum reflect_through_mirror(Mirror *m, GLenum cullFace) +{ + GLenum newCullFace = ((cullFace == GL_FRONT) ? GL_BACK : GL_FRONT); + + glMatrixMode(GL_PROJECTION); + glScalef(m->scale[0], m->scale[1], m->scale[2]); + glTranslatef(m->trans[0], m->trans[1], m->trans[2]); + glMatrixMode(GL_MODELVIEW); + + /* must flip the cull face since reflection reverses the orientation + * of the polygons */ + glCullFace(newCullFace); + + return newCullFace; +} + +void undo_reflect_through_mirror(Mirror *m, GLenum cullFace) +{ + glMatrixMode(GL_PROJECTION); + glTranslatef(-m->trans[0], -m->trans[1], -m->trans[2]); + glScalef(1./m->scale[0], 1./m->scale[1], 1./m->scale[2]); + glMatrixMode(GL_MODELVIEW); + + glCullFace(cullFace); +} + +void draw_scene(GLdouble secs, int passes, GLenum cullFace, + GLuint stencilVal, GLuint mirror) +{ + GLenum newCullFace; + int passesPerMirror, passesPerMirrorRem; + unsigned int curMirror, drawMirrors; + int i; + + /* one pass to draw the real scene */ + passes--; + + /* only draw in my designated locations */ + glStencilFunc(GL_EQUAL, stencilVal, 0xffffffff); + + /* draw things which may obscure the mirrors first */ + draw_sphere(secs); + draw_cone(); + + /* now draw the appropriate number of mirror reflections. for + * best results, we perform a depth-first traversal by allocating + * a number of passes for each of the mirrors. */ + if (mirror != 0xffffffff) { + passesPerMirror = passes / (nMirrors - 1); + passesPerMirrorRem = passes % (nMirrors - 1); + if (passes > nMirrors - 1) drawMirrors = nMirrors - 1; + else drawMirrors = passes; + } else { + /* mirror == -1 means that this is the initial scene (there was no + * mirror) */ + passesPerMirror = passes / nMirrors; + passesPerMirrorRem = passes % nMirrors; + if (passes > nMirrors) drawMirrors = nMirrors; + else drawMirrors = passes; + } + for (i = 0; drawMirrors > 0; i++) { + curMirror = i % nMirrors; + if (curMirror == mirror) continue; + drawMirrors--; + + /* draw mirror into stencil buffer but not color or depth buffers */ + glColorMask(0, 0, 0, 0); + glDepthMask(0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + draw_mirror(&mirrors[curMirror]); + glColorMask(1, 1, 1, 1); + glDepthMask(1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + /* draw reflected scene */ + newCullFace = reflect_through_mirror(&mirrors[curMirror], cullFace); + if (passesPerMirrorRem) { + draw_scene(secs, passesPerMirror + 1, newCullFace, stencilVal + 1, + curMirror); + passesPerMirrorRem--; + } else { + draw_scene(secs, passesPerMirror, newCullFace, stencilVal + 1, + curMirror); + } + undo_reflect_through_mirror(&mirrors[curMirror], cullFace); + + /* back to our stencil value */ + glStencilFunc(GL_EQUAL, stencilVal, 0xffffffff); + } + + draw_room(); +} + +void draw(void) +{ + GLenum err; + GLfloat secs = get_secs(); + + glDisable(GL_STENCIL_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + if (!headsUp) glEnable(GL_STENCIL_TEST); + draw_scene(secs, draw_passes, GL_BACK, 0, (unsigned)-1); + glDisable(GL_STENCIL_TEST); + + if (headsUp) { + /* draw a red floor on the original scene */ + glDisable(GL_LIGHTING); + glBegin(GL_QUADS); + glColor3f(1, 0, 0); + glVertex3f(-1, -.95, 1); + glVertex3f(1, -.95, 1); + glVertex3f(1, -.95, -1); + glVertex3f(-1, -.95, -1); + glEnd(); + glEnable(GL_LIGHTING); + } + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) { + case '.': case '>': case '+': case '=': + draw_passes++; + printf("Passes = %d\n", draw_passes); + make_viewpoint(); + break; + case ',': case '<': case '-': case '_': + draw_passes--; + if (draw_passes < 1) draw_passes = 1; + printf("Passes = %d\n", draw_passes); + make_viewpoint(); + break; + case 'h': case 'H': + /* heads up mode */ + headsUp = (headsUp == 0); + make_viewpoint(); + break; + case 27: + exit(0); + } +} + +#define MIN_COLOR_BITS 4 +#define MIN_DEPTH_BITS 8 + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + if (argc > 1) { + glutInitDisplayString("samples stencil>=3 rgb depth"); + } else { + glutInitDisplayString("samples stencil>=3 rgb double depth"); + } + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/multimirror.dsp b/lib/glut-3.7.6/progs/advanced97/multimirror.dsp new file mode 100644 index 0000000000..b1b1d23e89 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multimirror.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multimirror" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multimirror - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multimirror.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multimirror.mak" CFG="multimirror - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multimirror - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multimirror - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multimirror - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multimirror - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multimirror - Win32 Release" +# Name "multimirror - Win32 Debug" +# Begin Source File + +SOURCE=.\multimirror.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multiscreendoor.c b/lib/glut-3.7.6/progs/advanced97/multiscreendoor.c new file mode 100644 index 0000000000..3340042d26 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multiscreendoor.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef _WIN32 +#define trunc(x) ((double)((int)(x))) +#define random() ((long)rand() + (rand() << 15) + (rand() << 30)) +#endif + +GLUquadricObj *cone, *base, *qsphere; + +GLuint conePattern[32], spherePattern[32]; + +void create_stipple_pattern(GLuint *pat, GLfloat opacity) +{ + int x, y; + long threshold = (float)0x7fffffff * (1. - opacity); + + for (y = 0; y < 32; y++) { + pat[y] = 0; + for (x = 0; x < 32; x++) { + if (random() > threshold) pat[y] |= (1 << x); + } + } +} + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + gluQuadricOrientation(base, GLU_INSIDE); + + create_stipple_pattern(spherePattern, .5); + create_stipple_pattern(conePattern, .5); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluCylinder(cone, .3, 0, 1.25, 20, 1); + gluDisk(base, 0., .3, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(0, 0, .6); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_room(); + + /* draw the transparent objects... */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple((GLubyte *)conePattern); + draw_cone(); + + glPolygonStipple((GLubyte *)spherePattern); + secs = get_secs(); + draw_sphere(secs * 360. / 10.); + glDisable(GL_POLYGON_STIPPLE); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if (key == 27) exit(0); +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/multiscreendoor.dsp b/lib/glut-3.7.6/progs/advanced97/multiscreendoor.dsp new file mode 100644 index 0000000000..729dd123e3 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multiscreendoor.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="multiscreendoor" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multiscreendoor - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multiscreendoor.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multiscreendoor.mak" CFG="multiscreendoor - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multiscreendoor - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multiscreendoor - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multiscreendoor - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multiscreendoor - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multiscreendoor - Win32 Release" +# Name "multiscreendoor - Win32 Debug" +# Begin Source File + +SOURCE=.\multiscreendoor.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/multispheremap.c b/lib/glut-3.7.6/progs/advanced97/multispheremap.c new file mode 100644 index 0000000000..b2ab0cc647 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multispheremap.c @@ -0,0 +1,737 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +GLUquadricObj *cone, *base, *qsphere; + +static char defaultFile[] = "../data/mandrill.rgb"; +GLuint floorList; + +GLboolean animate = 1, useSphereMaps = 1; + +GLsizei w = 256, h = 256; + +#define LEFT 3 +#define RIGHT 1 +#define FRONT 2 +#define BACK 0 +#define TOP 4 +#define BOTTOM 5 + +GLuint *faceMap[6]; +GLsizei faceW = 128; + +GLuint *sphereMap[2]; +GLuint sphereW = 256; + +GLfloat angle1[6] = {90, 180, 270, 0, 90, -90}; +GLfloat axis1[6][3] = {{0,1,0}, {0,1,0}, {0,1,0}, {0,1,0}, {1,0,0}, {1,0,0}}; +GLfloat angle2[6] = {0, 0, 0, 0, 180, 180}; +GLfloat axis2[6][3] = {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,1,0}, {0,1,0}}; + +#define TORUS_BIT 1 +#define SPHERE_BIT 2 + +void reset_textures(void) +{ + unsigned int i; + + /* make sphereMap[0] start out all red... */ + for (i = 0; i < sphereW*sphereW; i++) sphereMap[0][i] = 0xff0000ff; + /* make sphereMap[1] start out all green... */ + for (i = 0; i < sphereW*sphereW; i++) sphereMap[1][i] = 0x00ff00ff; +} + +void realloc_textures(void) +{ + static int first = 1; + int i; + + if (!first) { + for (i = 0; i < 6; i++) free(faceMap[i]); + } else { + first = 0; + } + + for (i = 0; i < 6; i++) { + faceMap[i] = (GLuint *)malloc(faceW*faceW*sizeof(GLuint)); + if (!faceMap[i]) { + fprintf(stderr, "malloc of %d bytes failed.\n", + faceW*faceW*sizeof(GLuint)); + } + } + + sphereMap[0] = (GLuint *)malloc(sphereW * sphereW * sizeof(GLuint)); + sphereMap[1] = (GLuint *)malloc(sphereW * sphereW * sizeof(GLuint)); + reset_textures(); +} + +void eliminate_alpha(GLsizei w, GLsizei h, GLuint *map) +{ + int x, y; + + /* top & bottom rows */ + for (x = 0; x < w; x++) { + map[x] &= 0xffffff00; + map[x + (h-1)*w] &= 0xffffff00; + } + + for (y = 0; y < h; y++) { + map[y*w] &= 0xffffff00; + map[y*w + (w-1)] &= 0xffffff00; + } +} + +void init(const char *fname) +{ + GLuint *img; + GLsizei w, h; + int comps; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + + img = read_texture(fname, &w, &h, &comps); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + floorList = glGenLists(1); + glNewList(floorList, GL_COMPILE); + glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img); + glEndList(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + free(img); + + glClearColor(.25, .25, .5, 1.0); + + realloc_textures(); +} + +void reshape(GLsizei winW, GLsizei winH) +{ + w = winW/2; + + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(-1, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wallMat[] = {1.f, 1.f, 1.f, 1.f}; + + glPushMatrix(); + glScalef(3, 2, 3); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wallMat); + + /* floor, textured */ + glColor3f(1, 1, 1); + glEnable(GL_TEXTURE_2D); + glCallList(floorList); + glBegin(GL_QUADS); + glNormal3f(0, 1, 0); + glTexCoord2f(0, 0); + glVertex3f(-1, -1, 1); + glTexCoord2f(1, 0); + glVertex3f(1, -1, 1); + glTexCoord2f(1, 1); + glVertex3f(1, -1, -1); + glTexCoord2f(0, 1); + glVertex3f(-1, -1, -1); + glEnd(); + glDisable(GL_TEXTURE_2D); + + /* ceiling */ + glColor3f(wallMat[0] * 1., wallMat[1] * 1., wallMat[2] * 1.); + glBegin(GL_QUADS); + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glColor3f(wallMat[0] * .75, wallMat[1] * .75, wallMat[2] * .75); + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, 1, -1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, -1, 1); + + /* right wall */ + glColor3f(wallMat[0] * .25, wallMat[1] * .25, wallMat[2] * .25); + glNormal3f(-1, 0, 0); + glVertex3f(1, -1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, 1, -1); + glVertex3f(1, -1, -1); + + /* far wall */ + glColor3f(wallMat[0] * .5, wallMat[1] * .5, wallMat[2] * .5); + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + /* back wall */ + glColor3f(wallMat[0] * .5, wallMat[1] * .5, wallMat[2] * .5); + glNormal3f(0, 0, -1); + glVertex3f(-1, 1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(-1, -1, 1); + + glEnd(); + + glPopMatrix(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + + /* base is coplanar with floor, so turn off depth testing */ + glDisable(GL_DEPTH_TEST); + gluDisk(base, 0., .3, 20, 1); + glEnable(GL_DEPTH_TEST); + + gluCylinder(cone, .3, 0, 1.25, 20, 1); + + glPopMatrix(); +} + +void draw_cube(void) +{ + glBegin(GL_QUADS); + + glNormal3f(0, -1, 0); + glVertex3f(-.25, -.25, -.25); + glVertex3f(.25, -.25, -.25); + glVertex3f(.25, -.25, .25); + glVertex3f(-.25, -.25, .25); + + glNormal3f(0, 1, 0); + glVertex3f(-.25, .25, .25); + glVertex3f(.25, .25, .25); + glVertex3f(.25, .25, -.25); + glVertex3f(-.25, .25, -.25); + + glNormal3f(1, 0, 0); + glVertex3f(.25, -.25, -.25); + glVertex3f(.25, .25, -.25); + glVertex3f(.25, .25, .25); + glVertex3f(.25, -.25, .25); + + glNormal3f(-1, 0, 0); + glVertex3f(-.25, -.25, .25); + glVertex3f(-.25, .25, .25); + glVertex3f(-.25, .25, -.25); + glVertex3f(-.25, -.25, -.25); + + glNormal3f(0, 0, -1); + glVertex3f(-.25, .25, -.25); + glVertex3f(.25, .25, -.25); + glVertex3f(.25, -.25, -.25); + glVertex3f(-.25, -.25, -.25); + + glNormal3f(0, 0, 1); + glVertex3f(-.25, -.25, .25); + glVertex3f(.25, -.25, .25); + glVertex3f(.25, .25, .25); + glVertex3f(-.25, .25, .25); + + glEnd(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {.2f, .7f, .2f, 1.f}; + + glTexImage2D(GL_TEXTURE_2D, 0, 4, sphereW, sphereW, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if (useSphereMaps) glEnable(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glPushMatrix(); + glRotatef(45, 0, 0, 1); + glRotatef(angle, 0, 1, 0); + glTranslatef(1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + glColor3fv(sphere_mat); +#if 1 + { + GLUquadricObj *sphere = gluNewQuadric(); + gluSphere(sphere, .6, 64, 64); + gluDeleteQuadric(sphere); + } +#else + draw_cube(); +#endif + + glPopMatrix(); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_2D); +} + +void draw_torus(GLdouble angle) +{ + angle = 0; + + glTexImage2D(GL_TEXTURE_2D, 0, 4, sphereW, sphereW, 0, + GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[0]); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if (useSphereMaps) glEnable(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glColor3f(1, .5, .5); + + glPushMatrix(); + glRotatef(angle, 1, 0, 0); + glRotatef(0, 0, 1, 0); + +#if 0 + glutSolidTorus(.2, .25, 32, 32); +#else + { + GLUquadricObj *sphere = gluNewQuadric(); + gluSphere(sphere, .2, 64, 64); + } +#endif + + glPopMatrix(); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_2D); +} + +void draw_scene(GLdouble degrees, GLint bits) +{ + glEnable(GL_CULL_FACE); + draw_room(); + + if (bits & TORUS_BIT) draw_torus(degrees); + if (bits & SPHERE_BIT) draw_sphere(degrees); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw_special_sphere(int tess) +{ + float r = 1.0, r1, r2, z1, z2; + float theta, phi; + int nlon = tess, nlat = tess; + int i, j; + + glBegin(GL_TRIANGLE_FAN); + theta = M_PI*1.0/nlat; + r2 = r*sin(theta); z2 = r*cos(theta); + glNormal3f(0.0, 0.0, 1.0); + glVertex4f(0.0, 0.0, r*r, r); + for (j = 0, phi = 0.0; j <= nlon; j++, phi = 2*M_PI*j/nlon) { + glNormal3f(r2*cos(phi), r2*sin(phi), z2); + glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2); /* top */ + } + glEnd(); + + for (i = 2; i < nlat; i++) { + theta = M_PI*i/nlat; + r1 = r*sin(M_PI*(i-1)/nlat); z1 = r*cos(M_PI*(i-1)/nlat); + r2 = r*sin(theta); z2 = r*cos(theta); + + if (fabs(z1) < 0.01 || fabs(z2) < 0.01) + break; + + glBegin(GL_QUAD_STRIP); + for (j = 0, phi = 0; j <= nlat; j++, phi = 2*M_PI*j/nlon) { + glNormal3f(r1*cos(phi), r1*sin(phi), z1); + glVertex4f(r1*cos(phi)*z1, r1*sin(phi)*z1, z1*z1, z1); + glNormal3f(r2*cos(phi), r2*sin(phi), z2); + glVertex4f(r2*cos(phi)*z2, r2*sin(phi)*z2, z2*z2, z2); + } + glEnd(); + } +} + +void render_spheremap(void) +{ + GLfloat p[4]; + int i; + + glColor4f(1, 1, 1, 1); + +#if 1 + glEnable(GL_TEXTURE_2D); +#endif + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + p[0] = 2.0; p[1] = p[2] = p[3] = 0.0; /* 2zx */ + glTexGenfv(GL_S, GL_OBJECT_PLANE, p); + + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = 0.0; p[1] = 2.0; p[2] = p[3] = 0.0; /* 2zy */ + glTexGenfv(GL_T, GL_OBJECT_PLANE, p); + + glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + p[0] = p[1] = 0.0; p[2] = 0.0; p[3] = 2.0; /* 2z */ + glTexGenfv(GL_R, GL_OBJECT_PLANE, p); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-.98, .98, -.98, .98, 1.0, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 0, 6, + 0, 0, 0, + 0, 1, 0); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +#if 1 + glClearColor(0.25, 0.25, 0.5, 1.0); + glClearDepth(1.0); + glClear(/* GL_COLOR_BUFFER_BIT | */GL_DEPTH_BUFFER_BIT); +#endif + + for (i = 0; i < 6; i++) { + glTexImage2D(GL_TEXTURE_2D, 0, 4, faceW, faceW, 0, + GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)faceMap[i]); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.5, 0.5, 1.0); + glTranslatef(1.0, 1.0, 0.0); + glFrustum(-1.01, 1.01, -1.01, 1.01, 1.0, 100.0); + if (angle2[i]) { + glRotatef(angle2[i], axis2[i][0], axis2[i][1], axis2[i][2]); + } + glRotatef(angle1[i], axis1[i][0], axis1[i][1], axis1[i][2]); + + /* XXX atul does another angle thing here... */ + /* XXX atul does a third angle thing here... */ + + glTranslatef(0.0, 0.0, -1.00); + + glMatrixMode(GL_MODELVIEW); + glClear(GL_DEPTH_BUFFER_BIT); + draw_special_sphere(20); + } + + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + + glDisable(GL_TEXTURE_2D); +} + +void make_projection(int face, GLfloat xpos, GLfloat ypos, GLfloat zpos) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90, 1, .01, 10); + if (angle2[face]) { + glRotatef(angle2[face], axis2[face][0], axis2[face][1], axis2[face][2]); + } + glRotatef(angle1[face], axis1[face][0], axis1[face][1], axis1[face][2]); + gluLookAt(xpos, ypos, zpos, + ypos, ypos, zpos - 1, + 0, 1, 0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw(void) +{ + static int frame = 0; + GLenum err; + GLdouble secs; + static double degrees = 0; + GLfloat sphereX, sphereY, sphereZ; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* one revolution every 10 seconds... */ + if (animate) { + secs = get_secs(); + secs = secs - 10.*trunc(secs / 10.); + degrees = (secs/10.) * (360.); + } + + if (frame == 0) { + /* switch the viewport and draw the faces of the cube from the + * point of view of the square... */ + + glViewport(w + 0*faceW, 0, faceW, faceW); + make_projection(LEFT, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 0*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[LEFT]); + eliminate_alpha(faceW, faceW, faceMap[LEFT]); + + glViewport(w + 1*faceW, 0, faceW, faceW); + make_projection(RIGHT, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 1*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[RIGHT]); + eliminate_alpha(faceW, faceW, faceMap[RIGHT]); + + glViewport(w + 2*faceW, 0, faceW, faceW); + make_projection(BOTTOM, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 2*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BOTTOM]); + eliminate_alpha(faceW, faceW, faceMap[BOTTOM]); + + glViewport(w + 0*faceW, faceW, faceW, faceW); + make_projection(TOP, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 0*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[TOP]); + eliminate_alpha(faceW, faceW, faceMap[TOP]); + + glViewport(w + 1*faceW, faceW, faceW, faceW); + make_projection(FRONT, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 1*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[FRONT]); + eliminate_alpha(faceW, faceW, faceMap[FRONT]); + + glViewport(w + 2*faceW, faceW, faceW, faceW); + make_projection(BACK, 0, 0, 0); + draw_scene(degrees, -1 & ~TORUS_BIT); + glReadPixels(w + 2*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BACK]); + eliminate_alpha(faceW, faceW, faceMap[BACK]); + + /* create the sphere map for the cube... */ + glViewport(w, 2*faceW, sphereW, sphereW); + render_spheremap(); + glReadPixels(w, 2*faceW, sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE, + sphereMap[0]); + } else { + sphereX = + sphereY = cos((degrees/360.) * 2.*M_PI); + sphereZ = -sin((degrees/360.) * 2.*M_PI); + + glViewport(w + 0*faceW, 0, faceW, faceW); + make_projection(LEFT, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 0*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[LEFT]); + eliminate_alpha(faceW, faceW, faceMap[LEFT]); + + glViewport(w + 1*faceW, 0, faceW, faceW); + make_projection(RIGHT, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 1*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[RIGHT]); + eliminate_alpha(faceW, faceW, faceMap[RIGHT]); + + glViewport(w + 2*faceW, 0, faceW, faceW); + make_projection(BOTTOM, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 2*faceW, 0, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BOTTOM]); + eliminate_alpha(faceW, faceW, faceMap[BOTTOM]); + + glViewport(w + 0*faceW, faceW, faceW, faceW); + make_projection(TOP, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 0*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[TOP]); + eliminate_alpha(faceW, faceW, faceMap[TOP]); + + glViewport(w + 1*faceW, faceW, faceW, faceW); + make_projection(FRONT, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 1*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[FRONT]); + eliminate_alpha(faceW, faceW, faceMap[FRONT]); + + glViewport(w + 2*faceW, faceW, faceW, faceW); + make_projection(BACK, sphereX, sphereY, sphereZ); + draw_scene(degrees, -1 & ~SPHERE_BIT); + glReadPixels(w + 2*faceW, faceW, faceW, faceW, + GL_RGBA, GL_UNSIGNED_BYTE, faceMap[BACK]); + eliminate_alpha(faceW, faceW, faceMap[BACK]); + + /* create the sphere map for the cube... */ + glViewport(w + sphereW, 2*faceW, sphereW, sphereW); + render_spheremap(); + glReadPixels(w+sphereW, 2*faceW, sphereW, sphereW, + GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]); + } + frame = (frame == 0); + + /* draw both spheremaps */ + glViewport(w, 2*faceW, 2*sphereW, sphereW); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 2*sphereW, 0, sphereW, 0, 1); + glRasterPos2i(0, 0); + glDrawPixels(sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[0]); + glRasterPos2i(sphereW, 0); + glDrawPixels(sphereW, sphereW, GL_RGBA, GL_UNSIGNED_BYTE, sphereMap[1]); + + + /* draw the scene for the viewer's visual gratification... */ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 0, + 0, 0, -1, + 0, 1, 0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -2.577); + draw_scene(degrees, -1); + glLoadIdentity(); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + switch(key) { + case 'a': case 'A': + animate = (animate == 0); + printf("%sanimating\n", animate ? "" : "not "); + break; + case 'd': case 'D': + printf("drawing\n"); + draw(); + break; + case 'r': case 'R': + printf("resetting sphere maps...\n"); + reset_textures(); + draw(); + break; + case 't': case 'T': + useSphereMaps = (useSphereMaps == 0); + printf("%susing sphere maps\n", useSphereMaps ? "" : "not "); + break; + case 27: + exit(0); + default: + if (idle) { + glutIdleFunc(0); + } else { + glutIdleFunc(draw); + } + idle = (idle == 0); + printf("%sdrawing when idle\n", idle ? "" : "not "); + break; + } +} + +main(int argc, char *argv[]) +{ + glutInitWindowSize(w*2, h); + glutInitWindowPosition(0, 0); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(defaultFile); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/multispheremap.dsp b/lib/glut-3.7.6/progs/advanced97/multispheremap.dsp new file mode 100644 index 0000000000..e12a25484d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/multispheremap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="multispheremap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=multispheremap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multispheremap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multispheremap.mak" CFG="multispheremap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multispheremap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "multispheremap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multispheremap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "multispheremap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multispheremap - Win32 Release" +# Name "multispheremap - Win32 Debug" +# Begin Source File + +SOURCE=.\multispheremap.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/noise.c b/lib/glut-3.7.6/progs/advanced97/noise.c new file mode 100644 index 0000000000..38562429a1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/noise.c @@ -0,0 +1,263 @@ +/* noise.c - by Simon Hui, 3Dfx Interactive */ + +/* create an octave by filtering randomly generated noise */ + +#include +#include +#include +#include + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + + +static GLint texxsize = 256, texysize = 256; +static GLint winxsize = 512, winysize = 512; +static GLint freq = 4; + +/* texture object names */ +static GLuint basistex = 1; +static GLuint noisetex = 2; + +void +init_texture(void) { + int i, j, n; + int w, h; + GLubyte *basis, *tex; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + basis = (GLubyte *) malloc(texxsize * texysize); + w = texxsize / 2; + h = texysize / 2; + for (j=0; j < h; j++) { + for (i=0; i < w; i++) { + GLint r; + float u = i / (w - 1.0); + float v = j / (h - 1.0); + float f = 3 * u * u - 2 * u * u * u; + float g = 3 * v * v - 2 * v * v * v; + + /* basis is a bicubic spline */ + r = f * g * 0xff; + + /* reflect around x and y axes */ + basis[j * texxsize + i] = r; + basis[j * texxsize + texxsize-i-1] = r; + basis[(texysize-j-1) * texxsize + i] = r; + basis[(texysize-j-1) * texxsize + texxsize-i-1] = r; + } + } + glBindTexture(GL_TEXTURE_2D, basistex); + 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, GL_LUMINANCE, texxsize, texysize, 0, + GL_RED, GL_UNSIGNED_BYTE, basis); + free(basis); + + tex = (GLubyte *) malloc(4 * texxsize * texysize); + for (n=0; n < 4; n++) { + for (j=0; j < texysize; j++) { + for (i=0; i < texxsize; i++) { + int r = rand(); + + /* mix it up a little more */ + r = ((r & 0xff) + ((r & 0xff00) >> 8)) & 0xff; + + tex[j*texxsize + i] = r; + } + } + glBindTexture(GL_TEXTURE_2D, noisetex + n); + 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, GL_LUMINANCE, texxsize, texysize, 0, + GL_RED, GL_UNSIGNED_BYTE, tex); + } + free(tex); +} + +void +init(void) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glMatrixMode(GL_PROJECTION); + glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glViewport(0, 0, winxsize, winysize); + glBlendFunc(GL_DST_COLOR, GL_ZERO); + + glEnable(GL_TEXTURE_2D); + init_texture(); +} + +void +draw_basis(int tsize, int ssize, int xadj, int yadj) { + float tilessize = 1.0 / ssize; + float tiletsize = 1.0 / tsize; + float xoff = (xadj - 0.5) * 0.5 * tilessize; + float yoff = (yadj - 0.5) * 0.5 * tiletsize; + float xo, yo; + int i, j; + + glBindTexture(GL_TEXTURE_2D, basistex); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + /* draw as many copies of the basis function as needed for this frequency */ + for (j=0; j < tsize; j++) { + for (i=0; i < ssize; i++) { + xo = xoff + i * tilessize; + yo = yoff + j * tiletsize; + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); glVertex2f(xo, yo); + glTexCoord2f(0.f, 1.f); glVertex2f(xo, yo + tiletsize); + glTexCoord2f(1.f, 0.f); glVertex2f(xo + tilessize, yo); + glTexCoord2f(1.f, 1.f); glVertex2f(xo + tilessize, yo + tiletsize); + glEnd(); + } + } + glFinish(); +} + +void +draw_noise_texture(int tsize, int ssize, int xadj, int yadj, int texname) { + float tilessize = 1.0 / ssize; + float tiletsize = 1.0 / tsize; + float xoff = (xadj - 0.5) * 0.5 * tilessize; + float yoff = (yadj - 0.5) * 0.5 * tiletsize; + float scale = 1.0 / (texxsize / ssize); + + glBindTexture(GL_TEXTURE_2D, texname); + + /* scale the texture matrix to get a noise pattern of desired frequency */ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(scale,scale,scale); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); glVertex2f(xoff, yoff); + glTexCoord2f(0.f, 1.f); glVertex2f(xoff, yoff+1.0); + glTexCoord2f(1.f, 0.f); glVertex2f(xoff + 1.0, yoff); + glTexCoord2f(1.f, 1.f); glVertex2f(xoff + 1.0, yoff + 1.0); + glEnd(); + glFlush(); +} + +/* menu choices */ +enum { + BASIS, NOISE, BASIS_TIMES_NOISE, OCTAVE, HIGHER_FREQ, LOWER_FREQ, QUIT=27 +}; + +GLint showmode = BASIS_TIMES_NOISE; + +void +display(void) { + switch (showmode) { + + case BASIS: + glClear(GL_COLOR_BUFFER_BIT); + draw_basis(freq, freq, 0, 0); + break; + + case NOISE: + glClear(GL_COLOR_BUFFER_BIT); + draw_noise_texture(freq, freq, 0, 0, noisetex); + break; + + case BASIS_TIMES_NOISE: + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(freq, freq, 0, 0); + glEnable(GL_BLEND); + draw_noise_texture(freq, freq, 0, 0, noisetex); + glDisable(GL_BLEND); + break; + + case OCTAVE: + + /* put four sets together to get the final octave */ + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(freq, freq, 0, 0); + glEnable(GL_BLEND); + draw_noise_texture(freq, freq, 0, 0, noisetex); + glAccum(GL_LOAD, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(freq, freq, 1, 0); + glEnable(GL_BLEND); + draw_noise_texture(freq, freq, 1, 0, noisetex + 1); + glAccum(GL_ACCUM, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(freq, freq, 0, 1); + glEnable(GL_BLEND); + draw_noise_texture(freq, freq, 0, 1, noisetex + 2); + glAccum(GL_ACCUM, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(freq, freq, 1, 1); + glEnable(GL_BLEND); + draw_noise_texture(freq, freq, 1, 1, noisetex + 3); + glAccum(GL_ACCUM, 1.0); + + glDisable(GL_BLEND); + glClear(GL_COLOR_BUFFER_BIT); + glAccum(GL_RETURN, 1.0); + break; + } + glFlush(); +} + +void +reshape(int w, int h) { + glViewport(0, 0, w, h); + glutPostRedisplay(); +} + +void +menu(int value) { + switch (value) { + case BASIS: + case NOISE: + case BASIS_TIMES_NOISE: + case OCTAVE: + showmode = value; + break; + case HIGHER_FREQ: + if (freq < texxsize) freq *= 2; + break; + case LOWER_FREQ: + freq /= 2; + if (freq < 2) freq = 2; + break; + case QUIT: + exit(0); + } + glutPostRedisplay(); +} + +int +main(int argc, char** argv) { + glutInitWindowSize(winxsize, winysize); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM); + (void)glutCreateWindow("filtered noise function"); + init(); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutCreateMenu(menu); + glutAddMenuEntry("Show One Basis", BASIS); + glutAddMenuEntry("Show One Noise", NOISE); + glutAddMenuEntry("Show One Basis x Noise", BASIS_TIMES_NOISE); + glutAddMenuEntry("Show Octave", OCTAVE); + glutAddMenuEntry("Higher Frequency", HIGHER_FREQ); + glutAddMenuEntry("Lower Frequency", LOWER_FREQ); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced97/noise.dsp b/lib/glut-3.7.6/progs/advanced97/noise.dsp new file mode 100644 index 0000000000..dd1da5816c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/noise.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="noise" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=noise - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "noise.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "noise.mak" CFG="noise - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "noise - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "noise - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "noise - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "noise - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "noise - Win32 Release" +# Name "noise - Win32 Debug" +# Begin Source File + +SOURCE=.\noise.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.c b/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.c new file mode 100644 index 0000000000..a0ff8a9cca --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.c @@ -0,0 +1,590 @@ +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define TRUE 1 +#define FALSE 0 + +int whichSurface = 0; +int takeSnapshot = 0; + + +int winWidth, winHeight; +GLfloat *depthSave = NULL; +GLubyte *stencilSave = NULL; +GLubyte *colorSave = NULL; + + +void resizeBuffers(void) +{ + colorSave = realloc(colorSave, winWidth * winHeight * 4 * sizeof(GLubyte)); + depthSave = realloc(depthSave, winWidth * winHeight * 4 * sizeof(GLfloat)); + stencilSave = (GLubyte *)depthSave; +} + + +void pushOrthoView(float left, float right, float bottom, float top, + float znear, float zfar) +{ + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(left, right, bottom, top, znear, zfar); +} + + +void popView(void) +{ + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + + +void copyDepthToColor(GLenum whichColorBuffer) +{ + int x, y; + GLfloat max, min; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, + depthSave); + + /* I'm sure this could be done much better with OpenGL */ + max = 0; + min = 1; + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] < min) + min = depthSave[winWidth * y + x]; + if(depthSave[winWidth * y + x] > max && depthSave[winWidth * y + x] < .999) + max = depthSave[winWidth * y + x]; + } + + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + if(depthSave[winWidth * y + x] <= max) + depthSave[winWidth * y + x] = 1 - (depthSave[winWidth * y + x] - min) / (max - min); + else + depthSave[winWidth * y + x] = 0; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_LUMINANCE , GL_FLOAT, depthSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +unsigned char colors[][3] = +{ + {255, 0, 0}, /* red */ + {255, 218, 0}, /* yellow */ + {72, 255, 0}, /* yellowish green */ + {0, 255, 145}, /* bluish cyan */ + {0, 145, 255}, /* cyanish blue */ + {72, 0, 255}, /* purplish blue */ + {255, 0, 218}, /* reddish purple */ +}; + + +void copyStencilToColor(GLenum whichColorBuffer) +{ + int x, y; + GLint previousColorBuffer; + + glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, + stencilSave); + + /* I'm sure this could be done much better with OpenGL */ + for(y = 0; y < winHeight; y++) + for(x = 0; x < winWidth; x++) { + int stencilValue; + + stencilValue = stencilSave[winWidth * y + x]; + + colorSave[(winWidth * y + x) * 3 + 0] = colors[stencilValue % 7][0]; + colorSave[(winWidth * y + x) * 3 + 1] = colors[stencilValue % 7][1]; + colorSave[(winWidth * y + x) * 3 + 2] = colors[stencilValue % 7][2]; + } + + pushOrthoView(0, 1, 0, 1, 0, 1); + glRasterPos3f(0, 0, -.5); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer); + glDrawBuffer(whichColorBuffer); + glDrawPixels(winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, colorSave); + glDrawBuffer(previousColorBuffer); + glEnable(GL_DEPTH_TEST); + popView(); +} + + +#if 0 + +GLushort rrow[1280], grow[1280], brow[1280], arow[1280]; + + +#define iopen junk +#include +#undef iopen + + +IMAGE *iopen(char *file, char *mode, ...); +int putrow(IMAGE *image, unsigned short *buff, int y, int z); +int iclose(IMAGE *); + + +void saveSGIImage(char *name, int doAlphaToo) +{ + IMAGE *img; + FILE *fp; + GLubyte *pixels; + int x, y; + int numComp = doAlphaToo ? 4 : 3; + + pixels = malloc(winWidth * winHeight * numComp * sizeof(GLubyte)); + + glReadPixels(0, 0, winWidth, winHeight, doAlphaToo ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, pixels); + + img = iopen(name, "w", RLE(1), numComp, winWidth, winHeight, numComp); + + for(y = 0; y < winHeight; y++) { + for(x = 0; x < winWidth; x++) { + rrow[x] = pixels[(y * winWidth + x) * numComp + 0]; + grow[x] = pixels[(y * winWidth + x) * numComp + 1]; + brow[x] = pixels[(y * winWidth + x) * numComp + 2]; + if(doAlphaToo) + arow[x] = pixels[(y * winWidth + x) * numComp + 3]; + } + putrow(img, rrow, y, 0); + putrow(img, grow, y, 1); + putrow(img, brow, y, 2); + if(doAlphaToo) + putrow(img, arow, y, 3); + } + iclose(img); + + free(pixels); +} + +#endif + + +struct transformation { + float translation[3]; + float rotation[4]; + float scale[3]; +}; + + +void drawXform(struct transformation *xform, int applyScale) +{ + glTranslatef(xform->translation[0], xform->translation[1], xform->translation[2]); + glRotatef(xform->rotation[3] / M_PI * 180, xform->rotation[0], xform->rotation[1], xform->rotation[2]); + if(applyScale) + glScalef(xform->scale[0], xform->scale[1], xform->scale[2]); +} + + +enum trackballModeEnum { + ROTATE, + TRANSLATEXY, + TRANSLATEZ, + SCALEX, + SCALEY, + SCALEZ +} trackballMode = ROTATE; + + +struct transformation xform = +{ + 0, 0, 0, + -0.65, -0.75, -0.04, 0.89, + .7, .7, 2, +}; + + +void axisamountToMat(float aa[], float mat[]) +{ + float c, s, t; + + c = (float)cos(aa[3]); + s = (float)sin(aa[3]); + t = 1.0f - c; + + mat[0] = t * aa[0] * aa[0] + c; + mat[1] = t * aa[0] * aa[1] + s * aa[2]; + mat[2] = t * aa[0] * aa[2] - s * aa[1]; + mat[3] = t * aa[0] * aa[1] - s * aa[2]; + mat[4] = t * aa[1] * aa[1] + c; + mat[5] = t * aa[1] * aa[2] + s * aa[0]; + mat[6] = t * aa[0] * aa[2] + s * aa[1]; + mat[7] = t * aa[1] * aa[2] - s * aa[0]; + mat[8] = t * aa[2] * aa[2] + c; +} + + +void matToAxisamount(float mat[], float aa[]) +{ + float c; + float s; + + c = (mat[0] + mat[4] + mat[8] - 1.0f) / 2.0f; + aa[3] = (float)acos(c); + s = (float)sin(aa[3]); + if(fabs(s / M_PI - (int)(s / M_PI)) < .0000001) + { + aa[0] = 0.0f; + aa[1] = 1.0f; + aa[2] = 0.0f; + } + else + { + aa[0] = (mat[5] - mat[7]) / (2.0f * s); + aa[1] = (mat[6] - mat[2]) / (2.0f * s); + aa[2] = (mat[1] - mat[3]) / (2.0f * s); + } +} + + +void multMat(float m1[], float m2[], float r[]) +{ + float t[9]; + int i; + + t[0] = m1[0] * m2[0] + m1[1] * m2[3] + m1[2] * m2[6]; + t[1] = m1[0] * m2[1] + m1[1] * m2[4] + m1[2] * m2[7]; + t[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2] * m2[8]; + t[3] = m1[3] * m2[0] + m1[4] * m2[3] + m1[5] * m2[6]; + t[4] = m1[3] * m2[1] + m1[4] * m2[4] + m1[5] * m2[7]; + t[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5] * m2[8]; + t[6] = m1[6] * m2[0] + m1[7] * m2[3] + m1[8] * m2[6]; + t[7] = m1[6] * m2[1] + m1[7] * m2[4] + m1[8] * m2[7]; + t[8] = m1[6] * m2[2] + m1[7] * m2[5] + m1[8] * m2[8]; + for(i = 0; i < 9; i++) + { + r[i] = t[i]; + } +} + + +void rotateTrackball(int dx, int dy, float rotation[4]) +{ + float dist; + float oldMat[9]; + float rotMat[9]; + float newRot[4]; + + dist = (float)sqrt((double)(dx * dx + dy * dy)); + if(fabs(dist) < 0.99) + return; + + newRot[0] = (float) dy / dist; + newRot[1] = (float) dx / dist; + newRot[2] = 0.0f; + newRot[3] = (float)M_PI * dist / winWidth; + + axisamountToMat(rotation, oldMat); + axisamountToMat(newRot, rotMat); + multMat(oldMat, rotMat, oldMat); + matToAxisamount(oldMat, rotation); + + dist = (float)sqrt(rotation[0] * rotation[0] + rotation[1] * rotation[1] + + rotation[2] * rotation[2]); + + rotation[0] /= dist; + rotation[1] /= dist; + rotation[2] /= dist; +} + + +int stage = 6; +typedef enum {COLOR, DEPTH, STENCIL} BufferInterest; + +BufferInterest bufferInterest = COLOR; + + +void init(void) +{ + GLfloat defaultMat[] = {.75, .25, .25, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glMatrixMode(GL_PROJECTION); + glFrustum(-.33, .33, -.33, .33, .5, 40); + + glMatrixMode(GL_MODELVIEW); + gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); */ + + glEnable(GL_NORMALIZE); + + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_INCR, GL_INCR, GL_INCR); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, defaultMat); + + glLineWidth(3); + glShadeModel(GL_FLAT); +} + + +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glPushMatrix(); + + drawXform(&xform, TRUE); + + glEnable(GL_STENCIL_TEST); + if(whichSurface < 2) + glStencilFunc(GL_EQUAL, whichSurface, 0xff); + else + glStencilFunc(GL_ALWAYS, 0, 0); + + glutSolidTorus(2, 4, 20, 20); + + /* glDisable(GL_STENCIL_TEST); */ + /* glDisable(GL_LIGHTING); */ + /* glColor3f(1, 1, 1); */ + /* glutWireTorus(2, 4, 20, 20); */ + /* glEnable(GL_LIGHTING); */ + + glPopMatrix(); + + switch(bufferInterest) { + case COLOR: + break; /* color already in back buffer */ + + case STENCIL: + copyStencilToColor(GL_BACK); + break; + + case DEPTH: + copyDepthToColor(GL_BACK); + break; + } + + if(takeSnapshot) { + takeSnapshot = 0; + /* saveSGIImage("snap.rgb", FALSE); */ + /* printf("Saved RGBA image in snap.rgba\n"); */ + } + + glutSwapBuffers(); +} + + +void reshape(int width, int height) +{ + glViewport(0, 0, width, height); + winWidth = width; + winHeight = height; + resizeBuffers(); + glutPostRedisplay(); +} + + +void changeData(int data) +{ + char *s; + + bufferInterest = (BufferInterest) data; + glutPostRedisplay(); + + switch(data) { + case COLOR: + s = "color"; + break; + + case STENCIL: + s = "stencil"; + break; + + case DEPTH: + s = "depth"; + break; + } + printf("Now displaying %s data\n", s); +} + + +int mainMenu; + + +/* ARGSUSED1 */ +void keyboard(unsigned char key, int x, int y) +{ + switch(key) + { + case '1': + case '2': + case '3': + whichSurface = key - '1'; + glutPostRedisplay(); + break; + + case 'r': + trackballMode = ROTATE; + break; + + case 't': + trackballMode = TRANSLATEXY; + break; + + case 'T': + trackballMode = TRANSLATEZ; + break; + + case 'x': + trackballMode = SCALEX; + break; + + case 'y': + trackballMode = SCALEY; + break; + + case 'z': + trackballMode = SCALEZ; + break; + + case 'q': case 'Q': case '\033': + exit(0); + break; + + case '+': case '=': + stage++; + glutPostRedisplay(); + break; + + case '-': case '_': + stage--; + glutPostRedisplay(); + break; + + case 's': + printf("%f %f %f %f\n", xform.rotation[0], xform.rotation[1], + xform.rotation[2], xform.rotation[3]); + glutPostRedisplay(); + break; + } +} + + +static int ox, oy; + + +/* ARGSUSED */ +void button(int b, int state, int x, int y) +{ + ox = x; + oy = y; +} + + +void motion(int x, int y) +{ + int dx, dy; + + dx = x - ox; + dy = y - oy; + + ox = x; + oy = y; + + switch(trackballMode) { + case ROTATE: + rotateTrackball(dx, dy, xform.rotation); + break; + + case SCALEX: + xform.scale[0] += (dx + dy) / 20.0f; + break; + + case SCALEY: + xform.scale[1] += (dx + dy) / 20.0f; + break; + + case SCALEZ: + xform.scale[2] += (dx + dy) / 20.0f; + break; + + case TRANSLATEXY: + xform.translation[0] += dx / 20.0f; + xform.translation[1] -= dy / 20.0f; + break; + + case TRANSLATEZ: + xform.translation[2] += (dx + dy) / 20.0f; + break; + } + glutPostRedisplay(); +} + +/* ARGSUSED */ +void mainMenuFunc(int menu) +{ + /* */ +} + + +int main(int argc, char **argv) +{ + int bufferMenu; + int stenSize; + + glutInit(&argc, argv); + glutInitWindowSize(winWidth = 256, winHeight = 256); + glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_DEPTH|GLUT_ALPHA); + (void)glutCreateWindow("torus depth"); + glutDisplayFunc(redraw); + glutKeyboardFunc(keyboard); + glutMotionFunc(motion); + glutMouseFunc(button); + glutReshapeFunc(reshape); + + resizeBuffers(); + glGetIntegerv(GL_STENCIL_BITS, &stenSize); + fprintf(stderr, "(%d bits of stencil available in this visual)\n", stenSize); + + fprintf(stderr, "Hit 'h' for help message\n"); + + bufferMenu = glutCreateMenu(changeData); + glutAddMenuEntry("Color data", COLOR); + glutAddMenuEntry("Stencil data", STENCIL); + glutAddMenuEntry("Depth data", DEPTH); + + mainMenu = glutCreateMenu(mainMenuFunc); + glutAddSubMenu("Visible buffer", bufferMenu); + glutAttachMenu(GLUT_RIGHT_BUTTON); + init(); + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.dsp b/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.dsp new file mode 100644 index 0000000000..3d444ee6c1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/nthsurfdemo.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="nthsurfdemo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=nthsurfdemo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "nthsurfdemo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "nthsurfdemo.mak" CFG="nthsurfdemo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "nthsurfdemo - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "nthsurfdemo - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "nthsurfdemo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "nthsurfdemo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "nthsurfdemo - Win32 Release" +# Name "nthsurfdemo - Win32 Debug" +# Begin Source File + +SOURCE=.\nthsurfdemo.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/paint.c b/lib/glut-3.7.6/progs/advanced97/paint.c new file mode 100644 index 0000000000..3595cdfccd --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/paint.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +#define RW 0.3086 +#define GW 0.6094 +#define BW 0.0820 + +static char defaultFile0[] = "../data/mandrill.rgb"; +static char defaultFile1[] = "../data/sgi.bw"; +static char defaultBrushFile[] = "../data/brush.rgb"; +GLuint *img0, *img1, *brush; +GLsizei w0, w1, wbrush, h0, h1, hbrush; +GLsizei w, h; + +GLint comp; + +void init(void) +{ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +} + +GLuint *load_img(const char *fname, GLsizei *imgW, GLsizei *imgH) +{ + GLuint *img; + + img = read_texture(fname, imgW, imgH, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + return img; +} + +GLuint * +resize_img(GLuint *img, GLsizei curW, GLsizei curH) +{ + /* save & set buffer settings */ + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT); + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + + glPixelZoom((float)w / (float)curW, (float)h / (float)curH); + glRasterPos2i(0, 0); + glDrawPixels(curW, curH, GL_RGBA, GL_UNSIGNED_BYTE, img); + free(img); + img = (GLuint *)malloc(w * h * sizeof(GLuint)); + if (!img) { + fprintf(stderr, "Malloc of %d bytes failed.\n", + curW * curH * sizeof(GLuint)); + exit(1); + } + glPixelZoom(1, 1); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img); + + glPopAttrib(); + + return img; +} + +GLuint * +convert_to_luminance(GLuint *img, GLsizei w, GLsizei h) +{ + GLubyte *newImg, *src, *dst; + GLfloat val; + int i; + + newImg = (GLubyte *)malloc(w * h); + if (!newImg) { + fprintf(stderr, "malloc of %d bytes failed\n", w*h); + exit(1); + } + + src = (GLubyte *)img; + dst = newImg; + for (i = 0; i < w*h; i++) { + val = ((float)(*src++) * RW + + (float)(*src++) * GW + + (float)(*src++) * BW); + src++; + if (val > 255) val = 255; + *dst++ = val; + } + free(img); + + /* casting a ubyte ptr to a uint pointer is sloppy since it can + * lead to alignment errors, but since the pointer came from + * malloc we know it's legal in this case... */ + return (GLuint *)newImg; +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, w, h); + glLoadIdentity(); + glOrtho(0, winW, 0, winH, 0, 5); +} + +void draw(void) +{ + static int first = 1; + GLenum err; + + if (first) { + printf("Scaling images to %d by %d\n", w, h); + + if (w0 != w || h0 != h) { + img0 = resize_img(img0, w0, h0); + + } + if (w1 != w || h1 != h) { + img1 = resize_img(img1, w1, h1); + } + + first = 0; + } + + glClear(GL_COLOR_BUFFER_BIT); + glRasterPos2i(0, 0); + glDrawBuffer(GL_BACK); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img1); + glDrawBuffer(GL_FRONT); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); +} + +int lastX, lastY, curX, curY; + +int get_msecs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void idle(void) +{ + int x = curX - (wbrush/2); + int y = h - (curY + (hbrush/2)); + int msecs; + static int last_msecs = -1; + + /* do not do this more than 60 times a second. Otherwise it's + * to fast for use on high-end systems */ + msecs = get_msecs(); + if (fabs(last_msecs - msecs) < 1000./60.) { + return; + } + last_msecs = msecs; + + /* we draw the brush using a drawpixels command. on systems with + * hardware-accelerated texture mapping it would be better to use + * that. + * + * we use the bitmap hack to set the rasterpos because we don't + * know that the position will be within the window. + */ + glRasterPos2i(0, 0); + glBitmap(0, 0, 0, 0, x, y, 0); + glColorMask(0, 0, 0, 1); + glDrawBuffer(GL_BACK); + glDrawPixels(wbrush, hbrush, GL_ALPHA, GL_UNSIGNED_BYTE, brush); + glColorMask(1, 1, 1, 1); + + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glCopyPixels(x, y, wbrush, hbrush, GL_COLOR); + glDisable(GL_BLEND); + + glColorMask(1, 1, 1, 1); +} + +void motion(int xpos, int ypos) +{ + curX = xpos; + curY = ypos; +} + +/* ARGSUSED */ +void button(int button, int state, int xpos, int ypos) +{ + if (state == GLUT_DOWN) { + glutIdleFunc(idle); + lastX = lastY = -1; + curX = xpos; + curY = ypos; + return; + } else { + glutIdleFunc(0); + } +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if (key == 27) exit(0); +} + +void +show_usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "paint [imagefile0] [imagefile1] [brush]\n"); +} + +main(int argc, char *argv[]) +{ + const char *fileName0 = defaultFile0, *fileName1 = defaultFile1, + *brushName = defaultBrushFile; + + glutInit(&argc, argv); + if (argc > 1) { + fileName0 = argv[1]; + } + if (argc > 2) { + fileName1 = argv[2]; + } + if (argc > 3) { + brushName = argv[3]; + } + if (argc > 4) { + show_usage(); + exit(1); + } + printf("Image file 1 is %s\n", fileName0); + printf("Image file 2 is %s\n", fileName1); + printf("Brush file is %s\n", brushName); + + img0 = load_img(fileName0, &w0, &h0); + img1 = load_img(fileName1, &w1, &h1); + brush = load_img(brushName, &wbrush, &hbrush); + brush = convert_to_luminance(brush, wbrush, hbrush); + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + w = MAX(w0, w1); + h = MAX(h0, h1); + + glutInitWindowSize(w, h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(button); + glutMotionFunc(motion); + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/paint.dsp b/lib/glut-3.7.6/progs/advanced97/paint.dsp new file mode 100644 index 0000000000..adc57ccbc2 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/paint.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="paint" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=paint - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "paint.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "paint.mak" CFG="paint - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "paint - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "paint - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "paint - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "paint - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "paint - Win32 Release" +# Name "paint - Win32 Debug" +# Begin Source File + +SOURCE=.\paint.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/projtex.c b/lib/glut-3.7.6/progs/advanced97/projtex.c new file mode 100644 index 0000000000..9fd8f2ea11 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/projtex.c @@ -0,0 +1,837 @@ +/* +** Demonstrates simple projective texture mapping. +** +** Button1 changes view, Button2 moves texture. +** +** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli +** "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92) +** +** 1994,1995 -- David G Yu +** +** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm +*/ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +int winWidth, winHeight; + +GLboolean redrawContinuously; + +float angle, axis[3]; +enum MoveModes { MoveNone, MoveView, MoveObject, MoveTexture }; +enum MoveModes mode = MoveNone; + +GLfloat objectXform[4][4]; +GLfloat textureXform[4][4]; + +void (*drawObject)(void); +void (*loadTexture)(void); +GLboolean textureEnabled = GL_TRUE; +GLboolean showProjection = GL_TRUE; +GLboolean linearFilter = GL_TRUE; + +char *texFilename = NULL; + +GLfloat zoomFactor = 1.0; + +/*****************************************************************/ + +/* matrix = identity */ +void +matrixIdentity(GLfloat matrix[16]) +{ + matrix[ 0] = 1.0; + matrix[ 1] = 0.0; + matrix[ 2] = 0.0; + matrix[ 3] = 0.0; + matrix[ 4] = 0.0; + matrix[ 5] = 1.0; + matrix[ 6] = 0.0; + matrix[ 7] = 0.0; + matrix[ 8] = 0.0; + matrix[ 9] = 0.0; + matrix[10] = 1.0; + matrix[11] = 0.0; + matrix[12] = 0.0; + matrix[13] = 0.0; + matrix[14] = 0.0; + matrix[15] = 1.0; +} + +/* matrix2 = transpose(matrix1) */ +void +matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16]) +{ + matrix2[ 0] = matrix1[ 0]; + matrix2[ 1] = matrix1[ 4]; + matrix2[ 2] = matrix1[ 8]; + matrix2[ 3] = matrix1[12]; + + matrix2[ 4] = matrix1[ 1]; + matrix2[ 5] = matrix1[ 5]; + matrix2[ 6] = matrix1[ 9]; + matrix2[ 7] = matrix1[13]; + + matrix2[ 8] = matrix1[ 2]; + matrix2[ 9] = matrix1[ 6]; + matrix2[10] = matrix1[10]; + matrix2[11] = matrix1[14]; + + matrix2[12] = matrix1[ 3]; + matrix2[13] = matrix1[ 7]; + matrix2[14] = matrix1[14]; + matrix2[15] = matrix1[15]; +} + +/*****************************************************************/ + +/* load SGI .rgb image (pad with a border of the specified width and color) */ +static void +imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], + int *wOut, int *hOut, GLubyte **imgOut) +{ + int border = borderIn; + int width, height; + int w, h; + GLubyte *image, *img, *p; + int i, j, components; + + image = (GLubyte *)read_texture(filenameIn, &width, &height, &components); + w = width + 2*border; + h = height + 2*border; + img = (GLubyte *) calloc(w*h, 4*sizeof(unsigned char)); + + p = img; + for (j=-border; j 1.0) { + glDisable(GL_DEPTH_TEST); + glCopyPixels(0, 0, winWidth/zoomFactor, winHeight/zoomFactor, GL_COLOR); + glEnable(GL_DEPTH_TEST); + } + glFlush(); + glutSwapBuffers(); + checkErrors(); +} + +/*****************************************************************/ + +/* simple trackball-like motion control */ +GLboolean trackingMotion = GL_FALSE; +float lastPos[3]; +int lastTime; + +void +ptov(int x, int y, int width, int height, float v[3]) +{ + float d, a; + + /* project x,y onto a hemi-sphere centered within width, height */ + v[0] = (2.0*x - width) / width; + v[1] = (height - 2.0*y) / height; + d = sqrt(v[0]*v[0] + v[1]*v[1]); + v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0)); + a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + v[0] *= a; + v[1] *= a; + v[2] *= a; +} + +void +startMotion(int x, int y, int but, int time) +{ + if (but == GLUT_LEFT_BUTTON) { + mode = MoveView; + } else if (but == GLUT_RIGHT_BUTTON) { + mode = MoveTexture; + } else { + return; + } + + trackingMotion = GL_TRUE; + redrawContinuously = GL_FALSE; + lastTime = time; + ptov(x, y, winWidth, winHeight, lastPos); +} + +/*ARGSUSED*/ +void +stopMotion(int x, int y, int but, int time) +{ + if ((but == GLUT_LEFT_BUTTON && mode == MoveView) || + (but == GLUT_RIGHT_BUTTON && mode == MoveTexture)) + { + trackingMotion = GL_FALSE; + } else { + return; + } + + if (time == lastTime) { + redrawContinuously = GL_TRUE; + glutIdleFunc(display); + } else { + angle = 0.0; + redrawContinuously = GL_FALSE; + glutIdleFunc(0); + } + if (!redrawContinuously) { + mode = MoveNone; + } +} + +void +trackMotion(int x, int y) +{ + if (trackingMotion) { + float curPos[3], dx, dy, dz; + + ptov(x, y, winWidth, winHeight, curPos); + + dx = curPos[0] - lastPos[0]; + dy = curPos[1] - lastPos[1]; + dz = curPos[2] - lastPos[2]; + angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz); + + axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1]; + axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2]; + axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0]; + + lastTime = glutGet(GLUT_ELAPSED_TIME); + lastPos[0] = curPos[0]; + lastPos[1] = curPos[1]; + lastPos[2] = curPos[2]; + glutPostRedisplay(); + } +} + +/*****************************************************************/ + +void +object(void) +{ + static int object; + object++; object %= 3; + switch (object) { + case 0: + drawObject = drawCube; + break; + case 1: + drawObject = drawDodecahedron; + break; + case 2: + drawObject = drawSphere; + break; + default: + break; + } +} + +void +texture(void) +{ + static int texture; + + texture++; texture %= 3; + switch (texture) { + case 0: + loadTexture = NULL; + textureEnabled = GL_FALSE; + break; + case 1: + loadTexture = loadImageTexture; + (*loadTexture)(); + textureEnabled = GL_TRUE; + break; + case 2: + loadTexture = loadSpotlightTexture; + (*loadTexture)(); + textureEnabled = GL_TRUE; + break; + default: + break; + } +} + +void help(void) { + printf("'h' - help\n"); + printf("'l' - toggle linear/nearest filter\n"); + printf("'s' - toggle projection frustum\n"); + printf("'t' - toggle projected texture\n"); + printf("'o' - toggle object\n"); + printf("'z' - increase zoom factor\n"); + printf("'Z' - decrease zoom factor\n"); + printf("left mouse - move view\n"); + printf("right mouse - move projection\n"); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case '\033': + exit(EXIT_SUCCESS); + break; + case 'l': + linearFilter = !linearFilter; + (*loadTexture)(); + break; + case 's': + showProjection = !showProjection; + break; + case 't': + texture(); + break; + case 'o': + object(); + break; + case 'z': + zoomFactor += 1.0; + glPixelZoom(zoomFactor, zoomFactor); + glViewport(0, 0, winWidth/zoomFactor, winHeight/zoomFactor); + break; + case 'Z': + zoomFactor -= 1.0; + if (zoomFactor < 1.0) zoomFactor = 1.0; + glPixelZoom(zoomFactor, zoomFactor); + glViewport(0, 0, winWidth/zoomFactor, winHeight/zoomFactor); + break; + case 'h': help(); break; + } + glutPostRedisplay(); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) + startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP) + stopMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + glutPostRedisplay(); +} + +void +reshape(int w, int h) +{ + winWidth = w; + winHeight = h; + glViewport(0, 0, w/zoomFactor, h/zoomFactor); +} + +void +usage(char **argv) +{ + fprintf(stderr, "usage: %s \n", argv[0]); + fprintf(stderr, "\n"); +} + +int +main(int argc, char **argv) +{ + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); + (void)glutCreateWindow("projtex"); + if (argc > 1) { + texFilename = argv[argc-1]; + } else { + texFilename = "../data/fendi.rgb"; + } + loadTexture = loadImageTexture; + drawObject = drawCube; + initialize(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(trackMotion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/projtex.dsp b/lib/glut-3.7.6/progs/advanced97/projtex.dsp new file mode 100644 index 0000000000..ed88e0922f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/projtex.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="projtex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=projtex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "projtex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "projtex.mak" CFG="projtex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "projtex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "projtex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "projtex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "projtex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "projtex - Win32 Release" +# Name "projtex - Win32 Debug" +# Begin Source File + +SOURCE=.\projtex.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/sbias.c b/lib/glut-3.7.6/progs/advanced97/sbias.c new file mode 100644 index 0000000000..e0e1fe7a76 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/sbias.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +static char defaultFile[] = "../data/mandrill.rgb"; +GLuint *img; +GLsizei w, h; +GLint comp; + +GLfloat scale[] = {1, 1, 1}, bias[] = {0, 0, 0}; +GLboolean changeScale = 1, changeBias = 1; +GLboolean changeR = 1, changeG = 1, changeB = 1; + +void init(void) +{ + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_BACK); +} + +void load_img(const char *fname) +{ + img = read_texture(fname, &w, &h, &comp); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } +} + +void reshape(GLsizei winW, GLsizei winH) +{ + glViewport(0, 0, w, h); + glLoadIdentity(); + glOrtho(0, winW, 0, winH, 0, 5); +} + +void draw(void) +{ + GLenum err; + + glPixelTransferf(GL_RED_SCALE, 1); + glPixelTransferf(GL_GREEN_SCALE, 1); + glPixelTransferf(GL_BLUE_SCALE, 1); + glPixelTransferf(GL_RED_BIAS, 0); + glPixelTransferf(GL_GREEN_BIAS, 0); + glPixelTransferf(GL_BLUE_BIAS, 0); + + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_BACK); + glRasterPos2i(0, 0); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img); + + + glPixelTransferf(GL_RED_SCALE, scale[0]); + glPixelTransferf(GL_GREEN_SCALE, scale[1]); + glPixelTransferf(GL_BLUE_SCALE, scale[2]); + glPixelTransferf(GL_RED_BIAS, bias[0]); + glPixelTransferf(GL_GREEN_BIAS, bias[1]); + glPixelTransferf(GL_BLUE_BIAS, bias[2]); + glDrawBuffer(GL_FRONT); + glCopyPixels(0, 0, w, h, GL_COLOR); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + char change[][30] = {"Not changing", "Changing"}; + + switch(key) { + case 27: + exit(0); + case 's': case 'S': + changeScale = (changeScale == 0); + printf("%s scale\n", change[changeScale]); + break; + case 'i': case 'I': + changeBias = (changeBias == 0); + printf("%s bias\n", change[changeBias]); + break; + case 'r': case 'R': + changeR = (changeR == 0); + printf("%s red channel\n", change[changeR]); + break; + case 'g': case 'G': + changeG = (changeG == 0); + printf("%s green channel\n", change[changeG]); + break; + case 'b': case 'B': + changeB = (changeB == 0); + printf("%s blue channel\n", change[changeB]); + break; + case ' ': + changeScale = changeBias = changeR = changeG = changeB = 1; + scale[0] = scale[1] = scale[2] = 1; + bias[0] = bias[1] = bias[2] = 0; + printf("Resetting all\n"); + draw(); + break; + case '?': + printf("Scale:\n"); + printf("\tR: %f\n", scale[0]); + printf("\tG: %f\n", scale[1]); + printf("\tB: %f\n", scale[2]); + printf("Bias:\n"); + printf("\tR: %f\n", bias[0]); + printf("\tG: %f\n", bias[1]); + printf("\tB: %f\n\n", bias[2]); + } +} + +int lastX, lastY, curX, curY; + +void idle(void) +{ + float dScale, dBias; + + if (lastX != curX || lastY != curY) { + if (changeScale) { + dScale = (curX - lastX) / (float)w; + if (changeR) scale[0] += dScale; + if (changeG) scale[1] += dScale; + if (changeB) scale[2] += dScale; + } + if (changeBias) { + dBias = (curY - lastY) / (float)h; + if (changeR) bias[0] += dBias; + if (changeG) bias[1] += dBias; + if (changeB) bias[2] += dBias; + } + + glPixelTransferf(GL_RED_SCALE, scale[0]); + glPixelTransferf(GL_GREEN_SCALE, scale[1]); + glPixelTransferf(GL_BLUE_SCALE, scale[2]); + glPixelTransferf(GL_RED_BIAS, bias[0]); + glPixelTransferf(GL_GREEN_BIAS, bias[1]); + glPixelTransferf(GL_BLUE_BIAS, bias[2]); + + glRasterPos2i(0, 0); + glCopyPixels(0, 0, w, h, GL_COLOR); + + lastX = curX; + lastY = curY; + } +} + +void motion(int xpos, int ypos) +{ + curX = xpos; + curY = (h - ypos); +} + +/* ARGSUSED */ +void button(int button, int state, int xpos, int ypos) +{ + if (state == GLUT_DOWN) { + glutIdleFunc(idle); + curX = lastX = xpos; + curY = lastY = (h - ypos); + return; + } else { + glutIdleFunc(0); + } +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + if (argc > 1) { + load_img(argv[1]); + } else { + load_img(defaultFile); + } + glutInitWindowSize(w, h); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutMouseFunc(button); + glutMotionFunc(motion); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/sbias.dsp b/lib/glut-3.7.6/progs/advanced97/sbias.dsp new file mode 100644 index 0000000000..4b82758a23 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/sbias.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="sbias" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sbias - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sbias.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sbias.mak" CFG="sbias - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sbias - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sbias - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sbias - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sbias - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sbias - Win32 Release" +# Name "sbias - Win32 Debug" +# Begin Source File + +SOURCE=.\sbias.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/screendoor.c b/lib/glut-3.7.6/progs/advanced97/screendoor.c new file mode 100644 index 0000000000..64575d53af --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/screendoor.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +#ifdef _WIN32 +#define random() ((long)rand() + (rand() << 15) + (rand() << 30)) +#endif + +GLUquadricObj *cone, *base, *qsphere; + +void create_stipple_pattern(GLuint *pat, GLfloat opacity) +{ + int x, y; + long threshold = (float)0x7fffffff * (1. - opacity); + + for (y = 0; y < 32; y++) { + pat[y] = 0; + for (x = 0; x < 32; x++) { + if (random() > threshold) pat[y] |= (1 << x); + } + } +} + +void init(void) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + GLuint spherePattern[32]; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + cone = gluNewQuadric(); + base = gluNewQuadric(); + qsphere = gluNewQuadric(); + gluQuadricOrientation(base, GLU_INSIDE); + + create_stipple_pattern(spherePattern, .5); + glPolygonStipple((GLubyte *)spherePattern); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 2.577, 0, 0, -5, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, -1, 1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, 1, -1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); +} + +void draw_cone(void) +{ + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -1, 0); + glRotatef(-90, 1, 0, 0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluCylinder(cone, .3, 0, 1.25, 20, 1); + gluDisk(base, 0., .3, 20, 1); + + glPopMatrix(); +} + +void draw_sphere(GLdouble angle) +{ + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + + glPushMatrix(); + glTranslatef(0, -.3, 0); + glRotatef(angle, 0, 1, 0); + glTranslatef(0, 0, .6); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(qsphere, .3, 20, 20); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_room(); + draw_cone(); + secs = get_secs(); + + /* draw the transparent object... */ + glEnable(GL_POLYGON_STIPPLE); + draw_sphere(secs * 360. / 10.); + glDisable(GL_POLYGON_STIPPLE); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + if (key == 27) exit(0); +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/screendoor.dsp b/lib/glut-3.7.6/progs/advanced97/screendoor.dsp new file mode 100644 index 0000000000..ef9450d917 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/screendoor.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="screendoor" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=screendoor - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "screendoor.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "screendoor.mak" CFG="screendoor - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "screendoor - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "screendoor - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "screendoor - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "screendoor - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "screendoor - Win32 Release" +# Name "screendoor - Win32 Debug" +# Begin Source File + +SOURCE=.\screendoor.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/sm.c b/lib/glut-3.7.6/progs/advanced97/sm.c new file mode 100644 index 0000000000..7f214a60b7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/sm.c @@ -0,0 +1,112 @@ +#include "stdlib.h" +#include "math.h" +#include +#include "sm.h" + +#ifdef _WIN32 +#define drand48() ((double)rand()/RAND_MAX) +#define srand48(x) (srand((x))) +#endif + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +typedef struct elem { + float x, y, z; /* current position */ + float dx, dy, dz; /* displacement */ + float size; /* scale factor */ + float ts; /* time stamp */ + float opacity; /* alpha value */ +} elem_t; + +typedef struct smoke { + float ox, oy, oz; /* origin */ + float dx, dy, dz; /* drift */ + int elems; + float intensity; + float min_size; + float max_size; + unsigned texture; + elem_t *elem; +} smoke_t; + +void * +new_smoke(float x, float y, float z, float dx, float dy, float dz, + int elems, float intensity, unsigned texture) { + int i; + smoke_t *s = malloc(sizeof(smoke_t)); + + s->ox = x; s->oy = y, s->oz = z; + s->dx = dx; s->dy = dy; s->dz = dz; + s->min_size = .1f; + s->max_size = 1.0; + s->elems = elems; + s->elem = malloc(sizeof(elem_t)*elems); + for(i = 0; i < elems; i++) { + s->elem[i].ts = (float)i/elems;; + s->elem[i].dx = -drand48()*1.5f; + s->elem[i].dy = drand48()*1.5f; + s->elem[i].dz = drand48()*1.5f; + } + s->intensity = intensity; + s->texture = texture; + return s; +} + +void +delete_smoke(void *smoke) { + smoke_t *s = smoke; + free(s->elem); + free(s); +} + +void +draw_smoke(void *smoke) { + smoke_t *s = smoke; + int i; + + glEnable(GL_BLEND); + glDepthMask(0); +#if 1 + glEnable(GL_TEXTURE_2D); +#else + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif + glBindTexture(GL_TEXTURE_2D, s->texture); + for(i = 0; i < s->elems; i++) { + elem_t *e = s->elem+i; + glPushMatrix(); + glTranslatef(e->x, e->y, e->z); + glScalef(e->size, e->size, 1.); + glColor4f(s->intensity,s->intensity,s->intensity,e->opacity); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1., -1., -0.); + glTexCoord2f(0, 1); glVertex3f(-1., 1., 0.); + glTexCoord2f(1, 1); glVertex3f( 1., 1., 0.); + glTexCoord2f(1, 0); glVertex3f( 1., -1., -0.); + glEnd(); + glPopMatrix(); + } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_TEXTURE_2D); + glDepthMask(1); + glDisable(GL_BLEND); +} + +void +update_smoke(void *smoke, float tick) { + smoke_t *s = smoke; + int i; + + for(i = 0; i < s->elems; i++) { + elem_t *e = s->elem+i; + e->ts += tick; + if (e->ts > 1.0) e->ts = 0; + e->x = s->ox + s->dx*e->ts + e->dx*e->ts; + e->y = s->oy + s->dy*e->ts + e->dy*e->ts; + e->z = s->oz + s->dz*e->ts + e->dz*e->ts; + e->size = s->min_size + e->ts*s->max_size; + e->opacity = (1.0-e->ts); + } +} diff --git a/lib/glut-3.7.6/progs/advanced97/sm.h b/lib/glut-3.7.6/progs/advanced97/sm.h new file mode 100644 index 0000000000..ae7eb30f6a --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/sm.h @@ -0,0 +1,5 @@ +void* new_smoke(float x, float y, float z, float dx, float dy, float dz, + int elems, float intensity, unsigned texture); +void delete_smoke(void *smoke); +void draw_smoke(void *smoke); +void update_smoke(void *smoke, float tick); diff --git a/lib/glut-3.7.6/progs/advanced97/smoke.c b/lib/glut-3.7.6/progs/advanced97/smoke.c new file mode 100644 index 0000000000..5e8874b72e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/smoke.c @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf sin +#define cosf cos +#define atan2f atan2 +#endif + +static int texture = 1; +static float rot = 0; +static float opacity = 1.0; +static float intensity = 1.0; +static float size = .001, delta = 0; +static float scale = 1.; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void afunc(void) { + static int state; + if (state ^= 1) { + glAlphaFunc(GL_GREATER, .01); + glEnable(GL_ALPHA_TEST); + } else { + glDisable(GL_ALPHA_TEST); + } +} + +void bfunc(void) { + static int state; + if (state ^= 1) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } else { + glDisable(GL_BLEND); + } +} + +void tfunc(void) { + texture ^= 1; +} + +void up(void) { scale += .1; } +void down(void) { scale -= .1; } +void left(void) { intensity -= .05f; if (intensity < 0.f) intensity = 0.0f; } +void right(void) { intensity += .05f; if (intensity > 1.f) intensity = 1.0f; } + +void help(void) { + printf("Usage: smoke [image]\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'t' - toggle texturing\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("'LEFT' - darken\n"); + printf("'RIGHT' - brighten\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +void init(char *filename) { + static unsigned *image; + static int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } +#if 0 + if (components == 1) { + GLubyte *p = (GLubyte *)image; + int i; + for (i = 0; i < width*height; i++) { + p[i*4+3] = p[i*4+0]; + } + components = 2; + } +#endif + if (components != 2 && components != 4) { + printf("must be an RGBA or LA image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,20.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + glClearColor(.25f, .25f, .75f, .25f); + + glAlphaFunc(GL_GREATER, 0.016); + glEnable(GL_ALPHA_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); +} + +void +animate(void) { + if (delta > 8) { + delta = 0.f; + size = 0.f; + opacity = 1.f; + rot = 0.f; + } + size += .02f; + delta += .03f; + rot += .9f; + opacity -= .005f; + + glutPostRedisplay(); +} + +void +cube(void) { + glBegin(GL_QUADS); + glNormal3f(0.f, 0.f, -1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); + + glNormal3f(0.f, 0.f, 1.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + + glNormal3f(0.f, -1.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + + glNormal3f( 1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, 1.0); + + glNormal3f(-1.f, 0.f, 0.f); + glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); + glEnd(); +} +static void calcMatrix(void); + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glLoadIdentity(); +#define RAD(x) (((x)*M_PI)/180.) + gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.); + + /* floor */ + glColor4f(0.f,.2f,0.f,1.f); + glBegin(GL_POLYGON); + glVertex3f(-4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, -4.0); + glVertex3f( 4.0, -1.0, 4.0); + glVertex3f(-4.0, -1.0, 4.0); + glEnd(); + + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glColor3f(.3f,.3f,.3f); + glPushMatrix(); + glTranslatef(-1.f, -1.+.2f, -1.5f); + glScalef(.2f,.2f, .2f); + cube(); + glDisable(GL_LIGHTING); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(delta/2.f-1.f, delta-1.f, -1.5f); + calcMatrix(); + glScalef(size,size,1.); + if (texture) glEnable(GL_TEXTURE_2D); + glColor4f(intensity, intensity, intensity, opacity); + glRotatef(rot, 0., 0., 1.); + glDepthMask(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(); + glDepthMask(1); + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'a': afunc(); break; + case 'b': bfunc(); break; + case 'h': help(); break; + case 't': tfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } +} + +int main(int argc, char** argv) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow("smoke"); + init(argc == 1 ? "../data/smoke.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} + +void +printmat(float *m) { + int i; + for(i = 0; i < 4; i++) { + printf("%f %f %f %f\n", m[4*i+0], m[4*i+1], m[4*i+2], m[4*i+3]); + } +} + +void +buildRot(float theta, float x, float y, float z, float m[16]) { + float d = x*x + y*y + z*z; + float ct = cosf(RAD(theta)), st = sinf(RAD(theta)); + + /* normalize */ + if (d > 0) { + d = 1/d; + x *= d; + y *= d; + z *= d; + } + + m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0; + m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0; + m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0; + m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; + + /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S + * + * S = 0 -z y u' = (x, y, z) + * z 0 -x + * -y x 0 + */ + + m[0] = x*x + ct*(1-x*x) + st*0; + m[4] = x*y + ct*(0-x*y) + st*-z; + m[8] = x*z + ct*(0-x*z) + st*y; + + m[1] = y*x + ct*(0-y*x) + st*z; + m[5] = y*y + ct*(1-y*y) + st*0; + m[9] = y*z + ct*(0-y*z) + st*-x; + + m[2] = z*x + ct*(0-z*x) + st*-y; + m[6] = z*y + ct*(0-z*y) + st*x; + m[10]= z*z + ct*(1-z*z) + st*0; +} + +static void +calcMatrix(void) { + float mat[16]; + + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat); + glMultMatrixf(mat); +} diff --git a/lib/glut-3.7.6/progs/advanced97/smoke.dsp b/lib/glut-3.7.6/progs/advanced97/smoke.dsp new file mode 100644 index 0000000000..f1de91b747 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/smoke.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="smoke" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=smoke - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "smoke.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "smoke.mak" CFG="smoke - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "smoke - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "smoke - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "smoke - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "smoke - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "smoke - Win32 Release" +# Name "smoke - Win32 Debug" +# Begin Source File + +SOURCE=.\smoke.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/softshadow2.c b/lib/glut-3.7.6/progs/advanced97/softshadow2.c new file mode 100644 index 0000000000..d791e70fb4 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/softshadow2.c @@ -0,0 +1,632 @@ + +/* softshadow2.c - by Simon Hui, 3Dfx Interactive */ + +/* Soft shadows using a shadow texture per polygon. Based on an algorithm */ +/* described by Paul Heckbert and Michael Herf of CMU; see their web site */ +/* http://www.cs.cmu.edu/ph/shadow.html for details. */ +/* */ +/* This program shows two methods of using precomputed, per-polygon textures */ +/* to display soft shadows. The first method is a simplified version of */ +/* Heckbert and Herf's algorithm: for each polygon a texture is created that */ +/* encodes the full radiance, including illumination and shadows, of the */ +/* polygon. The texture is created in a preprocessing step by rendering the */ +/* entire scene onto the polygon from the point of view of the light. The */ +/* advantage of this method is that the scene can be rerendered quickly (if */ +/* only the eye moves and the scene is static), since all lighting effects */ +/* have been precomputed and encoded in the texture. This method requires */ +/* GL_RGB textures. */ +/* */ +/* The second method uses the texture as an occlusion map: the texels */ +/* encode only the amount of occlusion by shadowing objects, not the full */ +/* radiance. The texture is then used to modulate the lighting of the */ +/* polygon during the rendering pass. This has the disadvantage of */ +/* requiring OpenGL lighting during scene rendering, but it does retain some */ +/* of the benefit of the first method in that all shadow effects are */ +/* precomputed. This method requires GL_LUMINANCE textures. */ +/* */ +/* The reason for including the occlusion map method is that some OpenGL */ +/* implementations support GL_RGB textures with low color resolution, */ +/* resulting in noticeable banding when using radiance maps. However, these */ +/* implementations may support a higher color resolution for GL_LUMINANCE */ +/* textures. */ +/* */ +/* To use occlusion maps instead of rediance maps, run this program with */ +/* "-o" on the command line. */ + +#include +#include +#include +#include + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#define glCopyTexImage2D glCopyTexImage2DEXT +#endif + +/* whether to use radiance maps or occlusion maps */ +static GLboolean radianceMap = GL_TRUE; + +static GLint winxsize = 480, winysize = 480; +static GLint texxsize = 128, texysize = 128; + +/* texture object names */ +const GLuint floorTexture = 1; +const GLuint shadowTextures = 2; + +static GLfloat lightpos[4] = { 70.f, 70.f, -320.f, 1.f }; + +/* number of shadow textures to make and use */ +static GLint numShadowTex; + +/* list of polygons that have shadow textures */ +GLfloat pts[][4][3] = { + /* floor */ + -100.f, -100.f, -320.f, + -100.f, -100.f, -520.f, + 100.f, -100.f, -320.f, + 100.f, -100.f, -520.f, + + /* left wall */ + -100.f, -100.f, -320.f, + -100.f, 100.f, -320.f, + -100.f, -100.f, -520.f, + -100.f, 100.f, -520.f, + + /* back wall */ + -100.f, -100.f, -520.f, + -100.f, 100.f, -520.f, + 100.f, -100.f, -520.f, + 100.f, 100.f, -520.f, + + /* right wall */ + 100.f, -100.f, -520.f, + 100.f, 100.f, -520.f, + 100.f, -100.f, -320.f, + 100.f, 100.f, -320.f, + + /* ceiling */ + -100.f, 100.f, -520.f, + -100.f, 100.f, -320.f, + 100.f, 100.f, -520.f, + 100.f, 100.f, -320.f, + + /* blue panel */ + -60.f, -40.f, -400.f, + -60.f, 70.f, -400.f, + -30.f, -40.f, -480.f, + -30.f, 70.f, -480.f, + + /* yellow panel */ + -40.f, -50.f, -400.f, + -40.f, 50.f, -400.f, + -10.f, -50.f, -450.f, + -10.f, 50.f, -450.f, + + /* red panel */ + -20.f, -60.f, -400.f, + -20.f, 30.f, -400.f, + 10.f, -60.f, -420.f, + 10.f, 30.f, -420.f, + + /* green panel */ + 0.f, -70.f, -400.f, + 0.f, 10.f, -400.f, + 30.f, -70.f, -395.f, + 30.f, 10.f, -395.f, +}; + +GLfloat materials[][4] = { + 1.0f, 1.0f, 1.0f, 1.0f, /* floor */ + 1.0f, 1.0f, 1.0f, 1.0f, /* left wall */ + 1.0f, 1.0f, 1.0f, 1.0f, /* back wall */ + 1.0f, 1.0f, 1.0f, 1.0f, /* right wall */ + 1.0f, 1.0f, 1.0f, 1.0f, /* ceiling */ + 0.2f, 0.5f, 1.0f, 1.0f, /* blue panel */ + 1.0f, 0.6f, 0.0f, 1.0f, /* yellow panel */ + 1.0f, 0.2f, 0.2f, 1.0f, /* red panel */ + 0.3f, 0.9f, 0.6f, 1.0f, /* green panel */ +}; + +/* some simple vector utility routines */ + +void +vcopy(GLfloat a[3], GLfloat b[3]) +{ + b[0] = a[0]; + b[1] = a[1]; + b[2] = a[2]; +} + +void +vnormalize(GLfloat v[3]) +{ + float m = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + v[0] /= m; + v[1] /= m; + v[2] /= m; +} + +void +vadd(GLfloat a[3], GLfloat b[3], GLfloat c[3]) +{ + c[0] = a[0] + b[0]; + c[1] = a[1] + b[1]; + c[2] = a[2] + b[2]; +} + +void +vsub(GLfloat a[3], GLfloat b[3], GLfloat c[3]) +{ + c[0] = a[0] - b[0]; + c[1] = a[1] - b[1]; + c[2] = a[2] - b[2]; +} + +void +vcross(GLfloat a[3], GLfloat b[3], GLfloat c[3]) +{ + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = -(a[0] * b[2] - a[2] * b[0]); + c[2] = a[0] * b[1] - a[1] * b[0]; +} + +float +vdot(GLfloat a[3], GLfloat b[3]) +{ + return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); +} + +void +findNormal(GLfloat pts[][3], GLfloat normal[3]) { + GLfloat a[3], b[3]; + + vsub(pts[1], pts[0], a); + vsub(pts[2], pts[0], b); + vcross(b, a, normal); + vnormalize(normal); +} + +static GLfloat origin[4] = { 0.f, 0.f, 0.f, 1.f }; +static GLfloat black[4] = { 0.f, 0.f, 0.f, 1.f }; +static GLfloat ambient[4] = { 0.2f, 0.2f, 0.2f, 1.f }; + +void +make_shadow_texture(int index, GLfloat eyept[3], GLfloat dx, GLfloat dy) +{ + GLfloat xaxis[3], yaxis[3], zaxis[3]; + GLfloat cov[3]; /* center of view */ + GLfloat pte[3]; /* plane to eye */ + GLfloat eye[3]; + GLfloat tmp[3], normal[3], dist; + GLfloat (*qpts)[3] = pts[index]; + GLfloat left, right, bottom, top; + GLfloat znear = 10.f, zfar = 600.f; + GLint n; + + /* For simplicity, we don't compute the transformation matrix described */ + /* in Heckbert and Herf's paper. The transformation and frustum used */ + /* here is much simpler. */ + + vcopy(eyept, eye); + vsub(qpts[1], qpts[0], yaxis); + vsub(qpts[2], qpts[0], xaxis); + vcross(yaxis, xaxis, zaxis); + + vnormalize(zaxis); + vnormalize(xaxis); /* x-axis of eye coord system, in object space */ + vnormalize(yaxis); /* y-axis of eye coord system, in object space */ + + /* jitter the eyepoint */ + eye[0] += xaxis[0] * dx; + eye[1] += xaxis[1] * dx; + eye[2] += xaxis[2] * dx; + eye[0] += yaxis[0] * dy; + eye[1] += yaxis[1] * dy; + eye[2] += yaxis[2] * dy; + + /* center of view is just eyepoint offset in direction of normal */ + vadd(eye, zaxis, cov); + + /* set up viewing matrix */ + glPushMatrix(); + glLoadIdentity(); + gluLookAt(eye[0], eye[1], eye[2], + cov[0], cov[1], cov[2], + yaxis[0], yaxis[1], yaxis[2]); + + /* compute a frustum that just encloses the polygon */ + vsub(qpts[0], eye, tmp); /* from eye to 0th vertex */ + left = vdot(tmp, xaxis); + vsub(qpts[2], eye, tmp); /* from eye to 2nd vertex */ + right = vdot(tmp, xaxis); + vsub(qpts[0], eye, tmp); /* from eye to 0th vertex */ + bottom = vdot(tmp, yaxis); + vsub(qpts[1], eye, tmp); /* from eye to 1st vertex */ + top = vdot(tmp, yaxis); + + /* scale the frustum values based on the distance to the polygon */ + vsub(qpts[0], eye, pte); + dist = fabs(vdot(zaxis, pte)); + left *= (znear/dist); + right *= (znear/dist); + bottom *= (znear/dist); + top *= (znear/dist); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glFrustum(left, right, bottom, top, znear, zfar); + glMatrixMode(GL_MODELVIEW); + + if (radianceMap) { + glEnable(GL_LIGHTING); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materials[index]); + } else { + glDisable(GL_LIGHTING); + } + glDisable(GL_TEXTURE_2D); + + for (n=0; n < numShadowTex; n++) { + qpts = pts[n]; + + if (radianceMap) { + glColor3f(1.f, 1.f, 1.f); + findNormal(qpts, normal); + glNormal3fv(normal); + if (n == index) { + /* draw this poly with ambient and diffuse lighting */ + glEnable(GL_LIGHT0); + } else { + /* draw other polys with ambient lighting only */ + glDisable(GL_LIGHT0); + } + } else { + if (n == index) { + /* this poly has full intensity, no occlusion */ + glColor3f(1.f, 1.f, 1.f); + } else { + /* all other polys just occlude the light */ + glColor3f(0.f, 0.f, 0.f); + } + } + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(qpts[0]); + glVertex3fv(qpts[1]); + glVertex3fv(qpts[2]); + glVertex3fv(qpts[3]); + glEnd(); + } + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +void make_all_shadow_textures(float eye[3], float dx, float dy) { + GLint texPerRow; + GLint n; + GLfloat x, y; + + texPerRow = (winxsize / texxsize); + for (n=0; n < numShadowTex; n++) { + y = (n / texPerRow) * texysize; + x = (n % texPerRow) * texxsize; + glViewport(x, y, texxsize, texysize); + make_shadow_texture(n, eye, dx, dy); + } + glViewport(0, 0, winxsize, winysize); +} + +void store_all_shadow_textures(void) { + GLint texPerRow; + GLint n, x, y; + GLubyte *texbuf; + + texbuf = (GLubyte *) malloc(texxsize * texysize * sizeof(int)); + + /* how many shadow textures can fit in the window */ + texPerRow = (winxsize / texxsize); + + for (n=0; n < numShadowTex; n++) { + GLenum format; + + x = (n % texPerRow) * texxsize; + y = (n / texPerRow) * texysize; + + glBindTexture(GL_TEXTURE_2D, shadowTextures + n); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (radianceMap) { + format = GL_RGB; + } else { + format = GL_LUMINANCE; + } + glCopyTexImage2D(GL_TEXTURE_2D, 0, format, x, y, texxsize, texysize, 0); + } + free(texbuf); +} + +/* menu choices */ +enum { + NOSHADOWS, SOFTSHADOWS, HARDSHADOWS, VIEWTEXTURE, VIEWSCENE, QUIT +}; + +GLint shadowMode = HARDSHADOWS; +GLboolean viewTextures = GL_FALSE; + +void +redraw(void) +{ + GLint n; + GLfloat normal[3]; + GLfloat (*qpts)[3]; + + glPushMatrix(); + glLoadIdentity(); + if (radianceMap && (shadowMode != NOSHADOWS)) { + glLightfv(GL_LIGHT0, GL_POSITION, origin); + } else { + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + } + glPopMatrix(); + + if (shadowMode == SOFTSHADOWS) { + GLfloat jitterSize; + GLfloat dx, dy; + GLint numSteps, i, j; + + /* size of the area to jitter the light in */ + jitterSize = 15.0; + + /* number of times along x and y to jitter */ + numSteps = 5; + + glClear(GL_ACCUM_BUFFER_BIT); + for (j=0; j < numSteps; j++) { + for (i=0; i < numSteps; i++) { + + /* compute jitter amount, centering the jitter steps around zero */ + dx = (i - (numSteps - 1.0) / 2.0) / (numSteps - 1.0) * jitterSize; + dy = (j - (numSteps - 1.0) / 2.0) / (numSteps - 1.0) * jitterSize; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + make_all_shadow_textures(lightpos, dx, dy); + glAccum(GL_ACCUM, 1.0 / (numSteps * numSteps)); + if (viewTextures) { + glutSwapBuffers(); + } + } + } + glAccum(GL_RETURN, 1.0); + store_all_shadow_textures(); + + } else if (shadowMode == HARDSHADOWS) { + + /* make shadow textures from just one frame */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + make_all_shadow_textures(lightpos, 0, 0); + store_all_shadow_textures(); + if (viewTextures) { + glutSwapBuffers(); + } + } + if (viewTextures) { + glutSwapBuffers(); + return; + } + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glLoadIdentity(); + + glColor3f(1.f, 1.f, 1.f); + if (shadowMode == NOSHADOWS) { + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glDisable(GL_TEXTURE_2D); + for (n=0; n < numShadowTex; n++) { + qpts = pts[n]; + findNormal(qpts, normal); + glNormal3fv(normal); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materials[n]); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0,0); glVertex3fv(qpts[0]); + glTexCoord2f(0,1); glVertex3fv(qpts[1]); + glTexCoord2f(1,0); glVertex3fv(qpts[2]); + glTexCoord2f(1,1); glVertex3fv(qpts[3]); + glEnd(); + } + } else { + glEnable(GL_TEXTURE_2D); + + if (radianceMap) { + glDisable(GL_LIGHTING); + for (n=0; n < numShadowTex; n++) { + qpts = pts[n]; + glBindTexture(GL_TEXTURE_2D, shadowTextures + n); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0,0); glVertex3fv(qpts[0]); + glTexCoord2f(0,1); glVertex3fv(qpts[1]); + glTexCoord2f(1,0); glVertex3fv(qpts[2]); + glTexCoord2f(1,1); glVertex3fv(qpts[3]); + glEnd(); + } + } else { + + /* Unfortunately, using the texture as an occlusion map requires two */ + /* passes: one in which the occlusion map modulates the diffuse */ + /* lighting, and one in which the ambient lighting is added in. It's */ + /* incorrect to modulate the ambient lighting, but if the result is */ + /* acceptable to you, you can include it in the first pass and */ + /* omit the second pass. */ + + /* draw only with diffuse light, modulating it with the texture */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black); + for (n=0; n < numShadowTex; n++) { + qpts = pts[n]; + findNormal(qpts, normal); + glNormal3fv(normal); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materials[n]); + glBindTexture(GL_TEXTURE_2D, shadowTextures + n); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0,0); glVertex3fv(qpts[0]); + glTexCoord2f(0,1); glVertex3fv(qpts[1]); + glTexCoord2f(1,0); glVertex3fv(qpts[2]); + glTexCoord2f(1,1); glVertex3fv(qpts[3]); + glEnd(); + } + + /* add in the ambient lighting */ + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glDepthFunc(GL_LEQUAL); + for (n=0; n < numShadowTex; n++) { + qpts = pts[n]; + glColor4f(ambient[0] * materials[n][0], + ambient[1] * materials[n][1], + ambient[2] * materials[n][2], + ambient[3] * materials[n][3]); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0,0); glVertex3fv(qpts[0]); + glTexCoord2f(0,1); glVertex3fv(qpts[1]); + glTexCoord2f(1,0); glVertex3fv(qpts[2]); + glTexCoord2f(1,1); glVertex3fv(qpts[3]); + glEnd(); + } + /* restore the ambient colors to their defaults */ + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + } + } + + /* blend in the checkerboard floor */ + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glDepthFunc(GL_LEQUAL); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, floorTexture); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materials[0]); + glTranslatef(0.0f, 0.05f, 0.0f); + glColor3f(1.f, 1.f, 1.f); + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2f(0.f, 0.f); glVertex3fv(pts[0][0]); + glTexCoord2f(0.f, 1.f); glVertex3fv(pts[0][1]); + glTexCoord2f(1.f, 0.f); glVertex3fv(pts[0][2]); + glTexCoord2f(1.f, 1.f); glVertex3fv(pts[0][3]); + glEnd(); + + /* undo some state settings that we did above */ + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_LESS); + glTranslatef(0.0f, -0.05f, 0.0f); + +glutSwapBuffers(); +} + +void +menu(int mode) +{ + switch (mode) { + case NOSHADOWS: + case SOFTSHADOWS: + case HARDSHADOWS: + shadowMode = mode; + break; + case VIEWTEXTURE: + viewTextures = GL_TRUE; + break; + case VIEWSCENE: + viewTextures = GL_FALSE; + break; + case QUIT: + exit(0); + } + glutPostRedisplay(); +} + +/* Make a checkerboard texture for the floor. */ +GLfloat * +make_texture(int maxs, int maxt) +{ + GLint s, t; + static GLfloat *texture; + + texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); + for (t = 0; t < maxt; t++) { + for (s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char key, int x, int y) +{ + if (key == 27) /* ESC */ + exit(0); +} + +int +main(int argc, char *argv[]) +{ + GLfloat *tex; + GLint i; + + for (i = 1; i < argc; ++i) { + if (!strcmp("-o", argv[i])) { + /* use textures as occlusion maps rather than radiance maps */ + radianceMap = GL_FALSE; + } + } + + glutInit(&argc, argv); + glutInitWindowSize(winxsize, winysize); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_ACCUM | GLUT_SINGLE); + (void) glutCreateWindow("soft shadows"); + glutDisplayFunc(redraw); + glutKeyboardFunc(keyboard); + + glutCreateMenu(menu); + glutAddMenuEntry("No Shadows", NOSHADOWS); + glutAddMenuEntry("Soft Shadows", SOFTSHADOWS); + glutAddMenuEntry("Hard Shadows", HARDSHADOWS); + glutAddMenuEntry("View Textures", VIEWTEXTURE); + glutAddMenuEntry("View Scene", VIEWSCENE); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* set up perspective projection */ + glMatrixMode(GL_PROJECTION); + glFrustum(-30., 30., -30., 30., 100., 640.); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glCullFace(GL_BACK); + glLightfv(GL_LIGHT0, GL_AMBIENT, black); + + /* number of shadow textures to make */ + numShadowTex = sizeof(pts) / sizeof(pts[0]); + + tex = make_texture(texxsize, texysize); + glBindTexture(GL_TEXTURE_2D, floorTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 1, texxsize, texysize, 0, GL_RED, GL_FLOAT, + tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + free(tex); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced97/softshadow2.dsp b/lib/glut-3.7.6/progs/advanced97/softshadow2.dsp new file mode 100644 index 0000000000..91d6619373 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/softshadow2.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="softshadow2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=softshadow2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "softshadow2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "softshadow2.mak" CFG="softshadow2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "softshadow2 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "softshadow2 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "softshadow2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "softshadow2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "softshadow2 - Win32 Release" +# Name "softshadow2 - Win32 Debug" +# Begin Source File + +SOURCE=.\softshadow2.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/spectral.c b/lib/glut-3.7.6/progs/advanced97/spectral.c new file mode 100644 index 0000000000..4335f04c0e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/spectral.c @@ -0,0 +1,518 @@ +/* spectral.c - by Simon Hui, 3Dfx Interactive */ + +/* make a noise texture from multiple frequencies of noise */ + +#include +#include +#include +#include + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +static int texxsize = 256, texysize = 256; +static int winxsize = 512, winysize = 512; + +/* the highest and lowest octaves in the final noise */ +static int minoctave = 1; +static int maxoctave = 6; + +static GLenum ifmt = GL_LUMINANCE; + +/* texture object names */ +static GLuint basistex = 1; +static GLuint noisetex = 2; +static GLuint spectraltex = 6; +static GLuint abstex = 7; + +int +logOf(int n) { + int i=0; + for (i=-1; n > 0; i++) { + n >>= 1; + } + return i; +} + +void +init_texture(void) { + int i, j, n; + int w, h; + unsigned char *basis, *tex; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + basis = (unsigned char *) malloc(texxsize * texysize); + w = texxsize / 2; + h = texysize / 2; + for (j=0; j < h; j++) { + for (i=0; i < w; i++) { + GLint r; + float u = i / (w - 1.0); + float v = j / (h - 1.0); + float f = 3 * u * u - 2 * u * u * u; + float g = 3 * v * v - 2 * v * v * v; + + /* basis is a bicubic spline */ + r = f * g * 0xff; + + /* reflect around x and y axes */ + basis[j * texxsize + i] = r; + basis[j * texxsize + texxsize-i-1] = r; + basis[(texysize-j-1) * texxsize + i] = r; + basis[(texysize-j-1) * texxsize + texxsize-i-1] = r; + } + } + glBindTexture(GL_TEXTURE_2D, basistex); + 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, GL_LUMINANCE, texxsize, texysize, 0, + GL_RED, GL_UNSIGNED_BYTE, basis); + free(basis); + + tex = (unsigned char *) malloc(4 * texxsize * texysize); + for (n=0; n < 4; n++) { + for (j=0; j < texysize; j++) { + for (i=0; i < texxsize; i++) { + int r = rand(); + + /* mix it up a little more */ + r = ((r & 0xff) ^ ((r & 0xff00) >> 8)) & 0xff; + + /* For simplicity and because some opengl implementations offer */ + /* more texture color depth for luminance textures than rgb ones, */ + /* we use a luminance texture for the random noise. However, you */ + /* can make the texture rgb instead, and store different random */ + /* values for r, g, and b; this is especially useful if using */ + /* noise distortion below, because you'll get different distortion */ + /* values for s and t. */ + tex[j*texxsize + i] = r; + } + } + glBindTexture(GL_TEXTURE_2D, noisetex + n); + 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, GL_LUMINANCE, texxsize, texysize, 0, + GL_RED, GL_UNSIGNED_BYTE, tex); + } + free(tex); +} + +void +init(void) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glMatrixMode(GL_PROJECTION); + glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glViewport(0, 0, winxsize, winysize); + glDisable(GL_DITHER); + init_texture(); +} + +void +draw_basis(int tsize, int ssize, int xadj, int yadj) { + float tilessize = 1.0 / ssize; + float tiletsize = 1.0 / tsize; + float xoff = (xadj - 0.5) * 0.5 * tilessize; + float yoff = (yadj - 0.5) * 0.5 * tiletsize; + float xo, yo; + int i, j; + + glBindTexture(GL_TEXTURE_2D, basistex); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + /* draw as many copies of the basis function as needed for this frequency */ + for (j=0; j < tsize; j++) { + for (i=0; i < ssize; i++) { + xo = xoff + i * tilessize; + yo = yoff + j * tiletsize; + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); glVertex2f(xo, yo); + glTexCoord2f(0.f, 1.f); glVertex2f(xo, yo + tiletsize); + glTexCoord2f(1.f, 0.f); glVertex2f(xo + tilessize, yo); + glTexCoord2f(1.f, 1.f); glVertex2f(xo + tilessize, yo + tiletsize); + glEnd(); + } + } + glFinish(); +} + +void +draw_noise_texture(int tsize, int ssize, int xadj, int yadj, int texname) { + float tilessize = 1.0 / ssize; + float tiletsize = 1.0 / tsize; + float xoff = (xadj - 0.5) * 0.5 * tilessize; + float yoff = (yadj - 0.5) * 0.5 * tiletsize; + float scale = 1.0 / (texxsize / ssize); + + glBindTexture(GL_TEXTURE_2D, texname); + + /* scale the texture matrix to get a noise pattern of desired frequency */ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(scale,scale,scale); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); glVertex2f(xoff, yoff); + glTexCoord2f(0.f, 1.f); glVertex2f(xoff, yoff + 1.0); + glTexCoord2f(1.f, 0.f); glVertex2f(xoff + 1.0, yoff); + glTexCoord2f(1.f, 1.f); glVertex2f(xoff + 1.0, yoff + 1.0); + glEnd(); + glFlush(); +} + +static float wscale = 0.60; +static unsigned int **octbufs, *spectralbuf, *absbuf; + +void +make_octaves(void) { + int w, h, i; + int octaves = maxoctave - minoctave + 1; + float weight, sumweight; + + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + glEnable(GL_TEXTURE_2D); + + /* find the total weight */ + weight = 1.0; + sumweight = 0; + for (i=0; i < octaves; i++) { + sumweight += weight; + weight *= wscale; + } + octbufs = (unsigned int **) malloc(octaves * sizeof(unsigned int *)); + + weight = 1.0; + w = h = (1 << minoctave); + for (i=0; i < octaves; i++) { + octbufs[i] = (unsigned int *) malloc(sizeof(unsigned int) * + winxsize * winysize); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(w, h, 0, 0); + glEnable(GL_BLEND); + draw_noise_texture(w, h, 0, 0, noisetex); + glAccum(GL_LOAD, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(w, h, 1, 0); + glEnable(GL_BLEND); + draw_noise_texture(w, h, 1, 0, noisetex + 1); + glAccum(GL_ACCUM, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(w, h, 0, 1); + glEnable(GL_BLEND); + draw_noise_texture(w, h, 0, 1, noisetex + 2); + glAccum(GL_ACCUM, 1.0); + + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_BLEND); + draw_basis(w, h, 1, 1); + glEnable(GL_BLEND); + draw_noise_texture(w, h, 1, 1, noisetex + 3); + glAccum(GL_ACCUM, 1.0); + + glDisable(GL_BLEND); + glAccum(GL_RETURN, 1.0); + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + octbufs[i]); + w <<= 1; + h <<= 1; + } + glDisable(GL_TEXTURE_2D); +} + +static GLboolean need_remake_octaves = GL_TRUE; +static GLboolean need_remake_spectral = GL_TRUE; +static GLboolean need_remake_abs_noise = GL_TRUE; + +void +make_spectral_noise(void) { + int i; + int octaves = maxoctave - minoctave + 1; + float weight, sumweight; + + if (need_remake_octaves) { + make_octaves(); + need_remake_octaves = GL_FALSE; + } + /* find the total weight */ + weight = 1.0; + sumweight = 0; + for (i=0; i < octaves; i++) { + sumweight += weight; + weight *= wscale; + } + glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + weight = 1.0; + for (i=0; i < octaves; i++) { + glDrawPixels(winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) octbufs[i]); + glAccum(GL_ACCUM, weight/sumweight); + weight *= wscale; + } + + /* save image in a texture */ + glAccum(GL_RETURN, 1.0); + spectralbuf = (unsigned int *) malloc(4 * winxsize * winysize); + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + spectralbuf); + glBindTexture(GL_TEXTURE_2D, spectraltex); + 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, ifmt, winxsize, winysize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, spectralbuf); +} + +void +make_abs_noise(void) { + unsigned int *negbuf = (unsigned int *) malloc(4 * winxsize * winysize); + unsigned int *posbuf = (unsigned int *) malloc(4 * winxsize * winysize); + + if (need_remake_spectral) { + make_spectral_noise(); + need_remake_spectral = GL_FALSE; + } + glDrawPixels(winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) spectralbuf); + glAccum(GL_LOAD, 1.0); + + /* make it signed */ + glAccum(GL_ADD, -0.5); + + /* get the positive part of the noise */ + glAccum(GL_RETURN, 2.0); + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) negbuf); + + /* invert the negative part of the noise */ + glAccum(GL_RETURN, -2.0); + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) posbuf); + + /* add positive and inverted negative together, and you get abs() */ + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glDrawPixels(winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) posbuf); + glDrawPixels(winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) negbuf); + + /* invert the colors so that peaks are bright instead of dark */ + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + glColor4f(1,1,1,1); + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(0,0); + glVertex2f(0,1); + glVertex2f(1,0); + glVertex2f(1,1); + glEnd(); + glDisable(GL_BLEND); + + free(posbuf); + free(negbuf); + + /* save image in a texture */ + absbuf = (unsigned int *) malloc(4 * winxsize * winysize); + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) absbuf); + glBindTexture(GL_TEXTURE_2D, abstex); + 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, ifmt, winxsize, winysize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, absbuf); +} + +static GLboolean show_abs = GL_FALSE; +static GLboolean show_distort = GL_FALSE; +static GLboolean mapcolors = GL_FALSE; +static float distfactor = 0.20; + +void +display(void) { + if (need_remake_spectral) { + make_spectral_noise(); + need_remake_spectral = GL_FALSE; + } + if (show_abs) { + if (need_remake_abs_noise) { + make_abs_noise(); + need_remake_abs_noise = GL_FALSE; + } + glBindTexture(GL_TEXTURE_2D, abstex); + } else { + glBindTexture(GL_TEXTURE_2D, spectraltex); + } + + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + if (show_distort) { + /* Use values in the spectral texture to distort the texture being */ + /* viewed, by jittering the texture coordinates. */ + + float x, y0, y1; + float s, t0, t1; + float ds, dt; + unsigned int pix0, pix1; + int vrows = 64, vcols = 64; + int i, j; + + for (j=0; j < (vrows - 1); j++) { + t0 = y0 = j / (vrows - 1.0); + t1 = y1 = (j + 1) / (vrows - 1.0); + + glBegin(GL_TRIANGLE_STRIP); + for (i=0; i < vcols; i++) { + s = x = i / (vcols - 1.0); + pix0 = spectralbuf[j * winxsize + i]; + pix1 = spectralbuf[(j+1) * winxsize + i]; + + /* Use green component of noise to distort S coord, */ + /* and blue component to distort T coord. Subtract */ + /* 127.5 to make it signed, and scale by distfactor.*/ + + ds = ((pix0 & 0x00ff0000) >> 16); + dt = ((pix0 & 0x0000ff00) >> 8); + ds = (ds - 127.5) / 127.5 * distfactor; + dt = (dt - 127.5) / 127.5 * distfactor; + glTexCoord2f(s + ds, t0 + dt); glVertex2f(x, y0); + ds = ((pix1 & 0x00ff0000) >> 16); + dt = ((pix1 & 0x0000ff00) >> 8); + ds = (ds - 127.5) / 127.5 * distfactor; + dt = (dt - 127.5) / 127.5 * distfactor; + glTexCoord2f(s + ds, t1 + dt); glVertex2f(x, y1); + } + glEnd(); + } + } else { + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0, 0); glVertex2f(0, 0); + glTexCoord2f(0, 1); glVertex2f(0, 1); + glTexCoord2f(1, 0); glVertex2f(1, 0); + glTexCoord2f(1, 1); glVertex2f(1, 1); + glEnd(); + } + glDisable(GL_TEXTURE_2D); + + if (mapcolors) { + /* Map the gray values of the image into colors so that the texture */ + /* looks like flames. We do that by defining appropriate splines for */ + /* red, green, and blue. */ + + float r, g, b; + float rt = 0.8; + float gt = 0.3; + float bt = 0.1; + int i, j; + unsigned char *c; + unsigned int *mapbuf = (unsigned int *) malloc(4 * winxsize * winysize); + + glReadPixels(0, 0, winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + mapbuf); + + for (j=0; j < winysize; j++) { + for (i=0; i < winxsize; i++) { + c = (unsigned char *) &mapbuf[j * winxsize + i]; + r = c[0] / 255.0; + g = c[1] / 255.0; + b = c[2] / 255.0; + + if (r < (1-rt)) { + r = 0.0; + } else { + float k = (r - (1.0 - rt)) / rt; + r = (3.0*k*k - 2.0*k*k*k) * 255.0; + } + if (g < (1-gt)) { + g = 0.0; + } else { + float k = (g - (1.0 - gt)) / gt; + g = (3.0*k*k - 2.0*k*k*k) * 255.0; + } + if (b < (1-bt)) { + b = 0.0; + } else { + float k = (b - (1.0 - bt)) / bt; + b = (3.0*k*k - 2.0*k*k*k) * 255.0; + } + c[0] = r; + c[1] = g; + c[2] = b; + } + } + glDrawPixels(winxsize, winysize, GL_RGBA, GL_UNSIGNED_BYTE, + (GLvoid *) mapbuf); + free(mapbuf); + } + glFlush(); +} + +void +reshape(int w, int h) { + glViewport(0, 0, w, h); + glutPostRedisplay(); +} + +enum { + TOGGLE_ABS, TOGGLE_DISTORT, MORE_DISTORT, LESS_DISTORT, TOGGLE_MAP_COLORS, + FIRE, QUIT +}; + +void +menu(int value) { + switch (value) { + case TOGGLE_ABS: + show_abs = !show_abs; + break; + case TOGGLE_DISTORT: + show_distort = !show_distort; + break; + case MORE_DISTORT: + if (distfactor > 0.05) distfactor -= 0.05; + break; + case LESS_DISTORT: + if (distfactor < 1.00) distfactor += 0.05; + break; + case TOGGLE_MAP_COLORS: + mapcolors = !mapcolors; + break; + case FIRE: + mapcolors = GL_TRUE; + show_distort = GL_TRUE; + show_abs = GL_TRUE; + break; + case QUIT: + exit(0); + } + glutPostRedisplay(); +} + +int +main(int argc, char** argv) { + glutInit(&argc, argv); + glutInitWindowSize(winxsize, winysize); + glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM); + (void)glutCreateWindow("spectral noise function"); + init(); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutCreateMenu(menu); + glutAddMenuEntry("Toggle Absolute Value", TOGGLE_ABS); + glutAddMenuEntry("Toggle Noise Distortion", TOGGLE_DISTORT); + glutAddMenuEntry("Decrease Distortion", MORE_DISTORT); + glutAddMenuEntry("Increase Distortion", LESS_DISTORT); + glutAddMenuEntry("Toggle Color Mapping", TOGGLE_MAP_COLORS); + glutAddMenuEntry("Simulation of Fire", FIRE); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced97/spectral.dsp b/lib/glut-3.7.6/progs/advanced97/spectral.dsp new file mode 100644 index 0000000000..f40c17c644 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/spectral.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="spectral" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=spectral - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "spectral.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "spectral.mak" CFG="spectral - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "spectral - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "spectral - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "spectral - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "spectral - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "spectral - Win32 Release" +# Name "spectral - Win32 Debug" +# Begin Source File + +SOURCE=.\spectral.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/sphere.c b/lib/glut-3.7.6/progs/advanced97/sphere.c new file mode 100644 index 0000000000..0d29758040 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/sphere.c @@ -0,0 +1,185 @@ +#include +#include +#include + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define sqrtf(x) ((float)sqrt((x))) +#endif + +/* sphere tessellation code based on code originally + * written by Jon Leech (leech@cs.unc.edu) 3/24/89 + */ + +typedef struct { + float x, y, z; +} point; + +typedef struct { + point pt[3]; +} triangle; + +/* six equidistant points lying on the unit sphere */ +#define XPLUS { 1, 0, 0 } /* X */ +#define XMIN { -1, 0, 0 } /* -X */ +#define YPLUS { 0, 1, 0 } /* Y */ +#define YMIN { 0, -1, 0 } /* -Y */ +#define ZPLUS { 0, 0, 1 } /* Z */ +#define ZMIN { 0, 0, -1 } /* -Z */ + +/* for icosahedron */ +#define CZ (0.866025403) /* cos(30) */ +#define SZ (0.5) /* sin(30) */ +#define C1 (0.951056516) /* cos(18), */ +#define S1 (0.309016994) /* sin(18) */ +#define C2 (0.587785252) /* cos(54), */ +#define S2 (0.809016994) /* sin(54) */ +#define X1 (C1*CZ) +#define Y1 (S1*CZ) +#define X2 (C2*CZ) +#define Y2 (S2*CZ) + +#define Ip0 {0., 0., 1.} +#define Ip1 {-X2, -Y2, SZ} +#define Ip2 {X2, -Y2, SZ} +#define Ip3 {X1, Y1, SZ} +#define Ip4 {0, CZ, SZ} +#define Ip5 {-X1, Y1, SZ} + +#define Im0 {-X1, -Y1, -SZ} +#define Im1 {0, -CZ, -SZ} +#define Im2 {X1, -Y1, -SZ} +#define Im3 {X2, Y2, -SZ} +#define Im4 {-X2, Y2, -SZ} +#define Im5 {0., 0., -1.} + +/* vertices of a unit icosahedron */ +static triangle icosahedron[20]= { + /* front pole */ + { {Ip0, Ip1, Ip2}, }, + { {Ip0, Ip5, Ip1}, }, + { {Ip0, Ip4, Ip5}, }, + { {Ip0, Ip3, Ip4}, }, + { {Ip0, Ip2, Ip3}, }, + + /* mid */ + { {Ip1, Im0, Im1}, }, + { {Im0, Ip1, Ip5}, }, + { {Ip5, Im4, Im0}, }, + { {Im4, Ip5, Ip4}, }, + { {Ip4, Im3, Im4}, }, + { {Im3, Ip4, Ip3}, }, + { {Ip3, Im2, Im3}, }, + { {Im2, Ip3, Ip2}, }, + { {Ip2, Im1, Im2}, }, + { {Im1, Ip2, Ip1}, }, + + /* back pole */ + { {Im3, Im2, Im5}, }, + { {Im4, Im3, Im5}, }, + { {Im0, Im4, Im5}, }, + { {Im1, Im0, Im5}, }, + { {Im2, Im1, Im5}, }, +}; + +/* normalize point r */ +static void +normalize(point *r) { + float mag; + + mag = r->x * r->x + r->y * r->y + r->z * r->z; + if (mag != 0.0f) { + mag = 1.0f / sqrtf(mag); + r->x *= mag; + r->y *= mag; + r->z *= mag; + } +} + +/* linearly interpolate between a & b, by fraction f */ +static void +lerp(point *a, point *b, float f, point *r) { + r->x = a->x + f*(b->x-a->x); + r->y = a->y + f*(b->y-a->y); + r->z = a->z + f*(b->z-a->z); +} + +void +sphere(int maxlevel) { + int nrows = 1 << maxlevel; + int s; + + /* iterate over the 20 sides of the icosahedron */ + for(s = 0; s < 20; s++) { + int i; + triangle *t = &icosahedron[s]; + for(i = 0; i < nrows; i++) { + /* create a tstrip for each row */ + /* number of triangles in this row is number in previous +2 */ + /* strip the ith trapezoid block */ + point v0, v1, v2, v3, va, vb; + int j; + lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0); + lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1); + lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2); + lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3); + glBegin(GL_TRIANGLE_STRIP); +#define V(v) { point x; x = v; normalize(&x); glNormal3fv(&x.x); glVertex3fv(&x.x); } + V(v0); + V(v1); + for(j = 0; j < i; j++) { + /* calculate 2 more vertices at a time */ + lerp(&v0, &v2, (float)(j+1)/(i+1), &va); + lerp(&v1, &v3, (float)(j+1)/i, &vb); + V(va); + V(vb); + } + V(v2); +#undef V + glEnd(); + } + } +} + +float * +sphere_tris(int maxlevel) { + int nrows = 1 << maxlevel; + int s, n; + float *buf, *b; + + n = 20*(1 << (maxlevel * 2)); + b = buf = (float *)malloc(n*3*3*sizeof(float)); + + /* iterate over the 20 sides of the icosahedron */ + for(s = 0; s < 20; s++) { + int i; + triangle *t = &icosahedron[s]; + for(i = 0; i < nrows; i++) { + /* create a tstrip for each row */ + /* number of triangles in this row is number in previous +2 */ + /* strip the ith trapezoid block */ + point v0, v1, v2, v3, va, vb, x1, x2; + int j; + lerp(&t->pt[1], &t->pt[0], (float)(i+1)/nrows, &v0); + lerp(&t->pt[1], &t->pt[0], (float)i/nrows, &v1); + lerp(&t->pt[1], &t->pt[2], (float)(i+1)/nrows, &v2); + lerp(&t->pt[1], &t->pt[2], (float)i/nrows, &v3); +#define V(a, c, v) { point x = v; normalize(&a); normalize(&c); normalize(&x); \ + b[0] = a.x; b[1] = a.y; b[2] = a.z; \ + b[3] = c.x; b[4] = c.y; b[5] = c.z; \ + b[6] = x.x; b[7] = x.y; b[8] = x.z; b+=9; } + x1 = v0; + x2 = v1; + for(j = 0; j < i; j++) { + /* calculate 2 more vertices at a time */ + lerp(&v0, &v2, (float)(j+1)/(i+1), &va); + lerp(&v1, &v3, (float)(j+1)/i, &vb); + V(x1,x2,va); x1 = x2; x2 = va; + V(vb,x2,x1); x1 = x2; x2 = vb; + } + V(x1, x2, v2); +#undef V + } + } + return buf; +} diff --git a/lib/glut-3.7.6/progs/advanced97/tess.c b/lib/glut-3.7.6/progs/advanced97/tess.c new file mode 100644 index 0000000000..91daaa724f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/tess.c @@ -0,0 +1,185 @@ +#include +#include +#include + +static GLfloat spin = 0; +static int level = 4; +static int model = 0; +static GLfloat rotx, roty; +static int ox = -1, oy = -1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +movelight(int x, int y) { + spin += (x-ox); + ox = x; oy = y; + if (spin > 360.) spin -= 360.; + if (spin < -360.) spin -= -360.; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) movelight(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void togglewire(void) { + static int toggle = 0; + toggle ^= 1; + glPolygonMode(GL_FRONT_AND_BACK, toggle ? GL_LINE : GL_FILL); +} + +extern void sphere(int level); +void genmodel(void) { + + glNewList(1, GL_COMPILE); + if (model) { + GLUquadricObj *q = gluNewQuadric(); + gluSphere(q, 1.0, 10*level, 10*level); + gluDeleteQuadric(q); + } else { + sphere(level-1); + } + glEndList(); +} + +void togglemodel(void) { + model ^= 1; + genmodel(); +} + +void levelup(void) { + level += 1; + if (level > 7) level = 7; + genmodel(); +} + +void leveldown(void) { + level -= 1; + if (level <= 0) level = 1; + genmodel(); +} + +void help(void) { + printf("'h' - help\n"); + printf("'t' - tessellation style\n"); + printf("'UP' - increase tessellation\n"); + printf("'DOWN' - decrease tessellation\n"); + printf("left mouse - rotate sphere\n"); + printf("right mouse - move light\n"); +} + +void init(void) { + GLfloat specular[4] = { 1., 1., 1., 1. }; + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + genmodel(); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30); +} + +void display(void) { + GLfloat position[] = { 0.0, 0.0, 3.5, 1.0 }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPushMatrix(); + glTranslatef(0.0, 0.0, -5.0); + + glPushMatrix(); + glRotatef(spin, 1.0, 0.0, 0.0); + glRotatef(0.0, 1.0, 0.0, 0.0); + glLightfv(GL_LIGHT0, GL_POSITION, position); + + glPopMatrix(); + + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glCallList(1); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); + glMatrixMode(GL_MODELVIEW); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 't': togglemodel(); break; + case 'w': togglewire(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: levelup(); break; + case GLUT_KEY_DOWN: leveldown(); break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow(argv[0]); + init(); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/tess.dsp b/lib/glut-3.7.6/progs/advanced97/tess.dsp new file mode 100644 index 0000000000..1daf5a7044 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/tess.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="tess" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tess - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tess.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tess.mak" CFG="tess - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tess - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tess - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tess - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "tess - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "tess - Win32 Release" +# Name "tess - Win32 Debug" +# Begin Source File + +SOURCE=.\sphere.c +# End Source File +# Begin Source File + +SOURCE=.\tess.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/texgen.c b/lib/glut-3.7.6/progs/advanced97/texgen.c new file mode 100644 index 0000000000..19f10d5820 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texgen.c @@ -0,0 +1,292 @@ +#include +#include +#include +#include + +#ifndef __sgi +/* Most math.h's do not define float versions of math functions. */ +#define floorf(x) ((float)floor((x))) +#endif + +static float transx = 1.0, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(const int x, const int y) { + transx += (x-ox)/5.; + transy -= (y-oy)/5.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(const int x, const int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +#define stripeImageWidth 32 +GLubyte stripeImage[4*stripeImageWidth]; + +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; + } +} + +void +hsv_to_rgb(float h,float s,float v,float *r,float *g,float *b) +{ + int i; + float f, p, q, t; + + h *= 360.0; + if (s==0) { + *r = v; + *g = v; + *b = v; + } else { + if (h==360) + h = 0; + h /= 60; + i = floorf(h); + f = h - i; + p = v*(1.0-s); + q = v*(1.0-(s*f)); + t = v*(1.0-(s*(1.0-f))); + switch (i) { + case 0 : + *r = v; + *g = t; + *b = p; + break; + case 1 : + *r = q; + *g = v; + *b = p; + break; + case 2 : + *r = p; + *g = v; + *b = t; + break; + case 3 : + *r = p; + *g = q; + *b = v; + break; + case 4 : + *r = t; + *g = p; + *b = v; + break; + case 5 : + *r = v; + *g = p; + *b = q; + break; + } + } +} + +GLubyte rainbow[4*stripeImageWidth]; +void makeRainbow(void) { + int j; + for (j = 0; j < stripeImageWidth; j++) { + float r, g, b; + hsv_to_rgb((float)j/(stripeImageWidth-1.f), 1.0, 1.0, &r, &g, &b); + rainbow[4*j] = r*255; + rainbow[4*j+1] = g*255; + rainbow[4*j+2] = b*255; + rainbow[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(); + makeRainbow(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + 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); + glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, + GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); + + 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 tfunc(void) { + static int state; + if (state ^= 1) { + 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); + glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, + GL_RGBA, GL_UNSIGNED_BYTE, rainbow); + } else { + 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); + glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, + GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); + } + glutPostRedisplay(); +} + +void display(void) { +#if 0 + static GLUquadricObj *q = NULL; +#endif + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(0., 0., transx); + glRotatef(rotx, 1.0, 0.0, 0.0); + glRotatef(45.0, 0.0, 0.0, 1.0); + glutSolidTeapot(2.0); +#if 0 + if (!q) q = gluNewQuadric(); + gluQuadricTexture(q, GL_TRUE); + gluCylinder(q, 1.0, 2.0, 3.0, 10, 10); +#endif + glPopMatrix(); + glutSwapBuffers(); +} + +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 't': tfunc(); break; + case 27: + exit(0); + break; + default: + break; + } +} + +int main(int argc, char*argv[]) { + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(256, 256); + glutInitWindowPosition(100, 100); + glutInit(&argc, argv); + glutCreateWindow(argv[0]); + init(); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/texgen.dsp b/lib/glut-3.7.6/progs/advanced97/texgen.dsp new file mode 100644 index 0000000000..307792e310 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texgen.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="texgen" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=texgen - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "texgen.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texgen.mak" CFG="texgen - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texgen - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "texgen - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texgen - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "texgen - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "texgen - Win32 Release" +# Name "texgen - Win32 Debug" +# Begin Source File + +SOURCE=.\texgen.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/texmovie.c b/lib/glut-3.7.6/progs/advanced97/texmovie.c new file mode 100644 index 0000000000..767ec74405 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texmovie.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include "texture.h" + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glBindTexture glBindTextureEXT +#endif + +static int the_texture; +static int texture_count; +static int shrink = 1; + +void afunc(void) { + static int state; + if (state ^= 1) + glEnable(GL_ALPHA_TEST); + else + glDisable(GL_ALPHA_TEST); +} + +void bfunc(void) { + static int state; + if (state ^= 1) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); +} + +void sfunc(void) { + shrink ^= 1; +} + +void tfunc(void) { + static int state; + if (state ^= 1) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +void fourfunc(void) { + static int state; + GLenum wrap; + int i; + + glMatrixMode(GL_TEXTURE); + if (state ^= 1) { + wrap = GL_REPEAT; + glScalef(4.f, 4.f, 1.f); + } else { + wrap = GL_CLAMP; + glLoadIdentity(); + } + glMatrixMode(GL_MODELVIEW); + + for(i = 0; i < texture_count; i++) { + glBindTexture(GL_TEXTURE_2D, i+1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + } +} + +void help(void) { + printf("Usage: texmovie image0 ... imagen\n"); + printf("'h' - help\n"); + printf("'a' - toggle alpha test\n"); + printf("'b' - toggle blend\n"); + printf("'s' - toggle shrink\n"); + printf("'t' - toggle MODULATE or REPLACE\n"); + printf("'4' - toggle repeat by 4\n"); +} + +void init(int argc, char *argv[]) { + unsigned *image; + int i, width, height, components; + + glEnable(GL_TEXTURE_2D); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if (argv[0] == NULL) { + char name[256]; + for (i = 0; i < 32; i++) { + sprintf(name, "../data/flame/f%02d", i); + image = read_texture(name, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", argv[i]); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + glBindTexture(GL_TEXTURE_2D, i+1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + texture_count++; + } + } + + for(i = 0; i < argc; i++) { + image = read_texture(argv[i], &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + argv[i]); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + glBindTexture(GL_TEXTURE_2D, i+1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + texture_count++; + } + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + glClearColor(.25f, .25f, .25f, .25f); + + glAlphaFunc(GL_GREATER, 0.f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void +animate(void) { + + the_texture++; + if (the_texture >= texture_count) the_texture = 0; + + glutPostRedisplay(); +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, the_texture+1); + glPushMatrix(); + if (shrink) glScalef(.5f, .5f, 1.f); + 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(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/* ARGSUSED1 */ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'a': afunc(); break; + case 'b': bfunc(); break; + case 'h': help(); break; + case 's': sfunc(); break; + case 't': tfunc(); break; + case '4': fourfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argc-1, argv+1); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/texmovie.dsp b/lib/glut-3.7.6/progs/advanced97/texmovie.dsp new file mode 100644 index 0000000000..08524b53a6 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texmovie.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="texmovie" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=texmovie - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "texmovie.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texmovie.mak" CFG="texmovie - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texmovie - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "texmovie - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texmovie - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "texmovie - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "texmovie - Win32 Release" +# Name "texmovie - Win32 Debug" +# Begin Source File + +SOURCE=.\texmovie.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/texpage.c b/lib/glut-3.7.6/progs/advanced97/texpage.c new file mode 100644 index 0000000000..21418eaeb3 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texpage.c @@ -0,0 +1,503 @@ +#include +#include +#include +#include +#include "texture.h" +#include + +#if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2) +#define glTexSubImage2D glTexSubImage2DEXT +#endif + +static unsigned *image, *bgdtile; +static int width, height, components; +static int grid, zoom, texture; + + +#define TSIZE 128 +#define TILES 16 +#define TILESIZE 32 +static struct tile { + void *data; +} tiles[TILES][TILES]; + +static int x = TILES*TILESIZE/2, y = TILES*TILESIZE/2; + +/* + * make an rgb tile for the background. + */ +static void +background_tile(void) { + int i,j,grid; + unsigned char *ptr; + + bgdtile = (unsigned *) malloc(TILESIZE*TILESIZE*sizeof(unsigned)); + grid = 8; + ptr = (unsigned char *) bgdtile; + for (i=0; i= TILES/2-w2 && i < TILES/2-w2+w && j >= TILES/2-h2 && j < TILES/2-h2+h) { + /* interior */ + int x, y, k; + tiles[j][i].data = malloc(TILESIZE*TILESIZE*sizeof(*image)); + x = TILESIZE*(i-TILES/2+w2); + y = TILESIZE*(j-TILES/2+h2); + for(k = 0; k < TILESIZE; k++) + memcpy((unsigned *)tiles[j][i].data+k*TILESIZE, + image+width*(y+k)+x, TILESIZE*sizeof *image); + } + else + tiles[j][i].data = bgdtile; + } + } + for(i = 0; i < TILES; i++) { + for(j = 0; j < TILES; j++) { + printf("%d ", tiles[j][i].data != bgdtile); + } + printf("\n"); + } +} + +#define MAXMESH 64 + +static float Ml[4*2*(MAXMESH+1)*2 * (MAXMESH+1)]; + +static void +mesh0(float x0, float x1, float y0, float y1, + float s0, float s1, float t0, float t1, float z, int nx,int ny) +{ + float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2]; + float *mp = Ml; + + dx = (x1-x0)/nx; + dy = (y1-y0)/ny; + ds = (s1-s0)/nx; + dt = (t1-t0)/ny; + y = y0; + t = t0; + vb[2] = z; + while (y < y1) { + x = x0; + s = s0; + while(x <= x1) { + tb[0] = s; tb[1] = t; + vb[0] = x; vb[1] = y; + vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + tb[1] = t+dt; + vb[1] = y+dy; + vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + x += dx; + s += ds; + } + y += dy; + t += dt; + } +} + +static void +drawmesh(int nx,int ny) { + float *mp = Ml; + int i,j; + + glPushMatrix(); + if (zoom) glScalef(1.5f, 1.5f, 1.f); + glColor4f(1,1,1,1); + for (i = ny+1; i; i--) { + glBegin(GL_TRIANGLE_STRIP); + for (j = nx+1; j; j--) { + glTexCoord2fv(mp); + glVertex3fv(mp+4); + glTexCoord2fv(mp+8); + glVertex3fv(mp+12); mp += 16; + } + glEnd(); + } + glPopMatrix(); +} + +static void +help(void) { + printf("'h' - help\n"); + printf("'left' - pan left\n"); + printf("'right' - pan right\n"); + printf("'up' - pan up\n"); + printf("'down' - pan down\n"); + printf("'t' - toggle texture memory display\n"); + printf("'g' - toggle grid\n"); + printf("'x' - toggle auto pan\n"); + printf("'z' - toggle zoom\n"); +} + +static void +gfunc(void) { + grid ^= 1; +} + +static void +tfunc(void) { + texture ^= 1; +} + +static void anim(void); + +static void +xfunc(void) { + static int state; + glutIdleFunc((state ^= 1) ? anim : NULL); +} + +static void +zfunc(void) { + zoom ^= 1; +} + +#define CLAMP(v) { int w = TSIZE/2; \ + if (v < w) v = w; \ + else if (v > TILES*TILESIZE-w) v = TILES*TILESIZE-w; } +static void +up(void) { + y += 8; + CLAMP(y); +} + +static void +pfunc(void) { + static int delta = -1; + int xx = x + delta; + x += delta; CLAMP(x); + y += delta; CLAMP(y); + if (x != xx) delta = -delta; +} + +static void +down(void) { + y -= 8; + CLAMP(y); +} + +static void +right(void) { + x += 8; + CLAMP(x); +} + +static void +left(void) { + x -= 8; + CLAMP(x); +} + +static void +anim(void) { + static int delta = -1; + int xx = x + delta; + x += delta; + CLAMP(x); + y += delta; + CLAMP(y); + if (x != xx) delta = -delta; + glutPostRedisplay(); +} + + +static void +loadtiles(void) { + int lx, rx, ty, by; /* image bounding box */ + static int ox = TILES*TILESIZE/2, oy = TILES*TILESIZE/2; /* image origin */ + static int ot = 0, os = 0; + int dx = 0, dy = 0, nx = -1, ny = -1; + float trx, try; +#define S_TSIZE (TSIZE-TILESIZE) /* visible portion of texture = TSIZE less one tile for slop */ + + /* calculate tile #'s at corners of visible region */ + lx = x - S_TSIZE/2; + rx = lx + S_TSIZE; + by = y - S_TSIZE/2; + ty = by + S_TSIZE; + lx /= TILESIZE; rx /= TILESIZE; + by /= TILESIZE; ty /= TILESIZE; + + dx = ((x - S_TSIZE/2)/TILESIZE) - ((ox - S_TSIZE/2)/TILESIZE); + + nx = lx; ny = by; + if (dx < 0) { + /* add on left */ + os -= TILESIZE; + if (os < 0) os += TSIZE; + nx = lx; + } else if (dx > 0) { + nx = rx; + } + + dy = ((y - S_TSIZE/2) / TILESIZE) - ((oy - S_TSIZE/2) / TILESIZE); + if (dy > 0) { + /* add on bottom */ + ny = ty; + } else if (dy < 0) { + /* add on top */ + ot -= TILESIZE; + if (ot < 0) ot += TSIZE; + ny = by; + } +if (dx || dy) printf("dx %d dy %d lx %d rx %d by %d ty %d nx %d ny %d os %d ot %d\n", dx, dy, lx, rx, by, ty, nx, ny, os, ot); + if (dx) { + int t; + for(t = 0; t < TSIZE; t += TILESIZE) { + glTexSubImage2D(GL_TEXTURE_2D, 0, os, (t+ot) % TSIZE, TILESIZE, + TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE, + tiles[ny+t/TILESIZE][nx].data); +printf("load %d %d %d %d\n", nx, ny+t/TILESIZE, os, (t+ot) % TSIZE); + } + } + + if (dy) { + int s; + for(s = 0; s < TSIZE; s += TILESIZE) { + glTexSubImage2D(GL_TEXTURE_2D, 0, (s+os) % TSIZE, ot, TILESIZE, + TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE, + tiles[ny][nx+s/TILESIZE].data); +printf("load %d %d %d %d\n", nx+s/TILESIZE, ny, (s+os) % TSIZE, ot); + } + } + if (dx > 0) { + os += TILESIZE; + if (os >= TSIZE) os -= TSIZE; + } + if (dy > 0) { + ot += TILESIZE; + if (ot >= TSIZE) ot -= TSIZE; + } + ox = x; oy = y; + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + trx = (float)((x-TILES*TILESIZE/2) % TSIZE)/TSIZE; + try = (float)((y-TILES*TILESIZE/2) % TSIZE)/TSIZE; + glTranslatef(trx, try, 0.f); + glMatrixMode(GL_MODELVIEW); +} + +static void +init(char *filename) { + int i; + + mesh0(-1.f,1.f,-1.f,1.f,0.f,1.f,0.f,1.f,0.f,64,64); + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components < 3 || components > 4) { + printf("must be RGB or RGBA image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + components = 4; width = height = TSIZE; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + if (i & 1) + image[i+j*width] = 0xff; + else + image[i+j*width] = 0xff00; + if (j&1) + image[i+j*width] |= 0xff0000; + } + + } + if (width % TILESIZE || height % TILESIZE) { +#define TXSIZE 192 + unsigned *newimage = malloc(TXSIZE*TXSIZE*sizeof *newimage); + gluScaleImage(GL_RGBA, width, height, GL_UNSIGNED_BYTE, image, + TXSIZE, TXSIZE, GL_UNSIGNED_BYTE, newimage); + free(image); + image = newimage; width = height = TXSIZE; components = 4; + } + tile_image(image); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TSIZE, + TSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + for(i = 0; i < TILES; i++) { + int j; + for(j = 0; j < TILES; j++) { + glTexSubImage2D(GL_TEXTURE_2D, 0, i*TILESIZE, j*TILESIZE, TILESIZE, + TILESIZE, GL_RGBA, GL_UNSIGNED_BYTE, + tiles[(TILES-TSIZE/TILESIZE)/2+j][(TILES-TSIZE/TILESIZE)/2+i].data); + } + } + glEnable(GL_TEXTURE_2D); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.,1.,.1,10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-1.0); + glLineWidth(3.0); + glClearColor(.25, .25, .25, .25); + + /* start at center of image */ + x = TILES*TILESIZE/2; + y = TILES*TILESIZE/2; +} + +void +showgrid(void) { + GLfloat mat[16]; + int i; + + glPushMatrix(); + glDisable(GL_TEXTURE_2D); + glPushMatrix(); + glColor3f(0.f, 0.f, 0.f); + if (!zoom) glScalef(1.f/1.5f, 1.f/1.5f, 1.f); + glBegin(GL_LINE_LOOP); + glVertex2f(-1.f,-1.f); + glVertex2f(-1.f, 1.f); + glVertex2f( 1.f, 1.f); + glVertex2f( 1.f,-1.f); + glEnd(); + glPopMatrix(); + + glGetFloatv(GL_TEXTURE_MATRIX,mat); + glPushMatrix(); + if (zoom) glScalef(1.5f,1.5f,1.f); + glTranslatef(-1.f,-1.f,-1.f); + glScalef(2.f,2.f,1.f); + glTranslatef(-mat[12], -mat[13], 1.0f); +#if 1 + glColor3f(1.f,1.f,1.f); +#else + glColor3f(1.f,0.f,0.f); +#endif + glBegin(GL_LINES); + for(i = -TSIZE; i <= 2*TSIZE; i+=TILESIZE) { + GLfloat x = (GLfloat)i/(GLfloat)TSIZE; + glVertex2f(-1.f,x); + glVertex2f(2.f,x); + glVertex2f(x,-1.f); + glVertex2f(x,2.f); + } + glEnd(); + glPopMatrix(); + glEnable(GL_TEXTURE_2D); + glPopMatrix(); +} + +static void +drawtexture(void) { + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + glColor3f(1.f,1.f,1.f); + glBegin(GL_QUADS); + glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f); + glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f); + glTexCoord2f(1.f, 1.f); glVertex2f( 1.f, 1.f); + glTexCoord2f(1.f, 0.f); glVertex2f( 1.f, -1.f); + glEnd(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +static void +display(void) { + glClear(GL_COLOR_BUFFER_BIT); + loadtiles(); + if (texture) { + drawtexture(); + } else { + drawmesh(64,64); + if (grid) showgrid(); + } + glutSwapBuffers(); +} + +static void +reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +static void +key(unsigned char key, int x, int y) { + switch(key) { + case 'h': help(); break; + case 'g': gfunc(); break; + case 't': tfunc(); break; + case 'z': zfunc(); break; + case 'x': xfunc(); break; + case 'p': pfunc(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED1*/ +static void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } + glutPostRedisplay(); +} + +int main(int argc, char* argv[]) { + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argv[1] ? argv[1] : "../data/fendi.rgb"); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/texpage.dsp b/lib/glut-3.7.6/progs/advanced97/texpage.dsp new file mode 100644 index 0000000000..b3502b33d1 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texpage.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="texpage" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=texpage - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "texpage.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texpage.mak" CFG="texpage - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texpage - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "texpage - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texpage - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "texpage - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "texpage - Win32 Release" +# Name "texpage - Win32 Debug" +# Begin Source File + +SOURCE=.\texpage.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/textile.c b/lib/glut-3.7.6/progs/advanced97/textile.c new file mode 100644 index 0000000000..1b60f3092f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/textile.c @@ -0,0 +1,365 @@ +/* +** cc -o textile textile.c -lGLU -lGL -lglut -lXmu -lX11 -lm +*/ +#include +#include +#include +#include +#include +#include "texture.h" + +int maxTextureSize; +int maxTextureLevel; + +int imageWidth, imageHeight; +GLubyte *imageData; + +int texWidthLevel0, texHeightLevel0; +int texWidthTiles, texHeightTiles; +GLubyte **texImageLevel; + +GLboolean useBorder = GL_TRUE; +GLboolean useClamp = GL_TRUE; +GLboolean useLinear = GL_TRUE; +GLboolean useMipmap = GL_TRUE; +GLboolean useTextureTiling = GL_TRUE; + +/* (int)floor(log2(a)) */ +static int +iflog2(unsigned int a) +{ + int x = 0; + while (a >>= 1) ++x; + return x; +} + +static void +initialize(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-0.5, 0.5, -0.5, 0.5, 0.5, 1.5); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -0.90); + glRotatef( 45.0, 0, 1, 0); + glTranslatef(-0.5, -0.5, 0.0); + +#if 0 + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); +#else + maxTextureSize = 32; +#endif + maxTextureLevel = iflog2(maxTextureSize); + + texImageLevel = (GLubyte **) calloc(maxTextureLevel+1, sizeof(GLubyte *)); + if (texImageLevel == NULL) { + fprintf(stderr, "texture level image allocation failed\n"); + exit(EXIT_FAILURE); + } + glClearColor(0.1, 0.1, 0.1, 0.1); +} + +static void +imgLoad(char *filename_in, int *w_out, int *h_out, GLubyte **img_out) +{ + int comp; + + *img_out = (GLubyte *)read_texture(filename_in, w_out, h_out, &comp); + if (img_out == NULL) { + fprintf(stderr, "unable to read %s\n", filename_in); + exit(EXIT_FAILURE); + } + if (comp != 3 && comp != 4) { + fprintf(stderr, "%s: image is not RGB or RGBA\n", filename_in); + exit(EXIT_FAILURE); + } +} + +static void +buildMipmaps(void) +{ + int level, levelWidth, levelHeight; + + if (useTextureTiling) { + int width2 = iflog2(imageWidth); + int height2 = iflog2(imageHeight); + + width2 = (width2 > maxTextureLevel) ? width2 : maxTextureLevel; + height2 = (height2 > maxTextureLevel) ? height2 : maxTextureLevel; + + texWidthLevel0 = 1 << width2; + texHeightLevel0 = 1 << height2; + texWidthTiles = texWidthLevel0 >> maxTextureLevel; + texHeightTiles = texHeightLevel0 >> maxTextureLevel; + } else { + texWidthLevel0 = maxTextureSize; + texHeightLevel0 = maxTextureSize; + texWidthTiles = 1; + texHeightTiles = 1; + } + + texImageLevel[0] = (GLubyte *) + calloc(1, (texWidthLevel0+2)*(texHeightLevel0+2)*4*sizeof(GLubyte)); + + glPixelStorei(GL_PACK_ROW_LENGTH, texWidthLevel0+2); + glPixelStorei(GL_PACK_SKIP_PIXELS, 1); + glPixelStorei(GL_PACK_SKIP_ROWS, 1); + + gluScaleImage(GL_RGBA, imageWidth, imageHeight, + GL_UNSIGNED_BYTE, imageData, + texWidthLevel0, texHeightLevel0, + GL_UNSIGNED_BYTE, texImageLevel[0]); + + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 1); + + levelWidth = texWidthLevel0; + levelHeight = texHeightLevel0; + for (level=0; level 1) ? levelWidth / 2 : 1; + int newLevelHeight = (levelHeight > 1) ? levelHeight / 2 : 1; + + texImageLevel[level+1] = (GLubyte *) + calloc(1, (newLevelWidth+2)*(newLevelHeight+2)*4*sizeof(GLubyte)); + + glPixelStorei(GL_PACK_ROW_LENGTH, newLevelWidth+2); + glPixelStorei(GL_UNPACK_ROW_LENGTH, levelWidth+2); + + gluScaleImage(GL_RGBA, levelWidth, levelHeight, + GL_UNSIGNED_BYTE, texImageLevel[level], + newLevelWidth, newLevelHeight, + GL_UNSIGNED_BYTE, texImageLevel[level+1]); + + levelWidth = newLevelWidth; + levelHeight = newLevelHeight; + } + + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); +} + +static void +freeMipmaps(void) +{ + int i; + + for (i=0; i<=maxTextureLevel; ++i) { + if (texImageLevel[i] != NULL) { + free(texImageLevel[i]); + texImageLevel[i] = NULL; + } + } +} + +static void +loadTile(int row, int col) +{ + int border = useBorder ? 1 : 0; + int level, levelWidth, levelHeight; + + levelWidth = texWidthLevel0; + levelHeight = texHeightLevel0; + for (level=0; level<=maxTextureLevel; ++level) { + int tileWidth = levelWidth / texWidthTiles; + int tileHeight = levelHeight / texHeightTiles; + int skipPixels = col * tileWidth + (1 - border); + int skipRows = row * tileHeight + (1 - border); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, levelWidth+2); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skipPixels); + glPixelStorei(GL_UNPACK_SKIP_ROWS, skipRows); + + glTexImage2D(GL_TEXTURE_2D, level, 4, + tileWidth + 2*border, tileHeight + 2*border, + border, GL_RGBA, GL_UNSIGNED_BYTE, texImageLevel[level]); + + if (levelWidth > 1) levelWidth = levelWidth / 2; + if (levelHeight > 1) levelHeight = levelHeight / 2; + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); +} + +static void +redraw(void) +{ + GLenum minFilterMode, magFilterMode, wrapMode; + char *minFilterName, *magFilterName, *wrapName; + int i, j; + + if (useLinear) { + if (useMipmap) { + minFilterMode = GL_LINEAR_MIPMAP_LINEAR; + minFilterName = "LINEAR_MIPMAP_LINEAR"; + } else { + minFilterMode = GL_LINEAR; + minFilterName = "LINEAR"; + } + magFilterMode = GL_LINEAR; + magFilterName = "LINEAR"; + } else { + if (useMipmap) { + minFilterMode = GL_NEAREST_MIPMAP_LINEAR; + minFilterName = "NEAREST_MIPMAP_LINEAR"; + } else { + minFilterMode = GL_NEAREST; + minFilterName = "NEAREST"; + } + magFilterMode = GL_NEAREST; + magFilterName = "NEAREST"; + } + + if (useClamp) { + wrapMode = GL_CLAMP; + wrapName = "CLAMP"; + } else { + wrapMode = GL_REPEAT; + wrapName = "REPEAT"; + } + + fprintf(stderr, "tile(%s) ", useTextureTiling ? "yes" : "no"); + fprintf(stderr, "border(%s) ", useBorder ? "yes" : "no"); + fprintf(stderr, "filter(%s, %s) ", minFilterName, magFilterName); + fprintf(stderr, "wrap(%s) ", wrapName); + fprintf(stderr, "\n"); + + glClear(GL_COLOR_BUFFER_BIT); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilterMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilterMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + + buildMipmaps(); + + glEnable(GL_TEXTURE_2D); + + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=textile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "textile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "textile.mak" CFG="textile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "textile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "textile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "textile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "textile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "textile - Win32 Release" +# Name "textile - Win32 Debug" +# Begin Source File + +SOURCE=.\textile.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/texture.c b/lib/glut-3.7.6/progs/advanced97/texture.c new file mode 100644 index 0000000000..e3d28c0906 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texture.c @@ -0,0 +1,256 @@ +#include +#include +#include + +void +bwtorgba(unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = 0xff; + l += 4; b++; + } +} + +void +latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = *a; + l += 4; b++; a++; + } +} + +void +rgbtorgba(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] = 0xff; + l += 4; r++; g++; b++; + } +} + +void +rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l[3] = a[0]; + l += 4; r++; g++; b++; a++; + } +} + +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, *tmpR, *tmpG, *tmpB; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +static void +ConvertShort(unsigned short *array, long length) { + unsigned b1, b2; + unsigned char *ptr; + + ptr = (unsigned char *)array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + *array++ = (b1 << 8) | (b2); + } +} + +static void +ConvertLong(unsigned *array, long length) { + unsigned 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(const 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) { + perror(fileName); + exit(1); + } + + fread(image, 1, 12, image->file); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + image->tmp = (unsigned char *)malloc(image->xsize*256); + image->tmpR = (unsigned char *)malloc(image->xsize*256); + image->tmpG = (unsigned char *)malloc(image->xsize*256); + image->tmpB = (unsigned char *)malloc(image->xsize*256); + if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL || + image->tmpB == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + + if ((image->type & 0xFF00) == 0x0100) { + x = image->ysize * image->zsize * sizeof(unsigned); + image->rowStart = (unsigned *)malloc(x); + image->rowSize = (int *)malloc(x); + if (image->rowStart == NULL || image->rowSize == NULL) { + fprintf(stderr, "Out 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) { + ConvertLong(image->rowStart, x/(int)sizeof(unsigned)); + ConvertLong((unsigned *)image->rowSize, x/(int)sizeof(int)); + } + } + return image; +} + +static void +ImageClose(ImageRec *image) { + fclose(image->file); + free(image->tmp); + free(image->tmpR); + free(image->tmpG); + free(image->tmpB); + 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); + } +} + +unsigned * +read_texture(char *name, int *width, int *height, int *components) { + unsigned *base, *lptr; + unsigned char *rbuf, *gbuf, *bbuf, *abuf; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if(!image) + return NULL; + (*width)=image->xsize; + (*height)=image->ysize; + (*components)=image->zsize; + base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned)); + 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) + return NULL; + lptr = 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); + rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==3) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==2) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,abuf,y,1); + latorgba(rbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else { + ImageGetRow(image,rbuf,y,0); + bwtorgba(rbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } + } + ImageClose(image); + free(rbuf); + free(gbuf); + free(bbuf); + free(abuf); + + return (unsigned *) base; +} diff --git a/lib/glut-3.7.6/progs/advanced97/texture.dsp b/lib/glut-3.7.6/progs/advanced97/texture.dsp new file mode 100644 index 0000000000..876c7f0f34 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texture.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="texture" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=texture - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "texture.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "texture.mak" CFG="texture - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "texture - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "texture - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "texture - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "texture - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "texture - Win32 Release" +# Name "texture - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/texture.h b/lib/glut-3.7.6/progs/advanced97/texture.h new file mode 100644 index 0000000000..34012bdf3b --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/texture.h @@ -0,0 +1,16 @@ +/* + * read_texture() - read in an image file in SGI 'libimage' format + * currently its very simple minded and converts all images + * to RGBA8 regardless of the input format and returns the + * original number of components in the appropriate parameter. + * + * + * the components are converted as follows + * L -> LLL 1.0 + * LA -> LLL A + * RGB -> RGB 1.0 + * RGBA -> RGB A + * + */ +unsigned * +read_texture(const char *name, int *width, int *height, int *components); diff --git a/lib/glut-3.7.6/progs/advanced97/underwater.c b/lib/glut-3.7.6/progs/advanced97/underwater.c new file mode 100644 index 0000000000..4727f5a032 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/underwater.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define expf(x) ((float)exp((x))) +#define sinf(x) ((float)sin((x))) +#endif + +static float transx = 1.0, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +#define PAN 1 +#define ROT 2 + +void +pan(const int x, const int y) { + transx += (x-ox)/5.; + transy -= (y-oy)/5.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(const int x, const int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +static GLfloat s_plane[4] = { 1.0, 0., 0., 0.}; +static GLfloat t_plane[4] = { 0., 0., 1.0, 0.}; +static GLfloat fog_params[5] = {.015, .1, .2, .2, .1}; + +void init(void) { + int width, height, components; + GLubyte *image; + + glClearColor (0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + + if (!(image = (GLubyte *)read_texture("../data/sea.rgb", &width, &height, &components))) { + perror("sea.rgb"); + exit(EXIT_FAILURE); + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + 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_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_S, GL_EYE_PLANE, s_plane); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_T, GL_EYE_PLANE, t_plane); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_2D); + 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); + + glClearColor(.09f,.18f,.18f,1.f); + + glFogi(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, fog_params[0]); + glFogfv(GL_FOG_COLOR, fog_params+1); + glEnable(GL_FOG); + { + GLfloat pos[] = {0.,150.,1.,1.}; + glLightfv(GL_LIGHT0, GL_POSITION, pos); + } +} + +void display(void) { + GLfloat s, t; + static float phase; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + s = sinf(phase); t = s; phase += M_PI/25.f; + if (phase > 2*M_PI) phase -= 2*M_PI; + glTranslatef(.5f, -0.5f, 0.f); + glScalef(.1f, .1f, 1.f); + glTranslatef(s, t, 0.f); + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + glColor4f(.09, .18, .18, 1.f); + glDisable(GL_TEXTURE_2D); + glTranslatef(0., 0., -160.); + glScalef(200., 200., 1.); + glBegin(GL_POLYGON); + glVertex3f(-1.,-1.,0.); + glVertex3f( 1.,-1.,0.); + glVertex3f( 1., 1.,0.); + glVertex3f(-1., 1.,0.); + glEnd(); + glPopMatrix(); + glPushMatrix(); + glEnable(GL_TEXTURE_2D); + glTranslatef(0., 0., -100.+transx); + glRotatef(rotx, 0.0, 1.0, 0.0); + glScalef(10.f, 10.f, 10.f); + glutSolidTeapot(2.0); + glPopMatrix (); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40., 1.0, 10.0, 200000.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void ffunc(void) { + static int state = 1; + if (state ^= 1) + glEnable(GL_FOG); + else + glDisable(GL_FOG); +} + +void help(void) { + printf("Usage: smoke [image]\n"); + printf("'h' - help\n"); + printf("'f' - toggle fog\n"); + printf("left mouse - pan\n"); + printf("right mouse - rotate\n"); +} + +/*ARGSUSED1*/ +void key (unsigned char key, int x, int y) { + switch (key) { + case 'f': ffunc(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } +} + +void animate(void) { + glutPostRedisplay(); +} + +int main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(100, 100); + glutCreateWindow (argv[0]); + init(); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutIdleFunc(animate); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/underwater.dsp b/lib/glut-3.7.6/progs/advanced97/underwater.dsp new file mode 100644 index 0000000000..4f42b32ec9 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/underwater.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="underwater" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=underwater - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "underwater.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "underwater.mak" CFG="underwater - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "underwater - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "underwater - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "underwater - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "underwater - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "underwater - Win32 Release" +# Name "underwater - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\underwater.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/usespheremap.c b/lib/glut-3.7.6/progs/advanced97/usespheremap.c new file mode 100644 index 0000000000..81ff5c2bf8 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/usespheremap.c @@ -0,0 +1,252 @@ +#include +#include +#include +#include +#include +#include +#include "texture.h" + +#ifndef __sgi +#define trunc(x) ((double)((int)(x))) +#endif + +GLsizei sphereTexW, sphereTexH, padSphereTexW, padSphereTexH; +GLint sphereTexComp; + + +const char defaultSphereMap[] = "../data/spheremap.rgb"; +int drawTorus = 1; + + +int roundup(int n) +{ + int val = 1; + while (val < n) val <<= 1; + return val; +} + +void create_texture(const char *fname, GLsizei *w, GLsizei *h, + GLsizei *padW, GLsizei *padH, GLint *comps) +{ + GLuint *img, *padImg = NULL; + int y; + + img = read_texture(fname, w, h, comps); + if (!img) { + fprintf(stderr, "Could not open %s\n", fname); + exit(1); + } + + /* if width & height are not powers of two, pad image with black */ + if (*w & (*w - 1)) { + *padW = roundup(*w); + } else { + *padW = *w; + } + if (*h & (*h - 1)) { + *padH = roundup(*h); + } else { + *padH = *h; + } + + if (*padW != *w || *padH != *h) { +printf("rounding %s up...\n", fname); + padImg = (GLuint *)malloc(*padW * *padH * sizeof(GLuint)); + if (!padImg) { + fprintf(stderr, "Malloc of %d bytes failed.\n", + *padW * *padH * sizeof(GLuint)); + exit(1); + } + memset(padImg, 0, *padW * *padH * sizeof(GLuint)); + for (y = 0; y < *h; y++) { + memcpy(&padImg[y * *padW], &img[y * *w], *w * sizeof(GLuint)); + } + } + + /* you should use texture objects here if your system supports them... */ +printf("w = %d h = %d\n", *padW, *padH); + glTexImage2D(GL_TEXTURE_2D, 0, 4, *padW, *padH, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img); + + free(img); + if (padImg) free(padImg); +} + +void init(const char *sphereFile) +{ + static GLfloat lightpos[] = {.5, .75, 1.5, 1}; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + create_texture(sphereFile, &sphereTexW, &sphereTexH, + &padSphereTexW, &padSphereTexH, &sphereTexComp); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, 1, .01, 10); + gluLookAt(0, 0, 0, + 0, 0, -1, + 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void draw_room(void) +{ + /* material for the walls, floor, ceiling */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + glBegin(GL_QUADS); + + /* floor */ + glNormal3f(0, 1, 0); + glVertex3f(-1, -1, 1); + glVertex3f(1, -1, 1); + glVertex3f(1, -1, -1); + glVertex3f(-1, -1, -1); + + /* ceiling */ + glNormal3f(0, -1, 0); + glVertex3f(-1, 1, -1); + glVertex3f(1, 1, -1); + glVertex3f(1, 1, 1); + glVertex3f(-1, 1, 1); + + /* left wall */ + glNormal3f(1, 0, 0); + glVertex3f(-1, -1, -1); + glVertex3f(-1, 1, -1); + glVertex3f(-1, 1, 1); + glVertex3f(-1, -1, 1); + + /* right wall */ + glNormal3f(-1, 0, 0); + glVertex3f(1, -1, 1); + glVertex3f(1, 1, 1); + glVertex3f(1, 1, -1); + glVertex3f(1, -1, -1); + + /* far wall */ + glNormal3f(0, 0, 1); + glVertex3f(-1, -1, -1); + glVertex3f(1, -1, -1); + glVertex3f(1, 1, -1); + glVertex3f(-1, 1, -1); + + glEnd(); + +} + +void draw_torus(GLdouble angle) +{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); + + glPushMatrix(); + glTranslatef(0, 0, -3); + glRotatef(angle, 1, 1, 0); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if (drawTorus) { + glutSolidTorus(.4, .75, 32, 32); + } else { + GLUquadricObj *sphere = gluNewQuadric(); + gluSphere(sphere, 1, 32, 32); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glEnable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + + glPopMatrix(); +} + +GLdouble get_secs(void) +{ + return glutGet(GLUT_ELAPSED_TIME) / 1000.0; +} + +void draw(void) +{ + GLenum err; + GLdouble secs, degrees; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* one revolution every 10 seconds... */ + secs = get_secs(); + secs = secs - 10.*trunc(secs / 10.); + degrees = (secs/10.) * (360.); + +#if 0 + draw_room(); +#endif + draw_torus(degrees); + + err = glGetError(); + if (err != GL_NO_ERROR) printf("Error: %s\n", gluErrorString(err)); + + glutSwapBuffers(); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + static int idle = 1; + if (key == 27) exit(0); + if (key == 'o' || key == 'O') { + drawTorus = (drawTorus == 0); + draw(); + } else { + if (idle) { + glutIdleFunc(0); + } else { + glutIdleFunc(draw); + } + idle = (idle == 0); + } +} + +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(256, 256); + glutInitWindowPosition(0, 0); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(argv[0]); + glutDisplayFunc(draw); + glutIdleFunc(draw); + glutKeyboardFunc(key); + glutReshapeFunc(reshape); + init(defaultSphereMap); + + glutMainLoop(); + return 0; +} + diff --git a/lib/glut-3.7.6/progs/advanced97/usespheremap.dsp b/lib/glut-3.7.6/progs/advanced97/usespheremap.dsp new file mode 100644 index 0000000000..ce04921b3c --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/usespheremap.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="usespheremap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=usespheremap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "usespheremap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "usespheremap.mak" CFG="usespheremap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "usespheremap - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "usespheremap - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "usespheremap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "usespheremap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "usespheremap - Win32 Release" +# Name "usespheremap - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\usespheremap.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/vapor.c b/lib/glut-3.7.6/progs/advanced97/vapor.c new file mode 100644 index 0000000000..f51625849d --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/vapor.c @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the trig functions. */ +#define sinf sin +#define cosf cos +#define atan2f atan2 +#endif + + +/* taken from skyfly */ +static float paper_plane_vertexes[] = { +/*Nx Ny Nz Vx Vy Vz */ +/* ---------------------------- Top view of plane, middle stretched open */ + 0.2, 0., .98, -.10, 0, .02,/* vertex #'s 4 (.48,0,-.06) */ + 0., 0., 1., -.36, .20, -.04,/* . */ + 0., 0., 1., .36, .01, 0,/* ... */ + 0., 0.,-1., -.32, .02, 0,/* . +X */ + 0., 1., 0., .48, 0, -.06,/* 2 . 6,8 ^ */ + 0., 1., 0., -.30, 0, -.12,/* . . . | */ + 0.,-1., 0., .36, -.01, 0,/* .. . .. | */ + 0.,-1., 0., -.32, -.02, 0,/* . . . | */ + 0., 0.,-1., .36, -.01, 0,/* . . . . . +Y<-----* */ + 0., 0.,-1., -.36, -.20, -.04,/* . . . for this picture */ + -0.2, 0., .98, -.10, 0, .02,/* . . . . . coord system rot. */ + -0.2, 0., -.98, -.10, 0, .02,/* . . . 90 degrees */ + 0., 0., -1., -.36, .20, -.04,/* . . . . . */ + 0., 0., -1., .36, .01, 0,/* . # . # marks */ + 0., 0., 1., -.32, .02, 0,/* . . . . . (0,0) origin */ + 0., -1., 0., .48, 0, -.06,/* . . . (z=0 at top */ + 0., -1., 0., -.30, 0, -.12,/* . 0 . 10 . of plane) */ + 0.,1., 0., .36, -.01, 0,/* . . . . . */ + 0.,1., 0., -.32, -.02, 0,/* . . . . . . . */ + 0., 0.,1., .36, -.01, 0,/* . . . . . */ + 0., 0.,1., -.36, -.20, -.04,/* 1.......3.5.7.......9 */ + 0.2, 0., -.98, -.10, 0, .02,/* (-.36,.2,-.04) */ +}; + +#define MAX_TIME (2*196) +#define MAX_VAPOR 1024 +int vapors = 0; +static struct vapor { + float x, y, z; + int time; + float size; +} vapor[MAX_VAPOR]; + +static float ttrans[2]; +static float scale = 1.; +static float transx, transy, rotx, roty; +static int ox = -1, oy = -1; +static int show_t = 0; +static int mot; +#define PAN 1 +#define ROT 2 + +static int _time = 1; +static float _x = -1.; +static float _y = .75; + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void toggle_t(void) { + show_t ^= 1; +} + +void wire(void) { + static int w; + if (w ^= 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void light(void) { + static int l; + if (l ^= 1) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); +} + +void up(void) { scale += .1; } +void down(void) { scale -= .1; } + +void +draw_plane(void) { + glEnable(GL_LIGHTING); + glShadeModel(GL_FLAT); + glRotatef(-120.f, 1.f, 0.f, 0.f); +#define nv(p) glNormal3fv(paper_plane_vertexes+6*p); glVertex3fv(paper_plane_vertexes+6*p+3) + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + glBegin(GL_TRIANGLE_STRIP); + nv(0); nv(1); nv(2); nv(3); nv(4); nv(5); nv(6); nv(7); nv(8); nv(9); nv(10); + glEnd(); + glCullFace(GL_BACK); + glBegin(GL_TRIANGLE_STRIP); + nv(11); nv(12); nv(13); nv(14); nv(15); nv(16); nv(17); nv(18); nv(19); nv(20); nv(21); + glEnd(); + glDisable(GL_CULL_FACE); + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); +#undef nv +} + +void +add_vapor(void) { + int i; + /* garbage collect */ + for(i = 0; i < vapors; i++) + if (_time - vapor[i].time > MAX_TIME) { + memcpy(vapor+i, vapor+i+1, (vapors-i-1)*sizeof vapor[0]); + vapors--; + } + if (vapors >= MAX_VAPOR) { + printf("max_vapors\n"); + return; + } + vapor[vapors].time = _time; + vapor[vapors].x = -.6f + _x; + vapor[vapors].y = _y; + vapor[vapors].z = 0.f; + vapor[vapors].size = 1.f; + vapors++; + if (_x > 8.5) { + _y = .75f; + _x = -2.f; + vapors = 0; + } +} + +void +animate(void) { + static int cnt = 0; + ttrans[0] += .01; + if (ttrans[0] == 1.0) ttrans[0] = 0; + ttrans[1] += .005; + if (ttrans[1] == 1.0) ttrans[1] = 0; + _y -= .01f; + _x +=.025f; + if (cnt++ & 1) add_vapor(); + _time++; + glutPostRedisplay(); +} + +void help(void) { + printf("Usage: vapor [image]\n"); + printf("'h' - help\n"); + printf("'l' - toggle lighting\n"); + printf("'t' - toggle wireframe\n"); + printf("'UP' - scale up\n"); + printf("'DOWN' - scale down\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void init(char *filename) { + static GLfloat plane_mat[] = { 1.f, 1.f, .2f, 1.f }; + static unsigned *image; + static int width, height, components, i; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components != 2 && components != 4) { + printf("must be an rgba or la image\n"); + exit(EXIT_FAILURE); + } + for(i = 0; i < width*height; i++) + image[i] = image[i] | 0xffffff00; + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + + glEnable(GL_LIGHT0); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, plane_mat); + + glClearColor(0.1, 0.1, 0.6, 1.0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0./255.); + + glEnable(GL_DEPTH_TEST); +} + +void +draw_vapor(void) { + int i; + float intensity = .9f; + float t; + struct vapor *v; + + glDepthMask(0); + glEnable(GL_TEXTURE_2D); + + for(i = 0; i < vapors; i++) { + v = vapor+i; + t = _time - v->time; + + glPushMatrix(); + glTranslatef(v->x, v->y, v->z); + glScalef(.5*(t+40)/MAX_TIME, .5*(t+40)/MAX_TIME, 1.); + glColor4f(intensity,intensity,intensity,10./(t+0.f)); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1., -1., -0.); + glTexCoord2f(0, 1); glVertex3f(-1., 1., 0.); + glTexCoord2f(1, 1); glVertex3f( 1., 1., 0.); + glTexCoord2f(1, 0); glVertex3f( 1., -1., -0.); + glEnd(); + if (show_t) { + glDisable(GL_TEXTURE_2D); + glColor4f(0.,0.,0.,1.0); + glBegin(GL_LINE_LOOP); + glVertex3f(-1., -1., -0.); + glVertex3f(-1., 1., 0.); + glVertex3f( 1., 1., 0.); + glVertex3f( 1., -1., -0.); + glEnd(); + glEnable(GL_TEXTURE_2D); + } + glPopMatrix(); + } + glDisable(GL_TEXTURE_2D); + glDepthMask(1); +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glPushMatrix(); + glPushMatrix(); + glColor4f(1.f,1.f,.2f,1.f); + glTranslatef(_x, _y+.05f, 0.f); + glScalef(2.f,2.f,2.f); + glRotatef(-10.f, 0.f, 0.f, 1.f); + draw_plane(); + glPopMatrix(); + draw_vapor(); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'l': light(); break; + case 't': toggle_t(); break; + case 'w': wire(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + } +} + +int main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/smoke.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/vapor.dsp b/lib/glut-3.7.6/progs/advanced97/vapor.dsp new file mode 100644 index 0000000000..6d9799dfb7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/vapor.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="vapor" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=vapor - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "vapor.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "vapor.mak" CFG="vapor - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "vapor - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "vapor - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "vapor - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "vapor - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "vapor - Win32 Release" +# Name "vapor - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\vapor.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/volume.c b/lib/glut-3.7.6/progs/advanced97/volume.c new file mode 100644 index 0000000000..c9d39e09f9 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/volume.c @@ -0,0 +1,666 @@ +#include +#include +#include "texture.h" +#include +#include +#include + +/* nonzero if not power of 2 */ +#define NOTPOW2(num) ((num) & (num - 1)) + +int +makepow2(int val) +{ + int power = 0; + if(!val) + return 0; + + while(val >>= 1) + power++; + + return(1 << power); +} + +#define CHECK_ERROR(str) \ +{ \ + GLenum error; \ + if(error = glGetError()) \ + printf("GL Error: %s (%s)\n", gluErrorString(error), str); \ +} + +enum {X, Y, Z, W}; +enum {R, G, B, A}; +enum {OVER, ATTENUATE, NONE, LASTOP}; /* blend modes */ +/* mouse modes */ +enum {OBJ_ANGLE, SLICES, CUTTING, GEOMXY, GEOMZ, MINBOOST, BOOSTWID, BOOST}; +enum {NOLIST, SPHERE}; /* display list */ + +/* window dimensions */ +int winWidth = 512; +int winHeight = 512; +int active; +int operator = OVER; +GLboolean texture = GL_TRUE; +GLboolean dblbuf = GL_TRUE; +GLboolean cut = GL_FALSE; +GLboolean geom = GL_FALSE; +GLboolean map = GL_FALSE; +GLint cutbias = 50; +int hasBlendColor = 0; +#if defined(_WIN32) && !defined(MESA) +#include +PFNGLBLENDCOLOREXTPROC glBlendColorEXT; +#endif + +GLfloat objangle[2] = {0.f, 0.f}; +GLfloat objpos[3] = {0.f, 0.f, 0.f}; + + +GLfloat minboost = 0.f, boostwid = .03f, boost = 3.f; /* transfer function */ + +/* 3d texture data that's read in */ +/* XXX TODO; make command line arguments */ +int Texwid = 128; /* dimensions of each 2D texture */ +int Texht = 128; +int Texdepth = 69; /* number of 2D textures */ + +/* Actual dimensions of the texture (restricted to max 3d texture size) */ +int texwid, texht, texdepth; +int slices; +GLubyte *tex3ddata; /* pointer to 3D texture data */ + + +GLfloat *lighttex = 0; +GLfloat lightpos[4] = {0.f, 0.f, 1.f, 0.f}; +GLboolean lightchanged[2] = {GL_TRUE, GL_TRUE}; + + +void +reshape(int wid, int ht) +{ + winWidth = wid; + winHeight = ht; + glViewport(0, 0, wid, ht); +} + + +void +motion(int x, int y) +{ + switch(active) + { + case OBJ_ANGLE: + objangle[X] = (x - winWidth/2) * 360./winWidth; + objangle[Y] = (y - winHeight/2) * 360./winHeight; + glutPostRedisplay(); + break; + case SLICES: + slices = x * texwid/winWidth; + glutPostRedisplay(); + break; + case CUTTING: + cutbias = (x - winWidth/2) * 300/winWidth; + glutPostRedisplay(); + break; + case GEOMXY: + objpos[X] = (x - winWidth/2) * 300/winWidth; + objpos[Y] = (winHeight/2 - y) * 300/winHeight; + glutPostRedisplay(); + break; + case GEOMZ: + objpos[Z] = (x - winWidth/2) * 300/winWidth; + glutPostRedisplay(); + break; + case MINBOOST: + minboost = x * .25f/winWidth; + glutPostRedisplay(); + break; + case BOOSTWID: + boostwid = x * .5f/winWidth; + glutPostRedisplay(); + break; + case BOOST: + boost = x * 20.f/winWidth; + glutPostRedisplay(); + break; + } +} + +void +mouse(int button, int state, int x, int y) +{ + if(state == GLUT_DOWN) + switch(button) + { + case GLUT_LEFT_BUTTON: /* rotate the data volume */ + if(map) + active = MINBOOST; + else + active = OBJ_ANGLE; + motion(x, y); + break; + case GLUT_MIDDLE_BUTTON: + if(map) + active = BOOSTWID; + else + if(cut) + active = CUTTING; /* move cutting plane */ + else + active = GEOMXY; /* move geometry */ + motion(x, y); + break; + case GLUT_RIGHT_BUTTON: /* move the polygon */ + if(map) + active = BOOST; + else + if(geom) + active = GEOMZ; + else + active = SLICES; + motion(x, y); + break; + } +} + +/* use pixel path to remap 3D texture data */ +void +remaptex(void) +{ + int i, size; + GLfloat *map; + + glPixelTransferi(GL_MAP_COLOR, GL_TRUE); + + glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &size); + + map = (GLfloat *)malloc(sizeof(GLfloat) * size); + for(i = 0; i < size;i++) + { + map[i] = (GLfloat)i/(size - 1); + if(((GLfloat)i/size > minboost) && + ((GLfloat)i/size < minboost + boostwid)) + { + map[i] *= boost; + } + else + map[i] /= boost; + } + + glPixelMapfv(GL_PIXEL_MAP_R_TO_R, size, map); + glPixelMapfv(GL_PIXEL_MAP_G_TO_G, size, map); + glPixelMapfv(GL_PIXEL_MAP_B_TO_B, size, map); + glPixelMapfv(GL_PIXEL_MAP_A_TO_A, size, map); + +#ifdef GL_EXT_texture3D + glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_LUMINANCE_ALPHA, + texwid, texht, texdepth, + 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex3ddata); +#endif + + glPixelTransferi(GL_MAP_COLOR, GL_FALSE); + free(map); + + CHECK_ERROR("OpenGL Error in remaptex()"); +} + + +GLdouble clipplane0[] = {-1., 0., 0., 100.}; /* x < 100 out */ +GLdouble clipplane1[] = { 1., 0., 0., 100.}; /* x > 100 out */ +GLdouble clipplane2[] = { 0., -1., 0., 100.}; /* y < 100 out */ +GLdouble clipplane3[] = { 0., 1., 0., 100.}; /* y > 100 out */ +GLdouble clipplane4[] = { 0., 0., -1., 100.}; /* z < 100 out */ +GLdouble clipplane5[] = { 0., 0., 1., 100.}; /* z > 100 out */ + +/* define a cutting plane */ +GLdouble cutplane[] = {0.f, -.5f, -2.f, 50.f}; + +/* draw the object unlit without surface texture */ +void redraw(void) +{ + int i; + GLfloat offS, offT, offR; /* mapping texture to planes */ + + offS = 200.f/texwid; + offT = 200.f/texht; + offR = 200.f/texdepth; + + clipplane0[W] = 100.f - offS; + clipplane1[W] = 100.f - offS; + clipplane2[W] = 100.f - offT; + clipplane3[W] = 100.f - offT; + clipplane4[W] = 100.f - offR; + clipplane5[W] = 100.f - offR; + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + if(map) + remaptex(); + + /* GL_MODELVIEW */ + if(cut) + { + cutplane[W] = cutbias; + glClipPlane(GL_CLIP_PLANE5, cutplane); + } + + glPushMatrix(); /* identity */ + glRotatef(objangle[X], 0.f, 1.f, 0.f); + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + glClipPlane(GL_CLIP_PLANE0, clipplane0); + glClipPlane(GL_CLIP_PLANE1, clipplane1); + glClipPlane(GL_CLIP_PLANE2, clipplane2); + glClipPlane(GL_CLIP_PLANE3, clipplane3); + glClipPlane(GL_CLIP_PLANE4, clipplane4); + if(!cut) + glClipPlane(GL_CLIP_PLANE5, clipplane5); + glPopMatrix(); /* back to identity */ + + /* draw opaque geometry here */ + glDisable(GL_CLIP_PLANE0); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE3); + glDisable(GL_CLIP_PLANE4); + if(geom) + { + if(!cut) + glDisable(GL_CLIP_PLANE5); + glPushMatrix(); + glTranslatef(objpos[X], objpos[Y], objpos[Z]); + glCallList(SPHERE); + glPopMatrix(); + } + glMatrixMode(GL_TEXTURE); + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); + glEnable(GL_CLIP_PLANE4); + glEnable(GL_CLIP_PLANE5); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); /* identity */ + glTranslatef( .5f, .5f, .5f); + glRotatef(objangle[Y], 1.f, 0.f, 0.f); + glRotatef(objangle[X], 0.f, 0.f, 1.f); + glTranslatef( -.5f, -.5f, -.5f); + + switch(operator) + { + case OVER: + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case ATTENUATE: +#ifdef GL_EXT_blend_color + if (hasBlendColor){ + glEnable(GL_BLEND); + glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE); + glBlendColorEXT(1.f, 1.f, 1.f, 1.f/slices); + } else +#endif + { + fprintf(stderr, "volume: attenuate not supported!\n"); + } + break; + case NONE: + /* don't blend */ + break; + } + + if(texture) { +#ifdef GL_EXT_texture3D + glEnable(GL_TEXTURE_3D_EXT); +#endif + } else { +#ifdef GL_EXT_texture3D + glDisable(GL_TEXTURE_3D_EXT); +#endif + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + } + + + + for(i = 0; i < slices; i++) + { + glBegin(GL_QUADS); + glVertex3f(-100.f, -100.f, + -100.f + offR + i * (200.f - 2 * offR)/(slices - 1)); + glVertex3f( 100.f, -100.f, + -100.f + offR + i * (200.f - 2 * offR)/(slices - 1)); + glVertex3f( 100.f, 100.f, + -100.f + offR + i * (200.f - 2 * offR)/(slices - 1)); + glVertex3f(-100.f, 100.f, + -100.f + offR + i * (200.f - 2 * offR)/(slices - 1)); + glEnd(); + } +#ifdef GL_EXT_texture3D + glDisable(GL_TEXTURE_3D_EXT); +#endif + if(!texture) + { + glDisable(GL_LIGHTING); + } + glDisable(GL_BLEND); + + glPopMatrix(); /* back to identity */ + glMatrixMode(GL_MODELVIEW); + + if(operator == ATTENUATE) + { + glPixelTransferf(GL_RED_SCALE, 3.f); /* brighten image */ + glPixelTransferf(GL_GREEN_SCALE, 3.f); + glPixelTransferf(GL_BLUE_SCALE, 3.f); + glCopyPixels(0, 0, winWidth, winHeight, GL_COLOR); + } + if(dblbuf) + glutSwapBuffers(); + else + glFlush(); + + CHECK_ERROR("OpenGL Error in redraw()"); +} + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) + { + case 'm': /* remap texture values */ + if(map) + { + fprintf(stderr, "remapping off\n"); + map = GL_FALSE; + } + else + { + fprintf(stderr, "remapping on:\n" + "left mouse moves emphasize value\n" + "middle mouse moves emphasize width\n" + "right mouse adjusts gain\n"); + map = GL_TRUE; + } + + remaptex(); + glutPostRedisplay(); + break; + case 'o': + operator++; + if(operator == LASTOP) + operator = OVER; + glutPostRedisplay(); + break; + case 't': + if(texture) + texture = GL_FALSE; + else + texture = GL_TRUE; + glutPostRedisplay(); + break; + case 'c': + if(cut) + { + fprintf(stderr, "cutting plane off\n"); + cut = GL_FALSE; + } + else + { + fprintf(stderr, + "Cutting plane on: " + "middle mouse (horizontal) moves cutting plane\n"); + cut = GL_TRUE; + } + glutPostRedisplay(); + break; + case 'g': /* toggle geometry */ + if(geom) + geom = GL_FALSE; + else + geom = GL_TRUE; + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + case '?': + case 'h': + default: + fprintf(stderr, + "Keyboard Commands\n" + "m - toggle transfer function (remapping)\n" + "o - toggle operator\n" + "t - toggle 3D texturing\n" + "c - toggle cutting plane\n" + "g - toggle geometry\n"); + break; + } +} + +GLubyte * +loadtex3d(int *texwid, int *texht, int *texdepth, int *texcomps) +{ + char *filename; + GLubyte *tex3ddata; + GLuint *texslice; /* 2D slice of 3D texture */ + GLint max3dtexdims; /* maximum allowed 3d texture dimension */ + GLint newval; + int i; + + /* load 3D texture data */ + filename = (char*)malloc(sizeof(char) * strlen("../data/skull/skullXX.la")); + + tex3ddata = (GLubyte *)malloc(Texwid * Texht * Texdepth * + 4 * sizeof(GLubyte)); + for(i = 0; i < Texdepth; i++) + { + sprintf(filename, "../data/skull/skull%d.la", i); + /* read_texture reads as RGBA */ + texslice = read_texture(filename, texwid, texht, texcomps); + memcpy(&tex3ddata[i * Texwid * Texht * 4], /* copy in a slice */ + texslice, + Texwid * Texht * 4 * sizeof(GLubyte)); + free(texslice); + } + free(filename); + + *texdepth = Texdepth; + + max3dtexdims = 0; +#ifdef GL_EXT_texture3D + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &max3dtexdims); +#endif + + /* adjust width */ + newval = *texwid; + if(*texwid > max3dtexdims) + newval = max3dtexdims; + if(NOTPOW2(*texwid)) + newval = makepow2(*texwid); + if(newval != *texwid) + { + glPixelStorei(GL_UNPACK_ROW_LENGTH, *texwid); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, (*texwid - newval)/2); + *texwid = newval; + } + + /* adjust height */ + newval = *texht; + if(*texht > max3dtexdims) + newval = max3dtexdims; + if(NOTPOW2(*texht)) + newval = makepow2(*texht); + if(*texht > newval) + { +#ifdef GL_EXT_texture3D + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT_EXT, *texht); +#endif + glPixelStorei(GL_UNPACK_SKIP_ROWS, (*texht - newval)/2); + *texht = newval; + } + + /* adjust depth */ + newval = *texdepth; + if(*texdepth > max3dtexdims) + newval = max3dtexdims; + if(NOTPOW2(*texdepth)) + newval = makepow2(*texdepth); + if(*texdepth > newval) + { + *texdepth = newval; + } + return tex3ddata; +} + + + +main(int argc, char *argv[]) +{ + int texcomps; + static GLfloat splane[4] = {1.f/200.f, 0.f, 0.f, .5f}; + static GLfloat rplane[4] = {0, 1.f/200.f, 0, .5f}; + static GLfloat tplane[4] = {0, 0, 1.f/200.f, .5f}; + static GLfloat lightpos[4] = {150., 150., 150., 1.f}; + + + glutInit(&argc, argv); + glutInitWindowSize(winWidth, winHeight); + if(argc > 1) + { + char *args = argv[1]; + GLboolean done = GL_FALSE; + while(!done) + { + switch(*args) + { + case 's': /* single buffer */ + printf("Single Buffered\n"); + dblbuf = GL_FALSE; + break; + case '-': /* do nothing */ + break; + case 0: + done = GL_TRUE; + break; + } + args++; + } + } + if(dblbuf) + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); + else + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH); + + (void)glutCreateWindow("volume rendering demo"); + glutDisplayFunc(redraw); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutKeyboardFunc(key); + + /* Initialize OpenGL State */ + + /* draw a perspective scene */ +#if 0 + glMatrixMode(GL_PROJECTION); + /* cube, 300 on a side */ + glFrustum(-150., 150., -150., 150., 300., 600.); + glMatrixMode(GL_MODELVIEW); + /* look at scene from (0, 0, 450) */ + gluLookAt(0., 0., 450., 0., 0., 0., 0., 1., 0.); +#else + glMatrixMode(GL_PROJECTION); + /* cube, 300 on a side */ + glOrtho(-150., 150., -150., 150., -150., 150.); + glMatrixMode(GL_MODELVIEW); +#endif + + glEnable(GL_DEPTH_TEST); +#ifdef GL_EXT_texture3D + glEnable(GL_TEXTURE_3D_EXT); +#endif + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + + glTexGenfv(GL_S, GL_OBJECT_PLANE, splane); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tplane); + glTexGenfv(GL_R, GL_OBJECT_PLANE, rplane); + +#ifdef GL_EXT_texture3D + /* to avoid boundary problems */ + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_CLAMP); +#endif + + glEnable(GL_CLIP_PLANE0); + glEnable(GL_CLIP_PLANE1); + glEnable(GL_CLIP_PLANE2); + glEnable(GL_CLIP_PLANE3); + glEnable(GL_CLIP_PLANE4); + glEnable(GL_CLIP_PLANE5); + + glDisable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + + + tex3ddata = loadtex3d(&texwid, &texht, &texdepth, &texcomps); + + slices = texht; + +#ifdef GL_EXT_texture3D + glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_LUMINANCE_ALPHA, + texwid, texht, texdepth, + 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex3ddata); +#endif + + /* make a display list containing a sphere */ + glNewList(SPHERE, GL_COMPILE); + { + static GLfloat lightpos[] = {150.f, 150.f, 150.f, 1.f}; + static GLfloat material[] = {1.f, .5f, 1.f, 1.f}; + GLUquadricObj *qobj = gluNewQuadric(); + glPushAttrib(GL_LIGHTING_BIT); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material); + gluSphere(qobj, 20.f, 20, 20); + gluDeleteQuadric(qobj); + glPopAttrib(); + } + glEndList(); + + key('?', 0, 0); /* print usage message */ + + CHECK_ERROR("end of main"); + + if(!glutExtensionSupported("GL_EXT_texture3d")) { + fprintf(stderr, + "volume: requires OpenGL texture 3D extension to operate correctly.\n"); + } + hasBlendColor = glutExtensionSupported("GL_EXT_blend_color"); + if(!hasBlendColor) { + fprintf(stderr, + "volume: needs OpenGL blend color extension to attenuate.\n"); +#if defined(_WIN32) && !defined(MESA) + glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC) wglGetProcAddress("glBlendColorEXT"); + if (glBlendColorEXT == NULL) { + hasBlendColor = 0; + } +#endif + } + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/advanced97/volume.dsp b/lib/glut-3.7.6/progs/advanced97/volume.dsp new file mode 100644 index 0000000000..6f861e108f --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/volume.dsp @@ -0,0 +1,89 @@ +# Microsoft Developer Studio Project File - Name="volume" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=volume - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "volume.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "volume.mak" CFG="volume - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "volume - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "volume - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "volume - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "volume - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "volume - Win32 Release" +# Name "volume - Win32 Debug" +# Begin Source File + +SOURCE=.\volume.c +# PROP Exclude_From_Build 1 +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/warp.c b/lib/glut-3.7.6/progs/advanced97/warp.c new file mode 100644 index 0000000000..069da6a5a7 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/warp.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include +#include "texture.h" + +static unsigned *image; +static int width, height, components; +static float incr = .01, dir = 1.0; +static float scale = 1.0, tscale = 1.0, trotx, troty; + +static float transx = 1.0, transy, rotx, roty; +static int ox = -1, oy = -1; +static int mot = 0; +float *wrotx = &rotx, *wroty = &roty, *wscale = &scale; +#define PAN 1 +#define ROT 2 + +void +pan(const int x, const int y) { + transx += (x-ox)/5.; + transy -= (y-oy)/5.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(const int x, const int y) { + *wrotx += x-ox; + if (*wrotx > 360.) *wrotx -= 360.; + else if (*wrotx < -360.) *wrotx += 360.; + *wroty += y-oy; + if (*wroty > 360.) *wroty -= 360.; + else if (*wroty < -360.) *wroty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +#define MAXMESH 64 + +float Ml[4*2*(MAXMESH+1)*2 * (MAXMESH+1)]; + +float N = 1.5; +float B = -1.5; + +void +mesh1(float x0, float x1, float y0, float y1, + float s0, float s1, float t0, float t1, float z, int nx, int ny) +{ + float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2]; + float v; + float *mp = Ml; + + dx = (x1-x0)/nx; + dy = (y1-y0)/ny; + ds = (s1-s0)/nx; + dt = (t1-t0)/ny; + y = y0; + t = t0; + vb[2] = z; + while (y < y1) { + x = x0; + s = s0; + while(x <= x1) { + tb[0] = s; tb[1] = t; + vb[0] = x; vb[1] = y; + v = N*N - x*x - y*y; + if (v < 0.0) v = 0.0; + vb[2] = sqrt(v) + B; + if (vb[2] < 0.) vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + tb[1] = t+dt; + vb[1] = y+dy; + v = N*N - x*x - (y+dy)*(y+dy); + if (v < 0.0) v = 0.0; + vb[2] = sqrt(v) + B; + if (vb[2] < 0.) vb[2] = 0.0; + *mp++ = tb[0]; + *mp++ = tb[1]; + mp += 2; + *mp++ = vb[0]; + *mp++ = vb[1]; + *mp++ = vb[2]; + mp++; + x += dx; + s += ds; + } + y += dy; + t += dt; + } +} + +void +drawmesh(int nx,int ny) { + float *mp = Ml; + int i,j; + + glColor4f(1,1,1,1); + for (i = ny+1; i; i--) { + glBegin(GL_TRIANGLE_STRIP); + for (j = nx+1; j; j--) { + glTexCoord2fv(mp); + glVertex3fv(mp+4); + glTexCoord2fv(mp+8); + glVertex3fv(mp+12); mp += 16; + } + glEnd(); + } +} + +void +move(void) { + if (N > 2.1 || N < 1.5) + dir = -dir; + N += incr*dir; + mesh1(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64); + glutPostRedisplay(); +} + +void +alphaup(void) { + incr += .01; + if (incr > .1) incr = .1; + glutPostRedisplay(); +} + +void +alphadown(void) { + incr -= .01; + if (incr < 0) incr = 0; + glutPostRedisplay(); +} + +void +left(void) { + *wscale -= .1; +} + +void +right(void) { + *wscale += .1; +} + +void +wire(void) { + static int wire_mode; + if (wire_mode ^= 1) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void +tfunc(void) { + static state; + if (state ^= 1) { + wrotx = &trotx; + wroty = &troty; + wscale = &tscale; + } else { + wrotx = &rotx; + wroty = &roty; + wscale = &scale; + } + +} + + +void +help(void) { + printf("'h' - help\n"); + printf("'w' - wire frame\n"); + printf("UP - faster\n"); + printf("DOWN - slower\n"); +} + +void +init(char *filename) { + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components < 3 || components > 4) { + printf("must be RGB or RGBA image\n"); + exit(EXIT_FAILURE); + } + } else { + int i, j; + components = 4; width = height = 128; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + if (i & 16) + image[i+j*width] = 0xff; + else + image[i+j*width] = 0xff00; + if (j&16) + image[i+j*width] |= 0xff0000; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.,1.,.1,10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-1.5); + glClearColor(.25, .25, .25, 0.); + +} + +void +display(void) { + glClear(GL_COLOR_BUFFER_BIT); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glTranslatef(.5f, .5f, .5f); + glRotatef(trotx, 0.f, 0.f, 1.f); + glScalef(tscale, tscale, tscale); + glTranslatef(-.5f, -.5f, -.5f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glRotatef(rotx, 0.f, 0.f, 1.f); + glScalef(scale, scale, scale); + drawmesh(64,64); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glutSwapBuffers(); +} + +void +reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case '\033': exit(0); break; + case 'h': help(); break; + case 't': tfunc(); break; + case 'w': wire(); break; + } +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: alphaup(); break; + case GLUT_KEY_DOWN: alphadown(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } +} + +int +main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow("warp"); + init(argv[1] ? argv[1] : "../data/mandrill.rgb"); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutIdleFunc(move); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/warp.dsp b/lib/glut-3.7.6/progs/advanced97/warp.dsp new file mode 100644 index 0000000000..d6d9d5c0d5 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/warp.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="warp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=warp - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "warp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "warp.mak" CFG="warp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "warp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "warp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "warp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "warp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "warp - Win32 Release" +# Name "warp - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\warp.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/water.c b/lib/glut-3.7.6/progs/advanced97/water.c new file mode 100644 index 0000000000..d8e1c371d8 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/water.c @@ -0,0 +1,322 @@ +#include +#include +#include +#include +#include "texture.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef __sgi +/* Most math.h's do not define float versions of the math functions. */ +#define expf(x) ((float)exp((x))) +#define sinf(x) ((float)sin((x))) +#endif + +static int rgb; +static int mesh = 1; +static float ttrans[2]; +static float transx, transy, rotx, roty; +static float amplitude = 0.03; +static float freq = 5.0f; +static float phase = .00003; +static int ox = -1, oy = -1; +static int show_t = 1; +static int mot; +#define PAN 1 +#define ROT 2 + +void +pan(int x, int y) { + transx += (x-ox)/500.; + transy -= (y-oy)/500.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +rotate(int x, int y) { + rotx += x-ox; + if (rotx > 360.) rotx -= 360.; + else if (rotx < -360.) rotx += 360.; + roty += y-oy; + if (roty > 360.) roty -= 360.; + else if (roty < -360.) roty += 360.; + ox = x; oy = y; + glutPostRedisplay(); +} + +void +motion(int x, int y) { + if (mot == PAN) pan(x, y); + else if (mot == ROT) rotate(x,y); +} + +void +mouse(int button, int state, int x, int y) { + if(state == GLUT_DOWN) { + switch(button) { + case GLUT_LEFT_BUTTON: + mot = PAN; + motion(ox = x, oy = y); + break; + case GLUT_MIDDLE_BUTTON: + mot = ROT; + motion(ox = x, oy = y); + break; + case GLUT_RIGHT_BUTTON: + break; + } + } else if (state == GLUT_UP) { + mot = 0; + } +} + +void toggle_t(void) { + show_t ^= 1; +} + +void ffunc(void) { freq *= 2.f; } +void Ffunc(void) { freq /= 2.f; } +void mfunc(void) { mesh ^= 1; } + +void wire(void) { + static int w; + if (w ^= 1) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glEnable(GL_BLEND); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDisable(GL_BLEND); + } +} + +void light(void) { + static int l; + if (l ^= 1) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); +} + +void up(void) { amplitude += .01; } +void down(void) { amplitude -= .01; } +void left(void) { phase -= .00001; } +void right(void) { phase += .00001; } + +void +animate(void) { + ttrans[0] += .005f; + if (ttrans[0] == 1.0f) ttrans[0] = 0.0f; + ttrans[1] -= .0025f; + if (ttrans[1] <= 0.0f) ttrans[1] = 1.0f; + glutPostRedisplay(); +} + +void xfunc(void) { + static state = 1; + glutIdleFunc((state ^= 1) ? animate : NULL); +} + +void help(void) { + printf("Usage: water [image]\n"); + printf("'h' - help\n"); + printf("'l' - toggle lighting\n"); + printf("'f' - increase frequency\n"); + printf("'F' - decrease frequency\n"); + printf("'m' - toggle mesh\n"); + printf("'t' - toggle wireframe\n"); + printf("'x' - toggle water motion\n"); + printf("'UP' - increase amplitude\n"); + printf("'DOWN' - decrease amplitude\n"); + printf("'RIGHT' - increase phase change\n"); + printf("'LEFT' - decreae phase change\n"); + printf("left mouse - pan\n"); + printf("middle mouse - rotate\n"); +} + +void init(char *filename) { + GLfloat cloud_color[4] = { 1., 1., 1., 0., }; + GLfloat fog_color[4], fog_density = 0.05, density, far_cull; + unsigned *image; + int width, height, components; + if (filename) { + image = read_texture(filename, &width, &height, &components); + if (image == NULL) { + fprintf(stderr, "Error: Can't load image file \"%s\".\n", + filename); + exit(EXIT_FAILURE); + } else { + printf("%d x %d image loaded\n", width, height); + } + if (components < 3) rgb = 0; + } else { + int i, j; + unsigned char *img; + components = 4; width = height = 512; + image = (unsigned *) malloc(width*height*sizeof(unsigned)); + img = (unsigned char *)image; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) { + int w2 = width/2, h2 = height/2; + if (i & 32) + img[4*(i+j*width)+0] = 0xff; + else + img[4*(i+j*width)+1] = 0xff; + if (j&32) + img[4*(i+j*width)+2] = 0xff; + if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 && + (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff; + } + + } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cloud_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, components, width, + height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + image); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.,1.,.1,far_cull = 10.); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.,0.,-5.5); + + density = 1.- expf(-5.5 * fog_density * fog_density * + far_cull * far_cull); + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + density = MAX(MIN(density, 1.), 0.); + + fog_color[0] = .23 + density *.57; + fog_color[1] = .35 + density *.45; + fog_color[2] = .78 + density *.22; + + glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f); + + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fog_density); + glFogfv(GL_FOG_COLOR, fog_color); + if (fog_density > 0) + glEnable(GL_FOG); + glLineWidth(2.0f); + glEnable(GL_LINE_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void draw_mesh(void) { + if (mesh) { + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f); + glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f, 1.f); + glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f, 1.f); + glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f); + glEnd(); + } else { +#define MESH 32 + int i, j; + static float off; + float d = 1.f/MESH; + for(i = 0; i < MESH; i++) { + glBegin(GL_TRIANGLE_STRIP); + for(j = 0; j < MESH; j++) { + float s = (float)j*d; + float t = (float)i*d; + float x = -1.0 + 2.f*s; + float z = -1.0 + 2.f*t; + float y = amplitude*sinf(freq*2.f*M_PI*t+off); + glTexCoord2f(s, t); glVertex3f(x, y, z); + s += d; t += d; + x = -1.0 + 2.f*s; + z = -1.0 + 2.f*t; + y = amplitude*sinf(freq*2.f*M_PI*t+off); + glTexCoord2f(s, t); glVertex3f(x, y, z); + off += phase; + } + glEnd(); + } + } +} + +void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(transx, transy, 0.f); + glRotatef(rotx, 0., 1., 0.); + glRotatef(roty, 1., 0., 0.); + glScalef(10,1,10); + if (!rgb) + glColor3f(.31, .41, .97); + else + glColor3f(1.f,1.f,1.f); + glTranslatef(0.f,-1.f,0.f); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glTranslatef(ttrans[0], ttrans[1], 0.); + glScalef(10.f, 10.f,1.f); + draw_mesh(); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glutSwapBuffers(); +} + +void reshape(int w, int h) { + glViewport(0, 0, w, h); +} + +/*ARGSUSED1*/ +void +key(unsigned char key, int x, int y) { + switch(key) { + case 'l': light(); break; + case 'f': ffunc(); break; + case 'F': Ffunc(); break; + case 't': toggle_t(); break; + case 'm': mfunc(); break; + case 'w': wire(); break; + case 'x': xfunc(); break; + case 'h': help(); break; + case '\033': exit(EXIT_SUCCESS); break; + default: break; + } + glutPostRedisplay(); +} + +/*ARGSUSED1*/ +void +special(int key, int x, int y) { + switch(key) { + case GLUT_KEY_UP: up(); break; + case GLUT_KEY_DOWN: down(); break; + case GLUT_KEY_LEFT: left(); break; + case GLUT_KEY_RIGHT:right(); break; + } +} + +int main(int argc, char** argv) { + glutInitWindowSize(256, 256); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE); + (void)glutCreateWindow(argv[0]); + init(argc == 1 ? "../data/water.bw" : argv[1]); + glutDisplayFunc(display); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(animate); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/water.dsp b/lib/glut-3.7.6/progs/advanced97/water.dsp new file mode 100644 index 0000000000..3569a1b46b --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/water.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="water" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=water - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "water.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "water.mak" CFG="water - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "water - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "water - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "water - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "water - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "water - Win32 Release" +# Name "water - Win32 Debug" +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# Begin Source File + +SOURCE=.\water.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/advanced97/zcomposite.c b/lib/glut-3.7.6/progs/advanced97/zcomposite.c new file mode 100644 index 0000000000..c416db3e1e --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/zcomposite.c @@ -0,0 +1,430 @@ +#include +#include +#include + +/* +** Create a single component texture map +*/ +GLfloat *make_texture(int maxs, int maxt) +{ + int s, t; + static GLfloat *texture; + + texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); + for(t = 0; t < maxt; t++) { + for(s = 0; s < maxs; s++) { + texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); + } + } + return texture; +} + +GLboolean stencil = GL_TRUE; + +/* ARGSUSED1 */ +void key(unsigned char key, int x, int y) +{ + switch(key) { + case 't': /* toggle using stencil */ + if(stencil == GL_TRUE) + stencil = GL_FALSE; + else + stencil = GL_TRUE; + glutPostRedisplay(); + break; + case '\033': + exit(0); + break; + } +} + +enum {SPHERE = 1, CONE}; +enum {X, Y, Z}; + +int startx, starty; +int wid, ht; +int oldwid = 0, oldht = 0; + +const int WINDIM = 512; +const GLfloat FRUSTDIM = 110.f; +const GLfloat FRUSTNEAR = 320.f; +const GLfloat FRUSTFAR = 540.f; +const GLfloat FRUSTDIFF = 540.f - 320.f; + +GLboolean drawmode = GL_FALSE; +GLboolean depthmode = GL_FALSE; +GLboolean rubberbandmode = GL_FALSE; +GLfloat *color; +GLfloat *depth; +GLfloat depthbias = 0.f; +GLfloat raspos[] = {0.f, 0.f, -430.f}; + + +int winWidth = 512; +int winHeight = 512; + +GLfloat sx = 0; +GLfloat sy = 0; + + +/* Overlay Stuff */ +int transparent; +int red; + +void +setRasterPosXY(int x, int y) +{ + raspos[X] = (x - winWidth/2) * sx; + raspos[Y] = (y - winHeight/2) * sy; + + glRasterPos3fv(raspos); + + glutPostRedisplay(); +} + +void +setRasterPosZ(int y) +{ + raspos[Z] = -(FRUSTNEAR + y * FRUSTDIFF/winHeight); + + depthbias = (y - winHeight/2.f)/winHeight; + + glRasterPos3fv(raspos); + + glutPostRedisplay(); +} + + + +void +motion(int x, int y) +{ + y = winHeight - y; + if(drawmode) + setRasterPosXY(x, y); + + if(rubberbandmode) { + wid = x - startx; + ht = y - starty; + glutPostOverlayRedisplay(); + } + + if(depthmode) + setRasterPosZ(y); +} + +/* redraw function for overlay: used to show selected region */ +void +overlay(void) +{ + if(glutLayerGet(GLUT_OVERLAY_DAMAGED)) { + glClear(GL_COLOR_BUFFER_BIT); + } else { + glIndexi(transparent); + glBegin(GL_LINE_LOOP); + glVertex2i(startx, starty); + glVertex2i(startx + oldwid, starty); + glVertex2i(startx + oldwid, starty + oldht); + glVertex2i(startx, starty + oldht); + glEnd(); + } + + glIndexi(red); + glBegin(GL_LINE_LOOP); + glVertex2i(startx, starty); + glVertex2i(startx + wid, starty); + glVertex2i(startx + wid, starty + ht); + glVertex2i(startx, starty + ht); + glEnd(); + + oldwid = wid; + oldht = ht; + + glFlush(); +} + + +/* used to get current width and height of viewport */ +void +reshape(int wid, int ht) +{ + glutUseLayer(GLUT_OVERLAY); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, wid, 0, ht); /* 1 to 1 with window */ + glMatrixMode(GL_MODELVIEW); + glViewport(0, 0, wid, ht); + + glutUseLayer(GLUT_NORMAL); + glViewport((GLint) (-wid * .1), (GLint) (-ht * .1), + (GLsizei) (wid * 1.2), (GLsizei) (ht * 1.2)); + + winWidth = wid; + winHeight = ht; + + sx = 2 * FRUSTDIM/(winWidth * 1.2); + sy = 2 * FRUSTDIM/(winHeight * 1.2); +} + + +void +mouse(int button, int state, int x, int y) +{ + y = winHeight - y; /* flip y orientation */ + if(state == GLUT_DOWN) + switch(button) { + case GLUT_LEFT_BUTTON: /* select an image */ + startx = x; + starty = y; + wid = 0; ht = 0; + rubberbandmode = GL_TRUE; + glutShowOverlay(); + break; + case GLUT_MIDDLE_BUTTON: + glutUseLayer(GLUT_NORMAL); + if(color && depth) { + drawmode = GL_TRUE; + setRasterPosXY(x, y); + } + break; + case GLUT_RIGHT_BUTTON: /* change depth */ + glutUseLayer(GLUT_NORMAL); + if(color && depth) { + depthmode = GL_TRUE; + setRasterPosZ(y); + } + break; + } + else /* GLUT_UP */ + switch(button) { + case GLUT_LEFT_BUTTON: + rubberbandmode = GL_FALSE; + glutHideOverlay(); + wid = x - startx; + ht = y - starty; + if(wid < 0) { + wid = -wid; + startx = x; + } + if(ht < 0) { + ht = -ht; + starty = y; + } + color = (GLfloat *)realloc(color, wid * ht * 3 * sizeof(GLfloat)); + depth = (GLfloat *)realloc(depth, wid * ht * sizeof(GLfloat)); + + glutUseLayer(GLUT_NORMAL); + glReadPixels(startx, starty, wid, ht, GL_RGB, GL_FLOAT, color); + glReadPixels(startx, starty, wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT, + depth); + break; + case GLUT_MIDDLE_BUTTON: + drawmode = GL_FALSE; + break; + case GLUT_RIGHT_BUTTON: /* change depth */ + depthmode = GL_FALSE; + break; + } +} + + +/* Called when window needs to be redrawn */ +void +redraw(void) +{ + /* material properties for objects in scene */ + static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f}; + + glutUseLayer(GLUT_NORMAL); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + + /* + ** Note: wall verticies are ordered so they are all front facing + ** this lets me do back face culling to speed things up. + */ + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat); + + /* floor */ + /* make the floor textured */ + glEnable(GL_TEXTURE_2D); + + /* + ** Since we want to turn texturing on for floor only, we have to + ** make floor a separate glBegin()/glEnd() sequence. You can't + ** turn texturing on and off between begin and end calls + */ + glBegin(GL_QUADS); + glNormal3f(0.f, 1.f, 0.f); + glTexCoord2i(0, 0); + glVertex3f(-100.f, -100.f, -320.f); + glTexCoord2i(1, 0); + glVertex3f( 100.f, -100.f, -320.f); + glTexCoord2i(1, 1); + glVertex3f( 100.f, -100.f, -520.f); + glTexCoord2i(0, 1); + glVertex3f(-100.f, -100.f, -520.f); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* walls */ + + glBegin(GL_QUADS); + /* left wall */ + glNormal3f(1.f, 0.f, 0.f); + glVertex3f(-100.f, -100.f, -320.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -320.f); + + /* right wall */ + glNormal3f(-1.f, 0.f, 0.f); + glVertex3f( 100.f, -100.f, -320.f); + glVertex3f( 100.f, 100.f, -320.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + + /* ceiling */ + glNormal3f(0.f, -1.f, 0.f); + glVertex3f(-100.f, 100.f, -320.f); + glVertex3f(-100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f( 100.f, 100.f, -320.f); + + /* back wall */ + glNormal3f(0.f, 0.f, 1.f); + glVertex3f(-100.f, -100.f, -520.f); + glVertex3f( 100.f, -100.f, -520.f); + glVertex3f( 100.f, 100.f, -520.f); + glVertex3f(-100.f, 100.f, -520.f); + glEnd(); + + glPushMatrix(); + glTranslatef(-40.f, -60.f, -400.f); + glScalef(2, 2, 2); + glCallList(SPHERE); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(50.f, -120.f, -400.f); + glScalef(2, 2, 2); + glCallList(CONE); + glPopMatrix(); + + if(stencil) { + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilFunc(GL_ALWAYS, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glPixelTransferf(GL_DEPTH_BIAS, depthbias); + + glDrawPixels(wid, ht, GL_DEPTH_COMPONENT, GL_FLOAT, depth); + + glPixelTransferf(GL_DEPTH_BIAS, 0.f); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glStencilFunc(GL_EQUAL, 1, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDisable(GL_DEPTH_TEST); + + glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + } else + glDrawPixels(wid, ht, GL_RGB, GL_FLOAT, color); + + glutSwapBuffers(); +} + + +const int TEXDIM = 256; +/* Parse arguments, and set up interface between OpenGL and window system */ +main(int argc, char *argv[]) +{ + GLfloat *tex; + static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f}; + static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f}; + static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f}; + GLUquadricObj *sphere, *cone, *base; + + glutInit(&argc, argv); + glutInitWindowSize(WINDIM, WINDIM); + + glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL|GLUT_DOUBLE); + (void)glutCreateWindow("compositing images with depth"); + glutDisplayFunc(redraw); + glutKeyboardFunc(key); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutReshapeFunc(reshape); + + /* draw a perspective scene */ + glMatrixMode(GL_PROJECTION); + glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, FRUSTNEAR, FRUSTFAR); + glMatrixMode(GL_MODELVIEW); + + /* turn on features */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + /* place light 0 in the right place */ + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + + /* remove back faces to speed things up */ + glCullFace(GL_BACK); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glNewList(SPHERE, GL_COMPILE); + /* make display lists for sphere and cone; for efficiency */ + sphere = gluNewQuadric(); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); + gluSphere(sphere, 20.f, 20, 20); + gluDeleteQuadric(sphere); + glEndList(); + + glNewList(CONE, GL_COMPILE); + cone = gluNewQuadric(); + base = gluNewQuadric(); + glRotatef(-90.f, 1.f, 0.f, 0.f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); + gluQuadricOrientation(base, GLU_INSIDE); + gluDisk(base, 0., 20., 20, 1); + gluCylinder(cone, 20., 0., 60., 20, 20); + gluDeleteQuadric(cone); + gluDeleteQuadric(base); + glEndList(); + + /* load pattern for current 2d texture */ + tex = make_texture(TEXDIM, TEXDIM); + glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); + free(tex); + + /* storage for saved image */ + color = 0; + depth = 0; + + glReadBuffer(GL_FRONT);/* so glReadPixel() always get the right image */ + + glutInitDisplayMode(GLUT_SINGLE|GLUT_INDEX); + if(glutLayerGet(GLUT_OVERLAY_POSSIBLE)) { + glutEstablishOverlay(); + glutHideOverlay(); + transparent = glutLayerGet(GLUT_TRANSPARENT_INDEX); + glClearIndex(transparent); + red = (transparent + 1) % glutGet(GLUT_WINDOW_COLORMAP_SIZE); + glutSetColor(red, 1.0, 0.0, 0.0); /* Red. */ + glutOverlayDisplayFunc(overlay); + } + else + { + printf( "Overlay support unavailable - aborting.\n" ); + return 1; + } + + glutMainLoop(); + + return 0; +} diff --git a/lib/glut-3.7.6/progs/advanced97/zcomposite.dsp b/lib/glut-3.7.6/progs/advanced97/zcomposite.dsp new file mode 100644 index 0000000000..f034111046 --- /dev/null +++ b/lib/glut-3.7.6/progs/advanced97/zcomposite.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="zcomposite" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=zcomposite - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zcomposite.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zcomposite.mak" CFG="zcomposite - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zcomposite - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "zcomposite - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "zcomposite - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "zcomposite - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "zcomposite - Win32 Release" +# Name "zcomposite - Win32 Debug" +# Begin Source File + +SOURCE=.\zcomposite.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/aux2glut.sed b/lib/glut-3.7.6/progs/aux2glut.sed new file mode 100644 index 0000000000..b35983b2f3 --- /dev/null +++ b/lib/glut-3.7.6/progs/aux2glut.sed @@ -0,0 +1,55 @@ +# +# aux2glut.sed - a sed script for converting AUX code to GLUT +# +# You will still need to do some work, but this is a good start. +# +1i\ +/* aux2glut conversion Copyright (c) Mark J. Kilgard, 1994, 1995 */ +1i\ + +s/int main/void main/g +s/auxInitWindow/glutCreateWindow/g +s/AUX_SINGLE/GLUT_SINGLE/g +s/AUX_DOUBLE/GLUT_DOUBLE/g +s/AUX_RGB/GLUT_RGB/g +s/AUX_RGBA/GLUT_RGBA/g +s/AUX_ACCUM/GLUT_ACCUM/g +s/AUX_DEPTH/GLUT_DEPTH/g +s/AUX_STENCIL/GLUT_STENCIL/g +s/AUX_ALPHA/GLUT_ALPHA/g +s/AUX_MOUSEDOWN/GLUT_DOWN/g +s/AUX_MOUSEUP/GLUT_UP/g +s/AUX_LEFTBUTTON/GLUT_LEFT_BUTTON/g +s/AUX_MIDDLEBUTTON/GLUT_MIDDLE_BUTTON/g +s/AUX_RIGHTBUTTON/GLUT_RIGHT_BUTTON/g +s/(.*AUX_EVENTREC.*)/( int x, int y )/g +s/auxReshapeFunc/glutReshapeFunc/g +s/#include \"aux.h\"/#include /g +s/#include[ ]*\/#include /g +s/\(initialize.*$\)/glutInit(\&argc, argv); \1/g +s/auxInitDisplayMode/glutInitDisplayMode/g +s/auxMainLoop(display)/glutDisplayFunc(display); glutMainLoop()/g +s/auxMainLoop[ ]*([ ]*drawScene[ ]*)/glutDisplayFunc(drawScene); glutMainLoop()/g +s/auxAnimation.*$/glutIdleFunc(drawScene);/g +s/auxGetScreenSize.*$/width = glutGet(GLUT_SCREEN_WIDTH); height = glutGet(GLUT_SCREEN_HEIGHT);/g +s/auxGetSize.*$/width = glutGet(GLUT_WINDOW_WIDTH); height = glutGet(GLUT_WINDOW_HEIGHT);/g +s/auxInitPosition(\(.*\),\(.*\),\(.*\),\(.*\));/glutInitWindowPosition(\1,\2); glutInitWindowSize(\3,\4);/g +s/auxSwapBuffers/glutSwapBuffers/g +s/auxWireIcosahedron/glutWireIcosahedron/g +s/auxSolidIcosahedron/glutSolidIcosahedron/g +s/auxSolidTorus/glutSolidTorus/g +s/auxWireTorus/glutWireTorus/g +s/auxSolidCube/glutSolidCube/g +s/auxWireCube/glutWireCube/g +s/auxSolidSphere/glutSolidSphere/g +s/auxWireSphere/glutWireSphere/g +s/auxSolidCone/glutSolidCone/g +s/auxWireCone/glutWireCone/g +s/auxSolidOctahedron/glutSolidOctahedron/g +s/auxWireOctahedron/glutWireOctahedron/g +s/auxSolidTeapot/glutSoliddTeapot/g +s/auxWireTeapot/glutWireTeapot/g +s/auxKeyFunc(.*,/glutKeyboardFunc(/g +s/auxMouseFunc(.*AUX_MOUSELOC,.*NULL,/glutMouseMotion(/g +s/auxMouseFunc/glutMouseFunc/g +s/auxDeleteMouseFunc( .*$/glutMouseMotion( NULL );/g diff --git a/lib/glut-3.7.6/progs/bucciarelli.dsw b/lib/glut-3.7.6/progs/bucciarelli.dsw new file mode 100644 index 0000000000..7db308007f --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli.dsw @@ -0,0 +1,149 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "_all"=".\bucciarelli\_all.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name fire + End Project Dependency + Begin Project Dependency + Project_Dep_Name glbpaltex + End Project Dependency + Begin Project Dependency + Project_Dep_Name gltest + End Project Dependency + Begin Project Dependency + Project_Dep_Name paltex + End Project Dependency + Begin Project Dependency + Project_Dep_Name ray + End Project Dependency + Begin Project Dependency + Project_Dep_Name teapot + End Project Dependency + Begin Project Dependency + Project_Dep_Name terrain + End Project Dependency + Begin Project Dependency + Project_Dep_Name tunnel + End Project Dependency +}}} + +############################################################################### + +Project: "fire"=".\bucciarelli\fire.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "glbpaltex"=".\bucciarelli\glbpaltex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gltest"=".\bucciarelli\gltest.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "paltex"=".\bucciarelli\paltex.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "ray"=".\bucciarelli\ray.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "teapot"=".\bucciarelli\teapot.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "terrain"=".\bucciarelli\terrain.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tunnel"=".\bucciarelli\tunnel.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/progs/bucciarelli/Imakefile b/lib/glut-3.7.6/progs/bucciarelli/Imakefile new file mode 100644 index 0000000000..9e1de31cfa --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/Imakefile @@ -0,0 +1,22 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../Glut.cf" + +TARGETS = tunnel teapot fire terrain paltex gltest ray glbpaltx + +SRCS = dteapot.c fire.c glbpaltx.c gltest.c image.c paltex.c ray.c shadow.c \ + sources.c teapot.c terrain.c tunnel.c + +AllTarget($(TARGETS)) + +SimpleGlutProgramTarget(ray) +SimpleGlutProgramTarget(gltest) +SimpleGlutProgramTarget(paltex) +SimpleGlutProgramTarget(glbpaltx) +SimpleGlutProgramTarget(terrain) +NormalGlutProgramTarget(tunnel,tunnel.o image.o sources.o) +NormalGlutProgramTarget(teapot,teapot.o image.o dteapot.o shadow.o) +NormalGlutProgramTarget(fire,fire.o image.o) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/bucciarelli/README b/lib/glut-3.7.6/progs/bucciarelli/README new file mode 100644 index 0000000000..7c447402ea --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/README @@ -0,0 +1,155 @@ + +INTRODUCTION +------------ + +This directory is usually included in the Mesa demos distribution or +in the GLUT distribution. + +I have written the demos included in this directory mainly for showing +the capabilities of the Mesa library when using the Voodoo driver. +However all the demos are written using the GLUT and OpenGL so they +work with any GLUT/OpenGL platform (tested: Linux+Mesa+Voodoo driver, +Linux+Mesa+X11 driver, Win95+Mesa+Voodoo driver and SGI Onyx IR thanks +to Mark Kilgard). + +All the demos make an heavy use of texture mapping, blending, etc. so +you _need_ some kind of hardware support for the OpenGL otherwise they +will run at ~1fps. You need also a OpenGL 1.1 compliant library. + +you can find some screenshot of these demos at +http://www-hmw.caribel.pisa.it/fxmesa/fxdemos.hmtl + +Write me if you find some bug in the demos. + +David Bucciarelli (tech.hmw@plus.it) + +Humanware s.r.l. +Via XXIV Maggio 62 +Pisa, Italy +Tel./Fax +39-50-554108 +email: info.hmw@plus.it +www: www-hmw.caribel.pisa.it + + +A BRIEF DESCRIPTION OF THE DEMOS +-------------------------------- + +RAY +--- + +Sources: ray.c + +I'm using ray tracing to dynamically generate texture maps with +specular, diffuse, shadows, and mirror colors. Each frame the texture +maps of the plane and of the sphere are partially updated. With this +technique you can obtain true mirrors, shadows, specular highlights, +bump mapping, etc. in realtime. This demo is really CPU intensive +(~25fps on a PentiumII@300MHz with a Pure3D). + + +TUNNEL +------ + +Sources: tunnel.c image.c sources.c +Data: bw.rgb tile.rgb + +The model was designed and prelighted with Alias|Wavefront +PowerAnimator V8. Triangle strips were built with a tool written by +me and then statically included in the sources. + + +TEAPOT +------ + +Sources: teapot.c image.c dteapot.c shadow.c +Data: bw.rgb tile.rgb + +The shadow is drawn projecting the teapot geometry over the plane. All +other light effects are drawn using the standard OpenGL capabilities. + + +FIRE +---- + +Sources: fire.c image.c +Data: s128.rgb tree2.rgb + +The demo use a small particle system to draw some nice visual effect. +You can interactively change many parameters of the particle system +and you can choose the number of particles at the startup ('fire +4000'). This demo should be called fountain. + + +TERRAIN +------- + +Sources: mesaland.c + +This demo is base on another demo written by Mikael SkiZoWalker. +I have added the capabilities to freely fly around, view culling +and some nice color. + + +GLTEST +------ + +Sources: gltest.c + +This is a simple benchmark suite that I'm using in the development +of the Mesa/Voodoo driver. Type 'gltest >my.res' and you will get +some data about the performances of your OpenGL. Follow the +results with my PC (PentiumII@300MHz+Pure3D): + +Simple Points +587900.080674 Pnts/sec + +Smooth Lines +SIZE=480 => 39007.426183 Lins/sec +SIZE=250 => 74575.016485 Lins/sec +SIZE=100 => 179734.882409 Lins/sec +SIZE=050 => 183987.795297 Lins/sec +SIZE=025 => 183820.086309 Lins/sec + + +ZSmooth Triangles +SIZE=480 => 784.954997 Tris/sec +SIZE=250 => 2862.325889 Tris/sec +SIZE=100 => 17779.492938 Tris/sec +SIZE=050 => 159339.829844 Tris/sec +SIZE=025 => 428602.984008 Tris/sec + + +ZSmooth Tex Blend Triangles +SIZE=480 => 784.473931 Tris/sec +SIZE=250 => 2853.781513 Tris/sec +SIZE=100 => 17598.252146 Tris/sec +SIZE=050 => 152632.578337 Tris/sec +SIZE=025 => 377584.760048 Tris/sec + + +ZSmooth Tex Blend TMesh Triangles +SIZE=400 => 563.900695 Tris/sec, MPixel Fill/sec: 45.112056 +SIZE=250 => 1449.777225 Tris/sec, MPixel Fill/sec: 45.305538 +SIZE=100 => 8702.869121 Tris/sec, MPixel Fill/sec: 43.514346 +SIZE=050 => 31896.867466 Tris/sec, MPixel Fill/sec: 39.871084 +SIZE=025 => 114037.262894 Tris/sec, MPixel Fill/sec: 35.636645 +SIZE=010 => 220494.235839 Tris/sec, MPixel Fill/sec: 11.024712 +SIZE=005 => 225615.506651 Tris/sec, MPixel Fill/sec: 2.820194 +SIZE=002 => 225607.681439 Tris/sec, MPixel Fill/sec: 0.451215 + + +Color/Depth Buffer Clears +295.042474 Clrs/sec, MPixel Fill/sec: 90.553256 + + +PALTEX and GLBPALTX +------------------- + +Sources: paltex.c and glbpaltx.c + +The PALTEX example was written by Brian Paul and it shows the +capabilities of the GL_EXT_paletted_texture extension. I have written +the other example in order to show the capabilities of the +gl3DfxSetPaletteEXT() (it used only by GLQuake and Quake2). + + diff --git a/lib/glut-3.7.6/progs/bucciarelli/_all.dsp b/lib/glut-3.7.6/progs/bucciarelli/_all.dsp new file mode 100644 index 0000000000..6a4421548c --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "_all___Win32_Debug" +# PROP BASE Intermediate_Dir "_all___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/bw.rgb b/lib/glut-3.7.6/progs/bucciarelli/bw.rgb new file mode 100644 index 0000000000000000000000000000000000000000..8e22a30a7b03e0c89b4b7e464b9487b00efc4e98 GIT binary patch literal 54196 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 o%iajIh+0nrbP21uk(q^+wS}v`-2eap literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/bucciarelli/dteapot.c b/lib/glut-3.7.6/progs/bucciarelli/dteapot.c new file mode 100644 index 0000000000..312a0e1639 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/dteapot.c @@ -0,0 +1,196 @@ +/* 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. +*/ + +/* Modified by David Bucciarelli */ + +#include + +/* Rim, body, lid, and bottom data must be reflected in x + and y; handle and spout data across the y axis only. */ + +long patchdata[][16] = +{ + /* rim */ + {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15}, + /* body */ + {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27}, + {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40}, + /* lid */ + {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, + 101, 0, 1, 2, 3,}, + {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117}, + /* bottom */ + {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, + 125, 120, 40, 39, 38, 37}, + /* handle */ + {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56}, + {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 28, 65, 66, 67}, + /* spout */ + {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83}, + {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95} +}; +/* *INDENT-OFF* */ + +float cpdata[][3] = +{ + {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0, + -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125}, + {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375, + 0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375, + 2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84, + 2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875}, + {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75, + 1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35}, + {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2, + 0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12, + 0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225}, + {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225}, + {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0, + -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5, + -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3, + 2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0, + 2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0, + 2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8}, + {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3, + -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3, + 1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2, + -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0, + 1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0, + 0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66, + 0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1}, + {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7, + -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0, + 2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375}, + {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475}, + {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4}, + {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0, + 3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8, + 3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4, + -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0, + 2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4, + 2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3, + 2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4}, + {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425, + -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425, + 0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075}, + {0.84, -1.5, 0.075} +}; + +static float tex[2][2][2] = +{ + { {0, 0}, + {1, 0}}, + { {0, 1}, + {1, 1}} +}; + +/* *INDENT-ON* */ + +void teapot(GLint grid, GLdouble scale, GLenum type) +{ + float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3]; + long i, j, k, l; + + glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_MAP2_TEXTURE_COORD_2); + glPushMatrix(); + glRotatef(270.0, 1.0, 0.0, 0.0); + glScalef(0.5 * scale, 0.5 * scale, 0.5 * scale); + glTranslatef(0.0, 0.0, -1.5); + for (i = 0; i < 10; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + for (l = 0; l < 3; l++) { + p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 1) + q[j][k][l] *= -1.0; + if (i < 6) { + r[j][k][l] = + cpdata[patchdata[i][j * 4 + (3 - k)]][l]; + if (l == 0) + r[j][k][l] *= -1.0; + s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l]; + if (l == 0) + s[j][k][l] *= -1.0; + if (l == 1) + s[j][k][l] *= -1.0; + } + } + } + } + glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, + &tex[0][0][0]); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &p[0][0][0]); + glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &q[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + if (i < 6) { + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &r[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, + &s[0][0][0]); + glEvalMesh2(type, 0, grid, 0, grid); + } + } + glPopMatrix(); + glPopAttrib(); +} + diff --git a/lib/glut-3.7.6/progs/bucciarelli/fire.c b/lib/glut-3.7.6/progs/bucciarelli/fire.c new file mode 100644 index 0000000000..520119b0c9 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/fire.c @@ -0,0 +1,697 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#include +#include "image.h" + +#if defined(GL_VERSION_1_1) +/* Routines called directly. */ +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} + +#define vinit4(a,i,j,k,w) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ + (a)[3]=w;\ +} + + +#define vadds(a,dt,b) {\ + (a)[0]+=(dt)*(b)[0];\ + (a)[1]+=(dt)*(b)[1];\ + (a)[2]+=(dt)*(b)[2];\ +} + +#define vequ(a,b) {\ + (a)[0]=(b)[0];\ + (a)[1]=(b)[1];\ + (a)[2]=(b)[2];\ +} + +#define vinter(a,dt,b,c) {\ + (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ + (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ + (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ +} + +#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) + +#define vclamp(v) {\ + (v)[0]=clamp((v)[0]);\ + (v)[1]=clamp((v)[1]);\ + (v)[2]=clamp((v)[2]);\ +} + +static int WIDTH=640; +static int HEIGHT=480; + +#define FRAME 50 +#define DIMP 20.0 +#define DIMTP 16.0 + +#define RIDCOL 0.4 + +#define NUMTREE 50 +#define TREEINR 2.5 +#define TREEOUTR 8.0 + +#define AGRAV -9.8 + +typedef struct { + int age; + float p[3][3]; + float v[3]; + float c[3][4]; +} part; + +static float treepos[NUMTREE][3]; + +static float black[3]={0.0,0.0,0.0}; +static float blu[3]={0.0,0.2,1.0}; +static float blu2[3]={0.0,1.0,1.0}; + +static float fogcolor[4]={1.0,1.0,1.0,1.0}; + +static float q[4][3]={ + {-DIMP,0.0,-DIMP}, + {DIMP,0.0,-DIMP}, + {DIMP,0.0,DIMP}, + {-DIMP,0.0,DIMP} +}; + +static float qt[4][2]={ + {-DIMTP,-DIMTP}, + {DIMTP,-DIMTP}, + {DIMTP,DIMTP}, + {-DIMTP,DIMTP} +}; + +static int np; +static float eject_r,dt,maxage,eject_vy,eject_vl; +static short shadows; +static float ridtri; +static int fog=1; +static int help=1; +static int joyavailable=0; +static int joyactive=0; + +static part *p; + +static GLuint groundid; +static GLuint treeid; + +static float obs[3]={2.0,1.0,0.0}; +static float dir[3]; +static float v=0.0; +static float alpha=-90.0; +static float beta=90.0; + +static float gettime(void) +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +float vrnd(void) +{ + return(((float)rand())/RAND_MAX); +} + +static void setnewpart(part *p) +{ + float a,v[3],*c; + + p->age=0; + + a=vrnd()*3.14159265359*2.0; + + vinit(v,sin(a)*eject_r*vrnd(),0.15,cos(a)*eject_r*vrnd()); + vinit(p->p[0],v[0]+vrnd()*ridtri,v[1]+vrnd()*ridtri,v[2]+vrnd()*ridtri); + vinit(p->p[1],v[0]+vrnd()*ridtri,v[1]+vrnd()*ridtri,v[2]+vrnd()*ridtri); + vinit(p->p[2],v[0]+vrnd()*ridtri,v[1]+vrnd()*ridtri,v[2]+vrnd()*ridtri); + + vinit(p->v,v[0]*eject_vl/(eject_r/2),vrnd()*eject_vy+eject_vy/2,v[2]*eject_vl/(eject_r/2)); + + c=blu; + + vinit4(p->c[0],c[0]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[1]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[2]*((1.0-RIDCOL)+vrnd()*RIDCOL), + 1.0); + vinit4(p->c[1],c[0]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[1]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[2]*((1.0-RIDCOL)+vrnd()*RIDCOL), + 1.0); + vinit4(p->c[2],c[0]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[1]*((1.0-RIDCOL)+vrnd()*RIDCOL), + c[2]*((1.0-RIDCOL)+vrnd()*RIDCOL), + 1.0); +} + +static void setpart(part *p) +{ + float fact; + + if(p->p[0][1]<0.1) { + setnewpart(p); + return; + } + + p->v[1]+=AGRAV*dt; + + vadds(p->p[0],dt,p->v); + vadds(p->p[1],dt,p->v); + vadds(p->p[2],dt,p->v); + + p->age++; + + if((p->age)>maxage) { + vequ(p->c[0],blu2); + vequ(p->c[1],blu2); + vequ(p->c[2],blu2); + } else { + fact=1.0/maxage; + vadds(p->c[0],fact,blu2); + vclamp(p->c[0]); + p->c[0][3]=fact*(maxage-p->age); + + vadds(p->c[1],fact,blu2); + vclamp(p->c[1]); + p->c[1][3]=fact*(maxage-p->age); + + vadds(p->c[2],fact,blu2); + vclamp(p->c[2]); + p->c[2][3]=fact*(maxage-p->age); + } +} + +static void drawtree(float x, float y, float z) +{ + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex3f(x-1.5,y+0.0,z); + + glTexCoord2f(1.0,0.0); + glVertex3f(x+1.5,y+0.0,z); + + glTexCoord2f(1.0,1.0); + glVertex3f(x+1.5,y+3.0,z); + + glTexCoord2f(0.0,1.0); + glVertex3f(x-1.5,y+3.0,z); + + + glTexCoord2f(0.0,0.0); + glVertex3f(x,y+0.0,z-1.5); + + glTexCoord2f(1.0,0.0); + glVertex3f(x,y+0.0,z+1.5); + + glTexCoord2f(1.0,1.0); + glVertex3f(x,y+3.0,z+1.5); + + glTexCoord2f(0.0,1.0); + glVertex3f(x,y+3.0,z-1.5); + + glEnd(); + +} + +static void calcposobs(void) +{ + dir[0]=sin(alpha*M_PI/180.0); + dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[1]=cos(beta*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;ijoy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha+=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.01; + if(joy.wButtons & JOY_BUTTON2) + v-=0.01; + } + } else + joyavailable=0; +#endif +} + +static void drawfire(void) +{ + static int count=0; + static char frbuf[80]; + int j; + float fr; + + dojoy(); + + glEnable(GL_DEPTH_TEST); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glDepthMask(GL_TRUE); + glClearColor(1.0,1.0,1.0,1.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,1.0,0.0); + + glColor4f(1.0,1.0,1.0,1.0); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D,groundid); + glBegin(GL_QUADS); + glTexCoord2fv(qt[0]); + glVertex3fv(q[0]); + glTexCoord2fv(qt[1]); + glVertex3fv(q[1]); + glTexCoord2fv(qt[2]); + glVertex3fv(q[2]); + glTexCoord2fv(qt[3]); + glVertex3fv(q[3]); + glEnd(); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GEQUAL,0.9); + + glBindTexture(GL_TEXTURE_2D,treeid); + for(j=0;jsizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); + + glGenTextures(1,&treeid); + glBindTexture(GL_TEXTURE_2D,treeid); + + if(!(img=ImageLoad("tree2.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + for(y=0;y<128;y++) + for(x=0;x<128;x++) { + tex[x][y][0]=img->data[(y+x*128)*3]; + tex[x][y][1]=img->data[(y+x*128)*3+1]; + tex[x][y][2]=img->data[(y+x*128)*3+2]; + if((tex[x][y][0]==tex[x][y][1]) && (tex[x][y][1]==tex[x][y][2]) && (tex[x][y][2]==255)) + tex[x][y][3]=0; + else + tex[x][y][3]=255; + } + + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, + GL_UNSIGNED_BYTE, (GLvoid *)(tex)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); +} + +static void inittree(void) +{ + int i; + float dist; + + for(i=0;iTREEOUTR)); +} + +int main(int ac,char **av) +{ + int i; + + fprintf(stderr,"Fire V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + /* Default settings */ + + WIDTH=640; + HEIGHT=480; + np=800; + eject_r=0.1; + dt=0.015; + eject_vy=4; + eject_vl=1; + shadows=1; + ridtri=0.1; + + maxage=1.0/dt; + + if(ac==2) + np=atoi(av[1]); + + if(ac==4) { + WIDTH=atoi(av[2]); + HEIGHT=atoi(av[3]); + } + + glutInitWindowPosition(0,0); + glutInitWindowSize(WIDTH,HEIGHT); + glutInit(&ac,av); + + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + + glutCreateWindow("Fire"); + + reshape(WIDTH,HEIGHT); + + inittextures(); + + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE,GL_EXP); + glFogfv(GL_FOG_COLOR,fogcolor); + glFogf(GL_FOG_DENSITY,0.1); +#ifdef FX + glHint(GL_FOG_HINT,GL_NICEST); +#endif + + p=malloc(sizeof(part)*np); + + for(i=0;i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=fire - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fire.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fire.mak" CFG="fire - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fire - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "fire - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fire - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "fire - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "fire - Win32 Release" +# Name "fire - Win32 Debug" +# Begin Source File + +SOURCE=.\fire.c +# End Source File +# Begin Source File + +SOURCE=.\image.c +# End Source File +# Begin Source File + +SOURCE=.\image.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/glbpaltex.dsp b/lib/glut-3.7.6/progs/bucciarelli/glbpaltex.dsp new file mode 100644 index 0000000000..0c13c6cd34 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/glbpaltex.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="glbpaltex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=glbpaltex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "glbpaltex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "glbpaltex.mak" CFG="glbpaltex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "glbpaltex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "glbpaltex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "glbpaltex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "glbpaltex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "glbpaltex - Win32 Release" +# Name "glbpaltex - Win32 Debug" +# Begin Source File + +SOURCE=.\glbpaltx.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/glbpaltx.c b/lib/glut-3.7.6/progs/bucciarelli/glbpaltx.c new file mode 100644 index 0000000000..202dcb41b3 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/glbpaltx.c @@ -0,0 +1,160 @@ +/* glbpaltex.c */ + +/* + * Global Paletted texture demo. + */ + +#include +#include +#include +#include + +#if defined(FX) && defined(__WIN32__) +WINGDIAPI void APIENTRY gl3DfxSetPaletteEXT(GLuint *pal); +#else +void gl3DfxSetPaletteEXT(GLuint *pal); +#endif + +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 ); +} + + +/* ARGSUSED1 */ +static void Key( unsigned char key, int x, int y ) +{ + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +/* ARGSUSED1 */ +static void SpecialKey( int key, int x, int 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 ) +{ +#ifdef GL_3DFX_set_global_palette + 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}, + }; + int i; + + GLubyte table[256][4]; + + if (!glutExtensionSupported("3DFX_set_global_palette")) { +#endif + printf("Sorry, 3DFX_set_global_palette not supported\n"); + exit(0); +#ifdef GL_3DFX_set_global_palette + } + + /* put some wacky colors into the texture palette */ + for (i=0;i<256;i++) { + table[i][2] = i; + table[i][1] = 0; + table[i][0] = 127 + i / 2; + table[i][3] = 255; + } + + gl3DfxSetPaletteEXT((GLuint *)table); + + 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( 640, 480 ); + + 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/lib/glut-3.7.6/progs/bucciarelli/gltest.c b/lib/glut-3.7.6/progs/bucciarelli/gltest.c new file mode 100644 index 0000000000..b9ec29e8b7 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/gltest.c @@ -0,0 +1,535 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include +#include +#include +#include +#include + +typedef struct { + char *name; + char *unit; + void (*init)(void); + int (*run)(int, int); + int type; + int numsize; + int size[10]; +} benchmark; + +static int frontbuffer=1; + +/***************************************************************************/ + +static void init_test01(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-0.5,639.5,-0.5,479.5); + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_FLAT); + glDisable(GL_DEPTH_TEST); + + glClearColor(0.0,0.1,1.0,0.0); + glClear(GL_COLOR_BUFFER_BIT); + glColor3f(1.0,0.0,0.0); +} + +/* ARGSUSED */ +static int test01(int size, int num) +{ + int x,y; + + glBegin(GL_POINTS); + for(y=0;yinit(); + + stime=glutGet(GLUT_ELAPSED_TIME); + + dtime=0.0; + calibnum=0; + while(dtime<2.0) { + bmark->run(0,1); + glFinish(); + etime=glutGet(GLUT_ELAPSED_TIME); + dtime=(etime-stime)/1000.0; + calibnum++; + } + glPopAttrib(); + + fprintf(stderr,"Elapsed time for the calibration test (%d): %f\n",calibnum,dtime); + + num=(int)((BMARKS_TIME/dtime)*calibnum); + + if(num<1) + num=1; + + fprintf(stderr,"Selected number of benchmark iterations: %d\n",num); + + mintime=HUGE_VAL; + maxtime=-HUGE_VAL; + + for(tottime=0.0,j=0;j<5;j++) { + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime=glutGet(GLUT_ELAPSED_TIME); + numelem=bmark->run(0,num); + glFinish(); + etime=glutGet(GLUT_ELAPSED_TIME); + + glPopAttrib(); + + dtime=(etime-stime)/1000.0; + tottime+=dtime; + + fprintf(stderr,"Elapsed time for run %d: %f\n",j,dtime); + + if(dtimemaxtime) + maxtime=dtime; + } + + tottime-=mintime+maxtime; + + fprintf(stdout,"%s\n%f %s/sec",bmark->name,numelem/(tottime/3.0),bmark->unit); + + if(bmark->type==3) + fprintf(stdout,", MPixel Fill/sec: %f\n\n", + (numelem*bmark->size[0]*(float)bmark->size[0])/(1000000.0*tottime/3.0)); + else + fprintf(stdout,"\n\n"); +} + +/***************************************************************************/ + +static void dotest1param(benchmark *bmark) +{ + float stime,etime,dtime,tottime,maxtime,mintime; + int num,numelem,calibnum,j,k; + + fprintf(stdout,"%s\n",bmark->name); + + for(j=0;jnumsize;j++) { + fprintf(stderr,"Current size: %d\n",bmark->size[j]); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime=glutGet(GLUT_ELAPSED_TIME); + + dtime=0.0; + calibnum=0; + while(dtime<2.0) { + bmark->run(bmark->size[j],1); + glFinish(); + etime=glutGet(GLUT_ELAPSED_TIME); + dtime=(etime-stime)/1000.0; + calibnum++; + } + glPopAttrib(); + + fprintf(stderr,"Elapsed time for the calibration test (%d): %f\n",calibnum,dtime); + + num=(int)((BMARKS_TIME/dtime)*calibnum); + + if(num<1) + num=1; + + fprintf(stderr,"Selected number of benchmark iterations: %d\n",num); + + mintime=HUGE_VAL; + maxtime=-HUGE_VAL; + + for(numelem=1,tottime=0.0,k=0;k<5;k++) { + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime=glutGet(GLUT_ELAPSED_TIME); + numelem=bmark->run(bmark->size[j],num); + glFinish(); + etime=glutGet(GLUT_ELAPSED_TIME); + + glPopAttrib(); + + dtime=(etime-stime)/1000.0; + tottime+=dtime; + + fprintf(stderr,"Elapsed time for run %d: %f\n",k,dtime); + + if(dtimemaxtime) + maxtime=dtime; + } + + tottime-=mintime+maxtime; + + fprintf(stdout,"SIZE=%03d => %f %s/sec",bmark->size[j],numelem/(tottime/3.0),bmark->unit); + if(bmark->type==2) + fprintf(stdout,", MPixel Fill/sec: %f\n", + (numelem*bmark->size[j]*bmark->size[j]/2)/(1000000.0*tottime/3.0)); + else + fprintf(stdout,"\n"); + } + + fprintf(stdout,"\n\n"); +} + +/***************************************************************************/ + +static void display(void) +{ + int i; + + if(frontbuffer) + glDrawBuffer(GL_FRONT); + else + glDrawBuffer(GL_BACK); + + for(i=0;i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gltest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gltest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gltest.mak" CFG="gltest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gltest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gltest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gltest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "gltest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gltest - Win32 Release" +# Name "gltest - Win32 Debug" +# Begin Source File + +SOURCE=.\gltest.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/image.c b/lib/glut-3.7.6/progs/bucciarelli/image.c new file mode 100644 index 0000000000..1ebf3106ec --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/image.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include "image.h" + +#define IMAGIC 0x01da +#define IMAGIC_SWAP 0xda01 + +#define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \ +((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))) + + typedef struct + { + 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[5]; + unsigned long rleEnd; + unsigned long *rowStart; + unsigned long *rowSize; + } Image; + + +static Image *ImageOpen(char *fileName) +{ + Image *image; + unsigned long *rowStart, *rowSize, ulTmp; + int x, i; + + image = (Image *)malloc(sizeof(Image)); + if (image == NULL) + { + fprintf(stderr, "Out of memory!\n"); + exit(-1); + } + if ((image->file = fopen(fileName, "rb")) == NULL) + { + perror(fileName); + exit(-1); + } + /* + * Read the image header + */ + fread(image, 1, 12, image->file); + /* + * Check byte order + */ + if (image->imagic == IMAGIC_SWAP) + { + image->type = SWAP_SHORT_BYTES(image->type); + image->dim = SWAP_SHORT_BYTES(image->dim); + image->sizeX = SWAP_SHORT_BYTES(image->sizeX); + image->sizeY = SWAP_SHORT_BYTES(image->sizeY); + image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ); + } + + for ( i = 0 ; i <= image->sizeZ ; i++ ) + { + image->tmp[i] = (unsigned char *)malloc(image->sizeX*256); + if (image->tmp[i] == NULL ) + { + fprintf(stderr, "Out of memory!\n"); + exit(-1); + } + } + + if ((image->type & 0xFF00) == 0x0100) /* RLE image */ + { + x = image->sizeY * image->sizeZ * sizeof(long); + image->rowStart = (unsigned long *)malloc(x); + image->rowSize = (unsigned long *)malloc(x); + if (image->rowStart == NULL || image->rowSize == NULL) + { + fprintf(stderr, "Out 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 (image->imagic == IMAGIC_SWAP) + { + x /= sizeof(long); + rowStart = image->rowStart; + rowSize = image->rowSize; + while (x--) + { + ulTmp = *rowStart; + *rowStart++ = SWAP_LONG_BYTES(ulTmp); + ulTmp = *rowSize; + *rowSize++ = SWAP_LONG_BYTES(ulTmp); + } + } + } + return image; +} + +static void ImageClose( Image *image) +{ + int i; + + fclose(image->file); + for ( i = 0 ; i <= image->sizeZ ; i++ ) + free(image->tmp[i]); + free(image); +} + +static void ImageGetRow( Image *image, unsigned char *buf, int y, int z) +{ + unsigned char *iPtr, *oPtr, pixel; + int count; + + if ((image->type & 0xFF00) == 0x0100) /* RLE image */ + { + fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET); + fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY], + image->file); + + iPtr = image->tmp[0]; + 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 /* verbatim image */ + { + fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY), + SEEK_SET); + fread(buf, 1, image->sizeX, image->file); + } +} + +static void ImageGetRawData( Image *image, unsigned char *data) +{ + int i, j, k; + int remain; + + switch ( image->sizeZ ) + { + case 1: + remain = image->sizeX % 4; + break; + case 2: + remain = image->sizeX % 2; + break; + case 3: + remain = (image->sizeX * 3) & 0x3; + if (remain) + remain = 4 - remain; + break; + case 4: + remain = 0; + break; + } + + for (i = 0; i < image->sizeY; i++) + { + for ( k = 0; k < image->sizeZ ; k++ ) + ImageGetRow(image, image->tmp[k+1], i, k); + for (j = 0; j < image->sizeX; j++) + for ( k = 1; k <= image->sizeZ ; k++ ) + *data++ = *(image->tmp[k] + j); + data += remain; + } +} + +IMAGE *ImageLoad(char *fileName) +{ + Image *image; + IMAGE *final; + int sx; + + image = ImageOpen(fileName); + + final = (IMAGE *)malloc(sizeof(IMAGE)); + if (final == NULL) + { + fprintf(stderr, "Out of memory!\n"); + exit(-1); + } + final->imagic = image->imagic; + final->type = image->type; + final->dim = image->dim; + final->sizeX = image->sizeX; + final->sizeY = image->sizeY; + final->sizeZ = image->sizeZ; + + /* + * Round up so rows are long-word aligned + */ + sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2; + + final->data + = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int)); + + if (final->data == NULL) + { + fprintf(stderr, "Out of memory!\n"); + exit(-1); + } + + ImageGetRawData(image, final->data); + ImageClose(image); + return final; +} diff --git a/lib/glut-3.7.6/progs/bucciarelli/image.h b/lib/glut-3.7.6/progs/bucciarelli/image.h new file mode 100644 index 0000000000..52ccd5b11b --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/image.h @@ -0,0 +1,16 @@ +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +typedef struct +{ + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short sizeX, sizeY, sizeZ; + char name[128]; + unsigned char *data; +} IMAGE; + +IMAGE *ImageLoad(char *); + +#endif /* !__IMAGE_H__! */ diff --git a/lib/glut-3.7.6/progs/bucciarelli/mnt.bin b/lib/glut-3.7.6/progs/bucciarelli/mnt.bin new file mode 100644 index 0000000000..0dc479b418 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/mnt.bin @@ -0,0 +1 @@ +âããå½äãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½çéëíÿû÷ŸŸ÷ŸŸŸŸ°±ÛÜÝÝÛŸûþÿîíìëëëëëìëëíïÿîìììëé½ååäãâãââãåèêëëèåãâãäå½çç½åããääåçèéêîÿûûûüü÷±ÛܲŸ÷úú÷±²°ûïîîîîïíëé½ãââââãåçåäããããâãâââãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäå½éìíîÿû÷ŸŸ÷÷Ÿ°±±±²ÝÞÞ²÷ûþïìéèèèèèèèççéëëêêêéèç½½½äãäåãããä½èêëèåââãå½çç½½½½èéèèèèèêííîîîîþú°ÜÞÛ±°°°±Ûܰúþÿÿÿÿïíëè½ãâââââä½ääãâãä½çåääåãâãäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½èìïÿþüú÷ŸŸ÷÷÷°±²²ÜÝÝݱŸ÷üîéç½åää½½åääå½½èèç½½åå½åääçèç½½å½èëìé½ãâã½èééèèèìíííìêéèêëêéèêìïüŸÜÞÝÜÛÜÜÜÝݱ÷üþüüüþîëèåââââââäåãâââãåèêèèèçåäåçåâââââââãããääãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçéêíîþú÷÷Ÿ°÷úþþû÷²ÝÝÝÞÝÛ±÷üíé½äãâããããââââãäãããäääå½çèêìëêè½½èêìëéåãäåèìëëìîÿþüûÿîëêéèç½½èëïú±ÜÞßÞÝÞÞÞÝܰ÷üþÿþûûïìèäââââââäåââââã½êìëëêèç½èèåââââââãå½çèçåããââããããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½éëíîþ÷°°°°Ÿúüÿÿþû°ÜÝÝÝÝܱ÷þìçåãââââââââââââââãåååçéêíîîîìêéèéëîíéåää½êììíÿüûú÷Ÿúÿíëè½½ååèìÿú±ÜßßßÞÞÞÝÜÛ°÷üïïþûúÿìèäâââââäååãâããä½éìííìêèééèåãâââââäçèèèççççåå½çç½åäããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãâââââãââã½èêêëîü÷°°Ÿ÷÷üÿîîïþú°±ÛÜÛ±Ÿûþíê½ãâââââââââââââãå½çèéêìïïïîìëëêêëíëçäâäçêìíÿüúûú°²Ÿûïìêèç½çéìïûŸ²ÝÜÜÜܲ±²²°÷þïÿþûúüîéåãâââãäåååå½½çèêìîïîíëêéèåãââââä½èèèèéëìíëéëíìëéè½äããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåääããå½ääåèéëëìïûŸ°Ÿ÷úûþïîîÿþüú°ÛÜÛ±Ÿúüïëçäãâââââââââââãå½çèéëìîïþþïìëëêëìíêçåäåçéëîþú÷úŸÛܱ÷þîìêèçéëíÿûŸ²ÜÛ²±±ŸŸ°±Ÿûÿîïÿûúþíé½äãâââãä½çèçèêëíïÿÿÿþîíêèåããääåçèèèéêìïþüÿïÿþÿîìêç½½åãââââââãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããäå½çéççèèç½çèéêëíþúŸ°Ÿ÷üÿÿÿïïþüüüú°²Û²°úüîëéçåãâââââââââäå½çèèéëìïü÷÷üîìììììêéèèççèéëïü÷ŸŸ±ÛÝÛ°üïìêç½èëîþú±ÛÝÜÛ°÷÷÷Ÿ÷ûþîííïüûïëéçåäââââä½çççéëìïþþþûûþïìéèç½çèèêêêêëíîþûúûûûûþÿîëéééèåãââââããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½åå½êëêéééèçèèèéìïüúŸ°Ÿûÿîïÿÿÿþüüþû÷±ÜÛ°úüîëéç½äââââââââä½ççèéêéêíþú±²÷þïîîíëêëìëëêéêìïü÷Ÿ°²ÜÝÛŸüïíìé½èìïü÷±ÛÝܲŸúúûûúüïîííïüüîëéçåäââââââãä½êëìïþþüüþÿþïîíëèèèêëììíííîÿþûûûüÿîíëêëìëéçåå½äãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããåçêëêéçç½çççèëîÿÿþüúûüïîïÿïîîïïþüú÷°÷ûüÿëéççåãâââââââãåççççêêéêìï÷²Û°úüÿîíëëíííìêêìíïÿüúŸ°±°÷ûÿïîíéçêíîïþúŸ±²±Ÿúûþüûÿîììíïïîëé½åãââââââââã½êëëîþüüþÿÿüüüÿíêêëíííîîíîïïÿüþþþÿïíììîíììëêëëçääãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½éêéè½½½çççêîþþÿÿþüüþþÿÿÿïíìíïþûúú÷ûþÿïìéç½ãâââââââãäçéç½éëëêêëÿŸÜÞÛ±ŸûþÿîïïîîîììîÿÿÿüûúŸ÷ûþÿÿÿÿïìêëííîÿû÷°°°Ÿúüþûûÿîííîííìêçåäâââââââââãèëëíïþþþÿÿþüüûþîííîîîïïïÿþÿÿþþïïÿþÿïîîîîïÿïîïîêçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½çççççèéééìÿþüþÿÿþþüüüþÿîííîþú÷Ÿ÷úûüþÿíëèåãââââããäåçééçèêêêêêíü±ß¹ßÞÛ±Ÿ÷úúüÿïîííïüüüþþüûüÿïÿþüûüîíîîîîÿüúŸŸŸ÷úüüûûÿîììííìêéçåãââââââââã½êíîîîïïÿïïÿüûúüÿÿþþÿÿÿÿþüûþÿþÿïïÿþÿÿÿÿïïþûüþÿïìçãââââââââââââââââââââââââââââââââââââââââââââââââãââââââââââââââââââââââå½ççèèéëëìîïÿüþïîïÿþüüþïîîîÿû÷Ÿ°°Ÿ÷úüþîìèäâââââãä½çèèèèèêëêêìîü±ß›­¹ÞÛÛÛ²±÷üþÿïïû÷úúüþþþÿïîïþüüüþÿïïïïÿþúŸ°ŸŸŸ÷ûüþîììììëéç½åäâââââââââäèëïïîîîïïîîïÿþüþþÿÿïîîîîïþúüþÿïïÿÿÿÿþÿïïÿûûþÿïîë½ãâââââââââââââââââââââââââââââââââââââââââââââãä½çåäãâââââââââââââââââââä½½½½çèêëëëìíîíììíííîÿÿÿÿþþûŸ±±±±²°÷ûÿíêçäãâãäãäåååçèéèèêìëìíîû±Þ¹¹ôÝÛÛÝÝܱŸŸ÷ûû÷ŸŸ÷ûûþïïííîíììîÿÿîîïÿþüúŸŸ°²²Ÿúûüÿîíìêèäããäãââââââââãåéìÿÿÿîîïïïïîîÿüüÿïîíííííîü÷ûþÿïÿþÿïïïîîïþûúûÿïíê½ãââââââââââââââââââââââââââââââââââââââââââããåçéëìëéçåãâãäãâââââââââââââãåååäå½èêëëëëêêëììëëìïÿÿþû÷Ÿ²ÜÜÜÝܰ÷ûþíé½åäãåååäääå½çééèëííîîÿú±ÝôôôÝÛÝßô¹ÞÜÜÛ²±²Û²°Ÿúüïíìììëééìïÿïïÿûúú÷°°²Üܱ°Ÿ÷ûÿïìé½ãââââââââââââã½êìîïîìëìíïÿÿþþÿïîîíîíìììíþúþÿïîîîííìëëíïþûŸúüÿíê½äããââââââââââââââââââââââââââââââââââââââääåçéêíîîîíìêç½çè½½åäããâââââââââââââäåçêëììëêééééééëîïþû°²ÛÝôôôôݱ÷úüíé½ååå½ççåãä½èéêêìîïîííÿü÷²ÞÞÞÞÞßô­œ­¹ôôÞÝÞÞܲ±°ûïìêêêèèêìïÿÿþûŸŸ°±ÛÛÜÝÞܲ±±÷ûþíéäâââââââââââââäçêìîîîìëëíïüûûþïïîííîîìëìîüúûÿïîííííëêëíïþúŸŸûÿíêè½ääãâââââââââââââââââââââââââââââââââââãåçèéëíïÿÿüþÿîíêéêéêêéè½ãâââââââââââââãä½èëëëêéç½çééêëíÿüŸÛÝÞô¹­­ôݱŸ÷üíêçå½èéêéç½½çéëííîÿþÿÿÿþû÷²ÝÝÞßßô¹œžžžœ­¹¹ôÞÜܲúïìêééèéìïþüüûŸ²²ÛÜÜÝÞÞÞÞÝÝܱ÷ûïê½ãâââââââââââä½éìíííííîïþüúú÷üÿïîííïïíëìÿú°Ÿûÿïîïïïîïïÿüûú÷úûÿîëêè½äãââââââââââââââââââââââââââââââââââä½çêëíîÿþüûûÿíëëééç½½½½½äââââââââââââââââãåçèéèç½½çéêìíïü÷±ÛÜÞßÞÞÝÛ±Ÿ÷ûïíìçå½éêêééééêìîîîïüûûûûûú°ÛÜÝÞÞßßô››œžœ››››­­ßÜ÷þîëìîîÿü÷ŸŸ÷Ÿ²ÜÜÝÝÜÝßßßßßÞݰúþîëçãââââââââââã½éëííîîíîïþû÷÷°±÷üÿîííîííìíïú±°÷üÿÿþþþüûû÷÷÷÷úûûüïììëéçåâââââââââââââââââââââââââââââââãäåçéêíîîÿüûú÷÷ÿíëêéçåäãâäåãâââââââââââââââââãä½ç½å½çéêìîïþú±ÛÝÝÞÞÞÝÛ±°÷ûÿîíìéçèêêéêëììíîïþþû÷°ŸŸ°±±ÛÝÝÞÞßôô¹­›œžžžžžžž›ßÜŸüïíïüúŸ±ÛÜÛ±²ÝßôôßÞÞôô¹¹ßÞݱúþïìéäââââââââââã½êëìîïïïïþ÷±²ÜÜÛ°÷þïìëìíîïÿþú°±°úüûúúúúû÷°÷÷÷úûûüÿïïîíëèäââââââââââââââââââââââââââââããäå½èêëîîïþûû÷ŸŸûÿëèåãâââãääâââââââââââââââââââãäääå½èêíÿüú°ÛÜÜÜÝÝÞßݲ°Ÿúþïîîîìêêëêêëìììíïû°°°°±²ÛÝßÞßôôôôßßô­›œ›››œž»º›ôݱúþþû÷±ÛÝßßÞÝÞß¹¹­›­¹­­›¹ßßß²÷ûþîëçäâââââââââãçììíÿþþüû÷±ÛÝÞÞÞܰûïëêëíÿüüûŸ±±°÷÷÷ŸŸŸ÷Ÿ±±°ŸŸ÷ûüþþþüüüïë½ãââââââââââââââââââââââââââäçç½èêëìîÿÿÿüû÷Ÿ°°÷ÿê½äâââãäääâââââââââââââââââââââããäçéìïü÷²ÝÞÝÜÝÝÞÞÞÜÛ²Ÿúüþÿïÿïîíììëíííîÿú±ÛÛÛÛÛÝÞ¹œ››­­¹ôôô­žžžœ­­œ©ª¼»›Þ²÷ûûŸ²Ýô¹¹¹­¹¹­œžžœžœ¹ôôÞÛ±ŸúþîéåâââââââââãçìîïÿüûúŸ±±ÛÞßßÞÛŸüíéèéëîïÿû÷Ÿúúú÷÷÷Ÿ°°²²±±°Ÿúüÿïïþûûûïêåãââââââââââââââââââââââââãåçèéëìîÿüú÷÷÷Ÿ°°±Ÿ÷ûïëçäãââãå½½ãââââââââââââââââââââãä½èêíþû°ÜôßÝÝÞÞÞÜÛÛܲ°Ÿ÷úûüüþþïíííïþüúŸ²ÛÝÝÝÞô­œºœ›­¹¹¹›žºººž››ž©¼¶ø®œôܱŸŸ±Ûß­­¹­œžºººº›­­ßÝÝÝÛ°üíèåãââââââââãçíÿÿþû÷°ÛÝÝÝô¹ôÞ²÷þìéçèëëìïüûúú÷Ÿ°°±²ÛÛÛ²²²²°÷úþÿÿüú÷úÿëçäââââââââââââââââââââââãåèééêìîÿû÷Ÿ²ÜÜÛÛÛ±°Ÿ÷ûïë½åãââãä½çäââââââââââââââââââââãåçéìÿú÷±Þ­ôÞßôßÞܲÜÜÛ²²²±°Ÿ÷úúþïïÿû÷°ÛÝßßßß¹›žº©»®»ºžžœœººœœ®¶ýñ¶®º­ßݲ±²Þ­žœœž»¦»»»»©©œœ›ßÞßÞܱúÿìé½åâââââââäèìîÿüŸ±Üß­­­­­ôݱ÷þïëééêêëîþûŸ°±°±ÛÜÜÝÛ±°°²Û±°úüüüûŸ°÷üïê½ãâââââââââââãäääãââââäçêêêìîïþ÷±²ÛÞôßÝÝܱŸ÷÷þíèåãââââäççåäääãââââââââââââââââä½éíÿûŸ°²Þ­ôß¹­ôÞÛ²²²²ÝÞßßݲ°Ÿ÷üüûŸ±ÛÝô›œ››žº©»¦ªª®®¦©©»»»»»ººº»ªñæùæñ®œ­ôßô›žºº¦ªÈÈȼ¼ª¦»©ºž­ôÞÞÞݲŸþíêçãâââââã½éëîÿú±Üß¹œžž›­ÞÛ°úüïìëëëëëìïû°°°°°²ÛÜÜÛ°Ÿ°²ÜÛ°÷÷úû÷°°Ÿúþìçãâââââããããäåççç½äãââã½êììîÿüúŸÛÝßô›œ›ôÞݱ÷÷úþíèåââââãå½ååå½½ãââââââââââââââââäçêîüú÷°²ß­­­›­ôÝÛ±°±Üß¹›­ôÝÛ±Ÿ÷÷±ÜÝô›©¦®ª¦®Èȶø¶Èª¼¼¼ªª¦©»»¦ªª¶ýù§ù´¼»œ››žº©©»®¼ÈññññøÈ®¦»ž›ßÞÞÝÝÛŸüïëçãââââãåèèéíþ÷ÛÞô­››­››Þ²Ÿ÷üÿïîìëêéëíÿûûûüþüúŸ±ŸúúŸ±Û±±±±Ÿ÷Ÿ°ŸŸ÷ûïêçäâââãäå½½çè½äääãââââåéìïþü÷°²ÛÝôœº›ôÞܰŸŸ÷ûÿìèäâââââââãå½½ãââââââââââââââââã½èëîïüú°Ý¹­›­­ôÝÛ±°²Ý¹››¹ÞÞݲ±±ÛÞ¹›žº©»»»»»¦¦¦¼øøøñýñø¶øø¶¼ª¼¼ª¼È¶ýæ·¸ý¶ª»œ©¦®ªÈøññøø¶¶¼®¦»ºž›ßÛ²±±±÷üïìèäâââââåèéèêîû±ÜÞ¹››¹¹››Þ±°ŸûþþþïíêêêëíïîíííîïüúúûûúŸ±±²²²±°°°°±±°úÿìçäâãäçèéêêé½ãââââââãåéìÿú÷±ÛÜÜÞ­©©›ôܱ°±±÷þîëçäââââââãäåäââââââââââââââââââäçêìíÿüŸÛß¹››­ôÝÜÛÛÜÞ­››¹ôôÞÝÜÝÞ­»®¼¼¼ª®ª®®ªøýñýµµ´µµýøøýýýý´´µ·¸ùæý¶®»º©»¦ªÈøýæµýýñø¶¼®¦»º›ôÛŸ÷÷úúüïíìèäâââãäèèèèêîú²Þ¹›œ›­­­­ßÛ²°úüüüÿîìëééêëëêëëëíïüûüþþû°²Û²±±±²²ÜÝܲŸûîêçååçéêìììëçäããââââãçëîüŸ±ÛÛÛÜôœ©®ª»­ßÛ±°ŸûÿïìèåââââââââãäââââââââââââââââââãåçéìïüŸÛßô¹¹¹ôÞÝÝÝÝß¹¹¹ô¹¹ôßßß­»ª¶ñ´ýñøøøñøøññ´æù§¸·µµµæ·¸§§¸··§¯§·µñ¶®¦¦¦¦¼ñµ·§ùæµýø¶¼®¦©¹ÜŸûüþÿïîîìëçäââãä½êéçéìÿ÷ÛÞ­œžž›¹­­¹ÞÛ²°ŸŸŸúþîìêéèèèéééêëíÿüþïïü°Ûܲ±²²ÛÝß¹Þܲ°üîëèéêìîîïïîê½äãããââäèíÿú°ÛÝÝÝÞ­ž©¼Èª»ž¹Ü±Ÿ÷üþïëçäââââââââääâââââââââââââââââââãåèëïû°ÛÝß¹¹¹ôÞÝÝÞÞßßßß¹››­¹­›»¼ñµù§·ææææµ´´µù¸¯¬«¬§·ù¸¯«¨¨¾¾«¬¬«¯¸¸ùµñȼ®¦ªÈ´·¬¾¯·æ´ýñȪ¦©žÞ±ûÿïîìëìíìêçåååå½êîìêëíþ°Üßô­œž››œž›ôÜÛÛÛ²±÷üïïíëéç½½å½çèëîîííïû±ÝßÝÜÛÜÝß¹­ßÝÛ²÷üíêìîïÿÿþÿÿíéçåååäâãèîûŸ±Ýßßß¹œ©ªÈ¼»žßܲ±Ÿûþîéåââââââââââãââââââââââââââââââââåèìÿú°²Ýô¹¹¹ôôÞÝÝÞÞÞß¹›žœ›œ®¶´æù¬¨«¯§¯§·ù·¸§¯¬¾¾«««¯¯¯¬«¾¨¨¨¨¾¾¾«§¸ùæ´ñ¶Èª¼¶øµ¸«¨«¯¸ùµñ¶ª©ž­Ý°þíìëêëíîíëéééééëîþïííïü°ÜÞô­›œœžºž›ÞÛÝÞÝܱ÷üÿíëéçäãäåå½êìììíïû²ß¹ôÞÞßß­žœôÞÝÛ²÷ÿíîÿþüüûüüîëéèèçåäåêþŸ²Ûß­­­œº»¼øÈ¦œßÞݲ°÷ûîèäââââââââââââââââââââââââââââââãåéîûŸ°²Ýô¹­¹¹ôßÝÞßÞÞô›œ©»¼ñ§¯¬ÀŽÂÀÁÀ¾¬¯¬««¾¾¨¨¨¨ÀÁÀ¿¿¿¿ÀÀ¿¿¿¿¿¨¾¬¸´ýýñ¶øñýµù§¾¿¿¾¬§·´È©œôݰüíìëëíîîíìëêëíïïþûüüüüû°Üô›©©©©›ßÞß¹­­ÞÛ÷þìèåäâââââã½éêìíÿú²ß¹ôôôô¹›žž¹ÞÜܲ°úüüüüüüûúûÿîììêéç½éï÷²ÜÞ›ºº©»¦¼ø¼©œ¹ßÝÜÛ°ûíçãââââââââââââââââââââââââââââââãåéîúŸ±Üßôô¹›­ôÞÝÞÝÝÞô›žº©¦¦¼ýù¯¿¿Á’€’€’ÂÁÀÁÀÀÀÁÂŽŽŽŽŽŽŽŽÂÀ¿¿¿¨¨¬¸µ´´ýý´ææù¸¬¿Â¿¾«¬§·ùæø¦œÞ²Ÿþîîïïÿîíìëêëîþþüûüú÷úûú±Ý¹œ»»©©ºž­ôß¹››­ôݰþìèåäãããââã½èêíïþŸÜß¹¹¹¹¹¹›žž­ÞÜÛ²±ŸúûüþþüúŸ÷ûÿïîìêééíü°ÜÞ¹©»»©©»®È¶ª©­ÞÝÞݰûíçãâââââââââââââââââââââââââââââä½èëÿúŸ±ÜÞßß¹œ¹ôÞÝÝÜÜÝß›ž©¦®¼ø¬¿ÂŽ’ÅÍÆÅÆÆÃ’’ŽŽ’ÃÃÃÃÀÃÃ’ÂÀÀÀÀ¿¾¬¸æææµæ··§¬¾ÁÂÀ¨¾¬¯§¸ùýªß²÷ÿîîïÿþïìëëëíÿþüúüÿþüÿÿûŸ±Üß›žžœ›­ôßÜÜÝÞßôßÝŸüïíêèèè½å½çéêíþûŸÛÞô¹¹¹ôßßô¹­ôÝÛܱ÷ûüþþïîïüúŸûÿÿïíìêêìïû±Ý­ž©º¦ª¼¦œ¹ßÞܱûïêåâââââââââââââââââââââââââââââåèëíïþûúŸ²ÝÝÝß¹ßÝÛÛÛܲ²Ý­¦¦®Èý·«¨ÁŽ€ÆÏÇÇÍÍÇÅÃÃÃÅÅÅÅÆÆÆÆÆÆÆ€ŽÂÁÁ¿¨¬§··ùù¸§§¯¬¨ÀÀ¨¾¬¸¸§¸ùñªß²ûîëêêìííìëëìîïïÿþïíïïîîþû÷°Üß­›­ôßÞÝܱ±²ÛÝÞÝÛŸûûþïîîìëêëíííþ÷±ÜÞô¹››­ôÞÝÝÞßÝÜܲ÷üþþþÿïïîÿúŸüïïïîíììíïüŸÜ¹œžº©¦¦©º›¹ôÞ²÷ÿíèãââââââââââââââââââââââââââââäéíÿþÿþüú÷²ÝÝÝÞßÜÛÛÜÝܲ±Ý›®ªÈøµ§«¨ÀÂ’ÆÐÏÏÏÐÏÍÆÆÆÍÍÍÇÇÆÆÇÆÇÍÏÍÏÐÏÅ€ŽÂÁÀ¨«¬¬¯§¸§¬««¬««¨¨¾¾«§¸¸¸¸·´È¹²üíéèèéêìíìêìïïîîíììíííîÿüû÷±Ýô­ôÞÝÝÝܲ±°±ÛÜÝܱ°Ÿ÷ûûüÿïÿüûüûŸ²ÜÞ¹››œ››¹ÞÜÜÞÞÝÝÛ°üïïïîïÿÿïÿûúþïíííîîïÿüúŸÛô­žœ››œººž›­ßÜŸþíë½ãââââââââââââââââââââââââââââ½ìÿûüþüûú÷±ÛÜÜÝÝÛÛÜÝÜÛ²Ûßœªø´æ¸¬¾¨¿Â€ÇÉÐÏÍÏÍÍÇÍÏÉÐÏÍÇÆÆÅÅÅÇÇÍÐÑ¥ÐÆ€ŽÂÀ¿¿¨¾¾¨¿Á¿«««««¬¬¯¸¸¸¸§¯¯ùý®œÛüëççèéêëíìëìíííííìììíîîïÿþú°ÛÞßÝÛÛÜÝÝÛ²°±²ÛÜÛ²²±°°Ÿ÷úú÷Ÿ±²ÛÝÝß¹››œœœœôÝÛ²ÛÝÝÛ±úþïíìíîÿÿïÿþüþïïïïïþûú÷÷°ÛÞ¹­¹¹­œœžžžœœ­Þ±ûîëèåãââââââââââââââââââââââââââãäéîûŸŸú÷÷÷Ÿ°±²ÛÛ²±²ÜÝܲ²Üôœªñ¸¬¾¨¨¿ŽÏ¥¥ÉÏÍÍÏÏÐÉÉÐÏÍÍÇÅÅÇÍÏÐÉÒÔÓ¥ÍÅ€ŽÁÁÁÀÀÁ۬«¬¬¬¯¸ù·¸¸§¬¬¯ù´¼Üûë½çèêëìíííííîïíììíîïíììîÿû÷°²ÜÛ²ÛÜÜÜÛ²±±±²²±²Û±±±±±°ŸŸ°ÛÝßÞÞô­­¹­­­¹ÝÛ°Ÿ÷ŸŸŸúüþþîíîïïïïïïÿÿþûúúúú÷÷÷Ÿ±ÛÜÞßô¹­››­œœ­¹ôÛ÷ÿëè½ãâââââââãäääããâââââââââââââä½çëÿú±²²²²±±°ŸŸŸ÷úŸ±Ûܲ±²Üß›º¦øæ§¾¿ÁÂÍ¥ÔÔÑÏÇÍÐÐÏÐÉÐÐÐÐÏÍÐÑÒÓÔÔ™™ÒÐÇÅ’ŽÁÀÀÁÀÁÂ’Å’À¾¬¬¬§···§¯¯§ñ¦›Ûûë½çéìîîïïïÿþÿïíìíïïïìëììïþüûŸ±±²ÜÜÛ²±°°±±±±°±²²ÛÜÜÜÛ±°ÛÞ¹­¹¹­›­¹­­¹ßܱŸ÷üþüüþþüþÿïÿÿÿïïïïïÿûŸ°°±±±ŸŸ°±²²ÜÝôôô¹ôôœž›ôÞÜŸþìèåãâââââãâã½ççç½åââââââââââââãçéìïþŸÛÞÞÞÝÛ²°úûþÿþúŸ±²±°²ÜÞ¹ž»È´§¨ÁŽ€ÅÍÉÔÖÊÒÉÏÐÉÐÏÉ¥¥ÑÑÑ¥¥Ò™ÊÖ××ÖÊÒÐÇÅ€ŽÀ¨¨ÀÀÁÆÍŽ¿«¬¬·æù·¸¯¯¸µÈ»›ÜúìçèëîÿþþüüûüüÿïîïÿïíêêëíïþþüûúúŸ±²±Ÿ÷Ÿ°²±±±±±²ÛÞô¹¹ôÞÞô­œžœœœžœ›œ›¹ßܱ÷üïíììíïïïÿþüüþÿÿÿÿïþ÷°²ÛÜÜÛ²²²²±±²ÜÝÞÞÞÞô­œ­ßܱûîéåãâââââäåå½èêêêé½ãâââââââââââãèìÿþû±ÝÞÞÞÞÝÛŸüïíîïÿü÷±ŸŸ²Üß­¦È´¸¾Á’ÅÏÉÓÖØÕ™ÑÐÏÏÍÐ¥ÒÔ™ÓÓÔÔ™Õ×ØØØÖÕÓÉÍÆÃŽ¿¾¾¿ÀÂ’ÍÐÆ€Á¾¬§ææù¸§¯¸ýÈ»œÝ÷íéëíïûúúŸ°ŸŸúüÿÿþþïìëëìíîÿÿþûúú÷°²°úúŸ±²±²²±°²Þ­œžžœ­¹›žººžžžžž›ßݲŸþíéééêëíïþûûûüÿÿÿïÿûŸ±ÛÝÝÝÜÜÜÜÜÛ±²²ÛÛ²²Ýô›ž›ß²Ÿþíèåãââââãå½çéêëêêéçäâââââââââââåëÿú÷°ÜÞßÞÞßܱúþîíííïþú÷Ÿ±Üß­œº¦È´¸¾Â€ÆÉљך×ÕÓ¥ÐÐÉ¥Ò™ÕÖÕÊÕÕךËËššØÖÔÑÐÆ’À¾¿ÁÂŽ€ÆÏÏÇŽ¿«¯¸æ·¸¸¸ùµñȦžÞŸÿìíÿûŸŸ°²ÜÛ±÷üþþüûÿîíîîïïÿü÷Ÿ°Ÿ°²Û°÷÷°²ÛÛÜÜÛÜÞ¹›žºº›­›œžžœ›œžžœ¹ÞÛ÷ÿëèééèêìïÿþþþîìíïÿûûúŸ²²²²ÛÛÛÛÝÜÛ±ŸŸ°°²Ý¹žºœôܰûïêçäââââââãäçèèçèéè½äãââââââââãèîüŸŸ°ÛÞÞÝÝܲŸûÿÿþþþþþûŸ²ÜÞ­œ»ª¶´·¬¿ŽÅÉÒ™ÖØ×ÊÔÑ¥¥ÒÓ™Õר×××רššËËËØ×ÊÔÐÆ’À¨Á’€ÆÇÍÅÃŽÀ¾«¯¸··ùùùµýøÈ»žß±þìÿ÷±Û²±²Ü±÷ûüÿþûûÿîîïÿþþü÷°ÛÜÛÛÜܲ±±²ÛÝÞßÞÞô¹›ž»»©ºœœ›œžœ­œº»»º­ßÜ÷ÿëéééèèêìîÿÿîëêìïüûüû÷°±²ÛÜÜÜÞßÞÜŸûûú÷°Ûôœºœ¹Ý²Ÿüíé½ãââââââãå½çççèéçåãâââââââä½ëÿ÷°Ÿ°²ÜÜÜÛ²°÷ûüûûúûüû÷°ÜÞ­¦¼¶ñµ·§¾ÂÅÉÓÊØš×™ÓÑ¥ÑÓÊÕ××šššØØØššÌÌËš×ÕÓÐÆÃ’ÂÁ’ÅÆÆÇÆÆ’ŽÁÀ¨«¬§¸ùææ´ñ¶¼»žô±üïû±ÝÞÝÛÛ²ŸúúûþþüûûüüûúŸúúŸ²ÝÞÝÜÝÞÝÜÜÝÝÞ¹››œœœ»®¼ª®©ºž›­›œœ©»›ôÜ÷ÿìëéèçèéëíïïìêèêîüúú÷÷°ÛÝßôôôôßݱ÷úú÷Ÿ±Üôœºž­ßܱ÷þíêçäââââââãäç½½èèåãâãâââââåçêíþú÷÷Ÿ°±²±±±Ÿúûûûûûú÷Ÿ°±Ûßœ»®¼¶ýæ·«ÂÐљךÖÔÑ¥¥Ò™ÕÖÖךšššËšËá…ÌËšØÊÒÉÍÅÃ’€ÆÍÏÍÆÅÃÂÂÂÂÀ¨«¯·æææµý¶®œß²÷üŸÛÞôÝÛ²±°°÷ûüûûûú÷÷Ÿ°°ŸŸ²Üß¹ôßßÞßôôßô­žºº©®¼¶È¼¦©›­¹­œ©»žôÜŸüïìêèèéééëîìêéçéíü÷÷÷÷±Üß¹­›­¹ßݱ÷úúŸ±²ÜÞ›ºœ¹ÞÛ±÷þîë½ãââââââä½ååç½åäååãâââåéëíïüúŸŸŸŸŸŸŸ°°÷ûû÷÷÷÷ŸŸ°±±Üôž©®ªÈøý´µ¬ÁÃÍ¥ÓÖØÕÔÒ¥ÑÔÕ××ÖØËËÌááÌá ƒ…áÌšÕÔÑÐÇÆÅÆÇÐÉÍÆÅÃŽŽÁÀ¨¯ùæµµµµý¼©­ßܰŸÛÝô¹ßܲ±±±÷ûûûüþþüû÷÷÷÷°Üß¹­­­¹ô­œœœ©»»¦®¦»®ª¶ñø¼¦»ºººžœ­­›œ¦­ßÛ±÷þïíììéçéêèèèéìÿüû÷Ÿ±Ûß­›œ›¹ßÞÝÛ°÷÷Ÿ±²ÛÞ›º›¹ôÝܰûïë½ãâââââããããäå½çèèè½äãä½èêìîü÷±Ÿúûûûûúúûüû÷÷Ÿ°°°±±²Üßœ®¼¼¼Èññ´¸¨ŽÅÍ¥ÔÊ™™ÓÒÓ™ÖØššÌá…ƒƒƒ  Ù„„„Ù ËÖÔÑ¥ÐÆÃÅÇÇÆÅÅÀ’’ÂÁÁ¿«§´ýñøÈ®œßݲ°±ÛÝô­ôÝÛ²°Ÿûþþþÿîîîþûú÷Ÿ²Ýô¹›œœœ›žº»®ªª¼Èȼ¼¼Èø´ñ¼®¦©ºž›››ž©¦©ºœ¹ßݲŸúûþïëéèçååèëîþüú÷°Ûß›žºœôÞÞÞÛ°Ÿ°±±±ÛÞ›ºž›››¹Ý²÷þëçäââââããââãä½èééêëéèèèèéëìïû°²°÷ûüûûüüüüú÷÷Ÿ±²²²²²Ý­©ªª¦®¼¶øý·«ÂÃÇÐÑÔ™™™Ô™ÕØËÌá…ƒ†‡‘„ÙÙ‘‡‡‡‘„…ØÕÔÒÐÆÃÃÃÆÆÆÆÆÅÀÂÁÁÀ¾¯ùµñȪª»º­ÞÛÜÜÝÝÞ¹­¹ßÝÛ°÷üÿÿÿïííîþúŸ±ÛÝô­›œœžº»®¼¶¶øýµµýñññý´ñ¶¼ª®¦©ž››œ©¦¦»©º›ôßÝÛ±÷þíé½åäåèëîÿüúŸ°Ý­ž©»­ôÞÛ±°°±²²ÛÝß­žž­Þܲ÷ÿë½äãâââââãä½éêêêëíìììììîîîþ÷±Û²°úüþþÿÿïþû÷÷Ÿ°±±²ÛÜôœ¦®¦¦®®ªÈýù«Á’ÅÏ¥ÓÔ™™™ÊÖØË̃„‡‚ˆŠŠ‡ŠŠŠ‡‡‡‘ šÖ™ÑÐÍÆÅÅÃÅÇÇÇÅÃÀŽÂÁ¾¯·ý¼¦©œôÞÞôôôßßô¹¹¹¹ôݱûþïîíëìîÿ÷±ÜÞß¹­››œº©»®Èñýýæù·ùæµ´ý´´ýø¶ÈȪ¦ž›œ©¦¦¦¦¦©›­¹ÞÛŸüîéäâã½èìîïþû÷±Þ­©»»›ôܱ°±±²ÛÛÛÜÞô­œžœ›ôÞÝÛŸþìçäââââââãä½ééêêìíííîîïÿÿþû÷±Û²°úÿïïíìíïûŸŸŸ°±ÛÛÝô›¦¼¼ªª®®ªÈñ«ÀÃÇÐÑÒÓÔ™ÊÖØË „‡‚ˆ‰‰‰‰‰‰ˆŠ‘‡‘ Ë×ÊÓÑÐÍÇÅÃÃÆÍÏÏÆÃ’ÂÀ¾§¸ù´È®©ºž¹ß¹›œœ›­­¹­­­¹Þ²úþîìëêëíïüŸ²ÛÜÝÞô­›žžº©¦ª¶ýæ·¸·æµ´µæ´¶¼¼ªª®¦©©¦»©©¦®»ºœ¹ôÞ²Ÿûþíéäãäçèêëìíîÿ÷ܹ››œž›­Þ±ŸŸŸŸ°±±²²²²ÜÞßÜÛ±°Ÿ÷þíçãâââââââââãä½½½çèéêééëìïüûú°²²±úÿïíëêíþûŸ°°²ÜÝÞ¹œªøøøÈ¼Èøñ´·¾ÁÃÅÍÐÉ¥ÒÔ՚˅ Ù†Š‰‰‚ŠŠ‘ Ìš×™Ò¥ÐÏÏÇÇÏÐÉÐÇÅÅ€ÂÀ¾¬§·´ø¼¦©œ¹­œžž›­¹ôôßݱ÷üíëêèêìîïûŸ±²²ÜÞô­››ž»®¶´æù¸¸ùù··µøÈª¼È¼ª®®¼È®©©¦¦©ºž¹ÞÞÜŸûþïìéåãå½½çèééêíû²Þßßô¹ôßÛ°Ÿ÷÷÷÷Ÿ±±°Ÿ÷Ÿ°Ÿúúüþþþíèäâââââââââââãäãããä½ç½½çëÿú÷÷Ÿ±²²÷þîìêêíüú°±²ÜÞô¹œ¦¶´µµñøýµæ§¾Á’ÃÆÇÏ¥ÓÊ×Ë… ƒƒ†‡‰¡¡¡‰ˆˆ‚‘Ù …Ì×ÊÔÒ¥ÉÐÉÑÒÑÉÍÆÅÅÿ«¬§§ùµ´ñȦºžž©©ž­¹ôßÞܲŸüíëéèéëíïþúŸ²ÛÜÜÞô¹­œ®øýµù§¸··¸¸§¯¸æýø¶¶È¼¶¶ñ´ý¶®»©ºž­ÞÜÝÛŸüïîëèååååååååä½ëþ°ÜÝÝÝÞÝÛ±Ÿúú÷÷ú÷ŸŸúüüüïîîíëêëë½ãââââââââââââââââââããâã½êÿ÷°±±²²±Ÿúïëééíþ÷±ÛÜÝôô¹œº»¼ýùùùæµæ·¯«¿ÂÃÅÆÆÏ¥Ó֚჆†††‡‚‰¡‹Œ¡¡‰ˆŠ‘„ƒƒƒÌÖ™ÓÓÔÔ™™ÔÒÉÍÆÅ’ŽÁ¨¬¯§·ææµñ¼¦©º»¦¦©œ¹ßÝÛ°÷üÿíëèåèëíîïþ÷±²ÛÛÜÞßô¹œº®¶ñµ·¯§¸¸§¬««¯ùµýøø¶øñ´ææñÈ®ž›ôÞÜÜÛ°ûÿíêè½½½½ååäãâäêïú±ÛÛÛܲ°Ÿ÷ûûûûûûúúþïîëéèèçåå½åâââââââââââââââââââââââãåêÿ÷°²ÛÜÜÛ±÷ÿíëëîû°ÛÝß¹­­›º»¼ñ游¸¸··¸¬¨ÀÁ’ÅÆÆÇÏ¥Ô֚ᆂ‚‡‘‡ˆ‰¡‹‹Œ¡ˆŠ‡‘‡‘‘ šÖÕÕÖÖÖÕ™Ó¥ÏÇÆÃ€’ÂÀ«¯¸ùæ´øÈª¦¦®ªª¦ž­ÞÛ°úüÿîëé½äçêëëíÿüú÷÷Ÿ°±±²Üß›¼ñ¸¯§¸¸§§§§¸µýñýµæµñ¶®©ºž­ßÝÛÛ±úüÿîëéç½½½½çåãâã½êîü÷±²Ü²°Ÿ÷ûüþÿÿïïîëéçåäåäãââââââââââââââââââââââââââââãèíþú±ÛÜܱŸúüÿîîþ÷±Üß­ž¦¼ø´ù§§¯¬¬«¨Á’€ÃÃÅÇ¥ÓÕØ…‘ˆˆŠ‡Š‚ˆŒŒŒ¡ˆ‚ˆˆˆ‚„…ÌËšØ×ÕÊ™ÒÉÍÇÆÅ€Ž¨¬¸¸·ùµ´ñ¶ÈÈȶ¼¦ºœôܱúüïíëéçååèêéèëîïÿþüúúúŸ°±Ü­®øæ¸¬¬¯§§¸¸§¸µýýæù¸¸·ùµý¶ª¦©­ÞÝݲŸûþïîìëéç½½½çåãââã½éìþ÷²Ü²±°°÷üþÿîíëéçåãâââââââââââââââââââââââââââããââââã½êíþŸ²ÜÛ²±°úûüüúŸ²Þ­©»®ª¶ñ´¸¬«¾¨ÀÁŽ€ÃÅÅÇÉÓÊš ‡‰ˆ‚Š‚ˆ‰¡‹Î΋ŒÎΡ¡ŒŒ¡‰Š‘„ …áØÕÊ™ÓÑÐÇÇÅÀ€À«¬¯¯¸···ùæµ´ñññÈ»›Þ±úþïìêéç½åçèèç½éìììîþûú÷ŸŸ°Ü¹œ©¶æ¸¬«¬¯§¯¬¯§ùæµæù¸¯¯§·æ´øÈ¼¼¦º›ßÝܱ°÷üÿîìêçåäãäåääãããå½éíü°Û²±±±Ÿúþïíëè½äââââââââââââââââââââââââââââãäãâââââåçêïú°²ÛÜÜÛ±°úü÷±Ýô›º¦Èñ´µ·§¬¨¿ÀÂŽ€ÅÆÆÅÅÍÉÑÊØá†‚‚ŠŠˆ‰ŒÎ•¢¢¤¤•¤‹‹‹‹‹Œ‰ˆŠ‘Ù šÖÕÊ™ÔÑÏÆÃ€’’’Á¿¨¨¾««¬¯§¸ùµýýñª›Ü÷ÿíëëéèç½½ççç½½èééëîïþûúú÷ŸÛô›¼ýù¯¬¬¯¬««¬¯·ù·§¯¯««¬¸´ñø¶¶ª©œßÝÛ±°÷úÿíëêçäââãååäãââãä½êîû°ŸŸŸŸúüÿîêçåãââââââââââââââââââââââââââââãääãâââââãäçìþŸ²ÜÝÝÜÛ±÷÷°ÛÞ›ž»È´æù·¸¯«¨ÁÂ’€ÃÃÆÆÅÆÍÍÍÇÆÇÐ¥ÒÊØ…‘ˆŠ‡Š‚¡Î•“ÚÚ““•Î΋‹Î‹Œ¡ˆŠ† Ë×ÖÊÊÊÒÏÆ€’’€ÂÂÂÁÀ¿¨¾«¬§ùµýñ¼©º›Üúïìêêéèèçç½½½åå½ééêêëîÿþüû÷²ß¹ž»È´·¸¸§¯«¾««¬¬¬¬¬¬¬¬¬§¸¸µ´ñȦº­ôßÛŸûüïìêéçäããå½åäãââããä½êïüþÿîíëêé½ãâââââââââââââââââââââââââââââââââââââââââäèëïû÷Ÿ±±±°÷÷÷°Ûôž©¼ø´æù¸¯¬¨Á’€ÃÅÅÅÅÍÐÐÏÏÏÏÉÒÔÕÌ„‚‰ˆˆˆ‰Œ‹¤¢¢•••ÎŒ¡‰ˆ‚‡†ƒ…ËšØÖÕÊÓ¥ÏÇ€ÃÅ€’ÂÁÀ¿«¯¸æ´È¦º­Þ²úþîìêéèçåäååå½ççççèêëíîÿú°Üô­œ®øµù¸§¯«¾¨¿¨¨¨¨¨¾««¬¯«¬¯¸·æý¶¦ºœô²Ÿúüïíëéç½½çééèåãââãâãäçëíìé½åääãââââââââââââââââââââââââââââââââââââââââââã½èëîþûúú÷Ÿ÷÷ŸŸ²ß›®Èñµù¯«¿Â’ÃÀÃÅÆÅÅÍÉÉɥѥÐÑÔÕšƒŠ‰¡ŒŒŒŒŒ‹Î¤¤Î¤¢ÎŒˆ‚ˆ‚‡††„ áááášÖÊÔÓ¥ÏÇÆÆÆÃÃ’ŽŽÂ¿¾¬·ùµø®­ôݰúþîìëèåãããåçéçååå½çéêìÿ÷²Þ­›ž®Èñ港¬¾¨ÀÀ¿ÀÁÁ¿¨¿¿¨ÀÀ¿¨¨¾§æø®œßܲ²°úüïíëêêëëêèåããäåååäå½½äãâââââââââââââââââââââââââââââââââââââââââââââââå½èëîÿûþþüûú°²Üôœ»ªø´ù·¯¾ÁހůÃÃÆÇÍÏÉÑÑÒÒÓÑ¥ÓÊ×ᄊ‰ŒŒŒÎ¤Î¤¤¤ÎΕ¢¤Œ‰‚Ї‘‘††„ÙÙƒƒ áØÖÊ™ÑÉÉÐÏÍÇÇÇÍÇÅÀ’ŽÀ¿«§ùæø¦­ôÞܲ÷þîëè½ãâã½éé½åäãä½çèëÿ°Ýß­œž»ªøæ·¬¾¾¨ÀÀÁÂŽÁÀÁÂŽŽÂÂÁÀ¾¸´È»ž¹ßÞÝܱ÷ûÿîíííìëé½äää½åäãâââââââââââââââââââââââââââââââââââââââââââââââââââãå½éíÿüüÿïÿûŸ²Ýß›»ª¶æ·¯«¿Ž’ÅÇÍÆÆÅÆÏÏÐÉÑÓÔÔÓÑÑÔ×̃‘‚¡ÎÎΤ¢•¤¤Î‹Î•¢ÎŒˆŠ‡‘‘‘‡‡‘‘††„Ù ÌØ×ÕÔÒÒÑÉÏÏÐÐÐÏÇÆÅ€ŽÂÀ¾¯·µ¶¦º›¹ôôÞ²÷þîê½ãâã½çç½äãââäå½êÿ÷ÛÞ¹›œº©ª¶ñ´¸¯¾¿ÂŽŽŽ’’’ÂÀ¿¬ùýȦ©ž­ôÞÜÛ±Ÿúûþïîîíé½ääåäâââââââââââââââââââââââââââââââââââââââââââââââââââââä½çëîþúúüþûŸ±ÛÜÞô›»ªøµù¯¾ÀŽ€ÆÇÍÍÍÆÅÆÇÍÐ¥ÑÔ™ÓѥљØá„Љ‹•¤‹Î¤ÎŒ¡¡¡‹¤•Ρ‰‚ŠŠ‘‘‡‚‚ŠŠŠ‡„Ùƒ…áËØÕÔÓÑÉÏÐ¥ÉÉÐÏÍÅ€’ŽÀ¾¬·µ¶®»ºžœ­ßÛŸüîèäââãäåç½åäâââãåêÿ÷²Ýô­›ž¦ªÈøñµù¬ÀŽ’€€’’€ÃÃÀŽÂ¨¯ù´ø¼»º›ßßßÞÝÛ²÷ûûûþíèäå½ãâââââââââââââââââââââââââââââââââââââââââââââââââââââä½êíïüúŸ÷úŸ±²ÛÜÞô­ž®¶´ù¯¾ÀŽÇÍÐÉ¥ÏÆÇÇÉÒÒÓÊÕÔÒ¥ÑÕš †‚¡Î¤‹Œ‹‹Œ¡‹Î‹Œ‚‡‡‡‡‚‰‰‰‰Š†„ÙÙÙ ÌØÕÔÑÐÏÉ¥¥¥¥ÉÏÆÅÀ¾¬·µýø¼®¦œ¹ÝŸüìçãââââãåååãââãäåéîû°ÛÝß¹›žº»®¼¶ý渨ÂÂŽ’€Ã€€€ÃÃÀÁ¾¯·µøª»›­­¹ôßÞÛ°°°ûïé½½åãâââââââââââââââââââââââââââââââââââââââââââââââââââââäèëíïþú°°±ÛÜÜÝÝô­œ®¶´ù§«¿ŽÃÇÐÑÒÑÐÏÐÉÒÔ™Õ××ÊÔÓÔÕËÙ‡ˆŒ‹‹Œ¡¡‰¡¡¡‰ˆˆ‡‘‘‡ˆ¡¡ŒŒŒŒ¡‚‘„†‘І Ì×Ô¥ÐÐÉ¥¥¥Ñ¥ÉÐÍÅÀ¨«¸ùæµýñ¶®º›Þ°þëçäãâââäåäääãäå½èëïú±ÛÜÞô­žº©®È¶¶ýù¾ÁÁÁ€À€€ÃÅÆÆÃÂÀ¾§ý¶ªž›­­››­ßÜÛ²úÿëèç½äâââââââââââââââââââââââââââââââââââââââââââââââââââââåèëíïüŸÛÛÜÝÝÝÝß¹œº©ª¶´ù¸¬¿ŽÃÍÑÔÔÓÑ¥¥ÒÓ™ÕÖØš×Õ™Ê×Ì„ŠˆŒ‹Œ¡¡‰‰¡¡¡ˆŠ‡‡††‘ЉŒŒ¡¡¡¡‰Š†„„‡Š† áØ™ÑÉÏÐɥѥÉÉÐÇÅÀ¨«¯ùùæµ´ñªžô²üìèåääãä½ççè½åçêëïþúŸ²ÜÞô­ž©®¼È¶ý¯¨ÀÀÁÂ’Ã’’€’€€Ã€ŽÀ¨¯ù´ø¼¦ž­¹­œ›¹ÞÞÞݱúîêè½äãâââââââââââââââââââââââââââââââââââââââââââââââââââä½éëíÿû±ÝÝßÞÜÝÞßô›ž»¼øµ¸¯«¿Â€ÇÑÊÕ™ÔÒÒÓÓÓÔÕר×ÕÊÖØ…„Љ¡‹‹ŒŒŒ¡¡¡¡ˆ‡‘†„„„†‡‚‚‚‡‡‘†Ù á…Ù„ ËØÊÓÒÉÏÏÉÉÐÍÆÆÆÅÿ¾¬¸ùµýøÈ®©¹Ü÷þìèç½½½çèééèèëïü÷°±²Üß¹­œº©»¦ª¼¼Èñµ¸«¿¿ÀÁŽ’’’ŽŽŽÁ¿«¸ýȪ¦©›­œœ­¹ôôÞÛ÷þîëèåãâââââââââââââââââââââââââââââââââââââââââââââââââââåçéëîü÷Ûô¹ôÞÜÜÝÝß¹œªø´ù§¬¨ÀŽÃÏÓÖÕÊ™ÔÓÓÒÒ™Õ××ÖÕÕ×Ë…„ЉŒÎ¤Î‹‹Î‹ŒŒŒ¡¡ˆŠ‘„ÙƒÙÙ„†††„ƒƒ…ÌšØØËášÖ™ÒÑÑÐÍÏÏÏÏÆÃÃÀÁ¿¾¬·æµýø¶È¦ž¹Ý²ŸþíêëêéëììëêëîûŸÛÞßÞÞô­œº¦ª¼ª®®¼Èñ§¬«¨ÀÁŽŽŽÂŽŽÂÂÁ¾§ùµñȪª®»œžž­ôßݱ÷üïíé½ãââââââââââââââââââââââââââââââââââââââââââââââââââäèéëíþú°ßœ›­ßÝÝÜÛݹº®øµù¯¾¨¨ÀŽÅ¥™×ÖÕÕÊÔÓÓÔÊÖ×××ÖÖØÌ Ù‘‚¡Î¤Î‹Î΋‹Œ¡‰‚Š‘„ƒ  ƒƒ … áááÌš×ÕÊÖ×Õ™ÒÉÉÉÏÍÇÇÇÇÃ’ŽÂÂÂÁÀ¾§æñø¶ÈȪ©ºž­ôݲ÷þïîíìîïîííîü÷²ß¹­­­­œ»ª¶¶Èª®ª¼øµù¸¯¨ÀÀÁÂŽÂÀ¿ÀÁÁÀ¨¯ùæý¶¼Èȼ®©º›ôßݲ÷üïìéäââââââââââââââââââââââââââââââââââââââââââââââââââãçëëíÿú±Þœºœ­ôßÝÜÝ­©È´ù§¨ÀÀÀŽÃÍÒÊØ×ÖÖÖÊ™™™Õ×ØššØšÌ…ƒ„‘‚¡‹¤ÎΤ¤Î‹Œ¡‰‰ˆ‚‘Ù áááÌšššØššØÖ™ÓÔ™™ÔÒÉÏÏÐÏÇÆÅÅ’ÂÀ¨¿ÀÁÁ¾·ýø¶Èȼ¦ºœ¹ÞܱŸûþïîîïÿþÿþûŸÛßô­›žº©©»ªÈÈȼª®®¼øñ´§«¨¨¾¨À¨«««¾¨«¬¸ùæýø¶Èȼ¼»©©›¹ßݱûïìê½ãââââââââââââââââââââââââââââââââââââââââââââââââââäêîïü÷²Þœº©ºž›­ôÝÞ­©È´æ§¾ÀÁÇÉÓÊ×ÖÖרØ×רšËá…áÌÌ…ƒ„†‡ˆŒÎ•••¢“¢ÎŒŒˆ‚‡ƒáÌÌÌËšØØ×ÕÊÊ™ÔÓÑÑÑÑ¥ÐÍÇÍÍÅÃ’’’€ŽÀ«¯¬¾¨¿¯´ñøø¶È¦©©ž¹ßÝÛ±÷úþïîÿüûûû÷²Þ¹¹›žº»®¦®¼¶¶¶ÈÈ®¦ª¶¶ñµù§«¬¬¾¿¾¬§§¬¬¬§¸ùæµñ¶¶È¶¶ª®¦¦»ºœ¹ÞÛ°ûîëèäâââââââââââââââââââââââââââââââââââââââââââââââââãåèíü÷°Üôœ»®¦»ºœ¹ßÝ­º¼ý¯¿Ž€ÅÍÉÑÓÊ×ÖÖØËšËÌá… „†ƒ … Ù„‘‡‰‹¤¢“Ú”ö“•ÎŒˆ‡„…ÌÌÌËËšØÖÊÔÓÒ¥¥ÑÉÉÉÐÏÍÇÇÆ€ŽÂŽŽÀ«¯¸¸§¯¬¸æ´ýýýøÈ¦»»©ž­¹ßݲ°÷ûþÿÿþûú÷±Ý¹››žº©®¼¼¼È¶øñø¶ªªª¼¼¶ñµ¸¯¬¾¾¬§····¸¸·ùææ´´ýñø¶¶ø¶¼¦›Ý²°ûïìêåâââââââââââââââââââââââââââââââââââââââââââââââââãçêíû±Ûß›»®¼¼ª»ž­ÝÜôª´·«ÁÃÇÐ¥ÒÓÔÊ×ÖÕÖØšÌ…ƒÙ‘‡Š‘†Ùكن‡ˆŒ•Ú”öööÚÚ¢¤¡Š„ áÌËš××ÖÕ™ÒÑ¥ÉÉÉÐÍÇÇÆÆÆÅÅÃ’ŽÀ¿¿¿¾¬§¸·¸§§·æ´´´´ñ¶ª¦»»œ¹Þܱ÷ûûþÿþû÷°²Þ¹›»®È¶ÈÈÈÈøñø¶¼ªªª¼È¶ñæ·¸§¯¬§¸ùµææµ´µ´´ýøøñ´ñ¶®­Ý±úþîìéäââââââââââââââââââââââââââââââââââââââââââââââââãçìÿú±Üôœ©®®®¼¶È¼ª»º›ÞÜß¼´·«ÂÍ¥ÒÔÓÔÊÖÖÕÖØË̃„‘Šˆˆ‚‡‘†ÙÙ„†Š¤“”ö”Ú”öÚ¢ŒŠ„ƒ áË×Õ™ÔÔÒÉÏÍÍÏÍÇÀÃÃÀ€ÁÁ¨¾¾««¯§§·ù·¸¸ùµµµ´ñ¶¼®¦»ºœ¹ßܰûüþÿþþüú÷±Üß­»ª¼¼®®®ª¼Èȶ¼®ªÈÈȶñ´µæ·§§¸ùæµ´ññýýø¶Èȶ¶¶øñýøÈ®œ¹Ûúÿîìê½ãâââââââââââââââââââââââââââââââââââââââââââââãä½êïû±Ý¹œº®Èª®ªÈÈȪ¦©žßÝôž¦ñ¯À’ÅÏÑÓÓÔÊÖÕÖØššÌƒ†‡‚ˆ‰‚‡‡‡†„„†‘‚Œ•““¢“”””Ú‹ˆ‡†ƒáš×ÊÒÑ¥ÏÆÃÃÀ’’’ÂÀÀ¨«¬§¯¬¬¬§·ææùæ´´´ýøÈ®»©ž­ôßܲ÷üþÿþûûûû÷±Üô›©¦ªª®¦»»¦®®ªªªª¼¶Èȶøñý´µù¸¸¸æµýȪÈȼª®®®ª¼È¶ññ¶ª¦›Üúþÿîíèãââââââââââââââââââââââââââââââââââââââââââââä½çëîü°Ý­º¦È¶È¼È¶È¼¼®»¹ß­®ñ§¾Á€ÇÉÑÒÓ™ÕÊÖØššáƒ†‡Šˆ‰‚ŠŠŠ‘ÙÙ†‘ŠÎ¤••¢ÚÚö”Έ‡ÙáØÕÓÉÐÏÆÃ’ŽŽŽÁÁÂÂŽŽÀ¨«¬§¸·¸§¯¸µµµ´µææµ´´ýøÈª©ºº›ßßÞܰûÿÿþ÷±°÷÷°Ûß¹œ»®®¦»©©©»¦¦®ªÈ¶ÈÈÈȼ¼¶ñµæææµøª»»¦®®®¦¦¦¦®¼¶¶ÈÈȦœÜŸúûþïêåâââââââââââââââââââââââââââââââââââââââââãä½éìïþû°Ý¹º¦®¼È¶¶øøø¼ªª®©º›¹œ©ªñæù§¾ŽÏ¥ÒÓÔ™™ÊÖØÌ…Ù†‘‡‚ˆ‚ŠŠ‚‘„„‘‘‘‚Œ¤¤¤•¢””•¡‰‚„ÌÖÔÐÇÆÅÃ’ŽÁÀ¿¾¾¾¨ÀÁ¿¾§ùæµýýµ·§·µ´ýýñýµææµý¶¼®žžœ¹ôßݲŸþïþú°Û±Ÿ°²Ýô›º©¦®¦»»©©»»»»¦¼Èȼ¼ªª®®¼ø´æµ´µµñ¼»º©¦¦¦»¦»¦ª¼¼ÈñýªÞ±Ÿúüþìçãâââââââââââââââââââââââââââââââââââââââãåèìïü÷±²Ý¹®øøøøñý´ý¶ª®®»©ž›»Èýæ·¯À€ÍÉÑÑÓÔ™Ê×Ì ƒ„†‘‡‚‰ˆ‚ˆˆŠ‘‘‡‘‡‚ˆ¡‹‹¤•¢””¢‹‚„ËÊ¥ÇÅÀ’ŽÀ¨«¯¯§¯¾¨¾¬·µýñøøýæ·¸·ù´ýñøñ´ææñȪ»œ›­ôßܲ°úþþûú°²²²ÛÜÞ¹ž©¦®®®®®®¦¦¦¦¦¦ª¼®¦»»»®ª¼Èñýýñøø¶®œ¹ô­©»¦»¦¼È¼Èøø®Þ±Ÿ÷ûÿëçãââââââââââââââââââââââââââââââââââââäääåèëïüŸ²ÝÞ¹ž»¶æææ´ý´µý¶ª®»ººœžª¶´´µù§¾ŽÇÏÉÒÔ™ÖË…… ƒ†‡ˆ‰‰‰ˆˆ‚‚ŠŠŠˆˆ‰¡ŒÎ•¢ÚÚ¤¡ˆ‡ÙÌ™ÉÍÅÀ’’Ž¿«¯§·ù·§§·µñ¶È¶øñ´æù·ùææ´ýýý´´øÈ®ž›¹ÝÛ°ŸúûûûûúŸ²ÛÝÝß¹›»®ªª¼È¶¶¼ªª¼ªªª®»º©¦®ª¶¶¶¶È¼ªª›ôÝÞ¹œ»¦»¦¼¶ÈÈø¶®ß²°÷üïê½ãâââââââââââââââââââââââââââââââââââäçç½èëîü÷²Þ¹›»¶§§·æææ´ø¼¦©ºººº¦¼ñ´´´æù¬Á’ÅÇÐÒ™ÖØá   ƒ„‡ˆ¡¡¡‰‰‰ˆˆˆ‰ŒÎ•“ÚÚ•¡Š† šÔÉÍÅÀ€’ލ¯¸·æµµææµ´øÈÈȶøñýµæ···µýñøýýøÈ¦©ºž›ßܱ°÷ûþüûúŸ±ÛÞ¹­žžž©¦ªÈøññø¶¶¶Èª®¦»©©º©»®Èȼª¼ª®»›ßÜÜÞ¹›œ»®¼¼È¶¶¶øññ¼©›Ý±úþîéåâââââââââââââââââââââââââââââââââââåéìëëíïþú°Ý¹ž¦¶µ§¾¬¸¸·æ´ýø¼¦»»»»»ª¶ñµµµæù¬¿Â€ÆÉÓÕØÌ…ƒÙ„††‘Љ¡¡ŒŒ¡¡Œ¡¡¡‰‹¤¢Úö•‡ƒÌ×ÔÉÍÆÅÅ’Á¾¸ùæµµ´ýýýýøÈ¼¼È¶¶¶¶øýæù¸¸ùæ´ñøýýñ¶ª»ºœ­ßܱ÷ûþÿü÷Ÿ°Ûݹœºººº©»ª¶øñøññ¶È¼ª¦»ºººº©¦ªª®®®»©œôÝÛÛÝßô­»®¼È¶ÈÈøý´ýȦô²úÿìéåãââââââââââââââââââââââââââââââââã½ëíîîîþúŸ°Ûßœ®¶´¬À¨¬¬¯·ææµý¶ª¦®ªªª¶øýæµæ·¬¿Â€Ç¥ÔÖšá „†‘‘‘†‘ˆŒ‹‹‹‹‹ÎÎŒ¡¡¡‰ˆ‹¤“öö¤‰‘ ËÖÓÉÍÆÅ€À«§ùµ´´´ññø¶Èªª¼¼ªª¼¼Èøýæ·ùæ´ñ¶¶ñ´ñȼ¦º›¹ßݲŸûüû÷°°±²Ý¹œºººº»¦¦ª¼Èª¦»©žžž›››žºº›¹Þݲ°°±ÛÝ­º©¦¦®ÈñýñÈ»žß±ûîëé½ãâââââââââââââââââââââââââââââââãåéíîÿÿüŸÛÝßô›º»ª¶ý·¿ŽÁ¿¨¾§ùæý¶¼¼¼¼Èøý´µæ·¸§«À€ÍÑÔÊØÌ…ƒ„††††‘‚¡ŒŒÎ΋‹‹‹‹¡ˆ‚‰‹•“””¤‘ ØÔÉÇÅ€ŽÂÀ¿¨«§´ýýñøÈª¦©©ºº©¦ªÈøøÈȪ¦®¼ñµñȪ»ž¹ôßÝÛ²±°±²ÛÛ²ÛÝô›ºžžžžºººº©¦©ºžžžœ››­ô¹¹­œ›­­›œ›­ôÞÞÞ²Ÿ÷Ÿ°²Þôô›žº¦¼ñýý¶¦žÞ±ûîëêçäâââââââââââââââââââââââââââââââåèëîÿþû°Ý­œœž»®¼øµ§ÂÃ’ŽÂÀ«¸·ý¶¶Èȶñµææ·§¯¯¨ÁÅÏÑÓ™ØÌ Ù„„„„„„‡‚ˆŒÎ‹ŒŒ‹‹¡‰‚‚‚¡Î•“““·ƒØÓÍ€€€ŽÀ¨¨¿¿¾¯´ýýñ¶È®ºžœœ›››œžº©»»©©ºº»¼ýµñÈ®©ž¹ßÞÝÝÝÝÝÝÝÝÜÜÜÝß­œºžœ›œœœžºž›­­­­¹¹¹ôßÞÝÝÝÝÝÝÞßßßÞÝÝܲŸ÷÷÷±²ÛÜß¹œ©®¶ýµ¶»œß²ûîìéçåãâââââââââââââââââââââââââââââ½éëíÿþûŸÛôºº¦®¼¶ý«ŽÃ€Á«§·æñøøøøýµ···¸¯¬¾ÀŽ€ÆÏ¥ÓÊØá „„†„كل†‡ˆŒÎ‹Œ‹ÎŒ‚‡Šˆ¡Î•¢••Î¡ŠƒØÓÆ’ŽÁ¿¾¾¾¨¾¯ùµýñø¶ª»ž›¹ôßßô­›žžžœœžžœž®øý¶ª¦©œôÞÜÛÜÝßßÞÞÞÞÝÝÞß¹›œ¹¹­¹¹­­ôßßßßôôôÞÝÜÛ±°±²±±²²ÛÛÛÜÛ²°÷úú÷ŸŸŸ²ÜÞ¹œº¦È´µ¶¦¹ÛúÿìéçäâââââââââââââââââââââââââââââäèìïïþúŸ²Þ›º©»¦®¼¶ý§¨ÅÆÅÿ«¸´´µµ´æù·¯§§¬¾¨ÁŽÃÆÏÉÒÔÕš Ù†‘†„Ùƒ ƒ„‘‚¡Î‹Œ‹‹Œ‰‡‘‚ˆŒÎ¤¤¤Œ‰ŠƒØÒÅŽÂÀ¨¾¾¨¨¾¯·æ´ø¶¼¦º›ôÞÛ²²ÜÞ¹›­ôßßô¹¹›¦ÈøÈª¦›ôܲ²ÜÞôôßßßÞßßßô¹­œœœžž›­¹ßÞôßßÝÜÝÝÝÞÜÛÛ²±°÷Ÿ°±±±°°°°±±°Ÿúüûú÷÷÷°ÛÜÝß­ž©ªøñ¼©ž¹ÜŸþíêçäââââââââââââââââââââââââââââã½éìïü÷²ÝÝß­ž©¦¼¶ñµ¸¬¿’ÆÇÇÅ€Ž¿«¸¸¸·ùùù·¯«¬¬¿ÁŽ’ÍÉÒÓ™ÊÖË ƒÙÙÙ„‘†„Ù„‡‰¡Œ¡¡ŒŒ¡‰Š‘‘‡‚‰ŒÎ‹Œ‰‚†áÊɎŽ¿¾¾¨¨¬·æ´ñø¼®©ž¹Ü°úüüú°ÛÝÜÛ²ÛÝô¹›ž®¼®©º›ßÜÛÜÝÞßô­­­¹ôôô¹¹¹¹¹­›œœ›¹ßßÞÞÞÜÜÜÛÜܲ±±°ŸúúúŸ±±Ÿ÷úú÷ŸŸŸ÷ûþüüüûú°²ÜÜÝôœ©ª¶øª©­Ý±ûîêèåãââääãââââââââââââââââââââââäçêíÿ÷²Ýôô­››ž©®¶ø´·«ÀÅÍÏÍÇÅÃ’À«¾«¬¯¸¸¸¯¾¨¨¿ŽÃÅÍ¥ÔÊÊÊÖØÌ…   ƒ†Š‡‘†‘‚¡¡¡¡‰‚‘‘‘Љ¡¡Œ¡ˆ‘ šÔÏÃŽŽŽÁ¿¨¨¨¬ùæ´ý¶ª»¹Ü÷üîííïþú°Ÿ÷Ÿ°²Üß¹›»ª»ºœ¹ßÞÝÝÞÝÞ¹›œ›­ôßôôÞÝÜÝß¹­­­­ßÝÝÜÛÜÛÛ²²°Ÿ÷÷úúüü÷°÷ûþÿÿþûúúúüÿïïÿþüú±Û²Ûݹ¦Èøªž¹Ý±ûîêçåãäåå½äâââââââââââââââââââââã½èëíþ÷²ß››œœžº¦¼ñ´ù¬ÀÍ¥ÉÏÍÇÆÃ¿¿¿¨¾«««¾¨ÀÁŽÃÆÍÐ¥ÓÕ××ךÌá… ƒÙ†‡ŠŠŠ‚‚‰¡¡¡‰‰‰ˆˆŠ‡‡‘Šˆ‰‰Œ‹ˆ† ËÔÐ’ŽÂŽŽÁ¿¿¨¬¸ùµø¼®›ÝŸüïíëéëíîþÿïÿüú°Üô­ž©»ºžœ­ôôßÞÝÝÝÞô›ºž›­¹ôÞܲ±²Ýßôô¹¹ÝÛ²±²²²°°Ÿúûú÷úüþüûûþïîììîþüüþïíììîïÿûŸ±²²ÛÝ›©ª¼®©ž¹Þ²úïêèççè½ççäãâãââââââââââââââââââ½éëìïûŸÜ­žž»¼ø´ù¯¿ŽÃÍÑÔÒÉÐÏÇÅ’ÂÁÁÀÀÁÁÁÀÁÂÃÅÍÉÑÒ™ÖØØØšÌáá…ƒÙ†‡ŠŠ‚ˆ‰¡¡¡ˆ‰‰‰ˆŠŠ‡‡‚ˆ‰‹Œ‚† šÔÐÁÂÂÀ¿¾«§ùýÈ®©žôÛúÿîëè½çéêëêêëíîþ°Ýô›žœ­¹ôôßÞÝÞÞß­œž›ôݲ±±±²ÛÜÞßݲŸûüüüüþþÿÿüûüþüþïìììéèèëîïîëèççèëíïþûŸ±²±Ûôœº»©º­ßÛŸûïíììëè½½åãâââââââââââââââââââãåêîÿü÷±Ý­žº©©»ªñµù¯¨ŽÃÍÒ™Õ™Ó¥ÏÇÅ€ŽŽŽÂÁÀÁŽŽ’ÏÑÒÓ™ÊÕÊ™Õ×Ëá… ƒ„†‘‘ŠŠ‚ˆˆˆ‰‰¡¡¡‰‚Ї‚‚‚ˆ‰‰‡ÙÌեǀÂÁÂÂÂÁÁ¿¾¬¸µÈ»º›ßݱûïìé½äåçééèèèèêîú²ÜÝß¹¹¹ôôßÞÜÜÞôßô¹›žºº»©ž¹ßÝÛ²Ÿ÷Ÿ±ÛÝÛŸüïîîííííìíÿþþþüÿìêêéåäåéëëèåããä½éìîïþ÷±²±°Ý­žôݱŸûþÿÿïíé½½äãââââââââââââââââââã½êïûŸ±Ûôœ©¦ªªª¼ñ測¨ÂÃÇ¥™Ö×ÖÊÒÉÍÅÀÀÂÁÂŽ€ÅÐ¥ÒÓÔÔ™ÓÒÓÊØáƒÙÙÙ„††‡‡‚‚ˆˆ‰¡ŒŒ¡‰‚ŠŠ‚‚ŠŠ‚‚Š„…×ÒÍŽÀÀÁÁ¿¨¬·´ªœßÜÛ°ûîê½åãä½ççååå½èíû°°±ÜÝÝÝÞÞÝÜÛÜô¹­­­œº»®®©ž­ôÝÛ°ûúŸ±²Ÿþïíìëêêêêêìîÿÿüÿìè½ååãâä½ççåãâââä½éíÿü÷Ÿ°ŸŸÜ¹žºœ¹Þܲ÷ûþþÿïìé½åäãããâââââââââââââââäçìþ°Üô›©®¼¶øø¶ñ渫ÀŽ€ÆÐÓÕØÌš×™ÓÉÏÍÆÆÇÏÏÅ’ŽÁÁ€ÇÏ¥¥ÑÑ¥ÉÐ¥Ô×áÙ††„Ù†‘‡Š‚‰¡Œˆ‚Ї‡‘††††ÙÌ×™¥ÇÃŽÁÁÂÂŽŽÂÁ¿¬ùýªº­Ý²ŸúÿìèäããäååäãâãåçëîüúŸ±²²ÛÜÜÛ²²Ýô­œ©¦®ªª¼¦ºž›ôÜŸüû÷ŸŸûïíìëêéèèéêëíïþüîê½ãããââããããâââââãä½êïüúú÷÷ŸÛß­žœ›¹ÞÝܱŸúüüüïìè½ååäããääããââãââââäåçéìþŸÜ¹©®ª¼øýýý´æ¸«Á€ÅÍ¥™×áƒ…ËØÕÔÒ¥ÉÐÐÑÑÏÂŽ€ÍÉÉÐÏÏÏÐ¥Ô×˃††Ù„‘‡Š‚‰¡¡ŒŒŒ¡ŒŒ‰ˆŠŠ‘†ÙÙƒ á×ÔÑÉÍÅ’ÂÂÂÂÂÂÂÂÀ¬ñ®žô²÷ûþíé½ãââãããããããåçèêíÿþ÷°Ÿ÷°±±±²Ý¹›©©®ÈÈÈȼ»ºœôÜŸüþþÿïíëëììëêéêêêêëîþüíéäââââââââââââââââã½êîþþüüû°ÜßôôßÝÛ²²²²Ÿûûüÿïìêè½äãäåååäããääää½éìíÿú²Ý¹ž»ªÈȶñ´µù§¾Á’ÆÍÐÒÖáÙ‘†„ƒášÖÊÔÓÒÓÒÉÆ€€ÃÅÅÍÐÐÏÍÇÍÏÉÒ™×…„Ùƒ„‘‘‡‚‰¡¡‹‹Î‹¡‰‰‰ˆ‚†Ùƒ áÌ×™ÒÑÐÆ€ÂÁ¿¨¨¨¿¨§µÈ›Þ°üïíêçäâââââââãäââåççèéìïÿÿÿþüû÷±Ýô›œž»¼ñø¶È¼¦©ºœôÛ÷ÿïîìëêéëëëêêêëëëëíîÿÿîéäâââââââââââââââââãåéìíîïþ÷±²ÛÛÛ²±°±²Û±Ÿ÷úþÿîìé½åå½½çç½å½çèèêìïþú°Ûß­»ª¶ýñøýµæù¸¾Â€ÆÐÉ¥Ò™ËÙ‡‰‰Š„ƒ…š×ÖÊ™Ô¥ÍÆÅÆÆÇÍÆÅÇÇÍÍÍÇÇÏÉ¥ÓÖÌ ƒ„‘Ї‡ŠˆŒÎ¤¤ÎŒ¡¡¡¡ˆ‘Ù…áÌš×ÊÔÓ¥ÍÅÃŽÀ¾««¬«¬·´®žôÛúïìé½äââââââââããâãääãäåçéêëìíîüŸÛÞô­›œº¦¶´ñ¶Èª»œß±ûïìéçç½çèéèççèéëìîïÿÿþîéåââââââââââââââââââãåèéëíïüúŸ°ŸŸŸŸ÷°²ÛÛ²±Ÿûÿïîëéèç½çéêêêëìíïÿüû÷±Üß›º®¼¶ýµ´ýý´æ·¯À’Í¥Ò™ÕØ ‡¡••¤Œ‰Š†…ËØ×ÕÔÑÉÏÏÍÍÏÏÍÇÆÅÆÍÍÍÍÍÏÉÓÕš…Ù‘ŠˆŠ‡Š‚¡‹¤¤ÎÎÎÎÎ΋‹ŠÙ…áËØÖÊÔÓ¥ÐÇÁ¨¬¯¯¯§µÈ›ÝŸÿìé½äãâââââââââââââââââãääåçéìþ°Üß¹›œžº®øæýø¼®©ž›Þ±úïêç½äå½çèèçççéìíîÿþþÿíéåâââââââââââââââââââãäçêìîÿþûúúûûûú÷°ÛÜÛ²°ûÿÿîìëêéçèëìíîîîÿûŸ°°²Üô›¦Èøñµæ´ýý´¸¾Ž€ÅÏÑ™ÖØá†‰¤ÚÚ“•‹‡„ …ÌØÊ™ÒÑ¥ÐÐÉÉÉÐÍÇÏÐÐÐÏÍÐÑÔÕš…„‘Š‚‚‚‚ˆ‹¤¢•¤¤Î‹‹‹‹Œ‰ŠÙáËØÖÕ™ÓÑ¥ÐÇ’Á¾§§¸¸ø¦º­Üúîëéåãââââââââââââââââââââââäçëþ°Þ¹›œžªñµñ¼®»ºœ¹Ü±úÿíê½ãäåçéèç½çêííîîïïïíêçäâââââââââââââââââââã½éëííîÿüþþþüû÷°²±ŸŸúþïîíììììééêìîïïÿü÷±²²Üß­ž®Èñ´ææµµµæ·¬¿Ž’ÃÇÑÔÊØ…†ˆŒ¤ÎÎŒŒˆ‡†Ùƒ Ë×ÊÔ™™ÒÑÑÒÒÒÑÒÒÑÉÐÐÉÒ™ÖØÌ ƒ„‘Š‚ˆˆ‰¡Î¤¤Î‹Œ‰ˆŠ‡‘†ƒáš×ÊÓÒÑÉÏÏÍÆÀ¬·µµñ®ž¹Ü÷üþíçäââââââââââââââââââââââåéíü±Þ¹­›œ©¼´ùæø¼¦»ºœôݲŸûïë½ãâäçèèçççëîîííîïïíëé½äâââââââââââââââââââäèêëìîÿþþüþÿþû°±÷úüþïïîîîíîîìëëíïÿþü÷±ÛÜÝß­ž¦¼øñ´ææùù·¯¾ÁŽÃÇÐљؠ‘‚Œ‰‰‰‚‡‡†„ƒáØÖÖ××Ê™™™™™ÕÖÕÔÑÉÑÒÊØËá ƒÙ„‡ˆ‰‰¡‹••¤‹Œ‰ˆ‡† á…ááËÖÔÑÐÐÐÍÆÇÆÅÅÀ¯ùµñ¶¼©›ßÛ°°÷ÿê½ãââââââââââââââââââââãçëÿ÷Ûß¹­œžº»¶æù´¶ª¦»ž¹Ý±Ÿûïê½ããä½ç½½çéìîïïîíííìëéèåãââââãäãäääããââââââã½èéëïþüüûüüþü÷Ÿ÷ûþþþÿïïîîÿþïííîïþûŸ±ÛÛÛÜß›»¼ø´´´µæù·§¾ÀÂŽ€ÆÏ¥Ôؠن‡‚Ї‡Š‡‡ŠŠ‘„ ÌËšÌáËš×ÖÖךË×ÊÓÒÒÔÖËá ƒ„††‚¡ŒÎ••¤Œ‚‘Ù…šØØšš×ÔÉÍÆÅÅÅÅè¯ñȪ¦›ßÝÝܲûì½ãââââââââââââââââââââã½ëþŸÝ¹œ©»ªñ·µ¶¼®»ºœôÛŸúþíé½ääääåå½èêìíïÿïîííìëëêçåãââãåççççç½åãâââââãå½çëïüüûúúüüûúŸ÷üïïïïîîïïÿÿïïîîÿûŸ²²Û²²Üßœ©®¶ýµµµµæ·¯¨ÂŽ’ÃÇ¥™š… Ù†‘‘†‘‡‡Šˆ‚‡„Ùƒ     ÌšËÌ… ÌØÕ™™ÖË ƒƒÙ‘‘‡‰Œ¡¡Œ‹¤¤Î¡ˆ‘ƒáØÕ™ÊÕÖ™¥Ç€€ÃÃÃÃÀ¾§æø¼®©º›ô¹ßÞÛúí½ãââââââââââââââââââââã½ëü±Þ­»¦¦È´¸ñ¼¦ºœ¹Ý±ûïëèåãâââãååäå½çêíÿþþÿÿïïïîéåããå½èéèéêëëé½äãââââãåèìïþüúŸ÷ú÷÷ŸŸ÷üïììííìíîîíììíïü÷°²²²²ÜÝÞ›®Èøýµææù¸¬¨ÁÁÁŽ’ÃÆÉ™×Ì ††‘‘‡‡ŠŠŠ‰¡‰Š‡‡„Ù  ƒÙ áჄ†ƒ…ËšËá „ÙÙ†‡‡‚¡‹¡‰ˆ‰¡ŒŒ¡ˆ‡ƒËÖ™ÔÓÒÑÑÉÍ’ŽÁÁŽÂÂÁ¿¾¬·µñ¼¦­¹ô¹ßÛ÷ÿèäããââââââââââââââââââãçìû°Ýô›º©»¦øæ¸¬¸´¼©œôݲŸþìèåãââââãäãââãåèëïþüüüüüüþìèåä½éêéêìîÿïìéçåãâââãåéìïÿû÷°ŸŸ°°°Ÿúüïììëêêìëêééêíþû÷°±±²ÛÝÝß›º¦ª¶ýæù¸¯¾¿ÀÁÁÁ’ÃÅÇ¥™×̃††‘‡Š‡‡‡‚¡‹ˆ‰‚‡†ÙÙ„„كن‘‡†Ùƒ ƒÙ„‘††‘Š‚‰¡‹¡‰ˆˆ‰ˆŠ‘…×™ÒÑÉÍÆÆÅÃÂÀ¿¨¿À¨¨¾¬¯·æý¶¼»ººœ­­­ôÞ±üìççåââââââââââââââââââã½ìüŸÛݹž»®øæ§«·ý®¹Ý±÷üïëçäâââââãäãââãäåéìîïþûûúúûïìè½çèêìîïüúþîëèåãâãä½çêíïüŸ±²²Û±Ÿ÷úüÿíëëêèçç½çèéêíÿþû÷°°±ÛÝß¹›žº¦Èý槬¨¿ÀÂŽÂÂÂŽ’ÅÇÉÒÖá Ù„‡‡ŠŠŠ‚‹‹¡¡¡ˆ‡‘‘†††‘‡Š‚ˆŠ‡‡‡‡‡ŠŠ‡‡‘‡Š‚‰¡‰‰‰‰¡¡‰Š„ÌÕÒÐÍÆÃ’ÂÀ¨¾«¯¯¬«««¯§·´ø¼ª©œ›››­Ý±üìé½ãââââââââââââââââââäéïû±Ý¹ž»ªø¯«ùø¦ô²÷þïíé½ãâââââãããââââãçëííþú÷úúúþîêççéëîÿüŸ°÷þîëè½½çèèéìîüŸÛÝÝÝݱúûüþïíëêéç½ää½éêìîÿüûúŸŸ±ÛÝßô¹­ž©¼ý§«¿ÀÂŽÂÁÁŽ’ÃÅÇÉÓ×Ì…ƒ†ŠŠŠŠ‚‰¡‹Î‹‹Î‹ˆŠ‘‘‘Š‚ˆ‰¡¡¡¡‰‰ˆˆ‚Ї‡Šˆ‰‰‰‰ˆˆ‰‰‚†…×™ÑÏÆÃ’Ž¿¾¬¸¸¸·ù·§§§¸¸µñ¶¼®¦»©ºœ›­››ôÜ÷ïê½ãââââââââââââââââââãçíþŸÝ­»ªñ槯µÈ©œß²úÿìè½åãââââââââââââäçêëìïüüüûþíêç½çéìïÿü÷°Ÿúþíëëëííìíîþ÷²ÝÞÞÝݰûþïîíêè½ääãâã½éêìíþú÷÷Ÿ°²ÛÜÝÞô›žªø´·¯¾¿ÁÁÂŽ’€ÃÃÅÏÓ×Ì…Ù‘‚‚ŠŠ‚ˆ¡ŒÎÎÎ΋¡ˆ‘Ù„†‘‡‚‰¡Œ‹Î‹ŒŒŒ‰‚ŠŠˆ‰ˆ‚‚‚‚Ї‘„á×ÔÑÏÆ€ÂÀ¨¬·ùùùæµææùùùæý¶Èª®¦©ºž­¹­›­ß²ûíèåããââââââââââââââââââäéï÷Ü­žº©®¶µ¸¸ý®ºœôÛ÷ïêçååäâââââââââââãäçéêëíïïïïíé½½åçêíÿüû÷±±Ÿúüþÿþüþþüü÷°ÝôôÞÞÜŸüïìëëêé½ãâââãçéêëîþú÷Ÿ°²ÜÜÜÛÞ¹œžº®¶ýæ·¯¾¿ÀŽ’€€€ÃÀÃÏÔ×Ì…Ù‡‰‰ˆ‚Šˆ‹•••¤‹¡ˆ†ƒÙ„„‡‚‹¤¢Ú“•¤ÎŒ¡‰‚‚‰‰ˆ‚ˆ‚‡†ƒ ÌÖÓÉÇ’ŽÁ¿¨«¯·ææ´ýñøýµæµýø¼¼®®»º›ô¹››¹Þ±þìè½åäââââââââââââââââââãçíûÛ­œº»È´ø¦›Þ±ûïëè½äâââââââââââãããäåçéëìëììêåãããäçëÿþü÷±°±±±±±²²°Ÿ÷÷Ÿ²ß¹¹¹ßܰûïëëëëëèäâââäçééëîÿüû÷±ÛÜÜÛÜÞô›ž¦Èñý渫¿Á’€ÃÃÅÃÍÒÕÌ „ЉˆŠŠˆŒ•“•¤‹¡ˆŠ„  ƒ„‡ˆ‹•“öò”“•¤‹¡‰‰¡¡‚‘ƒÌØÕÓÉÇÃŽÁÀ¿¨«¯¸ùææ´ý¶È¶øø¶¼ª®®¦¦ºº­ô­­­¹Þ±üîêèçåâââââââââââââââââââåêÿ±ß¹›ž©¼ñµµ¶»­Ý°þíëêçãââââââââââãäããããåèééééèçäâââã½ëïÿü÷±±²ÛÞßôôôÞÝÛ±²Üß¹­­ôݱûïëêêìíê½ãâã½èéêìïþüú°±²Û²ÛÜÞô­ž®¶¶øµ·¯¨ÁŽ€€€ÃÀÃÍÑÕÌ Ù‡ˆ‰ˆ‚‚Γ”¢ÎŒ‰‚‘Ù… Ù„‡¤“öòöö”¢ÎŒŒŒŒŒŒ¡ŒŒŒ‚‡†…×™ÒÐÆŽÀ¿¨¾¾¬§ùùùµ´ñ¶ªªª®®»©©©»»©ž­¹ôô¹ôݱûîìëé½ãââââââââââââââââââãèîŸÝÞ¹œ®Èýýªœôݰþíëé½ãâââââââââââãããââä½ääååäåäãââäéíÿþûŸÛ²²Ýßô­­­¹ôÝÛÜÝß¹¹¹ßݰüïìêêìîìèäâã½èéëîïþú°±°Ÿ°±²ÛÞ¹ž®¶ñøñ´¸¯«¿ÁÂÁÂ’’ÃÍÒÕË…Ù†Šˆ‰ˆ‰‹¢“ڕ΋Œ‰‡„ƒÙÙÙ‘‰Œ•ÚÚ““Ú•ÎÎÎ΋Œ¡¡Œ¡Š†„ÙËÊÓÉÆ€ŽÁÀ¨¯§§§·ùùùµ´ñ¼¦¦®¦©©›¹ßÝÝÞÞݱ÷üîíëèåãââââââââââââââââââ½ëþŸÜß­žº©®øñªœôÜŸÿìëéçäââââââââââãäääââããââââââããâãçëïþüû±ÜÜÜÞô­œžœ›ßÞßô¹¹¹¹ôÞ±ûïíììîîìèåâãåçêíïþú°²²Ÿ÷÷°²Ûݹž©ªø´ýñ´·¸¯¾¨¨¾¨ÁŽÃÏÓÕØáÙ†‚‰Œ¤¢““•¤¤Î‡†††††‡‰¡¤“¢•¢¢••¢“•΋¡¡¡‚‘ƒƒá×Ô¥ÇÃŽÀ¿¾¯ùæù¸ùùæµ´ø®»»¦©º©œ¹ßÜÜÜÛ²²°÷üïîëè½ääãâââââââââââââââãèîü°Üô›žº»ÈȦº¹Ü°ûÿïíëèåãâââââââââãääãâââââââââââãã½éîÿüüú±ÜÜÝß­œ©©›ôô­›­›­¹ôÞ²÷ÿíìîïîëèåää½éìîþú°°±°ŸŸ°°²Üß­©ªñµýý´·§««¬¬¬«¿ÁÏÒ™×Ì †ˆ¡‹Î•¢“““¢¢••¡Š‡‘‡ŠŠ‚‰Œ¤¢•¤¤¤•Úöö¢‹‰ˆ‚Ї„ …ËÕÒÏÁ¿«§´´µµùæµµ´¶®»©º©©©œ¹ÞÛ²±°°°÷ûþîìëéèèçåãââââââââââââââäêïú±Ýô›œžº©®»º­Þ²÷þÿïíëé½ãâââââââââãäãââââââââââââäåèêîÿüûú±ÛÛÝß­žº©»º›­­œœœ›­¹ôÞ²÷ÿìíïîíê½å½½çêíïüŸ±°ŸŸ°±±±ÛÞ¹žº»ªøýý´æ·¸§¬«¬¯¬¾¿Â€ÆÐÒÊØÌ †‰Œ‹¢Ú“¢“Ú“¢•¤¡‚‡‡‚‚ˆˆ¡Î•¢•¤¤•“ò£ò¢Œ‰‚Ї†ƒáË×ԥǒÂÀ¾¯ùýøøøñ´æ´´µµñÈ®»ººžœºž­ßݲ±°Ÿ÷úûüÿîëêéèéè½äââââââââââââââåëÿ÷±ÛÞô›œž›ßܰüïîìêè½åãââââââââââââââââââââââââãåçéëíïþþüú÷Ÿ°²Ý¹œžœ›¹¹­­¹ôßÞݲŸüìèéëêêèççç½½éëîþ÷°Ÿ÷÷÷ŸŸ±Ýô›žº©¦¼øøýæ·ùù§«««¨ÀŽÃÅÏ¥Ô՚ბ‰ŒÎ••“ÚÚ¢ÎÎ‹Š‡‡Š‚‰Œ¤¢“Ú“ÚÚÚö—ò”¢ÎŒŒ‰‚‘„…ØÊÓÉÍÀ¾¯·´È¼ª®ª¼È¶ý´´ñÈ®©º›¹­žžžœ›¹ßÝÛ²²±Ÿûþþÿîìëé½åååääââââââââââââââåéîûŸ²²ÜÝß¹­­ß²ŸüïîëçåãâââââââââââââââââââââââââââäçéêëëíïïïþþüúŸ²Ýßô¹­¹ßôôßÞÞÝܲ°úïê½½çèçèèèéèçéêëîû÷Ÿ÷úûûú±Ýô­ž®¼¶¶ñæùùù§¬¾ÀÂÅÍÐÑÓ™Öšá„‚¡‹¤•“ÚÚ¤‹Œ¡ˆŠ‡‘‡ˆŒ¤¢”ööòòòò££öÚ¢Î΋¡‚‡†…×ÒÐÆ’¿¬·µøª¦»©»»»ª¶ñ´ñ¶¦œ¹ß¹››­¹ßÝÜÜÛ²±°÷üÿïîíìêèåãââãäââââââââââââââåéíþúŸŸ°±ÛÝÞݲ÷þîìêçãâââââââââââââââââââââââââââãåçèéëéèêëëíîîÿüû÷°ÛÜÝÝÝÝÝÜÛÛÛ²°÷üîêçåå½½çéêëìéççèèëïüûûüþþû°ÝÞ¹›©®ª¼È¶´æù¸¬¿ÃÇÏÉÑÓÔÊ×ËƒŠ¡‹‹Î‹Œ‹¤¢Ú¤¡‰‚Ї†‚¡¤Úö—£––òÚ•Î΋‰‚ІáÕÉÅ€Á¿«¸µø¼¦ºº¦Èñýñ¼žœ­ôßßßÞÞÝÝÜÛÛ²±°úüþÿÿïìêèåâââââãâââââââââââââãäèìïþûûûû÷÷÷ŸŸüîëé½äâââââââââââââââââââââââââââãä½ç½èêéèèèéêìîïþüüû÷Ÿ°±±²²°°²ÜÛ°ûïëçåååå½çéìîïìèèçèêíÿÿÿÿÿþú±ÝÞô­ž¦®¼¼Èñµæ·§«ÁÃÇÐ¥ÑÓ™ÊÕØá†ˆÎ¢•¤ŒŒ¢“¤Œˆ‚‚‡‘‰‹•”ò£–ijÄÄÄ–—”•¤¤ŒˆŠ‡†Ì™ÏÃÁ¿¾§æñ¼¦ºžœœœœœªøýø®ºœ­ôÞÞÝÜÜÝÜÜÛÛÛ²°÷üüþþþïíëçäâââââãâââââââââââââãåéëìîïÿÿÿþþüûûïìêèäââââââââââââââââââââââââââââââããã½èèèçççèëíîïïÿþüüûûû÷°Ÿ°ÛÞܱúÿìé½äåçççéëîïìêéèéêìîîïïÿþú°ÜÞÞÞô›¦¦®¼¶ý§¨ŽÃÇÏ¥ÑÒ™Õך…†ˆÎ“¢•ÎŒ¡‹•¢¤‹‰ˆˆ‡‡‰Œ¤¢”—£–––––££—ö¢ÎŒˆŠ‘†ƒØÓÇ€Á¾¯·´¶ª»›­­ôßßôœ»¼¶ª©º›¹¹¹ßÞÞÞÞÞÝÝÛ±÷ûûûüþþÿíêçåâââââãââââââãääããââãçëììììíîïþüûúþíêè½ãââââââââââââââââââââââââââââââââãåçèççç½çêíîííîííîÿÿÿü÷Ÿ°ÛÞÝÛ÷þîëçå½èèèêíÿÿîëééèèêëííîîÿûŸ²ÜÜÝÞ¹œž¦ªøæ§¿ÃÅÍÉÑÔÕך̃‡¤““¢¢¤ÎΕ¢¤ÎŒ‰ˆ‚‚ŒÎ•Ú—£––––£ò—ò“‹‰‡‘„ÙáÕÑÆ¾¸ùý¼¦©­ôôôßÞÝß›º¦ª¦ºžœœ›¹ßßßôôßÞܱ÷ûúúûûüïìè½äâââââãââââãä½è½åääããèíîìêéêëíïÿüüÿëçåãââââââââââââââââââââââââââââââââââä½½åååå½èëëëêêèèéëìîÿûŸ±ÜÞݲ÷üïìè½çêëìïþüüïëéè½çèéëììíïþúŸ±²²ÜÞßô­­œ®¶µ§À’Í¥ÔÕØÌ ƒ†‚Œ•ÚÚ”ÚÚ¢ÎΤ¤¤¤¤Î‹¡¡ŒŒŒÎ“ö£ÄÄ£—öÚ””¤Š††Ù áÖÑŬ·µ¶»œ­¹ôßßßßÝÞô­»»©ºžœ¹ßßôßÞÞßݲŸ÷÷÷÷Ÿúþìçäâââââä½åäãããäçêéè½åä½êííëèççèëíîïïîé½ãââââââââââââââââââââââââââââââââââãå½åãäåå½èêêèèé½å½çêìíþ÷²Ýßܱ÷ûïëè½èêìïüú÷÷þìêéèèèèêëíîïÿû÷ŸŸ±²ÛÛÝßô›©¼´¯ÀÂ’ÅÏÒÕØáƒ„‘‚‰‹“”öòòö“¤Î¤•¢ÚÚ¢•ÎŒŒ¡ŒÎ¢”£Ä£ò”ÚÚÚΉ‡„Ùƒƒ…֥ÿ¯ý¼©ž­ôßßÞÝÞÞÝÜÝß­º©ºžœ›¹ôßÝÜÝÞÛ±Ÿ÷úúŸ±÷ÿêåãââââãåççåäääåçéééçççéìííëéç½½éëëëìëèåãâââââââââââââââââââââââââââââââââââã½ååäãäçêìëêêéç½äåéìîþ÷±ÛÛŸúüÿìèåãäçêíÿûúúþîíììëééëíïþÿÿþûúŸŸ°±ÛÞô¹œžÈæ¬ÀŽÃÇÐÒÊ×Ì „‡ˆ¡¤ÚòòòöÚ•¤Î¤•“ÚÚ•ÎŒ¡¡ŒŒ‹•”ò££—òò”Úöö¤‰‘Ùƒƒƒ…ÕÉ€¨§ñ¼®©ž¹ßÝÛÛÜÜÛÜÞßßß¹›œœ›­­›¹ôßݲ±ÛܲŸúûüû÷÷þîê½åäääääååãââããäåå½åå½çéëìêéè½äåçéêêêé½äââââââââââââââââââââââââââââââââââââãåååäãåèìîíìëéçåãåèìîþúŸ±°úÿïíéåãâã½êíÿüûúüÿïÿïîìëìïûúüþÿÿüûúŸ±²Ýô›œž¶ù«ÁÍÉÒ™×Ì †Š‰‹¢ö££—ö¢¤‹‹¤•¢““¤‹‰¡¡ŒÎ•Úöòö”öö”ö££¢‘ƒƒÙÙ Ö¥€¿§æýȼ®ž¹Þ²²²²ÛÝÝܲ±ÛÜÞßÞÞßôßÞܱŸŸ°²±÷ûüþüûûþîêèçç½½½åäââââââââãããä½èéééççççåå½èééèåãââââââââââââââââââââââââââââââââââââââãããâãäçëïîìêéè½ää½êíÿüú÷÷þíëêçäââãèìÿþüúŸŸúûüþþïíîü÷Ÿ÷úÿîïÿüú÷°Ûßô­œÈ¬ÀŽ€ÆÐÒ™ØáÙ‡‚‰‹¢ò£—”¢ÎŒ‹¤•¢““•¤¡ŒÎ΢”ò”ÚÚÚ”—–£“¡‘Ù„‘‘„šÒÀ¯ù´¶¼®»œôÛ±±ÛÝÝܲ÷ûúŸ±ÛÜÝÝÝÛ²ŸúúúŸ°÷úûüÿÿþüþïìêèç½½äãâââââââââããää½½½åäää½ççèèç½½äãââââââââââââââââââââââââââââââââââââââââââââä½ëîìêèéçåää½éíÿþþüüîêè½åãââåéíþþüŸ±±°Ÿ÷úûÿïü÷Ÿ±Ÿûïìíîÿþú°ÜÞô›ž»¶æ¯¨ÁÅÏ¥™Ø „‡Š‰‹Ú£–£ö“¤Î¤¤•“Ú““•‹¡ŒÎΕ“ö”Ú“Úö£–£“¡Š†‘ŠŠ†ËÒÅÁ¬·µñȪ®»º­ÜŸ°²ÜÝÛŸþîïþ÷±²²²±°÷üþþüûúúûüþïÿÿþþþïëéç½½½äââââââââââããäåãâââãä½çèèèç½äâââââââââââââââââââââââââââââââââââââââââââââääçëíìêèçåãâã½êíïîíííé½äããâââãçëïþûŸ±²²°÷úúûûú÷÷÷üÿîîîîïþú²ÜÞ­žº¦Èµ¸«¿Â€ÆÉÓÖჄ‘‚‹Ú—Ä–ö“¢¢••¢ÚÚ““¢Î‹Œ‹Î¤¤¢Ú”””””öò—ò•¡‚‘‘‡‘ƒØÒÆŽ«·´¶¼¼®»ºœÝŸŸ°²²Ÿüíêëíþúúûûúüÿîíîÿþüüþþÿÿþüüüüïëêéèèçåãããââââââââââââââããäåçèèèéçåãâââââââââââââââââââââââââââââââââââââââââââââã½éìëéç½äâââåèêëéèéèäâââââââã½êïüû°ÛÞݲ°°±°°°Ÿ÷ûÿïÿïîíîþ÷±ÜÞ­©®¶´·¬¾ÀÏÑÕÌ…ƒ‘ˆ‹Ú—Äò””Ú““Ú””Ú“•¤¤¤¤¤•¢Úö”ööòòò——ò“‹‰ŠŠ‡†ƒØÒǾ¸´¶¶¶ª»œÞ°Ÿ÷°°úîéççéìîïïïîíëêêìîïïÿÿÿþüüüûûüïíìëêééèççåãâââââââââââââäåå½èèèéêè½ãâââââââââââââââââââââââââââââââââââââââââââââãåçéèèçåãââãäå½çç½åãââââââââäçêîÿú²ßôßÝÜÝÝÜÛ±°÷üþüþÿïîïü÷±Üß­©ª¶ñæ§«¿Â’ÅÐÊËá †ˆ‹“—ijĖ£òööòòöööÚ““Ú“¢“Ú”öò£££òòööòò“Ρ‰‚‘„ ÖÑÍ€¿§µñøø¼®œßÛ°Ÿ÷÷ÿê½äåçéêëìëëéèèèéêëíííïüûû÷Ÿúüïîìëêééèèèåãââââââââââââäççççèèéêé½ãââââââââââââââââââââââââââââââââââââââââââââââããäåå½åäââãââãåç½ãâââââââââã½éëîþŸÝ­­ôßÞßßÞܲŸúüüûüüüþÿü÷²ß›ž¦È¶ñ測¨ÁÂÃÏ™šá ‘ˆ‹“—Ä£—££ò”öö”“Ú”“““Ú”ö—–£—öÚÚÚöò“Ρ‰Š†ƒÌÊÉÆ¨¸µø¶È¼¦º›ôܱŸúþë½ããäå½çççèéèçç½å½êëìíÿüû÷ŸŸûþïíëëëëêèéè½ãââââââââââââ彽罽èéêéåâââââââââââââââââââââââââââââââââââââââââââââââââââãäääããããåççèåãâââââââââãçëïü÷±Ý­¹ßÜÛÛÝÝܱ÷ûûûûû÷úûþü°Þ›º©¦®ªÈýæ·§«¿ÂЙšáƒ†ˆ‹“ò££££–£—òòÚ“¢•¤¤••¤¤Î¤¢“ÚÚ¢•¤¤Î¤¢Ú•Œ‰ŠÙ…šÕÑÇ’À§µ¶¼®¦»›ôÞÛ°úþíçãâââââââä½éèèçäãåèêêëíïþûüþÿïíìëêêëéèèçåãââââââââââââãåäãââãäåäââââââââââââââââââââââââââââââââââââââââââââââââââââââãåäääåçééè½ãââââãå½åäåèîþ÷°±Ý¹ôÞÛ±²ÜÜܱ÷÷÷ûú÷ŸŸ÷ûû²¹º¦ª¼ª¼øµù¸¯¾¿ŽÐ™š…„‡ˆ‹“ö———£–£—òöÚ•‹¡¡Œ‹‹ŒŒ‹‹‹¡‰¡Œ¤•΂† šÊÒÍþøª¦©ºž­ßܲŸûþîêåâââââââââåçèçåããäçéêêëìïÿîîîíìììëììêèçåäãââââââââââââãäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½½åå½½çèè½ãâââä½êêéççêíþŸ²Ûß¹ôÞܲ²ÛÜÝÛ²±°÷÷Ÿ°ŸŸ÷ŸÝœ»Èøñ¶¶ý¸¬«¨Á’ÅÐÔš ‘‚΢”ò—————£òö¢Î‰‡‡‚‚ˆ‰‰‰‰ˆ‚‡††‘Šˆ‰¡ŒŒˆ‘Ù ØÔÑÐÅ¿§ýªž­ôÞܲŸúþïíéåââââââââââãååäããâäå½ççèêìíììêééêëìíîëçäââââââââââââââââãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½½½½½ååççåãââã½êîíìììíÿú²ÜÞô¹ôßݲ²ÛÝÝÜÜÛ±ŸŸŸŸ°°°Û¹ºªñ´´ýý測¾¨ÀÂÃÇÐÔš ‡ˆ¡¤¢”—££————ò”•¡‘ÙÙ„„†‡Š‡‘Ùƒ …… Ù†‡‚ˆˆ† ÌØÔÉÍ¿¯¶©œßܲ±Ÿúüÿîëèäâââââââââââããããããããäååå½çéêééèçççéìîïëçãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäååç½åäå½çåäâââ½êíîÿÿþûŸ±ÛÜÝÞßôßܲ²ÛÜÜÛÛÛ²°Ÿ÷úúŸ²Ýœ»Èýýýýµ·¯¾ÀÁÁÃÆÐÔš ‘Š¡Î•“öò———ò”“•¡‘…ËššššÌ………áÌËËËÌ…ƒ„††„áØÕ™ÉŒލ§æñ¦ž¹Ý±Ÿ÷ûïìêèåãâââââââââââââââââââãåç½åääååå½åäãã½éëìèåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäåäåç½åää½çåäââäèëîÿüû÷°²ÛÝÝÞÞßßßܱ±°±±±±²²°÷ûûú°Ü­ºªñýý´æ·¯«¿ÀÁŽ’ÃÆÉ™Ø…„‡‹•“”öò——ö¢¤ŒŠƒËÖÊÔÓÔÊÖÖ×××ררšÌÌá…áØ™Ó¥Ç’Â¿§æñªº›ßܰ÷ûÿìêèåãââââââââââââââââââââãåç½äââââããâââãåçéêè½ãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäååääãââä½åäãã½ëîüú°²ÜÝÝÞßßßßßßßܲŸúûûûûú÷÷úûû÷±Þœ©Èñµ·¸¯¬¾¨¿Â€ÃÆÏ¥Ô×Ë ‘‰‹¢”òòöòò¢‹¡ˆ‘…×™ÑÉÐÉ¥ÑÒÓÔ™™™™™™™Ô™ÖØ™ÑÐÆ€Â¿¬·´È©›ßܱ÷þíêèåâââââââââââââââââââââââåè½äâââââââââãåçéëêçäââââââââââââââââââââââââââââãâââââââââââââââââââââââââââââââââââââââââââââââââãåçåäããââä½ååäåêîüúŸ²Ýôßß¹¹¹ôôôôôÞ²ŸúûüþþûŸŸ÷ûûŸ²ô¦¼ý·§¯¯¬¾¨¨ŽÃÅÍÐÉÓÊ×á„‚¡•”òòö”“Ή‚‘ šÊÑÐÇÅÆÆÆÍÐÉ¥ÑÒÒÑ¥ÉÐÑÔ™ÒÏ’ŽÁ«¸æñ®œ­ÞÛ°úïëèåãââââââââââââââââââââââã½çåãâââââââââãäçêëêèäââââââââââââââââââââââââââââââãââââããââââââââââââââââââââââââââââââââââââââââââä½åäãããä½ççççéëïþú÷°ÛÞÝÞÝÝßôô­­¹Ý²±±ŸûüûŸ±ŸŸúû÷²ôžªñù¸§¸¸¯«¬¾Á€ÅÍÏÉÑÔÕš…„ˆ‹•ÚÚ¢•¤‡„…šÊÑÐÍÆÃ’’€ÃÆÍÏÏÏÍÇÍÉÒÔÉÅ’ŽÁ¾·µý¶©›¹Þ°ûüÿë½ãâââââââââââââââââââââââââä½åãââââââââââã½ççç½ãâââââââââââââââââââââââââââââããââââãããâââââââââââââââââââââââââââââââââââââââââäå½åãâãåèêêêëìîïþûúŸ²ÜÜÛ²ÛÞß¹œœ­ÞÛÛÛ°÷÷÷²Û±Ÿúú°Ü¹œ®ñ·¸·ùù¸§¯«À’ÅÏÐÐÑÓ՚ბˆ‹•¤Î‹Š„áØÊÑÏÆÅÀÂÀÀÀÂ’ÆÅÅÅÆÏ¥ÒÏÃÀ¾¸µñ¶ªº­Þ²ûïíê½ãââââââââââââââââââââââââââãåäãââââââââââä½½ååäââââââââââââââââââââââââââââââããâãå½½½åäãäå½ååäãâââââââââââââââââââââââââââââââããäåäãããäçëíïþüüüüú÷Ÿ°±±±±²ÜÞ­ž¹ÞÞܱ°Ÿ°ÛÞÝÛ°°ÛÞ­ž©ªý·ùæù·¯¾ÂÃÇÐÉ¥Ò™ÖššÌÙŠ¡¤‹‚‘ÙáØÊÑÍÅÃÁÀ¿¨¾¬¬¨Á€ÅÅÆÏÉÆ€Á¾§æñ¼®©­Ü÷ïëèåãâââââââââââââââââââââââââââãååããããââââââããããääãããâââââââââââââââââââââââââââããâã½èéèç½½½èéèèççåãââããäâââââââââââââââââââââââââââãääãâãåèíÿú°°÷úúú÷ŸŸ°±±±²Ýßœºº›­¹ßÝÛÛÛÞßÞÝÛÜÞô›º¦È´ùùæµæù¸¬¿ÅÍÐ¥ÑÓ™Õ×ÖØ…‘ˆ¡‰‡„ Ë×™ÑÏŀ¨«¯§§§¸¸¯¨ÃÀÃÃÇÇÅ’À¬ùý¶®©ºž¹²üíéåâââââââââââââââââââââââââââââãçåääãââââââãäâââââãããââââââââââââââââââââââââââââãããä½è½å½çåå½çç½çè½½ççç½äãâââââââââââââââââââââââââääããäçêîþû÷°±°°Ÿ÷úú÷Ÿ°²ÛÝß­©žœœ­¹¹¹­­¹ôßÞô­ž®¶´µý´¸¯¨Â€ÆÐÉ¥ÓÊÕÕ™ÊØ…Ù††ÙÌÖ™ÒÏ’Ž¨¬§·µµæù¸«Á’’€ÃÅÆÅ€Ž¿¬ñª©ž­Þ±üìèäâââââââââââââââââââââââââââââãåãââââââââãääââââââââââââââââââââââââââââââââââââããããääãä½ç½ä½ç½çéëëëììëêè½ãâââââââââââââââââââââââãääå½èëîü÷Ÿ°²²²±°÷ûú÷Ÿ±ÜÞô­ž»»»©ºººžœ›­¹­œ¦¼ø´ææ´ýýæù§¾Á’ÆÏÐÉÓÕÊ™ÓÔÕš…ƒ…šÊÑÐÇ¿¨¬·æ´ñ¶ÈÈøýµù¯¿Ž€ÃÁ¨¬¶¦ºœ­ßÜŸþëçäâââââââââââââââââââââââââââââãäããââãäãâââââââââââââââââââââââââââââââââââââââââââââââãå½½åå½çèéëíîÿÿÿÿÿíéåäãâââââãäãââââââââââââââåçêêìíïú°²ÜÝݲ°Ÿ÷÷÷÷±Üß¹›ž»¦»©©»©»»®®®»ž›­¹­ž®ª¶ñýñøøññ´ù¯¨ÇÍÉÔÕ™ÓÒÓÊØÌÌÖÓÐǾ§ùµñÈ®©»¼¶ýæ·¬¿Â’’€’’€€Ž¿«§µÈ¦­ßܱûîê½ãâââââââââââââââââââââââââââââãäåååååäâââââââââââââââââââââââââââââââââââââââââââââââãäåääååçééêìïüûûûûûÿìéè½åäããä½çåãââââââââââââäçêííîïü÷±ÜÞôßܲ°ŸŸŸ°²Þ­œžº©»©©»¦»»ª¼ªª¦©œ­¹›©ªªÈ¶¶¶¶¶¶¶ñµ·«Â€ÆÇÏÒÔÓÑÑÑÔÕ××ÓÏŀ¨¸µ¶ª¦ž­¹¹œ©®¼ø´¯¨ÀÁŽŽÂÁ«§·ý¼»žôÛ±úïëçäâââââââââââââââââââââââââââââââãå½ççåãââââââââââââââââââââââââââââââââââââââââââââãäääääããäå½½½½éíïÿÿþþþïíêéèèåãäåçèåãããââââââââââäèéêìîþúŸ²Ý¹›œ¹ÞÛ°°°±Üß­››­›žº©¦¦»žœ›ôßô¹ž»¦ª¼¶ñýñøñ´µæ§¿ŽÃÅÍÐÐÐÍÍ¥Ó™™ÉÆ’Á«¸µ¶»ž›­¹ßÞô¹›ž»ªø´æù¸¬¬«««¯·´È¦œÞ±üíéåâââââââââââââââââââââââââââââââââãããäãââââââââââââââââââââââââââââââââââââââââââââââäçç½½åäãääå½å½êíîîïÿþþÿïíêêé½äå½çèçå½åãâââââââââä½çêìïûŸ±Ü¹œ­ÝÛÛÛÝô­›­¹ô¹›žžºº©œ­­¹¹ÞÝÝßœº»®¼ñ´´ýñ´´ý´·«Á’€’€ÃÅÆÍÉÒÒÏ€Á«·´È»ž¹ßÞÞßÞÜÛÛÜÞ­º¦¼¼Èø´æææµý¶¦›Ý÷îèäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåèééèç½åå½½ååçêìíîïÿþüüþïîìéç½½çèè½å½½äãããââââââãåçêìïüŸÜ¹›ž©¦©¹ßÞÞô›œ›­ôôôô¹›ºž›¹ßÞÞܱ±ÛÞ¹›º¦È´µµý´ýñøý渾ÁÀÀÁÂ’’€ÆÍÏŬý¼œôݲ°°°°°Ÿ°Ÿ°Ûßœ©©»¦ª¶øø¶È®ž›¹Ûûëåââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèééêêéèèéçççèéëìîîÿþüüüÿïìéééêëìëêéééèç½åäãäãããä½èëïüŸÛô›®È®œ¹¹­œžž›¹ôôßÞß­œœ¹¹ßÞܲ°°²Ýß­»¶µµ´ýññøøñ´ù¯¾««¾¨¿ÁÂ’€Å¾ñ¼©œßÜÛ°÷ûüûúúúûúŸÛß­­­­­›¦®¦»©ºœ­¹Þ°ïèãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½çèëîíììëééèèêììììííîÿÿîíëëëìíÿþüÿîííìëêêéèç½½ççéëïû°Üß›»ªÈ¶ª©ž­¹››­¹ôÝÝÝÞÜÜÞôœºž›­­­ôÞÝܲ±ÛÞô›º¦¶´´ýñ¶¶Èøý´æ·§¸§§§¯«¨¿¿À¾ùñ¼»­ÞÛ±úüÿîïÿþÿÿûúŸ°²ÜÝßôô­žœ­¹ôÞÝܱüìçãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½èíþÿïîíìêéêìíììëêêêìîíìííîÿþûŸ°ŸúûüþÿÿïîíìêééêìïûŸÜß›»¼øññ¼¦žžœ­ôÞÜÛÜܲ²Üßœœ›­¹¹¹ßÞÝÛ²²ÜÞ¹œª¶ññøÈ¼¼Èøýý´µæµµµµù¸¯¬¬¾¨«ùñª©›ôݲ÷üþîìíììëîÿþþû÷Ÿ±ÛÜÝÝßôÞÜÜÜÛ±Ÿûîêçãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåêÿ÷÷úüþÿîîîïïîíëéèééêëíîïþüû°ÛÝÞßÞܲŸúûüüþïíîïÿþú±Ýôž©ª¶ýµ´¶ª¦©©œ­ôÝÛÜÛ±±Üß­œœ›­¹ßÝÝÝÛ±°°Üô­œ®¼ø¶¼®®ªÈøññø¶È¼ª¼¶ýµæææùùæñ¼©œ¹ßܱ÷üþÿíìéèççêììíïÿþû÷°°±±±°±±±°÷üïê½äââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäåäââââââââââäèíúÛܲ°÷ûþþþÿþÿîìêêêêëíïÿüûúŸ²Þ¹›œ›¹Þ²°ŸŸ°÷úúúûûúŸÜô›º®øýææ´øÈª¦©œ›ßÛ²±±°°ÛÝß­­¹¹¹ßÜÜܱ°°²Ýß¹œº»ªÈ¼¦¦¦®¼¶øøÈª»©»®¼È¶¶¶øøø¼¦žôÞܱúþïîíìé½åää½èèéêìíîþüûûûüûûûúûþïìçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½ç½äââââââââãåèêíúÛÛ±²±÷üþþþüþÿîîíîîîïüú÷ŸŸŸ±ÛÞô¹ôôÞÜÛ²²ÜÜÜÛÛ²±°ÛÞ›©¼ýµæµýø¼©ž›­¹Þ²°°°Ÿú÷°²Ýôôßô¹ÞÜÛ°°±²ÛÜÝÞôœ¦¼®¦®®®ªÈ¶Èª¦©ººº©»¦®ª®©¹Ý²Ÿûÿïíêèçåãâââääåçéééëíÿÿÿïÿÿÿïîëééèäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããââââââââââäçëíÿ°ÛÛÛÜܰúüþþüüûüüüüüûúŸŸ°±±°°°±ÛÝÞßßÞÝÝß¹­­­¹ôÞÝÞ¹žº»¶µæý¶®©­ßÞݲŸŸ°Ÿ÷ûúŸ²ÝßÞÝßôßݱŸ°±ÛÝÛÛÜÝ­º»®¦¦®¼ªª¼¼ª»ºž›¹¹¹­›œº›Þ±úþîìëéåääãââââââãåç½çèêììììíîìê½åå½åâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèíïûŸ²ÛÛÝݱŸ÷÷Ÿ°°°°±±±²²±±°°²Ü²±Ÿ÷Ÿ±ÛÜÞßô­œžºººž­­œªøµùµ¶®©žôݲ±°Ÿ÷úûûûúŸ±ÛÝÝÞô¹ßܰ÷Ÿ±Ûݲ²²Ûß­©»¦ªÈª¦»»ºžœœœ­ÞÛ²²²ÛÝß­›¹Ý²Ÿûïëçåãâââââââââââãäååäåçéììíêçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéïþú°±ÛÜÞÞÜÛÛÛÛÜÜÜÜÝÞßÞÞÝÜÛ²ÜÜÛ²°Ÿ÷°²ÜÞôœº»¦®¦¦»»žž¦Èýµùùæø®©¹Ü±°Ÿ÷úûüüüû÷±²ÜÝÞßßÞܰ÷°±Üݲ±±²Üß›º©¦ªª¦©©ž›››ôݱ÷ûüüûŸ²Þßܰ÷ûÿíçäââââââââââââââããââãäçéëêçãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåëÿüúŸ±ÛÝÞßßßôôßÞßßôô¹¹ô¹¹¹ÞÜÜÜÝÝÛ²²ÛÜÞô›©¦ªÈ¼ª®»©®Èøýµ·¸·ý¼®©›Ý±Ÿ÷úûþþüüüúŸŸ°²ÝÝÝÝÛŸúŸ²ÝÝÛ²ÛÝßô¹›©»»»©ºžœ­Ý°üïïïíîüŸ°°úüÿîë½ãâââââââââââââââââââââãå½åãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½ëþüü÷°²Ýß¹­­žœ­›œ›­­›œžœœ¹ßßÞßßßßôôôß¹žº»¦¼øýø¶¼®¦®¼øý´µæù·§§æøÈªßÛ°Ÿ÷ûüüüþþûúúú°ÛÛÜܲŸ÷°ÛÝÞÜÜÝÞôôßô›œž»©©ºž¹ÜúïíììëìîþþÿïíëéåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåêïÿüúŸ²Üß›žº©»ºœœºººœ›­ôßß¹›­­¹ô›º¦¼Èø´æµýø¼¼¶ýµæææææù¯¬·´ñ¼›Þ²°Ÿ÷úþÿÿÿþüûûú÷±Û²±±±±²ÜÝÝÞÞßßÞÜÜÜÞ¹œº»©œ¹Ûúïìëêêêêëëëè½äãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãââââââââââââââââãåêîÿþúŸ²Ý¹ž©¦ª¦©©©žžžº©ºœ¹ô¹›œ­­ôß­º®È¶øý´´µñøñ´æù·ù¸¬¬¸æý¶¦ß²°°°÷þïïîïïÿÿÿû°Û±°°°±±ÛÝÞÞÞÞÝܲ°²Ý¹ž»©ºž¹ÛûíëêéèçççççäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãâââââââââââââââääçëïïÿûŸ±Üô­œž¦»©ººž›­­›œºœ­­­›œ›ôÞÝÝß­©¦®®ªÈøøøýµ··ùùù¸¯¯¯¸ùµø¦œÞ²±±°÷üïíëëêëíïüŸÛ±Ÿ÷Ÿ÷÷±ÜÝÝÝÝÝÝÛÛÝß›º©ºž›ß±üíéççççççèçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäççèìîîïû÷Ÿ±Ýß­œº¦»ºž›­ô¹­œœœ›­››­ßÜÛÛÜÞôœºº¦¼Èøýµ··ùùù§¯¯¯§·ý®žßÛ²°Ÿúüîêç½çéëîüŸÛ²°÷úûú±ÜÝÝÜÛÝÝÜÝß¹žºžœ¹Ý°ûíéç½½çççèçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèëìììíîÿûúú°±Üô›º»ºœ›¹ôôßô­žººžœ›­¹Þ²°°±²Ý¹­››œ©®Èøýµù§¬¬¬¸æýªôܱŸúüïë½ããåèëíÿú²²°úþÿü°ÛÛÛ²ÜÝÝÞßô­œžœ¹Ý°ûíê½ääååå½çäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäçêìîííìíïþüüú÷Ÿ±Þœž­ôÞÞÞÞô­œžžžºž›­¹Ý±Ÿ÷Ÿ°ÛÞßßÞß¹ž»Èøýµùù¸¯¬¯·ææ´È©›Þ²Ÿúüîéäâãäèëíÿú±±Ÿûïïü÷°±±ÛÜÝÝÞßô­œœœžžž›¹Ü°üîëè½åäääååãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäçêííííîííïþþþú°±²Þ­ž›ôÝÛÛÜÝßßßßß¹››œ›­ôÞÜÛ±±°°²ÜÛ²ÛÜôœ®¶ýæ···ùù¸¬¬¯·æµ´¶¦žßÛ°÷üíçãââã½éíÿûŸ÷úüÿÿÿþûŸ±²ÛÜÜÝô¹­››­­››­ôÞÛŸüÿîìëéééè½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããåèëìììíïÿïïÿþþü÷±ÛÝÞô›ž­ßÛ²±²ÜÞÜÛÛÛÞô¹­¹ôÞÜÛÛÛ²±°°°Ÿ÷±Üß­ž©¼ñù§¸·ùù¸¯¬¬·æµý¶®ºœß²Ÿüì½ãâââåéíïþüüûüüþÿïþû÷Ÿ°°±Ýôôßô¹¹ôô­ôÞÝÜŸûþÿïîííëé½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââå½èëíìììîïÿïïïÿþûŸ²ÜÞÝÞôôßݲ°°²ÜÜÜÛ²²Ýô¹­ôßÝÛ²Û²±÷ûûûüþû°Ý¹ž®ø¸·ù·¸·¸¯¯¸ùæñ¼¦©ºôÛŸþë½ãââåèëìíîÿþþþþÿÿïîïþüüú°ÝôßÞÞÞßßô¹ôßßÞ±÷þÿÿþïîìé½äääãääãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåçéìîÿïîîïïÿïïïÿþûŸ²ÜÜÜÜÞÞÞܱŸ°²ÛÜÜܲ±Üß¹­¹ôÞÜÜܲ±úüþþÿïþ÷Ûôœ¦¶µ··¸¸·ù·§§¸·æøª¦¦¹²÷ÿêåââãåèêêëíÿÿîïÿÿÿíëìîïÿü°ÝßÝÜÜÝÝß¹¹¹ôôÞ²÷üÿþþþïëçåäååå½åååäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçéëíïÿþïïíììíïÿþûûúŸ°±²ÜÝÝÛ²°÷Ÿ²ÜÝÞݲ±Üß­žž›¹ßôßܲŸûüüþüûú°Üôœ®ñæùææ·¸¸ùæñ¼®¦›Þ±þë½ãâââãçêêëîÿîììíííêéêíïÿü÷±²±±²²ÛÜÜÝÞÞÞܰüîíííìëèåãââââââââãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½èêëíîïîìììîÿþûûûúúúŸ±ÛÝÝÛ±ŸŸ±ÜÝßôôÝÜÞô›ººžœœ­ÞÛ±÷ûüûúú÷°Üß›ž©Èýµ´ýý´æùùæ´¶¼®©œôÜúíçäãâââãçêêëííìêééêëéèêíïþüûú÷°°ŸŸ±±±²ÛÛÛ²úîëééééè½åãâââââââãäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½çèéêììëìíîïÿÿÿþûûüû÷÷°²ÜÛ±±ÛÞô¹›œ›¹¹­œº»»»»»ž¹Þ²°úú÷ŸŸ°±Ýô­œº¦Èȼ¼ÈÈøýµ´´ñÈ»ôÛ÷ÿëçäãâââäçêêëëëêêéèèèççéìíïþüûú÷÷ú÷ŸŸ°±°°°Ÿþìèççç½äââââââââââääââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½½åååçêìîïïïïÿþüþüú÷÷ŸÛÝÛ²Ûݹœžžžž»¦®ª®®¦žôÞ²Ÿ÷ŸŸ°°²Ýô›œž¦»©»®ª¼¶ñýýø¼©›Ûúþîëçäãâââäçêêëëìëéèççèèçéëíÿÿÿþûúúúú÷÷Ÿ°÷ûûþíè½ååäââââââââââââãäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½½äããåèééêêëîÿÿþþüûûú°²Û²²Üô›ž©º»®®¦»»»»©ºœ›ßÛ±±°°Ÿ÷°²Ýôôô›ºº»ª¼¶ø¶È®ôŸþîíêçäãããä½éìëêêìêç½½½çççéíïÿîíîïîïïÿþüúúÿíìëçåäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½äãä½èèèççêìîïþþüüû÷°±²²ÜÞ¹œ©¦»©¦ª¼ªª¦»»»žžœ¹ßÝܲ±Ÿúú°ÛÜÛÛÞ­›››œ¦ªÈȼª»›Üûîíëêçäããäçéìíëéêìé½½çèééèëîÿÿíìëëêêëëìïþÿìéçåãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãååããå½çç½å½çèêíÿüûûú÷÷÷Ÿ±ÛÞ¹œ»¦»©»ª¼¼È¶ª¦»©ººž­¹ôÞÛŸûúŸ°°°±ÛÜÜÝÞôœ©®¼ªª¦º¹²üîìêè½åää½èêììéèêëéééêëëëìíïÿïíìêêèçççèêëìê½ãââââââââââââââââââââââââââââãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½åãâââãäåääå½½èìïþûúúúûûúŸ²ß›©»»»®È¼¼¶ø¶ª»ºº©»ž›ô²ûþüúú÷ŸŸ°°°±²Ý­º¦¼¼¦º›Þ±üîëéç½½çççèêëêééêëëëëìììíîïîîîíëëéè½½å½çéêèäâââââââââââââââââââââââââââãääâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäååãâââââã½åååçèêíïïÿþûüüüûŸÜ¹žº©»®¼øÈÈø´ý¶®©©»»ºž­ßÛ÷ÿíïþûúúú÷÷Ÿ°±Ü¹ž»¼ª©žßÛŸüîëèç½½çç½½èççéêëìëêééêëìíìììíìëììëêéèèéêêçäããââââââââââââââââââââââââââãäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäãââââã½éçååçèêìîîîïþþþüú°Ü­ººº»®¶ñ¶¶ýµ´ñȦ¦¦¦¦ºœôÛŸþìëìîÿþþÿþúŸ°²Ýôœ©¼®©›Ü±úÿíëéèç½½åååääåèëîïíêéèéêìíìëìíëìíïîîíìëìëêçåååäâââââââââââââââââââââââââãäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäãâââãåèêçååå½èëîííîïÿþû÷±Ý­ºº©¦Èøøñý´´ýøÈ¼ª®»ž¹Ü°üíêèèêëíííïûŸ²Üß­»ª»ôÛŸüïíëéè½äãâãâââãçìîÿîìêèêìïÿîìëëëìïüüûþïîíêçççèéçäâââââââââââââââââââââââä½çåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãããâãååèêçåå½çèëìíîïÿþüŸ±Üß›º©¦¼¶øñ´µ´ýñøÈª¦©œß±ûïìèå½èêêêëîü°²Þ¹›»ª©žß²÷üïíìëéçäãããâââäèëîïîíêèëíïÿîìêéëîüú÷÷úüïíéçèêëêè½ãââââââââââââââââââââââä½çåäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãääåçç½çéêéééêìîïþûŸ²Ý¹›œºº©¦®ªÈñµýø¶Èª¦»œß°þïìçäåèêëëìÿú°²ÜÞ¹œ¦›Þ²°úÿíììêéç½åååååèëííìëêè½èêìíëéèéìïüú÷ŸŸ÷üîêèéêéèè½äãââââââââââââââââââââââäåääâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½çèéëëêéèèëîÿü°ÜÞ¹œžžººº©»®¶ñø¶ÈȪ¦»›ÝŸüÿíçääçêìíîü÷°±²Üß­º»œôܲ°ûîííììëéçççèêìííìëééç½çèêêèççéíÿüû÷Ÿ°Ÿûïëèéêèèççç½ãâââââââââââââââââââââãääãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½èéëìíëéççëïüŸÛݹžººººžžººººº»ª¶ññø¶ª¦»º­Ý±úþíçäåçêíîÿü÷°°±Ûݹ›ôÞÜŸþïîííííëêééëîîíìêêéçççèêéçççêîÿþúŸ°°Ÿûÿíëêéèèççèçåãâââââââââââââããâââââãäãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½éëííìêéèèëîû°Üßœººž©º»¼øýýñø¼®©¹Ü±÷þìçäåèëîÿüû÷Ÿ°°°Ûôž©ž­ßݰüÿïîîîîíìëëíïîìëëêèèèèèéèèééëîþûŸ°°°ŸûþîëêèèéèèèéçåâââââââââââââãââââââãäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçêëêèçéêëíÿûŸÛôœººººººžž®¶ýýññ¶ª©ºžß²÷üîê½ãäèëíîÿü÷÷Ÿ÷÷±Þ›œ­¹ßÝܰûïííîíìììëêêëëìììêééèèééèêëêëîþúŸ÷÷Ÿ÷ûÿëèèèèééèç½äãââââââââââââââââââââããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçèç½çêíïÿþü÷Ûôœºº©ººººº¦Èýµý¶ø¶¦œ­Ý°ûïìê½ãåçêìîïü÷÷úüüŸÜô›­ôÞÜÛ²°ûÿîïïìêëìéçèçéëíîìééèéééêììëìîüú÷úúúúüïé½ççèéèè½äããââââââââââââââââââââãäãâããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäå½éìÿú÷úúŸ²ß›º©¦º»»¦ª¶ñµýøÈ¼©œ­ôÛ÷ÿëéè½å½çéìíïû÷úüÿüú±ÜßÞݲ°Ÿ÷úûüþÿïìêéè½½½½èëîÿíéèççèéêëëëìîþû÷÷úûüïìç½½çèéèçååäãããâââââââââââââââââããäââãããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåêï÷±±±±²ÛÞ¹žº»¦©ººº»¦ª¼¶ýæý¶È®ºœ¹Þ²ûîéççç½å½éëìïüúûÿïÿü÷±ÛÛ±Ÿúûûúúúüþïìéçç½ååäèìÿüïëé½çéêêëëëëíïüúúûþíëè½ää½éêèçåäããäãâââââââââââââââââãå½äããäãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåëü°ÛÜÞßß¹­›ž©©©»©©»®ÈøýµæñÈ®»­ÞÛ°ûíçääåäãåçèêìïþþïÿþûúú÷÷úûúúŸŸŸ÷ûÿîêçççåääåéíÿþïíêççèéééêêêëíîÿÿîëèç½äââäçêéçäããåäââââââââââââââââââã½çåãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½îú±Þô›œžžž©©»¦®»©»®Èýµæùùý¼¦œ¹Ý±Ÿüë½ääãâãäå½èéìîîîïÿþþþüüüüû÷Ÿ°Ÿúþîëéçççåää½éìîþÿïìééèééêêéèêëíîìé½äääãââã½éêè½åååãâââââââââââââââãåäåçè½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåéÿ÷ܹœº©©»©©¦®®®¦»»®Èñæ·§¸µ¶»­ßÛ°úÿëç½½ããâââãä½èëëëìîîìíîÿþþûûûú÷üîìëéèç½åäåçéêíïîîììëêéêêêééëíîïìéåââââââã½éêéèçåãââââââââââãããââãå½½éëëé½äâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçêþ°Þ›©»¦¦®¦»¦ªª®¦¦»»ª¶´·§¯§æ¶»ž¹Ý²°úÿìéèçåäãââââãçèéêëìëêêëîïÿÿÿÿüúÿììêéèçèèççéééìîíííííìêééêêêëìîîëçäââââââä½çèçç½äââââââââââãääãããäåçéëííëé½äâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½èèêïŸÝ­œžºººº©»¦®¦»ºº»¼ñµ·¯««·´ª¹ÜÛ²÷þîìêéèçåãâââå½½èéêêêëêêìííììíÿüîìëêéèéêêééééêëíìëêêêêè½çèèèççéê½ãâââââââââââââââââââââââââããââââãåèèéíïíêçåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçèéèéî÷Üô¹­›œœœžº©¦¦»©žªø´·§«¾¸µÈ©­ßÝܰûþÿíëëëèäãâäååå½èçéêëêééééêëëîþîìëëèèêììëêéééêêêéççç½ää½ç½äããå½ãââââââââââââââââââââââââââââââââãåèèéìïíêèçäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäçéëëìþŸÜô¹ô¹›œžº©»ž­­ž¦¼ýæ·¯«¸æø»œôÞݰúúûÿîîîêçååãããä½èééèéç½ååå½çéîþïìêè½çêìëêèçèéèèç½ååãâââäåãââââââââââââââââââââââââââââââââââââââãåç½çëîíëêêçåäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåêìîïÿúŸÛßßßô¹›žžº©©ž¹ßôœ©ªø´¸¯¸ø¦ž¹ßܱ°°°÷ûþïìêè½ããää½çèèèéè½ääãäåèëîìêçç½èêìëêéééèç½½åäãâââââââââââââââââââââââââââââââââââââââââââââãåååçêìêèéêéç½äââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåéíîÿþûú÷±ÛÛÛÜÞ¹›žºº©©ž¹ôô›º»®¶´¸ùµ¶¦­Þܲ²ÛÛ±úüÿíëèçååäãããääåçç½å½ääå½èéçåäåå½éëììëëéç½ç½½äâââââââââââââââââââââââââââââââââââââââââââââââãäää½é½åå½½½åäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããå½éìþüúŸŸ÷ûúŸŸŸ²Ûß›ººœôôô¹­ž®øµæ´¶®›ßÝÜÜÝݲŸúþîëéèççäâââââãäå½½½äãäå½åãâââãäèëììììé½åçççåãââââââââââââââââââââââââââââââââââââââââââââââââââä½äãâãäääãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½éêìîü°±²±°úüûúú÷°²Þ­žººººž¹ÞÞßßô¹œ©¼ñ´ýñ¶¼»º›ôßÞÞÝÛ²°úþïíëçäâââââââã½éèåâââääãâââââãåèééêìêççççç½åãâââââââââââââââââââââââââââââââââââââââââââââââââãäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ½ëîþú°ÛÞÞÜÛ±÷úúúú÷°²Þ­žººž¹ßÞÝÝÝÜß­»¼¶¶ø¶È¦œ­¹ßÞÝܲ°úþÿîë½ãââââââââ½êèäââããââââââââãåå½éëéè½½½½½åãââââââââââââââââââââââââââââââââââââââââââââââââââäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçìïû±ÝÞôßÝÜÛ±²²±±±²ÜÞ¹œœôÞÝÛÛܲ²ÛÝ­º©¦ª¼®»ºœ­­ôÞÝÛ±÷üÿíëêèäâââââââââ½êçãâââããââââââââââãåååããããããâââââââââââââââââââââââââââââââââââââââââââââââââââãåääââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèìÿŸÜß­¹ßÞÝÝßôßÞÝÝÝÞô­œ›¹Ýܲ±²±±°±²ßœº©»»©œ­­¹ÞܲŸûïîìé½ååâââââââââãçé½ãâââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½½åãââããäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèëï÷Üôžœ­¹¹¹›œž›¹ßÞß¹¹¹ßÝÛ²°÷÷÷Ÿ°°°Ûôœºž›­¹¹ßÛ°úüîìêè½äääââââââââãå½½äãââãääãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãç½åããåçèèåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåèêíúÛ­ºžžœžº©»©›ô¹­¹ßܱ²±Ÿûûûú÷ŸŸ±Ý­žœ­¹¹ô¹ßݰûþïìëé½åãäãââââââââãäååääãâãääãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèç½ååçêëìé½ãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½éíúÜ›ºººžž¦®ª¦©ž­­›¹ßÛ±±±úÿïÿþþþü÷²ß­ôÝÝÝÝÝÛ±÷ûüÿîíéç½½åäãââââââââãä½ääãââãããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåè½åää½èëíëéåââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½êþŸÝœ©©ºº©®¼¶È®º›››­ôܱŸúüïîîïîïÿü÷ÛÞÝÛÛÛ²±ŸŸ÷úüþÿîêçç½½åãâââââââââä½åääãââãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåè½äãä½éìîíêåãäååäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçíû±ßœ©ºº©¦Èø¶ª©›­ôܱúüÿïîîîïïïþú±Û²ÛÛÛ±°Ÿ÷÷÷ûûÿíêè½åååãâââââââââäåääääââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäç½å½èêëíîíêç½½èéèåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåêÿŸ²Þœºº©®Èñ¶¼¦ž›­ôݱúÿïîíììíííïÿû÷Ÿ±±°÷÷úûûüþþîêèçåääãââââââââââããããããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåä½çêëìïÿîëéèéëíìèåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãèíü°Ûßœºº»®È¶È®­ôôÞܲ°ûïìêéçç½åççèëíïÿÿïïîííìêéè½ääãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããä½ééëïþîëêêêëííé½ãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéïú±Ý¹œžºº©¦¼Èª©›ÞÝÝÜÛ±Ÿüïê½åäãââââäåçèééééèéêçåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½èèéîþïíííìíîîëçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçìüŸ²Þ¹­œººº©¦žôÜÛ²±°÷ûÿíçäââââââââââãäääããååãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½½êïüüþÿïïïïïìê½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½ëÿ÷±ÛÝß¹›œžžœ››žœ­ÝÛ°Ÿ÷ûüþîëçãââââââââââââââââããââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäçêÿúúûüþþÿÿïíêèåäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ½ëÿú±Üßßô­œœœ›­ôô¹­ôÞÛ°úûþïîìêèäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½èìþúûûüüüüÿïíëè½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéîû±Üô›œžžœ­ßÞÞÞܱŸûþÿìêéè½äââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½éìþúûûûúûþÿïîíéçäãäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãèíû±Ý¹ž©©©ºœôÞÝܱúüÿïíìé½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèëïüþÿüüÿïîïîíìëéç½äâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ½ìû²ß­©¦¦»¦®¦º›ôÞܲ÷þïîìêé½ãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèêíïîîþûþïïÿÿïïïìêçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéÿ±ôœ©¦ªªªªª»º›ôÞݲ÷ûþîëè½ãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçêììîþûüüüûüþþþíé½äââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåéïŸÝ­žº»®®ªª¼¦ºœ­ôÞ²°÷üîéçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäèëìîüûûú÷Ÿ÷ûûûïëçåäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçëï÷ܹžº¦®®ªÈ¶®©›ôݲ±úþíé½ãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçêìïþüüúŸ²±ŸŸ÷üïêçåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèìÿû±Þ­º¦¼¼Èñ´È»º›ôÝܲúþíèäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçêíïÿþüú°Û²±°ŸûþíéçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãâãäåéîÿüŸÛ¹®È¶øýµ¶®ž­ßݲ÷þë½ãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèëîÿüû÷±Û²°°Ÿûÿíëè½äââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåççééêìîÿü÷²ô©®¼øµý¼»›ôÞܰþêåââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèêìïüú÷±Û±±°÷ûÿîíëéåããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèìîïïïïÿûúŸ²ßœ¦¼ñæùý¼œ­¹ßݰþëåââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãçèêíþüûŸ±Ÿ÷÷÷ûþþþîêç½åäãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½éíþû÷ŸŸúú÷Ÿ°Ûô©®¼øµæñª©œ­ßÜŸÿêäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½èéíÿþûŸ°÷úúúûûûüïìéèç½äâââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½éíþú°ÛÛÛ²²²²Ûݹ©®¼øµ´¶¦ºœ­Ý°üíçãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèëîïÿûú÷ûüûúúúûüïíêçåäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãèíïþ÷²ÛÜÜÜÛÛ²ÛÞ›º»ªøµæ´ø®žô²úÿëçãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèëíîþûûûüüûúûûüüÿîëèåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéíîÿ÷²ÜÝÝÜܲ±±Ü¹»ªø´´ñȪ»›Ý°ûîëçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåèêìïÿþüûüþþþþþüþïíìëçåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåêîÿú±ÛÜÝÝÞÛ±°°Ü­¦ª¶ññ¶È®¹Û÷ÿíêçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçèëîïþûúûüüþüþüÿîìíìé½äâââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½êíÿúŸ²ÜÝÝݲ²°°Ýœ»ªª¼¶¶¼¦žô±üìèåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçéëíïüú÷ú÷ûûüüüþîíîíëèåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½éìÿûŸ±²±°±±Ÿ°Ýœ©¦®È¶È¦ž¹ÝŸïèäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½èêìíïü÷°°Ÿ÷úúûüþÿîïïìèäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½éíÿû÷ŸúúŸŸŸ±Þž¦®¼ÈÈ»ž¹Ý°üìçãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçéìÿüúŸ±±±°÷úüüûüüþïëèäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåéíþüþþüúŸ±²ßœ®ªÈ¶È©›ß²úïêçäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäçêîüúúŸŸ°±°÷ûüûûûûþïêçãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäèìîîîÿþûŸ±Üß›¦ªÈȪ¹Ý²úïëçãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½êíÿÿüüûúûüüþþþþÿîëèåäââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââäéììíîîïü÷²Þßôœ¦ª¼®¹ÞÛ÷ÿëçãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããããããâããçêìíîÿÿïÿÿïïïïïïíëçåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââã½êêêëìíîüŸÛßÞß›¦ª®º­Þ²úÿëèåäãããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½½½åäãääåéììíîîîííëêêëìììêèåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½èççèëìîü°ÜßÞß¹­œº¦»¹Ý±÷þíêè½½çåãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèéè½ää½çèêëìíîîíìêè½ççéêêè½äãâââââââââââââââââââââââââââââââââââââââââââââââââââãââââââââââãäå½½½èêìÿú±ÜÞßßßß­žºœ¹Ü°úüîëêêéè½åãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèêêè½½çèéëìííííìëè½ååääåçåäããââââââââââââââââââââââââââââââââââââââââââââââââââãåãââââââââããããäåçéíÿúŸ±ÛÝÞßÞÞ¹œ›­¹Þ²÷úþïîíìêéç½åãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåèéêëêêééêëìîïÿïîíëçåäãââãããâããââââââââââââââââââââââââââââââââââââââââââââââââââ½èåãâââââãäåäãããå½éíüŸ±±ÛÝÞÞÝÝô­¹ßܱŸúüþÿïìëêéèèçåãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããããä½èêëìííîíììíïÿþþÿïîìçåãâââââââããâââââââââââââââââââââââââââââââââââââââââââââââââäèêèçäãããåçèè½äãäåçêïû±²²ÜßßÞÜÜÝßßßÛŸúüþÿþÿìêéèèèèçäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãääãä½èëíîîîÿþÿíîîïþüþÿïíëçäâââââââãããââââââââââââââââââââââââââââââââââââââããâââââââãä½êìëé½ääåèëëéçåäåçèìÿ÷²ÛÛÞôßßÞÝÝÝÞôݱ÷úüÿÿïëèçç½½½çäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãããäçëîÿïîííìëëëëìíîíìëëè½äãââââââââââââââââââââââââââââââââââââââââââââââââââââââãäçêìîìé½åäåèëëëêèçççêîþ÷²²ÛÞÞÞßÞÝÝÞô­ßܱ°ûþÿïëèç½ääå½äâââââââââââââââââââââââââââââââââââââââââââââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãääèìÿüÿíìëêéééèéêêéééêéè½åãâãããâââââââââââââââââââââââââââââââââââââââââââââââãää½êìîïíêçç½½èëìììëéçèëíÿ÷±²ÛÜÝÞßÞÞßß­­ôÞܲúþïíêè½äããä½äââââââââââââââââââââââââââââââââââââââââââââãäåäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½çêíÿüÿîìêèèéè½çèéèèèéèç½½ääääãâââââââââââââââââââââââââââââââââââââââââââââââä½çêìíïþïìêèççêííííëééêëìïûŸ±²²ÛÝÞÞôô¹›­¹ôݲúþïíëèåãââãäããããâââââââââââââââââââââââââââââââââââââââââãå½åãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½èéêíþüþîìèèééç½½çèçèééèèèç½çç½äââââââââââââââââââââââââââââââââââââââãâââââââãä½éëìîþûþïíëêêìíìíîíëëìëìïü÷°²ÛÜÝÞô¹ô¹ôÞÝܲŸûüÿîëçäããââââââäââââââââââââââââââââââââââââââââââââââââââãäãââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãåçèéëïÿþïíêéééèçççéêëìëëêëéèèèççåãâââââââââââââââââââââââââââââââââââââââââââââââã½èêíþúúüþÿîííííîïïîïîîÿüú÷°²ÛÜÝÞÞÞÝÝÝÜÛ²°÷úûÿíé½ääãâââââãäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½çèëíîÿþïìêêêêéééêëìíîííììëêéèççäâââââââââââââââââââââââââââââââââââââââââââââââââäçêíü÷÷÷Ÿúüþÿÿïþüüüüþüú÷÷Ÿ²ÜÜÝÞÞÝÝÜÛÛÛ²±°Ÿúþîëçãââââââââãäääããââââââââââââââââââââââââââââââââââââââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãå½½½çéêìïÿíëëëëìëëìíîîîîííììëëêèèçäâââââââââââââââââââââââââââââââââââââââââââââââââã½êîû÷Ÿ±±±°Ÿ÷÷÷ŸŸ÷÷÷ûüû÷Ÿ°²ÜÞÞÞÞÝܲ²Û²°ŸŸ÷üïíêåãââââââââãäåå½äââââââââââââââââââââââââââââââââââââââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââä½èç½èéééìïíììììììíïÿÿÿïîííííììéèèçåãââââââââââââââââããâââââââââââââââââââââââââââââââäéîü÷°°±ÛÛ²±°±²²±°÷úû÷°°°±ÛÝÝÜÜÝÛ±±°÷úüþþÿïìçääããâââââââããããââââââââââââââââââââââââââââââââââââââââããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââåè½½çèççêììííìëìíïïîîÿþÿïîíìëëêêèçåãâââââââââââââââãâââââââââââââââââââââââââââââââââãçìÿûûû÷Ÿ°°ŸŸŸ±±ŸŸŸŸŸ°°ŸŸŸ±±°±ÛÛ²°Ÿ÷ûþÿîîîìèåääääâââââââããââââââââââââââââââââââââââââââââââââââââââäããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããââã½ç½½½½å½èêìíììëíÿþïíîïÿÿÿÿîíìëêêèèçäãâââââââââââââââââââââââââââãäããââââââââââââââââââåéíþÿþüú÷÷÷ŸŸ°°Ÿ°±±²²°÷ú÷ŸŸ÷÷°±±Ÿúüîíììíêèåäãââãââââââââââââââââââââââââââââââââââââââââââââââââââãåããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããäåççååå½èèèèçèêìïüûþïííîÿüþÿïííìëêé½ääãââãããäããââââââââââââââââââã½ççååååäãââããããâââââãä½êîïÿÿþûŸ±²°Ÿ÷úŸ°²Û°÷ûüú÷÷úúûûúþïìêééêëçäãââââãââââââââââââââââââââââââââââââââââââââââââââââââââãåäãâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãä½ç½½½½½çèèèççèêíþú÷ûþîîïþúúüþþÿïíìêçååäãâäåååååäããâââââââââââââââåèêêéééè½äãäå½½äââââããä½êîïïÿþú°ÛܲŸúûú°Üܰúüþüüûúüÿÿïìëêè½½èé½åäãããââââââââââââââââââââââââââââââââââââââââââââââââââââãäâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââääääå½çççèëëëìíïü÷Ÿ÷ûþþþû÷÷úûþïîíëêééç½ååçèç½çç½½½½åããââââââââââäçêêééè½åääåå½½åãâââãä½½èìïÿÿþûúŸÛݲŸüþüŸ²Û±÷þïïÿüüïíìëêêèåää½ç½åääããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââããä½½½½èíîïîÿûú°±ŸúûûúŸ°±°÷þîïîëéêëéèççéêêêëëéèééè½äãââââââââä½éëêéè½äããå½½½åäãâããäåçèêîÿÿþüûúŸ²ÜÛ°üÿü÷±Û±÷ÿííïÿÿîìêéèçäãããå½äãããâââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââãäåçèêíïþþûúúŸŸ÷úúŸ±²ÛÛ²Ÿüÿÿïìëëëëêéêêëìíîíëêëêè½äãâââââââä½èêêè½äãããäå½½½åãâãããåçéêìïþüüüû÷°²Û²Ÿûüû÷±±°úÿíííîïíëéè½ä0 \ No newline at end of file diff --git a/lib/glut-3.7.6/progs/bucciarelli/paltex.c b/lib/glut-3.7.6/progs/bucciarelli/paltex.c new file mode 100644 index 0000000000..13955bd5b1 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/paltex.c @@ -0,0 +1,175 @@ +/* paltex.c */ + +/* + * Paletted texture demo. + */ + +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include + +#if defined(GL_EXT_paletted_texture) && defined(_WIN32) +void (*glColorTableEXT)(GLenum target, GLenum internalFormat, + GLsizei width, GLenum format, GLenum type, const GLvoid * data); +#endif + +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 ); +} + + +/* ARGSUSED1 */ +static void Key( unsigned char key, int x, int y ) +{ + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +/* ARGSUSED1 */ +static void SpecialKey( int key, int x, int 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 ) +{ +#ifdef GL_EXT_paletted_texture + 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")) { +#endif + printf("Sorry, GL_EXT_paletted_texture not supported\n"); + exit(0); +#ifdef GL_EXT_paletted_texture + } + + /* 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; + } + +#if defined(GL_EXT_paletted_texture) && defined(_WIN32) + glColorTableEXT = (void *) wglGetProcAddress("glColorTableEXT"); + if (!glColorTableEXT) { + fprintf(stderr, "wglGetProcAddress could not get glColorTableEXT\n"); + exit(1); + } +#endif + + 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 */ + + 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( 640, 480 ); + + 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/lib/glut-3.7.6/progs/bucciarelli/paltex.dsp b/lib/glut-3.7.6/progs/bucciarelli/paltex.dsp new file mode 100644 index 0000000000..cadf48f90b --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/paltex.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="paltex" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=paltex - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "paltex.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "paltex.mak" CFG="paltex - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "paltex - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "paltex - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "paltex - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "paltex - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "paltex - Win32 Release" +# Name "paltex - Win32 Debug" +# Begin Source File + +SOURCE=.\paltex.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/ray.c b/lib/glut-3.7.6/progs/bucciarelli/ray.c new file mode 100644 index 0000000000..97a5a07044 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/ray.c @@ -0,0 +1,862 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#include + +#if defined(GL_VERSION_1_1) +/* Routines called directly. */ +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#define glTexSubImage2D(A,B,C,D,E,F,G,H,I) glTexSubImage2DEXT(A,B,C,D,E,F,G,H,I) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#define glTexSubImage2D(A,B,C,D,E,F,G,H,I) +#endif + +static int WIDTH=640; +static int HEIGHT=480; + +#define FRAME 50 + +#define BASESIZE 7.5f +#define SPHERE_RADIUS 0.75f + +#define TEX_CHECK_WIDTH 256 +#define TEX_CHECK_HEIGHT 256 +#define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16) +#define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE) + +#define TEX_REFLECT_WIDTH 256 +#define TEX_REFLECT_HEIGHT 256 +#define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16) +#define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE) + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define EPSILON 0.0001 + +#define clamp255(a) ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) ) + +#define fabs(x) ((x)<0.0f?-(x):(x)) + +#define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; } +#define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; } +#define dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) +#define vnormalize(a,b) { \ + register float m_norm; \ + m_norm=sqrt((double)dprod((a),(a))); \ + (a)[0] /=m_norm; \ + (a)[1] /=m_norm; \ + (a)[2] /=m_norm; } + +static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3]; +static GLuint checkid; +static int checkmap_currentslot=0; + +static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3]; +static GLuint reflectid; +static int reflectmap_currentslot=0; + +static GLuint lightdlist; +static GLuint objdlist; + +static float lightpos[3]={2.1,2.1,2.8}; +static float objpos[3]={0.0,0.0,1.0}; + +static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3]; + +static float fogcolor[4]={0.05,0.05,0.05,1.0}; + +static float obs[3]={7.0,0.0,2.0}; +static float dir[3]; +static float v=0.0; +static float alpha=-90.0; +static float beta=90.0; + +static int fog=1; +static int bfcull=1; +static int poutline=0; +static int help=1; +static int showcheckmap=1; +static int showreflectmap=1; +static int joyavailable=0; +static int joyactive=0; + +static float gettime(void) +{ + static float told=0.0f; + float tnew,ris; + + tnew=glutGet(GLUT_ELAPSED_TIME); + + ris=tnew-told; + + told=tnew; + + return ris/1000.0; +} + +static void calcposobs(void) +{ + dir[0]=sin(alpha*M_PI/180.0); + dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[2]=cos(beta*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; +} + +/* ARGSUSED1 */ +static void special(int k, int x, int y) +{ + switch(k) { + case GLUT_KEY_LEFT: + alpha-=2.0; + break; + case GLUT_KEY_RIGHT: + alpha+=2.0; + break; + case GLUT_KEY_DOWN: + beta-=2.0; + break; + case GLUT_KEY_UP: + beta+=2.0; + break; + } +} + +/* ARGSUSED1 */ +static void key(unsigned char k, int x, int y) +{ + switch(k) { + case 27: + exit(0); + break; + + case 's': + lightpos[1]-=0.1; + break; + case 'd': + lightpos[1]+=0.1; + break; + case 'e': + lightpos[0]-=0.1; + break; + case 'x': + lightpos[0]+=0.1; + break; + case 'w': + lightpos[2]-=0.1; + break; + case 'r': + lightpos[2]+=0.1; + break; + + case 'j': + objpos[1]-=0.1; + break; + case 'k': + objpos[1]+=0.1; + break; + case 'i': + objpos[0]-=0.1; + break; + case 'm': + objpos[0]+=0.1; + break; + case 'u': + objpos[2]-=0.1; + break; + case 'o': + objpos[2]+=0.1; + break; + + case 'a': + v+=0.005; + break; + case 'z': + v-=0.005; + break; + + case 'g': + joyactive=(!joyactive); + break; + case 'h': + help=(!help); + break; + case 'f': + fog=(!fog); + break; + + case '1': + showcheckmap=(!showcheckmap); + break; + case '2': + showreflectmap=(!showreflectmap); + break; + + case 'b': + if(bfcull) { + glDisable(GL_CULL_FACE); + bfcull=0; + } else { + glEnable(GL_CULL_FACE); + bfcull=1; + } + break; + case 'p': + if(poutline) { + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + poutline=0; + } else { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + poutline=1; + } + break; + } +} + +static void reshape(int w, int h) +{ + WIDTH=w; + HEIGHT=h; + glViewport(0,0,w,h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0,w/(float)h,0.8,40.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;i0.0)) + return GL_FALSE; + + d=sqrt(d); + + t=b-d; + + if(t10)) + return GL_FALSE; + + y=(int)((ppos[1]+BASESIZE/2)*(10.0f/BASESIZE)); + if((y<0) || (y>10)) + return GL_FALSE; + + r=255.0f; + if(y & 1) { + if(x & 1) + g=255.0f; + else + g=0.0f; + } else { + if(x & 1) + g=0.0f; + else + g=255.0f; + } + b=0.0f; + + vsub(ldir,lightpos,ppos); + vnormalize(ldir,ldir); + + if(seelight(ppos,ldir)) { + c[0]=r*0.05f; + c[1]=g*0.05f; + c[2]=b*0.05f; + + return GL_TRUE; + } + + dfact=dprod(ldir,norm); + if(dfact<0.0f) + dfact=0.0f; + + vsub(vdir,obs,ppos); + vnormalize(vdir,vdir); + h[0]=0.5f*(vdir[0]+ldir[0]); + h[1]=0.5f*(vdir[1]+ldir[1]); + h[2]=0.5f*(vdir[2]+ldir[2]); + kfact=dprod(h,norm); + kfact=kfact*kfact*kfact*kfact*kfact*kfact*kfact*7.0f*255.0f; + + r=r*dfact+kfact; + g=g*dfact+kfact; + b=b*dfact+kfact; + + c[0]=clamp255(r); + c[1]=clamp255(g); + c[2]=clamp255(b); + + return GL_TRUE; +} + +static void updatecheckmap(int slot) +{ + float c[3],ppos[3]; + int x,y; + + glBindTexture(GL_TEXTURE_2D,checkid); + + ppos[2]=0.0f; + for(y=slot*TEX_CHECK_SLOT_SIZE;y<(slot+1)*TEX_CHECK_SLOT_SIZE;y++) { + ppos[1]=(y/(float)TEX_CHECK_HEIGHT)*BASESIZE-BASESIZE/2; + + for(x=0;xEPSILON) { + rdir[0]=rf*norm[0]-vdir[0]; + rdir[1]=rf*norm[1]-vdir[1]; + rdir[2]=rf*norm[2]-vdir[2]; + + t=-objpos[2]/rdir[2]; + + if(t>EPSILON) { + planepos[0]=objpos[0]+t*rdir[0]; + planepos[1]=objpos[1]+t*rdir[1]; + planepos[2]=0.0f; + + if(!colorcheckmap(planepos,rcol)) + rcol[0]=rcol[1]=rcol[2]=0.0f; + } else + rcol[0]=rcol[1]=rcol[2]=0.0f; + } else + rcol[0]=rcol[1]=rcol[2]=0.0f; + + dfact=0.1f*dprod(ldir,norm); + + if(dfact<0.0f) { + dfact=0.0f; + kfact=0.0f; + } else { + h[0]=0.5f*(vdir[0]+ldir[0]); + h[1]=0.5f*(vdir[1]+ldir[1]); + h[2]=0.5f*(vdir[2]+ldir[2]); + kfact=dprod(h,norm); + kfact*=kfact; + kfact*=kfact; + kfact*=kfact; + kfact*=kfact; + kfact*=10.0f; + } + + r=dfact+kfact; + g=dfact+kfact; + b=dfact+kfact; + + r*=255.0f; + g*=255.0f; + b*=255.0f; + + r+=rcol[0]; + g+=rcol[1]; + b+=rcol[2]; + + r=clamp255(r); + g=clamp255(g); + b=clamp255(b); + + reflectmap[y][x][0]=(GLubyte)r; + reflectmap[y][x][1]=(GLubyte)g; + reflectmap[y][x][2]=(GLubyte)b; + } + + glTexSubImage2D(GL_TEXTURE_2D,0,0,slot*TEX_REFLECT_SLOT_SIZE,TEX_REFLECT_WIDTH, + TEX_REFLECT_SLOT_SIZE,GL_RGB,GL_UNSIGNED_BYTE, + &reflectmap[slot*TEX_REFLECT_SLOT_SIZE][0][0]); +} + +static void drawbase(void) +{ + glColor3f(0.0,0.0,0.0); + glBindTexture(GL_TEXTURE_2D,checkid); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f,0.0f); + glVertex3f(-BASESIZE/2.0f,-BASESIZE/2.0f,0.0f); + + glTexCoord2f(1.0f,0.0f); + glVertex3f(BASESIZE/2.0f,-BASESIZE/2.0f,0.0f); + + glTexCoord2f(1.0f,1.0f); + glVertex3f(BASESIZE/2.0f,BASESIZE/2.0f,0.0f); + + glTexCoord2f(0.0f,1.0f); + glVertex3f(-BASESIZE/2.0f,BASESIZE/2.0f,0.0f); + + glEnd(); +} + +static void drawobj(void) +{ + glColor3f(0.0,0.0,0.0); + glBindTexture(GL_TEXTURE_2D,reflectid); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); + + glPushMatrix(); + glTranslatef(objpos[0],objpos[1],objpos[2]); + glCallList(objdlist); + glPopMatrix(); +} + +static void dojoy(void) +{ +#ifdef _WIN32 + static UINT max[2]={0,0}; + static UINT min[2]={0xffffffff,0xffffffff},center[2]; + MMRESULT res; + JOYINFO joy; + + res=joyGetPos(JOYSTICKID1,&joy); + + if(res==JOYERR_NOERROR) { + joyavailable=1; + + if(max[0]joy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.005; + if(joy.wButtons & JOY_BUTTON2) + v-=0.005; + } + } else + joyavailable=0; +#endif +} + +static void updatemaps(void) +{ + updatecheckmap(checkmap_currentslot); + checkmap_currentslot=(checkmap_currentslot+1) % TEX_CHECK_NUMSLOT; + + updatereflectmap(reflectmap_currentslot); + reflectmap_currentslot=(reflectmap_currentslot+1) % TEX_REFLECT_NUMSLOT; +} + +static void draw(void) +{ + static int count=0; + static char frbuf[80]; + float fr; + + dojoy(); + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glPushMatrix(); + calcposobs(); + + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,0.0,1.0); + + drawbase(); + drawobj(); + + glColor3f(1.0,1.0,1.0); + glDisable(GL_TEXTURE_2D); + + glPushMatrix(); + glTranslatef(lightpos[0],lightpos[1],lightpos[2]); + glCallList(lightdlist); + glPopMatrix(); + + glPopMatrix(); + + if((count % FRAME)==0) { + fr=gettime(); + sprintf(frbuf,"Frame rate: %f",FRAME/fr); + } + + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); + glMatrixMode(GL_MODELVIEW); + + glColor3f(0.0f,0.3f,1.0f); + + if(showcheckmap) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,checkid); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f,0.0f); + glVertex2i(10,30); + glTexCoord2f(1.0f,1.0f); + glVertex2i(10+90,30); + glTexCoord2f(0.0f,1.0f); + glVertex2i(10+90,30+90); + glTexCoord2f(0.0f,0.0f); + glVertex2i(10,30+90); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINE_LOOP); + glVertex2i(10,30); + glVertex2i(10+90,30); + glVertex2i(10+90,30+90); + glVertex2i(10,30+90); + glEnd(); + glRasterPos2i(105,65); + printstring(GLUT_BITMAP_HELVETICA_18,"Plane Texture Map"); + } + + if(showreflectmap) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,reflectid); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f,0.0f); + glVertex2i(540,30); + glTexCoord2f(1.0f,1.0f); + glVertex2i(540+90,30); + glTexCoord2f(0.0f,1.0f); + glVertex2i(540+90,30+90); + glTexCoord2f(0.0f,0.0f); + glVertex2i(540,30+90); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINE_LOOP); + glVertex2i(540,30); + glVertex2i(540+90,30); + glVertex2i(540+90,30+90); + glVertex2i(540,30+90); + glEnd(); + glRasterPos2i(360,65); + printstring(GLUT_BITMAP_HELVETICA_18,"Sphere Texture Map"); + } + + glDisable(GL_TEXTURE_2D); + + glRasterPos2i(10,10); + printstring(GLUT_BITMAP_HELVETICA_18,frbuf); + glRasterPos2i(360,470); + printstring(GLUT_BITMAP_HELVETICA_10,"Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if(help) + printhelp(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + updatemaps(); + + glutSwapBuffers(); + + count++; +} + +static void inittextures(void) +{ + int y; + + glGenTextures(1,&checkid); + glBindTexture(GL_TEXTURE_2D,checkid); + + for(y=0;y +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ray - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ray.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ray.mak" CFG="ray - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ray - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ray - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ray - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ray - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "ray - Win32 Release" +# Name "ray - Win32 Debug" +# Begin Source File + +SOURCE=.\ray.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/s128.rgb b/lib/glut-3.7.6/progs/bucciarelli/s128.rgb new file mode 100644 index 0000000000000000000000000000000000000000..79f5c1d98c6b614e6dc20863fe782bcd0ddd92df GIT binary patch literal 54258 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�Y{m}I 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 + +enum { + X, Y, Z, W +}; +enum { + A, B, C, D +}; + +/* create a matrix that will project the desired shadow */ +void +shadowmatrix(GLfloat shadowMat[4][4], + GLfloat groundplane[4], + GLfloat lightpos[4]) +{ + GLfloat dot; + + /* find dot product between light position vector and ground plane normal */ + dot = groundplane[X] * lightpos[X] + + groundplane[Y] * lightpos[Y] + + groundplane[Z] * lightpos[Z] + + groundplane[W] * lightpos[W]; + + shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; + shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; + shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; + shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; + + shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; + shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; + shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; + shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; + + shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; + shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; + shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; + shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; + + shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; + shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; + shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; + shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; + +} + +/* find the plane equation given 3 points */ +void +findplane(GLfloat plane[4], + GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ + GLfloat vec0[3], vec1[3]; + + /* need 2 vectors to find cross product */ + vec0[X] = v1[X] - v0[X]; + vec0[Y] = v1[Y] - v0[Y]; + vec0[Z] = v1[Z] - v0[Z]; + + vec1[X] = v2[X] - v0[X]; + vec1[Y] = v2[Y] - v0[Y]; + vec1[Z] = v2[Z] - v0[Z]; + + /* find cross product to get A, B, and C of plane equation */ + plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; + plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); + plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + + plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} diff --git a/lib/glut-3.7.6/progs/bucciarelli/sources.c b/lib/glut-3.7.6/progs/bucciarelli/sources.c new file mode 100644 index 0000000000..0da4ae3556 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/sources.c @@ -0,0 +1,85 @@ + +#if defined(_WIN32) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +/* Object: skin_13 */ + +int striplength_skin_13[]={ +10,7,3,5,5,4,4,4,4,5,3,4,5,4,4,4,4,4,4,6, +6,3,6,3,3,3,3,0}; + +float stripdata_skin_13[]={ +0.415686,0.415686,0.415686,1.000000,0.000000,1.500000,2.000000,4.000000,0.000000,0.341176,0.341176,0.341176,1.000000,-0.500000,1.500000,4.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.435294,0.435294,0.435294,1.000000,-0.500000,1.000000,4.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.450980,0.450980,0.450980,1.000000,-0.500000,0.500000,4.000000,4.000000,4.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.388235,0.388235,0.388235,1.000000,-0.500000,0.000000,4.000000,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,0.000000,-0.500000,2.000000,4.000000,8.000000,0.333333,0.333333,0.333333,1.000000,-0.500000,-0.500000,4.000000,4.000000,8.000000, +0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.415686,0.415686,0.415686,1.000000,1.000000,1.500000,-2.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.450980,0.450980,0.450980,1.000000,0.500000,1.500000,0.000000,4.000000,0.000000,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.415686,0.415686,0.415686,1.000000,0.000000,1.500000,2.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000, +0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.341176,0.341176,0.341176,1.000000,1.500000,1.500000,-4.000000,4.000000,0.000000,0.415686,0.415686,0.415686,1.000000,1.000000,1.500000,-2.000000,4.000000,0.000000, +0.356863,0.356863,0.356863,1.000000,0.000000,-0.500000,2.000000,4.000000,8.000000,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.415686,0.415686,0.415686,1.000000,0.395020,-0.133318,0.420032,4.000000,6.533272,0.423529,0.423529,0.423529,1.000000,0.388550,-0.103582,0.445932,4.000000,6.414327, +0.423529,0.423529,0.423529,1.000000,0.388550,-0.103582,0.445932,4.000000,6.414327,0.427451,0.427451,0.427451,1.000000,0.383423,-0.069344,0.466541,4.000000,6.277375,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.435294,0.435294,0.435294,1.000000,0.380371,-0.034595,0.478689,4.000000,6.138380,0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000, +0.407843,0.407843,0.407843,1.000000,0.414673,-0.191394,0.341301,4.000000,6.765576,0.411765,0.411765,0.411765,1.000000,0.403687,-0.162957,0.385368,4.000000,6.651829,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.415686,0.415686,0.415686,1.000000,0.395020,-0.133318,0.420032,4.000000,6.533272, +0.400000,0.400000,0.400000,1.000000,0.438232,-0.232438,0.247284,4.000000,6.929754,0.403922,0.403922,0.403922,1.000000,0.425171,-0.212276,0.299425,4.000000,6.849104,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.407843,0.407843,0.407843,1.000000,0.414673,-0.191394,0.341301,4.000000,6.765576, +0.396078,0.396078,0.396078,1.000000,0.467285,-0.260554,0.130636,4.000000,7.042214,0.400000,0.400000,0.400000,1.000000,0.453857,-0.250068,0.184711,4.000000,7.000273,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.400000,0.400000,0.400000,1.000000,0.438232,-0.232438,0.247284,4.000000,6.929754, +0.396078,0.396078,0.396078,1.000000,0.500000,-0.270672,0.000000,4.000000,7.082688,0.396078,0.396078,0.396078,1.000000,0.482788,-0.267902,0.068730,4.000000,7.071609,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.396078,0.396078,0.396078,1.000000,0.467285,-0.260554,0.130636,4.000000,7.042214, +0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000,0.474510,0.474510,0.474510,1.000000,0.379272,0.180448,0.482673,4.000000,5.278208,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.513726,0.513726,0.513726,1.000000,0.379272,0.360896,0.482673,4.000000,4.556417,0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000, +0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000, +0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.552941,0.552941,0.552941,1.000000,0.379272,0.541344,0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000, +0.552941,0.552941,0.552941,1.000000,0.379272,0.541344,0.482673,4.000000,3.834625,0.556863,0.556863,0.556863,1.000000,0.459717,0.541344,0.160891,4.000000,3.834625,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.556863,0.556863,0.556863,1.000000,0.500000,0.541344,0.000000,4.000000,3.834625,0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625, +0.396078,0.396078,0.396078,1.000000,0.517212,-0.267902,-0.068730,4.000000,7.071609,0.396078,0.396078,0.396078,1.000000,0.500000,-0.270672,0.000000,4.000000,7.082688,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000, +0.400000,0.400000,0.400000,1.000000,0.546143,-0.250068,-0.184711,4.000000,7.000273,0.396078,0.396078,0.396078,1.000000,0.532715,-0.260554,-0.130636,4.000000,7.042214,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.396078,0.396078,0.396078,1.000000,0.517212,-0.267902,-0.068730,4.000000,7.071609, +0.403922,0.403922,0.403922,1.000000,0.574829,-0.212276,-0.299425,4.000000,6.849104,0.400000,0.400000,0.400000,1.000000,0.561768,-0.232438,-0.247284,4.000000,6.929754,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.400000,0.400000,0.400000,1.000000,0.546143,-0.250068,-0.184711,4.000000,7.000273, +0.411765,0.411765,0.411765,1.000000,0.596313,-0.162957,-0.385368,4.000000,6.651829,0.407843,0.407843,0.407843,1.000000,0.585327,-0.191394,-0.341301,4.000000,6.765576,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.403922,0.403922,0.403922,1.000000,0.574829,-0.212276,-0.299425,4.000000,6.849104, +0.423529,0.423529,0.423529,1.000000,0.611450,-0.103582,-0.445931,4.000000,6.414327,0.415686,0.415686,0.415686,1.000000,0.604980,-0.133318,-0.420033,4.000000,6.533272,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.411765,0.411765,0.411765,1.000000,0.596313,-0.162957,-0.385368,4.000000,6.651829, +0.435294,0.435294,0.435294,1.000000,0.619629,-0.034595,-0.478689,4.000000,6.138380,0.427451,0.427451,0.427451,1.000000,0.616577,-0.069344,-0.466541,4.000000,6.277375,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.423529,0.423529,0.423529,1.000000,0.611450,-0.103582,-0.445931,4.000000,6.414327, +0.513726,0.513726,0.513726,1.000000,0.620728,0.360896,-0.482673,4.000000,4.556417,0.474510,0.474510,0.474510,1.000000,0.620728,0.180448,-0.482673,4.000000,5.278208,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.439216,0.439216,0.439216,1.000000,0.620728,0.000000,-0.482673,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.435294,0.435294,0.435294,1.000000,0.619629,-0.034595,-0.478689,4.000000,6.138380, +0.333333,0.333333,0.333333,1.000000,1.500000,-0.500000,-4.000000,4.000000,8.000000,0.388235,0.388235,0.388235,1.000000,1.500000,0.000000,-4.000000,4.000000,6.000000,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.513726,0.513726,0.513726,1.000000,0.620728,0.360896,-0.482673,4.000000,4.556417,0.545098,0.545098,0.545098,1.000000,0.620728,0.500000,-0.482673,4.000000,4.000000, +0.333333,0.333333,0.333333,1.000000,1.500000,-0.500000,-4.000000,4.000000,8.000000,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000, +0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625,0.552941,0.552941,0.552941,1.000000,0.620728,0.541344,-0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.450980,0.450980,0.450980,1.000000,1.500000,0.500000,-4.000000,4.000000,4.000000,0.388235,0.388235,0.388235,1.000000,1.500000,0.000000,-4.000000,4.000000,6.000000, +0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.552941,0.552941,0.552941,1.000000,0.620728,0.541344,-0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,0.620728,0.500000,-0.482673,4.000000,4.000000, +0.450980,0.450980,0.450980,1.000000,1.500000,0.500000,-4.000000,4.000000,4.000000,0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000, +0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000, +0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000 + +}; + + +/* Object: skin_12 */ + +int striplength_skin_12[]={ +12,12,12,12,12,0}; + +float stripdata_skin_12[]={ +0.498039,0.498039,0.498039,1.000000,-0.099976,1.500000,-2.400000,-4.000000,-0.000002,0.337255,0.337255,0.337255,1.000000,-0.500000,1.500000,-4.000000,-4.000000,-0.000002,0.568627,0.568627,0.568627,1.000000,-0.099976,1.100000,-2.400000,-4.000000,1.599999,0.341176,0.341176,0.341176,1.000000,-0.500000,1.100000,-4.000000,-4.000000,1.599999,0.498039,0.498039,0.498039,1.000000,-0.099976,0.700000,-2.400000,-4.000000,3.200000,0.325490,0.325490,0.325490,1.000000,-0.500000,0.700000,-4.000000,-4.000000,3.199999,0.352941,0.352941,0.352941,1.000000,-0.099976,0.300000,-2.400000,-4.000000,4.800000,0.282353,0.282353,0.282353,1.000000,-0.500000,0.300000,-4.000000,-4.000000,4.800000,0.282353,0.282353,0.282353,1.000000,-0.099976,-0.100000,-2.400000,-4.000000,6.400001,0.254902,0.254902,0.254902,1.000000,-0.500000,-0.100000,-4.000000,-4.000000,6.400000,0.239216,0.239216,0.239216,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,8.000000,0.227451,0.227451,0.227451,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,8.000000, +0.239216,0.239216,0.239216,1.000000,1.099976,-0.500000,2.400001,-4.000000,8.000000,0.227451,0.227451,0.227451,1.000000,1.500000,-0.500000,4.000002,-4.000000,8.000000,0.282353,0.282353,0.282353,1.000000,1.099976,-0.100000,2.400001,-4.000000,6.400001,0.254902,0.254902,0.254902,1.000000,1.500000,-0.100000,4.000002,-4.000000,6.400001,0.352941,0.352941,0.352941,1.000000,1.099976,0.300000,2.400002,-4.000000,4.800001,0.282353,0.282353,0.282353,1.000000,1.500000,0.300000,4.000002,-4.000000,4.800001,0.498039,0.498039,0.498039,1.000000,1.099976,0.700000,2.400002,-4.000000,3.200000,0.321569,0.321569,0.321569,1.000000,1.500000,0.700000,4.000003,-4.000000,3.200000,0.568627,0.568627,0.568627,1.000000,1.099976,1.100000,2.400002,-4.000000,1.599999,0.341176,0.341176,0.341176,1.000000,1.500000,1.100000,4.000003,-4.000000,1.599999,0.494118,0.494118,0.494118,1.000000,1.099976,1.500000,2.400003,-4.000000,-0.000002,0.337255,0.337255,0.337255,1.000000,1.500000,1.500000,4.000004,-4.000000,-0.000002, +0.639216,0.639216,0.639216,1.000000,0.300049,1.500000,-0.799999,-4.000000,-0.000002,0.498039,0.498039,0.498039,1.000000,-0.099976,1.500000,-2.400000,-4.000000,-0.000002,0.858824,0.858824,0.858824,1.000000,0.300049,1.100000,-0.799999,-4.000000,1.599999,0.568627,0.568627,0.568627,1.000000,-0.099976,1.100000,-2.400000,-4.000000,1.599999,0.686275,0.686275,0.686275,1.000000,0.300049,0.700000,-0.799999,-4.000000,3.200000,0.498039,0.498039,0.498039,1.000000,-0.099976,0.700000,-2.400000,-4.000000,3.200000,0.419608,0.419608,0.419608,1.000000,0.300049,0.300000,-0.800000,-4.000000,4.800000,0.352941,0.352941,0.352941,1.000000,-0.099976,0.300000,-2.400000,-4.000000,4.800000,0.298039,0.298039,0.298039,1.000000,0.300049,-0.100000,-0.800000,-4.000000,6.400001,0.282353,0.282353,0.282353,1.000000,-0.099976,-0.100000,-2.400000,-4.000000,6.400001,0.247059,0.247059,0.247059,1.000000,0.300049,-0.500000,-0.800000,-4.000000,8.000000,0.239216,0.239216,0.239216,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,8.000000, +0.639216,0.639216,0.639216,1.000000,0.699951,1.500000,0.800002,-4.000000,-0.000002,0.639216,0.639216,0.639216,1.000000,0.300049,1.500000,-0.799999,-4.000000,-0.000002,0.858824,0.858824,0.858824,1.000000,0.699951,1.100000,0.800001,-4.000000,1.599999,0.858824,0.858824,0.858824,1.000000,0.300049,1.100000,-0.799999,-4.000000,1.599999,0.686275,0.686275,0.686275,1.000000,0.699951,0.700000,0.800001,-4.000000,3.200000,0.686275,0.686275,0.686275,1.000000,0.300049,0.700000,-0.799999,-4.000000,3.200000,0.419608,0.419608,0.419608,1.000000,0.699951,0.300000,0.800001,-4.000000,4.800001,0.419608,0.419608,0.419608,1.000000,0.300049,0.300000,-0.800000,-4.000000,4.800000,0.298039,0.298039,0.298039,1.000000,0.699951,-0.100000,0.800001,-4.000000,6.400001,0.298039,0.298039,0.298039,1.000000,0.300049,-0.100000,-0.800000,-4.000000,6.400001,0.247059,0.247059,0.247059,1.000000,0.699951,-0.500000,0.800000,-4.000000,8.000000,0.247059,0.247059,0.247059,1.000000,0.300049,-0.500000,-0.800000,-4.000000,8.000000, +0.494118,0.494118,0.494118,1.000000,1.099976,1.500000,2.400003,-4.000000,-0.000002,0.639216,0.639216,0.639216,1.000000,0.699951,1.500000,0.800002,-4.000000,-0.000002,0.568627,0.568627,0.568627,1.000000,1.099976,1.100000,2.400002,-4.000000,1.599999,0.858824,0.858824,0.858824,1.000000,0.699951,1.100000,0.800001,-4.000000,1.599999,0.498039,0.498039,0.498039,1.000000,1.099976,0.700000,2.400002,-4.000000,3.200000,0.686275,0.686275,0.686275,1.000000,0.699951,0.700000,0.800001,-4.000000,3.200000,0.352941,0.352941,0.352941,1.000000,1.099976,0.300000,2.400002,-4.000000,4.800001,0.419608,0.419608,0.419608,1.000000,0.699951,0.300000,0.800001,-4.000000,4.800001,0.282353,0.282353,0.282353,1.000000,1.099976,-0.100000,2.400001,-4.000000,6.400001,0.298039,0.298039,0.298039,1.000000,0.699951,-0.100000,0.800001,-4.000000,6.400001,0.239216,0.239216,0.239216,1.000000,1.099976,-0.500000,2.400001,-4.000000,8.000000,0.247059,0.247059,0.247059,1.000000,0.699951,-0.500000,0.800000,-4.000000,8.000000 + +}; + + +/* Object: skin_11 */ + +int striplength_skin_11[]={ +12,12,12,12,12,0}; + +float stripdata_skin_11[]={ +0.145098,0.145098,0.145098,1.000000,-0.099976,1.500000,-2.400000,4.000002,0.000000,0.141176,0.141176,0.141176,1.000000,-0.500000,1.500000,-4.000000,4.000002,0.000000,0.176471,0.176471,0.176471,1.000000,-0.099976,1.100000,-2.400000,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,-0.500000,1.100000,-4.000000,2.400001,0.000000,0.341176,0.341176,0.341176,1.000000,-0.099976,0.700000,-2.400000,0.800000,0.000000,0.188235,0.188235,0.188235,1.000000,-0.500000,0.700000,-4.000000,0.800000,0.000000,0.450980,0.450980,0.450980,1.000000,-0.099976,0.300000,-2.400000,-0.800000,0.000000,0.247059,0.247059,0.247059,1.000000,-0.500000,0.300000,-4.000000,-0.800000,0.000000,0.439216,0.439216,0.439216,1.000000,-0.099976,-0.100000,-2.400000,-2.400000,0.000000,0.270588,0.270588,0.270588,1.000000,-0.500000,-0.100000,-4.000000,-2.400000,0.000000,0.364706,0.364706,0.364706,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,0.000000,0.258824,0.258824,0.258824,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,0.000000, +0.364706,0.364706,0.364706,1.000000,1.099976,-0.500000,2.400001,-4.000000,0.000000,0.258824,0.258824,0.258824,1.000000,1.500000,-0.500000,4.000002,-4.000000,0.000000,0.439216,0.439216,0.439216,1.000000,1.099976,-0.100000,2.400001,-2.400001,0.000000,0.270588,0.270588,0.270588,1.000000,1.500000,-0.100000,4.000002,-2.400001,0.000000,0.454902,0.454902,0.454902,1.000000,1.099976,0.300000,2.400002,-0.800000,0.000000,0.247059,0.247059,0.247059,1.000000,1.500000,0.300000,4.000002,-0.800000,0.000000,0.341176,0.341176,0.341176,1.000000,1.099976,0.700000,2.400002,0.800000,0.000000,0.184314,0.184314,0.184314,1.000000,1.500000,0.700000,4.000003,0.800000,0.000000,0.176471,0.176471,0.176471,1.000000,1.099976,1.100000,2.400002,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,1.500000,1.100000,4.000003,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,1.099976,1.500000,2.400003,4.000003,0.000000,0.141176,0.141176,0.141176,1.000000,1.500000,1.500000,4.000004,4.000002,0.000000, +0.145098,0.145098,0.145098,1.000000,0.300049,1.500000,-0.799999,4.000002,0.000000,0.145098,0.145098,0.145098,1.000000,-0.099976,1.500000,-2.400000,4.000002,0.000000,0.262745,0.262745,0.262745,1.000000,0.300049,1.100000,-0.799999,2.400001,0.000000,0.176471,0.176471,0.176471,1.000000,-0.099976,1.100000,-2.400000,2.400001,0.000000,0.580392,0.580392,0.580392,1.000000,0.300049,0.700000,-0.799999,0.800000,0.000000,0.341176,0.341176,0.341176,1.000000,-0.099976,0.700000,-2.400000,0.800000,0.000000,0.709804,0.709804,0.709804,1.000000,0.300049,0.300000,-0.800000,-0.800000,0.000000,0.450980,0.450980,0.450980,1.000000,-0.099976,0.300000,-2.400000,-0.800000,0.000000,0.627451,0.627451,0.627451,1.000000,0.300049,-0.100000,-0.800000,-2.400001,0.000000,0.439216,0.439216,0.439216,1.000000,-0.099976,-0.100000,-2.400000,-2.400000,0.000000,0.458824,0.458824,0.458824,1.000000,0.300049,-0.500000,-0.800000,-4.000000,0.000000,0.364706,0.364706,0.364706,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,0.000000, +0.145098,0.145098,0.145098,1.000000,0.699951,1.500000,0.800002,4.000002,0.000000,0.145098,0.145098,0.145098,1.000000,0.300049,1.500000,-0.799999,4.000002,0.000000,0.262745,0.262745,0.262745,1.000000,0.699951,1.100000,0.800001,2.400001,0.000000,0.262745,0.262745,0.262745,1.000000,0.300049,1.100000,-0.799999,2.400001,0.000000,0.580392,0.580392,0.580392,1.000000,0.699951,0.700000,0.800001,0.800000,0.000000,0.580392,0.580392,0.580392,1.000000,0.300049,0.700000,-0.799999,0.800000,0.000000,0.713726,0.713726,0.713726,1.000000,0.699951,0.300000,0.800001,-0.800000,0.000000,0.709804,0.709804,0.709804,1.000000,0.300049,0.300000,-0.800000,-0.800000,0.000000,0.631373,0.631373,0.631373,1.000000,0.699951,-0.100000,0.800001,-2.400001,0.000000,0.627451,0.627451,0.627451,1.000000,0.300049,-0.100000,-0.800000,-2.400001,0.000000,0.458824,0.458824,0.458824,1.000000,0.699951,-0.500000,0.800000,-4.000000,0.000000,0.458824,0.458824,0.458824,1.000000,0.300049,-0.500000,-0.800000,-4.000000,0.000000, +0.145098,0.145098,0.145098,1.000000,1.099976,1.500000,2.400003,4.000003,0.000000,0.145098,0.145098,0.145098,1.000000,0.699951,1.500000,0.800002,4.000002,0.000000,0.176471,0.176471,0.176471,1.000000,1.099976,1.100000,2.400002,2.400001,0.000000,0.262745,0.262745,0.262745,1.000000,0.699951,1.100000,0.800001,2.400001,0.000000,0.341176,0.341176,0.341176,1.000000,1.099976,0.700000,2.400002,0.800000,0.000000,0.580392,0.580392,0.580392,1.000000,0.699951,0.700000,0.800001,0.800000,0.000000,0.454902,0.454902,0.454902,1.000000,1.099976,0.300000,2.400002,-0.800000,0.000000,0.713726,0.713726,0.713726,1.000000,0.699951,0.300000,0.800001,-0.800000,0.000000,0.439216,0.439216,0.439216,1.000000,1.099976,-0.100000,2.400001,-2.400001,0.000000,0.631373,0.631373,0.631373,1.000000,0.699951,-0.100000,0.800001,-2.400001,0.000000,0.364706,0.364706,0.364706,1.000000,1.099976,-0.500000,2.400001,-4.000000,0.000000,0.458824,0.458824,0.458824,1.000000,0.699951,-0.500000,0.800000,-4.000000,0.000000 + +}; + + +/* Object: skin_9 */ + +int striplength_skin_9[]={ +18,0}; + +float stripdata_skin_9[]={ +0.384314,0.384314,0.384314,1.000000,-0.500000,1.500000,-4.000000,4.000000,8.000000,0.384314,0.384314,0.384314,1.000000,1.500000,1.500000,4.000000,4.000000,8.000000,0.376471,0.376471,0.376471,1.000000,-0.500000,1.250000,-4.000000,3.695518,9.530733,0.403922,0.403922,0.403922,1.000000,1.500000,1.250000,4.000000,3.695518,9.530733,0.415686,0.415686,0.415686,1.000000,-0.500000,1.000000,-4.000000,2.828427,10.828427,0.431373,0.431373,0.431373,1.000000,1.500000,1.000000,4.000000,2.828427,10.828427,0.435294,0.435294,0.435294,1.000000,-0.500000,0.750000,-4.000000,1.530734,11.695518,0.443137,0.443137,0.443137,1.000000,1.500000,0.750000,4.000000,1.530734,11.695518,0.439216,0.439216,0.439216,1.000000,-0.500000,0.500000,-4.000000,0.000000,12.000000,0.435294,0.435294,0.435294,1.000000,1.500000,0.500000,4.000000,0.000000,12.000000,0.427451,0.427451,0.427451,1.000000,-0.500000,0.250000,-4.000000,-1.530734,11.695518,0.411765,0.411765,0.411765,1.000000,1.500000,0.250000,4.000000,-1.530734,11.695518,0.396078,0.396078,0.396078,1.000000,-0.500000,0.000000,-4.000000,-2.828427,10.828427,0.368627,0.368627,0.368627,1.000000,1.500000,0.000000,4.000000,-2.828427,10.828427,0.341176,0.341176,0.341176,1.000000,-0.500000,-0.250000,-4.000000,-3.695518,9.530733,0.301961,0.301961,0.301961,1.000000,1.500000,-0.250000,4.000000,-3.695518,9.530733,0.294118,0.294118,0.294118,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,8.000000,0.294118,0.294118,0.294118,1.000000,1.500000,-0.500000,4.000000,-4.000000,8.000000 + +}; + + diff --git a/lib/glut-3.7.6/progs/bucciarelli/teapot.c b/lib/glut-3.7.6/progs/bucciarelli/teapot.c new file mode 100644 index 0000000000..02226030ec --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/teapot.c @@ -0,0 +1,594 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#include + +#if defined(GL_VERSION_1_1) +/* Routines called directly. */ +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#endif + +#include "image.h" + +static int WIDTH=640; +static int HEIGHT=480; + +#define FRAME 50 + +#define BASESIZE 10.0 + +#define BASERES 12 +#define TEAPOTRES 3 + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +extern void teapot(GLint, GLdouble, GLenum); +extern void shadowmatrix(GLfloat [4][4], GLfloat [4], GLfloat [4]); +extern void findplane(GLfloat [4], GLfloat [3], GLfloat [3], GLfloat [3]); + +static float obs[3]={5.0,0.0,1.0}; +static float dir[3]; +static float v=0.0; +static float alpha=-90.0; +static float beta=90.0; + +static GLfloat baseshadow[4][4]; +static GLfloat lightpos[4]={2.3,0.0,3.0,1.0}; +static GLfloat lightdir[3]={-2.3,0.0,-3.0}; +static GLfloat lightalpha=0.0; + +static int fog=1; +static int bfcull=1; +static int usetex=1; +static int help=1; +static int joyavailable=0; +static int joyactive=0; + +static GLuint t1id,t2id; +static GLuint teapotdlist,basedlist,lightdlist; + +static float gettime(void) +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +static void calcposobs(void) +{ + dir[0]=sin(alpha*M_PI/180.0); + dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[2]=cos(beta*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; +} + +/* ARGSUSED1 */ +static void special(int k, int x, int y) +{ + switch(k) { + case GLUT_KEY_LEFT: + alpha-=2.0; + break; + case GLUT_KEY_RIGHT: + alpha+=2.0; + break; + case GLUT_KEY_DOWN: + beta-=2.0; + break; + case GLUT_KEY_UP: + beta+=2.0; + break; + } +} + +/* ARGSUSED1 */ +static void key(unsigned char k, int x, int y) +{ + switch(k) { + case 27: + exit(0); + break; + + case 'a': + v+=0.005; + break; + case 'z': + v-=0.005; + break; + + case 'j': + joyactive=(!joyactive); + break; + case 'h': + help=(!help); + break; + case 'f': + fog=(!fog); + break; + case 't': + usetex=(!usetex); + break; + case 'b': + if(bfcull) { + glDisable(GL_CULL_FACE); + bfcull=0; + } else { + glEnable(GL_CULL_FACE); + bfcull=1; + } + break; + } +} + +static void reshape(int w, int h) +{ + WIDTH=w; + HEIGHT=h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0,w/(float)h,0.2,40.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0,0,w,h); +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;ijoy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.005; + if(joy.wButtons & JOY_BUTTON2) + v-=0.005; + } + } else + joyavailable=0; +#endif +} + +static void draw(void) +{ + static int count=0; + static char frbuf[80]; + float fr; + + dojoy(); + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + if(usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glEnable(GL_LIGHTING); + + glShadeModel(GL_SMOOTH); + + glPushMatrix(); + calcposobs(); + + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,0.0,1.0); + + drawlight1(); + glCallList(basedlist); + drawteapot(); + drawlight2(); + glPopMatrix(); + + if((count % FRAME)==0) { + fr=gettime(); + sprintf(frbuf,"Frame rate: %f",FRAME/fr); + } + + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(10,10); + printstring(GLUT_BITMAP_HELVETICA_18,frbuf); + glRasterPos2i(350,470); + printstring(GLUT_BITMAP_HELVETICA_10,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if(help) + printhelp(); + + reshape(WIDTH,HEIGHT); + + glutSwapBuffers(); + + count++; +} + +static void inittextures(void) +{ + IMAGE *img; + GLenum gluerr; + + glGenTextures(1,&t1id); + glBindTexture(GL_TEXTURE_2D,t1id); + + if(!(img=ImageLoad("tile.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + + glGenTextures(1,&t2id); + glBindTexture(GL_TEXTURE_2D,t2id); + + if(!(img=ImageLoad("bw.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); +} + +static void initlight(void) +{ + float lamb[4]={0.2,0.2,0.2,1.0}; + float lspec[4]={1.0,1.0,1.0,1.0}; + + glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,70.0); + glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,20.0); + glLightfv(GL_LIGHT0,GL_AMBIENT,lamb); + glLightfv(GL_LIGHT0,GL_SPECULAR,lspec); + + glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,20.0); + glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,lspec); + + glEnable(GL_LIGHT0); +} + +static void initdlists(void) +{ + GLUquadricObj *lcone,*lbase; + GLfloat plane[4]; + GLfloat v0[3]={0.0,0.0,0.0}; + GLfloat v1[3]={1.0,0.0,0.0}; + GLfloat v2[3]={0.0,1.0,0.0}; + + findplane(plane,v0,v1,v2); + shadowmatrix(baseshadow,plane,lightpos); + + teapotdlist=glGenLists(1); + glNewList(teapotdlist,GL_COMPILE); + glRotatef(90.0,1.0,0.0,0.0); + glCullFace(GL_FRONT); + glBindTexture(GL_TEXTURE_2D,t2id); + teapot(TEAPOTRES,0.6,GL_FILL); + glCullFace(GL_BACK); + glEndList(); + + basedlist=glGenLists(1); + glNewList(basedlist,GL_COMPILE); + drawbase(); + glEndList(); + + lightdlist=glGenLists(1); + glNewList(lightdlist,GL_COMPILE); + glDisable(GL_LIGHTING); + + lcone=gluNewQuadric(); + lbase=gluNewQuadric(); + glRotatef(45.0,0.0,1.0,0.0); + + glColor3f(1.0,1.0,1.0); + glCullFace(GL_FRONT); + gluDisk(lbase,0.0,0.2,12.0,1.0); + glCullFace(GL_BACK); + + glColor3f(0.5,0.0,0.0); + gluCylinder(lcone,0.2,0.0,0.5,12,1); + + gluDeleteQuadric(lcone); + gluDeleteQuadric(lbase); + + glEnable(GL_LIGHTING); + glEndList(); +} + +int main(int ac, char **av) +{ + float fogcolor[4]={0.025,0.025,0.025,1.0}; + + fprintf(stderr,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + /* + if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) { + fprintf(stderr,"Error setting the process class.\n"); + return 0; + } + + if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) { + fprintf(stderr,"Error setting the process priority.\n"); + return 0; + } + */ + + glutInitWindowPosition(0,0); + glutInitWindowSize(WIDTH,HEIGHT); + glutInit(&ac,av); + + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + + glutCreateWindow("Teapot"); + + reshape(WIDTH,HEIGHT); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE,GL_EXP2); + glFogfv(GL_FOG_COLOR,fogcolor); + + glFogf(GL_FOG_DENSITY,0.04); +#ifdef FX + glHint(GL_FOG_HINT,GL_NICEST); +#endif + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + calcposobs(); + + inittextures(); + initlight(); + +#ifndef FX + glDisable(GL_TEXTURE_2D); + usetex=0; +#endif + + initdlists(); + + glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]); + + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(draw); + + glutMainLoop(); + + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/bucciarelli/teapot.dsp b/lib/glut-3.7.6/progs/bucciarelli/teapot.dsp new file mode 100644 index 0000000000..289963aa75 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/teapot.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="teapot" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=teapot - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "teapot.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "teapot.mak" CFG="teapot - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "teapot - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "teapot - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "teapot - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "teapot - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "teapot - Win32 Release" +# Name "teapot - Win32 Debug" +# Begin Source File + +SOURCE=.\dteapot.c +# End Source File +# Begin Source File + +SOURCE=.\image.c +# End Source File +# Begin Source File + +SOURCE=.\image.h +# End Source File +# Begin Source File + +SOURCE=.\shadow.c +# End Source File +# Begin Source File + +SOURCE=.\teapot.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/terrain.c b/lib/glut-3.7.6/progs/bucciarelli/terrain.c new file mode 100644 index 0000000000..6a60e03906 --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/terrain.c @@ -0,0 +1,596 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + * + * based on a Mikael SkiZoWalker's (MoDEL) / France (Skizo@Hol.Fr) demo + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#include + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +#define heightMnt 450 +#define lenghtXmnt 62 +#define lenghtYmnt 62 + +#define stepXmnt 96.0 +#define stepYmnt 96.0 + +#define WIDTH 640 +#define HEIGHT 480 + +#define TSCALE 4 + +#define FRAME 50 + +#define FOV 85 + +static GLfloat terrain[256*256]; +static GLfloat terraincolor[256*256][3]; + +static int fog=1; +static int bfcull=1; +static int usetex=1; +static int poutline=0; +static int help=1; +static int joyavailable=0; +static int joyactive=0; +static long GlobalMnt=0; + +static int scrwidth=WIDTH; +static int scrheight=HEIGHT; + +#define OBSSTARTX 992.0 +#define OBSSTARTY 103.0 + +static float obs[3]={OBSSTARTX,heightMnt*1.3,OBSSTARTY}; +static float dir[3],v1[2],v2[2]; +static float v=0.0; +static float alpha=75.0; +static float beta=90.0; + +static float gettime(void) +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +static void calcposobs(void) +{ + float alpha1,alpha2; + + dir[0]=sin(alpha*M_PI/180.0); + dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[1]=cos(beta*M_PI/180.0); + + alpha1=alpha+FOV/2.0; + v1[0]=sin(alpha1*M_PI/180.0); + v1[1]=cos(alpha1*M_PI/180.0); + + alpha2=alpha-FOV/2.0; + v2[0]=sin(alpha2*M_PI/180.0); + v2[1]=cos(alpha2*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; + + if(obs[1]<0.0) + obs[1]=0.0; +} + +static void reshape( int width, int height ) +{ + scrwidth=width; + scrheight=height; + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, ((GLfloat) width/(GLfloat)height), lenghtXmnt*stepYmnt*0.01, + lenghtXmnt*stepYmnt*0.7); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +int clipstrip(float y, float *start, float *end) +{ + float x1,x2,t1,t2,tmp; + + if(v1[1]==0.0) { + t1=0.0; + x1=-HUGE_VAL; + } else { + t1=y/v1[1]; + x1=t1*v1[0]; + } + + if(v2[1]==0.0) { + t2=0.0; + x2=HUGE_VAL; + } else { + t2=y/v2[1]; + x2=t2*v2[0]; + } + + if(((x1<-(lenghtXmnt*stepXmnt)/2) && (t2<=0.0)) || + ((t1<=0.0) && (x2>(lenghtXmnt*stepXmnt)/2)) || + ((t1<0.0) && (t2<0.0))) + return 0; + + if((t1==0.0) && (t2==0.0)) { + if((v1[0]<0.0) && (v1[1]>0.0) && (v2[0]<0.0) && (v2[1]<0.0)) { + *start=-(lenghtXmnt*stepXmnt)/2; + *end=stepXmnt; + return 1; + } else { + if((v1[0]>0.0) && (v1[1]<0.0) && (v2[0]>0.0) && (v2[1]>0.0)) { + *start=-stepXmnt; + *end=(lenghtXmnt*stepXmnt)/2; + return 1; + } else + return 0; + } + } else { + if(t2<0.0) { + if(x1<0.0) + x2=-(lenghtXmnt*stepXmnt)/2; + else + x2=(lenghtXmnt*stepXmnt)/2; + } + + if(t1<0.0) { + if(x2<0.0) + x1=-(lenghtXmnt*stepXmnt)/2; + else + x1=(lenghtXmnt*stepXmnt)/2; + } + } + + if(x1>x2) { + tmp=x1; + x1=x2; + x2=tmp; + } + + x1-=stepXmnt; + if(x1<-(lenghtXmnt*stepXmnt)/2) + x1=-(lenghtXmnt*stepXmnt)/2; + + x2+=stepXmnt; + if(x2>(lenghtXmnt*stepXmnt)/2) + x2=(lenghtXmnt*stepXmnt)/2; + + *start=((int)(x1/stepXmnt))*stepXmnt; + *end=((int)(x2/stepXmnt))*stepXmnt; + + return 1; +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;ijoy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha+=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.5; + if(joy.wButtons & JOY_BUTTON2) + v-=0.5; + } + } else + joyavailable=0; +#endif +} + +void drawscene(void) +{ + static int count=0; + static char frbuf[80]; + float fr; + + dojoy(); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + if(usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + calcposobs(); + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,1.0,0.0); + + drawterrain(); + glPopMatrix(); + + if((count % FRAME)==0) { + fr=gettime(); + sprintf(frbuf,"Frame rate: %.3f",FRAME/fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(10,10); + printstring(GLUT_BITMAP_HELVETICA_18,frbuf); + glRasterPos2i(350,470); + printstring(GLUT_BITMAP_HELVETICA_10,"Terrain V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); + glRasterPos2i(434,457); + printstring(GLUT_BITMAP_HELVETICA_10,"Based on a Mickael's demo (Skizo@Hol.Fr)"); + + if(help) + printhelp(); + + reshape(scrwidth,scrheight); + + glutSwapBuffers(); + + count++; +} + +/* ARGSUSED1 */ +static void key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + case 'a': + v+=0.5; + break; + case 'z': + v-=0.5; + break; + case 'p': + if(poutline) { + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + poutline=0; + } else { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + poutline=1; + } + break; + case 'j': + joyactive=(!joyactive); + break; + case 'h': + help=(!help); + break; + case 'f': + fog=(!fog); + break; + case 't': + usetex=(!usetex); + break; + case 'b': + if(bfcull) { + glDisable(GL_CULL_FACE); + bfcull=0; + } else { + glEnable(GL_CULL_FACE); + bfcull=1; + } + break; + } +} + +/* ARGSUSED1 */ +static void special(int k, int x, int y) +{ + switch(k) { + case GLUT_KEY_LEFT: + alpha+=2.0; + break; + case GLUT_KEY_RIGHT: + alpha-=2.0; + break; + case GLUT_KEY_DOWN: + beta-=2.0; + break; + case GLUT_KEY_UP: + beta+=2.0; + break; + } +} + +static void calccolor(GLfloat height, GLfloat c[3]) +{ + GLfloat color[4][3]={ + {1.0,1.0,1.0}, + {0.0,0.8,0.0}, + {1.0,1.0,0.3}, + {0.0,0.0,0.8} + }; + GLfloat fact; + + height=height*(1.0/255.0); + + if(height>=0.9) { + c[0]=color[0][0]; c[1]=color[0][1]; c[2]=color[0][2]; + return; + } + + if((height<0.9) && (height>=0.7)) { + fact=(height-0.7)*5.0; + c[0]=fact*color[0][0]+(1.0-fact)*color[1][0]; + c[1]=fact*color[0][1]+(1.0-fact)*color[1][1]; + c[2]=fact*color[0][2]+(1.0-fact)*color[1][2]; + return; + } + + if((height<0.7) && (height>=0.6)) { + fact=(height-0.6)*10.0; + c[0]=fact*color[1][0]+(1.0-fact)*color[2][0]; + c[1]=fact*color[1][1]+(1.0-fact)*color[2][1]; + c[2]=fact*color[1][2]+(1.0-fact)*color[2][2]; + return; + } + + if((height<0.6) && (height>=0.5)) { + fact=(height-0.5)*10.0; + c[0]=fact*color[2][0]+(1.0-fact)*color[3][0]; + c[1]=fact*color[2][1]+(1.0-fact)*color[3][1]; + c[2]=fact*color[2][2]+(1.0-fact)*color[3][2]; + return; + } + + c[0]=color[3][0]; c[1]=color[3][1]; c[2]=color[3][2]; +} + +static void loadpic (void) +{ + GLubyte bufferter[256*256],terrainpic[256*256]; + FILE *FilePic; + int i,tmp; + GLenum gluerr; + + if((FilePic=fopen("mnt.bin","r"))==NULL) { + fprintf(stderr,"Error loading Mnt.bin\n"); + exit(-1); + } + fread(bufferter , 256*256 , 1 , FilePic); + fclose(FilePic); + + for (i=0;i<(256*256);i++) { + terrain[i]=(bufferter[i]*(heightMnt/255.0f)); + calccolor((GLfloat)bufferter[i],terraincolor[i]); + tmp=(((int)bufferter[i])+96); + terrainpic[i]=(tmp>255) ? 255 : tmp; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 1, 256, 256, GL_LUMINANCE, + GL_UNSIGNED_BYTE, (GLvoid *)(&terrainpic[0])))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + glEnable(GL_TEXTURE_2D); +} + +static void init( void ) +{ + float fogcolor[4]={0.6,0.7,0.7,1.0}; + + glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE,GL_EXP2); + glFogfv(GL_FOG_COLOR,fogcolor); + glFogf(GL_FOG_DENSITY,0.0007); +#ifdef FX + glHint(GL_FOG_HINT,GL_NICEST); +#endif + + reshape(scrwidth,scrheight); +} + + +int main(int ac, char **av) +{ + glutInitWindowPosition(0,0); + glutInitWindowSize(WIDTH,HEIGHT); + glutInit(&ac,av); + + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + + glutCreateWindow("Terrain"); + + loadpic(); + + init(); + +#ifndef FX + glDisable(GL_TEXTURE_2D); + usetex=0; +#endif + + glutReshapeFunc(reshape); + glutDisplayFunc(drawscene); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(drawscene); + + glutMainLoop(); + + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/bucciarelli/terrain.dsp b/lib/glut-3.7.6/progs/bucciarelli/terrain.dsp new file mode 100644 index 0000000000..a4ef5e121d --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/terrain.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="terrain" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=terrain - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "terrain.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "terrain.mak" CFG="terrain - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "terrain - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "terrain - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "terrain - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "terrain - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "terrain - Win32 Release" +# Name "terrain - Win32 Debug" +# Begin Source File + +SOURCE=.\terrain.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/bucciarelli/tile.rgb b/lib/glut-3.7.6/progs/bucciarelli/tile.rgb new file mode 100644 index 0000000000000000000000000000000000000000..8daf5acd11e0d08befd268a9f654b51cc33110e4 GIT binary patch literal 53807 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/bucciarelli/tree2.rgb b/lib/glut-3.7.6/progs/bucciarelli/tree2.rgb new file mode 100644 index 0000000000000000000000000000000000000000..ce2c44dd6637f2659b8e7f54a36c99c95deda504 GIT binary patch literal 24816 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 QH`xBS9O`+0$MQb|0DxKGv;Y7A literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/bucciarelli/tunnel.c b/lib/glut-3.7.6/progs/bucciarelli/tunnel.c new file mode 100644 index 0000000000..3b7c3bcaee --- /dev/null +++ b/lib/glut-3.7.6/progs/bucciarelli/tunnel.c @@ -0,0 +1,534 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#include + +#if defined(GL_VERSION_1_1) +/* Routines called directly. */ +#elif defined(GL_EXT_texture_object) && defined(GL_EXT_copy_texture) && defined(GL_EXT_subtexture) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#define glDeleteTextures(A,B) +#endif + +#include "image.h" + +static int WIDTH=640; +static int HEIGHT=480; + +#define FRAME 50 + +#define NUMBLOC 5 + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +extern int striplength_skin_13[]; +extern float stripdata_skin_13[]; + +extern int striplength_skin_12[]; +extern float stripdata_skin_12[]; + +extern int striplength_skin_11[]; +extern float stripdata_skin_11[]; + +extern int striplength_skin_9[]; +extern float stripdata_skin_9[]; + +static float obs[3]={1000.0,0.0,2.0}; +static float dir[3]; +static float v=0.0; +static float alpha=90.0; +static float beta=90.0; + +static int fog=1; +static int bfcull=1; +static int usetex=1; +static int cstrip=0; +static int help=1; +static int joyavailable=0; +static int joyactive=0; + +static GLuint t1id,t2id; + +static void inittextures(void) +{ + IMAGE *img; + GLenum gluerr; + + glGenTextures(1,&t1id); + glBindTexture(GL_TEXTURE_2D,t1id); + + if(!(img=ImageLoad("tile.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + + glGenTextures(1,&t2id); + glBindTexture(GL_TEXTURE_2D,t2id); + + if(!(img=ImageLoad("bw.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + 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_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); +} + +static void drawobjs(int *l, float *f) +{ + int mend,j; + + if(cstrip) { + float r=0.33,g=0.33,b=0.33; + + for(;(*l)!=0;) { + mend=*l++; + + r+=0.33; + if(r>1.0) { + r=0.33; + g+=0.33; + if(g>1.0) { + g=0.33; + b+=0.33; + if(b>1.0) + b=0.33; + } + } + + glColor3f(r,g,b); + glBegin(GL_TRIANGLE_STRIP); + for(j=0;jjoy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha-=2.0*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.0*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.01; + if(joy.wButtons & JOY_BUTTON2) + v-=0.01; + } + } else + joyavailable=0; +#endif +} + +static void draw(void) +{ + static int count=0; + static char frbuf[80]; + int i; + float fr,base,offset; + + dojoy(); + + glEnable(GL_DEPTH_TEST); + + /* + if(count & 1) { + glDepthRange(1.0,0.5); + glDepthFunc(GL_GREATER); + } else { + glDepthRange(0.0,0.5); + glDepthFunc(GL_LESS); + } + */ + + /*glClear(GL_COLOR_BUFFER_BIT);*/ + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + if(usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glShadeModel(GL_SMOOTH); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,0.0,1.0); + + if(dir[0]>0) { + offset=8.0; + base=obs[0]-fmod(obs[0],8.0); + } else { + offset=-8.0; + base=obs[0]+(8.0-fmod(obs[0],8.0)); + } + + glPushMatrix(); + glTranslatef(base-offset/2.0,0.0,0.0); + for(i=0;i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tunnel - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tunnel.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tunnel.mak" CFG="tunnel - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tunnel - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tunnel - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tunnel - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "tunnel - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "tunnel - Win32 Release" +# Name "tunnel - Win32 Debug" +# Begin Source File + +SOURCE=.\image.c +# End Source File +# Begin Source File + +SOURCE=.\image.h +# End Source File +# Begin Source File + +SOURCE=.\sources.c +# End Source File +# Begin Source File + +SOURCE=.\tunnel.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib.dsw b/lib/glut-3.7.6/progs/contrib.dsw new file mode 100644 index 0000000000..84397c3b79 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib.dsw @@ -0,0 +1,209 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "_all"=".\contrib\_all.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name agv_viewer + End Project Dependency + Begin Project Dependency + Project_Dep_Name fractals + End Project Dependency + Begin Project Dependency + Project_Dep_Name gears + End Project Dependency + Begin Project Dependency + Project_Dep_Name hanoi + End Project Dependency + Begin Project Dependency + Project_Dep_Name hanoi2 + End Project Dependency + Begin Project Dependency + Project_Dep_Name lineblend + End Project Dependency + Begin Project Dependency + Project_Dep_Name moth + End Project Dependency + Begin Project Dependency + Project_Dep_Name noof + End Project Dependency + Begin Project Dependency + Project_Dep_Name rings + End Project Dependency + Begin Project Dependency + Project_Dep_Name steam + End Project Dependency + Begin Project Dependency + Project_Dep_Name text3d + End Project Dependency + Begin Project Dependency + Project_Dep_Name worms + End Project Dependency +}}} + +############################################################################### + +Project: "agv_viewer"=".\contrib\agv_viewer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "fractals"=".\contrib\fractals.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gears"=".\contrib\gears.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "hanoi"=".\contrib\hanoi.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "hanoi2"=".\contrib\hanoi2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lineblend"=".\contrib\lineblend.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "moth"=".\contrib\moth.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "noof"=".\contrib\noof.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rings"=".\contrib\rings.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "steam"=".\contrib\steam.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "text3d"=".\contrib\text3d.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "worms"=".\contrib\worms.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/progs/contrib/Imakefile b/lib/glut-3.7.6/progs/contrib/Imakefile new file mode 100644 index 0000000000..ae7641c2ca --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/Imakefile @@ -0,0 +1,26 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../Glut.cf" + +TARGETS = lineblend worms rings agv_example fractals moth text3d \ + noof gears hanoi steam + +SRCS = lineblend.c rings.c worms.c agv_example.c agviewer.c fractals.c \ + fracviewer.c hanoi.c moth.c gears.c noof.c text3d.c hanoi.c steam.c + +AllTarget($(TARGETS)) + +SimpleGlutProgramTarget(gears) +SimpleGlutProgramTarget(hanoi) +SimpleGlutProgramTarget(lineblend) +SimpleGlutProgramTarget(moth) +SimpleGlutProgramTarget(noof) +SimpleGlutProgramTarget(rings) +SimpleGlutProgramTarget(steam) +SimpleGlutProgramTarget(text3d) +SimpleGlutProgramTarget(worms) +NormalGlutProgramTarget(agv_example,agv_example.o agviewer.o) +NormalGlutProgramTarget(fractals,fractals.o fracviewer.o) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/contrib/_all.dsp b/lib/glut-3.7.6/progs/contrib/_all.dsp new file mode 100644 index 0000000000..6a4421548c --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "_all___Win32_Debug" +# PROP BASE Intermediate_Dir "_all___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/agv_example.c b/lib/glut-3.7.6/progs/contrib/agv_example.c new file mode 100644 index 0000000000..9826ccc498 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/agv_example.c @@ -0,0 +1,215 @@ +/* + * agv_example.c (version 1.0) + * + * Example program to show how to use AGV + * + * See agviewer.h, agviewer.c and comments within for more info + * + * Philip Winston - 4/11/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + */ + +#include + +#include +#include +#include + +#include "agviewer.h" + +typedef enum {NOTALLOWED, AXES, STUFF, RING } DisplayLists; + +int DrawAxes = 0; + +#define ROTATEINC 2; + +GLfloat Rotation = 0; /* start ring flat and not spinning */ +int Rotating = 0; + + +void myGLInit(void) +{ + GLfloat mat_ambuse[] = { 0.6, 0.0, 0.0, 1.0 }; + GLfloat mat_specular[] = { 0.4, 0.4, 0.4, 1.0 }; + + GLfloat light0_position[] = { 0.6, 0.4, 0.3, 0.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, light0_position); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_ambuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialf(GL_FRONT, GL_SHININESS, 25.0); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_NORMALIZE); + + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + + glShadeModel(GL_SMOOTH); + + glFlush(); +} + + +void MakeDisplayLists(void) +{ + glNewList(STUFF, GL_COMPILE); + glPushMatrix(); + glutSolidCube(1.0); + glTranslatef(2, 0, 0); + glutSolidSphere(0.5, 10, 10); + glTranslatef(-2, 0, 3); + glRotatef(-90, 1, 0, 0); + glutSolidCone(0.5, 1.0, 8, 8); + glPopMatrix(); + glEndList(); + + glNewList(RING, GL_COMPILE); + glutSolidTorus(0.1, 0.5, 8, 15); + glEndList(); +} + + +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(60, 1, 0.01, 100); + + /* so this replaces gluLookAt or equiv */ + agvViewTransform(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* we call agvMakeAxesList() to make this display list */ + if (DrawAxes) + glCallList(AXES); + + glCallList(STUFF); + + glTranslatef(-2, 1, -2); + glRotatef(Rotation, 1, 0, 0); + glCallList(RING); + + glutSwapBuffers(); + glFlush(); +} + + + /* rotate the axis and adjust position if nec. */ +void rotatethering(void) +{ + Rotation += ROTATEINC; + + if (agvMoving) /* we since we are the only idle function, we must */ + agvMove(); /* give AGV the chance to update the eye position */ + + glutPostRedisplay(); +} + +typedef enum { MENU_AXES, MENU_QUIT, MENU_RING } MenuChoices; + +void handlemenu(int value) +{ + switch (value) { + case MENU_AXES: + DrawAxes = !DrawAxes; + break; + case MENU_QUIT: + exit(0); + break; + case MENU_RING: + Rotating = !Rotating; + if (Rotating) { + glutIdleFunc(rotatethering); /* install our idle function */ + agvSetAllowIdle(0); /* and tell AGV to not */ + } else { + glutIdleFunc(NULL); /* uninstall our idle function */ + agvSetAllowIdle(1); /* and tell AGV it can mess with it */ + } + break; + } + glutPostRedisplay(); +} + +void visible(int v) +{ + if (v == GLUT_VISIBLE) { + if (Rotating) { + glutIdleFunc(rotatethering); + agvSetAllowIdle(0); + } else { + glutIdleFunc(NULL); + agvSetAllowIdle(1); + } + } else { + glutIdleFunc(NULL); + agvSetAllowIdle(0); + } +} + + +void MenuInit(void) +{ + int sub2 = glutCreateMenu(agvSwitchMoveMode); /* pass these right to */ + glutAddMenuEntry("Flying move", FLYING); /* agvSwitchMoveMode() */ + glutAddMenuEntry("Polar move", POLAR); + + glutCreateMenu(handlemenu); + glutAddSubMenu("Movement", sub2); + glutAddMenuEntry("Toggle Axes", MENU_AXES); + glutAddMenuEntry("Toggle ring rotation", MENU_RING); + glutAddMenuEntry("Quit", MENU_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); + glutCreateWindow("AGV example"); + + glutVisibilityFunc(visible); + + if (Rotating) + glutIdleFunc(rotatethering); + + /* + * let AGV know if it can mess with the idle function (if we've + * just installed an idle function, we tell AGV it can't touch it) + */ + + agvInit(!Rotating); + + /* + * agvInit() installs mouse, motion, and keyboard handles, but + * we don't care for this example cause we only use right button menu + */ + + agvMakeAxesList(AXES); /* create AGV axes */ + + myGLInit(); + MakeDisplayLists(); + MenuInit(); + + glutDisplayFunc(display); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + + diff --git a/lib/glut-3.7.6/progs/contrib/agv_viewer.dsp b/lib/glut-3.7.6/progs/contrib/agv_viewer.dsp new file mode 100644 index 0000000000..49913b1147 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/agv_viewer.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="agv_viewer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=agv_viewer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "agv_viewer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "agv_viewer.mak" CFG="agv_viewer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "agv_viewer - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "agv_viewer - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "agv_viewer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "agv_viewer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "agv_viewer___Win32_Debug" +# PROP BASE Intermediate_Dir "agv_viewer___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "agv_viewer - Win32 Release" +# Name "agv_viewer - Win32 Debug" +# Begin Source File + +SOURCE=.\agv_example.c +# End Source File +# Begin Source File + +SOURCE=.\agviewer.c +# End Source File +# Begin Source File + +SOURCE=.\agviewer.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/agviewer.c b/lib/glut-3.7.6/progs/contrib/agviewer.c new file mode 100644 index 0000000000..addba578a8 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/agviewer.c @@ -0,0 +1,497 @@ +/* + * agviewer.c (version 1.0) + * + * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut + * + * See agv_example.c and agviewer.h comments within for more info. + * + * I welcome any feedback or improved versions! + * + * Philip Winston - 4/11/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + */ + +#include +#include +#include +#include + +#include "agviewer.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/***************************************************************/ +/************************** SETTINGS ***************************/ +/***************************************************************/ + + /* Initial polar movement settings */ +#define INIT_POLAR_AZ 0.0 +#define INIT_POLAR_EL 30.0 +#define INIT_DIST 8.0 +#define INIT_AZ_SPIN 0.5 +#define INIT_EL_SPIN 0.0 + + /* Initial flying movement settings */ +#define INIT_EX 0.0 +#define INIT_EY -2.0 +#define INIT_EZ -2.0 +#define INIT_MOVE 0.01 +#define MINMOVE 0.001 + + /* Start in this mode */ +#define INIT_MODE POLAR + + /* Controls: */ + + /* map 0-9 to an EyeMove value when number key is hit in FLYING mode */ +#define SPEEDFUNCTION(x) ((x)*(x)*0.001) + + /* Multiply EyeMove by (1+-MOVEFRACTION) when +/- hit in FLYING mode */ +#define MOVEFRACTION 0.25 + + /* What to multiply number of pixels mouse moved by to get rotation amount */ +#define EL_SENS 0.5 +#define AZ_SENS 0.5 + + /* What to multiply number of pixels mouse moved by for movement amounts */ +#define DIST_SENS 0.01 +#define E_SENS 0.01 + + /* Minimum spin to allow in polar (lower forced to zero) */ +#define MIN_AZSPIN 0.1 +#define MIN_ELSPIN 0.1 + + /* Factors used in computing dAz and dEl (which determine AzSpin, ElSpin) */ +#define SLOW_DAZ 0.90 +#define SLOW_DEL 0.90 +#define PREV_DAZ 0.80 +#define PREV_DEL 0.80 +#define CUR_DAZ 0.20 +#define CUR_DEL 0.20 + +/***************************************************************/ +/************************** GLOBALS ****************************/ +/***************************************************************/ + +int MoveMode = INIT_MODE; /* FLYING or POLAR mode? */ + +GLfloat Ex = INIT_EX, /* flying parameters */ + Ey = INIT_EY, + Ez = INIT_EZ, + EyeMove = INIT_MOVE, + + EyeDist = INIT_DIST, /* polar params */ + AzSpin = INIT_AZ_SPIN, + ElSpin = INIT_EL_SPIN, + + EyeAz = INIT_POLAR_AZ, /* used by both */ + EyeEl = INIT_POLAR_EL; + +int agvMoving; /* Currently moving? */ + +int downx, downy, /* for tracking mouse position */ + lastx, lasty, + downb = -1; /* and button status */ + +GLfloat downDist, downEl, downAz, /* for saving state of things */ + downEx, downEy, downEz, /* when button is pressed */ + downEyeMove; + +GLfloat dAz, dEl, lastAz, lastEl; /* to calculate spinning w/ polar motion */ +int AdjustingAzEl = 0; + +int AllowIdle, RedisplayWindow; + /* If AllowIdle is 1 it means AGV will install its own idle which + * will update the viewpoint as needed and send glutPostRedisplay() to the + * window RedisplayWindow which was set in agvInit(). AllowIdle of 0 + * means AGV won't install an idle funciton, and something like + * "if (agvMoving) agvMove()" should exist at the end of the running + * idle function. + */ + +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define TORAD(x) ((M_PI/180.0)*(x)) +#define TODEG(x) ((180.0/M_PI)*(x)) + +/***************************************************************/ +/************************ PROTOTYPES ***************************/ +/***************************************************************/ + + /* + * these are functions meant for internal use only + * the other prototypes are in agviewer.h + */ + +void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth); +void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el); +int ConstrainEl(void); +void MoveOn(int v); +void SetMove(float newmove); +static void normalize(GLfloat v[3]); +static void ncrossprod(float v1[3], float v2[3], float cp[3]); + + +/***************************************************************/ +/************************ agvInit ******************************/ +/***************************************************************/ + +void agvInit(int window) +{ + glutMouseFunc(agvHandleButton); + glutMotionFunc(agvHandleMotion); + glutKeyboardFunc(agvHandleKeys); + RedisplayWindow = glutGetWindow(); + agvSetAllowIdle(window); +} + +/***************************************************************/ +/************************ VIEWPOINT STUFF **********************/ +/***************************************************************/ + + /* + * viewing transformation modified from page 90 of red book + */ +void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth) +{ + glTranslatef(0, 0, -dist); + glRotatef(elevation, 1, 0, 0); + glRotatef(azimuth, 0, 1, 0); + +} + + /* + * I took the idea of tracking eye position in absolute + * coords and direction looking in Polar form from denis + */ +void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el) +{ + float lookat[3], perp[3], up[3]; + + lookat[0] = sin(TORAD(az))*cos(TORAD(el)); + lookat[1] = sin(TORAD(el)); + lookat[2] = -cos(TORAD(az))*cos(TORAD(el)); + normalize(lookat); + perp[0] = lookat[2]; + perp[1] = 0; + perp[2] = -lookat[0]; + normalize(perp); + ncrossprod(lookat, perp, up); + gluLookAt(x, y, z, + x+lookat[0], y+lookat[1], z+lookat[2], + up[0], up[1], up[2]); +} + + /* + * Call viewing transformation based on movement mode + */ +void agvViewTransform(void) +{ + switch (MoveMode) { + case FLYING: + FlyLookFrom(Ex, Ey, Ez, EyeAz, EyeEl); + break; + case POLAR: + PolarLookFrom(EyeDist, EyeEl, EyeAz); + break; + } +} + + /* + * keep them vertical; I think this makes a lot of things easier, + * but maybe it wouldn't be too hard to adapt things to let you go + * upside down + */ +int ConstrainEl(void) +{ + if (EyeEl <= -90) { + EyeEl = -89.99; + return 1; + } else if (EyeEl >= 90) { + EyeEl = 89.99; + return 1; + } + return 0; +} + + /* + * Idle Function - moves eyeposition + */ +void agvMove(void) +{ + + switch (MoveMode) { + case FLYING: + Ex += EyeMove*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey += EyeMove*sin(TORAD(EyeEl)); + Ez -= EyeMove*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); + break; + + case POLAR: + EyeEl += ElSpin; + EyeAz += AzSpin; + if (ConstrainEl()) { /* weird spin thing to make things look */ + ElSpin = -ElSpin; /* look better when you are kept from going */ + /* upside down while spinning - Isn't great */ + if (fabs(ElSpin) > fabs(AzSpin)) + AzSpin = fabs(ElSpin) * ((AzSpin > 0) ? 1 : -1); + } + break; + } + + if (AdjustingAzEl) { + dAz *= SLOW_DAZ; + dEl *= SLOW_DEL; + } + + if (AllowIdle) { + glutSetWindow(RedisplayWindow); + glutPostRedisplay(); + } +} + + + /* + * Don't install agvMove as idle unless we will be updating the view + * and we've been given a RedisplayWindow + */ +void MoveOn(int v) +{ + if (v && ((MoveMode == FLYING && EyeMove != 0) || + (MoveMode == POLAR && + (AzSpin != 0 || ElSpin != 0 || AdjustingAzEl)))) { + agvMoving = 1; + if (AllowIdle) + glutIdleFunc(agvMove); + } else { + agvMoving = 0; + if (AllowIdle) + glutIdleFunc(NULL); + } +} + + /* + * set new redisplay window. If <= 0 it means we are not to install + * an idle function and will rely on whoever does install one to + * put statement like "if (agvMoving) agvMove();" at end of it + */ +void agvSetAllowIdle(int allowidle) +{ + if ((AllowIdle = allowidle)) + MoveOn(1); +} + + + /* + * when moving to flying we stay in the same spot, moving to polar we + * reset since we have to be looking at the origin (though a pivot from + * current position to look at origin might be cooler) + */ +void agvSwitchMoveMode(int move) +{ + switch (move) { + case FLYING: + if (MoveMode == FLYING) return; + Ex = -EyeDist*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey = EyeDist*sin(TORAD(EyeEl)); + Ez = EyeDist*(cos(TORAD(EyeAz))*cos(TORAD(EyeEl))); + EyeAz = EyeAz; + EyeEl = -EyeEl; + EyeMove = INIT_MOVE; + break; + case POLAR: + EyeDist = INIT_DIST; + EyeAz = INIT_POLAR_AZ; + EyeEl = INIT_POLAR_EL; + AzSpin = INIT_AZ_SPIN; + ElSpin = INIT_EL_SPIN; + break; + } + MoveMode = move; + MoveOn(1); + glutPostRedisplay(); +} + +/***************************************************************/ +/******************* MOUSE HANDLING ***********************/ +/***************************************************************/ + +void agvHandleButton(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN && downb == -1) { + lastx = downx = x; + lasty = downy = y; + downb = button; + + switch (button) { + case GLUT_LEFT_BUTTON: + lastEl = downEl = EyeEl; + lastAz = downAz = EyeAz; + AzSpin = ElSpin = dAz = dEl = 0; + AdjustingAzEl = 1; + MoveOn(1); + break; + + case GLUT_MIDDLE_BUTTON: + downDist = EyeDist; + downEx = Ex; + downEy = Ey; + downEz = Ez; + downEyeMove = EyeMove; + EyeMove = 0; + } + + } else if (state == GLUT_UP && button == downb) { + + downb = -1; + + switch (button) { + case GLUT_LEFT_BUTTON: + if (MoveMode != FLYING) { + AzSpin = -dAz; + if (AzSpin < MIN_AZSPIN && AzSpin > -MIN_AZSPIN) + AzSpin = 0; + ElSpin = -dEl; + if (ElSpin < MIN_ELSPIN && ElSpin > -MIN_ELSPIN) + ElSpin = 0; + } + AdjustingAzEl = 0; + MoveOn(1); + break; + + case GLUT_MIDDLE_BUTTON: + EyeMove = downEyeMove; + } + } +} + + /* + * change EyeEl and EyeAz and position when mouse is moved w/ button down + */ +void agvHandleMotion(int x, int y) +{ + int deltax = x - downx, deltay = y - downy; + + switch (downb) { + case GLUT_LEFT_BUTTON: + EyeEl = downEl + EL_SENS * ((MoveMode == FLYING) ? -deltay : deltay); + ConstrainEl(); + EyeAz = downAz + AZ_SENS * deltax; + dAz = PREV_DAZ*dAz + CUR_DAZ*(lastAz - EyeAz); + dEl = PREV_DEL*dEl + CUR_DEL*(lastEl - EyeEl); + lastAz = EyeAz; + lastEl = EyeEl; + break; + case GLUT_MIDDLE_BUTTON: + EyeDist = downDist + DIST_SENS*deltay; + Ex = downEx - E_SENS*deltay*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey = downEy - E_SENS*deltay*sin(TORAD(EyeEl)); + Ez = downEz + E_SENS*deltay*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); + break; + } + glutPostRedisplay(); +} + +/***************************************************************/ +/********************* KEYBOARD HANDLING ***********************/ +/***************************************************************/ + + /* + * set EyeMove (current speed) for FLYING mode + */ +void SetMove(float newmove) +{ + if (newmove > MINMOVE) { + EyeMove = newmove; + MoveOn(1); + } else { + EyeMove = 0; + MoveOn(0); + } +} + + /* + * 0->9 set speed, +/- adjust current speed -- in FLYING mode + */ +/* ARGSUSED1 */ +void agvHandleKeys(unsigned char key, int x, int y) +{ + if (MoveMode != FLYING) + return; + + if (key >= '0' && key <= '9') + SetMove(SPEEDFUNCTION((key-'0'))); + else + switch(key) { + case '+': + if (EyeMove == 0) + SetMove(MINMOVE); + else + SetMove(EyeMove *= (1 + MOVEFRACTION)); + break; + case '-': + SetMove(EyeMove *= (1 - MOVEFRACTION)); + break; + } +} + +/***************************************************************/ +/*********************** VECTOR STUFF **************************/ +/***************************************************************/ + + /* normalizes v */ +static void normalize(GLfloat v[3]) +{ + GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + + if (d == 0) + fprintf(stderr, "Zero length vector in normalize\n"); + else + v[0] /= d; v[1] /= d; v[2] /= d; +} + + /* calculates a normalized crossproduct to v1, v2 */ +static void ncrossprod(float v1[3], float v2[3], float cp[3]) +{ + cp[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cp[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cp[2] = v1[0]*v2[1] - v1[1]*v2[0]; + normalize(cp); +} + +/***************************************************************/ +/**************************** AXES *****************************/ +/***************************************************************/ + + + /* draw axes -- was helpful to debug/design things */ +void agvMakeAxesList(int displaylistnum) +{ + int i,j; + GLfloat axes_ambuse[] = { 0.5, 0.0, 0.0, 1.0 }; + glNewList(displaylistnum, GL_COMPILE); + glPushAttrib(GL_LIGHTING_BIT); + glMatrixMode(GL_MODELVIEW); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, axes_ambuse); + glBegin(GL_LINES); + glVertex3f(15, 0, 0); glVertex3f(-15, 0, 0); + glVertex3f(0, 15, 0); glVertex3f(0, -15, 0); + glVertex3f(0, 0, 15); glVertex3f(0, 0, -15); + glEnd(); + for (i = 0; i < 3; i++) { + glPushMatrix(); + glTranslatef(-10*(i==0), -10*(i==1), -10*(i==2)); + for (j = 0; j < 21; j++) { + glutSolidCube(0.1); + glTranslatef(i==0, i==1, i==2); + } + glPopMatrix(); + } + glPopAttrib(); + glEndList(); +} + + diff --git a/lib/glut-3.7.6/progs/contrib/agviewer.h b/lib/glut-3.7.6/progs/contrib/agviewer.h new file mode 100644 index 0000000000..a404bfb1b9 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/agviewer.h @@ -0,0 +1,104 @@ +/* + * agviewer.h (version 1.0) + * + * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut + * + * The two view movement modes are POLAR and FLYING. Both move the eye, NOT + * THE OBJECT. You can never be upside down or twisted (roll) in either mode. + * + * A nice addition would be an examiner type trackball mode where you are + * moving the object and so could see it from any angle. Also less restricted + * flying and polar modes (fly upside down, do rolls, etc.). + * + * Controls for Polar are just left and middle buttons -- for flying it's + * those plus 0-9 number keys and +/- for speed adjustment. + * + * See agv_example.c and agviewer.c for more info. Probably want to make + * a copy of these and then edit for each program. This isn't meant to be + * a library, just something to graft onto your own programs. + * + * I welcome any feedback or improved versions. + * + * Philip Winston - 4/11/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + */ + + + /* + * Call agvInit() with glut's current window set to the window in + * which you want to run the viewer. Right after creating it is fine. It + * will remember that window for possible later use (see below) and + * registers mouse, motion, and keyboard handlers for that window (see below). + * + * allowidle is 1 or 0 depnding on whether you will let AGV install + * and uninstall an idle function. 0 means you will not let it (because + * you will be having your own idle function). In this case it is your + * responsibility to put a statement like: + * + * if (agvMoving) + * agvMove(); + * + * at the end of your idle function, to let AGV update the viewpoint if it + * is moving. + * + * If allowidle is 1 it means AGV will install its own idle which + * will update the viewpoint as needed and send glutPostRedisplay() to the + * window which was current when agvInit() was called. + * + * agvSetIdleAllow changes this value so you can let AGV install its idle + * when your idle isn't installed. + * + */ +void agvInit(int allowidle); +void agvSetAllowIdle(int allowidle); + + + /* + * Set which movement mode you are in. + */ +typedef enum { FLYING, POLAR } MovementType; +void agvSwitchMoveMode(int move); + + /* + * agvViewTransform basically does the appropriate gluLookAt() for the + * current position. So call it in your display on the projection matrix + */ +void agvViewTransform(void); + + /* + * agvMoving will be set by AGV according to whether it needs you to call + * agvMove() at the end of your idle function. You only need these if + * you aren't allowing AGV to do its own idle. + * (Don't change the value of agvMoving) + */ +extern int agvMoving; +void agvMove(void); + + /* + * These are the routines AGV registers to deal with mouse and keyboard input. + * Keyboard input only matters in flying mode, and then only to set speed. + * Mouse input only uses left two buttons in both modes. + * These are all registered with agvInit(), but you could register + * something else which called these, or reregister these as needed + */ +void agvHandleButton(int button, int state, int x, int y); +void agvHandleMotion(int x, int y); +void agvHandleKeys(unsigned char key, int x, int y); + + /* + * Just an extra routine which makes an x-y-z axes (about 10x10x10) + * which is nice for aligning things and debugging. Pass it an available + * displaylist number. + */ +void agvMakeAxesList(int displaylist); + + + + + + + + + + diff --git a/lib/glut-3.7.6/progs/contrib/engine.c b/lib/glut-3.7.6/progs/contrib/engine.c new file mode 100644 index 0000000000..999bf135c7 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/engine.c @@ -0,0 +1,75 @@ + +/* hanoi solver for hanoi2 */ + +#include +#include +#include +#include + +static int num_disks[3] = +{0, 0, 0}; + +static void +move_disk(int from, int to, int fd) +{ + char buf[3]; + + assert(from != to); + num_disks[from]--; + num_disks[to]++; +#ifdef TEST_ENGINE + printf("%d --> %d\n", from, to); +#else + buf[0] = 'M'; + buf[1] = (char) from; + buf[2] = (char) to; + if (3 != write(fd, buf, 3)) { + perror("can't write"); + exit(1); + } +#endif +} + +static void +move_disks(int from, int to, int n, int fd) +{ + static int other_table[9] = + {-1, 2, 1, 2, -1, 0, 1, 0, -1}; + int other; + + assert(from != to); + other = other_table[from * 3 + to]; + assert(other != -1); + if (n == 1) { + move_disk(from, to, fd); + } else { + move_disks(from, other, n - 1, fd); + move_disk(from, to, fd); + move_disks(other, to, n - 1, fd); + } +} + +void +engine(int *args) +{ + num_disks[0] = args[0]; + for (;;) { + move_disks(0, 2, args[0], args[1]); + move_disks(2, 0, args[0], args[1]); + } +} + +#ifdef TEST_ENGINE +int +main(int argc, char *argv[]) +{ + int engine_args[2]; + + if (argc > 1) { + engine_args[0] = atoi(argv[1]); + } + engine_args[1] = 1; + engine(n, engine_args); + return 0; /* ANSI C requires main to return int. */ +} +#endif diff --git a/lib/glut-3.7.6/progs/contrib/fractals.c b/lib/glut-3.7.6/progs/contrib/fractals.c new file mode 100644 index 0000000000..542b753b79 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/fractals.c @@ -0,0 +1,713 @@ +/* + * To compile: cc -o fractals fractals.c -lGL -lGLU -lX11 -lglut -lXmu -lm + * + * Usage: fractals + * + * Homework 6, Part 2: fractal mountains and fractal trees + * (Pretty Late) + * + * Draws fractal mountains and trees -- and an island of mountains in water + * (I tried having trees on the island but it didn't work too well.) + * + * Two viewer modes: polar and flying (both restrained to y>0 for up vector). + * Keyboard 0->9 and +/- control speed when flying. + * + * Only keyboard commands are 0-9 and +/- for speed in flying mode. + * + * Fog would make the island look much better, but I couldn't get it to work + * correctly. Would line up on -z axis not from eye. + * + * Philip Winston - 3/4/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + * + */ + +#include + +#include +#include +#include +#include /* ULONG_MAX is defined here */ +#include /* FLT_MAX is atleast defined here */ + +#include /* for random seed */ + +#include "fracviewer.h" + +#ifdef _WIN32 +#define drand48() (((float) rand())/((float) RAND_MAX)) +#define srand48(x) (srand((x))) +#endif + +typedef enum { NOTALLOWED, MOUNTAIN, TREE, ISLAND, BIGMTN, STEM, LEAF, + MOUNTAIN_MAT, WATER_MAT, LEAF_MAT, TREE_MAT, STEMANDLEAVES, + AXES } DisplayLists; + +#define MAXLEVEL 8 + +int Rebuild = 1, /* Rebuild display list in next display? */ + Fract = TREE, /* What fractal are we building */ + Level = 4; /* levels of recursion for fractals */ + +int DrawAxes = 0; + +/***************************************************************/ +/************************* VECTOR JUNK *************************/ +/***************************************************************/ + + /* print vertex to stderr */ +void printvert(float v[3]) +{ + fprintf(stderr, "(%f, %f, %f)\n", v[0], v[1], v[2]); +} + + /* normalizes v */ +void normalize(GLfloat v[3]) +{ + GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + + if (d == 0) + fprintf(stderr, "Zero length vector in normalize\n"); + else + v[0] /= d; v[1] /= d; v[2] /= d; +} + + /* calculates a normalized crossproduct to v1, v2 */ +void ncrossprod(float v1[3], float v2[3], float cp[3]) +{ + cp[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cp[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cp[2] = v1[0]*v2[1] - v1[1]*v2[0]; + normalize(cp); +} + + /* calculates normal to the triangle designated by v1, v2, v3 */ +void triagnormal(float v1[3], float v2[3], float v3[3], float norm[3]) +{ + float vec1[3], vec2[3]; + + vec1[0] = v3[0] - v1[0]; vec2[0] = v2[0] - v1[0]; + vec1[1] = v3[1] - v1[1]; vec2[1] = v2[1] - v1[1]; + vec1[2] = v3[2] - v1[2]; vec2[2] = v2[2] - v1[2]; + + ncrossprod(vec2, vec1, norm); +} + +float xzlength(float v1[3], float v2[3]) +{ + return sqrt((v1[0] - v2[0])*(v1[0] - v2[0]) + + (v1[2] - v2[2])*(v1[2] - v2[2])); +} + +float xzslope(float v1[3], float v2[3]) +{ + return ((v1[0] != v2[0]) ? ((v1[2] - v2[2]) / (v1[0] - v2[0])) + : FLT_MAX); +} + + +/***************************************************************/ +/************************ MOUNTAIN STUFF ***********************/ +/***************************************************************/ + +GLfloat DispFactor[MAXLEVEL]; /* Array of what to multiply random number + by for a given level to get midpoint + displacement */ +GLfloat DispBias[MAXLEVEL]; /* Array of what to add to random number + before multiplying it by DispFactor */ + +#define NUMRANDS 191 +float RandTable[NUMRANDS]; /* hash table of random numbers so we can + raise the same midpoints by the same amount */ + + /* The following are for permitting an edge of a moutain to be */ + /* pegged so it won't be displaced up or down. This makes it */ + /* easier to setup scenes and makes a single moutain look better */ + +GLfloat Verts[3][3], /* Vertices of outside edges of mountain */ + Slopes[3]; /* Slopes between these outside edges */ +int Pegged[3]; /* Is this edge pegged or not */ + + /* + * Comes up with a new table of random numbers [0,1) + */ +void InitRandTable(unsigned int seed) +{ + int i; + + srand48((long) seed); + for (i = 0; i < NUMRANDS; i++) + RandTable[i] = drand48() - 0.5; +} + + /* calculate midpoint and displace it if required */ +void Midpoint(GLfloat mid[3], GLfloat v1[3], GLfloat v2[3], + int edge, int level) +{ + unsigned hash; + + mid[0] = (v1[0] + v2[0]) / 2; + mid[1] = (v1[1] + v2[1]) / 2; + mid[2] = (v1[2] + v2[2]) / 2; + if (!Pegged[edge] || (fabs(xzslope(Verts[edge], mid) + - Slopes[edge]) > 0.00001)) { + srand48((int)((v1[0]+v2[0])*23344)); + hash = drand48() * 7334334; + srand48((int)((v2[2]+v1[2])*43433)); + hash = (unsigned)(drand48() * 634344 + hash) % NUMRANDS; + mid[1] += ((RandTable[hash] + DispBias[level]) * DispFactor[level]); + } +} + + /* + * Recursive moutain drawing routine -- from lecture with addition of + * allowing an edge to be pegged. This function requires the above + * globals to be set, as well as the Level global for fractal level + */ +void FMR(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int level) +{ + if (level == Level) { + GLfloat norm[3]; + + triagnormal(v1, v2, v3, norm); + glNormal3fv(norm); + glVertex3fv(v1); + glVertex3fv(v2); + glVertex3fv(v3); + + } else { + GLfloat m1[3], m2[3], m3[3]; + + Midpoint(m1, v1, v2, 0, level); + Midpoint(m2, v2, v3, 1, level); + Midpoint(m3, v3, v1, 2, level); + + FMR(v1, m1, m3, level + 1); + FMR(m1, v2, m2, level + 1); + FMR(m3, m2, v3, level + 1); + FMR(m1, m2, m3, level + 1); + } +} + + /* + * sets up lookup tables and calls recursive mountain function + */ +void FractalMountain(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], + int pegged[3]) +{ + GLfloat lengths[MAXLEVEL]; + GLfloat fraction[8] = { 0.3, 0.3, 0.4, 0.2, 0.3, 0.2, 0.4, 0.4 }; + GLfloat bias[8] = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 }; + int i; + float avglen = (xzlength(v1, v2) + + xzlength(v2, v3) + + xzlength(v3, v1) / 3); + + for (i = 0; i < 3; i++) { + Verts[0][i] = v1[i]; /* set mountain vertex globals */ + Verts[1][i] = v2[i]; + Verts[2][i] = v3[i]; + Pegged[i] = pegged[i]; + } + + Slopes[0] = xzslope(Verts[0], Verts[1]); /* set edge slope globals */ + Slopes[1] = xzslope(Verts[1], Verts[2]); + Slopes[2] = xzslope(Verts[2], Verts[0]); + + lengths[0] = avglen; + for (i = 1; i < Level; i++) { + lengths[i] = lengths[i-1]/2; /* compute edge length for each level */ + } + + for (i = 0; i < Level; i++) { /* DispFactor and DispBias arrays */ + DispFactor[i] = (lengths[i] * ((i <= 7) ? fraction[i] : fraction[7])); + DispBias[i] = ((i <= 7) ? bias[i] : bias[7]); + } + + glBegin(GL_TRIANGLES); + FMR(v1, v2, v3, 0); /* issues no GL but vertex calls */ + glEnd(); +} + + /* + * draw a mountain and build the display list + */ +void CreateMountain(void) +{ + GLfloat v1[3] = { 0, 0, -1 }, v2[3] = { -1, 0, 1 }, v3[3] = { 1, 0, 1 }; + int pegged[3] = { 1, 1, 1 }; + + glNewList(MOUNTAIN, GL_COMPILE); + glPushAttrib(GL_LIGHTING_BIT); + glCallList(MOUNTAIN_MAT); + FractalMountain(v1, v2, v3, pegged); + glPopAttrib(); + glEndList(); +} + + /* + * new random numbers to make a different moutain + */ +void NewMountain(void) +{ + InitRandTable(time(NULL)); +} + +/***************************************************************/ +/***************************** TREE ****************************/ +/***************************************************************/ + +long TreeSeed; /* for srand48 - remember so we can build "same tree" + at a different level */ + + /* + * recursive tree drawing thing, fleshed out from class notes pseudocode + */ +void FractalTree(int level) +{ + long savedseed; /* need to save seeds while building tree too */ + + if (level == Level) { + glPushMatrix(); + glRotatef(drand48()*180, 0, 1, 0); + glCallList(STEMANDLEAVES); + glPopMatrix(); + } else { + glCallList(STEM); + glPushMatrix(); + glRotatef(drand48()*180, 0, 1, 0); + glTranslatef(0, 1, 0); + glScalef(0.7, 0.7, 0.7); + + savedseed = (long) drand48()*ULONG_MAX; /* recurse on a 3-way branching */ + glPushMatrix(); + glRotatef(110 + drand48()*40, 0, 1, 0); + glRotatef(30 + drand48()*20, 0, 0, 1); + FractalTree(level + 1); + glPopMatrix(); + + srand48(savedseed); + savedseed = (long) drand48()*ULONG_MAX; + glPushMatrix(); + glRotatef(-130 + drand48()*40, 0, 1, 0); + glRotatef(30 + drand48()*20, 0, 0, 1); + FractalTree(level + 1); + glPopMatrix(); + + srand48(savedseed); + glPushMatrix(); + glRotatef(-20 + drand48()*40, 0, 1, 0); + glRotatef(30 + drand48()*20, 0, 0, 1); + FractalTree(level + 1); + glPopMatrix(); + + glPopMatrix(); + } +} + + /* + * Create display lists for a leaf, a set of leaves, and a stem + */ +void CreateTreeLists(void) +{ + GLUquadricObj *cylquad = gluNewQuadric(); + int i; + + glNewList(STEM, GL_COMPILE); + glPushMatrix(); + glRotatef(-90, 1, 0, 0); + gluCylinder(cylquad, 0.1, 0.08, 1, 10, 2 ); + glPopMatrix(); + glEndList(); + + glNewList(LEAF, GL_COMPILE); /* I think this was jeff allen's leaf idea */ + glBegin(GL_TRIANGLES); + glNormal3f(-0.1, 0, 0.25); /* not normalized */ + glVertex3f(0, 0, 0); + glVertex3f(0.25, 0.25, 0.1); + glVertex3f(0, 0.5, 0); + + glNormal3f(0.1, 0, 0.25); + glVertex3f(0, 0, 0); + glVertex3f(0, 0.5, 0); + glVertex3f(-0.25, 0.25, 0.1); + glEnd(); + glEndList(); + + glNewList(STEMANDLEAVES, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glCallList(STEM); + glCallList(LEAF_MAT); + for(i = 0; i < 3; i++) { + glTranslatef(0, 0.333, 0); + glRotatef(90, 0, 1, 0); + glPushMatrix(); + glRotatef(0, 0, 1, 0); + glRotatef(50, 1, 0, 0); + glCallList(LEAF); + glPopMatrix(); + glPushMatrix(); + glRotatef(180, 0, 1, 0); + glRotatef(60, 1, 0, 0); + glCallList(LEAF); + glPopMatrix(); + } + glPopAttrib(); + glPopMatrix(); + glEndList(); +} + + /* + * draw and build display list for tree + */ +void CreateTree(void) +{ + srand48(TreeSeed); + + glNewList(TREE, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glCallList(TREE_MAT); + glTranslatef(0, -1, 0); + FractalTree(0); + glPopAttrib(); + glPopMatrix(); + glEndList(); +} + + /* + * new seed for a new tree (groan) + */ +void NewTree(void) +{ + TreeSeed = time(NULL); +} + +/***************************************************************/ +/*********************** FRACTAL PLANET ************************/ +/***************************************************************/ + +void CreateIsland(void) +{ + CreateMountain(); + glNewList(ISLAND, GL_COMPILE); + glPushAttrib(GL_LIGHTING_BIT); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glCallList(WATER_MAT); + + glBegin(GL_QUADS); + glNormal3f(0, 1, 0); + glVertex3f(100, 0.01, 100); + glVertex3f(100, 0.01, -100); + glVertex3f(-100, 0.01, -100); + glVertex3f(-100, 0.01, 100); + glEnd(); + + glPushMatrix(); + glTranslatef(0, -0.1, 0); + glCallList(MOUNTAIN); + glPopMatrix(); + + glPushMatrix(); + glRotatef(135, 0, 1, 0); + glTranslatef(0.2, -0.15, -0.4); + glCallList(MOUNTAIN); + glPopMatrix(); + + glPushMatrix(); + glRotatef(-60, 0, 1, 0); + glTranslatef(0.7, -0.07, 0.5); + glCallList(MOUNTAIN); + glPopMatrix(); + + glPushMatrix(); + glRotatef(-175, 0, 1, 0); + glTranslatef(-0.7, -0.05, -0.5); + glCallList(MOUNTAIN); + glPopMatrix(); + + glPushMatrix(); + glRotatef(165, 0, 1, 0); + glTranslatef(-0.9, -0.12, 0.0); + glCallList(MOUNTAIN); + glPopMatrix(); + + glPopMatrix(); + glPopAttrib(); + glEndList(); +} + + +void NewFractals(void) +{ + NewMountain(); + NewTree(); +} + +void Create(int fract) +{ + switch(fract) { + case MOUNTAIN: + CreateMountain(); + break; + case TREE: + CreateTree(); + break; + case ISLAND: + CreateIsland(); + break; + } +} + + + +/***************************************************************/ +/**************************** OPENGL ***************************/ +/***************************************************************/ + + +void SetupMaterials(void) +{ + GLfloat mtn_ambuse[] = { 0.426, 0.256, 0.108, 1.0 }; + GLfloat mtn_specular[] = { 0.394, 0.272, 0.167, 1.0 }; + GLfloat mtn_shininess[] = { 10 }; + + GLfloat water_ambuse[] = { 0.0, 0.1, 0.5, 1.0 }; + GLfloat water_specular[] = { 0.0, 0.1, 0.5, 1.0 }; + GLfloat water_shininess[] = { 10 }; + + GLfloat tree_ambuse[] = { 0.4, 0.25, 0.1, 1.0 }; + GLfloat tree_specular[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat tree_shininess[] = { 0 }; + + GLfloat leaf_ambuse[] = { 0.0, 0.8, 0.0, 1.0 }; + GLfloat leaf_specular[] = { 0.0, 0.8, 0.0, 1.0 }; + GLfloat leaf_shininess[] = { 10 }; + + glNewList(MOUNTAIN_MAT, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mtn_ambuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mtn_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mtn_shininess); + glEndList(); + + glNewList(WATER_MAT, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, water_ambuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, water_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, water_shininess); + glEndList(); + + glNewList(TREE_MAT, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tree_ambuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, tree_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, tree_shininess); + glEndList(); + + glNewList(LEAF_MAT, GL_COMPILE); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, leaf_ambuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, leaf_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, leaf_shininess); + glEndList(); +} + +void myGLInit(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[] = { 0.0, 0.3, 0.3, 0.0 }; + + GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 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, lmodel_ambient); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_NORMALIZE); +#if 0 + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); +#endif + + glShadeModel(GL_SMOOTH); +#if 0 + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif + + SetupMaterials(); + CreateTreeLists(); + + glFlush(); +} + +/***************************************************************/ +/************************ GLUT STUFF ***************************/ +/***************************************************************/ + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0,0,w,h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, (GLdouble)w/h, 0.01, 100); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glFlush(); +} + +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFlush(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPushMatrix(); /* clear of last viewing xform, leaving perspective */ + + agvViewTransform(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (Rebuild) { + Create(Fract); + Rebuild = 0; + } + + glCallList(Fract); + + if (DrawAxes) + glCallList(AXES); + + glutSwapBuffers(); + glFlush(); +} + + +void visible(int v) +{ + if (v == GLUT_VISIBLE) + agvSetAllowIdle(1); + else { + glutIdleFunc(NULL); + agvSetAllowIdle(0); + } +} + +void menuuse(int v) +{ + if (v == GLUT_MENU_NOT_IN_USE) + agvSetAllowIdle(1); + else { + glutIdleFunc(NULL); + agvSetAllowIdle(0); + } +} + +/***************************************************************/ +/******************* MENU SETUP & HANDLING *********************/ +/***************************************************************/ + +typedef enum { MENU_QUIT, MENU_RAND, MENU_MOVE, MENU_AXES } MenuChoices; + +void setlevel(int value) +{ + Level = value; + Rebuild = 1; + glutPostRedisplay(); +} + +void choosefract(int value) +{ + Fract = value; + Rebuild = 1; + glutPostRedisplay(); +} + +void handlemenu(int value) +{ + switch (value) { + case MENU_QUIT: + exit(0); + break; + case MENU_RAND: + NewFractals(); + Rebuild = 1; + glutPostRedisplay(); + break; + case MENU_AXES: + DrawAxes = !DrawAxes; + glutPostRedisplay(); + break; + } +} + +void MenuInit(void) +{ + int submenu3, submenu2, submenu1; + + submenu1 = glutCreateMenu(setlevel); + glutAddMenuEntry("0", 0); glutAddMenuEntry("1", 1); + glutAddMenuEntry("2", 2); glutAddMenuEntry("3", 3); + glutAddMenuEntry("4", 4); glutAddMenuEntry("5", 5); + glutAddMenuEntry("6", 6); glutAddMenuEntry("7", 7); + glutAddMenuEntry("8", 8); + + submenu2 = glutCreateMenu(choosefract); + glutAddMenuEntry("Moutain", MOUNTAIN); + glutAddMenuEntry("Tree", TREE); + glutAddMenuEntry("Island", ISLAND); + + submenu3 = glutCreateMenu(agvSwitchMoveMode); + glutAddMenuEntry("Flying", FLYING); + glutAddMenuEntry("Polar", POLAR); + + glutCreateMenu(handlemenu); + glutAddSubMenu("Level", submenu1); + glutAddSubMenu("Fractal", submenu2); + glutAddSubMenu("Movement", submenu3); + glutAddMenuEntry("New Fractal", MENU_RAND); + glutAddMenuEntry("Toggle Axes", MENU_AXES); + glutAddMenuEntry("Quit", MENU_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + + +/***************************************************************/ +/**************************** MAIN *****************************/ +/***************************************************************/ + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutCreateWindow("Fractal Planet?"); + + agvInit(1); /* 1 cause we don't have our own idle */ + + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutVisibilityFunc(visible); + glutMenuStateFunc(menuuse); + + NewFractals(); + agvMakeAxesList(AXES); + myGLInit(); + MenuInit(); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/fractals.dsp b/lib/glut-3.7.6/progs/contrib/fractals.dsp new file mode 100644 index 0000000000..26ff71f0db --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/fractals.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="fractals" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=fractals - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fractals.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fractals.mak" CFG="fractals - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fractals - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "fractals - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fractals - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "fractals - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "fractals - Win32 Release" +# Name "fractals - Win32 Debug" +# Begin Source File + +SOURCE=.\fractals.c +# End Source File +# Begin Source File + +SOURCE=.\fracviewer.c +# End Source File +# Begin Source File + +SOURCE=.\fracviewer.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/fracviewer.c b/lib/glut-3.7.6/progs/contrib/fracviewer.c new file mode 100644 index 0000000000..105c4379e0 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/fracviewer.c @@ -0,0 +1,498 @@ +/* + * fractviewer.c [from agviewer.c (version 1.0)] + * + * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut + * + * See agv_example.c and agviewer.h comments within for more info. + * + * I welcome any feedback or improved versions! + * + * Philip Winston - 4/11/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + */ + +#include +#include +#include +#include + +#include "fracviewer.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/***************************************************************/ +/************************** SETTINGS ***************************/ +/***************************************************************/ + + /* Initial polar movement settings */ +#define INIT_POLAR_AZ 0.0 +#define INIT_POLAR_EL 30.0 +#define INIT_DIST 4.0 +#define INIT_AZ_SPIN 0.5 +#define INIT_EL_SPIN 0.0 + + /* Initial flying movement settings */ +#define INIT_EX 0.0 +#define INIT_EY -2.0 +#define INIT_EZ -2.0 +#define INIT_MOVE 0.01 +#define MINMOVE 0.001 + + /* Start in this mode */ +#define INIT_MODE POLAR + + /* Controls: */ + + /* map 0-9 to an EyeMove value when number key is hit in FLYING mode */ +#define SPEEDFUNCTION(x) ((x)*(x)*0.001) + + /* Multiply EyeMove by (1+-MOVEFRACTION) when +/- hit in FLYING mode */ +#define MOVEFRACTION 0.25 + + /* What to multiply number of pixels mouse moved by to get rotation amount */ +#define EL_SENS 0.5 +#define AZ_SENS 0.5 + + /* What to multiply number of pixels mouse moved by for movement amounts */ +#define DIST_SENS 0.01 +#define E_SENS 0.01 + + /* Minimum spin to allow in polar (lower forced to zero) */ +#define MIN_AZSPIN 0.1 +#define MIN_ELSPIN 0.1 + + /* Factors used in computing dAz and dEl (which determine AzSpin, ElSpin) */ +#define SLOW_DAZ 0.90 +#define SLOW_DEL 0.90 +#define PREV_DAZ 0.80 +#define PREV_DEL 0.80 +#define CUR_DAZ 0.20 +#define CUR_DEL 0.20 + +/***************************************************************/ +/************************** GLOBALS ****************************/ +/***************************************************************/ + +int MoveMode = INIT_MODE; /* FLYING or POLAR mode? */ + +GLfloat Ex = INIT_EX, /* flying parameters */ + Ey = INIT_EY, + Ez = INIT_EZ, + EyeMove = INIT_MOVE, + + EyeDist = INIT_DIST, /* polar params */ + AzSpin = INIT_AZ_SPIN, + ElSpin = INIT_EL_SPIN, + + EyeAz = INIT_POLAR_AZ, /* used by both */ + EyeEl = INIT_POLAR_EL; + +int agvMoving; /* Currently moving? */ + +int downx, downy, /* for tracking mouse position */ + lastx, lasty, + downb = -1; /* and button status */ + +GLfloat downDist, downEl, downAz, /* for saving state of things */ + downEx, downEy, downEz, /* when button is pressed */ + downEyeMove; + +GLfloat dAz, dEl, lastAz, lastEl; /* to calculate spinning w/ polar motion */ +int AdjustingAzEl = 0; + +int AllowIdle, RedisplayWindow; + /* If AllowIdle is 1 it means AGV will install its own idle which + * will update the viewpoint as needed and send glutPostRedisplay() to the + * window RedisplayWindow which was set in agvInit(). AllowIdle of 0 + * means AGV won't install an idle funciton, and something like + * "if (agvMoving) agvMove()" should exist at the end of the running + * idle function. + */ + +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define TORAD(x) ((M_PI/180.0)*(x)) +#define TODEG(x) ((180.0/M_PI)*(x)) + +/***************************************************************/ +/************************ PROTOTYPES ***************************/ +/***************************************************************/ + + /* + * these are functions meant for internal use only + * the other prototypes are in agviewer.h + */ + +void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth); +void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, + GLfloat az, GLfloat el); +int ConstrainEl(void); +void MoveOn(int v); +void SetMove(float newmove); +static void normalize(GLfloat v[3]); +static void ncrossprod(float v1[3], float v2[3], float cp[3]); + + +/***************************************************************/ +/************************ agvInit ******************************/ +/***************************************************************/ + +void agvInit(int window) +{ + glutMouseFunc(agvHandleButton); + glutMotionFunc(agvHandleMotion); + glutKeyboardFunc(agvHandleKeys); + RedisplayWindow = glutGetWindow(); + agvSetAllowIdle(window); +} + +/***************************************************************/ +/************************ VIEWPOINT STUFF **********************/ +/***************************************************************/ + + /* + * viewing transformation modified from page 90 of red book + */ +void PolarLookFrom(GLfloat dist, GLfloat elevation, GLfloat azimuth) +{ + glTranslatef(0, 0, -dist); + glRotatef(elevation, 1, 0, 0); + glRotatef(azimuth, 0, 1, 0); + +} + + /* + * I took the idea of tracking eye position in absolute + * coords and direction looking in Polar form from denis + */ +void FlyLookFrom(GLfloat x, GLfloat y, GLfloat z, GLfloat az, GLfloat el) +{ + float lookat[3], perp[3], up[3]; + + lookat[0] = sin(TORAD(az))*cos(TORAD(el)); + lookat[1] = sin(TORAD(el)); + lookat[2] = -cos(TORAD(az))*cos(TORAD(el)); + normalize(lookat); + perp[0] = lookat[2]; + perp[1] = 0; + perp[2] = -lookat[0]; + normalize(perp); + ncrossprod(lookat, perp, up); + gluLookAt(x, y, z, + x+lookat[0], y+lookat[1], z+lookat[2], + up[0], up[1], up[2]); +} + + /* + * Call viewing transformation based on movement mode + */ +void agvViewTransform(void) +{ + switch (MoveMode) { + case FLYING: + FlyLookFrom(Ex, Ey, Ez, EyeAz, EyeEl); + break; + case POLAR: + PolarLookFrom(EyeDist, EyeEl, EyeAz); + break; + } +} + + /* + * keep them vertical; I think this makes a lot of things easier, + * but maybe it wouldn't be too hard to adapt things to let you go + * upside down + */ +int ConstrainEl(void) +{ + if (EyeEl <= -90) { + EyeEl = -89.99; + return 1; + } else if (EyeEl >= 90) { + EyeEl = 89.99; + return 1; + } + return 0; +} + + /* + * Idle Function - moves eyeposition + */ +void agvMove(void) +{ + + switch (MoveMode) { + case FLYING: + Ex += EyeMove*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey += EyeMove*sin(TORAD(EyeEl)); + Ez -= EyeMove*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); + break; + + case POLAR: + EyeEl += ElSpin; + EyeAz += AzSpin; + if (ConstrainEl()) { /* weird spin thing to make things look */ + ElSpin = -ElSpin; /* look better when you are kept from going */ + /* upside down while spinning - Isn't great */ + if (fabs(ElSpin) > fabs(AzSpin)) + AzSpin = fabs(ElSpin) * ((AzSpin > 0) ? 1 : -1); + } + break; + } + + if (AdjustingAzEl) { + dAz *= SLOW_DAZ; + dEl *= SLOW_DEL; + } + + if (AllowIdle) { + glutSetWindow(RedisplayWindow); + glutPostRedisplay(); + } +} + + + /* + * Don't install agvMove as idle unless we will be updating the view + * and we've been given a RedisplayWindow + */ +void MoveOn(int v) +{ + if (v && ((MoveMode == FLYING && EyeMove != 0) || + (MoveMode == POLAR && + (AzSpin != 0 || ElSpin != 0 || AdjustingAzEl)))) { + agvMoving = 1; + if (AllowIdle) + glutIdleFunc(agvMove); + } else { + agvMoving = 0; + if (AllowIdle) + glutIdleFunc(NULL); + } +} + + /* + * set new redisplay window. If <= 0 it means we are not to install + * an idle function and will rely on whoever does install one to + * put statement like "if (agvMoving) agvMove();" at end of it + */ +void agvSetAllowIdle(int allowidle) +{ + if ((AllowIdle = allowidle)) + MoveOn(1); +} + + + /* + * when moving to flying we stay in the same spot, moving to polar we + * reset since we have to be looking at the origin (though a pivot from + * current position to look at origin might be cooler) + */ +void agvSwitchMoveMode(int move) +{ + switch (move) { + case FLYING: + if (MoveMode == FLYING) return; + Ex = -EyeDist*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey = EyeDist*sin(TORAD(EyeEl)); + Ez = EyeDist*(cos(TORAD(EyeAz))*cos(TORAD(EyeEl))); + EyeAz = EyeAz; + EyeEl = -EyeEl; + EyeMove = INIT_MOVE; + break; + case POLAR: + EyeDist = INIT_DIST; + EyeAz = INIT_POLAR_AZ; + EyeEl = INIT_POLAR_EL; + AzSpin = INIT_AZ_SPIN; + ElSpin = INIT_EL_SPIN; + break; + } + MoveMode = move; + MoveOn(1); + glutPostRedisplay(); +} + +/***************************************************************/ +/******************* MOUSE HANDLING ***********************/ +/***************************************************************/ + +void agvHandleButton(int button, int state, int x, int y) +{ + if (state == GLUT_DOWN && downb == -1) { + lastx = downx = x; + lasty = downy = y; + downb = button; + + switch (button) { + case GLUT_LEFT_BUTTON: + lastEl = downEl = EyeEl; + lastAz = downAz = EyeAz; + AzSpin = ElSpin = dAz = dEl = 0; + AdjustingAzEl = 1; + MoveOn(1); + break; + + case GLUT_MIDDLE_BUTTON: + downDist = EyeDist; + downEx = Ex; + downEy = Ey; + downEz = Ez; + downEyeMove = EyeMove; + EyeMove = 0; + } + + } else if (state == GLUT_UP && button == downb) { + + downb = -1; + + switch (button) { + case GLUT_LEFT_BUTTON: + if (MoveMode != FLYING) { + AzSpin = -dAz; + if (AzSpin < MIN_AZSPIN && AzSpin > -MIN_AZSPIN) + AzSpin = 0; + ElSpin = -dEl; + if (ElSpin < MIN_ELSPIN && ElSpin > -MIN_ELSPIN) + ElSpin = 0; + } + AdjustingAzEl = 0; + MoveOn(1); + break; + + case GLUT_MIDDLE_BUTTON: + EyeMove = downEyeMove; + } + } +} + + /* + * change EyeEl and EyeAz and position when mouse is moved w/ button down + */ +void agvHandleMotion(int x, int y) +{ + int deltax = x - downx, deltay = y - downy; + + switch (downb) { + case GLUT_LEFT_BUTTON: + EyeEl = downEl + EL_SENS * ((MoveMode == FLYING) ? -deltay : deltay); + ConstrainEl(); + EyeAz = downAz + AZ_SENS * deltax; + dAz = PREV_DAZ*dAz + CUR_DAZ*(lastAz - EyeAz); + dEl = PREV_DEL*dEl + CUR_DEL*(lastEl - EyeEl); + lastAz = EyeAz; + lastEl = EyeEl; + break; + case GLUT_MIDDLE_BUTTON: + EyeDist = downDist + DIST_SENS*deltay; + Ex = downEx - E_SENS*deltay*sin(TORAD(EyeAz))*cos(TORAD(EyeEl)); + Ey = downEy - E_SENS*deltay*sin(TORAD(EyeEl)); + Ez = downEz + E_SENS*deltay*cos(TORAD(EyeAz))*cos(TORAD(EyeEl)); + break; + } + glutPostRedisplay(); +} + +/***************************************************************/ +/********************* KEYBOARD HANDLING ***********************/ +/***************************************************************/ + + /* + * set EyeMove (current speed) for FLYING mode + */ +void SetMove(float newmove) +{ + if (newmove > MINMOVE) { + EyeMove = newmove; + MoveOn(1); + } else { + EyeMove = 0; + MoveOn(0); + } +} + + /* + * 0->9 set speed, +/- adjust current speed -- in FLYING mode + */ +/* ARGSUSED1 */ +void agvHandleKeys(unsigned char key, int x, int y) +{ + if (MoveMode != FLYING) + return; + + if (key >= '0' && key <= '9') + SetMove(SPEEDFUNCTION((key-'0'))); + else + switch(key) { + case '+': + if (EyeMove == 0) + SetMove(MINMOVE); + else + SetMove(EyeMove *= (1 + MOVEFRACTION)); + break; + case '-': + SetMove(EyeMove *= (1 - MOVEFRACTION)); + break; + } +} + +/***************************************************************/ +/*********************** VECTOR STUFF **************************/ +/***************************************************************/ + + /* normalizes v */ +static void normalize(GLfloat v[3]) +{ + GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + + if (d == 0) + fprintf(stderr, "Zero length vector in normalize\n"); + else + v[0] /= d; v[1] /= d; v[2] /= d; +} + + /* calculates a normalized crossproduct to v1, v2 */ +static void ncrossprod(float v1[3], float v2[3], float cp[3]) +{ + cp[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cp[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cp[2] = v1[0]*v2[1] - v1[1]*v2[0]; + normalize(cp); +} + +/***************************************************************/ +/**************************** AXES *****************************/ +/***************************************************************/ + + + /* draw axes -- was helpful to debug/design things */ +void agvMakeAxesList(int displaylistnum) +{ + int i,j; + GLfloat axes_ambuse[] = { 0.5, 0.0, 0.0, 1.0 }; + glNewList(displaylistnum, GL_COMPILE); + glPushAttrib(GL_LIGHTING_BIT); + glMatrixMode(GL_MODELVIEW); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, axes_ambuse); + glBegin(GL_LINES); + glVertex3f(15, 0, 0); glVertex3f(-15, 0, 0); + glVertex3f(0, 15, 0); glVertex3f(0, -15, 0); + glVertex3f(0, 0, 15); glVertex3f(0, 0, -15); + glEnd(); + for (i = 0; i < 3; i++) { + glPushMatrix(); + glTranslatef(-10*(i==0), -10*(i==1), -10*(i==2)); + for (j = 0; j < 21; j++) { + glutSolidCube(0.1); + glTranslatef(i==0, i==1, i==2); + } + glPopMatrix(); + } + glPopAttrib(); + glEndList(); +} + + diff --git a/lib/glut-3.7.6/progs/contrib/fracviewer.h b/lib/glut-3.7.6/progs/contrib/fracviewer.h new file mode 100644 index 0000000000..0bfe6d0b1b --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/fracviewer.h @@ -0,0 +1,104 @@ +/* + * fracviewer.h [from agviewer.h (version 1.0)] + * + * AGV: a glut viewer. Routines for viewing a 3d scene w/ glut + * + * The two view movement modes are POLAR and FLYING. Both move the eye, NOT + * THE OBJECT. You can never be upside down or twisted (roll) in either mode. + * + * A nice addition would be an examiner type trackball mode where you are + * moving the object and so could see it from any angle. Also less restricted + * flying and polar modes (fly upside down, do rolls, etc.). + * + * Controls for Polar are just left and middle buttons -- for flying it's + * those plus 0-9 number keys and +/- for speed adjustment. + * + * See agv_example.c and agviewer.c for more info. Probably want to make + * a copy of these and then edit for each program. This isn't meant to be + * a library, just something to graft onto your own programs. + * + * I welcome any feedback or improved versions. + * + * Philip Winston - 4/11/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + */ + + + /* + * Call agvInit() with glut's current window set to the window in + * which you want to run the viewer. Right after creating it is fine. It + * will remember that window for possible later use (see below) and + * registers mouse, motion, and keyboard handlers for that window (see below). + * + * allowidle is 1 or 0 depnding on whether you will let AGV install + * and uninstall an idle function. 0 means you will not let it (because + * you will be having your own idle function). In this case it is your + * responsibility to put a statement like: + * + * if (agvMoving) + * agvMove(); + * + * at the end of your idle function, to let AGV update the viewpoint if it + * is moving. + * + * If allowidle is 1 it means AGV will install its own idle which + * will update the viewpoint as needed and send glutPostRedisplay() to the + * window which was current when agvInit() was called. + * + * agvSetIdleAllow changes this value so you can let AGV install its idle + * when your idle isn't installed. + * + */ +void agvInit(int allowidle); +void agvSetAllowIdle(int allowidle); + + + /* + * Set which movement mode you are in. + */ +typedef enum { FLYING, POLAR } MovementType; +void agvSwitchMoveMode(int move); + + /* + * agvViewTransform basically does the appropriate gluLookAt() for the + * current position. So call it in your display on the projection matrix + */ +void agvViewTransform(void); + + /* + * agvMoving will be set by AGV according to whether it needs you to call + * agvMove() at the end of your idle function. You only need these if + * you aren't allowing AGV to do its own idle. + * (Don't change the value of agvMoving) + */ +extern int agvMoving; +void agvMove(void); + + /* + * These are the routines AGV registers to deal with mouse and keyboard input. + * Keyboard input only matters in flying mode, and then only to set speed. + * Mouse input only uses left two buttons in both modes. + * These are all registered with agvInit(), but you could register + * something else which called these, or reregister these as needed + */ +void agvHandleButton(int button, int state, int x, int y); +void agvHandleMotion(int x, int y); +void agvHandleKeys(unsigned char key, int x, int y); + + /* + * Just an extra routine which makes an x-y-z axes (about 10x10x10) + * which is nice for aligning things and debugging. Pass it an available + * displaylist number. + */ +void agvMakeAxesList(int displaylist); + + + + + + + + + + diff --git a/lib/glut-3.7.6/progs/contrib/gears.c b/lib/glut-3.7.6/progs/contrib/gears.c new file mode 100644 index 0000000000..9f5ced6f12 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/gears.c @@ -0,0 +1,569 @@ +#include +#include + +#include +#ifndef _WIN32 +#include +#endif +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#include +#include + +/* For portability... */ +#undef fcos +#undef fsin +#undef fsqrt +#define fcos cos +#define fsin sin +#define fsqrt sqrt + +static double d_near = 1.0; +static double d_far = 2000; +static int poo = 0; + +typedef struct { + float rad, wid; +} Profile; + +void flat_face(float ir, float or, float wd); +void draw_inside(float w1, float w2, float rad); +void draw_outside(float w1, float w2, float rad); +void tooth_side(int nt, float ir, float or, float tp, float tip, float wd); + +int circle_subdiv; + +int mode = GLUT_DOUBLE; + +void +gear(int nt, float wd, float ir, float or, float tp, float tip, int ns, Profile * ip) +{ + /** + * nt - number of teeth + * wd - width of gear at teeth + * ir - inside radius absolute scale + * or - radius at outside of wheel (tip of tooth) ratio of ir + * tp - ratio of tooth in slice of circle (0..1] (1 = teeth are touching at base) + * tip - ratio of tip of tooth (0..tp] (cant be wider that base of tooth) + * ns - number of elements in wheel width profile + * *ip - list of float pairs {start radius, width, ...} (width is ratio to wd) + * + */ + + /* gear lying on xy plane, z for width. all normals calulated + (normalized) */ + + float prev; + int k, t; + + /* estimat # times to divide circle */ + if (nt <= 0) + circle_subdiv = 64; + else { + /* lowest multiple of number of teeth */ + circle_subdiv = nt; + while (circle_subdiv < 64) + circle_subdiv += nt; + } + + /* --- draw wheel face --- */ + + /* draw horzontal, vertical faces for each section. if first + section radius not zero, use wd for 0.. first if ns == 0 + use wd for whole face. last width used to edge. */ + + if (ns <= 0) { + flat_face(0.0, ir, wd); + } else { + /* draw first flat_face, then continue in loop */ + if (ip[0].rad > 0.0) { + flat_face(0.0, ip[0].rad * ir, wd); + prev = wd; + t = 0; + } else { + flat_face(0.0, ip[1].rad * ir, ip[0].wid * wd); + prev = ip[0].wid; + t = 1; + } + for (k = t; k < ns; k++) { + if (prev < ip[k].wid) { + draw_inside(prev * wd, ip[k].wid * wd, ip[k].rad * ir); + } else { + draw_outside(prev * wd, ip[k].wid * wd, ip[k].rad * ir); + } + prev = ip[k].wid; + /* - draw to edge of wheel, add final face if needed - */ + if (k == ns - 1) { + flat_face(ip[k].rad * ir, ir, ip[k].wid * wd); + + /* now draw side to match tooth rim */ + if (ip[k].wid < 1.0) { + draw_inside(ip[k].wid * wd, wd, ir); + } else { + draw_outside(ip[k].wid * wd, wd, ir); + } + } else { + flat_face(ip[k].rad * ir, ip[k + 1].rad * ir, ip[k].wid * wd); + } + } + } + + /* --- tooth side faces --- */ + tooth_side(nt, ir, or, tp, tip, wd); + + /* --- tooth hill surface --- */ +} + +void +tooth_side(int nt, float ir, float or, float tp, float tip, float wd) +{ + + float i; + float end = 2.0 * M_PI / nt; + float x[6], y[6]; + float s[3], c[3]; + + or = or * ir; /* or is really a ratio of ir */ + for (i = 0; i < 2.0 * M_PI - end / 4.0; i += end) { + + c[0] = fcos(i); + s[0] = fsin(i); + c[1] = fcos(i + end * (0.5 - tip / 2)); + s[1] = fsin(i + end * (0.5 - tip / 2)); + c[2] = fcos(i + end * (0.5 + tp / 2)); + s[2] = fsin(i + end * (0.5 + tp / 2)); + + x[0] = ir * c[0]; + y[0] = ir * s[0]; + x[5] = ir * fcos(i + end); + y[5] = ir * fsin(i + end); + /* ---treat veritices 1,4 special to match strait edge of + face */ + x[1] = x[0] + (x[5] - x[0]) * (0.5 - tp / 2); + y[1] = y[0] + (y[5] - y[0]) * (0.5 - tp / 2); + x[4] = x[0] + (x[5] - x[0]) * (0.5 + tp / 2); + y[4] = y[0] + (y[5] - y[0]) * (0.5 + tp / 2); + x[2] = or * fcos(i + end * (0.5 - tip / 2)); + y[2] = or * fsin(i + end * (0.5 - tip / 2)); + x[3] = or * fcos(i + end * (0.5 + tip / 2)); + y[3] = or * fsin(i + end * (0.5 + tip / 2)); + + /* draw face trapezoids as 2 tmesh */ + glNormal3f(0.0, 0.0, 1.0); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[2], y[2], wd / 2); + glVertex3f(x[1], y[1], wd / 2); + glVertex3f(x[3], y[3], wd / 2); + glVertex3f(x[4], y[4], wd / 2); + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[2], y[2], -wd / 2); + glVertex3f(x[1], y[1], -wd / 2); + glVertex3f(x[3], y[3], -wd / 2); + glVertex3f(x[4], y[4], -wd / 2); + glEnd(); + + /* draw inside rim pieces */ + glNormal3f(c[0], s[0], 0.0); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[0], y[0], -wd / 2); + glVertex3f(x[1], y[1], -wd / 2); + glVertex3f(x[0], y[0], wd / 2); + glVertex3f(x[1], y[1], wd / 2); + glEnd(); + + /* draw up hill side */ + { + float a, b, n; + /* calculate normal of face */ + a = x[2] - x[1]; + b = y[2] - y[1]; + n = 1.0 / fsqrt(a * a + b * b); + a = a * n; + b = b * n; + glNormal3f(b, -a, 0.0); + } + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[1], y[1], -wd / 2); + glVertex3f(x[2], y[2], -wd / 2); + glVertex3f(x[1], y[1], wd / 2); + glVertex3f(x[2], y[2], wd / 2); + glEnd(); + /* draw top of hill */ + glNormal3f(c[1], s[1], 0.0); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[2], y[2], -wd / 2); + glVertex3f(x[3], y[3], -wd / 2); + glVertex3f(x[2], y[2], wd / 2); + glVertex3f(x[3], y[3], wd / 2); + glEnd(); + + /* draw down hill side */ + { + float a, b, c; + /* calculate normal of face */ + a = x[4] - x[3]; + b = y[4] - y[3]; + c = 1.0 / fsqrt(a * a + b * b); + a = a * c; + b = b * c; + glNormal3f(b, -a, 0.0); + } + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[3], y[3], -wd / 2); + glVertex3f(x[4], y[4], -wd / 2); + glVertex3f(x[3], y[3], wd / 2); + glVertex3f(x[4], y[4], wd / 2); + glEnd(); + /* inside rim part */ + glNormal3f(c[2], s[2], 0.0); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(x[4], y[4], -wd / 2); + glVertex3f(x[5], y[5], -wd / 2); + glVertex3f(x[4], y[4], wd / 2); + glVertex3f(x[5], y[5], wd / 2); + glEnd(); + } +} + +void +flat_face(float ir, float or, float wd) +{ + + int i; + float w; + + /* draw each face (top & bottom ) * */ + if (poo) + printf("Face : %f..%f wid=%f\n", ir, or, wd); + if (wd == 0.0) + return; + for (w = wd / 2; w > -wd; w -= wd) { + if (w > 0.0) + glNormal3f(0.0, 0.0, 1.0); + else + glNormal3f(0.0, 0.0, -1.0); + + if (ir == 0.0) { + /* draw as t-fan */ + glBegin(GL_TRIANGLE_FAN); + glVertex3f(0.0, 0.0, w); /* center */ + glVertex3f(or, 0.0, w); + for (i = 1; i < circle_subdiv; i++) { + glVertex3f(fcos(2.0 * M_PI * i / circle_subdiv) * or, + fsin(2.0 * M_PI * i / circle_subdiv) * or, + w); + } + glVertex3f(or, 0.0, w); + glEnd(); + } else { + /* draw as tmesh */ + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(or, 0.0, w); + glVertex3f(ir, 0.0, w); + for (i = 1; i < circle_subdiv; i++) { + glVertex3f(fcos(2.0 * M_PI * i / circle_subdiv) * or, + fsin(2.0 * M_PI * i / circle_subdiv) * or, + w); + glVertex3f(fcos(2.0 * M_PI * i / circle_subdiv) * ir, + fsin(2.0 * M_PI * i / circle_subdiv) * ir, + w); + } + glVertex3f(or, 0.0, w); + glVertex3f(ir, 0.0, w); + glEnd(); + + } + } +} + +void +draw_inside(float w1, float w2, float rad) +{ + + int i, j; + float c, s; + if (poo) + printf("Inside: wid=%f..%f rad=%f\n", w1, w2, rad); + if (w1 == w2) + return; + + w1 = w1 / 2; + w2 = w2 / 2; + for (j = 0; j < 2; j++) { + if (j == 1) { + w1 = -w1; + w2 = -w2; + } + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(rad, 0.0, w1); + glVertex3f(rad, 0.0, w2); + for (i = 1; i < circle_subdiv; i++) { + c = fcos(2.0 * M_PI * i / circle_subdiv); + s = fsin(2.0 * M_PI * i / circle_subdiv); + glNormal3f(-c, -s, 0.0); + glVertex3f(c * rad, + s * rad, + w1); + glVertex3f(c * rad, + s * rad, + w2); + } + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(rad, 0.0, w1); + glVertex3f(rad, 0.0, w2); + glEnd(); + } +} + +void +draw_outside(float w1, float w2, float rad) +{ + + int i, j; + float c, s; + if (poo) + printf("Outsid: wid=%f..%f rad=%f\n", w1, w2, rad); + if (w1 == w2) + return; + + w1 = w1 / 2; + w2 = w2 / 2; + for (j = 0; j < 2; j++) { + if (j == 1) { + w1 = -w1; + w2 = -w2; + } + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(1.0, 0.0, 0.0); + glVertex3f(rad, 0.0, w1); + glVertex3f(rad, 0.0, w2); + for (i = 1; i < circle_subdiv; i++) { + c = fcos(2.0 * M_PI * i / circle_subdiv); + s = fsin(2.0 * M_PI * i / circle_subdiv); + glNormal3f(c, s, 0.0); + glVertex3f(c * rad, + s * rad, + w1); + glVertex3f(c * rad, + s * rad, + w2); + } + glNormal3f(1.0, 0.0, 0.0); + glVertex3f(rad, 0.0, w1); + glVertex3f(rad, 0.0, w2); + glEnd(); + } +} + +Profile gear_profile[] = +{0.000, 0.0, + 0.300, 7.0, + 0.340, 0.4, + 0.550, 0.64, + 0.600, 0.4, + 0.950, 1.0 +}; + +float a1 = 27.0; +float a2 = 67.0; +float a3 = 47.0; +float a4 = 87.0; +float i1 = 1.2; +float i2 = 3.1; +float i3 = 2.3; +float i4 = 1.1; +void +oneFrame(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(0.0, 0.0, -4.0); + glRotatef(a3, 1.0, 1.0, 1.0); + glRotatef(a4, 0.0, 0.0, -1.0); + glTranslatef(0.14, 0.2, 0.0); + gear(76, + 0.4, 2.0, 1.1, + 0.4, 0.04, + sizeof(gear_profile) / sizeof(Profile), gear_profile); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.1, 0.2, -3.8); + glRotatef(a2, -4.0, 2.0, -1.0); + glRotatef(a1, 1.0, -3.0, 1.0); + glTranslatef(0.0, -0.2, 0.0); + gear(36, + 0.4, 2.0, 1.1, + 0.7, 0.2, + sizeof(gear_profile) / sizeof(Profile), gear_profile); + glPopMatrix(); + + a1 += i1; + if (a1 > 360.0) + a1 -= 360.0; + if (a1 < 0.0) + a1 -= 360.0; + a2 += i2; + if (a2 > 360.0) + a2 -= 360.0; + if (a2 < 0.0) + a2 -= 360.0; + a3 += i3; + if (a3 > 360.0) + a3 -= 360.0; + if (a3 < 0.0) + a3 -= 360.0; + a4 += i4; + if (a4 > 360.0) + a4 -= 360.0; + if (a4 < 0.0) + a4 -= 360.0; + if (mode == GLUT_SINGLE) { + glFlush(); + } else { + glutSwapBuffers(); + } +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void +myReshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, d_near, d_far); + /** + use perspective instead: + + if (w <= h){ + glOrtho( 0.0, 1.0, + 0.0, 1.0 * (GLfloat) h / (GLfloat) w, + -16.0, 4.0); + }else{ + glOrtho( 0.0, 1.0 * (GLfloat) w / (GLfloat) h, + 0.0, 1.0, + -16.0, 4.0); + } + */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void +visibility(int status) +{ + if (status == GLUT_VISIBLE) { + glutIdleFunc(oneFrame); + } else { + glutIdleFunc(NULL); + } + +} + +void +myinit(void) +{ + float f[20]; + glClearColor(0.0, 0.0, 0.0, 0.0); + myReshape(640, 480); + /* glShadeModel(GL_FLAT); */ + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_LIGHTING); + + glLightf(GL_LIGHT0, GL_SHININESS, 1.0); + f[0] = 1.3; + f[1] = 1.3; + f[2] = -3.3; + f[3] = 1.0; + glLightfv(GL_LIGHT0, GL_POSITION, f); + f[0] = 0.8; + f[1] = 1.0; + f[2] = 0.83; + f[3] = 1.0; + glLightfv(GL_LIGHT0, GL_SPECULAR, f); + glLightfv(GL_LIGHT0, GL_DIFFUSE, f); + glEnable(GL_LIGHT0); + + glLightf(GL_LIGHT1, GL_SHININESS, 1.0); + f[0] = -2.3; + f[1] = 0.3; + f[2] = -7.3; + f[3] = 1.0; + glLightfv(GL_LIGHT1, GL_POSITION, f); + f[0] = 1.0; + f[1] = 0.8; + f[2] = 0.93; + f[3] = 1.0; + glLightfv(GL_LIGHT1, GL_SPECULAR, f); + glLightfv(GL_LIGHT1, GL_DIFFUSE, f); + glEnable(GL_LIGHT1); + + /* gear material */ + f[0] = 0.1; + f[1] = 0.15; + f[2] = 0.2; + f[3] = 1.0; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, f); + + f[0] = 0.9; + f[1] = 0.3; + f[2] = 0.3; + f[3] = 1.0; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, f); + + f[0] = 0.4; + f[1] = 0.9; + f[2] = 0.6; + f[3] = 1.0; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, f); + + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 4); +} + +/* ARGSUSED1 */ +void +keys(unsigned char c, int x, int y) +{ + + if (c == 0x1b) + exit(0); /* escape */ +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + + if (argc > 1) + mode = GLUT_SINGLE; + glutInitDisplayMode(mode | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(100, 100); + glutInitWindowSize(640, 480); + glutCreateWindow(argv[0]); + + myinit(); + glutReshapeFunc(myReshape); + glutDisplayFunc(display); + glutKeyboardFunc(keys); + glutVisibilityFunc(visibility); + glutPostRedisplay(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/gears.dsp b/lib/glut-3.7.6/progs/contrib/gears.dsp new file mode 100644 index 0000000000..1fa4c54ca1 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/gears.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="gears" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gears - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gears.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gears.mak" CFG="gears - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gears - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gears - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gears - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "gears - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gears - Win32 Release" +# Name "gears - Win32 Debug" +# Begin Source File + +SOURCE=.\gears.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/hanoi.c b/lib/glut-3.7.6/progs/contrib/hanoi.c new file mode 100644 index 0000000000..46db95290b --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/hanoi.c @@ -0,0 +1,469 @@ + +/* hanoi.c - written by Greg Humphreys while an intern at SGI */ + +#include +#include +#include +#include + +double WIDTH = 800; +double HEIGHT = 800; + +GLboolean motion = GL_TRUE; +GLboolean back_wall = GL_FALSE; +GLint xangle = 0, yangle = 0; +GLint xlangle = 0, ylangle = 0; + +#define other(i,j) (6-(i+j)) +#define wallz -(WIDTH/2) +#define DISK_HEIGHT 20 +int NUM_DISKS = 11; +#define CONE NUM_DISKS+1 +#define WALL CONE + 1 +#define HANOI_SOLVE 0 +#define HANOI_QUIT 1 +#define HANOI_LIGHTING 2 +#define HANOI_WALL 3 +#define HANOI_FOG 4 + +GLfloat lightOneDirection[] = +{0, 0, -1}; +GLfloat lightOnePosition[] = +{200, 100, 300, 1}; +GLfloat lightOneColor[] = +{1.0, 1.0, 0.5, 1.0}; + +GLfloat lightTwoDirection[] = +{0, 0, -1}; +GLfloat lightTwoPosition[] = +{600, 100, 300, 1}; +GLfloat lightTwoColor[] = +{1.0, 0.0, 0.3, 1.0}; + +GLfloat lightZeroPosition[] = +{400, 200, 300, 1}; +GLfloat lightZeroColor[] = +{.3, .3, .3, .3}; + +GLfloat diskColor[] = +{1.0, 1.0, 1.0, .8}, poleColor[] = +{1.0, 0.2, 0.2, .8}; + +typedef struct stack_node { + int size; + struct stack_node *next; +} stack_node; + +typedef struct stack { + struct stack_node *head; + int depth; +} stack; + +stack poles[4]; + +void +push(int which, int size) +{ + stack_node *node = malloc(sizeof(stack_node)); + if (!node) { + fprintf(stderr, "out of memory!\n"); + exit(-1); + } + node->size = size; + node->next = poles[which].head; + poles[which].head = node; + poles[which].depth++; +} + +int +pop(int which) +{ + int retval = poles[which].head->size; + stack_node *temp = poles[which].head; + poles[which].head = poles[which].head->next; + poles[which].depth--; + free(temp); + return retval; +} + +typedef struct move_node { + int t, f; + struct move_node *next; + struct move_node *prev; +} move_node; + +typedef struct move_stack { + int depth; + struct move_node *head, *tail; +} move_stack; + +move_stack moves; + +void +init(void) +{ + int i; + for (i = 0; i < 4; i++) { + poles[i].head = NULL; + poles[i].depth = 0; + } + moves.head = NULL; + moves.tail = NULL; + moves.depth = 0; + + for (i = 1; i <= NUM_DISKS; i++) { + glNewList(i, GL_COMPILE); + { + glutSolidTorus(DISK_HEIGHT / 2, 5 * i, 15, 15); + } + glEndList(); + } + glNewList(CONE, GL_COMPILE); + { + glutSolidCone(10, (NUM_DISKS + 1) * DISK_HEIGHT, 20, 20); + } + glEndList(); +} + +void +mpop(void) +{ + move_node *temp = moves.head; + moves.head = moves.head->next; + free(temp); + moves.depth--; +} + +void +mpush(int t, int f) +{ + move_node *node = malloc(sizeof(move_node)); + if (!node) { + fprintf(stderr, "Out of memory!\n"); + exit(-1); + } + node->t = t; + node->f = f; + node->next = NULL; + node->prev = moves.tail; + if (moves.tail) + moves.tail->next = node; + moves.tail = node; + if (!moves.head) + moves.head = moves.tail; + moves.depth++; +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 27: /* ESC */ + case 'q': + case 'Q': + exit(0); + } +} + +void +update(void) +{ + glutPostRedisplay(); +} + +void +DrawPost(int xcenter) +{ + glPushMatrix(); + { + glTranslatef(xcenter, 0, 0); + glRotatef(90, -1, 0, 0); + glCallList(CONE); + } glPopMatrix(); +} + +void +DrawPosts(void) +{ + glColor3fv(poleColor); + glLineWidth(10); + glMaterialfv(GL_FRONT, GL_DIFFUSE, poleColor); + DrawPost((int) WIDTH / 4); + DrawPost(2 * (int) WIDTH / 4); + DrawPost(3 * (int) WIDTH / 4); +} + +void +DrawDisk(int xcenter, int ycenter, int size) +{ + glPushMatrix(); + { + glTranslatef(xcenter, ycenter, 0); + glRotatef(90, 1, 0, 0); + glCallList(size); + } glPopMatrix(); +} + +void +DrawDooDads(void) +{ + int i; + stack_node *temp; + int xcenter, ycenter; + glColor3fv(diskColor); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diskColor); + for (i = 1; i <= 3; i++) { + xcenter = i * WIDTH / 4; + for (temp = poles[i].head, ycenter = DISK_HEIGHT * poles[i].depth - DISK_HEIGHT / 2; temp; temp = temp->next, ycenter -= DISK_HEIGHT) { + DrawDisk(xcenter, ycenter, temp->size); + } + } +} + +#define MOVE(t,f) mpush((t),(f)) + +static void +mov(int n, int f, int t) +{ + int o; + + if (n == 1) { + MOVE(t, f); + return; + } + o = other(f, t); + mov(n - 1, f, o); + mov(1, f, t); + mov(n - 1, o, t); +} + +GLfloat wallcolor[] = +{0, .3, 1, 1}; + +void +DrawWall(void) +{ + int i; + int j; + glColor3fv(wallcolor); + for (i = 0; i < WIDTH; i += 10) { + for (j = 0; j < HEIGHT; j += 10) { + glBegin(GL_POLYGON); + { + glNormal3f(0, 0, 1); + glVertex3f(i + 10, j, wallz); + glVertex3f(i + 10, j + 10, wallz); + glVertex3f(i, j + 10, wallz); + glVertex3f(i, j, wallz); + } + glEnd(); + } + } +} + +void +draw(void) +{ + int t, f; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (back_wall) { + glMaterialfv(GL_FRONT, GL_DIFFUSE, wallcolor); + DrawWall(); + } + glPushMatrix(); + { + glTranslatef(WIDTH / 2, HEIGHT / 2, 0); + glRotatef(xlangle, 0, 1, 0); + glRotatef(ylangle, 1, 0, 0); + glTranslatef(-WIDTH / 2, -HEIGHT / 2, 0); + glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition); + } + glPopMatrix(); + + glPushMatrix(); + { + glTranslatef(WIDTH / 2, HEIGHT / 2, 0); + glRotatef(xangle, 0, 1, 0); + glRotatef(yangle, 1, 0, 0); + glTranslatef(-WIDTH / 2, -HEIGHT / 2, 0); + DrawPosts(); + DrawDooDads(); + } + glPopMatrix(); + if (motion && moves.depth) { + t = moves.head->t; + f = moves.head->f; + push(t, pop(f)); + mpop(); + } + glutSwapBuffers(); +} + +void +hanoi_menu(int value) +{ + switch (value) { + case HANOI_SOLVE: + motion = !motion; + if(motion) { + glutIdleFunc(update); + } else { + glutIdleFunc(NULL); + } + break; + case HANOI_LIGHTING: + if (glIsEnabled(GL_LIGHTING)) + glDisable(GL_LIGHTING); + else + glEnable(GL_LIGHTING); + break; + case HANOI_WALL: + back_wall = !back_wall; + break; + case HANOI_FOG: + if (glIsEnabled(GL_FOG)) + glDisable(GL_FOG); + else { + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, .01); + } + break; + case HANOI_QUIT: + exit(0); + break; + } + glutPostRedisplay(); +} + +int oldx, oldy; + +GLboolean leftb = GL_FALSE, middleb = GL_FALSE; + +void +hanoi_mouse(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON) { + oldx = x; + oldy = y; + if (state == GLUT_DOWN) + leftb = GL_TRUE; + else + leftb = GL_FALSE; + } + if (button == GLUT_MIDDLE_BUTTON) { + oldx = x; + oldy = y; + if (state == GLUT_DOWN) + middleb = GL_TRUE; + else + middleb = GL_FALSE; + } +} + +void +hanoi_visibility(int state) +{ + if (state == GLUT_VISIBLE && motion) { + glutIdleFunc(update); + } else { + glutIdleFunc(NULL); + } +} + +void +hanoi_motion(int x, int y) +{ + if (leftb) { + xangle -= (x - oldx); + yangle -= (y - oldy); + } + if (middleb) { + xlangle -= (x - oldx); + ylangle -= (y - oldy); + } + oldx = x; + oldy = y; + glutPostRedisplay(); +} + +int +main(int argc, char *argv[]) +{ + int i; + + glutInit(&argc, argv); + for(i=1; i= argc) { + printf("hanoi: number after -n is required\n"); + exit(1); + } + NUM_DISKS = atoi(argv[i]); + } + } + + glutInitWindowSize((int) WIDTH, (int) HEIGHT); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); + + glutCreateWindow("Hanoi"); + + glutDisplayFunc(draw); + glutKeyboardFunc(keyboard); + + glViewport(0, 0, (GLsizei) WIDTH, (GLsizei) HEIGHT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, WIDTH, 0, HEIGHT, -10000, 10000); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0); + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + +/* glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); */ + + glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition); + glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor); + glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 10); + glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, lightOneDirection); + glEnable(GL_LIGHT1); + + glLightfv(GL_LIGHT2, GL_POSITION, lightTwoPosition); + glLightfv(GL_LIGHT2, GL_DIFFUSE, lightTwoColor); +/* glLightf(GL_LIGHT2,GL_LINEAR_ATTENUATION,.005); */ + glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 10); + glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, lightTwoDirection); + glEnable(GL_LIGHT2); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor); + glEnable(GL_LIGHT0); + + glEnable(GL_LIGHTING); + + glutMouseFunc(hanoi_mouse); + glutMotionFunc(hanoi_motion); + glutVisibilityFunc(hanoi_visibility); + + glutCreateMenu(hanoi_menu); + glutAddMenuEntry("Solve", HANOI_SOLVE); + glutAddMenuEntry("Lighting", HANOI_LIGHTING); + glutAddMenuEntry("Back Wall", HANOI_WALL); + glutAddMenuEntry("Fog", HANOI_FOG); + glutAddMenuEntry("Quit", HANOI_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + init(); + + for (i = 0; i < NUM_DISKS; i++) + push(1, NUM_DISKS - i); + mov(NUM_DISKS, 1, 3); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/hanoi.dsp b/lib/glut-3.7.6/progs/contrib/hanoi.dsp new file mode 100644 index 0000000000..20abbbfcc7 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/hanoi.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="hanoi" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=hanoi - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "hanoi.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "hanoi.mak" CFG="hanoi - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "hanoi - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "hanoi - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "hanoi - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "hanoi - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "hanoi - Win32 Release" +# Name "hanoi - Win32 Debug" +# Begin Source File + +SOURCE=.\hanoi.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/hanoi2.c b/lib/glut-3.7.6/progs/contrib/hanoi2.c new file mode 100644 index 0000000000..ebe660196b --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/hanoi2.c @@ -0,0 +1,444 @@ +#include +#include +#include +#include +#include +#include +#include + +#define MAX_DISKS 6 + +#define DISK_HEIGHT 0.2 +#define CYL_RADIUS 0.1 +#define CYL_HEIGHT 1.8 +#define OVER_CLICKS 120 +#define UP_CLICKS 120 + +enum {X=0, Y, Z}; +enum {DL_POLE=1, DL_FLOOR, DL_DISK}; /* disk must be last */ + +/* motion states */ +enum {ST_UP=1, ST_TO_1, ST_TO_2, ST_DOWN, ST_READNEXT, ST_IDLE}; + +int motion = 1; +int spinning = 1; +int click = 0; +int delay = 0; +int direction; +int state=ST_READNEXT; +int c_pole; +int old_pole; +int c_disk; +int engine_fd; +int engine_pid; + +float pole_offset[3][2] = { { 0, -0.575 }, + { 1.15, 0.575 }, + { -1.15, 0.575 } }; +float disk_offset[MAX_DISKS][3] = {{ 0, -0.575, 0}, + { 0, -0.575, 0}, + { 0, -0.575, 0}, + { 0, -0.575, 0}, + { 0, -0.575, 0}, + { 0, -0.575, 0}}; +float disk_incr[3] = { 0, 0, 0 }; + +int num_disks; +struct { + int num_disks; + int disks[MAX_DISKS]; +} disks_on_poles[3]; + +/* + * create display list for disk of outside radius orad + */ +void +diskdlist(int dlist, float orad) +{ + GLUquadricObj *obj; + + obj = gluNewQuadric(); + if (obj == 0) { + perror("can't alloc quadric"); + exit(1); + } + glNewList(dlist, GL_COMPILE); + glPushMatrix(); + glColor4ub(205, 67, 100, 200); + gluQuadricDrawStyle(obj, GLU_FILL); + + gluQuadricOrientation(obj, GLU_OUTSIDE); + gluCylinder(obj, orad, orad, DISK_HEIGHT, 20, 4); + + gluQuadricOrientation(obj, GLU_INSIDE); + gluCylinder(obj, CYL_RADIUS, CYL_RADIUS, DISK_HEIGHT, 20, 4); + + gluQuadricOrientation(obj, GLU_INSIDE); + gluDisk(obj, CYL_RADIUS, orad, 20, 4); + + gluQuadricOrientation(obj, GLU_OUTSIDE); + glPushMatrix(); + glTranslatef(0.0, 0.0, DISK_HEIGHT); + gluDisk(obj, CYL_RADIUS, orad, 20, 4); + glPopMatrix(); + glPopMatrix(); + glEndList(); +} + +/* + * create display list for pole + */ +void +poledlist(int dlist) +{ + GLUquadricObj *obj; + + obj = gluNewQuadric(); + if (obj == 0) { + perror("can't alloc quadric"); + exit(1); + } + + glNewList(dlist, GL_COMPILE); + glPushMatrix(); + glColor3ub(67, 205, 128); + gluQuadricDrawStyle(obj, GLU_FILL); + gluQuadricOrientation(obj, GLU_OUTSIDE); + + gluCylinder(obj, CYL_RADIUS, CYL_RADIUS, CYL_HEIGHT, 12, 3); + + gluQuadricOrientation(obj, GLU_INSIDE); + gluDisk(obj, 0.0, CYL_RADIUS, 12, 3); + + gluQuadricOrientation(obj, GLU_OUTSIDE); + glPushMatrix(); + glTranslatef(0.0, 0.0, CYL_HEIGHT); + gluDisk(obj, 0.0, CYL_RADIUS, 12, 3); + glPopMatrix(); + glPopMatrix(); + glEndList(); + +} + +/* + * create display list for floor + */ +void +floordlist(int dlist) +{ + glNewList(dlist, GL_COMPILE); + glPushMatrix(); + glColor4ub(90, 100, 230,100); + + /* top/bottom */ + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(-2.0, -2.0, 0); + glVertex3f(2.0, -2.0, 0); + glVertex3f(-2.0, 2.0, 0); + glVertex3f(2.0, 2.0, 0); + glEnd(); + glPushMatrix(); + glTranslatef(0, 0, -0.2); + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(2.0, -2.0, 0); + glVertex3f(-2.0, -2.0, 0); + glVertex3f(2.0, 2.0, 0); + glVertex3f(-2.0, 2.0, 0); + glEnd(); + glPopMatrix(); + + /* edges */ + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(-2.0, -2.0, -0.2); + glVertex3f(-2.0, -2.0, 0); + glVertex3f(-2.0, 2.0, -0.2); + glVertex3f(-2.0, 2.0, 0); + glNormal3f(0.0, 1.0, 0.0); + glVertex3f(2.0, 2.0, -0.2); + glVertex3f(2.0, 2.0, 0); + glNormal3f(1.0, 0.0, 0.0); + glVertex3f(2.0, -2.0, -0.2); + glVertex3f(2.0, -2.0, 0); + glNormal3f(0.0, -1.0, 0.0); + glVertex3f(-2.0, -2.0, -0.2); + glVertex3f(-2.0, -2.0, 0); + glEnd(); + glPopMatrix(); + glEndList(); +} + +/* + * motion state machine -- idle loop + */ +void +idle(void) +{ + static int over_clicks; + int rc; + char next_move[3]; + + if (spinning) + click++; + + if (motion) { + switch(state) { + case ST_READNEXT: + /* + * read an instruction from the hanoi engine + */ + rc = read(engine_fd, next_move, 3); + if (rc == 3 && next_move[0] == 'M') { + /* choose poles/disks to move */ + old_pole = next_move[1]; + c_pole = next_move[2]; + c_disk = disks_on_poles[old_pole].disks[disks_on_poles[old_pole].num_disks - 1]; + state = ST_UP; + disk_incr[Z] = CYL_HEIGHT / (float)UP_CLICKS; + } + else if (rc == 3 && next_move[0] == 'D') { + state = ST_IDLE; + } + else if (rc != 0) { + fprintf(stderr,"bad read; %d, [%d%d%d]\n", + rc, next_move[0], next_move[1], next_move[2]); + exit(1); + } + /* if rc == 0, do nothing this frame */ + break; + + case ST_UP: + disk_offset[c_disk][Z] += disk_incr[Z]; + if (disk_offset[c_disk][Z] >= (CYL_HEIGHT+0.1)) { + state = ST_TO_1; + over_clicks = OVER_CLICKS; + disk_incr[X] = (pole_offset[c_pole][X] + - pole_offset[old_pole][X]) / (float)(over_clicks-1); + disk_incr[Y] = (pole_offset[c_pole][Y] + - pole_offset[old_pole][Y]) / (float)(over_clicks-1); + disk_incr[Z] = 0.0; + } + break; + + case ST_DOWN: + disk_offset[c_disk][Z] -= disk_incr[Z]; + if (disk_offset[c_disk][Z] <= (disks_on_poles[c_pole].num_disks*0.2+disk_incr[Z])) { + disk_offset[c_disk][Z] = disks_on_poles[c_pole].num_disks*0.2; + disks_on_poles[old_pole].num_disks --; + disks_on_poles[c_pole].disks[disks_on_poles[c_pole].num_disks ++] = c_disk; + state = ST_READNEXT; + } + break; + + case ST_TO_1: + case ST_TO_2: + disk_offset[c_disk][X] += disk_incr[X]; + disk_offset[c_disk][Y] += disk_incr[Y]; + over_clicks --; + if (over_clicks == 0) { + state = ST_DOWN; + disk_incr[X] = 0.0; + disk_incr[Y] = 0.0; + disk_incr[Z] = CYL_HEIGHT / (float)UP_CLICKS; + disk_offset[c_disk][X] = pole_offset[c_pole][X]; /* paranoia */ + disk_offset[c_disk][Y] = pole_offset[c_pole][Y]; + } + break; + + case ST_IDLE: + break; + } + } + glutPostRedisplay(); +} + +void +draw_scene(void) +{ + int i; + glPushMatrix(); + glRotatef(click, 0, 0, 1); + glRotatef(click/5.0, 1, 0, 0); + for (i=0; i<3; i++) { + glPushMatrix(); + glTranslatef(pole_offset[i][X], pole_offset[i][Y], 0); + glCallList(DL_POLE); + glPopMatrix(); + } + for(i=0; i MAX_DISKS) { + num_disks = MAX_DISKS; + } + break; + case 's': + spinning = atoi(optarg) ? 1 : 0; + break; + case 'm': + motion = atoi(optarg) ? 1 : 0; + break; + default: + break; + } + } + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("Hanoi"); + glutDisplayFunc(display); + glutVisibilityFunc(visible); + glMatrixMode(GL_PROJECTION); + gluPerspective(40.0, 1.0, 0.1, 10.0); + glMatrixMode(GL_MODELVIEW); + gluLookAt(0, 5.5, 3.5, + 0, 0, 0, + 0, 0, 1); + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); +#ifndef TOOSLOW + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + glEnable(GL_COLOR_MATERIAL); +#endif +#ifndef TOOSLOW + glShadeModel(GL_SMOOTH); +#endif + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); +#ifndef TOOSLOW + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +#endif + glDepthFunc(GL_LEQUAL); + glClearColor(0.3, 0.3, 0.3, 0.0); +#ifndef TOOSLOW + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif + + glPolygonMode(GL_FRONT, GL_FILL); + + glutCreateMenu(menu); + glutAddMenuEntry("Toggle motion", 2); + glutAddMenuEntry("Toggle spinning", 3); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); +#if defined(GL_POLYGON_OFFSET_EXT) + if (glutExtensionSupported("GL_EXT_polygon_offset")) { + glPolygonOffsetEXT(0.5, 0.0); + glEnable(GL_POLYGON_OFFSET_EXT); + } +#endif + + poledlist(DL_POLE); + floordlist(DL_FLOOR); + + disks_on_poles[0].num_disks = num_disks; + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=hanoi2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "hanoi2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "hanoi2.mak" CFG="hanoi2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "hanoi2 - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "hanoi2 - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "hanoi2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "hanoi2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "hanoi2___Win32_Debug" +# PROP BASE Intermediate_Dir "hanoi2___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "hanoi2 - Win32 Release" +# Name "hanoi2 - Win32 Debug" +# Begin Source File + +SOURCE=.\engine.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\hanoi2.c +# PROP Exclude_From_Build 1 +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/lineblend.c b/lib/glut-3.7.6/progs/contrib/lineblend.c new file mode 100644 index 0000000000..a844ce2a67 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/lineblend.c @@ -0,0 +1,257 @@ + +/* lineblend.c + * + * To compile: cc -o lineblend lineblend.c -lGL -lGLU -lX11 -lglut -lXmu + * + * Usage: lineblend + * + * This is an puffed up version of the first GL assignment we had for my + * graphics class: write a 2-d openGL program w/ color and interactivity. + * + * Left and middle buttons drawn colored lines, right button brings up a menu + * with a few options. If you draw for long enough and then hit pick + * "redraw" (or resize or uncover the window) it takes so long to redraw + * all the lines it is kind of like a kaleidoscope animation. Or something. + * + * Philip Winston - 2/11/95 (modified: 2/12) + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + * + */ + +#include + +#include +#include + +#ifdef _WIN32 +#define drand48() (((float) rand())/((float) RAND_MAX)) +#endif + +typedef enum {MENU_ALPHA_1, MENU_ALPHA_2, MENU_ALPHA_3, MENU_ALPHA_4, + MENU_COLOR_1, MENU_COLOR_2, MENU_COLOR_3, MENU_COLOR_4, + MENU_ANTI_ON, MENU_ANTI_OFF, + MENU_ERASE, MENU_REDRAW, MENU_QUIT} MenuChoices; + +typedef enum {SC1, SC2, SC3, SC4} ColorScheme; + +int wwidth, wheight, downbtn = -1, downx, downy; + +GLuint DispLists = 1; + +GLfloat Alpha = 0.2; +int Color = SC1; + +void myglInit(void) +{ + glLineWidth(10.0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-0.5,0.5,-0.5,0.5); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glFlush(); +} + +void myreshape(GLsizei w, GLsizei h) +{ + wwidth = w; wheight = h; + glViewport(0,0,w,h); + glClear(GL_COLOR_BUFFER_BIT); + glFlush(); +} + +void mydisplay(void) +{ + GLuint i; + + glClear(GL_COLOR_BUFFER_BIT); + + for (i = 0; i < DispLists; i++) + glCallList(i); + + glFlush(); +} + +void drawline(int x, int y) +{ + GLfloat fx = (float)(x - downx)/wwidth, + fy = -((float)(y - downy)/wheight), + r1, g1, b1, r2, g2, b2; + + switch(Color) { /* four different ways to pick colors */ + case SC1: /* just kind of random formulas... */ + r1 = fy+1; g1 = 0; b1 = (float)x/wwidth; + r2 = 0; g2 = fy+1; b2 = 1-(float)x/wwidth; + break; + case SC2: + r1 = fx+fy+1; g1 = 0; b1 = 0; + r2 = 0; g2 = fx+fy+1; b2 = 0; + break; + case SC3: + r1 = 0; g1 = (float)downx/wwidth; b1 = (float)x/wwidth; + r2 = 0; g2 = (float)y/wheight; b2 = (float)downy/wheight; + break; + case SC4: + r1 = drand48(); g1 = drand48(); b1 = (float)downx/(wwidth*1.5); + r2 = drand48(); g2 = (float)downy/(wheight*1.5); b2 = drand48(); + break; + } + + + glBegin(GL_LINES); + glColor4f(r1, g1, b1, Alpha); + switch(downbtn) { + case GLUT_LEFT_BUTTON: glVertex2f(0,0); break; + case GLUT_MIDDLE_BUTTON: glVertex2f(-fx,-fy); break; + } + glColor4f(r2, g2, b2, Alpha); glVertex2f(fx,fy); + glEnd(); + + glFlush(); +} + +void mousebutton(int btn, int state, int x, int y) +{ + GLfloat fx = (float)x/wwidth - 0.5, + fy = -(float)y/wheight + 0.5; + + if (state == GLUT_DOWN && downbtn == -1) { + glNewList(DispLists++, GL_COMPILE_AND_EXECUTE); + glPushMatrix(); + glTranslatef(fx, fy, 0); + downbtn = btn; + downx = x; + downy = y; + drawline(x, y); + } else if (state == GLUT_UP && btn == downbtn) { + glPopMatrix(); + glEndList(); + downbtn = -1; + } +} + +/* + * For some reason I felt like doing these check boxes -- it is kind of + * lame the way I did it, though. Probably a smarter and easier way. + */ + +void handlealphamenu(int value) +{ + glutChangeToMenuEntry(1,"[ ] 0.05", MENU_ALPHA_1); + glutChangeToMenuEntry(2,"[ ] 0.20", MENU_ALPHA_2); + glutChangeToMenuEntry(3,"[ ] 0.50", MENU_ALPHA_3); + glutChangeToMenuEntry(4,"[ ] 1.00", MENU_ALPHA_4); + switch (value) { + case MENU_ALPHA_1: + glutChangeToMenuEntry(1, "[ * ] 0.05", MENU_ALPHA_1); + Alpha = 0.05; break; + case MENU_ALPHA_2: + glutChangeToMenuEntry(2, "[ * ] 0.20", MENU_ALPHA_2); + Alpha = 0.2; break; + case MENU_ALPHA_3: + glutChangeToMenuEntry(3, "[ * ] 0.50", MENU_ALPHA_3); + Alpha = 0.5; break; + case MENU_ALPHA_4: + glutChangeToMenuEntry(4, "[ * ] 1.00", MENU_ALPHA_4); + Alpha = 1.0; break; + } +} + +void handlecolormenu(int value) +{ + glutChangeToMenuEntry(1,"[ ] Various", MENU_COLOR_1); + glutChangeToMenuEntry(2,"[ ] Red/Green ", MENU_COLOR_2); + glutChangeToMenuEntry(3,"[ ] Blue/Green", MENU_COLOR_3); + glutChangeToMenuEntry(4,"[ ] Random", MENU_COLOR_4); + switch (value) { + case MENU_COLOR_1: + glutChangeToMenuEntry(1, "[ * ] Various", MENU_COLOR_1); + Color = SC1; break; + case MENU_COLOR_2: + glutChangeToMenuEntry(2, "[ * ] Red/Green", MENU_COLOR_2); + Color = SC2; break; + case MENU_COLOR_3: + glutChangeToMenuEntry(3, "[ * ] Blue/Green", MENU_COLOR_3); + Color = SC3; break; + case MENU_COLOR_4: + glutChangeToMenuEntry(4, "[ * ] Random", MENU_COLOR_4); + Color = SC4; break; + } +} + +void handlemenu(int value) +{ + switch (value) { + case MENU_ANTI_OFF: + glDisable(GL_LINE_SMOOTH); + glutChangeToMenuEntry(3, "anti-aliasing [NO]", MENU_ANTI_ON); + break; + case MENU_ANTI_ON: + glEnable(GL_LINE_SMOOTH); + glutChangeToMenuEntry(3, "anti-aliasing [YES]", MENU_ANTI_OFF); + break; + case MENU_REDRAW: + glutPostRedisplay(); + break; + case MENU_ERASE: + glDeleteLists(0, DispLists); + DispLists = 1; + mydisplay(); + break; + case MENU_QUIT: + exit(0); + break; + } +} + +void myMenuInit(void) +{ + int sub1,sub2,sub3; + + sub3 = glutCreateMenu(handlealphamenu); + glutAddMenuEntry("[ ] 0.05", MENU_ALPHA_1); + glutAddMenuEntry("[ * ] 0.20", MENU_ALPHA_2); + glutAddMenuEntry("[ ] 0.50", MENU_ALPHA_3); + glutAddMenuEntry("[ ] 1.00", MENU_ALPHA_4); + sub2 = glutCreateMenu(handlecolormenu); + glutAddMenuEntry("[ * ] Various", MENU_COLOR_1); + glutAddMenuEntry("[ ] Red/Green", MENU_COLOR_2); + glutAddMenuEntry("[ ] Blue/Green", MENU_COLOR_3); + glutAddMenuEntry("[ ] Random", MENU_COLOR_4); + sub1 = glutCreateMenu(handlemenu); + glutAddSubMenu("Colors", sub2); + glutAddSubMenu("Alpha", sub3); + glutAddMenuEntry("anti-aliasing [NO]", MENU_ANTI_ON); + glutCreateMenu(handlemenu); + glutAddSubMenu("Lines", sub1); + glutAddMenuEntry("Erase", MENU_ERASE); + glutAddMenuEntry("Redraw", MENU_REDRAW); + glutAddMenuEntry("Quit", MENU_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutCreateWindow("lineblend"); + + myglInit(); + myMenuInit(); + + glutReshapeFunc(myreshape); + glutMouseFunc(mousebutton); + glutMotionFunc(drawline); + glutDisplayFunc(mydisplay); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + diff --git a/lib/glut-3.7.6/progs/contrib/lineblend.dsp b/lib/glut-3.7.6/progs/contrib/lineblend.dsp new file mode 100644 index 0000000000..ad2725848e --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/lineblend.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="lineblend" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=lineblend - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lineblend.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lineblend.mak" CFG="lineblend - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lineblend - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "lineblend - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lineblend - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "lineblend - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lineblend - Win32 Release" +# Name "lineblend - Win32 Debug" +# Begin Source File + +SOURCE=.\lineblend.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/moth.c b/lib/glut-3.7.6/progs/contrib/moth.c new file mode 100644 index 0000000000..2ba2affaad --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/moth.c @@ -0,0 +1,1372 @@ +/* + "moth" by Robert Doyle, Naval Research Laboratory, Washington, DC. + Scene objects are built into display lists in the 'myInit' function + (look for three rows of I's). Objects are assembled and motion + described in the 'display' function (look for three rows of $'s). +*/ +#include +#include +#include +#include +#include + +GLfloat wall_color[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat wall_ambient[] = {0.5, 0.5, 0.5, 1.0}; +GLfloat floor_color[] = {0.5, 1.0, 0.5, 0.5}; +GLfloat column_color[] = {1.0, 0.0, 0.0, 1.0}; +GLfloat column_ambient[] = {0.25, 0.0, 0.0, 1.0}; + +GLfloat panel_color[] = {0.1, 0.1, 1.0, 1.0}; +GLfloat panel_ambient[] = {0.01, 0.01, 0.3, 1.0}; + +GLfloat lamp_ambient[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat lamp_diffuse[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat lamp_specular[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat lamp_post_diffuse[] = {0.8, 0.0, 0.0, 1.0}; +GLfloat lamp_post_specular[] = {0.8, 0.0, 0.0, 1.0}; +GLfloat lamp_post_ambient[] = {0.25, 0.0, 0.0, 1.0}; + +GLfloat satellite_diffuse[] = {1.0, 0.69, 0.0, 1.0}; +GLfloat satellite_shiny[] = {128.0}; +GLfloat satellite_specular[] = {1.0, 1.0, 1.0, 1.0}; +GLfloat satellite_ambient[] = {0.37, 0.25, 0.0, 1.0}; + +GLfloat cube_color[] = {1.0, 1.0, 0.0, 1.0}; +GLfloat cube_shiny[] = {99.0}; +GLfloat cube_specular[] = {0.9, 0.9, 0.9, 1.0}; +GLfloat cube_ambient[] = {0.1, 0.1, 0.1, 1.0}; + +GLfloat shadow_ambient[] = {0.0, 0.0, 0.0, 1.0}; +GLfloat shadow_diffuse[] = {0.0, 0.0, 0.0, 0.3}; +GLfloat shadow_shiny[] = {0.0}; +GLfloat shadow_specular[] = {0.0, 0.0, 0.0, 1.0}; + +GLuint column = 3; +GLuint ground_shadow_matrix = 16; +GLuint left_wall_shadow_matrix = 17; +GLuint ground = 30; +GLuint left_wall = 40; +GLuint right_wall = 50; +GLuint four_columns = 7; +GLuint two_columns = 32; +GLuint satellite1 = 301; +GLuint satellite2 = 302; +GLuint panel1 = 303; +GLuint panel2 = 304; + +static GLfloat Tx = -0.01; +static GLfloat Ty = -0.01; +static GLfloat Tz = -0.02; +#if 0 +static GLfloat mvt_zi = -0.7; +#endif +#if 0 +static GLfloat mvt_x = 0.0; +static GLfloat mvt_y = 0.0; +static GLfloat mvt_z = -0.7; +#endif + +static GLfloat mvt_x = -15.0; +static GLfloat mvt_y = -15.0; +static GLfloat mvt_z = -30.7; + +/*static GLfloat Rx = 0.1; +static GLfloat mvr_d = 0.0; +static GLfloat mvr_x = 1.0; +static GLfloat mvr_y = -1.0; +static GLfloat mvr_z = -1.0;*/ + +static GLfloat Rx = 0.1; +static GLfloat mvr_d = 150.0; +static GLfloat mvr_x = 1.0; +static GLfloat mvr_y = -1.0; +static GLfloat mvr_z = -1.0; + +GLfloat cubeXform[4][4]; +GLfloat column1Xform[4][4]; +GLfloat column2Xform[4][4]; +GLfloat column3Xform[4][4]; +GLfloat four_columnsXform[4][4]; + +/*static GLint nest[1];*/ +static float shadowMat_ground[4][4]; +static float shadowMat_left[4][4]; +static float shadowMat_back[4][4]; +static float shadowMat_column[4][4]; +static float shadowMat_right[4][4]; + +static float shadowMat1_ground[4][4]; +static float shadowMat1_left[4][4]; +static float shadowMat1_back[4][4]; +static float shadowMat1_right[4][4]; + +static int useDB = 1; + +static int tick = -1; +static int moving = 1; + +#if 0 +static float lmodel_ambient[4] = {0.2, 0.2, 0.2, 1.0}; +#endif +static float lightPos[4] = {1.0, 2.5, 3.0, 1.0}; +#if 0 +static float lightDir[4] = {-2.0, -4.0, -2.0, 1.0}; +static float lightAmb[4] = {0.2, 0.2, 0.2, 1.0}; +static float lightDiff[4] = {0.3, 0.3, 0.3, 1.0}; +static float lightSpec[4] = {0.4, 0.4, 0.4, 1.0}; +#endif + +static float light1Pos[4] = {0.0, 1.6, -5.0, 1.0}; +static float light1Amb[4] = {1.0, 1.0, 1.0, 1.0}; +static float light1Diff[4] = {1.0, 1.0, 1.0, 1.0}; +static float light1Spec[4] = {1.0, 1.0, 1.0, 1.0}; + +static float leftPlane[4] = {1.0, 0.0, 0.0, 4.88}; /* X = -4.88 */ +static float rightPlane[4] = {-1.0, 0.0, 0.0, 4.88}; /* X = 4.98 */ +static float groundPlane[4] = {0.0, 1.0, 0.0, 1.450}; /* Y = -1.480 */ +static float columnPlane[4] = {0.0, 0.0, 1.0, 0.899}; /* Z = -0.899 */ +static float backPlane[4] = {0.0, 0.0, 1.0, 8.98}; /* Z = -8.98 */ + +#define S 0.7071 +#define NS 0.382683 +#define NC 0.923880 + +/* satellite body. */ +static float oct_vertices[8][3][4] = +{ + { + {0.0, 0.0, 0.0, 1.0}, + {0.0, 1.0, 0.0, 1.0}, + {-S, S, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {-S, S, 0.0, 1.0}, + {-1.0, 0.0, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {-1.0, 0.0, 0.0, 1.0}, + {-S, -S, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {-S, -S, 0.0, 1.0}, + {0.0, -1.0, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {0.0, -1.0, 0.0, 1.0}, + {S, -S, 0.0, 1.0}}, + + { + + {0.0, 0.0, 0.0, 1.0}, + {S, -S, 0.0, 1.0}, + {1.0, 0.0, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {1.0, 0.0, 0.0, 1.0}, + {S, S, 0.0, 1.0}}, + + { + {0.0, 0.0, 0.0, 1.0}, + {S, S, 0.0, 1.0}, + {0.0, 1.0, 0.0, 1.0}} + +}; + +static float oct_side_vertices[8][4][4] = +{ + { + {-S, S, 0.0, 1.0}, + {0.0, 1.0, 0.0, 1.0}, + {0.0, 1.0, -1.0, 1.0}, + {-S, S, -1.0, 1.0}}, + + { + {-1.0, 0.0, 0.0, 1.0}, + {-S, S, 0.0, 1.0}, + {-S, S, -1.0, 1.0}, + {-1.0, 0.0, -1.0, 1.0}}, + + { + {-S, -S, 0.0, 1.0}, + {-1.0, 0.0, 0.0, 1.0}, + {-1.0, 0.0, -1.0, 1.0}, + {-S, -S, -1.0, 1.0}}, + + { + {0.0, -1.0, 0.0, 1.0}, + {-S, -S, 0.0, 1.0}, + {-S, -S, -1.0, 1.0}, + {0.0, -1.0, -1.0, 1.0}}, + + { + {S, -S, 0.0, 1.0}, + {0.0, -1.0, 0.0, 1.0}, + {0.0, -1.0, -1.0, 1.0}, + {S, -S, -1.0, 1.0}}, + + { + {1.0, 0.0, 0.0, 1.0}, + {S, -S, 0.0, 1.0}, + {S, -S, -1.0, 1.0}, + {1.0, 0.0, -1.0, 1.0}}, + + { + {S, S, 0.0, 1.0}, + {1.0, 0.0, 0.0, 1.0}, + {1.0, 0.0, -1.0, 1.0}, + {S, S, -1.0, 1.0}}, + + { + {0.0, 1.0, 0.0, 1.0}, + {S, S, 0.0, 1.0}, + {S, S, -1.0, 1.0}, + {0.0, 1.0, -1.0, 1.0}} + +}; + +static float oct_side_normals[8][3] = +{ + {-NS, NC, 0.0}, + {-NC, NS, 0.0}, + {-NC, -NS, 0.0}, + {-NS, -NC, 0.0}, + {NS, -NC, 0.0}, + {NC, -NS, 0.0}, + {NC, NS, 0.0}, + {NS, NC, 0.0} + +}; + +static float cube_vertexes[6][4][4] = +{ + { + {-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}, + {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 cube_normals[6][4] = +{ + {-1.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, 1.0, 0.0, 0.0}, + {0.0, 0.0, -1.0, 0.0}, + {0.0, 0.0, 1.0, 0.0} +}; + +static void usage(void) +{ + printf("\n"); + printf("usage: moth\n"); + printf("\n"); + printf(" Open_gl demo.\n"); + printf("\n"); + printf(" Options:\n"); + printf(" Press the right mouse button for very limited options.\n"); + printf("\n"); +#ifndef EXIT_FAILURE /* should be defined by ANSI C */ +#define EXIT_FAILURE 1 +#endif + exit(EXIT_FAILURE); +} + +/*!!!!!!!!!!!!!!!!!!!!!! ERRORS? !!!!!!!!!!!!!!!!!!!!*/ + +static void checkErrors(void) +{ + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); + } +} + +/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + +/*%%%%%%%%%%%%%%%%%%%% DRAW CUBE %%%%%%%%%%%%%%%%%%*/ + +static void +drawCube(GLfloat color[4], GLfloat ambient[4]) +{ + int i; + + glMaterialfv(GL_FRONT, GL_DIFFUSE, color); + glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + + for (i = 0; i < 6; ++i) { + glNormal3fv(&cube_normals[i][0]); + glBegin(GL_POLYGON); + glVertex4fv(&cube_vertexes[i][0][0]); + glVertex4fv(&cube_vertexes[i][1][0]); + glVertex4fv(&cube_vertexes[i][2][0]); + glVertex4fv(&cube_vertexes[i][3][0]); + glEnd(); + } +} + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/*OOOOOOOOOOO DRAW OCTOGON TOP OOOOOOOOOOOOO*/ + +static void drawOct(void) +{ + int i; + + for (i = 0; i < 8; ++i) { + glNormal3f(0.0, 0.0, 1.0); + glBegin(GL_TRIANGLE_FAN); + glVertex4fv(&oct_vertices[i][0][0]); + glVertex4fv(&oct_vertices[i][1][0]); + glVertex4fv(&oct_vertices[i][2][0]); + glEnd(); + } +} + +/*OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO*/ + +/*oooooooooooDRAW OCTOGON SIDES ooooooooo*/ + +static void drawOctSides(void) +{ + int i; + + for (i = 0; i < 8; ++i) { + glNormal3fv(&oct_side_normals[i][0]); + glBegin(GL_POLYGON); + glVertex4fv(&oct_side_vertices[i][0][0]); + glVertex4fv(&oct_side_vertices[i][1][0]); + glVertex4fv(&oct_side_vertices[i][2][0]); + glVertex4fv(&oct_side_vertices[i][3][0]); + glEnd(); + } +} + +/*ooooooooooooooooooooooooooooooooooooooo*/ + +/*SSSSSSSSSSSSSSSS DRAW SATELLITE BODY SSSSSSSSSSSSSSSSSSS*/ + +static void drawSatellite(GLfloat diffuse[4], GLfloat ambient[4], GLfloat specular[4], GLfloat shiny[1]) +{ + + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT, GL_SPECULAR, specular); + glMaterialfv(GL_FRONT, GL_SHININESS, shiny); + + + glPushMatrix(); + glScalef(0.3, 0.3, 0.9); + glPushMatrix(); + drawOctSides(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0, 0.0, 0.0); + drawOct(); + glPopMatrix(); + glPushMatrix(); + glRotatef(180, 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, 1.0); + drawOct(); + glPopMatrix(); + glPopMatrix(); +} + +/*SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS*/ + +/*PPPPPPPPPPPPPPPP DRAW SOLAR PANELS PPPPPPPPPPPP*/ + +static void drawPanels(GLfloat color[4], GLfloat ambient[4]) +{ + + glMaterialfv(GL_FRONT, GL_DIFFUSE, color); + glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + + glPushMatrix(); + glTranslatef(0.95, 0.0, -0.45); + glRotatef(45.0, 1.0, 0.0, 0.0); + glScalef(0.65, 0.20, 0.02); + drawCube(color, ambient); + glPopMatrix(); + +/* glPushMatrix(); + glTranslatef(0.95, 0.0, -0.45); + glTranslatef((1.3/3.0), 0.1, 0.01); + glRotatef(45.0, 1.0, 0.0, 0.0); + glScalef(0.65/3.2, 0.20/2.1, 0.08); + drawCube(color, ambient); + glPopMatrix(); +*/ + glPushMatrix(); + glTranslatef(-0.95, 0.0, -0.45); + glRotatef(45.0, 1.0, 0.0, 0.0); + glScalef(0.65, 0.20, 0.02); + drawCube(color, ambient); + glPopMatrix(); + +} +/*PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP*/ + +/*################ DRAW FLOOR ################*/ + +void drawFloor(GLfloat f_color[4], GLfloat ambient[4]) +{ + + glMaterialfv(GL_FRONT, GL_DIFFUSE, f_color); + glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + +/* glNormal3f (0.0, 0.0, 1.0); */ + + glBegin (GL_QUADS); + glVertex3f (-1.0, -1.0, 0.0); + glVertex3f (1.0, -1.0, 0.0); + glVertex3f (1.0, 1.0, 0.0); + glVertex3f (-1.0, 1.0, 0.0); + glEnd(); + +} + +/*################################################*/ + +/*||||||||||||||| DRAW GROUND |||||||||||||||||*/ + +/* Ground coordinates are in drawGround() below. Subdivision */ +/* of triangles id done by subDivide(). */ + + +void subDivide(float u1[3], float u2[3], float u3[3], int depth) +{ + +GLfloat u12[3]; +GLfloat u23[3]; +GLfloat u31[3]; + +GLint i; + + if(depth == 0) { + + glBegin (GL_POLYGON); + glNormal3f (0.0, 0.0, 1.0); glVertex3fv(u1); + glNormal3f (0.0, 0.0, 1.0); glVertex3fv(u2); + glNormal3f (0.0, 0.0, 1.0); glVertex3fv(u3); + glEnd(); + return; +} + + for(i = 0; i < 3; i++){ + + u12[i] = (u1[i] + u2[i]) / 2.0; + u23[i] = (u2[i] + u3[i]) / 2.0; + u31[i] = (u3[i] + u1[i]) / 2.0; + + } + + subDivide(u1, u12, u31, depth - 1); + subDivide(u2, u23, u12, depth - 1); + subDivide(u3, u31, u23, depth - 1); + subDivide(u12, u23, u31, depth - 1); + +} + +void drawGround(void) +{ + +/* Use two subdivided triangles for the unscaled 1X1 square. */ +/* Subdivide to this depth: */ + +GLint maxdepth = 2; + +/* Coordinates of first triangle: */ + +GLfloat u1[] = {-1.0, -1.0, 0.0}; +GLfloat u2[] = {1.0, -1.0, 0.0}; +GLfloat u3[] = {1.0, 1.0, 0.0}; + +/* Coordinates of second triangle: */ + +GLfloat v1[] = {-1.0, -1.0, 0.0}; +GLfloat v2[] = {1.0, 1.0, 0.0}; +GLfloat v3[] = {-1.0, 1.0, 0.0}; + + subDivide(u1, u2, u3, maxdepth); + subDivide(v1, v2, v3, maxdepth); + +} + + +/*|||||||||||||||||||||||||||||||||||||||||||*/ + +/* Matrix for shadow. From Mark Kilgard's "scube". */ + +static void +myShadowMatrix(float ground[4], float light[4], float shadowMat[4][4]) +{ + float dot; +/* float shadowMat[4][4]; */ + + dot = ground[0] * light[0] + + ground[1] * light[1] + + ground[2] * light[2] + + ground[3] * light[3]; + + shadowMat[0][0] = dot - light[0] * ground[0]; + shadowMat[1][0] = 0.0 - light[0] * ground[1]; + shadowMat[2][0] = 0.0 - light[0] * ground[2]; + shadowMat[3][0] = 0.0 - light[0] * ground[3]; + + shadowMat[0][1] = 0.0 - light[1] * ground[0]; + shadowMat[1][1] = dot - light[1] * ground[1]; + shadowMat[2][1] = 0.0 - light[1] * ground[2]; + shadowMat[3][1] = 0.0 - light[1] * ground[3]; + + shadowMat[0][2] = 0.0 - light[2] * ground[0]; + shadowMat[1][2] = 0.0 - light[2] * ground[1]; + shadowMat[2][2] = dot - light[2] * ground[2]; + shadowMat[3][2] = 0.0 - light[2] * ground[3]; + + shadowMat[0][3] = 0.0 - light[3] * ground[0]; + shadowMat[1][3] = 0.0 - light[3] * ground[1]; + shadowMat[2][3] = 0.0 - light[3] * ground[2]; + shadowMat[3][3] = dot - light[3] * ground[3]; + +/* glMultMatrixf((const GLfloat *) shadowMat); */ +} + +void +idle(void) +{ + tick++; + if (tick >= 60) { + tick = 0; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char ch, int x, int y) +{ + switch (ch) { + case 27: /* escape */ + exit(0); + break; + case ' ': + if (!moving) { + idle(); + glutPostRedisplay(); + } + } +} + +/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ +/*$$$$$$$$$$$$$$$$$$$$$$ DISPLAY $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ +/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ + +void display(void) +{ + + + glPushMatrix(); /* Make sure the matrix stack is cleared at the end of this function. */ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + +/*@@@@@@ Rotation and Translation of Entire Scene @@@@@*/ + + if(mvt_x < 0 && mvt_y < 0){ + glTranslatef(mvt_x ,mvt_y ,mvt_z ); + mvt_x = mvt_x - Tx; + mvt_y = mvt_y - Ty; + mvt_z = mvt_z - Tz; + + glRotatef(mvr_d, mvr_x, mvr_y, mvr_z); + mvr_d = mvr_d - Rx; + } + + else{ + glTranslatef(0.0, 0.0 ,mvt_z); + } + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +glPushMatrix(); + glLightfv(GL_LIGHT1, GL_POSITION, light1Pos); +glPopMatrix(); +/*______________________ Draw Floor _______________________*/ + +glPushMatrix(); + glCallList(ground); +glPopMatrix(); + +/*_________________________________________________________*/ + +/*@@@@@@@@@ Draw Lamp Post amd Lamp @@@@@@@@@@*/ + +glPushMatrix(); + glCallList(21); +glPopMatrix(); + +glPushMatrix(); + glCallList(22); +glPopMatrix(); + +glPushMatrix(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glCallList(501); + glDisable(GL_BLEND); +glPopMatrix(); + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/*||||||||||||||||||| Draw Left Wall ||||||||||||||||||*/ + + glCallList(left_wall); + +/*|||||||||||||||||||||||||||||||||||||||||||||||||||||*/ + +/*\\\\\\\\\\\\\\\\ Draw Right Wall \\\\\\\\\\\\\\*/ + + glCallList(right_wall); + +/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +/*[[[[[[[[[[[[[[[[[[[ Draw Columns ]]]]]]]]]]]]]]]]]]]*/ + +/***** Place columns at front of scene. *****/ + + glCallList(four_columns); + +/***** Place columns at back of scene. *****/ + + glPushMatrix(); + glTranslatef(0.0, 0.0, -9.0); + glCallList(four_columns); + glPopMatrix(); + +/***** Place columns at centers of left and right walls. *****/ + + glCallList(two_columns); + +/*[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]*/ + + +/*....................... Draw Column Shadows ....................*/ + +/*glDepthMask(GL_FALSE); +glEnable(GL_BLEND); +glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);*/ + +/* shadows on floor */ + +/* glPushMatrix(); + glCallList(100); + glPopMatrix();*/ + +/* shdows on left wall */ + +/* glPushMatrix(); + glCallList(101); + glPopMatrix();*/ + +/* shdows on back wall */ + +/* glPushMatrix(); + glCallList(102); + glPopMatrix();*/ + +/* shdows on right wall */ + +/* glPushMatrix(); + glCallList(103); + glPopMatrix();*/ + +/*glDepthMask(GL_TRUE); +glDisable(GL_BLEND);*/ + +/*................................................................*/ + +/************************* CUBE ***********************/ + + glMaterialf(GL_FRONT, GL_SHININESS, 99.0); + glMaterialfv(GL_FRONT, GL_SPECULAR, cube_specular); + + glPushMatrix(); + glTranslatef(0.0, 0.0, -5.0); + glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0); + glPushMatrix(); + glTranslatef(0.0, 0.2, 2.0); +/* glTranslatef(0.0, 0.2, 0.0); */ +/* glScalef(0.3, 0.3, 0.3); */ + glRotatef((360.0 / (30 * 1)) * tick, 1, 0, 0); + glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0); + glRotatef((360.0 / (30 * 4)) * tick, 0, 0, 1); + + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform); + +/* drawSatellite(satellite_diffuse, satellite_ambient, satellite_specular, satellite_shiny); */ + glCallList(satellite1); + glCallList(panel1); +/* drawPanels(panel_color, panel_ambient); */ + + glPopMatrix(); + glPopMatrix(); + + glMaterialf(GL_FRONT, GL_SHININESS, 0.0); + glMaterialfv(GL_FRONT, GL_SPECULAR, shadow_specular); + +/****************************************************/ + +/*................... CUBE SHADOWS .............................*/ + +/*glDepthMask(GL_FALSE);*/ +glEnable(GL_BLEND); +glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat1_ground); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) cubeXform); + + +/* drawSatellite(shadow_diffuse, shadow_ambient, shadow_specular, shadow_shiny); */ /* draw ground shadow */ + glCallList(satellite2); + glTranslatef(0.0, -.040, 0.0); + glCallList(panel2); +/* drawPanels(shadow_diffuse, shadow_ambient); */ + glPopMatrix(); + +/* Shadow left wall only if cube is in front of left wall. */ + if((tick*6) >= 220 && (tick*6) <= 320) { + + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat1_left); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) cubeXform); + drawSatellite(shadow_diffuse, shadow_ambient, shadow_specular, shadow_shiny); /* draw left shadow */ + drawPanels(shadow_diffuse, shadow_ambient); + glPopMatrix(); + + } + +/* Shadow back wall only if cube is in front of back wall. */ + if((tick*6) >= 125 && (tick*6) <= 330) { + + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat1_back); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) cubeXform); + drawSatellite(shadow_diffuse, shadow_ambient, shadow_specular, shadow_shiny); /* draw back wall shadow */ + drawPanels(shadow_diffuse, shadow_ambient); + glPopMatrix(); + + } + +/* Shadow right wall only if cube is in front of right wall. */ + if((tick*6) >= 40 && (tick*6) <= 145) { + + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat1_right); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) cubeXform); + drawSatellite(shadow_diffuse, shadow_ambient, shadow_specular, shadow_shiny); /* draw right wall shadow */ + drawPanels(shadow_diffuse, shadow_ambient); + glPopMatrix(); + + } + +/*glDepthMask(GL_TRUE);*/ +glDisable(GL_BLEND); + +/*.........................................................*/ + + glutSwapBuffers(); + + checkErrors(); + + glPopMatrix(); /* Clear the matrix stack */ + +} + +/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ + +void +menu_select(int mode) +{ + switch (mode) { + case 1: + moving = 1; + glutIdleFunc(idle); + break; + case 2: + moving = 0; + glutIdleFunc(NULL); + break; + case 5: + exit(0); + break; + } +} + +void +visible(int state) +{ + if (state == GLUT_VISIBLE) { + if (moving) + glutIdleFunc(idle); + } else { + if (moving) + glutIdleFunc(NULL); + } +} + +/* IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII*/ +/* IIIIIIIIIIIIIIIIII INITIALIZE IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII*/ +/* IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII*/ + +void myInit(void) +{ + +/* glGetIntegerv(GL_MAX_CLIP_PLANES, nest); + printf("GL_MAX_CLIP_PLANES are %d \n", nest[0]); */ + +/*%%%%%%%% Initialize Positional Light and Ambient Light %%%%%%%%*/ + +#if 0 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); +#endif + +#if 0 + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff); + glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec); + glEnable(GL_LIGHT0); +#endif + +/*** Initial light position is declared in the display function ***/ + + glLightfv(GL_LIGHT1, GL_AMBIENT, light1Amb); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light1Diff); + glLightfv(GL_LIGHT1, GL_SPECULAR, light1Spec); + glEnable(GL_LIGHT1); + + glEnable(GL_LIGHTING); + +/* glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.7);*/ +/* glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.04);*/ /* use 0.04 w/ 24 bit color */ + glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.07); /* try 0.07 w/ 24 bit color */ + + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/*########### Initialize Fog ##################*/ + +/* +{ + GLfloat fog_color[] = {0.5, 0.5, 0.5, 1.0}; + GLfloat fog_start[] = {0.0, 0.0, 1.0, 20.0}; + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogfv(GL_FOG_COLOR, fog_color); + glFogf(GL_FOG_DENSITY, 0.35); + glFogfv(GL_FOG_START, fog_start); + glHint(GL_FOG_HINT, GL_FASTEST); +} + +*/ + +/*##########################################*/ + +/*....Shadow Matrices For Floor, Left Wall, Back Wall, and Right Wall......*/ + + +/* For light0 */ + + myShadowMatrix(groundPlane, lightPos, shadowMat_ground); + myShadowMatrix(leftPlane, lightPos, shadowMat_left); + myShadowMatrix(columnPlane, lightPos, shadowMat_column); + myShadowMatrix(backPlane, lightPos, shadowMat_back); + myShadowMatrix(rightPlane, lightPos, shadowMat_right); + +/* For light1 */ + + myShadowMatrix(groundPlane, light1Pos, shadowMat1_ground); + myShadowMatrix(leftPlane, light1Pos, shadowMat1_left); + myShadowMatrix(backPlane, light1Pos, shadowMat1_back); + myShadowMatrix(rightPlane, light1Pos, shadowMat1_right); + +/*.......................................................................*/ + +/*sssssssssssssssss Make Satellite Body and Shadow ssssssssssssssssssssssss*/ + + glNewList(satellite1, GL_COMPILE); + glPushMatrix(); + drawSatellite(satellite_diffuse, satellite_ambient, satellite_specular, satellite_shiny); + glPopMatrix(); + glEndList(); + glNewList(satellite2, GL_COMPILE); + glPushMatrix(); + drawSatellite(shadow_diffuse, shadow_ambient, shadow_specular, shadow_shiny); + glPopMatrix(); + glEndList(); + +/*sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss*/ + +/*ppppppppppppppppppppppppppp Make Solar Panels and Shadows pppppppppppppppppp*/ + + glNewList(panel1, GL_COMPILE); + glPushMatrix(); + drawPanels(panel_color, panel_ambient); + glPopMatrix(); + glEndList(); + + glNewList(panel2, GL_COMPILE); + glPushMatrix(); + drawPanels(shadow_diffuse, shadow_ambient); + glPopMatrix(); + glEndList(); + + +/*pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp*/ + +/*========= Make Floor ==============*/ + + glNewList(ground, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_DIFFUSE, floor_color); + glMaterialfv(GL_FRONT, GL_AMBIENT, shadow_ambient); + glTranslatef(0.0, -1.5, -5.0); + glRotatef(-90.0, 1, 0, 0); + glScalef(5.0, 5.0, 1.0); + drawGround(); /* draw ground */ + glPopAttrib(); + glPopMatrix(); + glEndList(); + +/*==================================*/ + +/*@@@@@@@@@@ Make Lamp Post and Lamp @@@@@@@@@@@@*/ + + glNewList(21, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_AMBIENT, lamp_post_specular); + glTranslatef(0.0, -0.1, -5.0); + glScalef(0.07, 1.45, 0.07); + drawCube(lamp_post_diffuse, lamp_post_ambient); /* draw lamp post */ + glPopAttrib(); + glPopMatrix(); + glPushMatrix(); + glTranslatef(0.0, -1.45, -5.0); + glScalef(0.3, 0.05, 0.3); + drawCube(wall_color, cube_ambient); /* draw lamp post base */ + glPopMatrix(); + glEndList(); + + glNewList(22, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_AMBIENT, lamp_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, lamp_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, lamp_specular); + glTranslatef(0.0, 1.6, -5.0); + glutSolidSphere(0.3, 20.0, 20.0); /* draw lamp */ + glPopAttrib(); + glPopMatrix(); + glEndList(); + +/*** Lamp post base shadow ***/ + + glNewList(501, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_AMBIENT, shadow_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, shadow_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, shadow_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, shadow_shiny); + glTranslatef(0.0, -1.49, -5.0); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glScalef(0.7, 0.7, 1.0); + drawOct(); + glPopAttrib(); + glPopMatrix(); + glEndList(); + + + + + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/*||||||||||| Make Left Wall |||||||||||||*/ + + glNewList(left_wall, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_DIFFUSE, wall_color); + glMaterialfv(GL_FRONT, GL_AMBIENT, wall_ambient); + glTranslatef(0.0, -1.5, 0.0); + glTranslatef(0.0, 1.2, 0.0); + glTranslatef(0.0, 0.0, -5.0); + glTranslatef(-5.0, 0.0, 0.0); + glRotatef(90.0, 0, 1, 0); + glScalef(4.5, 1.2, 1.0); + glNormal3f (0.0, 0.0, 1.0); + drawGround(); /* draw left wall */ + glPopAttrib(); + glPopMatrix(); + glEndList(); + +/*||||||||||||||||||||||||||||||||||||||||*/ + +/*\\\\\\\\\\\\\ Make Right Wall \\\\\\\\\\\\\\\\\\\*/ + + glNewList(right_wall, GL_COMPILE); + glPushMatrix(); + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT, GL_DIFFUSE, wall_color); + glMaterialfv(GL_FRONT, GL_AMBIENT, wall_ambient); + glTranslatef(0.0, -1.5, 0.0); + glTranslatef(0.0, 1.2, 0.0); + + glTranslatef(0.0, 0.0, -5.0); + glTranslatef(5.0, 0.0, 0.0); + glRotatef(270.0, 0, 1, 0); + + glScalef(4.5, 1.2, 1.0); + glNormal3f (0.0, 0.0, 1.0); + drawGround(); /* draw right wall */ + glPopAttrib(); + glPopMatrix(); + glEndList(); + +/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ + +/*[[[[[[[[[[[ Build Columns ]]]]]]]]]]]*/ + +glPushMatrix(); + glNewList(1, GL_COMPILE); + glPushMatrix(); + glScalef(0.4, 1.4, 0.4); + drawCube(column_color, column_ambient); /* draw column1 */ + glPopMatrix(); + glEndList(); + + glNewList(2, GL_COMPILE); + glPushMatrix(); + glTranslatef(0.0, -1.45, 0.0); + glScalef(0.5, 0.1, 0.5); + drawCube(wall_color, cube_ambient); /* draw base */ + glPopMatrix(); + glPushMatrix(); + glTranslatef(0.0, 1.45, 0.0); + glScalef(0.5, 0.1, 0.5); + drawCube(wall_color, cube_ambient); /* draw top */ + glPopMatrix(); + glEndList(); +glPopMatrix(); + + glNewList(column, GL_COMPILE); + glPushMatrix(); + glCallList(1); + glCallList(2); + glPopMatrix(); + glEndList(); + +/***** Place columns at front of scene. *****/ + +glNewList(4, GL_COMPILE); + glPushMatrix(); + glTranslatef(-5.0, 0.0, -0.5); + glCallList(column); + glPopMatrix(); +glEndList(); + +glNewList(5, GL_COMPILE); + glPushMatrix(); + glTranslatef(-1.75, 0.0, -0.5); + glCallList(column); + glPopMatrix(); +glEndList(); + +glNewList(6, GL_COMPILE); + glPushMatrix(); + glTranslatef(1.75, 0.0, -0.5); + glCallList(column); + glPopMatrix(); +glEndList(); + +glNewList(17, GL_COMPILE); + glPushMatrix(); + glTranslatef(5.0, 0.0, -0.5); + glCallList(column); + glPopMatrix(); +glEndList(); + + +/*** Get the modelview matrix once ***/ + glPushMatrix(); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) four_columnsXform); + glPopMatrix(); + +glNewList(four_columns, GL_COMPILE); + glPushMatrix(); + glCallList(4); + glCallList(5); + glCallList(6); + glCallList(17); + glPopMatrix(); +glEndList(); + +/***** Make two columns for sides of scene *****/ + +glNewList(two_columns, GL_COMPILE); + glPushMatrix(); + glRotatef(90.0, 0.0, 1.0, 0.0); + glTranslatef(5.0, 0.0, -5.0); + glPushMatrix(); + glTranslatef(0.0, 0.0, -0.3); + glCallList(column); + glPopMatrix(); + glPushMatrix(); + glTranslatef(0.0, 0.0, 10.3); + glCallList(column); + glPopMatrix(); + glPopMatrix(); +glEndList(); + + + + +/*[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]*/ + + +/* .......................Make shadows .........................*/ + + glPushMatrix(); + glNewList(8, GL_COMPILE); + glPushMatrix(); + glScalef(0.4, 1.4, 0.4); + drawCube(shadow_diffuse, shadow_ambient); /* draw column1 */ + glPopMatrix(); + glEndList(); + + + glNewList(9, GL_COMPILE); + glPushMatrix(); + glTranslatef(0.0, -1.45, 0.0); + glScalef(0.5, 0.1, 0.5); + drawCube(shadow_diffuse, shadow_ambient); /* draw base. */ + glPopMatrix(); + glPushMatrix(); + glTranslatef(0.0, 1.45, 0.0); + glScalef(0.5, 0.1, 0.5); + drawCube(shadow_diffuse, shadow_ambient); /* draw top. */ + glPopMatrix(); + glEndList(); + glPopMatrix(); + + glNewList(10, GL_COMPILE); + glPushMatrix(); + glCallList(8); + glCallList(9); + glPopMatrix(); + glEndList(); + +glNewList(11, GL_COMPILE); + glPushMatrix(); + glTranslatef(-5.0, 0.0, -0.5); + glCallList(10); + glPopMatrix(); +glEndList(); + +glNewList(12, GL_COMPILE); + glPushMatrix(); + glTranslatef(-1.75, 0.0, -0.5); + glCallList(10); + glPopMatrix(); +glEndList(); + +glNewList(13, GL_COMPILE); + glPushMatrix(); + glTranslatef(1.75, 0.0, -0.5 ); + glCallList(10); + glPopMatrix(); +glEndList(); + +glNewList(14, GL_COMPILE); + glPushMatrix(); + glTranslatef(5.0, 0.0, -0.5 ); + glCallList(10); + glPopMatrix(); +glEndList(); + +glNewList(15, GL_COMPILE); + glPushMatrix(); + glCallList(11); + glCallList(12); + glCallList(13); + glCallList(14); + glPopMatrix(); +glEndList(); + +glNewList(100, GL_COMPILE); + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat_ground); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glMultMatrixf((const GLfloat *) four_columnsXform); + glCallList(15); + glPopMatrix(); +glEndList(); + +glNewList(101, GL_COMPILE); + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat_left); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glMultMatrixf((const GLfloat *) four_columnsXform); + glCallList(15); + glPopMatrix(); +glEndList(); + +glNewList(102, GL_COMPILE); + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat_back); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) four_columnsXform); + glCallList(15); + glPopMatrix(); +glEndList(); + +glNewList(103, GL_COMPILE); + glPushMatrix(); + glMultMatrixf((const GLfloat *) shadowMat_right); + glRotatef(-mvr_d, mvr_x, mvr_y, mvr_z); + glTranslatef(-mvt_x, -mvt_y, -mvt_z); /* correct for modelview matrix */ + glMultMatrixf((const GLfloat *) four_columnsXform); + glCallList(15); + glPopMatrix(); +glEndList(); + + +/* ......................................................*/ + +} + +/* IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII*/ + + +/* ////////////////////////////////////////////////////////////// */ +/* //////////////////////\ MAIN ///////////////////////////////// */ +/* ////////////////////////////////////////////////////////////// */ + +int main(int argc, char **argv) +{ + int width = 320, height = 240; + int i; + + char *name; + glutInitWindowSize(width, height); + glutInit(&argc, argv); + + /* process commmand line args */ + for (i = 1; i < argc; ++i) { + if (!strcmp("-db", argv[i])) { + useDB = !useDB; + } else { + usage(); + } + } + +/* choose visual */ + + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + name = "MOTH - by Bob Doyle"; + glutCreateWindow(name); + + glutKeyboardFunc(keyboard); + + myInit(); /* initialize objects in scene */ + glutDisplayFunc(display); + glutVisibilityFunc(visible); + + + glutCreateMenu(menu_select); + glutAddMenuEntry("Start motion", 1); + glutAddMenuEntry("Stop motion", 2); + glutAddMenuEntry("Quit", 5); + glutAddMenuEntry("Drink Ed's beer", 5); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glFrustum(-.9, .9, -.9, .9, 1.0, 35.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#if 0 + glTranslatef(0.0, 0.0, mvt_zi); +#endif + + glEnable(GL_NORMALIZE); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); /* double your fun */ + glShadeModel(GL_SMOOTH); + glDepthFunc(GL_LESS); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + myInit(); /* initialize objects in scene */ + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/moth.dsp b/lib/glut-3.7.6/progs/contrib/moth.dsp new file mode 100644 index 0000000000..4c01451efc --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/moth.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="moth" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=moth - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "moth.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "moth.mak" CFG="moth - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "moth - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "moth - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "moth - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "moth - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "moth - Win32 Release" +# Name "moth - Win32 Debug" +# Begin Source File + +SOURCE=.\moth.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/noof.c b/lib/glut-3.7.6/progs/contrib/noof.c new file mode 100644 index 0000000000..d8835f80c1 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/noof.c @@ -0,0 +1,475 @@ + +/* XXX Very crufty code follows. */ + +#include +#include + +#include +#ifndef _WIN32 +#include +#else +#define random rand +#define srandom srand +#include +#endif +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#include +#include + +/* For portability... */ +#undef fcos +#undef fsin +#define fcos cos +#define fsin sin + +/* --- shape parameters def'n --- */ +#define N_SHAPES 7 +float pos[N_SHAPES * 3]; +float dir[N_SHAPES * 3]; +float acc[N_SHAPES * 3]; +float col[N_SHAPES * 3]; +float hsv[N_SHAPES * 3]; +float hpr[N_SHAPES * 3]; +float ang[N_SHAPES]; +float spn[N_SHAPES]; +float sca[N_SHAPES]; +float geep[N_SHAPES]; +float peep[N_SHAPES]; +float speedsq[N_SHAPES]; +int blad[N_SHAPES]; + +float ht, wd; + +void +initshapes(int i) +{ + int k; + float f; + + /* random init of pos, dir, color */ + for (k = i * 3; k <= i * 3 + 2; k++) { + f = random() / (float)RAND_MAX; + pos[k] = f; + f = random() / (float)RAND_MAX; + f = (f - 0.5) * 0.05; + dir[k] = f; + f = random() / (float)RAND_MAX; + f = (f - 0.5) * 0.0002; + acc[k] = f; + f = random() / (float)RAND_MAX; + col[k] = f; + } + + speedsq[i] = dir[i * 3] * dir[i * 3] + dir[i * 3 + 1] * dir[i * 3 + 1]; + f = random() / (float)RAND_MAX; + blad[i] = 2 + (int) (f * 17.0); + f = random() / (float)RAND_MAX; + ang[i] = f; + f = random() / (float)RAND_MAX; + spn[i] = (f - 0.5) * 40.0 / (10 + blad[i]); + f = random() / (float)RAND_MAX; + sca[i] = (f * 0.1 + 0.08); + dir[i * 3] *= sca[i]; + dir[i * 3 + 1] *= sca[i]; + + f = random() / (float)RAND_MAX; + hsv[i * 3] = f * 360.0; + + f = random() / (float)RAND_MAX; + hsv[i * 3 + 1] = f * 0.6 + 0.4; + + f = random() / (float)RAND_MAX; + hsv[i * 3 + 2] = f * 0.7 + 0.3; + + f = random() / (float)RAND_MAX; + hpr[i * 3] = f * 0.005 * 360.0; + f = random() / (float)RAND_MAX; + hpr[i * 3 + 1] = f * 0.03; + f = random() / (float)RAND_MAX; + hpr[i * 3 + 2] = f * 0.02; + + geep[i] = 0; + f = random() / (float)RAND_MAX; + peep[i] = 0.01 + f * 0.2; +} + +int tko = 0; + +float bladeratio[] = +{ + /* nblades = 2..7 */ + 0.0, 0.0, 3.00000, 1.73205, 1.00000, 0.72654, 0.57735, 0.48157, + /* 8..13 */ + 0.41421, 0.36397, 0.19076, 0.29363, 0.26795, 0.24648, + /* 14..19 */ + 0.22824, 0.21256, 0.19891, 0.18693, 0.17633, 0.16687, +}; + +void +drawleaf(int l) +{ + + int b, blades; + float x, y; + float wobble; + + blades = blad[l]; + + y = 0.10 * fsin(geep[l] * M_PI / 180.0) + 0.099 * fsin(geep[l] * 5.12 * M_PI / 180.0); + if (y < 0) + y = -y; + x = 0.15 * fcos(geep[l] * M_PI / 180.0) + 0.149 * fcos(geep[l] * 5.12 * M_PI / 180.0); + if (x < 0.0) + x = 0.0 - x; + if (y < 0.001 && x > 0.000002 && ((tko & 0x1) == 0)) { + initshapes(l); /* let it become reborn as something + else */ + tko++; + return; + } { + float w1 = fsin(geep[l] * 15.3 * M_PI / 180.0); + wobble = 3.0 + 2.00 * fsin(geep[l] * 0.4 * M_PI / 180.0) + 3.94261 * w1; + } + + /** + if(blades == 2) if (y > 3.000*x) y = x*3.000; + if(blades == 3) if (y > 1.732*x) y = x*1.732; + if(blades == 4) if (y > x) y = x; + if(blades == 5) if (y > 0.726*x) y = x*0.726; + if(blades == 6) if (y > 0.577*x) y = x*0.577; + if(blades == 7) if (y > 0.481*x) y = x*0.481; + if(blades == 8) if (y > 0.414*x) y = x*0.414; + */ + if (y > x * bladeratio[blades]) + y = x * bladeratio[blades]; + + for (b = 0; b < blades; b++) { + glPushMatrix(); + glTranslatef(pos[l * 3], pos[l * 3 + 1], pos[l * 3 + 2]); + glRotatef(ang[l] + b * (360.0 / blades), 0.0, 0.0, 1.0); + glScalef(wobble * sca[l], wobble * sca[l], wobble * sca[l]); + /** + if(tko & 0x40000) glColor3f(col[l*3], col[l*3+1], col[l*3+2]); + else + */ + glColor4ub(0, 0, 0, 0x60); + + /* constrain geep cooridinates here XXX */ + glEnable(GL_BLEND); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(x * sca[l], 0.0); + glVertex2f(x, y); + glVertex2f(x, -y); /* C */ + glVertex2f(0.3, 0.0); /* D */ + glEnd(); + + /** + if(tko++ & 0x40000) glColor3f(0,0,0); + else + */ + glColor3f(col[l * 3], col[l * 3 + 1], col[l * 3 + 2]); + glBegin(GL_LINE_LOOP); + glVertex2f(x * sca[l], 0.0); + glVertex2f(x, y); + glVertex2f(0.3, 0.0); /* D */ + glVertex2f(x, -y); /* C */ + glEnd(); + glDisable(GL_BLEND); + + glPopMatrix(); + } +} + +void +motionUpdate(int t) +{ + if (pos[t * 3] < -sca[t] * wd && dir[t * 3] < 0.0) { + dir[t * 3] = -dir[t * 3]; + /** + acc[t*3+1] += 0.8*acc[t*3]; + acc[t*3] = -0.8*acc[t*3]; + */ + } else if (pos[t * 3] > (1 + sca[t]) * wd && dir[t * 3] > 0.0) { + dir[t * 3] = -dir[t * 3]; + /** + acc[t*3+1] += 0.8*acc[t*3]; + acc[t*3] = -0.8*acc[t*3]; + */ + } else if (pos[t * 3 + 1] < -sca[t] * ht && dir[t * 3 + 1] < 0.0) { + dir[t * 3 + 1] = -dir[t * 3 + 1]; + /** + acc[t*3] += 0.8*acc[t*3+1]; + acc[t*3+1] = -0.8*acc[t*3+1]; + */ + } else if (pos[t * 3 + 1] > (1 + sca[t]) * ht && dir[t * 3 + 1] > 0.0) { + dir[t * 3 + 1] = -dir[t * 3 + 1]; + /** + acc[t*3] += 0.8*acc[t*3+1]; + acc[t*3+1] = -0.8*acc[t*3+1]; + */ + } + + pos[t * 3] += dir[t * 3]; + pos[t * 3 + 1] += dir[t * 3 + 1]; + /** + dir[t*3] += acc[t*3]; + dir[t*3+1] += acc[t*3+1]; + */ + ang[t] += spn[t]; + geep[t] += peep[t]; + if (geep[t] > 360 * 5.0) + geep[t] -= 360 * 5.0; + if (ang[t] < 0.0) { + ang[t] += 360.0; + } + if (ang[t] > 360.0) { + ang[t] -= 360.0; + } +} + +void +colorUpdate(int i) +{ + if (hsv[i * 3 + 1] <= 0.5 && hpr[i * 3 + 1] < 0.0) + hpr[i * 3 + 1] = -hpr[i * 3 + 1]; /* adjust s */ + if (hsv[i * 3 + 1] >= 1.0 && hpr[i * 3 + 1] > 0.0) + hpr[i * 3 + 1] = -hpr[i * 3 + 1]; /* adjust s */ + if (hsv[i * 3 + 2] <= 0.4 && hpr[i * 3 + 2] < 0.0) + hpr[i * 3 + 2] = -hpr[i * 3 + 2]; /* adjust s */ + if (hsv[i * 3 + 2] >= 1.0 && hpr[i * 3 + 2] > 0.0) + hpr[i * 3 + 2] = -hpr[i * 3 + 2]; /* adjust s */ + + hsv[i * 3] += hpr[i * 3]; + hsv[i * 3 + 1] += hpr[i * 3 + 1]; + hsv[i * 3 + 2] += hpr[i * 3 + 2]; + + /* --- hsv -> rgb --- */ +#define H(hhh) hhh[i*3 ] +#define S(hhh) hhh[i*3+1] +#define V(hhh) hhh[i*3+2] + +#define R(hhh) hhh[i*3 ] +#define G(hhh) hhh[i*3+1] +#define B(hhh) hhh[i*3+2] + + if (V(hsv) < 0.0) + V(hsv) = 0.0; + if (V(hsv) > 1.0) + V(hsv) = 1.0; + if (S(hsv) <= 0.0) { + R(col) = V(hsv); + G(col) = V(hsv); + B(col) = V(hsv); + } else { + float f, h, p, q, t, v; + int hi; + + while (H(hsv) < 0.0) + H(hsv) += 360.0; + while (H(hsv) >= 360.0) + H(hsv) -= 360.0; + + if (S(hsv) < 0.0) + S(hsv) = 0.0; + if (S(hsv) > 1.0) + S(hsv) = 1.0; + + h = H(hsv) / 60.0; + hi = (int) (h); + f = h - hi; + v = V(hsv); + p = V(hsv) * (1 - S(hsv)); + q = V(hsv) * (1 - S(hsv) * f); + t = V(hsv) * (1 - S(hsv) * (1 - f)); + + if (hi <= 0) { + R(col) = v; + G(col) = t; + B(col) = p; + } else if (hi == 1) { + R(col) = q; + G(col) = v; + B(col) = p; + } else if (hi == 2) { + R(col) = p; + G(col) = v; + B(col) = t; + } else if (hi == 3) { + R(col) = p; + G(col) = q; + B(col) = v; + } else if (hi == 4) { + R(col) = t; + G(col) = p; + B(col) = v; + } else { + R(col) = v; + G(col) = p; + B(col) = q; + } + } +} + +void +gravity(float fx) +{ + int a, b; + + for (a = 0; a < N_SHAPES; a++) { + for (b = 0; b < a; b++) { + float t, d2; + + t = pos[b * 3] - pos[a * 3]; + d2 = t * t; + t = pos[b * 3 + 1] - pos[a * 3 + 1]; + d2 += t * t; + if (d2 < 0.000001) + d2 = 0.00001; + if (d2 < 0.1) { + + float v0, v1, z; + v0 = pos[b * 3] - pos[a * 3]; + v1 = pos[b * 3 + 1] - pos[a * 3 + 1]; + + z = 0.00000001 * fx / (d2); + + dir[a * 3] += v0 * z * sca[b]; + dir[b * 3] += -v0 * z * sca[a]; + dir[a * 3 + 1] += v1 * z * sca[b]; + dir[b * 3 + 1] += -v1 * z * sca[a]; + + } + } + /** apply brakes + if(dir[a*3]*dir[a*3] + dir[a*3+1]*dir[a*3+1] + > 0.0001) { + dir[a*3] *= 0.9; + dir[a*3+1] *= 0.9; + } + */ + } +} +void +oneFrame(void) +{ + int i; + + /** + if((random() & 0xff) == 0x34){ + glClear(GL_COLOR_BUFFER_BIT); + } + + if((tko & 0x1f) == 0x1f){ + glEnable(GL_BLEND); + glColor4f(0.0, 0.0, 0.0, 0.09); + glRectf(0.0, 0.0, wd, ht); + glDisable(GL_BLEND); +#ifdef __sgi + sginap(0); +#endif + } + */ + gravity(-2.0); + for (i = 0; i < N_SHAPES; i++) { + motionUpdate(i); +#ifdef __sgi + sginap(0); +#endif + colorUpdate(i); +#ifdef __sgi + sginap(0); +#endif + drawleaf(i); +#ifdef __sgi + sginap(0); +#endif + + } + glFlush(); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); +} + +void +myReshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (w <= h) { + wd = 1.0; + ht = (GLfloat) h / (GLfloat) w; + glOrtho(0.0, 1.0, + 0.0, 1.0 * (GLfloat) h / (GLfloat) w, + -16.0, 4.0); + } else { + wd = (GLfloat) w / (GLfloat) h; + ht = 1.0; + glOrtho(0.0, 1.0 * (GLfloat) w / (GLfloat) h, + 0.0, 1.0, + -16.0, 4.0); + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void +visibility(int status) +{ + if (status == GLUT_VISIBLE) { + glutIdleFunc(oneFrame); + } else { + glutIdleFunc(NULL); + } + +} + +void +myinit(void) +{ + int i; + srandom(getpid()); + glClearColor(0.0, 0.0, 0.0, 1.0); + glEnable(GL_LINE_SMOOTH); + glShadeModel(GL_FLAT); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for (i = 0; i < N_SHAPES; i++) + initshapes(i); + myReshape(200, 200); +} + +/* ARGSUSED1 */ +void +keys(unsigned char c, int x, int y) +{ + + if (c == 0x1b) + exit(0); /* escape */ +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(300, 300); + glutCreateWindow(argv[0]); + + myinit(); + glutReshapeFunc(myReshape); + glutDisplayFunc(display); + glutKeyboardFunc(keys); + glutVisibilityFunc(visibility); + glutIdleFunc(oneFrame); + glutPostRedisplay(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/noof.dsp b/lib/glut-3.7.6/progs/contrib/noof.dsp new file mode 100644 index 0000000000..e7a2897249 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/noof.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="noof" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=noof - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "noof.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "noof.mak" CFG="noof - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "noof - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "noof - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "noof - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "noof - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "noof - Win32 Release" +# Name "noof - Win32 Debug" +# Begin Source File + +SOURCE=.\noof.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/rings.c b/lib/glut-3.7.6/progs/contrib/rings.c new file mode 100644 index 0000000000..32d0f9b303 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/rings.c @@ -0,0 +1,279 @@ +/* rings.c + * + * To compile: cc -o rings rings.c -lGL -lGLU -lX11 -lglut -lXmu -lm + * + * Usage: rings + * + * Homework 4, Part 1: perspective, hierarchical coords, moving eye pos. + * + * Do a slow zoom on a bunch of rings (ala Superman III?) + * + * Philip Winston - 2/21/95 + * pwinston@hmc.edu + * http://www.cs.hmc.edu/people/pwinston + * + */ + +#include + +#include +#include +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +typedef enum {MENU_STARTOVER, MENU_ZOOM_OUT, MENU_STOP_RINGS, MENU_STOP_FADE, + MENU_START_RINGS, MENU_START_FADE, MENU_QUIT} MenuChoices; + +typedef enum {NOTALLOWED, CONE, TORUS, INNERMAT, OUTTERMAT} DisplayLists; + +#define STEPS 30 + +int Fade = 1; /* Start moving out */ + +float Axis = 0, AxisInc = (2.0 * M_PI / STEPS); + +GLfloat InnerRad, OutterRad, Tilt, Trans, TransCone, Dist; + + /* mainly computes the translation amount as a function of the + tilt angle and torus radii */ +void myInit(void) +{ + float sinoftilt; + + InnerRad = 0.70; + OutterRad = 5.0; + Tilt = 15; + Dist = 10; + + sinoftilt = sin(Tilt * M_PI*2/360); + + Trans = (2*OutterRad + InnerRad) * sinoftilt + InnerRad + + ((1 - sinoftilt) * InnerRad) - (InnerRad * 1/10); + + TransCone = Trans + (OutterRad * sinoftilt + InnerRad); +} + + /* I used code from the book's accnot.c as a starting point for lighting. + I have one positional light in center, then one directional */ +void myglInit(void) +{ + GLfloat light0_position[] = { 1.0, 0.2, 1.0, 0.0 }; + GLfloat light1_position[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; + + glEnable(GL_NORMALIZE); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glLightfv(GL_LIGHT0, GL_POSITION, light0_position); + glLightfv(GL_LIGHT1, GL_POSITION, light1_position); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular); + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.2); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + + glFlush(); +} + +void myreshape(GLsizei w, GLsizei h) +{ + glViewport(0,0,w,h); + glFlush(); +} + + /* setup display lists to change material for inner/outter rings and + to draw a single torus or cone */ +void MakeDisplayLists(void) +{ + GLfloat cone_diffuse[] = { 0.0, 0.7, 0.7, 1.0 }; + GLfloat mat1_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat2_ambient[] = { 0.0, 0.0, 0.0, 0.0 }; + GLfloat torus1_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; + GLfloat torus2_diffuse[] = { 0.3, 0.0, 0.0, 1.0 }; + GLfloat mat1_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat2_specular[] = { 0.5, 0.5, 0.5, 1.0 }; + + glNewList(INNERMAT, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat1_specular); + glMaterialf(GL_FRONT, GL_SHININESS, 50.0); + glMaterialfv(GL_FRONT, GL_DIFFUSE, torus1_diffuse); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat1_ambient); + glEndList(); + + glNewList(OUTTERMAT, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat2_specular); + glMaterialf(GL_FRONT, GL_SHININESS, 25.0); + glMaterialfv(GL_FRONT, GL_DIFFUSE, torus2_diffuse); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat2_ambient); + glEndList(); + + glNewList(CONE, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_DIFFUSE, cone_diffuse); + glPushMatrix(); + glTranslatef(0, -TransCone, 0); + glRotatef(90, 1, 0, 0); + glutSolidCone(OutterRad, 10, 8, 8); + glPopMatrix(); + glEndList(); + + glNewList(TORUS, GL_COMPILE); + glPushMatrix(); + glRotatef(90, 1, 0, 0); + glutSolidTorus(InnerRad, OutterRad, 15, 25); + glPopMatrix(); + glEndList(); +} + + /* Draw three rings, rotated and translate so they look cool */ +void DrawRings(float axis) +{ + GLfloat x = sin(axis), y = cos(axis); + + glPushMatrix(); + glTranslatef(0, Trans, 0); + glRotatef(Tilt, x, 0, y); + glCallList(TORUS); + glPopMatrix(); + + glPushMatrix(); + glRotatef(-Tilt, x, 0, y); + glCallList(TORUS); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0, -Trans, 0); + glRotatef(Tilt, x, 0, y); + glCallList(TORUS); + glPopMatrix(); +} + + /* Draw the inner thing, then glScale and draw 3 huge rings */ +void mydisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1, 1, -1, 1, 10, 1000); + gluLookAt(0, 0, Dist, 0, 0, 0, 0, 1, 0); + + glMatrixMode(GL_MODELVIEW); + + glCallList(INNERMAT); + DrawRings(Axis); + glCallList(CONE); + + glCallList(OUTTERMAT); + glPushMatrix(); + glScalef(10, 10, 10); + DrawRings(Axis/3); + glPopMatrix(); + + glutSwapBuffers(); + glFlush(); +} + + /* rotate the axis and adjust position if nec. */ +void myidle(void) +{ + Axis += AxisInc; + + if (Dist < 15 && Fade) /* start slow */ + Dist += 0.1; + else if (Dist < 800 && Fade) /* don't go back too far */ + Dist *= 1.005; + + mydisplay(); +} + + /* nothing fancy */ +void handlemenu(int value) +{ + switch (value) { + case MENU_STARTOVER: + Dist = 10; Axis = 0; Fade = 1; + AxisInc = (2.0 * M_PI / STEPS); + glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS); + glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE); + break; + case MENU_ZOOM_OUT: + Dist = 800; + break; + case MENU_STOP_RINGS: + AxisInc = 0; + glutChangeToMenuEntry(3, "Start rings", MENU_START_RINGS); + break; + case MENU_START_RINGS: + AxisInc = (2.0 * M_PI / STEPS); + glutChangeToMenuEntry(3, "Stop rings", MENU_STOP_RINGS); + break; + case MENU_STOP_FADE: + Fade = 0; + glutChangeToMenuEntry(4, "Start fade", MENU_START_FADE); + break; + case MENU_START_FADE: + Fade = 1; + glutChangeToMenuEntry(4, "Stop fade", MENU_STOP_FADE); + break; + case MENU_QUIT: + exit(0); + break; + } +} + +void MenuInit(void) +{ + glutCreateMenu(handlemenu); + glutAddMenuEntry("Start Over", MENU_STARTOVER); + glutAddMenuEntry("Zoom Out", MENU_ZOOM_OUT); + glutAddMenuEntry("Stop rings", MENU_STOP_RINGS); + glutAddMenuEntry("Stop fade", MENU_STOP_FADE); + glutAddMenuEntry("Quit", MENU_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +void +vis(int visible) +{ + if (visible == GLUT_VISIBLE) { + glutIdleFunc(myidle); + } else { + glutIdleFunc(NULL); + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow("rings"); + + myInit(); + myglInit(); + + MakeDisplayLists(); + MenuInit(); + + glutReshapeFunc(myreshape); + glutDisplayFunc(mydisplay); + glutVisibilityFunc(vis); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/rings.dsp b/lib/glut-3.7.6/progs/contrib/rings.dsp new file mode 100644 index 0000000000..91d4aa5e67 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/rings.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="rings" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rings - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rings.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rings.mak" CFG="rings - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rings - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "rings - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rings - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "rings - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rings - Win32 Release" +# Name "rings - Win32 Debug" +# Begin Source File + +SOURCE=.\rings.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/steam.c b/lib/glut-3.7.6/progs/contrib/steam.c new file mode 100644 index 0000000000..07d9cc095f --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/steam.c @@ -0,0 +1,621 @@ +/** + + Description: Interactive 3D graphics, Assignment #1 + Miniature Steam Engine Simulation. + Author: Troy Robinette + Date: 29/9/95 + Email: troyr@yallara.cs.rmit.edu.au + Notes: - Transparence doesn't quite work. The color of the + underlying object doesn't show through. + - Also only the front side of the transparent objects are + transparent. + +**/ + +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/* Dimensions of texture image. */ +#define IMAGE_WIDTH 64 +#define IMAGE_HEIGHT 64 + +/* Step to be taken for each rotation. */ +#define ANGLE_STEP 10 + +/* Magic numbers for relationship b/w cylinder head and crankshaft. */ +#define MAGNITUDE 120 +#define PHASE 270.112 +#define FREQ_DIV 58 +#define ARC_LENGHT 2.7 +#define ARC_RADIUS 0.15 + +/* Rotation angles */ +GLdouble view_h = 270, view_v = 0, head_angle = 0; +GLint crank_angle = 0; + +/* Crank rotation step. */ +GLdouble crank_step = 5; + +/* Toggles */ +GLshort shaded = TRUE, anim = FALSE; +GLshort texture = FALSE, transparent = FALSE; +GLshort light1 = TRUE, light2 = FALSE; + +/* Storage for the angle look up table and the texture map */ +GLdouble head_look_up_table[361]; +GLubyte image[IMAGE_WIDTH][IMAGE_HEIGHT][3]; + +/* Indentifiers for each Display list */ +GLint list_piston_shaded = 1; +GLint list_piston_texture = 2; +GLint list_flywheel_shaded = 4; +GLint list_flywheel_texture = 8; + +/* Variable used in the creaton of glu objects */ +GLUquadricObj *obj; + +/* Draws a box by scaling a glut cube of size 1. Also checks the shaded + toggle to see which rendering style to use. NB Texture doesn't work + correctly due to the cube being scaled. */ +void +myBox(GLdouble x, GLdouble y, GLdouble z) +{ + glPushMatrix(); + glScalef(x, y, z); + if (shaded) + glutSolidCube(1); + else + glutWireCube(1); + glPopMatrix(); +} + +/* Draws a cylinder using glu function, drawing flat disc's at each end, + to give the appearence of it being solid. */ +void +myCylinder(GLUquadricObj * object, GLdouble outerRadius, + GLdouble innerRadius, GLdouble lenght) +{ + glPushMatrix(); + gluCylinder(object, outerRadius, outerRadius, lenght, 20, 1); + glPushMatrix(); + glRotatef(180, 0.0, 1.0, 0.0); + gluDisk(object, innerRadius, outerRadius, 20, 1); + glPopMatrix(); + + glTranslatef(0.0, 0.0, lenght); + gluDisk(object, innerRadius, outerRadius, 20, 1); + glPopMatrix(); +} + +/* Draws a piston. */ +void +draw_piston(void) +{ + glPushMatrix(); + glColor4f(0.3, 0.6, 0.9, 1.0); + + glPushMatrix(); + glRotatef(90, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -0.07); + myCylinder(obj, 0.125, 0.06, 0.12); + glPopMatrix(); + + glRotatef(-90, 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, 0.05); + myCylinder(obj, 0.06, 0.0, 0.6); + glTranslatef(0.0, 0.0, 0.6); + myCylinder(obj, 0.2, 0.0, 0.5); + glPopMatrix(); +} + +/* Draws the engine pole and the pivot pole for the cylinder head. */ +void +draw_engine_pole(void) +{ + glPushMatrix(); + glColor4f(0.9, 0.9, 0.9, 1.0); + myBox(0.5, 3.0, 0.5); + + glColor3f(0.5, 0.1, 0.5); + glRotatef(90, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.9, -0.4); + myCylinder(obj, 0.1, 0.0, 2); + glPopMatrix(); +} + +/* Draws the cylinder head at the appropreate angle, doing the necesary + translations for the rotation. */ +void +draw_cylinder_head(void) +{ + glPushMatrix(); + glColor4f(0.5, 1.0, 0.5, 0.1); + glRotatef(90, 1.0, 0.0, 0.0); + glTranslatef(0, 0.0, 0.4); + glRotatef(head_angle, 1, 0, 0); + glTranslatef(0, 0.0, -0.4); + myCylinder(obj, 0.23, 0.21, 1.6); + glRotatef(180, 1.0, 0.0, 0.0); + gluDisk(obj, 0, 0.23, 20, 1); + glPopMatrix(); +} + +/* Draws the flywheel. */ +void +draw_flywheel(void) +{ + glPushMatrix(); + glColor4f(0.5, 0.5, 1.0, 1.0); + glRotatef(90, 0.0, 1.0, 0.0); + myCylinder(obj, 0.625, 0.08, 0.5); + glPopMatrix(); +} + +/* Draws the crank bell, and the pivot pin for the piston. Also calls the + appropreate display list of a piston doing the nesacary rotations before + hand. */ +void +draw_crankbell(void) +{ + glPushMatrix(); + glColor4f(1.0, 0.5, 0.5, 1.0); + glRotatef(90, 0.0, 1.0, 0.0); + myCylinder(obj, 0.3, 0.08, 0.12); + + glColor4f(0.5, 0.1, 0.5, 1.0); + glTranslatef(0.0, 0.2, 0.0); + myCylinder(obj, 0.06, 0.0, 0.34); + + glTranslatef(0.0, 0.0, 0.22); + glRotatef(90, 0.0, 1.0, 0.0); + glRotatef(crank_angle - head_angle, 1.0, 0.0, 0.0); + if (shaded) { + if (texture) + glCallList(list_piston_texture); + else + glCallList(list_piston_shaded); + } else + draw_piston(); + glPopMatrix(); +} + +/* Draws the complete crank. Piston also gets drawn through the crank bell + function. */ +void +draw_crank(void) +{ + glPushMatrix(); + glRotatef(crank_angle, 1.0, 0.0, 0.0); + + glPushMatrix(); + glRotatef(90, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -1.0); + myCylinder(obj, 0.08, 0.0, 1.4); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.28, 0.0, 0.0); + draw_crankbell(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-0.77, 0.0, 0.0); + if (shaded) { + if (texture) + glCallList(list_flywheel_texture); + else + glCallList(list_flywheel_shaded); + } else + draw_flywheel(); + glPopMatrix(); + glPopMatrix(); +} + +/* Main display routine. Clears the drawing buffer and if transparency is + set, displays the model twice, 1st time accepting those fragments with + a ALPHA value of 1 only, then with DEPTH_BUFFER writing disabled for + those with other values. */ +void +display(void) +{ + int pass; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + if (transparent) { + glEnable(GL_ALPHA_TEST); + pass = 2; + } else { + glDisable(GL_ALPHA_TEST); + pass = 0; + } + + /* Rotate the whole model */ + glRotatef(view_h, 0, 1, 0); + glRotatef(view_v, 1, 0, 0); + + do { + if (pass == 2) { + glAlphaFunc(GL_EQUAL, 1); + glDepthMask(GL_TRUE); + pass--; + } else if (pass != 0) { + glAlphaFunc(GL_NOTEQUAL, 1); + glDepthMask(GL_FALSE); + pass--; + } + draw_engine_pole(); + + glPushMatrix(); + glTranslatef(0.5, 1.4, 0.0); + draw_cylinder_head(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0, -0.8, 0.0); + draw_crank(); + glPopMatrix(); + } while (pass > 0); + glDepthMask(GL_TRUE); + glutSwapBuffers(); + glPopMatrix(); +} + +/* Called when the window is idle. When called increments the crank angle + by ANGLE_STEP, updates the head angle and notifies the system that + the screen needs to be updated. */ +void +animation(void) +{ + if ((crank_angle += crank_step) >= 360) + crank_angle = 0; + head_angle = head_look_up_table[crank_angle]; + glutPostRedisplay(); +} + +/* Called when a key is pressed. Checks if it reconises the key and if so + acts on it, updateing the screen. */ +/* ARGSUSED1 */ +void +keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 's': + if (shaded == FALSE) { + shaded = TRUE; + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glEnable(GL_COLOR_MATERIAL); + gluQuadricNormals(obj, GLU_SMOOTH); + gluQuadricDrawStyle(obj, GLU_FILL); + } else { + shaded = FALSE; + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_COLOR_MATERIAL); + gluQuadricNormals(obj, GLU_NONE); + gluQuadricDrawStyle(obj, GLU_LINE); + gluQuadricTexture(obj, GL_FALSE); + } + if (texture && !shaded); + else + break; + case 't': + if (texture == FALSE) { + texture = TRUE; + glEnable(GL_TEXTURE_2D); + gluQuadricTexture(obj, GL_TRUE); + } else { + texture = FALSE; + glDisable(GL_TEXTURE_2D); + gluQuadricTexture(obj, GL_FALSE); + } + break; + case 'o': + if (transparent == FALSE) { + transparent = TRUE; + } else { + transparent = FALSE; + } + break; + + case 'a': + if ((crank_angle += crank_step) >= 360) + crank_angle = 0; + head_angle = head_look_up_table[crank_angle]; + break; + case 'z': + if ((crank_angle -= crank_step) <= 0) + crank_angle = 360; + head_angle = head_look_up_table[crank_angle]; + break; + case '0': + if (light1) { + glDisable(GL_LIGHT0); + light1 = FALSE; + } else { + glEnable(GL_LIGHT0); + light1 = TRUE; + } + break; + case '1': + if (light2) { + glDisable(GL_LIGHT1); + light2 = FALSE; + } else { + glEnable(GL_LIGHT1); + light2 = TRUE; + } + break; + case '4': + if ((view_h -= ANGLE_STEP) <= 0) + view_h = 360; + break; + case '6': + if ((view_h += ANGLE_STEP) >= 360) + view_h = 0; + break; + case '8': + if ((view_v += ANGLE_STEP) >= 360) + view_v = 0; + break; + case '2': + if ((view_v -= ANGLE_STEP) <= 0) + view_v = 360; + break; + case ' ': + if (anim) { + glutIdleFunc(0); + anim = FALSE; + } else { + glutIdleFunc(animation); + anim = TRUE; + } + break; + case '+': + if ((++crank_step) > 45) + crank_step = 45; + break; + case '-': + if ((--crank_step) <= 0) + crank_step = 0; + break; + default: + return; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + if ((view_h -= ANGLE_STEP) <= 0) + view_h = 360; + break; + case GLUT_KEY_RIGHT: + if ((view_h += ANGLE_STEP) >= 360) + view_h = 0; + break; + case GLUT_KEY_UP: + if ((view_v += ANGLE_STEP) >= 360) + view_v = 0; + break; + case GLUT_KEY_DOWN: + if ((view_v -= ANGLE_STEP) <= 0) + view_v = 360; + break; + default: + return; + } + glutPostRedisplay(); +} + +/* Called when a menu option has been selected. Translates the menu item + identifier into a keystroke, then call's the keyboard function. */ +void +menu(int val) +{ + unsigned char key; + + switch (val) { + case 1: + key = 's'; + break; + case 2: + key = ' '; + break; + case 3: + key = 't'; + break; + case 4: + key = 'o'; + break; + case 5: + key = '0'; + break; + case 6: + key = '1'; + break; + case 7: + key = '+'; + break; + case 8: + key = '-'; + break; + default: + return; + } + keyboard(key, 0, 0); +} + +/* Initialises the menu of toggles. */ +void +create_menu(void) +{ + glutCreateMenu(menu); + glutAttachMenu(GLUT_LEFT_BUTTON); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutAddMenuEntry("Shaded", 1); + glutAddMenuEntry("Animation", 2); + glutAddMenuEntry("Texture", 3); + glutAddMenuEntry("Transparency", 4); + glutAddMenuEntry("Right Light (0)", 5); + glutAddMenuEntry("Left Light (1)", 6); + glutAddMenuEntry("Speed UP", 7); + glutAddMenuEntry("Slow Down", 8); +} + +/* Makes a simple check pattern image. (Copied from the redbook example + "checker.c".) */ +void +make_image(void) +{ + int i, j, c; + + for (i = 0; i < IMAGE_WIDTH; i++) { + for (j = 0; j < IMAGE_HEIGHT; j++) { + c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255; + image[i][j][0] = (GLubyte) c; + image[i][j][1] = (GLubyte) c; + image[i][j][2] = (GLubyte) c; + } + } +} + +/* Makes the head look up table for all possible crank angles. */ +void +make_table(void) +{ + GLint i; + GLdouble k; + + for (i = 0, k = 0.0; i < 360; i++, k++) { + head_look_up_table[i] = + MAGNITUDE * atan( + (ARC_RADIUS * sin(PHASE - k / FREQ_DIV)) / + ((ARC_LENGHT - ARC_RADIUS * cos(PHASE - k / FREQ_DIV)))); + } +} + +/* Initialises texturing, lighting, display lists, and everything else + associated with the model. */ +void +myinit(void) +{ + GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0}; + GLfloat mat_shininess[] = {50.0}; + GLfloat light_position1[] = {1.0, 1.0, 1.0, 0.0}; + GLfloat light_position2[] = {-1.0, 1.0, 1.0, 0.0}; + + glClearColor(0.0, 0.0, 0.0, 0.0); + + obj = gluNewQuadric(); + make_table(); + make_image(); + + /* Set up Texturing */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, 3, IMAGE_WIDTH, + IMAGE_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, + image); + 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_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + /* Set up Lighting */ + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + glLightfv(GL_LIGHT0, GL_POSITION, light_position1); + glLightfv(GL_LIGHT1, GL_POSITION, light_position2); + + /* Initial render mode is with full shading and LIGHT 0 + enabled. */ + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + + /* Initialise display lists */ + glNewList(list_piston_shaded, GL_COMPILE); + draw_piston(); + glEndList(); + glNewList(list_flywheel_shaded, GL_COMPILE); + draw_flywheel(); + glEndList(); + + gluQuadricTexture(obj, GL_TRUE); + glNewList(list_piston_texture, GL_COMPILE); + draw_piston(); + glEndList(); + glNewList(list_flywheel_texture, GL_COMPILE); + draw_flywheel(); + glEndList(); + gluQuadricTexture(obj, GL_FALSE); +} + +/* Called when the model's window has been reshaped. */ +void +myReshape(int w, int h) +{ + glViewport(0, 0, w, 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); /* viewing transform */ + glScalef(1.5, 1.5, 1.5); +} + +/* Main program. An interactive model of a miniture steam engine. + Sets system in Double Buffered mode and initialises all the call-back + functions. */ +int +main(int argc, char **argv) +{ + puts("Miniature Steam Engine Troy Robinette\n"); + + puts("Keypad Arrow keys (with NUM_LOCK on) rotates object."); + puts("Rotate crank: 'a' = anti-clock wise 'z' = clock wise"); + puts("Crank Speed : '+' = Speed up by 1 '-' = Slow Down by 1"); + puts("Toggle : 's' = Shading 't' = Texture"); + puts(" : ' ' = Animation 'o' = Transparency"); + puts(" : '0' = Right Light '1' = Left Light"); + puts(" Alternatively a pop up menu with all toggles is attached"); + puts(" to the left mouse button.\n"); + + glutInitWindowSize(400, 400); + glutInit(&argc, argv); + + /* Transperancy won't work properly without GLUT_ALPHA */ + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutCreateWindow("Miniature Steam Engine by Troy Robinette"); + + glutDisplayFunc(display); + glutKeyboardFunc(keyboard); + glutSpecialFunc(special); + create_menu(); + + myinit(); + + glutReshapeFunc(myReshape); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/steam.dsp b/lib/glut-3.7.6/progs/contrib/steam.dsp new file mode 100644 index 0000000000..77cb2f3ca4 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/steam.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="steam" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=steam - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "steam.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "steam.mak" CFG="steam - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "steam - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "steam - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "steam - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "steam - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "steam - Win32 Release" +# Name "steam - Win32 Debug" +# Begin Source File + +SOURCE=.\steam.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/text3d.c b/lib/glut-3.7.6/progs/contrib/text3d.c new file mode 100644 index 0000000000..b3f0c5e099 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/text3d.c @@ -0,0 +1,509 @@ +/* Text3d by Robert J. Doyle, Jr., Naval Research Laboratory, Washington, DC. */ +#include +#include +#include +#include +#ifndef _WIN32 +#include +#endif +#include + +typedef enum {RESERVED, M_SIDE, M_EDGE, M_WHOLE, O_SIDE, O_EDGE, O_WHOLE, +T_SIDE, T_EDGE, T_WHOLE, H_SIDE, H_EDGE, H_WHOLE,REPEAT_SIDE, REPEAT_EDGE, REPEAT1, +REPEAT2_SIDE, REPEAT2_EDGE,REPEAT2, REPEAT3_SIDE, REPEAT3_EDGE,REPEAT3, +REPEAT4_SIDE, REPEAT4_EDGE,REPEAT4} displayLists; + +GLfloat sideColor[] = {0.0, 0.0, 0.5, 1.0}; +GLfloat edgeColor[] = {0.7, 0.7, 0.0, 1.0}; +GLfloat shininess[] = {128.0}; +GLfloat mat_specular[] = {0.7, 0.7, 0.7, 1.0}; + +GLfloat width = 0.0; +GLfloat width2 = 2.0; + +GLfloat letterM[][3] = +{ + {-3.125000, 0.000000, 0.000000}, + {-3.125000, 6.208000, 0.000000}, + {-1.233000, 6.208000, 0.000000}, + {0.003000, 1.484000, 0.000000}, + {1.223000, 6.208000, 0.000000}, + {3.123000, 6.208000, 0.000000}, + {3.123000, 0.000000, 0.000000}, + {1.923000, 0.000000, 0.000000}, + {1.923000, 5.010000, 0.000000}, + {0.659000, 0.000000, 0.000000}, + {-0.649000, 0.000000, 0.000000}, + {-1.925000, 5.010000, 0.000000}, + {-1.925000, 0.000000, 0.000000} + +}; + +GLfloat letterO[][3] = +{ + {-3.038000, 3.102000, 0.000000}, + {-2.974000, 3.874000, 0.000000}, + {-2.827000, 4.440000, 0.000000}, + {-2.802000, 4.508000, 0.000000}, + {-2.544000, 5.042000, 0.000000}, + {-2.502000, 5.110000, 0.000000}, + {-2.223000, 5.479000, 0.000000}, + {-2.132000, 5.576000, 0.000000}, + {-1.784000, 5.869000, 0.000000}, + {-1.678000, 5.940000, 0.000000}, + {-1.260000, 6.155000, 0.000000}, + {-1.148000, 6.198000, 0.000000}, + {-0.677000, 6.321000, 0.000000}, + {-0.638000, 6.328000, 0.000000}, + {-0.002000, 6.378000, 0.000000}, + {0.634000, 6.328000, 0.000000}, + {1.107000, 6.210000, 0.000000}, + {1.144000, 6.198000, 0.000000}, + {1.570000, 6.002000, 0.000000}, + {1.674000, 5.940000, 0.000000}, + {2.038000, 5.661000, 0.000000}, + {2.128000, 5.576000, 0.000000}, + {2.428000, 5.217000, 0.000000}, + {2.504000, 5.104000, 0.000000}, + {2.762000, 4.598000, 0.000000}, + {2.798000, 4.508000, 0.000000}, + {2.960000, 3.913000, 0.000000}, + {2.970000, 3.862000, 0.000000}, + {3.034000, 3.102000, 0.000000}, + {2.970000, 2.342000, 0.000000}, + {2.815000, 1.745000, 0.000000}, + {2.798000, 1.696000, 0.000000}, + {2.554000, 1.182000, 0.000000}, + {2.504000, 1.100000, 0.000000}, + {2.221000, 0.726000, 0.000000}, + {2.128000, 0.628000, 0.000000}, + {1.776000, 0.332000, 0.000000}, + {1.674000, 0.264000, 0.000000}, + {1.256000, 0.049000, 0.000000}, + {1.144000, 0.006000, 0.000000}, + {0.672000, -0.117000, 0.000000}, + {0.634000, -0.124000, 0.000000}, + {-0.002000, -0.174000, 0.000000}, + {-0.638000, -0.124000, 0.000000}, + {-1.112000, -0.006000, 0.000000}, + {-1.148000, 0.006000, 0.000000}, + {-1.576000, 0.202000, 0.000000}, + {-1.678000, 0.264000, 0.000000}, + {-2.041000, 0.540000, 0.000000}, + {-2.132000, 0.628000, 0.000000}, + {-2.430000, 0.983000, 0.000000}, + {-2.502000, 1.094000, 0.000000}, + {-2.773000, 1.622000, 0.000000}, + {-2.802000, 1.696000, 0.000000}, + {-2.962000, 2.258000, 0.000000}, + {-2.974000, 2.330000, 0.000000}, + {-1.736000, 3.102000, 10000.0}, + {-1.710000, 3.578000, 0.000000}, + {-1.644000, 3.934000, 0.000000}, + {-1.503000, 4.328000, 0.000000}, + {-1.494000, 4.346000, 0.000000}, + {-1.352000, 4.593000, 0.000000}, + {-1.306000, 4.656000, 0.000000}, + {-1.120000, 4.857000, 0.000000}, + {-1.040000, 4.926000, 0.000000}, + {-0.825000, 5.067000, 0.000000}, + {-0.726000, 5.116000, 0.000000}, + {-0.480000, 5.200000, 0.000000}, + {-0.402000, 5.218000, 0.000000}, + {-0.041000, 5.257000, 0.000000}, + {-0.002000, 5.258000, 0.000000}, + {0.361000, 5.227000, 0.000000}, + {0.400000, 5.220000, 0.000000}, + {0.650000, 5.147000, 0.000000}, + {0.726000, 5.116000, 0.000000}, + {0.950000, 4.990000, 0.000000}, + {1.038000, 4.926000, 0.000000}, + {1.239000, 4.736000, 0.000000}, + {1.306000, 4.656000, 0.000000}, + {1.462000, 4.413000, 0.000000}, + {1.498000, 4.342000, 0.000000}, + {1.635000, 3.964000, 0.000000}, + {1.644000, 3.934000, 0.000000}, + {1.710000, 3.568000, 0.000000}, + {1.736000, 3.102000, 0.000000}, + {1.710000, 2.636000, 0.000000}, + {1.642000, 2.268000, 0.000000}, + {1.508000, 1.886000, 0.000000}, + {1.496000, 1.860000, 0.000000}, + {1.351000, 1.610000, 0.000000}, + {1.304000, 1.546000, 0.000000}, + {1.115000, 1.343000, 0.000000}, + {1.036000, 1.276000, 0.000000}, + {0.823000, 1.135000, 0.000000}, + {0.724000, 1.086000, 0.000000}, + {0.480000, 1.001000, 0.000000}, + {0.400000, 0.984000, 0.000000}, + {0.035000, 0.946000, 0.000000}, + {-0.002000, 0.946000, 0.000000}, + {-0.368000, 0.979000, 0.000000}, + {-0.402000, 0.986000, 0.000000}, + {-0.653000, 1.057000, 0.000000}, + {-0.726000, 1.088000, 0.000000}, + {-0.952000, 1.213000, 0.000000}, + {-1.040000, 1.278000, 0.000000}, + {-1.240000, 1.467000, 0.000000}, + {-1.306000, 1.548000, 0.000000}, + {-1.460000, 1.788000, 0.000000}, + {-1.494000, 1.858000, 0.000000}, + {-1.639000, 2.251000, 0.000000}, + {-1.644000, 2.270000, 0.000000}, + {-1.710000, 2.626000, 0.000000} +}; + +GLfloat letterT[][3] = +{ + {-0.640000, 0.000000, 0.000000}, + {-0.640000, 5.104000, 0.000000}, + {-2.476000, 5.104000, 0.000000}, + {-2.476000, 6.208000, 0.000000}, + {2.476000, 6.208000, 0.000000}, + {2.476000, 5.104000, 0.000000}, + {0.640000, 5.104000, 0.000000}, + {0.640000, 0.000000, 0.000000} +}; + +GLfloat letterH[][3] = +{ + {-2.570000, 0.000000, 0.000000}, + {-2.570000, 6.208000, 0.000000}, + {-1.282000, 6.208000, 0.000000}, + {-1.282000, 3.900000, 0.000000}, + {1.280000, 3.900000, 0.000000}, + {1.280000, 6.208000, 0.000000}, + {2.568000, 6.208000, 0.000000}, + {2.568000, 0.000000, 0.000000}, + {1.280000, 0.000000, 0.000000}, + {1.280000, 2.760000, 0.000000}, + {-1.282000, 2.760000, 0.000000}, + {-1.282000, 0.000000, 0.000000} +}; + +/* Initialize light source and lighting. + */ + + +static void checkErrors(void) +{ + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error)); + } +} + +void myinit(void) +{ + int count1 = sizeof(letterM) / (3 * sizeof(GLfloat)); + int count2 = sizeof(letterO) / (3 * sizeof(GLfloat)); + int count3 = sizeof(letterT) / (3 * sizeof(GLfloat)); + int count4 = sizeof(letterH) / (3 * sizeof(GLfloat)); + + int i; + + GLfloat light_ambient[] = { 1.0, 1.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); + + glDrawBuffer(GL_FRONT_AND_BACK); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_ACCUM_BUFFER_BIT); + glDrawBuffer(GL_BACK); + +/* Zero position of text */ + + for(i = 0; i < count1; i++) { + letterM[i][1] = letterM[i][1] - 3.175; + } + for(i = 0; i < count2; i++) { + letterO[i][1] = letterO[i][1] - 3.175; + } + for(i = 0; i < count3; i++) { + letterT[i][1] = letterT[i][1] - 3.175; + } + for(i = 0; i < count4; i++) { + letterH[i][1] = letterH[i][1] - 3.175; + } +} + + +/* Mark Kilgard's tessellation code from the "dino" demos. */ +void extrudeSolidFromPolygon(GLfloat data[][3], unsigned int dataSize, + GLdouble thickness, GLuint side, GLuint edge, GLuint whole) +{ + GLdouble vertex[3], dx, dy, len; + int i, k; + int flag = 0; + int count = dataSize / (3 * sizeof(GLfloat)); + static GLUtriangulatorObj *tobj = NULL; + + if (tobj == NULL) { + tobj = gluNewTess(); + + gluTessCallback(tobj, GLU_BEGIN, glBegin); + gluTessCallback(tobj, GLU_VERTEX, glVertex3fv); + gluTessCallback(tobj, GLU_END, glEnd); + } + glNewList(side, GL_COMPILE); + glShadeModel(GL_SMOOTH); + gluBeginPolygon(tobj); + for(i = 0; i < count; i++) { + /* This detects a new contour from a large number placed in + the unused z coordinate of the vertex where the new contour + starts. See the coordinates for letterO, above. The coordinate + must be reset below for additional calls. */ + + if (data[i][2] > 1000.0) { + data[i][2] = 0.0; + flag = 1; k = i; + gluNextContour(tobj, GLU_INTERIOR); + } + + vertex[0] = data[i][0]; + vertex[1] = data[i][1]; + vertex[2] = 0.0; + gluTessVertex(tobj, vertex, data[i]); + } + gluEndPolygon(tobj); + glEndList(); + + /* Reset coordinate for new calls. */ + if (flag == 1) { + data[k][2] = 10000.0; + flag = 0; + } + glNewList(edge, GL_COMPILE); + glBegin(GL_QUAD_STRIP); + for(i = 0; i <= count; i++) { + glVertex3f(data[i % count][0], data[i % count][1], 0.0); + glVertex3f(data[i % count][0], data[i % count][1], thickness); + /* Normals */ + dx = data[(i+ 1) % count][1] - data[i % count][1]; + dy = data[i % count][0] - data[(i + 1) % count][0]; + len = sqrt(dx * dx + dy * dy); + glNormal3f(dx / len, dy / len, 0.0); + } + glEnd(); + glEndList(); + + glNewList(whole, GL_COMPILE); + glFrontFace(GL_CW); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, edgeColor); + glMaterialfv(GL_FRONT, GL_SHININESS, shininess); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + + glCallList(edge); + glNormal3f(0.0, 0.0, -1.0); + glCallList(side); + glPushMatrix(); + glTranslatef(0.0, 0.0, thickness); + glFrontFace(GL_CCW); + glNormal3f(0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, sideColor); + glMaterialfv(GL_FRONT, GL_SHININESS, shininess); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + + glCallList(side); + glPopMatrix(); + glEndList(); +} + +void repeat(int j) +{ + if(j == 2){ + glPushMatrix(); + glTranslatef((31 * -0.34) , 9.3, -9.6); + glCallList(REPEAT1); + glPopMatrix(); + } + if(j == 3){ + glPushMatrix(); + glTranslatef(31 * -0.34, 9.3, -9.6); + glCallList(REPEAT1); + glPopMatrix(); + glPushMatrix(); + glTranslatef(31 * -.09, 9.3, -9.6); + glCallList(REPEAT2); + glPopMatrix(); + } + if(j == 4){ + glPushMatrix(); + glTranslatef(31 * -0.34, 9.3, -9.6); + glCallList(REPEAT1); + glPopMatrix(); + glPushMatrix(); + glTranslatef(31 * -.09, 9.3, -9.6); + glCallList(REPEAT2); + glPopMatrix(); + glPushMatrix(); + glTranslatef(31 * 0.12, 9.3, -9.6); + glCallList(REPEAT3); + glPopMatrix(); + } +} + +void display(void) +{ + int i, j; + GLfloat xPos = -0.34; + glLoadIdentity(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glTranslatef(0.0, 0.0, -10.0); + + extrudeSolidFromPolygon(letterM, sizeof(letterM), width2, REPEAT_SIDE, + REPEAT_EDGE, REPEAT1); + extrudeSolidFromPolygon(letterO, sizeof(letterO), width2, REPEAT2_SIDE, + REPEAT2_EDGE, REPEAT2); + extrudeSolidFromPolygon(letterT, sizeof(letterT), width2, REPEAT3_SIDE, + REPEAT3_EDGE, REPEAT3); + extrudeSolidFromPolygon(letterH, sizeof(letterH), width2, REPEAT4_SIDE, + REPEAT4_EDGE, REPEAT4); + + for(j = 1; j < 5; j++){ + width = 0.0; +checkErrors(); + for(i = 0; i < 10; i++){ + + glPushMatrix(); + repeat(j); + glPopMatrix(); + + glPushMatrix(); + glRotatef(90.0, 0.0, 1.0, 0.0); + if(j == 1){ + extrudeSolidFromPolygon(letterM, sizeof(letterM), width, M_SIDE, + M_EDGE, M_WHOLE); + glCallList(M_WHOLE); + } + if(j == 2){ + extrudeSolidFromPolygon(letterO, sizeof(letterO), width, O_SIDE, + O_EDGE, O_WHOLE); + glCallList(O_WHOLE); + } + if(j == 3){ + extrudeSolidFromPolygon(letterT, sizeof(letterT), width, T_SIDE, + T_EDGE, T_WHOLE); + glCallList(T_WHOLE); + } + if(j == 4){ + extrudeSolidFromPolygon(letterH, sizeof(letterH), width, H_SIDE, + H_EDGE, H_WHOLE); + glCallList(H_WHOLE); + } + glutSwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + width = width + 0.2; + glPopMatrix(); + } + for(i = 0; i < 45 ; i++){ + + glPushMatrix(); + repeat(j); + glPopMatrix(); + + glPushMatrix(); + glRotatef(90.0 - (2.0 * i), 0.0, 1.0, 0.0); + if(j == 1){ + glCallList(M_WHOLE); + } + if(j == 2){ + glCallList(O_WHOLE); + } + if(j == 3){ + glCallList(T_WHOLE); + } + if(j == 4){ + glCallList(H_WHOLE); + } + glutSwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPopMatrix(); + } + for(i = 1; i < 32 ; i++){ + + glPushMatrix(); + repeat(j); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(i * xPos, i * 0.3, i * -0.3); + if(j == 1){ + glCallList(M_WHOLE); + } + if(j == 2){ + glCallList(O_WHOLE); + } + if(j == 3){ + glCallList(T_WHOLE); + } + if(j == 4){ + glCallList(H_WHOLE); + } + glutSwapBuffers(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glPopMatrix(); + } + + if(j == 1){ + xPos = xPos + 0.25; + } + else{ + xPos = xPos + 0.21; + } + } + glFlush(); +} + +void myReshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-7.0, 7.0, -7.0, 7.0, 6.0, 20.0); +/* if (w <= h) + glOrtho (-7.0, 7.0, -7.0*(GLfloat)h/(GLfloat)w, + 7.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0); + else + glOrtho (-7.0*(GLfloat)w/(GLfloat)h, + 7.0*(GLfloat)w/(GLfloat)h, -7.0, 7.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_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutCreateWindow ("text3d"); + +/*glCullFace(GL_FRONT);*/ +/*glEnable(GL_CULL_FACE);*/ + + myinit(); + glutReshapeFunc (myReshape); + glutDisplayFunc (display); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/contrib/text3d.dsp b/lib/glut-3.7.6/progs/contrib/text3d.dsp new file mode 100644 index 0000000000..7f1dc794bf --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/text3d.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="text3d" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=text3d - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "text3d.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "text3d.mak" CFG="text3d - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "text3d - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "text3d - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "text3d - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "text3d - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "text3d - Win32 Release" +# Name "text3d - Win32 Debug" +# Begin Source File + +SOURCE=.\text3d.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/contrib/worms.c b/lib/glut-3.7.6/progs/contrib/worms.c new file mode 100644 index 0000000000..95efed8570 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/worms.c @@ -0,0 +1,519 @@ +#if 0 +From jallen@cs.hmc.edu Fri Feb 17 00:49:59 1995 +Received: from giraffe.asd.sgi.com by hoot.asd.sgi.com via SMTP (940816.SGI.8.6.9/940406.SGI.AUTO) + for id AAA13591; Fri, 17 Feb 1995 00:49:33 -0800 +Received: from sgi.sgi.com by giraffe.asd.sgi.com via SMTP (920330.SGI/920502.SGI) + for mjk@hoot.asd.sgi.com id AA09774; Fri, 17 Feb 95 00:52:30 -0800 +Received: from cs.hmc.edu by sgi.sgi.com via SMTP (950215.405.SGI.8.6.10/910110.SGI) + for id AAA06439; Fri, 17 Feb 1995 00:52:28 -0800 +Received: by cs.hmc.edu (5.0/SMI-SVR4) + id AA13309; Fri, 17 Feb 1995 00:52:10 -0800 +Date: Fri, 17 Feb 1995 00:52:10 -0800 +From: jallen@cs.hmc.edu (Jeff R. Allen) +Message-Id: <9502170852.AA13309@cs.hmc.edu> +To: nate@cs.hmc.edu (Nathan Tuck), mjk@sgi.sgi.com, hadas@cs.hmc.edu +Subject: Re: GLUT demos +In-Reply-To: <9502100805.AA08487@cs.hmc.edu> +References: <9502100805.AA08487@cs.hmc.edu> +Reply-To: Jeff Allen +Content-Length: 12851 +Status: RO + +Below is a program I wrote for the Graphics class at Harvey Mudd. As +the comments explain, I am currently working on a version in 3D with +lighting, and a pre-programmed camera flight-path. I also added a +checker-board-type-thing for the worms to crawl around on, so that +there is some reference for the viewer. + +For now, here is the program. + +-- +Jeff R. Allen | Senior CS major | Support your local +(fnord) | South 351d, x4940 | unicyclist! + +------------------------- begin worms.c ------------------------- +#endif + +/* worms.c -- demos OpenGL in 2D using the GLUT interface to the + underlying window system. + + Compile with: [g]cc -O3 -o worms worms.c -lm -lGLU -lglut -lXmu -lX11 -lGL + + This is a fun little demo that actually makes very little use of + OpenGL and GLUT. It generates a bunch of worms and animates them as + they crawl around your screen. When you click in the screen with + the left mouse button, the worms converge on the spot for a while, + then go back to their business. The animation is incredibly simple: + we erase the tail, then draw a new head, repeatedly. It is so + simple, actually, we don't even need double-buffering! + + The behavior of the worms can be controlled via the compile-time + constants below. Enterprising indiviuals wil want to add GLUT menus + to control these constants at run time. This is left as an exercise + to the reader. The only thing that can currently be controlled is + wether or not the worms are filled. Use the right button to get a popup + menu. + + A future version of this program will make more use of OpenGL by + rendering 3d worms crawling in 3-space (or possibly just around on + a plane) and it will allow the user to manipulate the viewpoint + using the mouse. This will require double-buffering and less + optimal updates. + + This program is Copyright 1995 by Jeff R. Allen . + Permission is hereby granted to use and modify this code freely, + provided it is not sold or redistibuted in any way for profit. This + is copyrighted material, and is NOT in the Public Domain. + + $Id: //sw/main/apps/OpenGL/glut/progs/contrib/worms.c#6 $ + + */ + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#define drand48() (((float) rand())/((float) RAND_MAX)) +#define srand48(x) (srand((x))) +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* operational constants */ +#define RADIAN .0174532 +#define CIRCLE_POINTS 25 +#define SIDETOLERANCE .01 +#define INITH 500 +#define INITW 500 + +/* worm options */ +#define SEGMENTS 20 +#define SEG_RADIUS 0.01 +#define STEPSIZE 0.01 +#define MAXTURN (20 * RADIAN) /* in radians */ +#define MAXWORMS 400 +#define INITWORMS 40 +#define MARKTICKS 100 + +typedef struct worm_s { + float dir; /* direction in radians */ + float segx[SEGMENTS]; /* location of segments. */ + float segy[SEGMENTS]; + GLfloat *color; /* pointer to the RGB color of the worm */ + int head; /* which elt of seg[xy] is currently head */ + /* the tail is always (head+1 % SEGMENTS) */ +} worm_t; + +/* colors available for worms... this is a huge mess because I + originally brought these colors in from rgb.txt as integers, + but they have to be normalized into floats. And C is stupid + and truncates them unless I add the annoying .0's + */ + +const GLfloat colors[][3] = { + { 255.0/255.0, 0.0/255.0, 0.0/255.0}, + { 238.0/255.0, 0.0/255.0, 0.0/255.0}, + { 205.0/255.0, 0.0/255.0, 0.0/255.0}, + { 0.0/255.0, 255.0/255.0, 0.0/255.0}, + { 0.0/255.0, 238.0/255.0, 0.0/255.0}, + { 0.0/255.0, 205.0/255.0, 0.0/255.0}, + { 0.0/255.0, 0.0/255.0, 255.0/255.0}, + { 0.0/255.0, 0.0/255.0, 238.0/255.0}, + { 0.0/255.0, 0.0/255.0, 205.0/255.0}, + { 255.0/255.0, 255.0/255.0, 0.0/255.0}, + { 238.0/255.0, 238.0/255.0, 0.0/255.0}, + { 205.0/255.0, 205.0/255.0, 0.0/255.0}, + { 0.0/255.0, 255.0/255.0, 255.0/255.0}, + { 0.0/255.0, 238.0/255.0, 238.0/255.0}, + { 0.0/255.0, 205.0/255.0, 205.0/255.0}, + { 255.0/255.0, 0.0/255.0, 255.0/255.0}, + { 238.0/255.0, 0.0/255.0, 238.0/255.0}, + { 205.0/255.0, 0.0/255.0, 205.0/255.0}, +}; + +#define COLORS 18 + +/* define's for the menu item numbers */ +#define MENU_NULL 0 +#define MENU_FILLED 1 +#define MENU_UNFILLED 2 +#define MENU_QUIT 3 + +/* flag to determine how to draw worms; set by popup menu -- starts out + filled in + */ +int filled = 1; + +/* the global worm array */ +worm_t worms[MAXWORMS]; +int curworms = 0; + +/* global window extent variables */ +GLfloat gleft = -1.0, gright = 1.0, gtop = 1.0, gbottom = -1.0; +GLint wsize, hsize; + +/* globals for marking */ +float markx, marky; +int marktime; + +/* prototypes */ +void mydisplay(void); + +void drawCircle(float x0, float y0, float radius) +{ + int i; + float angle; + + /* a table of offsets for a circle (used in drawCircle) */ + static float circlex[CIRCLE_POINTS]; + static float circley[CIRCLE_POINTS]; + static int inited = 0; + + if (! inited) { + for (i = 0; i < CIRCLE_POINTS; i++) { + angle = 2.0 * M_PI * i / CIRCLE_POINTS; + circlex[i] = cos(angle); + circley[i] = sin(angle); + } + inited++; + }; + + if (filled) + glBegin(GL_POLYGON); + else + glBegin(GL_LINE_LOOP); + for(i = 0; i < CIRCLE_POINTS; i++) + glVertex2f((radius * circlex[i]) + x0, (radius * circley[i]) + y0); + glEnd(); + + return; +} + +void drawWorm(worm_t *theworm) +{ + int i; + + glColor3fv(theworm->color); + for (i = 0; i < SEGMENTS; i++) + drawCircle(theworm->segx[i], theworm->segy[i], SEG_RADIUS); + + return; +} + +void myinit(void) +{ + int i, j, thecolor; + float thedir; + + srand48(time(NULL)); + + curworms = INITWORMS; + + for (j = 0; j < curworms; j++) { + /* divide the circle up into a number of pieces, and send one worm + each direction. + */ + worms[j].dir = ((2.0 * M_PI) / curworms) * j; + thedir = worms[j].dir; + + worms[j].segx[0] = 0.0; + worms[j].segy[0] = 0.0; + + for (i = 1; i < SEGMENTS; i++) { + worms[j].segx[i] = worms[j].segx[i-1] + (STEPSIZE * cos(thedir)); + worms[j].segy[i] = worms[j].segx[i-1] + (STEPSIZE * sin(thedir)); + }; + worms[j].head = (SEGMENTS - 1); + + /* make this worm one of the predefined colors */ + thecolor = (int) COLORS * drand48(); + worms[j].color = (GLfloat *) colors[thecolor]; + }; + + /* now that they are all set, draw them as though they have just been + uncovered + */ + mydisplay(); +} + + + +/* this routine is called after the coordinates are changed to make sure + worms outside the window come back into view right away. (This behavior + is arbitrary, but they are my worms, and they'll do what I please!) + */ + +void warpWorms(void) +{ + register int j, head; + + for (j = 0; j < curworms; j++) { + head = worms[j].head; + + if (worms[j].segx[head] < gleft) + worms[j].segx[head] = gleft; + if (worms[j].segx[head] > gright) + worms[j].segx[head] = gright; + if (worms[j].segx[head] > gtop) + worms[j].segx[head] = gtop; + if (worms[j].segx[head] < gbottom) + worms[j].segx[head] = gbottom; + } +} + +/* a bunch of extra hoopla goes on here to change the Global coordinate + space at teh same rate that the window itself changes. This give the + worms more space to play in when the window gets bigger, and vice versa. + The alternative would be to end up with big worms when the window gets + big, and that looks silly. + */ + +void myreshape (GLsizei w, GLsizei h) +{ + float ratiow = (float) w/INITW; + float ratioh = (float) h/INITH; + + glViewport(0,0,w,h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gleft = -1 * ratiow; + gright = 1 * ratiow; + gbottom = -1 * ratioh; + gtop = 1 * ratioh; + + gluOrtho2D(gleft, gright, gbottom, gtop); + warpWorms(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + wsize = w; hsize = h; + + return; +} + + +/* given a pointer to a worm, this routine will decide on the next + place to put a head and will advance the head pointer + */ + +void updateWorm(worm_t *theworm) +{ + int newhead; + float prevx, prevy; + float newh = -1, newv = -1; + float num, denom; + + /* make an easy to reference local copy of head, and update it in + the worm structure. The new head replaces the old tail. + */ + newhead = (theworm->head + 1) % SEGMENTS; + + prevx = theworm->segx[theworm->head]; + prevy = theworm->segy[theworm->head]; + + /* if there is a mark, home in on it. After this, we still allow + the random adjustment so that the worms play around a bit on the + way to the mark. + */ + if (marktime) { + num = marky - prevy; + denom = markx - prevx; + theworm->dir = atan2(num,denom); + }; + + /* make a bit of a turn: between -MAXTURN and MAXTURN degrees change + to dir (actualy theworm->dir is in radians for later use with + cosf(). + */ + theworm->dir += (MAXTURN - (2 * MAXTURN * (float) drand48())); + + theworm->segx[newhead] = prevx + (STEPSIZE * cos(theworm->dir)); + theworm->segy[newhead] = prevy + (STEPSIZE * sin(theworm->dir)); + + /* if we are at an edge, change direction so that we are heading away + from the edge in question. There might be a problem here handling + corner cases, but I have never seen a worm get stuck, so what the + heck... + */ + if (theworm->segx[newhead] <= gleft) + theworm->dir = 0; + if (theworm->segx[newhead] >= gright) + theworm->dir = (180 * RADIAN); + if (theworm->segy[newhead] >= gtop) + theworm->dir = (270 * RADIAN); + if (theworm->segy[newhead] <= gbottom) + theworm->dir = (90 * RADIAN); + + if ((newv >= 0) || (newh >= 0)) { + newh = (newh<0) ? 0 : newh; + newv = (newv<0) ? 0 : newv; + }; + + /* update the permanent copy of the new head index */ + theworm->head = newhead; +} + +/* updates the worms -- drawing takes place here, which may actually + be a bad idea. It will probably be better to update the internal + state only here, then post a redisplay using GLUT. +*/ + +void myidle (void) +{ + register int i, tail; + + if (marktime) + marktime--; + + for (i = 0; i < curworms; i++) { + /* first find tail */ + tail = (worms[i].head + 1) % SEGMENTS; + + /* erase tail */ + glColor3f(0.0, 0.0, 0.0); + drawCircle(worms[i].segx[tail], worms[i].segy[tail], SEG_RADIUS); + + /* update head segment position and head pointer */ + updateWorm(&worms[i]); + + /* draw head */ + glColor3fv(worms[i].color); + drawCircle(worms[i].segx[worms[i].head], worms[i].segy[worms[i].head], + SEG_RADIUS); + }; + + glFlush(); + return; +} + +/* redraws the worms from scratch -- called after a window gets obscured */ + +void mydisplay(void) +{ + int i; + +#ifndef WORMS_EAT_BACKGROUND + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); +#endif + + for (i = 0; i < curworms; i++) + drawWorm(&worms[i]); + + glFlush(); + return; +} + +/* this routine gets called when the mouse is clicked. The incoming + coordinates are in screen coordinates relative to the upper-left corner + of the window, and oriented according to X, not to GL. So, here we + convert the given coordinates into worm-world coordinates, and set the + mark. + */ + +void markSpot(int x, int y) +{ + /* map into the corridinate space I am using */ + markx = (float)((x - wsize/2)*(gright - gleft)/wsize); + marky = -(float)((y - hsize/2)*(gtop - gbottom)/hsize); + + marktime = MARKTICKS; +} + +void handleMouse(int btn, int state, int x, int y) +{ + switch (btn) { + + case (GLUT_LEFT_BUTTON): + if (state == GLUT_UP) + markSpot(x,y); + break; + + default: + /* do nothing */ + break; + } + + return; +} + +void menuSelect(int value) +{ + switch (value) { + case MENU_FILLED: + filled = 1; + break; + + case MENU_UNFILLED: + filled = 0; + break; + + case MENU_QUIT: + exit(0); + break; + + case MENU_NULL: + return; + + default: + break; + }; + + glutPostRedisplay(); + return; +} + +void visibility(int status) +{ + if (status == GLUT_VISIBLE) + glutIdleFunc(myidle); + else + glutIdleFunc(NULL); +} + +/* this is where GLUT is initialized, and the whole thing starts up. + All animation and redisplay happens via the callbacks registered below. + */ + +int main(int argc, char **argv) +{ + int fillmenu = 0; + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(INITW, INITH); + glutCreateWindow("Worms"); + + myinit(); + + glutDisplayFunc(mydisplay); + glutVisibilityFunc(visibility); + glutReshapeFunc(myreshape); + glutMouseFunc(handleMouse); + + /* popup menu, courtsey of GLUT */ + fillmenu = glutCreateMenu(menuSelect); + glutAddMenuEntry("Filled", MENU_FILLED); + glutAddMenuEntry("Unfilled", MENU_UNFILLED); + + glutCreateMenu(menuSelect); + glutAddMenuEntry(" WORMS", MENU_NULL); + glutAddSubMenu("Drawing Mode", fillmenu); + glutAddMenuEntry("Quit", MENU_QUIT); + + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} + + diff --git a/lib/glut-3.7.6/progs/contrib/worms.dsp b/lib/glut-3.7.6/progs/contrib/worms.dsp new file mode 100644 index 0000000000..fe85e96669 --- /dev/null +++ b/lib/glut-3.7.6/progs/contrib/worms.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="worms" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=worms - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "worms.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "worms.mak" CFG="worms - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "worms - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "worms - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "worms - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "worms - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "worms - Win32 Release" +# Name "worms - Win32 Debug" +# Begin Source File + +SOURCE=.\worms.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/data/00.rgb b/lib/glut-3.7.6/progs/data/00.rgb new file mode 100644 index 0000000000000000000000000000000000000000..ec7f50f58937179bbc7a35dd8b15db81ae3282d7 GIT binary patch literal 13275 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 VZf-6vPBvyqC1rIDEdyHz1^`oq%jEz7 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/01.rgb b/lib/glut-3.7.6/progs/data/01.rgb new file mode 100644 index 0000000000000000000000000000000000000000..8a0568465f7198833d2e62ac1d973030758617f5 GIT binary patch literal 13552 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/02.rgb b/lib/glut-3.7.6/progs/data/02.rgb new file mode 100644 index 0000000000000000000000000000000000000000..56b846111207a7178ca3753b8f1d709f78398882 GIT binary patch literal 13284 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¨B2iYAtuZ(%q?xF&MeZ;&B@Hk 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/03.rgb b/lib/glut-3.7.6/progs/data/03.rgb new file mode 100644 index 0000000000000000000000000000000000000000..3ec52599a05ba4598c6940e8aa3bd54b284fd888 GIT binary patch literal 14103 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/05.rgb b/lib/glut-3.7.6/progs/data/05.rgb new file mode 100644 index 0000000000000000000000000000000000000000..84e719949c9d23c8ee256e10ac825d534400f4ff GIT binary patch literal 7160 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 AHvj+t literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/brick.rgb b/lib/glut-3.7.6/progs/data/brick.rgb new file mode 100644 index 0000000000000000000000000000000000000000..d37b755d9e5ca24ebbe22dbbc46332dcda1fd911 GIT binary patch literal 66048 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 M{-H4c4BPn&034T{Z2$lO literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/brush.rgb b/lib/glut-3.7.6/progs/data/brush.rgb new file mode 100644 index 0000000000000000000000000000000000000000..45a59364484626a634c04b0516f762756171562c GIT binary patch literal 10097 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 GfdK%OarA)z literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/newave/texmap.rgb b/lib/glut-3.7.6/progs/demos/newave/texmap.rgb new file mode 100644 index 0000000000000000000000000000000000000000..9d41d5efdad836fb38016eea34e357aac9ff7468 GIT binary patch literal 810169 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¬^sV;nT+tZ`{9s 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

    )xFEM-TC(S-_Lh1UVM1^>fPHHhj!m* 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

    S5I44SKoyGIV(4B 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

    ~*&uJ-zqn%KWP4%;Kx?zZFr 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

    GmiA`y?AEz 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 jlgj&pYO)gw8d?=n`<-4qg@!Y8Cw_t+%u +#include +#include +#include + +void +bwtorgba(unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = 0xff; + l += 4; b++; + } +} + +void +rgbtorgba(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] = 0xff; + l += 4; r++; g++; b++; + } +} + +void +rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l[3] = a[0]; + l += 4; r++; g++; b++; a++; + } +} + +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, *tmpR, *tmpG, *tmpB; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +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) { + perror(fileName); + exit(1); + } + + fread(image, 1, 12, image->file); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + image->tmp = (unsigned char *)malloc(image->xsize*256); + image->tmpR = (unsigned char *)malloc(image->xsize*256); + image->tmpG = (unsigned char *)malloc(image->xsize*256); + image->tmpB = (unsigned char *)malloc(image->xsize*256); + if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL || + image->tmpB == NULL) { + fprintf(stderr, "Out 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, "Out 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->tmpR); + free(image->tmpG); + free(image->tmpB); + 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); + } +} + +unsigned * +read_texture(char *name, int *width, int *height, int *components) { + unsigned *base, *lptr; + unsigned char *rbuf, *gbuf, *bbuf, *abuf; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if(!image) + return NULL; + (*width)=image->xsize; + (*height)=image->ysize; + (*components)=image->zsize; + base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned)); + 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) + return NULL; + lptr = 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); + rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==3) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else { + ImageGetRow(image,rbuf,y,0); + bwtorgba(rbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } + } + ImageClose(image); + free(rbuf); + free(gbuf); + free(bbuf); + free(abuf); + + return (unsigned *) base; +} + +void imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4], + int *wOut, int *hOut, GLubyte ** imgOut) +{ + int border = borderIn; + int width, height; + int w, h; + GLubyte *image, *img, *p; + int i, j, components; + + image = (GLubyte *) read_texture(filenameIn, &width, &height, &components); + w = width + 2 * border; + h = height + 2 * border; + img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char)); + + p = img; + for (j = -border; j < height + border; ++j) { + for (i = -border; i < width + border; ++i) { + if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) { + p[0] = image[4 * (j * width + i) + 0]; + p[1] = image[4 * (j * width + i) + 1]; + p[2] = image[4 * (j * width + i) + 2]; + p[3] = 0xff; + } else { + p[0] = borderColorIn[0] * 0xff; + p[1] = borderColorIn[1] * 0xff; + p[2] = borderColorIn[2] * 0xff; + p[3] = borderColorIn[3] * 0xff; + } + p += 4; + } + } + free(image); + *wOut = w; + *hOut = h; + *imgOut = img; +} diff --git a/lib/glut-3.7.6/progs/demos/newave/texture.h b/lib/glut-3.7.6/progs/demos/newave/texture.h new file mode 100644 index 0000000000..d2b8c025ad --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/newave/texture.h @@ -0,0 +1,11 @@ + +/* texture.h - by David Blythe, SGI */ + +/* Simple SGI .rgb image file loader routine. */ +unsigned * +read_texture(char *name, int *width, int *height, int *components); + +extern void imgLoad(char *filenameIn, + int borderIn, GLfloat borderColorIn[4], + int *wOut, int *hOut, GLubyte ** imgOut); + diff --git a/lib/glut-3.7.6/progs/demos/opengl_logo/Imakefile b/lib/glut-3.7.6/progs/demos/opengl_logo/Imakefile new file mode 100644 index 0000000000..ac0c51d861 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/opengl_logo/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = opengl_logo + +SRCS = opengl_logo.c def_logo.c + +OBJS = opengl_logo.o def_logo.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(opengl_logo,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/opengl_logo/def_logo.c b/lib/glut-3.7.6/progs/demos/opengl_logo/def_logo.c new file mode 100644 index 0000000000..41b9e201a1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/opengl_logo/def_logo.c @@ -0,0 +1,622 @@ +/* + * Def_logo.c + * + * This file is part of the openGL-logo demo. + * (c) Henk Kok (kok@wins.uva.nl) + * + * Copying, redistributing, etc is permitted as long as this copyright + * notice and the Dutch variable names :) stay in tact. + */ + +#include +#include +#include + +/* some math.h's don't define M_PI */ +#ifndef M_PI +#define M_PI 3.14159265359 +#endif + +#define ACC 8 +#define ACC2 16 +#define ACC3 48 +#define ACC4 24 +#define THLD 0.6 +#define THLD2 0.8 + +extern int angle, rotating; +extern float progress; + +GLfloat TRANS[7][3]; +GLfloat ROTAXIS[7][3]; +GLfloat ROT[7]; + +GLfloat char_El[ACC3+1][ACC][3]; +GLfloat normal_El[ACC3+1][ACC][3]; + +GLfloat char_O[ACC4][ACC][3]; +GLfloat normal_O[ACC4][ACC][3]; + +GLfloat char_P[ACC2][ACC][3]; +GLfloat normal_P[ACC2][ACC][3]; + +GLfloat char_G[ACC4][ACC][3]; +GLfloat normal_G[ACC4][ACC][3]; + +GLfloat accSIN[ACC], accCOS[ACC]; + +GLfloat difmat4[4] = { 0.425, 0.570, 0.664, 1.0 }; +GLfloat difamb4[4] = { 0.425, 0.570, 0.664, 1.0 }; +GLfloat matspec4[4] = { 0.174, 0.174, 0.174, 1.0 }; + +int rnd(int i) +{ + return rand()%i; +} + +void groen_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat4); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb4); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec4); + glMaterialf(GL_FRONT, GL_SHININESS, 35.0); +} + +void def_O(void) +{ + float a, s, c, ln; + int i,j,k,l,m,n; + float dx, dy; + float dx1, dx2, dy1, dy2, dz1, dz2; + GLfloat center_O[ACC4+4][3]; + GLfloat width_O[ACC4+4]; + for (i=0;i1.01?0.8:0)) + 0.8; + center_O[i][2] = 0.0; + width_O[i] = 0.6; + } +/* I should be able to generalise this. oh well */ + for (i=0;iTHLD?THLD:s)); + } + } + for (i=0;i1.01?0.7:0)) + 0.7; + center_P[i][2] = 0.0; + width_P[i] = 0.5; + } + + for (i=0;iTHLD?THLD:s)); + } + } + for (i=0;iTHLD2?THLD2:s)); + } + } + for (i=0;i1.01?0.8:0)) + 0.8; + center_G[i][2] = 0.0; + width_G[i] = 0.9; + if (i>ACC4*3/4) + width_G[i] = 0.9 - ((i-ACC4*3/4)*0.9)/ACC; + } + for (i=0;iTHLD?THLD:s)); + } + } + for (i=0;i=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + for (j=0;j=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + for (j=0;j=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + glNormal3f(normal_P[0][k][0], normal_P[0][k][1], normal_P[0][k][2]); + glVertex3f(char_P[0][k][0], char_P[0][k][1]+0.0, char_P[0][k][2]); + glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]); + glVertex3f(char_P[0][i][0], char_P[0][i][1]+0.0, char_P[0][i][2]); + for (j=1;j=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + for (j=0;j<=ACC3;j++) + { + glNormal3f(normal_El[j][k][0], normal_El[j][k][1], normal_El[j][k][2]); + glVertex3f(char_El[j][k][0], char_El[j][k][1], char_El[j][k][2]); + glNormal3f(normal_El[j][i][0], normal_El[j][i][1], normal_El[j][i][2]); + glVertex3f(char_El[j][i][0], char_El[j][i][1], char_El[j][i][2]); + } + glEnd(); + } +} + +void draw_N(void) +{ + int i,j,k; + for (i=0;i=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + for (j=0;j<=ACC2/2;j++) + { + glNormal3f(normal_P[j][k][0], normal_P[j][k][1], normal_P[j][k][2]); + glVertex3f(char_P[j][k][0], char_P[j][k][1], char_P[j][k][2]); + glNormal3f(normal_P[j][i][0], normal_P[j][i][1], normal_P[j][i][2]); + glVertex3f(char_P[j][i][0], char_P[j][i][1], char_P[j][i][2]); + } + glEnd(); + } + + j = 0; + glBegin(GL_QUAD_STRIP); + for (i=0;i=ACC) + k = 0; + glBegin(GL_QUAD_STRIP); + glNormal3f(normal_G[0][k][0], normal_G[0][k][1], normal_G[0][k][2]); + glVertex3f(char_G[0][k][0], char_G[0][k][1]+1.2, char_G[0][k][2]); + glNormal3f(normal_G[0][i][0], normal_G[0][i][1], normal_G[0][i][2]); + glVertex3f(char_G[0][i][0], char_G[0][i][1]+1.2, char_G[0][i][2]); + for (j=1;j=0;i--) + glVertex3f(5.6, 0.9+0.9*accSIN[i], 0.9*accCOS[i]); + glVertex3f(5.6, 0.9+0.9*accSIN[ACC-1], 0.9*accCOS[ACC-1]); + glEnd(); +} + +void draw_part(int i) +{ + glPushMatrix(); + glTranslatef(TRANS[i][0]*progress, TRANS[i][1]*progress, TRANS[i][2]*progress); + glRotatef(ROT[i]*progress, ROTAXIS[i][0], ROTAXIS[i][1], ROTAXIS[i][2]); + switch(i) + { + case 0: draw_El(); break; + case 1: draw_O(); break; + case 2: draw_P(); break; + case 3: draw_E(); break; + case 4: draw_N(); break; + case 5: draw_G(); break; + case 6: draw_L(); break; + } + glPopMatrix(); +} + +void draw_logo(void) +{ + groen_texture(); + glEnable(GL_CULL_FACE); + glTranslatef(-2.8, 0.0, 0.0); + + draw_part(0); + glTranslatef(-12.0, 4.3, 0.0); + draw_part(1); + glTranslatef(7.3, 0.0, 0.0); + draw_part(2); + glTranslatef(5.4, 0.0, 0.0); + draw_part(3); + glTranslatef(5.4, 0.0, 0.0); + draw_part(4); + glTranslatef(7.4, 0.0, 0.0); + draw_part(5); + glTranslatef(6.8, 0.0, 0.0); + draw_part(6); +} diff --git a/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.c b/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.c new file mode 100644 index 0000000000..1672858d6d --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.c @@ -0,0 +1,133 @@ +/* + * Main.c + * + * This file is part of the openGL-logo demo. + * (c) Henk Kok (kok@wins.uva.nl) + * + * Copying, redistributing, etc is permitted as long as this copyright + * notice and the Dutch variable names :) stay in tact. + */ + +#include +#include +#include +#include + +GLfloat lightpos[4] = { 1.0, 1.0, 1.0, 0.0 }; +GLfloat lightamb[4] = { 0.3, 0.3, 0.3, 1.0 }; +GLfloat lightdif[4] = { 0.8, 0.8, 0.8, 1.0 }; +float speed=0, progress = 1; +void SetCamera(void); + +extern void randomize(void); +extern void def_logo(void); +extern void draw_logo(void); + +void do_display (void) +{ + SetCamera(); + draw_logo(); + glFlush(); + glutSwapBuffers(); +} + +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + do_display(); +} + +void myinit (void) +{ + glShadeModel (GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightdif); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glColor3f(1.0, 1.0, 1.0); + glClearColor(0.0, 0.0, 0.0, 1.0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_NORMALIZE); + def_logo(); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); +} + +/* ARGSUSED1 */ +void parsekey(unsigned char key, int x, int y) +{ + switch (key) + { + case 27: exit(0); break; + case 13: break; + case ' ': progress = 1; randomize(); break; + } +} + +/* ARGSUSED1 */ +void parsekey_special(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP: break; + case GLUT_KEY_DOWN: break; + case GLUT_KEY_RIGHT: break; + case GLUT_KEY_LEFT: break; + } +} + +void Animate(void) +{ + speed = -0.95*speed + progress*0.05; + if (progress > 0.0 && speed < 0.0003) + speed = 0.0003; + if (speed > 0.01) + speed = 0.01; + progress = progress - speed; + if (progress < 0.0) + { + progress = 0.0; + speed = 0; + } + glutPostRedisplay(); +} + +void myReshape(int w, int h) +{ + glMatrixMode (GL_MODELVIEW); + glViewport (0, 0, w, h); + glLoadIdentity(); + SetCamera(); +} + +void SetCamera(void) +{ + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glFrustum (-0.1333, 0.1333, -0.1, 0.1, 0.2, 150.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0,1.5,2, 0,1.5,0, 0,1,0); + glTranslatef(0.0, -8.0, -45.0); + glRotatef(-progress*720, 0.0, 1.0, 0.0); +} + +int main(int argc, char *argv[]) +{ + glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE); + glutInitWindowPosition(200, 0); + glutInitWindowSize(640, 480); + glutCreateWindow("Rotating OpenGL Logo"); + glutDisplayFunc(display); + glutKeyboardFunc(parsekey); + glutSpecialFunc(parsekey_special); + glutReshapeFunc(myReshape); + glutIdleFunc(Animate); + randomize(); + myinit(); + glutSwapBuffers(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.dsp b/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.dsp new file mode 100644 index 0000000000..c5b130d509 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/opengl_logo/opengl_logo.dsp @@ -0,0 +1,92 @@ +# Microsoft Developer Studio Project File - Name="opengl_logo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=opengl_logo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "opengl_logo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "opengl_logo.mak" CFG="opengl_logo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "opengl_logo - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "opengl_logo - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "opengl_logo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "opengl_logo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "opengl_logo - Win32 Release" +# Name "opengl_logo - Win32 Debug" +# Begin Source File + +SOURCE=.\def_logo.c +# End Source File +# Begin Source File + +SOURCE=.\opengl_logo.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/particle/Imakefile b/lib/glut-3.7.6/progs/demos/particle/Imakefile new file mode 100644 index 0000000000..92614a7cbf --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/particle/Imakefile @@ -0,0 +1,15 @@ + +/* Copyright (c) Mark J. Kilgard, 1998. */ + +#include "../../../Glut.cf" + +TARGETS = particle + +SRCS = particle.c +OBJS = particle.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(particle,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/particle/particle.c b/lib/glut-3.7.6/progs/demos/particle/particle.c new file mode 100644 index 0000000000..6dacc6327a --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/particle/particle.c @@ -0,0 +1,728 @@ +/* + particle.c + Nate Robins, 1998 + + An example of a simple particle system. + + */ + + +#include +#include +#include +#include +#include + + +#ifdef _WIN32 +#define drand48() ((float)rand()/RAND_MAX) +#endif + + +/* #define SCREEN_SAVER_MODE */ + +#define PS_GRAVITY -9.8 +#define PS_WATERFALL 0 +#define PS_FOUNTAIN 1 + + +typedef struct { + float x, y, z; + float radius; +} PSsphere; + +typedef struct { + float position[3]; /* current position */ + float previous[3]; /* previous position */ + float velocity[3]; /* velocity (magnitude & direction) */ + float dampening; /* % of energy lost on collision */ + int alive; /* is this particle alive? */ +} PSparticle; + + +PSparticle* particles = NULL; +#define NUM_SPHERES 3 +PSsphere spheres[NUM_SPHERES] = { /* position of spheres */ + { -0.1, 0.6, 0, 0.4 }, + { -0.7, 1.4, 0, 0.25 }, + { 0.1, 1.5, 0.1, 0.3 }, +}; +int num_particles = 10000; +int type = PS_WATERFALL; +int points = 1; +int draw_spheres = 1; +int frame_rate = 1; +float frame_time = 0; +float flow = 500; +float slow_down = 1; + +float spin_x = 0; +float spin_y = 0; +int point_size = 4; + + +/* timedelta: returns the number of seconds that have elapsed since + the previous call to the function. */ +#if defined(_WIN32) +#include +#else +#include +#include +#include +#include +#endif +#ifndef CLK_TCK +#define CLK_TCK 1000 +#endif +float +timedelta(void) +{ + static long begin = 0; + static long finish, difference; + +#if defined(_WIN32) + static struct timeb tb; + ftime(&tb); + finish = tb.time*1000+tb.millitm; +#else + static struct tms tb; + finish = times(&tb); +#endif + + difference = finish - begin; + begin = finish; + + return (float)difference/(float)CLK_TCK; +} + + +/* text: draws a string of text with an 18 point helvetica bitmap font + at position (x,y) in window space (bottom left corner is (0,0). */ +void +text(int x, int y, char* s) +{ + int lines; + char* p; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), + 0, glutGet(GLUT_WINDOW_HEIGHT), -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glColor3ub(0, 0, 0); + glRasterPos2i(x+1, y-1); + for(p = s, lines = 0; *p; p++) { + if (*p == '\n') { + lines++; + glRasterPos2i(x+1, y-1-(lines*18)); + } + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p); + } + glColor3ub(128, 0, 255); + glRasterPos2i(x, y); + for(p = s, lines = 0; *p; p++) { + if (*p == '\n') { + lines++; + glRasterPos2i(x, y-(lines*18)); + } + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p); + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glEnable(GL_FOG); + glEnable(GL_DEPTH_TEST); +} + + +int +fequal(float a, float b) +{ + float epsilon = 0.1; + float f = a - b; + + if (f < epsilon && f > -epsilon) + return 1; + else + return 0; +} + + +void +psTimeStep(PSparticle* p, float dt) +{ + if (p->alive == 0) + return; + + p->velocity[0] += 0; + p->velocity[1] += PS_GRAVITY*dt; + p->velocity[2] += 0; + + p->previous[0] = p->position[0]; + p->previous[1] = p->position[1]; + p->previous[2] = p->position[2]; + + p->position[0] += p->velocity[0]*dt; + p->position[1] += p->velocity[1]*dt; + p->position[2] += p->velocity[2]*dt; +} + + +void +psNewParticle(PSparticle* p, float dt) +{ + if (type == PS_WATERFALL) { + p->velocity[0] = -2*(drand48()-0.0); + p->velocity[1] = 0; + p->velocity[2] = 0.5*(drand48()-0.0); + p->position[0] = 0; + p->position[1] = 2; + p->position[2] = 0; + p->previous[0] = p->position[0]; + p->previous[1] = p->position[1]; + p->previous[2] = p->position[2]; + p->dampening = 0.45*drand48(); + p->alive = 1; + } else if (type == PS_FOUNTAIN) { + p->velocity[0] = 2*(drand48()-0.5); + p->velocity[1] = 5; + p->velocity[2] = 2*(drand48()-0.5); + p->position[0] = -0.1; + p->position[1] = 0.9; + p->position[2] = 0; + p->previous[0] = p->position[0]; + p->previous[1] = p->position[1]; + p->previous[2] = p->position[2]; + p->dampening = 0.35*drand48(); + p->alive = 1; + } + + psTimeStep(p, 2*dt*drand48()); +} + + +/* psBounce: the particle has gone past (or exactly hit) the ground + plane, so calculate the time at which the particle actually + intersected the ground plane (s). essentially, this just rolls + back time to when the particle hit the ground plane, then starts + time again from then. + + - - o A (previous position) + | | \ + | s \ o (position it _should_ be at) - + t | \ / | t - s + | - ------X-------- - + | \ + - o B (new position) + + A + V*s = 0 or s = -A/V + + to calculate where the particle should be: + + A + V*t + V*(t-s)*d + + where d is a damping factor which accounts for the loss + of energy due to the bounce. */ +void +psBounce(PSparticle* p, float dt) +{ + float s; + + if (p->alive == 0) + return; + + /* since we know it is the ground plane, we only need to + calculate s for a single dimension. */ + s = -p->previous[1]/p->velocity[1]; + + p->position[0] = (p->previous[0] + p->velocity[0] * s + + p->velocity[0] * (dt-s) * p->dampening); + p->position[1] = -p->velocity[1] * (dt-s) * p->dampening; /* reflect */ + p->position[2] = (p->previous[2] + p->velocity[2] * s + + p->velocity[2] * (dt-s) * p->dampening); + + /* damp the reflected velocity (since the particle hit something, + it lost some energy) */ + p->velocity[0] *= p->dampening; + p->velocity[1] *= -p->dampening; /* reflect */ + p->velocity[2] *= p->dampening; +} + +void +psCollideSphere(PSparticle* p, PSsphere* s) +{ + float vx = p->position[0] - s->x; + float vy = p->position[1] - s->y; + float vz = p->position[2] - s->z; + float distance; + + if (p->alive == 0) + return; + + distance = sqrt(vx*vx + vy*vy + vz*vz); + + if (distance < s->radius) { +#if 0 + vx /= distance; vy /= distance; vz /= distance; + d = 2*(-vx*p->velocity[0] + -vy*p->velocity[1] + -vz*p->velocity[2]); + p->velocity[0] += vx*d*2; + p->velocity[1] += vy*d*2; + p->velocity[2] += vz*d*2; + d = sqrt(p->velocity[0]*p->velocity[0] + + p->velocity[1]*p->velocity[1] + + p->velocity[2]*p->velocity[2]); + p->velocity[0] /= d; + p->velocity[1] /= d; + p->velocity[2] /= d; +#else + p->position[0] = s->x+(vx/distance)*s->radius; + p->position[1] = s->y+(vy/distance)*s->radius; + p->position[2] = s->z+(vz/distance)*s->radius; + p->previous[0] = p->position[0]; + p->previous[1] = p->position[1]; + p->previous[2] = p->position[2]; + p->velocity[0] = vx/distance; + p->velocity[1] = vy/distance; + p->velocity[2] = vz/distance; +#endif + } +} + + +void +reshape(int width, int height) +{ + float black[] = { 0, 0, 0, 0 }; + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, (float)width/height, 0.1, 1000); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0, 1, 3, 0, 1, 0, 0, 1, 0); + glFogfv(GL_FOG_COLOR, black); + glFogf(GL_FOG_START, 2.5); + glFogf(GL_FOG_END, 4); + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + glPointSize(point_size); + glEnable(GL_POINT_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHT0); + + timedelta(); +} + + +void +display(void) +{ + static int i; + static float c; + static int j = 0; + static char s[32]; + static int frames = 0; + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glPushMatrix(); + + glRotatef(spin_y, 1, 0, 0); + glRotatef(spin_x, 0, 1, 0); + + glEnable(GL_LIGHTING); + if (draw_spheres) { + for (i = 0; i < draw_spheres; i++) { + glPushMatrix(); + glTranslatef(spheres[i].x, spheres[i].y, spheres[i].z); + glColor3ub(0, 255, 128); + glutSolidSphere(spheres[i].radius, 16, 16); + glPopMatrix(); + } + } + glDisable(GL_LIGHTING); + + glBegin(GL_QUADS); + glColor3ub(0, 128, 255); + glVertex3f(-2, 0, -2); + glVertex3f(-2, 0, 2); + glVertex3f(2, 0, 2); + glVertex3f(2, 0, -2); + glEnd(); + + if (points) { + glBegin(GL_POINTS); + + for (i = 0; i < num_particles; i++) { + if (particles[i].alive == 0) + continue; + c = particles[i].position[1]/2.1*255; + glColor3ub(c, 128+c*0.5, 255); + glVertex3fv(particles[i].position); + } + glEnd(); + } else { + glBegin(GL_LINES); + for (i = 0; i < num_particles; i++) { + if (particles[i].alive == 0) + continue; + c = particles[i].previous[1]/2.1*255; + glColor4ub(c, 128+c*0.5, 255, 32); + glVertex3fv(particles[i].previous); + c = particles[i].position[1]/2.1*255; + glColor4ub(c, 128+c*0.5, 255, 196); + glVertex3fv(particles[i].position); + } + glEnd(); + } + + /* spit out frame rate. */ + if (frame_rate) { + frames++; + if (frames > 7) { + sprintf(s, "%g fps", (float)7/frame_time); + frame_time = 0; + frames = 0; + } + text(5, 5, s); + } + + glPopMatrix(); + glutSwapBuffers(); +} + +void +idle(void) +{ + static int i, j; + static int living = 0; /* index to end of live particles */ + static float dt; + static float last = 0; + + dt = timedelta(); + frame_time += dt; + +#if 1 + /* slow the simulation if we can't keep the frame rate up around + 10 fps */ + if (dt > 0.1) { + slow_down = 1.0/(100*dt); + } else if (dt < 0.1) { + slow_down = 1; + } +#endif + + dt *= slow_down; + + /* resurrect a few particles */ + for (i = 0; i < flow*dt; i++) { + psNewParticle(&particles[living], dt); + living++; + if (living >= num_particles) + living = 0; + } + + for (i = 0; i < num_particles; i++) { + psTimeStep(&particles[i], dt); + + /* collision with sphere? */ + if (draw_spheres) { + for (j = 0; j < draw_spheres; j++) { + psCollideSphere(&particles[i], &spheres[j]); + } + } + + /* collision with ground? */ + if (particles[i].position[1] <= 0) { + psBounce(&particles[i], dt); + } + + /* dead particle? */ + if (particles[i].position[1] < 0.1 && + fequal(particles[i].velocity[1], 0)) { + particles[i].alive = 0; + } + } + + glutPostRedisplay(); +} + +void +visible(int state) +{ + if (state == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); +} + +void +bail(int code) +{ + free(particles); + exit(code); +} + +#ifdef SCREEN_SAVER_MODE +void +ss_keyboard(char key, int x, int y) +{ + bail(0); +} + +void +ss_mouse(int button, int state, int x, int y) +{ + bail(0); +} + +void +ss_passive(int x, int y) +{ + static int been_here = 0; + + /* for some reason, GLUT sends an initial passive motion callback + when a window is initialized, so this would immediately + terminate the program. to get around this, see if we've been + here before. (actually if we've been here twice.) */ + + if (been_here > 1) + bail(0); + been_here++; +} + +#else + +void +keyboard(unsigned char key, int x, int y) +{ + static int fullscreen = 0; + static int old_x = 50; + static int old_y = 50; + static int old_width = 512; + static int old_height = 512; + static int s = 0; + + switch (key) { + case 27: + bail(0); + break; + + case 't': + if (type == PS_WATERFALL) + type = PS_FOUNTAIN; + else if (type == PS_FOUNTAIN) + type = PS_WATERFALL; + break; + + case 's': + draw_spheres++; + if (draw_spheres > NUM_SPHERES) + draw_spheres = 0; + break; + + case 'S': + printf("PSsphere spheres[NUM_SPHERES] = {/* position of spheres */\n"); + for (s = 0; s < NUM_SPHERES; s++) { + printf(" { %g, %g, %g, %g },\n", + spheres[s].x, spheres[s].y, + spheres[s].z, spheres[s].radius); + } + printf("};\n"); + break; + + case 'l': + points = !points; + break; + + case 'P': + point_size++; + glPointSize(point_size); + break; + + case 'p': + point_size--; + if (point_size < 1) + point_size = 1; + glPointSize(point_size); + break; + + case '+': + flow += 100; + if (flow > num_particles) + flow = num_particles; + printf("%g particles/second\n", flow); + break; + + case '-': + flow -= 100; + if (flow < 0) + flow = 0; + printf("%g particles/second\n", flow); + break; + + case '#': + frame_rate = !frame_rate; + break; + + case '~': + fullscreen = !fullscreen; + if (fullscreen) { + old_x = glutGet(GLUT_WINDOW_X); + old_y = glutGet(GLUT_WINDOW_Y); + old_width = glutGet(GLUT_WINDOW_WIDTH); + old_height = glutGet(GLUT_WINDOW_HEIGHT); + glutFullScreen(); + } else { + glutReshapeWindow(old_width, old_height); + glutPositionWindow(old_x, old_y); + } + break; + + case '!': + s++; + if (s >= NUM_SPHERES) + s = 0; + break; + + case '4': + spheres[s].x -= 0.05; + break; + + case '6': + spheres[s].x += 0.05; + break; + + case '2': + spheres[s].y -= 0.05; + break; + + case '8': + spheres[s].y += 0.05; + break; + + case '7': + spheres[s].z -= 0.05; + break; + + case '3': + spheres[s].z += 0.05; + break; + + case '9': + spheres[s].radius += 0.05; + break; + + case '1': + spheres[s].radius -= 0.05; + break; + + } +} + +void +menu(int item) +{ + keyboard((unsigned char)item, 0, 0); +} + +void +menustate(int state) +{ + /* hook up a fake time delta to avoid jumping when menu comes up */ + if (state == GLUT_MENU_NOT_IN_USE) + timedelta(); +} +#endif + +int old_x, old_y; + +void +mouse(int button, int state, int x, int y) +{ + old_x = x; + old_y = y; + + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + spin_x = x - old_x; + spin_y = y - old_y; + + glutPostRedisplay(); +} + +int +main(int argc, char** argv) +{ + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + glutInitWindowPosition(0, 0); + glutInitWindowSize(640, 480); + glutInit(&argc, argv); + + glutCreateWindow("Particles"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); +#ifdef SCREEN_SAVER_MODE + glutPassiveMotionFunc(ss_passive); + glutKeyboardFunc(ss_keyboard); + glutMouseFunc(ss_mouse); + glutSetCursor(GLUT_CURSOR_NONE); + glutFullScreen(); +#else + glutMotionFunc(motion); + glutMouseFunc(mouse); + glutKeyboardFunc(keyboard); +#endif + + glutMenuStateFunc(menustate); + glutCreateMenu(menu); + glutAddMenuEntry("Particle", 0); + glutAddMenuEntry("", 0); + glutAddMenuEntry("[f] Fog on/off", 'f'); + glutAddMenuEntry("[t] Spray type", 't'); + glutAddMenuEntry("[s] Collision spheres", 's'); + glutAddMenuEntry("[-] Less flow", '-'); + glutAddMenuEntry("[+] More flow", '+'); + glutAddMenuEntry("[p] Smaller points", 'p'); + glutAddMenuEntry("[P] Larger points", 'P'); + glutAddMenuEntry("[l] Toggle points/lines", 'l'); + glutAddMenuEntry("[#] Toggle framerate on/off", '#'); + glutAddMenuEntry("[~] Toggle fullscreen on/off", '~'); + glutAddMenuEntry("", 0); + glutAddMenuEntry("Use the numeric keypad to move the spheres", 0); + glutAddMenuEntry("[!] Change active sphere", 0); + glutAddMenuEntry("", 0); + glutAddMenuEntry("[Esc] Quit", 27); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + if (argc > 1) { + if (strcmp(argv[1], "-h") == 0) { + fprintf(stderr, "%s [particles] [flow] [speed%]\n", argv[0]); + exit(0); + } + sscanf(argv[1], "%d", &num_particles); + if (argc > 2) + sscanf(argv[2], "%f", &flow); + if (argc > 3) + sscanf(argv[3], "%f", &slow_down); + } + + particles = (PSparticle*)malloc(sizeof(PSparticle) * num_particles); + + glutVisibilityFunc(visible); + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/demos/particle/particle.dsp b/lib/glut-3.7.6/progs/demos/particle/particle.dsp new file mode 100644 index 0000000000..fb943011df --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/particle/particle.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="particle" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=particle - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "particle.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "particle.mak" CFG="particle - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "particle - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "particle - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "particle - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "particle - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "particle - Win32 Release" +# Name "particle - Win32 Debug" +# Begin Source File + +SOURCE=.\particle.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/Imakefile b/lib/glut-3.7.6/progs/demos/rollercoaster/Imakefile new file mode 100644 index 0000000000..353780caa1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = rc + +SRCS = defrc.c matrix.c rc.c + +OBJS = defrc.o matrix.o rc.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(rc,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/defrc.c b/lib/glut-3.7.6/progs/demos/rollercoaster/defrc.c new file mode 100644 index 0000000000..4d94152290 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/defrc.c @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include "matrix.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +typedef struct parameter +{ + double value; + double speed; + int steps; +} Parameter; + +Matrix pos; +Parameter roll, alignment, heading, pitch; +double tot_al = 0.0; +int tot = 0; + +#define MAX 10000 + +extern GLfloat x[MAX], y[MAX], z[MAX]; +extern GLfloat dx[MAX], dy[MAX], dz[MAX]; +extern GLfloat hd[MAX], al[MAX], pt[MAX], rl[MAX]; +extern GLfloat strips[27][MAX][3], normal[24][MAX][3]; +extern int opt[MAX]; +extern GLfloat bnormal[2][MAX][3]; +extern GLfloat r1[MAX], r2[MAX], r3[MAX]; + +void update_parameters(void); +void update_parameter(Parameter *p); +void init_parameter(Parameter *p); + +Vector strips_tmp[27], normal_tmp[27]; + +void calculate_rc(void) +{ + FILE *in; + int i, j; + char cmd[256]; + double a; + Vector v; + Matrix tmp, t2; +#if 0 + GLfloat nx, ny, nz, ac; +#endif + + printf("Reading RC parameters.\n"); +/* + out = fopen("rc.in", "w"); + if (!out) + { + fprintf(stderr, "Failed to open file 'rc.in' for writing.\n"); + exit(1); + } +*/ + + in = fopen("rc.def", "r"); + if (!in) + { + fprintf(stderr, "Failed to open file 'rc.def'.\n"); + exit(1); + } + + init_parameter(&roll); + init_parameter(&pitch); + init_parameter(&heading); + init_parameter(&alignment); + + init_matrix(&pos); + pos.index[3][2] = 0; + + for (i=0;i<27;i++) + { + init_vector(&normal_tmp[i]); + init_vector(&strips_tmp[i]); + } + + for (i=0;i<8;i++) + { + strips_tmp[i].index[2] = 1.0; + strips_tmp[i+8].index[2] = -1.0; + strips_tmp[i+16].index[1] = -1.0; + } + + for (i=0;i<3;i++) + { + for (j=0;j<8;j++) + { + normal_tmp[i*8+j].index[2] = cos(j*M_PI/4); + normal_tmp[i*8+j].index[1] = sin(j*M_PI/4); + strips_tmp[i*8+j].index[2] += cos(j*M_PI/4)/(i==2?2:4); + strips_tmp[i*8+j].index[1] += sin(j*M_PI/4)/(i==2?2:4); + } + strips_tmp[24].index[2] = 1.0; + strips_tmp[25].index[2] = -1.0; + strips_tmp[26].index[1] = -1.0; + } + + while (!feof(in)) + { + for (i=0;i<256;i++) + { + int ch; + + ch = fgetc(in); + if ((ch == '\n') || (ch == EOF)) + { + cmd[i] = 0; + break; + } + cmd[i] = ch; + } + if (cmd[0] == '#') + continue; + else if (!cmd[0]) + continue; + else if (sscanf(cmd, "pitch %lf %d", &a, &i)) + { + pitch.speed = (a - pitch.value)/i; + pitch.steps = i; + } + else if (sscanf(cmd, "alignment %lf %d", &a, &i)) + { + alignment.speed = (a - alignment.value)/i; + alignment.steps = i; + } + else if (sscanf(cmd, "heading %lf %d", &a, &i)) + { + heading.speed = (a - heading.value)/i; + heading.steps = i; + } + else if (sscanf(cmd, "roll %lf %d", &a, &i)) + { + roll.speed = (a - roll.value)/i; + roll.steps = i; + } + else if (sscanf(cmd, "wait %d", &i)) + { + for (;i>=0;i--) + { + update_parameters(); + + init_vector(&v); + v.index[0] = 0.15; + multiply_matrix_vector(&pos, &v); + for (j=0;j<3;j++) + pos.index[3][j] = v.index[j]; + + rotate_x(-roll.value*M_PI/(180*50), &pos); + rotate_y(-heading.value*M_PI/(180*50), &pos); + rotate_z(-pitch.value*M_PI/(180*50), &pos); + + x[tot] = v.index[0]; + y[tot] = v.index[1]; + z[tot] = v.index[2]; + al[tot] = alignment.value/50.0; + rl[tot] = roll.value/50.0; + hd[tot] = heading.value/50.0; + pt[tot] = pitch.value/50.0; + opt[tot] = 100*fabs(rl[tot] - al[tot]) + 100*fabs(hd[tot])+ + 100*fabs(pt[tot]); + + copy_matrix(&tmp, &pos); + init_vector(&v); + v.index[1] = 1; + tot_al += alignment.value*M_PI/180/50; + rotate_x(-tot_al, &tmp); + multiply_matrix_vector(&tmp, &v); + dx[tot] = v.index[0] - tmp.index[3][0]; + dy[tot] = v.index[1] - tmp.index[3][1]; + dz[tot] = v.index[2] - tmp.index[3][2]; + + copy_matrix(&tmp, &pos); + tot_al += alignment.value*M_PI/180/50; + rotate_x(-tot_al, &tmp); + copy_matrix(&t2, &tmp); + for (j=0;j<27;j++) + { + copy_vector(&v, &strips_tmp[j]); + multiply_matrix_vector(&t2, &v); + + strips[j][tot][0] = v.index[0]; + strips[j][tot][1] = v.index[1]; + strips[j][tot][2] = v.index[2]; + + copy_vector(&v, &normal_tmp[j]); + multiply_matrix_vector(&t2, &v); + + normal[j][tot][0] = v.index[0] - t2.index[3][0]; + normal[j][tot][1] = v.index[1] - t2.index[3][1]; + normal[j][tot][2] = v.index[2] - t2.index[3][2]; + } + init_vector(&v); + v.index[0] = -1.0; + v.index[1] = -1.5; + multiply_matrix_vector(&pos, &v); + bnormal[0][tot][0] = v.index[0] - pos.index[3][0]; + bnormal[0][tot][1] = v.index[1] - pos.index[3][1]; + bnormal[0][tot][2] = v.index[2] - pos.index[3][2]; + + init_vector(&v); + v.index[2] = -1.0; + v.index[1] = 1.5; + multiply_matrix_vector(&pos, &v); + bnormal[0][tot][0] = v.index[0] - pos.index[3][0]; + bnormal[0][tot][1] = v.index[1] - pos.index[3][1]; + bnormal[0][tot][2] = v.index[2] - pos.index[3][2]; + +#if 0 + copy_matrix(&tmp, &pos); + tmp.index[3][0] = 0.0; + tmp.index[3][1] = 0.0; + tmp.index[3][2] = 0.0; + + init_vector(&v); + v.index[0] = 1.0; + multiply_matrix_vector(&tmp, &v); + + nx = v.index[0]; + ny = v.index[1]; + nz = v.index[2]; + + ac = sqrt(nx*nx+nz*nz); + + if (ac == 0.0) + r1[tot] = 0.0; + else if (nx > 0) + r1[tot] = asin(nz/ac); + else + r1[tot] = M_PI-asin(nz/ac); + + r2[tot] = asin(ny); + + rotate_y(-r1[tot], &tmp); + rotate_z(-r2[tot], &tmp); + + init_vector(&v); + v.index[1] = 1.0; + multiply_matrix_vector(&tmp, &v); + nx = v.index[0]; + ny = v.index[1]; + nz = v.index[2]; + + ac = sqrt(nz*nz+ny*ny); /* this *should* be 1 */ + + if (ac == 0.0) + r3[tot] = 0.0; + else if (nz > 0) + r3[tot] = M_PI-asin(ny/ac); + else + r3[tot] = asin(ny/ac); +#endif + + copy_matrix(&tmp, &pos); + rotate_x(-tot_al, &tmp); + if (tmp.index[0][0] == 0.0 && tmp.index[0][1] == 0.0) { + r1[tot] = atan2(- tmp.index[1][0], - tmp.index[2][0]); + r2[tot] = 0.5 * M_PI; + r3[tot] = 0.0; + } else { + r1[tot] = atan2(tmp.index[1][2], tmp.index[2][2]); + r2[tot] = asin(tmp.index[0][2]); + r3[tot] = atan2(tmp.index[0][1], tmp.index[0][0]); + } + +#if 0 + printf("R: %f, %f, %f.\n", r1[tot], r2[tot], r3[tot]); +#endif + tot ++; + } + } + else + fprintf(stderr, "Not understood: %s\n", cmd); + } + printf("Done.\nTotal of %d parts\n", tot); + printf("Ended at %f, %f, %f\n", x[tot-1], y[tot-1], z[tot-1]); +} + +void update_parameters(void) +{ + update_parameter(&roll); + update_parameter(&pitch); + update_parameter(&heading); + update_parameter(&alignment); +} + +void update_parameter(Parameter *p) +{ + if (!p->steps) + return; + p->steps--; + p->value += p->speed; +} + +void init_parameter(Parameter *p) +{ + p->value = 0; + p->speed = 0; + p->steps = 10; +} diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.c b/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.c new file mode 100644 index 0000000000..5dcc7ca972 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.c @@ -0,0 +1,113 @@ +#include "matrix.h" +#include "math.h" + +void init_matrix(Matrix *m) +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<4;j++) + m->index[i][j] = (i==j?1:0); +} + +void init_vector(Vector *v) +{ + int i; + for (i=0;i<3;i++) + v->index[i] = 0; + v->index[3] = 1; +} + +void copy_vector(Vector *v1, Vector *v2) +{ + int i; + for (i=0;i<4;i++) + v1->index[i] = v2->index[i]; +} + +void copy_matrix(Matrix *m1, Matrix *m2) +{ + int i,j; + for (i=0;i<4;i++) + for (j=0;j<4;j++) + m1->index[i][j] = m2->index[i][j]; +} + +void multiply_vector_matrix(Matrix *m, Vector *v) +{ + int i,j; + Vector t; + for (i=0;i<4;i++) + { + t.index[i] = 0; + for (j=0;j<4;j++) + t.index[i] += m->index[i][j] * v->index[j]; + } + copy_vector(v, &t); +} + +void multiply_matrix_vector(Matrix *m, Vector *v) +{ + int i,j; + Vector t; + for (i=0;i<4;i++) + { + t.index[i] = 0; + for (j=0;j<4;j++) + t.index[i] += m->index[j][i] * v->index[j]; + } + copy_vector(v, &t); +} + +void multiply_matrix(Matrix *m2, Matrix *m1) +{ + int i,j,k; + Matrix m; + for (i=0;i<4;i++) + { + for (j=0;j<4;j++) + { + m.index[i][j] = 0; + for (k=0;k<4;k++) + m.index[i][j] += m1->index[i][k]* m2->index[k][j]; + } + } + copy_matrix(m2, &m); +} + +void rotate_x(double angle, Matrix *m) +{ + Matrix r; + double c = cos(angle), s = sin(angle); + init_matrix(&r); + r.index[1][1] = c; + r.index[1][2] = s; + r.index[2][1] = -s; + r.index[2][2] = c; + multiply_matrix(m, &r); +} + +void rotate_y(double angle, Matrix *m) +{ + Matrix r; + double c = cos(angle), s = sin(angle); + init_matrix(&r); + r.index[0][0] = c; + r.index[0][2] = -s; + r.index[2][0] = s; + r.index[2][2] = c; + multiply_matrix(m, &r); +} + +void rotate_z(double angle, Matrix *m) +{ + Matrix r; + double c = cos(angle), s = sin(angle); + init_matrix(&r); + r.index[0][0] = c; + r.index[0][1] = s; + r.index[1][0] = -s; + r.index[1][1] = c; + multiply_matrix(m, &r); +} + +void mcount() {} diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.h b/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.h new file mode 100644 index 0000000000..c685b16bb9 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/matrix.h @@ -0,0 +1,18 @@ +typedef struct matrix { + double index[4][4]; +} Matrix; + +typedef struct vector { + double index[4]; +} Vector; + +void init_matrix(Matrix *m); +void init_vector(Vector *v); +void copy_vector(Vector *v1, Vector *v2); +void copy_matrix(Matrix *m1, Matrix *m2); +void multiply_vector_matrix(Matrix *m, Vector *v); +void multiply_matrix_vector(Matrix *m, Vector *v); +void multiply_matrix(Matrix *m1, Matrix *m2); +void rotate_x(double angle, Matrix *m); +void rotate_y(double angle, Matrix *m); +void rotate_z(double angle, Matrix *m); diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/rc.c b/lib/glut-3.7.6/progs/demos/rollercoaster/rc.c new file mode 100644 index 0000000000..d6aa26463b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/rc.c @@ -0,0 +1,703 @@ +#include +#include +#include +#include +double floor(double o); +#define ACC 48 + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define FOG +#define FOG_D 0.1 +#define DIST 30 + +#define MESA_BUGGED + +int rr=0; +int frame = 0; + +GLfloat difmat1[4] = { 1.0, 0.4, 0.4, 1.0 }; +GLfloat difamb1[4] = { 1.0, 0.4, 0.4, 1.0 }; +GLfloat difmat2[4] = { 0.6, 0.6, 0.6, 1.0 }; +GLfloat difamb2[4] = { 0.6, 0.6, 0.6, 1.0 }; +GLfloat difmat3[4] = { 1.0, 1.0, 1.0, 1.0 }; +GLfloat difamb3[4] = { 1.0, 1.0, 1.0, 1.0 }; +GLfloat difmat4[4] = { 0.5, 0.5, 1.0, 1.0 }; +GLfloat difamb4[4] = { 0.5, 0.5, 1.0, 1.0 }; +GLfloat difmat5[4] = { 1.0, 1.0, 0.5, 1.0 }; +GLfloat difamb5[4] = { 1.0, 1.0, 0.5, 1.0 }; +GLfloat matspec1[4] = { 1.0, 1.0, 1.0, 0.0 }; +GLfloat matspec2[4] = { 0.774, 0.774, 0.774, 1.0 }; +GLfloat matspec4[4] = { 0.5, 0.5, 1.0, 1.0 }; +GLfloat dif_zwart[4] = { 0.3, 0.3, 0.3, 1.0 }; +GLfloat amb_zwart[4] = { 0.4, 0.4, 0.4, 1.0 }; +GLfloat spc_zwart[4] = { 0.4, 0.4, 0.4, 1.0 }; +GLfloat dif_copper[4] = { 0.5, 0.3, 0.1, 1.0 }; +GLfloat amb_copper[4] = { 0.2, 0.1, 0.0, 1.0 }; +GLfloat spc_copper[4] = { 0.3, 0.1, 0.1, 1.0 }; +GLfloat fogcol[4] = { 1.0, 1.0, 1.0, 1.0 }; +GLfloat hishin[1] = { 100.0 }; +GLfloat loshin[1] = { 5.0 }; +GLfloat lightpos[4] = { 1.0, 1.0, 1.0, 0.0 }; +GLfloat lightamb[4] = { 0.2, 0.2, 0.2, 1.0 }; +GLfloat lightdif[4] = { 0.8, 0.8, 0.8, 1.0 }; + +GLubyte texture[32][32][3]; +GLubyte sky[32][32][3]; + +#if defined(_WIN32) +#define drand48() (((float) rand())/((float) RAND_MAX)) +#endif + +int rnd(int i) +{ + return (int) ((double) drand48()*i); +} + +void make_texture(void) +{ + int i,j; + GLubyte r, g, b; + for (i=0;i<32;i++) + { + for (j=0;j<32;j++) + { + r = 100 + rnd(156); + g = 100 + rnd(156); + b = (b+g)/2 - rnd(100); + texture[i][j][0] = r/2; + texture[i][j][1] = g/2; + texture[i][j][2] = b/2; + r = rnd(100); + b = rnd(100)+156; + sky[i][j][1] = sky[i][j][0] = r; + sky[i][j][2] = b; + } + } +} + +#define MAX 10000 +extern int tot; +float plaatje = 0.0; +float speed = 0; +int angle = 0; +float angle2 = 0; +float angle3 = 0; + +GLfloat x[MAX], y[MAX], z[MAX]; +GLfloat dx[MAX], dy[MAX], dz[MAX]; +GLfloat al[MAX], rl[MAX], hd[MAX], pt[MAX]; +GLfloat strips[27][MAX][3], normal[27][MAX][3], bnormal[2][MAX][3]; +GLdouble cum_al = 0.0, view_al = 0.0; +int opt[MAX]; +GLfloat r1[MAX], r2[MAX], r3[MAX]; + +void copper_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dif_copper); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb_copper); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spc_copper); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 13); +} + +void groen_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat4); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb4); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec4); + glMaterialf(GL_FRONT, GL_SHININESS, 5.0); +} + +void rood_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat1); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb1); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec1); + glMaterialf(GL_FRONT, GL_SHININESS, 0.1*128); +} + +void metaal_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat2); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb2); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec2); + glMaterialf(GL_FRONT, GL_SHININESS, 0.6*128.0); +} + +void wit_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat3); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb3); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec1); + glMaterialf(GL_FRONT, GL_SHININESS, 0.8*128.0); +} + +void geel_texture(void) +{ + glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat5); + glMaterialfv(GL_FRONT, GL_AMBIENT, difamb5); + glMaterialfv(GL_FRONT, GL_SPECULAR, matspec1); + glMaterialf(GL_FRONT, GL_SHININESS, 0.8*128.0); +} + +void zwart_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dif_zwart); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb_zwart); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spc_zwart); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 90); +} + +#define VERTEX(I,J) glNormal3fv(normal[I][J]); glVertex3fv(strips[I][J]); + +void do_display (void) +{ + int i,j,s,t, tmp; + cum_al = 0.0; + + metaal_texture(); + + for (s=0;s<24;s += 2) + { + t = s+2; + if (!(t&7)) + t=t-8; + + if (s == 16) + rood_texture(); + glBegin(GL_QUADS); + for (i=0;i 4000 || (!(j%(3*DIST)))) + break; + + if (j>=tot) + j = 0; + + rr++; + VERTEX(s, j); + VERTEX(s, i); + VERTEX(t, i); + VERTEX(t, j); + if (!j) + break; + } + glEnd(); + } + printf("Split up to %d parts.\n", rr); + rood_texture(); + for (i=0;i= tot) + plaatje2 -= tot; + display_cart(plaatje2); + + plaatje2 = plaatje + 20; + if (plaatje2 >= tot) + plaatje2 -= tot; + display_cart(plaatje2); + + plaatje2 = plaatje - 20; + if (plaatje2 < 0) + plaatje2 += tot; + display_wheel(plaatje2); + + glFlush(); + glutSwapBuffers(); + glPopMatrix(); +} + +void myinit (void) { + glShadeModel (GL_SMOOTH); + glFrontFace(GL_CCW); + glEnable(GL_DEPTH_TEST); + + glClearColor(fogcol[0], fogcol[1], fogcol[2], fogcol[3]); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightdif); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glColor3f(1.0, 1.0, 1.0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +#ifdef FOG +/* fog */ + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogfv(GL_FOG_COLOR, fogcol); + glFogf(GL_FOG_DENSITY, 0.01); + glFogf(GL_FOG_START, 0.01); + glFogf(GL_FOG_END, 55.0); + glHint(GL_FOG_HINT, GL_NICEST); +#endif + + make_texture(); + init_wheel(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +/* + glTexImage2D(GL_TEXTURE_2D, 0, 3, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, + &texture[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); +} + +/* ARGSUSED1 */ +void parsekey(unsigned char key, int x, int y) +{ + switch (key) + { + case 27: exit(0); + case 13: speed = 0; break; + } +} + +/* ARGSUSED1 */ +void parsekey_special(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP: speed ++; break; + case GLUT_KEY_DOWN: speed --; break; + case GLUT_KEY_RIGHT: angle ++; break; + case GLUT_KEY_LEFT: angle --; break; + } +} + +void SetCamera(void) +{ + float plaatje2; + int l,l2; + l = plaatje; + plaatje2 = plaatje + 10; + + if (plaatje2 >= tot) + plaatje2 -= tot; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum (-0.1, 0.1, -0.1, 0.1, 0.1, 550.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + +#if 1 + glTranslated(0.0, +0.4, 0.0); + glRotated(angle*5.0, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -6.5-2*sin(angle2)-sin(angle3)); + glRotatef(45 - 35*cos(angle3), 1.0, 0.0, 0.0); + glRotatef(-100*sin(angle3), 0.0, 1.0, 0.0); +#else + glRotatef(100*sin(angle3), 0.0, 1.0, 0.0); + glRotatef(-45 + 35*cos(angle3), 1.0, 0.0, 0.0); + glTranslatef(0.0, 0.0, +6+2*sin(angle2)+sin(angle3)); + glRotated(-angle*5.0, 0.0, 1.0, 0.0); + glTranslated(0.0, -0.4, 0.0); +#endif + + l2 = plaatje2; + glTranslatef(-0.15*(plaatje-l), 0.0, 0.0); + + gluLookAt(x[l], y[l], z[l], + x[l2], y[l2], z[l2], + dx[l], dy[l], dz[l]); +} + +void Animate(void) +{ + int l1; + + l1 = plaatje; + speed += (y[l1] - y[l1+4])*2-0.005; + + speed -= (fabs(rl[l1]-al[l1]) + fabs(pt[l1]) + fabs(hd[l1])) * speed/200; + + if (frame > 450) + speed -= 0.2208; + + if (speed < 0) + speed = 0; + + if (frame < 10) + speed = 0; + + if (frame == 10) + speed = 4.5; + + if (frame > 155 && frame < 195) + speed = 7.72; + + plaatje += speed; + + if (plaatje >= tot) { + plaatje = tot - 1; + glutIdleFunc(NULL); + return; + } + + if (plaatje < 0) + plaatje += tot; + + SetCamera(); + + angle2 = frame*4*M_PI/503; + angle3 = frame*6*M_PI/503; + + glutPostRedisplay(); + frame++; +} + +void myReshape(int w, int h) +{ + SetCamera(); + glViewport (0, 0, w, h); +} + +int main(int argc, char *argv[]) +{ + int sz; + extern void calculate_rc(void); + + calculate_rc(); + printf("tot = %d\n", tot); + if (argc > 1) + sz = atoi(argv[1]); + else + sz = 200; + glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE); + glutInitWindowPosition(200, 0); + glutInitWindowSize(sz, sz); + glutCreateWindow("Roller coaster"); + glNewList(1, GL_COMPILE); + do_display(); + glEndList(); + glutDisplayFunc(display); + glutKeyboardFunc(parsekey); + glutSpecialFunc(parsekey_special); + glutReshapeFunc(myReshape); + glutIdleFunc(Animate); + myinit(); + glutSwapBuffers(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/rc.def b/lib/glut-3.7.6/progs/demos/rollercoaster/rc.def new file mode 100644 index 0000000000..1126a330a3 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/rc.def @@ -0,0 +1,217 @@ +# eerste (hele flauwe) helling +pitch 16 10 +wait 10 +# weer recht zetten +pitch 0 10 +wait 100 +pitch -16 10 +wait 10 +pitch 0 10 +wait 10 + +# eerste bocht (rechts): +# begin indraaien +alignment 40 30 +wait 20 +# begin bocht +heading -45 10 +wait 10 +# einde indraaien +alignment 0 30 +wait 79 +# begin uitdraaien +alignment -10 30 +wait 10 +# einde bocht +heading 0 10 +wait 20 +# einde uitdraaien +alignment 0 10 +wait 160 + +# tweede bocht (rechts): +# begin indraaien +alignment 10 10 +wait 20 +# begin bocht +heading -45 10 +wait 10 +# einde indraaien +alignment 0 30 +wait 79 +# begin uitdraaien +alignment -40 30 +wait 10 +# einde bocht +heading 0 10 +wait 20 +# einde uitdraaien +alignment 0 30 +wait 50 + +# begin stijging +pitch -45 10 +wait 50 +# stabiel stijging +pitch 0 10 +wait 250 +# einde stijging +pitch 45 10 +wait 50 +# stabiel +pitch 0 10 +# alignment voor de bocht die gaat komen. +wait 30 +roll 20 30 +wait 30 + +# nu gaat het gebeuren! +# in een bocht naar rechts naar beneden storten. +# roll 0 30 +heading -52 20 +alignment 6 40 +wait 40 +alignment 0 40 +wait 120 +heading 0 20 +roll 10 40 +alignment -11 40 +wait 40 +roll 0 40 +heading 0 30 +alignment 0 40 +wait 80 + +# loop 1!!!! +pitch -45 50 +roll -10 50 +wait 440 + +# einde van de loop +pitch -20 50 +wait 100 + +# loop 2!!!! +pitch -45 50 +wait 150 + +# voorbereiding bocht in looping 2 +roll -32 20 +wait 100 +roll 0 20 + +heading 0 40 +wait 80 + +pitch 0 50 +heading 0 30 +roll -18 40 +alignment 25 40 +wait 50 + +pitch 10 20 +roll 0 40 +alignment 0 40 +wait 50 +pitch 0 20 +wait 30 + +heading -45 20 +alignment -25 40 +roll -15 40 +wait 50 +alignment 0 40 +roll 0 40 +wait 49 +heading 0 20 +wait 20 +pitch -20 30 +wait 30 +pitch 0 30 +heading -74 20 +wait 99 +# einde bocht + +heading 0 20 +roll -42 40 +pitch 20 20 +wait 30 +pitch 0 20 +wait 20 +roll -40 40 +heading -40 40 +pitch -40 40 +wait 250 +heading 0 40 +roll 0 40 +alignment -40 10 +wait 20 +alignment 0 10 +wait 80 +pitch 0 40 +# scherpe bocht na schroef +heading 90 40 +wait 100 +heading 0 40 +alignment 40 10 +roll -65 10 +pitch 15 20 +wait 20 +alignment 0 10 +roll 0 10 +pitch 0 20 +heading 37 10 +wait 10 +heading 0 10 +wait 30 +pitch -60 10 +wait 50 +pitch 0 10 +wait 60 +heading 20 10 +wait 30 +heading 0 10 +wait 10 +alignment 40 10 +wait 40 +alignment 0 10 +heading -50 10 +wait 200 +heading 0 10 +wait 10 +alignment -40 40 +wait 40 +alignment 0 40 +wait 79 +roll -13 10 +pitch -13.113200 10 +wait 10 +roll 0 10 +pitch 0 10 +wait 10 +wait 70 +alignment 40 40 +wait 19 +#laatste bocht! +heading -36.2 20 +wait 20 +alignment 0 40 +wait 24 +heading 0 20 +wait 20 +wait 10 +heading -44.4373 20 +wait 134 +heading 0 20 +wait 20 +alignment -40 40 +wait 40 +alignment 0 40 +pitch -5 10 +wait 10 +pitch 0 10 +wait 29 +pitch 5 10 +wait 10 +pitch 0 18 +wait 115 diff --git a/lib/glut-3.7.6/progs/demos/rollercoaster/rollercoaster.dsp b/lib/glut-3.7.6/progs/demos/rollercoaster/rollercoaster.dsp new file mode 100644 index 0000000000..5c36b6d351 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/rollercoaster/rollercoaster.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="rollercoaster" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rollercoaster - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rollercoaster.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rollercoaster.mak" CFG="rollercoaster - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rollercoaster - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "rollercoaster - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rollercoaster - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "rollercoaster - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rollercoaster - Win32 Release" +# Name "rollercoaster - Win32 Debug" +# Begin Source File + +SOURCE=.\defrc.c +# End Source File +# Begin Source File + +SOURCE=.\matrix.c +# End Source File +# Begin Source File + +SOURCE=.\matrix.h +# End Source File +# Begin Source File + +SOURCE=.\rc.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/skyfly/Imakefile b/lib/glut-3.7.6/progs/demos/skyfly/Imakefile new file mode 100644 index 0000000000..375918ea37 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/Imakefile @@ -0,0 +1,14 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = skyfly + +SRCS = database.c fly.c gm_main.c image.c perfdraw.c skyfly.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(skyfly,database.o fly.o gm_main.o image.o perfdraw.o skyfly.o) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/skyfly/clouds.bw b/lib/glut-3.7.6/progs/demos/skyfly/clouds.bw new file mode 100644 index 0000000000000000000000000000000000000000..c62c1dc02bb0f877444416c6be7dd0272ec9c08b GIT binary patch literal 16625 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/skyfly/database.c b/lib/glut-3.7.6/progs/demos/skyfly/database.c new file mode 100644 index 0000000000..3d4c76c755 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/database.c @@ -0,0 +1,522 @@ + +/* + * database.c $Revision: 1.2 $ + */ + +#include +#include +#include +#include "skyfly.h" + +#if defined(_WIN32) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +#define cosf(a) cos((float)a) +#define sinf(a) sin((float)a) +#define sqrtf(a) sqrt((float)a) +#define expf(a) exp((float)a) + +static void create_terrain(void); +static void erode_terrain(void); +static void color_terrain(void); +static void init_cells(void); +static void put_cell(float *source, perfobj_t *pobj); +static void put_paper_plane(float *source, perfobj_t *pobj); +static void put_texture_bind(int bind, perfobj_t *pobj); + +int clouds; +static float paper_plane_vertexes[] = { +/*Nx Ny Nz Vx Vy Vz */ +/* ---------------------------- Top view of plane, middle streached open */ + 0.2, 0., .98, -.10, 0, .02,/* vertex #'s 4 (.48,0,-.06) */ + 0., 0., 1., -.36, .20, -.04,/* . */ + 0., 0., 1., .36, .01, 0,/* ... */ + 0., 0.,-1., -.32, .02, 0,/* . +X */ + 0., 1., 0., .48, 0, -.06,/* 2 . 6,8 ^ */ + 0., 1., 0., -.30, 0, -.12,/* . . . | */ + 0.,-1., 0., .36, -.01, 0,/* .. . .. | */ + 0.,-1., 0., -.32, -.02, 0,/* . . . | */ + 0., 0.,-1., .36, -.01, 0,/* . . . . . +Y<-----* */ + 0., 0.,-1., -.36, -.20, -.04,/* . . . for this picture */ + -0.2, 0., .98, -.10, 0, .02,/* . . . . . coord system rot. */ + -0.2, 0., -.98, -.10, 0, .02,/* . . . 90 degrees */ + 0., 0., -1., -.36, .20, -.04,/* . . . . . */ + 0., 0., -1., .36, .01, 0,/* . # . # marks */ + 0., 0., 1., -.32, .02, 0,/* . . . . . (0,0) origin */ + 0., -1., 0., .48, 0, -.06,/* . . . (z=0 at top */ + 0., -1., 0., -.30, 0, -.12,/* . 0 . 10 . of plane) */ + 0.,1., 0., .36, -.01, 0,/* . . . . . */ + 0.,1., 0., -.32, -.02, 0,/* . . . . . . . */ + 0., 0.,1., .36, -.01, 0,/* . . . . . */ + 0., 0.,1., -.36, -.20, -.04,/* 1.......3.5.7.......9 */ + 0.2, 0., -.98, -.10, 0, .02,/* (-.36,.2,-.04) */ +}; + +#define SIZE 400 + +float *A; + +void init_paper_planes(void) +{ + perfobj_t *pobj; + + /* + * create various perf-objs for planes + */ + pobj = &(SharedData->paper_plane_obj); + pobj->flags = SharedData->paper_plane_flags; + pobj->vdata = (float *) SharedData->paper_plane_verts; + put_paper_plane(paper_plane_vertexes, pobj); + + pobj = &(SharedData->paper_plane_start_obj); + pobj->flags = SharedData->paper_plane_start_flags; + *(pobj->flags) = PD_PAPER_PLANE_MODE; + *(pobj->flags + 1) = PLANES_START; + *(pobj->flags + 2) = PD_END; + + pobj = &(SharedData->paper_plane_2ndpass_obj); + pobj->flags = SharedData->paper_plane_2ndpass_flags; + *(pobj->flags) = PD_PAPER_PLANE_MODE; + *(pobj->flags + 1) = PLANES_SECOND_PASS; + *(pobj->flags + 2) = PD_END; + + pobj = &(SharedData->paper_plane_end_obj); + pobj->flags = SharedData->paper_plane_end_flags; + *(pobj->flags) = PD_PAPER_PLANE_MODE; + *(pobj->flags + 1) = PLANES_END; + *(pobj->flags + 2) = PD_END; +} + + +/* + * create perfobj from static definition of plane geometry above + */ + +static void put_paper_plane(float *source, perfobj_t *pobj) +{ + int j; + perfobj_vert_t *pdataptr =(perfobj_vert_t *) pobj->vdata; + unsigned int *flagsptr = pobj->flags; + float *sp = source; + + *flagsptr++ = PD_DRAW_PAPER_PLANE; + + for (j = 0; j < 22; j++) { + putn3fdata(sp + 0, pdataptr); + putv3fdata(sp + 3, pdataptr); + + sp += 6; + pdataptr++; + } + *flagsptr++ = PD_END; + +} + +static void put_texture_bind(int bind, perfobj_t *pobj) +{ + unsigned int *flagsptr = pobj->flags; + + *flagsptr++ = PD_TEXTURE_BIND; + *flagsptr++ = bind; + + *flagsptr++ = PD_END; + +} + +static void put_clouds_vert(float s, float t, float x, float y, float z, + perfobj_vert_t *pdataptr) +{ + float D[5]; + D[0] = s; + D[1] = t; + D[2] = x; + D[3] = y; + D[4] = z; + putt2fdata(D, pdataptr); + putv3fdata(D + 2, pdataptr); +} + +float S[SIZE][SIZE]; +float T[SIZE][SIZE]; +float C[SIZE][SIZE][3]; +int M[SIZE][SIZE]; + +void init_terrain(void) +{ + GridDim = CellDim * NumCells; + XYScale = (float)GRID_RANGE / (float)GridDim; + CellSize = (float)GRID_RANGE / (float)NumCells; + + create_terrain(); + erode_terrain(); + color_terrain(); + init_cells(); +} + +#define SKY 50. + +void init_clouds(void) +{ + perfobj_t *pobj; + perfobj_vert_t *pdataptr; + + clouds = 0; + pobj = &(SharedData->clouds_texture_obj); + pobj->flags = SharedData->clouds_texture_flags; + put_texture_bind(2,pobj); + + pobj = &(SharedData->clouds_obj); + pobj->flags = SharedData->clouds_flags; + pobj->vdata = (float *)SharedData->clouds_verts; + *(pobj->flags+ 0) = PD_DRAW_CLOUDS; + *(pobj->flags+ 1) = PD_END; + + pdataptr =(perfobj_vert_t *) pobj->vdata; + + put_clouds_vert(0.,0., -SKY, -SKY, SKY_HIGH,pdataptr); + pdataptr++; + put_clouds_vert(24.,0., SKY+GRID_RANGE, -SKY, SKY_HIGH,pdataptr); + pdataptr++; + put_clouds_vert(24.,24., SKY+GRID_RANGE, SKY+GRID_RANGE, SKY_HIGH,pdataptr); + pdataptr++; + put_clouds_vert(0.,24., -SKY, SKY+GRID_RANGE, SKY_HIGH,pdataptr); +} + +static void create_terrain(void) +{ + int r, c, i, x1, y1, x2, y2; + int hillsize; + + hillsize = GRID_RANGE / 12; + + A = (float*)calloc(GridDim * GridDim, sizeof(float)); + + /* + * initialize elevation to zero, except band down middle + * where make a maximum height 'hill' that will later be + * inverted to make the negative elevation 'canyon' + */ + + for (r = 0; r < GridDim; r++) + for (c = 0; c < GridDim; c++) + if(r>=(GridDim/2-2-IRND(2)) && r<=(GridDim/2+2+IRND(2))) + A[r * GridDim + c] = 1.0; + else + A[r * GridDim + c] = 0.0; + + /* + * create random sinusoidal hills that add on top + * of each other + */ + for (i = 1; i <= 10*GridDim; i++) { + + /* randomly position hill */ + x1 = IRND(GridDim - hillsize); + x2 = x1 + hillsize/ 8 + IRND(hillsize-hillsize/ 8); + y1 = IRND(GridDim - hillsize); + y2 = y1 + hillsize/ 8 + IRND(hillsize-hillsize/ 8); + + if((x1<=GridDim/2-4 && x2>=GridDim/2-4) || + (x1<=GridDim/2+4 && x2>=GridDim/2+4)) + { + x1 = IRND(2)-2 + GridDim/2; + x2 = x1 + IRND(GridDim/2 - x1 + 2); + } + + /* make a sinusoidal hill */ + for (r = x1; r < x2; r++) + for (c = y1; c < y2; c++) { + A[r * GridDim + c] +=.35 * + (sinf(M_PI * (float) (r - x1) / (float) (x2 - x1)) * + (sinf(M_PI * (float) (c - y1) / (float) (y2 - y1)))); + } + } + + /* clamp the elevation of the terrain */ + for (r = 1; r < GridDim; r++) + for (c = 1; c < GridDim; c++) { + A[r * GridDim + c] = MIN(A[r * GridDim + c], .95); + A[r * GridDim + c] = MAX(A[r * GridDim + c], 0.); + } + +} + +#define NUM_DROPS 80 + +static void erode_terrain(void) +{ + float x, y, xv, yv, dx, dy; + float cut, min, take; + int nm; + int t, xi, yi, xo, yo, done; + int ii, jj, r, c; + + for (nm = 1; nm < NUM_DROPS*GridDim; nm++) { + + /* find a random position to start the 'rain drop' */ + x = (float) (IRND(GridDim)); + y = (float) (IRND(GridDim)); + + /* Clamp x and y to be inside grid */ + x = MIN(MAX(2., x), (float)GridDim-2.); + y = MIN(MAX(2., y), (float)GridDim-2.); + + done = 0; + yv = xv = 0.; + + t = 0; + cut = .3; + + while (!done) { + xi = (int) x; + yi = (int) y; + + min = 90.; + + if (xi != xo || yi != yo) { + cut *=.99; + + /* gradient */ + dx = (A[(xi + 1)*GridDim + yi] - A[(xi - 1) * GridDim + yi]); + dy = (A[xi * GridDim + yi + 1] - A[xi * GridDim + yi - 1]); + + + /* find lowest neighbor */ + for (ii = -1; ii <= 1; ii++) + for (jj = -1; jj <= 1; jj++) + if (A[(xi + ii)*GridDim + yi + jj] < min) + min = A[(xi + ii)*GridDim + yi + jj]; + + /* evaporate drop if sitting on my old location */ + if (M[xi][yi] == nm) + done = 1; + M[xi][yi] = nm; + + /* cave in neighbors by .3 */ + for (ii = -1; ii <= 1; ii++) + for (jj = -1; jj <= 1; jj++) { + take =.3 * cut * (A[(xi + ii)*GridDim + yi + jj]-min); + A[(xi + ii)*GridDim + yi + jj] -= take; + } + + /* take away from this cell by .7 */ + take = (A[xi*GridDim + yi] - min) *.7 * cut; + A[xi*GridDim + yi] -= take; + + } + xo = xi; + yo = yi; + + /* move drop using kinematic motion*/ + xv = xv - dx -.8 * xv; + yv = yv - dy -.8 * yv; + + x += xv; + y += yv; + + /* + * make sure can't move by more that 1.0 + * in any direction + */ + + xv = MAX(xv, -1); + yv = MAX(yv, -1); + xv = MIN(xv, 1); + yv = MIN(yv, 1); + + /* check to see if need a new drop */ + /* ie ran of world, got stuck, or at 'sea level' */ + if (x < 1.|| x > GridDim - 1.|| y < 1.|| y > GridDim - 1. + || t++ > 2000 + || cut <.01) + done = 1; + + if (A[xi*GridDim + yi] < 0.0001) { + A[xi*GridDim + yi] = 0.; + done = 1; + } + } /* while (!done) with this drop */ + } /* next drop */ + + /* + * invert the pseudo hill int the pseudo canyon + */ + + for (r = 0; r < GridDim; r++) + for (c = 0; c < GridDim; c++) + if(r>=GridDim/2-4 && r<=GridDim/2+4) + A[r * GridDim + c] = MAX((-3.2 * A[r * GridDim + c]), -1.8); +} + +static void color_terrain(void) +{ + float N[3], D, alt, maxelev = -1.; + int x, y; + + for (x = 0; x < GridDim; x++) + for (y = 0; y < GridDim; y++) + maxelev = MAX(maxelev, A[x * GridDim + y]); + + for (x = 1; x < GridDim - 1; x++) + for (y = 1; y < GridDim - 1; y++) { + alt = A[x * GridDim + y] * 1.5; + /* randomly perterb to get a mottling effect */ + alt += IRND(100) / 400. -.125; + alt = MIN(alt, 1.0); + if (alt < -.11) { + C[x][y][0] = 0.6; /* soil/rock in canyon */ + C[x][y][1] = 0.5; + C[x][y][2] = 0.2; + } else if (alt < .000001) { + C[x][y][0] = 0.0; /* dark, jungle lowlands */ + C[x][y][1] = 0.2; + C[x][y][2] = 0.05; + } else if (alt <.90) { + C[x][y][0] = alt*.25; /* green to redish hillsides */ + C[x][y][1] = (1.0 - alt) *.4 + .1; + C[x][y][2] = 0.1; + } else { + C[x][y][0] = alt; + C[x][y][1] = alt; /* incresingly white snow */ + C[x][y][2] = alt; + } + + /* compute normal to terrain */ + + N[0] = A[(x - 1)*GridDim + y] - A[(x + 1)*GridDim + y]; + N[1] = A[x*GridDim + y - 1] - A[x*GridDim + y + 1]; + N[2] = 2.0 / ScaleZ; + + D = 1.0 / sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); + + N[0] *= D; + N[1] *= D; + N[2] *= D; + + /* perform diffuse lighting of terrain */ + + D = N[0] * LX + N[1] * LY + N[2] * LZ; + D *= 1.2; + + if(!IRND(4)) D *= .5; + + D = MAX(D,0); + + /* darken terrain on shaded side */ + C[x][y][0] *= D; + C[x][y][1] *= D; + C[x][y][2] *= D; + + S[x][y] = (float) (x) / (float)CellDim; + T[x][y] = (float) (y) / (float)CellDim; + + } +} + +/* + * create perobj to hold a cell of terrain + * for a 5x5 terrain cell, there will be 5 + * tmeshes each with 10 triangles (12 vertexes) + * this means looking past my cell to neighbors + * to stitch things together. To keep data contigious, + * vertexes are repeated in tmeshes, not shared. + */ + +static void init_cells(void) +{ + int x, y, xx, yy, world_x, world_y; + int pntr, index, sstart, tstart; + float *D; + perfobj_t *pobj; + + D = (float*)calloc(CellDim *(CellDim + 1) * + 2 * FLOATS_PER_VERT_PAIR, sizeof(float)); + + pobj = &(SharedData->terrain_texture_obj); + pobj->flags = SharedData->terrain_texture_flags; + + put_texture_bind(1, pobj); + + for (x = 0; x < NumCells; x++) + for (y = 0; y < NumCells; y++) { + index = x*NumCells+y; + SharedData->terrain_cells[index].flags = + SharedData->terrain_cell_flags[index]; + + SharedData->terrain_cells[index].vdata = + (float *) SharedData->terrain_cell_verts[index]; + + pntr = 0; + + /* + * Guarantee S,T to be within range 0-8 for tmesh strip using + * 256x256 sized texture. This avoids texture index clipping + * in pipe. + */ + sstart = (int)S[x*CellDim][y*CellDim]; + tstart = (int)T[x*CellDim][y*CellDim]; + + for (xx = 0; xx < CellDim; xx++) + for (yy = 0; yy < CellDim + 1; yy++) { + + /* init a perfobj */ + + world_x = MIN(x * CellDim + xx, GridDim-2); + world_y = MIN(y * CellDim + yy, GridDim-2); + + D[pntr + 0] = S[world_x][world_y] - sstart; + D[pntr + 1] = T[world_x][world_y] - tstart; + D[pntr + 2] = C[world_x][world_y][0]; + D[pntr + 3] = C[world_x][world_y][1]; + D[pntr + 4] = C[world_x][world_y][2]; + D[pntr + 5] = (float)world_x * XYScale; + D[pntr + 6] = (float)world_y * XYScale; + D[pntr + 7] = A[world_x*GridDim + world_y]*ScaleZ; + + + D[pntr + 8] = S[world_x + 1][world_y] - sstart; + D[pntr + 9] = T[world_x + 1][world_y] - tstart; + D[pntr + 10] = C[world_x + 1][world_y][0]; + D[pntr + 11] = C[world_x + 1][world_y][1]; + D[pntr + 12] = C[world_x + 1][world_y][2]; + D[pntr + 13] = (float)(world_x+1) * XYScale; + D[pntr + 14] = (float)world_y * XYScale; + D[pntr + 15] = A[(world_x+1)*GridDim + world_y] * ScaleZ; + + pntr += FLOATS_PER_VERT_PAIR; + + } /* for each cell */ + put_cell(D, &(SharedData->terrain_cells[index])); + + } /* for all cells in world */ + + free(D); +} + +static void put_cell(float *source, perfobj_t *pobj) +{ + int i, j; + perfobj_vert_t *pdataptr =(perfobj_vert_t *) pobj->vdata; + unsigned int *flagsptr = pobj->flags; + float *sp = source; + + /* For all tmesh strips in cell */ + for (i = 0; i < CellDim; i++) { + *flagsptr++ = PD_DRAW_TERRAIN_CELL; + *flagsptr++ = (unsigned long) pdataptr; + + /* For all verts in tmesh strip */ + for (j = 0; j < (CellDim + 1) * 2; j++) { + putt2fdata(sp, pdataptr); + putc3fdata(sp + 2, pdataptr); + putv3fdata(sp + 5, pdataptr); + + sp += 8; + pdataptr++; + } + } + *flagsptr++ = PD_END; +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/fly.c b/lib/glut-3.7.6/progs/demos/skyfly/fly.c new file mode 100644 index 0000000000..35d3a6b220 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/fly.c @@ -0,0 +1,282 @@ + +/* + * fly.c $Revision: 1.2 $ + */ + +#include "stdio.h" +#include "math.h" +#include "skyfly.h" + +#if defined(_WIN32) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +#define cosf(a) cos((float)a) +#define sinf(a) sin((float)a) +#define sqrtf(a) sqrt((float)a) +#define expf(a) exp((float)a) + +typedef struct paper_plane_struct { + float Pturn_rate; + float PX, PY, PZ, PZv; + float Pazimuth; + float Proll; + int Pcount, Pdirection; +} paper_plane; + +static paper_plane flock[NUM_PLANES]; +static float X, Y, Z, Azimuth, Speed; +static int Keyboard_mode; + +extern float *A; +extern int Wxorg, Wyorg; + +static float terrain_height(float x, float y); + +int Xgetbutton(int b); +int Xgetvaluator(int v); + +void init_positions(void) +{ + int i; + + X = GRID_RANGE / 2.; + Y = GRID_RANGE / 2.; + Z = 1.5; + + /* + * randomly position the planes near center of world + * take MAX of height above terrain and 0, so planes + * don't fall into canyon. Canyon has negative elevation + */ + + for (i = 0; i < NUM_PLANES; i++) { + flock[i].PX = (float) IRND(20) + GRID_RANGE / 2 - 10; + flock[i].PY = (float) IRND(20) + GRID_RANGE / 2 - 10; + flock[i].PZ = MAX(terrain_height(flock[i].PX, flock[i].PY),0.) + + 2.*(float)i/NUM_PLANES+.3; + flock[i].Pazimuth = ((float)IRND(256) / 128.) * M_PI; + } + Speed = 0.1f; + Azimuth = M_PI / 2.; + +#if 0 +// if (Init_pos) { +// X = Init_x; +// Y = Init_y; +// Z = Init_z; +// Azimuth = Init_azimuth; +// Keyboard_mode = 1; +// } +#endif +} + +int _frame = 0; + +void fly(perfobj_t *viewer_pos) +{ + float terrain_z, xpos, ypos, xcntr, ycntr; + float delta_speed = .003; + +/* if (++_frame == 1000) { + _frame = 0; + init_positions(); + }*/ + + xcntr = Wxsize / 2; + ycntr = Wysize / 2; + + if (Xgetbutton(RKEY)) + init_positions(); + + if (Xgetbutton(SPACEKEY)) { + Keyboard_mode = !Keyboard_mode; + } + + if (Keyboard_mode) { + + /* + * step-at-a-time debugging mode + */ + + if (Keyboard_mode && Xgetbutton(LEFTARROWKEY)) { + Azimuth -= 0.025; + } + if (Keyboard_mode && Xgetbutton(RIGHTARROWKEY)) { + Azimuth += 0.025; + } + if (Keyboard_mode && Xgetbutton(UPARROWKEY)) { + X += cosf(-Azimuth + M_PI / 2.) * 0.025; + Y += sinf(-Azimuth + M_PI / 2.) * 0.025; + } + if (Keyboard_mode && Xgetbutton(DOWNARROWKEY)) { + X -= cosf(-Azimuth + M_PI / 2.) * 0.025; + Y -= sinf(-Azimuth + M_PI / 2.) * 0.025; + } + if (Keyboard_mode && Xgetbutton(PAGEUPKEY)) { + Z += 0.025; + } + if (Keyboard_mode && Xgetbutton(PAGEDOWNKEY)) { + Z -= 0.025; + } + + } else { + + /* + * simple, mouse-driven flight model + */ + + if (Xgetbutton(LEFTMOUSE) && Speed < .3) + Speed += delta_speed; + if (Xgetbutton(RIGHTMOUSE) && Speed > -.3) + Speed -= delta_speed; + if (Xgetbutton(MIDDLEMOUSE)) + Speed = Speed*.8; + + xpos = (Xgetvaluator(MOUSEX)-xcntr) / ((float)Wxsize*14.); + ypos = (Xgetvaluator(MOUSEY)-ycntr) / ((float)Wysize*.5); + + /* + * move in direction of view + */ + + Azimuth += xpos; + X += cosf(-Azimuth + M_PI / 2.) * Speed; + Y += sinf(-Azimuth + M_PI / 2.) * Speed; + Z -= ypos * Speed; + } + + /* + * keep from getting too close to terrain + */ + + terrain_z = terrain_height(X, Y); + if (Z < terrain_z +.4) + Z = terrain_z +.4; + + X = MAX(X, 1.); + X = MIN(X, GRID_RANGE); + Y = MAX(Y, 1.); + Y = MIN(Y, GRID_RANGE); + Z = MIN(Z, 20.); + + *((float *) viewer_pos->vdata + 0) = X; + *((float *) viewer_pos->vdata + 1) = Y; + *((float *) viewer_pos->vdata + 2) = Z; + *((float *) viewer_pos->vdata + 3) = Azimuth; +} + +void fly_paper_planes(perfobj_t *paper_plane_pos) +{ + int i; + float speed = .08; + float terrain_z; + + /* + * slow planes down in cyclops mode since + * frame rate is doubled + */ + + for (i = 0; i < NUM_PLANES; i++) { + /* + * If plane is not turning, one chance in 50 of + * starting a turn + */ + if (flock[i].Pcount == 0 && IRND(50) == 1) { + /* initiate a roll */ + /* roll for a random period */ + flock[i].Pcount = IRND(100); + /* random turn rate */ + flock[i].Pturn_rate = IRND(100) / 10000.; + flock[i].Pdirection = IRND(3) - 1; + } + if (flock[i].Pcount > 0) { + /* continue rolling */ + flock[i].Proll += flock[i].Pdirection * flock[i].Pturn_rate; + flock[i].Pcount--; + } else + /* damp amount of roll when turn complete */ + flock[i].Proll *=.95; + + /* turn as a function of roll */ + flock[i].Pazimuth -= flock[i].Proll *.05; + + /* follow terrain elevation */ + terrain_z=terrain_height(flock[i].PX,flock[i].PY); + + /* use a "spring-mass-damp" system of terrain follow */ + flock[i].PZv = flock[i].PZv - + .01 * (flock[i].PZ - (MAX(terrain_z,0.) + + 2.*(float)i/NUM_PLANES+.3)) - flock[i].PZv *.04; + + /* U-turn if fly off world!! */ + if (flock[i].PX < 1 || flock[i].PX > GRID_RANGE - 2 || flock[i].PY < 1 || flock[i].PY > GRID_RANGE - 2) + flock[i].Pazimuth += M_PI; + + /* move planes */ + flock[i].PX += cosf(flock[i].Pazimuth) * speed; + flock[i].PY += sinf(flock[i].Pazimuth) * speed; + flock[i].PZ += flock[i].PZv; + + } + + for (i = 0; i < NUM_PLANES; i++) { + *((float *) paper_plane_pos[i].vdata + 0) = flock[i].PX; + *((float *) paper_plane_pos[i].vdata + 1) = flock[i].PY; + *((float *) paper_plane_pos[i].vdata + 2) = flock[i].PZ; + *((float *) paper_plane_pos[i].vdata + 3) = flock[i].Pazimuth * RAD_TO_DEG; + *((float *) paper_plane_pos[i].vdata + 4) = flock[i].PZv * (-500.); + *((float *) paper_plane_pos[i].vdata + 5) = flock[i].Proll *RAD_TO_DEG; + } +} + +/* compute height above terrain */ +static float terrain_height(float x, float y) +{ + + float dx, dy; + float z00, z01, z10, z11; + float dzx1, dzx2, z1, z2; + int xi, yi; + + x /= XYScale; + y /= XYScale; + xi = MIN((int)x, GridDim-2); + yi = MIN((int)y, GridDim-2); + dx = x - xi; + dy = y - yi; + + /* + View looking straight down onto terrain + + <--dx--> + + z00----z1-------z10 (terrain elevations) + | | | + ^ | Z at(x,y) | + | | | | + dy | | | + | | | | + | | | | + V z00----z2-------z10 + (xi,yi) + + Z= height returned + + */ + + z00 = A[xi * GridDim + yi]; + z10 = A[(xi + 1) * GridDim + yi]; + z01 = A[xi * GridDim + yi + 1]; + z11 = A[(xi + 1) * GridDim + yi + 1]; + + dzx1 = z10 - z00; + dzx2 = z11 - z01; + + z1 = z00 + dzx1 * dx; + z2 = z01 + dzx2 * dx; + + return (ScaleZ*((1.0 - dy) * z1 + dy * z2)); +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/gm_main.c b/lib/glut-3.7.6/progs/demos/skyfly/gm_main.c new file mode 100644 index 0000000000..a74c8f0bf0 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/gm_main.c @@ -0,0 +1,341 @@ + +#include +#include +#include +#include + +#include "skyfly.h" + +void init_misc(void); +void init_skyfly(void); +void sim_singlechannel(void); +void cull_proc(void); +void draw_proc(void); + +#define SKY_R 0.23f +#define SKY_G 0.35f +#define SKY_B 0.78f + +#define TERR_DARK_R 0.27f +#define TERR_DARK_G 0.18f +#define TERR_DARK_B 0.00f + +#define TERR_LITE_R 0.24f +#define TERR_LITE_G 0.53f +#define TERR_LITE_B 0.05f + +typedef struct { + unsigned char red; + unsigned char green; + unsigned char blue; +} palette_t; + +palette_t pal[256]; +static int buttons[BUTCOUNT] = { 0 }; +static int mouse_x, mouse_y; + +GLboolean show_timer = GL_FALSE; +GLboolean fullscreen = GL_FALSE; + +int Xgetbutton(int button) +{ + int b; + if (button < 0 || button >= BUTCOUNT) + return -1; + b = buttons[button]; + if (button < LEFTMOUSE) + buttons[button] = 0; + return b; +} + +int Xgetvaluator(int val) +{ + switch (val) { + case MOUSEX: + return mouse_x; + case MOUSEY: + return mouse_y; + default: + return -1; + } +} + +void setPaletteIndex(int i, GLfloat r, GLfloat g, GLfloat b) +{ + pal[i].red = (255.0F * r); + pal[i].green = (255.0F * g); + pal[i].blue = (255.0F * b); +} + +void init_cmap(void) +{ + int ii, jj, color; + GLfloat r0, g0, b0, r1, g1, b1; + + /* Set up color map */ + color = 10; + memset(pal,0,sizeof(pal)); + + /* Sky colors */ + sky_base = color; + r0 = SKY_R; r1 = 1.0f; + g0 = SKY_G; g1 = 1.0f; + b0 = SKY_B; b1 = 1.0f; + for (ii = 0; ii < SKY_COLORS; ii++) { + GLfloat p, r, g, b; + p = (GLfloat) ii / (SKY_COLORS-1); + r = r0 + p * (r1 - r0); + g = g0 + p * (g1 - g0); + b = b0 + p * (b1 - b0); + for (jj = 0; jj < FOG_LEVELS; jj++) { + GLfloat fp, fr, fg, fb; + fp = (FOG_LEVELS > 1) ? (GLfloat) jj / (FOG_LEVELS-1) : 0.0f; + fr = r + fp * (fog_params[0] - r); + fg = g + fp * (fog_params[1] - g); + fb = b + fp * (fog_params[2] - b); + setPaletteIndex(sky_base + (ii*FOG_LEVELS) + jj, fr, fg, fb); + } + } + color += (SKY_COLORS * FOG_LEVELS); + + /* Terrain colors */ + terr_base = color; + r0 = TERR_DARK_R; r1 = TERR_LITE_R; + g0 = TERR_DARK_G; g1 = TERR_LITE_G; + b0 = TERR_DARK_B; b1 = TERR_LITE_B; + for (ii = 0; ii < TERR_COLORS; ii++) { + GLfloat p, r, g, b; + p = (GLfloat) ii / (TERR_COLORS-1); + r = r0 + p * (r1 - r0); + g = g0 + p * (g1 - g0); + b = b0 + p * (b1 - b0); + for (jj = 0; jj < FOG_LEVELS; jj++) { + GLfloat fp, fr, fg, fb; + fp = (FOG_LEVELS > 1) ? (GLfloat) jj / (FOG_LEVELS-1) : 0.0f; + fr = r + fp * (fog_params[0] - r); + fg = g + fp * (fog_params[1] - g); + fb = b + fp * (fog_params[2] - b); + setPaletteIndex(terr_base + (ii*FOG_LEVELS) + jj, fr, fg, fb); + } + } + color += (TERR_COLORS * FOG_LEVELS); + + /* Plane colors */ + plane_colors[0] = color; + plane_colors[1] = color + (PLANE_COLORS/2); + plane_colors[2] = color + (PLANE_COLORS-1); + r0 = 0.4; r1 = 0.8; + g0 = 0.4; g1 = 0.8; + b0 = 0.1; b1 = 0.1; + for (ii = 0; ii < PLANE_COLORS; ii++) { + GLfloat p, r, g, b; + p = (GLfloat) ii / (PLANE_COLORS); + r = r0 + p * (r1 - r0); + g = g0 + p * (g1 - g0); + b = b0 + p * (b1 - b0); + setPaletteIndex(plane_colors[0] + ii, r, g, b); + } + color += PLANE_COLORS; +#if 0 + GM_setPalette(pal,256,0); + GM_realizePalette(256,0,true); +#endif +} + +void draw(void); + +void gameLogic(void) +{ + sim_singlechannel(); + draw(); +} + +/* When not visible, stop animating. Restart when visible again. */ +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) { + glutIdleFunc(gameLogic); + } else { + glutIdleFunc(NULL); + } +} + +int lastCount; /* Timer count for last fps update */ +int frameCount; /* Number of frames for timing */ +int fpsRate; /* Current frames per second rate */ + +void draw(void) +{ + int newCount; + char buf[20]; + int i, len; + + /* Draw the frame */ + cull_proc(); + draw_proc(); + + /* Update the frames per second count if we have gone past at least + a quarter of a second since the last update. */ + newCount = glutGet(GLUT_ELAPSED_TIME); + frameCount++; + if ((newCount - lastCount) > 1000) { + fpsRate = (int) ((10000.0f / (newCount - lastCount)) * frameCount); + lastCount = newCount; + frameCount = 0; + } + if (show_timer) { + sprintf(buf,"%3d.%d fps", fpsRate / 10, fpsRate % 10); + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_BLEND); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, Wxsize, 0, Wysize, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glColor3f(1.0f, 1.0f, 0.0f); + glRasterPos2i(10, 10); + len = strlen(buf); + for (i = 0; i < len; i++) + glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buf[i]); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + } + + glutSwapBuffers(); +} + +void +reshape(int width, int height) +{ + Wxsize = width; + Wysize = height; + + mouse_x = Wxsize/2; + mouse_y = Wysize/2; + + glViewport(0, 0, width, height); +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char c, int x, int y) +{ + switch (c) { + case 0x1B: + exit(0); + break; + case 'r': + buttons[RKEY] = 1; + break; + case '.': + buttons[PERIODKEY] = 1; + break; + case ' ': + buttons[SPACEKEY] = 1; + break; + case 'f': + set_fog(!fog); + break; + case 'd': + set_dither(!dither); + break; + case 't': + show_timer = !show_timer; + break; + } +} + +void mouse(int button, int state, int x, int y) +{ + mouse_x = x; + mouse_y = y; + switch (button) { + case GLUT_LEFT_BUTTON: + buttons[LEFTMOUSE] = (state == GLUT_DOWN); + break; + case GLUT_MIDDLE_BUTTON: + buttons[MIDDLEMOUSE] = (state == GLUT_DOWN); + break; + case GLUT_RIGHT_BUTTON: + buttons[RIGHTMOUSE] = (state == GLUT_DOWN); + break; + } +} + +void motion(int x, int y) +{ + mouse_x = x; + mouse_y = y; +} + + +/* ARGSUSED1 */ +void special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + buttons[LEFTARROWKEY] = 1; + break; + case GLUT_KEY_UP: + buttons[UPARROWKEY] = 1; + break; + case GLUT_KEY_RIGHT: + buttons[RIGHTARROWKEY] = 1; + break; + case GLUT_KEY_DOWN: + buttons[DOWNARROWKEY] = 1; + break; + case GLUT_KEY_PAGE_UP: + buttons[PAGEUPKEY] = 1; + break; + case GLUT_KEY_PAGE_DOWN: + buttons[PAGEDOWNKEY] = 1; + break; + } +} + +int +main(int argc, char **argv) +{ + glutInit(&argc, argv); + + if (argc > 1 && !strcmp(argv[1], "-f")) + fullscreen = GL_TRUE; + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); + if (fullscreen) { + glutGameModeString("640x480:16@60"); + glutEnterGameMode(); + } else { + glutInitWindowSize(400, 400); + glutCreateWindow("GLUT-based OpenGL skyfly"); + } + glutDisplayFunc(draw); + glutReshapeFunc(reshape); + glutVisibilityFunc(visible); + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutPassiveMotionFunc(motion); + glutSpecialFunc(special); + + init_misc(); + if (!rgbmode) + init_cmap(); + init_skyfly(); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/skyfly/image.c b/lib/glut-3.7.6/progs/demos/skyfly/image.c new file mode 100644 index 0000000000..b4448399df --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/image.c @@ -0,0 +1,33 @@ +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +unsigned char * read_bwimage(char *name, int *w, int *h) +{ + unsigned char *image; + FILE *image_in; + int components; + + if ( (image_in = fopen(name, "rb")) == NULL) { + return 0; + } + + if (strncmp("terrain", name, 7) == 0) { + *w = 256; + *h = 256; + } else if (strncmp("clouds", name, 6) == 0) { + *w = 128; + *h = 128; + } + components = 1; + + if (components != 1) + return 0; + + image = (unsigned char *)malloc(sizeof(unsigned char) * *w * *h); + + fread(image, sizeof image[0], *w * *h, image_in); + fclose(image_in); + return image; +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/perfdraw.c b/lib/glut-3.7.6/progs/demos/skyfly/perfdraw.c new file mode 100644 index 0000000000..5dc4bb9f51 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/perfdraw.c @@ -0,0 +1,331 @@ + +/* + * perfdraw.c - $Revision: 1.4 $ + */ + +#include +#include +#include +#include "skyfly.h" + +#if !defined(GL_VERSION_1_1) +#if defined(GL_EXT_texture_object) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#define glDeleteTextures(A,B) +#endif +#endif + +/* static routine decls */ + +extern int clouds; +static void drawlitmesh_11(float *objdata); +static void drawcolrtexmesh_10(float *objdata); +static void drawclouds(float *objdata); + +void drawperfobj(perfobj_t *perfobj) +{ + float *vdata_ptr =(float *) perfobj->vdata; + extern void texenv(int), lightpos(void); + + unsigned int *flagsptr = perfobj->flags; + float *dp; + + for (;;) { + switch (*flagsptr) { + /* + * A paper plane is a single tmesh folded on itself so the orientations + * of some triangles in the mesh are incorrect with respect to + * their normals. This is solved by drawing the tmesh twice; + * first draw only backfaces, then only frontfaces. + */ + case PD_DRAW_PAPER_PLANE: + flagsptr += 1; + glCullFace(GL_FRONT); + drawlitmesh_11(vdata_ptr); + glCullFace(GL_BACK); + drawlitmesh_11((float *)((perfobj_vert_t *) vdata_ptr + 11)); + glPopMatrix(); + break; + + case PD_DRAW_TERRAIN_CELL: + dp = *(float **) (flagsptr + 1); + flagsptr += 2; + drawcolrtexmesh_10(dp); + break; + + case PD_DRAW_CLOUDS: + if (rgbmode) { +#if 0 + glColor3ub(0x30, 0x40, 0xb0); +#else + glColor3f(1.0f, 1.0f, 1.0f); +#endif + } + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + /*texenv(2);*/ + drawclouds(vdata_ptr); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + flagsptr += 1; + break; + + case PD_PAPER_PLANE_MODE: + switch (*(flagsptr + 1)) { + case PLANES_START: + glShadeModel(GL_FLAT); + glEnable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + if (fog && !rgbmode) + glDisable(GL_FOG); + break; + case PLANES_END: + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); + if (fog && !rgbmode && FOG_LEVELS > 1) + glEnable(GL_FOG); + break; + } + flagsptr += 2; + break; + + case PD_PAPER_PLANE_POS: /* contains the pushmatrix */ + glPushMatrix(); + glTranslatef(*(vdata_ptr), *(vdata_ptr + 1), *(vdata_ptr + 2)); + glRotatef(*(vdata_ptr + 3), 0.0, 0.0, 1.0); + glRotatef(*(vdata_ptr + 4), 0.0, 1.0, 0.0); + glRotatef(*(vdata_ptr + 5), 1.0, 0.0, 0.0); + flagsptr += 1; + break; + + case PD_VIEWER_POS: + glLoadIdentity(); + glRotatef(-90., 1.0, 0., 0.); + glRotatef(*(vdata_ptr + 3) * RAD_TO_DEG, 0.0, 0.0, 1.0); /* yaw */ + lightpos(); + glTranslatef(-*(vdata_ptr), -*(vdata_ptr + 1), -*(vdata_ptr + 2)); + flagsptr += 1; + break; + + case PD_TEXTURE_BIND: + glBindTexture(GL_TEXTURE_2D, *(flagsptr + 1)); + texenv(*(flagsptr + 1)); + glEnable(GL_TEXTURE_2D); + flagsptr += 2; + break; + + case PD_END: + return; + + default: + fprintf(stderr, "Bad PD primitive %d\n", *flagsptr); + flagsptr++; + break; + } + } +} + +/* + * Notice how the following routines unwind loops and pre-compute indexes + * at compile time. This is crucial in obtaining the maximum data transfer + * from cpu to the graphics pipe. + */ +static void drawlitmesh_11(float *op) +{ + glBegin(GL_TRIANGLE_STRIP); + /* one */ + glNormal3fv((op + PD_V_NORMAL)); + glVertex3fv((op + PD_V_POINT)); + /* two */ + glNormal3fv((op + (PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (PD_V_SIZE + PD_V_POINT))); + /* three */ + glNormal3fv((op + (2 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT))); + /* four */ + glNormal3fv((op + (3 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT))); + /* five */ + glNormal3fv((op + (4 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT))); + /* six */ + glNormal3fv((op + (5 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT))); + /* seven */ + glNormal3fv((op + (6 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT))); + /* eight */ + glNormal3fv((op + (7 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT))); + /* nine */ + glNormal3fv((op + (8 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT))); + /* ten */ + glNormal3fv((op + (9 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT))); + /* eleven */ + glNormal3fv((op + (10 * PD_V_SIZE + PD_V_NORMAL))); + glVertex3fv((op + (10 * PD_V_SIZE + PD_V_POINT))); + + glEnd(); + +} + +static void drawcolrtexmesh_10(float *op) +{ + glBegin(GL_TRIANGLE_STRIP); + /* one */ + glTexCoord2fv((op + PD_V_TEX)); + glColor3fv((op + PD_V_COLOR)); + glVertex3fv((op + PD_V_POINT)); + /* two */ + glTexCoord2fv((op + (PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (PD_V_SIZE + PD_V_POINT))); + /* three */ + glTexCoord2fv((op + (2 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (2 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (2 * PD_V_SIZE + PD_V_POINT))); + /* four */ + glTexCoord2fv((op + (3 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (3 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (3 * PD_V_SIZE + PD_V_POINT))); + /* five */ + glTexCoord2fv((op + (4 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (4 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (4 * PD_V_SIZE + PD_V_POINT))); + /* six */ + glTexCoord2fv((op + (5 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (5 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (5 * PD_V_SIZE + PD_V_POINT))); + /* seven */ + glTexCoord2fv((op + (6 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (6 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (6 * PD_V_SIZE + PD_V_POINT))); + /* eight */ + glTexCoord2fv((op + (7 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (7 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (7 * PD_V_SIZE + PD_V_POINT))); + /* nine */ + glTexCoord2fv((op + (8 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (8 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (8 * PD_V_SIZE + PD_V_POINT))); + /* ten */ + glTexCoord2fv((op + (9 * PD_V_SIZE + PD_V_TEX))); + glColor3fv((op + (9 * PD_V_SIZE + PD_V_COLOR))); + glVertex3fv((op + (9 * PD_V_SIZE + PD_V_POINT))); + + glEnd(); +} + +static void drawclouds(float *op) +{ +#define SKY_STRIPS 24 + + /* Break into quad strips so cheap fog works better */ + if (0 == clouds) { + + GLfloat *vc0, *vc1, *vc2; + GLfloat *tc0, *tc1, *tc2; + GLfloat sky_s0, sky_s1, sky_t0, sky_t1; + GLfloat sky_x0, sky_x1, sky_y0, sky_y1, sky_z; + int ii, jj; + GLfloat s0, s1, t0, t1; + GLfloat x0, x1, y0, y1, z0; + + vc0 = op + PD_V_POINT; + vc1 = op + PD_V_POINT + PD_V_SIZE; + vc2 = op + PD_V_POINT + PD_V_SIZE * 2; + + tc0 = op + PD_V_TEX; + tc1 = op + PD_V_TEX + PD_V_SIZE; + tc2 = op + PD_V_TEX + PD_V_SIZE * 2; + + sky_s0 = tc0[0]; + sky_s1 = tc1[0]; + sky_t0 = tc0[1]; + sky_t1 = tc2[1]; + + sky_x0 = vc0[0]; + sky_x1 = vc1[0]; + sky_y0 = vc0[1]; + sky_y1 = vc2[1]; + sky_z = vc0[2]; + + clouds = glGenLists(1); + + glNewList(clouds, GL_COMPILE); + + s1 = (1.0f / SKY_STRIPS) * (sky_s1 - sky_s0); + t1 = (1.0f / SKY_STRIPS) * (sky_t1 - sky_t0); + x1 = (1.0f / SKY_STRIPS) * (sky_x1 - sky_x0); + y1 = (1.0f / SKY_STRIPS) * (sky_y1 - sky_y0); + + z0 = sky_z; + s0 = sky_s0; + x0 = sky_x0; + + for (ii = 0; ii < SKY_STRIPS; ii++, s0 += s1, x0 += x1) { + + t0 = sky_t0; + y0 = sky_y0; + + glBegin(GL_QUAD_STRIP); + + glTexCoord2f(s0, t0); + glVertex3f(x0, y0, z0); + + glTexCoord2f(s0 + s1, t0); + glVertex3f(x0 + x1, y0, z0); + + for (jj = 0; jj < SKY_STRIPS; jj++, t0 += t1, y0 += y1) { + + glTexCoord2f(s0 + s1, t0 + t1); + glVertex3f(x0 + x1, y0 + y1, z0); + + glTexCoord2f(s0, t0 + t1); + glVertex3f(x0, y0 + y1, z0); + } + + glEnd(); + + } + + glEndList(); + } + + glCallList(clouds); +} + +void putv3fdata(float *v, perfobj_vert_t *ptr) +{ + ptr->vert[0] = v[0]; + ptr->vert[1] = v[1]; + ptr->vert[2] = v[2]; +} + +void putc3fdata(float *c, perfobj_vert_t *ptr) +{ + ptr->color[0] = c[0]; + ptr->color[1] = c[1]; + ptr->color[2] = c[2]; +} + +void putn3fdata(float *n, perfobj_vert_t *ptr) +{ + ptr->normal[0] = n[0]; + ptr->normal[1] = n[1]; + ptr->normal[2] = n[2]; +} + +void putt2fdata(float *t, perfobj_vert_t *ptr) +{ + ptr->texture[0] = t[0]; + ptr->texture[1] = t[1]; +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/random.c b/lib/glut-3.7.6/progs/demos/skyfly/random.c new file mode 100644 index 0000000000..7c8ee43aa4 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/random.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef __STDC__ + #pragma weak initstate = _initstate + #pragma weak random = _random + #pragma weak setstate = _setstate + #pragma weak srandom = _srandom +#endif +/*#include "synonyms.h"*/ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)random.c 5.5 (Berkeley) 7/6/88"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include /* for prototyping */ + +#undef random +long random(void); + +/* + * random.c: + * An improved random number generation package. In addition to the standard + * rand()/srand() like interface, this package also has a special state info + * interface. The initstate() routine is called with a seed, an array of + * bytes, and a count of how many bytes are being passed in; this array is then + * initialized to contain information for random number generation with that + * much state information. Good sizes for the amount of state information are + * 32, 64, 128, and 256 bytes. The state can be switched by calling the + * setstate() routine with the same array as was initiallized with initstate(). + * By default, the package runs with 128 bytes of state information and + * generates far better random numbers than a linear congruential generator. + * If the amount of state information is less than 32 bytes, a simple linear + * congruential R.N.G. is used. + * Internally, the state information is treated as an array of longs; the + * zeroeth element of the array is the type of R.N.G. being used (small + * integer); the remainder of the array is the state information for the + * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of + * state information, which will allow a degree seven polynomial. (Note: the + * zeroeth word of state information also has some other information stored + * in it -- see setstate() for details). + * The random number generation technique is a linear feedback shift register + * approach, employing trinomials (since there are fewer terms to sum up that + * way). In this approach, the least significant bit of all the numbers in + * the state table will act as a linear feedback shift register, and will have + * period 2^deg - 1 (where deg is the degree of the polynomial being used, + * assuming that the polynomial is irreducible and primitive). The higher + * order bits will have longer periods, since their values are also influenced + * by pseudo-random carries out of the lower bits. The total period of the + * generator is approximately deg*(2**deg - 1); thus doubling the amount of + * state information has a vast influence on the period of the generator. + * Note: the deg*(2**deg - 1) is an approximation only good for large deg, + * when the period of the shift register is the dominant factor. With deg + * equal to seven, the period is actually much longer than the 7*(2**7 - 1) + * predicted by this formula. + */ + + + +/* + * For each of the currently supported random number generators, we have a + * break value on the amount of state information (you need at least this + * many bytes of state info to support this random number generator), a degree + * for the polynomial (actually a trinomial) that the R.N.G. is based on, and + * the separation between the two lower order coefficients of the trinomial. + */ + +#define TYPE_0 0 /* linear congruential */ +#define BREAK_0 8 +#define DEG_0 0 +#define SEP_0 0 + +#define TYPE_1 1 /* x**7 + x**3 + 1 */ +#define BREAK_1 32 +#define DEG_1 7 +#define SEP_1 3 + +#define TYPE_2 2 /* x**15 + x + 1 */ +#define BREAK_2 64 +#define DEG_2 15 +#define SEP_2 1 + +#define TYPE_3 3 /* x**31 + x**3 + 1 */ +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +#define TYPE_4 4 /* x**63 + x + 1 */ +#define BREAK_4 256 +#define DEG_4 63 +#define SEP_4 1 + + +/* + * Array versions of the above information to make code run faster -- relies + * on fact that TYPE_i == i. + */ + +#define MAX_TYPES 5 /* max number of types above */ + +static const int degrees[ MAX_TYPES ] = { DEG_0, DEG_1, DEG_2, + DEG_3, DEG_4 }; + +static const int seps[ MAX_TYPES ] = { SEP_0, SEP_1, SEP_2, + SEP_3, SEP_4 }; + + + +/* + * Initially, everything is set up as if from : + * initstate( 1, &randtbl, 128 ); + * Note that this initialization takes advantage of the fact that srandom() + * advances the front and rear pointers 10*rand_deg times, and hence the + * rear pointer which starts at 0 will also end up at zero; thus the zeroeth + * element of the state information, which contains info about the current + * position of the rear pointer is just + * MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3. + */ + +static long randtbl[ DEG_3 + 1 ] = { TYPE_3, + 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, + 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, + 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, + 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, + 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, + 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, + 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, + 0xf5ad9d0e, 0x8999220b, 0x27fb47b9 }; + +/* + * fptr and rptr are two pointers into the state info, a front and a rear + * pointer. These two pointers are always rand_sep places aparts, as they cycle + * cyclically through the state information. (Yes, this does mean we could get + * away with just one pointer, but the code for random() is more efficient this + * way). The pointers are left positioned as they would be from the call + * initstate( 1, randtbl, 128 ) + * (The position of the rear pointer, rptr, is really 0 (as explained above + * in the initialization of randtbl) because the state table pointer is set + * to point to randtbl[1] (as explained below). + */ + +static long *fptr = &randtbl[ SEP_3 + 1 ]; +static long *rptr = &randtbl[ 1 ]; + + + +/* + * The following things are the pointer to the state information table, + * the type of the current generator, the degree of the current polynomial + * being used, and the separation between the two pointers. + * Note that for efficiency of random(), we remember the first location of + * the state information, not the zeroeth. Hence it is valid to access + * state[-1], which is used to store the type of the R.N.G. + * Also, we remember the last location, since this is more efficient than + * indexing every time to find the address of the last element to see if + * the front and rear pointers have wrapped. + */ + +static long *state = &randtbl[ 1 ]; + +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; + +static long *end_ptr = &randtbl[ DEG_3 + 1 ]; + + + +/* + * srandom: + * Initialize the random number generator based on the given seed. If the + * type is the trivial no-state-information type, just remember the seed. + * Otherwise, initializes state[] based on the given "seed" via a linear + * congruential generator. Then, the pointers are set to known locations + * that are exactly rand_sep places apart. Lastly, it cycles the state + * information a given number of times to get rid of any initial dependencies + * introduced by the L.C.R.N.G. + * Note that the initialization of randtbl[] for default usage relies on + * values produced by this routine. + */ + +void +srandom( x ) + unsigned x; +{ + register int i; + + if( rand_type == TYPE_0 ) { + state[ 0 ] = (long) x; + } + else { + state[ 0 ] = (long) x; + for( i = 1; i < rand_deg; i++ ) { + state[i] = 1103515245*state[i - 1] + 12345; + } + fptr = &state[ rand_sep ]; + rptr = &state[ 0 ]; + for( i = 0; i < 10*rand_deg; i++ ) random(); + } +} + + + +/* + * initstate: + * Initialize the state information in the given array of n bytes for + * future random number generation. Based on the number of bytes we + * are given, and the break values for the different R.N.G.'s, we choose + * the best (largest) one we can and set things up for it. srandom() is + * then called to initialize the state information. + * Note that on return from srandom(), we set state[-1] to be the type + * multiplexed with the current value of the rear pointer; this is so + * successive calls to initstate() won't lose this information and will + * be able to restart with setstate(). + * Note: the first thing we do is save the current state, if any, just like + * setstate() so that it doesn't matter when initstate is called. + * Returns a pointer to the old state. + */ + +char * +initstate( seed, arg_state, n ) + + unsigned seed; /* seed for R. N. G. */ + char *arg_state; /* pointer to state array */ + size_t n; /* # bytes of state info */ +{ + register char *ostate = (char *)( &state[ -1 ] ); + + if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; + else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; + if( n < BREAK_1 ) { + if( n < BREAK_0 ) { + fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n", n ); + return 0; + } + rand_type = TYPE_0; + rand_deg = DEG_0; + rand_sep = SEP_0; + } + else { + if( n < BREAK_2 ) { + rand_type = TYPE_1; + rand_deg = DEG_1; + rand_sep = SEP_1; + } + else { + if( n < BREAK_3 ) { + rand_type = TYPE_2; + rand_deg = DEG_2; + rand_sep = SEP_2; + } + else { + if( n < BREAK_4 ) { + rand_type = TYPE_3; + rand_deg = DEG_3; + rand_sep = SEP_3; + } + else { + rand_type = TYPE_4; + rand_deg = DEG_4; + rand_sep = SEP_4; + } + } + } + } + state = &( ( (long *)arg_state )[1] ); /* first location */ + end_ptr = &state[ rand_deg ]; /* must set end_ptr before srandom */ + srandom( seed ); + if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; + else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; + return( ostate ); +} + + + +/* + * setstate: + * Restore the state from the given state array. + * Note: it is important that we also remember the locations of the pointers + * in the current state information, and restore the locations of the pointers + * from the old state information. This is done by multiplexing the pointer + * location into the zeroeth word of the state information. + * Note that due to the order in which things are done, it is OK to call + * setstate() with the same state as the current state. + * Returns a pointer to the old state information. + */ + +char * +setstate( arg_state ) + + const char *arg_state; +{ + register long *new_state = (long *)arg_state; + register int type = (int)new_state[0]%MAX_TYPES; + register int rear = (int)new_state[0]/MAX_TYPES; + char *ostate = (char *)( &state[ -1 ] ); + + if( rand_type == TYPE_0 ) state[ -1 ] = rand_type; + else state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type; + switch( type ) { + case TYPE_0: + case TYPE_1: + case TYPE_2: + case TYPE_3: + case TYPE_4: + rand_type = type; + rand_deg = degrees[ type ]; + rand_sep = seps[ type ]; + break; + + default: + fprintf( stderr, "setstate: state info has been munged; not changed.\n" ); + } + state = &new_state[ 1 ]; + if( rand_type != TYPE_0 ) { + rptr = &state[ rear ]; + fptr = &state[ (rear + rand_sep)%rand_deg ]; + } + end_ptr = &state[ rand_deg ]; /* set end_ptr too */ + return( ostate ); +} + + + +/* + * random: + * If we are using the trivial TYPE_0 R.N.G., just do the old linear + * congruential bit. Otherwise, we do our fancy trinomial stuff, which is the + * same in all ther other cases due to all the global variables that have been + * set up. The basic operation is to add the number at the rear pointer into + * the one at the front pointer. Then both pointers are advanced to the next + * location cyclically in the table. The value returned is the sum generated, + * reduced to 31 bits by throwing away the "least random" low bit. + * Note: the code takes advantage of the fact that both the front and + * rear pointers can't wrap on the same call by not testing the rear + * pointer if the front one has wrapped. + * Returns a 31-bit random number. + */ + +long +random(void) +{ + long i; + + if( rand_type == TYPE_0 ) { + i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff; + } + else { + *fptr += *rptr; + i = (*fptr >> 1)&0x7fffffff; /* chucking least random bit */ + if( ++fptr >= end_ptr ) { + fptr = state; + ++rptr; + } + else { + if( ++rptr >= end_ptr ) rptr = state; + } + } + return( i ); +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/skyfly.c b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.c new file mode 100644 index 0000000000..8143cd3dde --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.c @@ -0,0 +1,777 @@ + +/* + * skyfly.c $Revision: 1.5 $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include "skyfly.h" + +#if !defined(GL_VERSION_1_1) +#if defined(GL_EXT_texture_object) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) +#else +#define glBindTexture(A,B) +#define glGenTextures(A,B) +#define glDeleteTextures(A,B) +#endif +#if defined(GL_EXT_texture) +#define GL_RGB5 GL_RGB5_EXT +#else +#define GL_RGB5 GL_RGB +#endif +#endif + +#define ERR_WARNING 0x1 +#define ERR_FATAL 0x2 +#define ERR_SYSERR 0x4 + +#define AMALLOC(a, type, num, func) { \ + if((int)(a = (type*)malloc(sizeof(type)*(num))) <= 0) \ + err_msg(ERR_FATAL, func, "amalloc failed"); \ +} + +float ScaleZ = 2.3; /* Terrain height scale factor */ +int CellDim = 4; /* Terrain cell is CellDim X Celldim quads */ +int NumCells = 36; /* Terrain grid is NumCells X NumCells cells */ +int GridDim; /* Terrain grid is GridDim X GridDim quads */ +float XYScale; /* Conversion from world-space to grid index */ +float CellSize; /* World-space size of cell */ + +int Init_pos; /* if true, set initial position and kbd mode */ +float Init_x, Init_y, Init_z, Init_azimuth; +int rgbmode = GL_TRUE; + +/* Color index ramp info */ +int sky_base, terr_base; +int plane_colors[3]; + +/* + * Data that changes from frame to frame needs to be double-buffered because + * two processes may be working on two different frames at the same time. + */ +typedef struct buffered_data_struct { + + /* objects */ + perfobj_t paper_plane_pos_obj[NUM_PLANES]; + perfobj_t viewer_pos_obj; + + /* flags */ + unsigned int paper_plane_pos_flags[2]; + unsigned int viewer_pos_flags[2]; + + /* data */ + float paper_plane_position[NUM_PLANES][6]; + float viewer_position[4]; + +} buffered_data; + +/* + * This is the per-pipe data structure which holds pipe id, semaphores, + * and variable data buffers. Both gfxpipe and buffer structures live in + * shared memory so the sim can communicate with its forked children. + */ +typedef struct gfxpipe_data_struct { + int gfxpipenum; + buffered_data **buffers; + +} gfxpipe_data; + +static gfxpipe_data *gfxpipe; /* A processes' gfxpipe struct */ +static gfxpipe_data *gfxpipes[1]; /* Maximum of 1 graphics pipe */ +static int num_pipes; +float fog_params[4]; /* Fog and clear color */ +static float fog_density = 0.025*2; +float far_cull = 31.; /* Far clip distance from eye */ +int mipmap = 0; +static int texmode = GL_NEAREST; + +static int threecomp = 1; + +int dither = GL_TRUE, fog = GL_TRUE; +int Wxsize = 320, Wysize = 240; /* Default to 320x240 window */ + +/* + * All non-variable data like geometry is stored in shared memory. This way + * forked processes avoid duplicating data unnecessarily. + */ +shared_data *SharedData; + +/* //////////////////////////////////////////////////////////////////////// */ + +void sim_proc(void); +void sim_cyclops(void); +void sim_dualchannel(void); +void sim_singlechannel(void); +void cull_proc(void); +void draw_proc(void); +void sim_exit(void); +void init_misc(void); +void init_shmem(void); +void init_terrain(void); +void init_clouds(void); +void init_paper_planes(void); +void init_positions(void); +void init_gfxpipes(void); +void init_gl(int gfxpipenum); +void err_msg(int type, char* func, char* error); +void fly(perfobj_t *viewer_pos); +void fly_paper_planes(perfobj_t *paper_plane_pos); +float terrain_height(void); + +void init_skyfly(void) +{ + init_shmem(); + init_gfxpipes(); + init_clouds(); + init_terrain(); + init_paper_planes(); + init_positions(); + + gfxpipe = gfxpipes[0]; + init_gl(gfxpipe->gfxpipenum); +} + +/* + * This is a single-channel version of the dual-channel simulation + * described above. + */ +void sim_singlechannel(void) +{ + buffered_data **buffered = gfxpipes[0]->buffers; + + fly(&(buffered[0]->viewer_pos_obj)); + fly_paper_planes(buffered[0]->paper_plane_pos_obj); +} + +/*-------------------------------------- Cull ------------------------------*/ + +/* + * The cull and draw processes operate in a classic producer/consumer, + * write/read configuration using a ring buffer. The ring consists of pointers + * to perfobj's instead of actual geometric data. This is important because + * you want to minimize the amount of data 'shared' between two processes that + * run on different processors in order to reduce cache invalidations. + * enter_in_ring and get_from_ring spin on ring full and ring empty + * conditions respectively. + * Since cull/draw are shared group processes(sproc), the ring buffer is + * in the virtual address space of both processes and shared memory is not + * necessary. +*/ + +#define RING_SIZE 1000 /* Size of ring */ + +typedef struct render_ring_struct { + volatile unsigned int head, tail; + perfobj_t **ring; +} render_ring; + +render_ring ringbuffer; + +void enter_in_ring(perfobj_t *perfobj); +perfobj_t* get_from_ring(void); + +void cull_proc(void) +{ + + static struct cull { + perfobj_t **cells; + perfobj_t viewer_pos_obj[2]; + unsigned int viewer_pos_flags[4]; + float viewer_position[2][4]; + float fovx, side, farr, epsilon, plane_epsilon; + } cull; + + static int init = 0; + + if (!init) { + int x, y; + + cull.fovx = FOV *(float) Wxsize /(float) Wysize; + cull.side = far_cull / cosf(cull.fovx / 2.); + cull.farr = 2.* cull.side * sinf(cull.fovx / 2.); + cull.epsilon = sqrtf(2.) * CellSize / 2.; + cull.plane_epsilon = .5; + + cull.cells = (perfobj_t **) malloc(NumCells * NumCells * sizeof(perfobj_t *)); + for (x = 0; x < NumCells; x++) + for (y = 0; y < NumCells; y++) + cull.cells[x * NumCells + y] = + &(SharedData->terrain_cells[x * NumCells + y]); + + ringbuffer.ring = malloc(RING_SIZE * sizeof(perfobj_t *)); + ringbuffer.head = ringbuffer.tail = 0; + + cull.viewer_pos_obj[0].flags = cull.viewer_pos_flags; + cull.viewer_pos_obj[0].vdata = cull.viewer_position[0]; + cull.viewer_pos_obj[1].flags = cull.viewer_pos_flags; + cull.viewer_pos_obj[1].vdata = cull.viewer_position[1]; + + *(cull.viewer_pos_flags) = PD_VIEWER_POS; + *(cull.viewer_pos_flags + 1) = PD_END; + init = 1; + } + + { + float *viewer; + float vX, vY, vazimuth, px, py; + float left_area, right_area; + float left_dx, left_dy, right_dx, right_dy; + float ax, ay, bx, by, cx, cy; + float minx, maxx, miny, maxy; + int i, buffer = 0; + int x, y, x0, y0, x1, y1; + perfobj_t *viewer_pos, *paper_plane_pos; + buffered_data *buffered; + perfobj_t *terrain_texture = &(SharedData->terrain_texture_obj); + perfobj_t *paper_plane = &(SharedData->paper_plane_obj); + perfobj_t *paper_plane_start = &(SharedData->paper_plane_start_obj); + perfobj_t *paper_plane_end = &(SharedData->paper_plane_end_obj); + perfobj_t *clouds_texture = &(SharedData->clouds_texture_obj); + perfobj_t *clouds = &(SharedData->clouds_obj); + + buffered = gfxpipe->buffers[buffer]; + + viewer_pos = &(buffered->viewer_pos_obj); + paper_plane_pos = buffered->paper_plane_pos_obj; + + vX = *((float *) viewer_pos->vdata + 0); + vY = *((float *) viewer_pos->vdata + 1); + vazimuth = *((float *) viewer_pos->vdata + 3); + + viewer = cull.viewer_position[buffer]; + + viewer[0] = vX; + viewer[1] = vY; + viewer[2] = *((float *) viewer_pos->vdata + 2); + viewer[3] = vazimuth; + + /* + * Begin cull to viewing frustrum + */ + ax = (vX - sinf(-vazimuth + cull.fovx *.5) * cull.side); + ay = (vY + cosf(-vazimuth + cull.fovx *.5) * cull.side); + bx = vX; + by = vY; + cx = (vX + sinf(vazimuth + cull.fovx *.5) * cull.side); + cy = (vY + cosf(vazimuth + cull.fovx *.5) * cull.side); + + minx = MIN(MIN(ax, bx), cx); + miny = MIN(MIN(ay, by), cy); + maxx = MAX(MAX(ax, bx), cx); + maxy = MAX(MAX(ay, by), cy); + + x0 = MAX((int) (minx / CellSize), 0); + x1 = MIN((int) (maxx / CellSize) + 1, NumCells); + y0 = MAX((int) (miny / CellSize), 0); + y1 = MIN((int) (maxy / CellSize) + 1, NumCells); + + left_dx = ax - bx; + left_dy = ay - by; + right_dx = cx - bx; + right_dy = cy - by; + + enter_in_ring(&cull.viewer_pos_obj[buffer]); + + if (viewer[2] -cull.epsilon * cull.side)) { + enter_in_ring(cull.cells[x * NumCells + y]); + } + } + } + + enter_in_ring(paper_plane_start); + /* + * Add visible planes to ring buffer + */ + for (i = 0; i < NUM_PLANES; i++) { + + px = *((float *) paper_plane_pos[i].vdata + 0); + py = *((float *) paper_plane_pos[i].vdata + 1); + left_area = left_dx * (py - by) - left_dy * (px - bx); + right_area = right_dx * (py - by) - right_dy * (px - bx); + + if (left_area < cull.plane_epsilon * cull.side && right_area > -cull.plane_epsilon * cull.side) { + enter_in_ring(&paper_plane_pos[i]); + enter_in_ring(paper_plane); + } + } + + enter_in_ring(paper_plane_end); + + if (viewer[2]>SKY_HIGH) { + /* draw clouds after everything else */ + enter_in_ring(clouds_texture); + enter_in_ring(clouds); + } + + enter_in_ring((perfobj_t *) 0); /* 0 indicates end of frame */ + + buffer = !buffer; + } +} + +void enter_in_ring(perfobj_t *perfobj) +{ + while (ringbuffer.head == RING_SIZE+ringbuffer.tail-1) {} + ringbuffer.ring[ringbuffer.head % RING_SIZE] = perfobj; + ringbuffer.head++; +} + +perfobj_t* get_from_ring(void) +{ + static perfobj_t *pobj; + + while(ringbuffer.tail == ringbuffer.head) {} + pobj = ringbuffer.ring[ringbuffer.tail % RING_SIZE]; + ringbuffer.tail++; + return pobj; +} + +/*-------------------------------------- Draw ------------------------------*/ + +void draw_proc(void) +{ + perfobj_t *too_draw; + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + while ((too_draw = get_from_ring())) { + drawperfobj(too_draw); + } +} + + +/*------------------------------- Init -----------------------------------*/ + +void init_texture_and_lighting(void); +void init_buffered_data(buffered_data *buffered); + +void init_misc(void) +{ + float density; + + threecomp = rgbmode; + + /* + * Compute fog and clear color to be linear interpolation between blue + * and white. + */ + density = 1.- expf(-5.5 * fog_density * fog_density * + far_cull * far_cull); + density = MAX(MIN(density, 1.), 0.); + + fog_params[0] = .23 + density *.57; + fog_params[1] = .35 + density *.45; + fog_params[2] = .78 + density *.22; + fog_params[3] = 1.0f; +} + +void init_shmem(void) +{ + int i; + unsigned int *flagsptr; + perfobj_vert_t *vertsptr; + int nflags, nverts; + + AMALLOC(SharedData, shared_data, 1, "init_shmem"); + AMALLOC(SharedData->terrain_cells, perfobj_t, + NumCells * NumCells, "init_shmem"); + AMALLOC(SharedData->terrain_cell_flags, unsigned int *, + NumCells * NumCells, "init_shmem"); + AMALLOC(SharedData->terrain_cell_verts, perfobj_vert_t *, + NumCells * NumCells, "init_shmem"); + + /* + * Allocate the flags and vertices of all terrain cells in 2 big chunks + * to improve data locality and consequently, cache hits + */ + nflags = 2 * CellDim + 1; + AMALLOC(flagsptr, unsigned int, nflags * NumCells * NumCells, "init_shmem"); + nverts = (CellDim + 1) * 2 * CellDim; + AMALLOC(vertsptr, perfobj_vert_t, nverts * NumCells * NumCells, "init_shmem"); + + for (i = 0; i < NumCells * NumCells; i++) { + SharedData->terrain_cell_flags[i] = flagsptr; + flagsptr += nflags; + SharedData->terrain_cell_verts[i] = vertsptr; + vertsptr += nverts; + } +} + +/* + * Initialize gfxpipe data structures. There is one set of semaphores + * per pipe. + */ +void init_gfxpipes(void) +{ + int i, j; + + num_pipes = 1; + + for (i = 0; i < num_pipes; i++) { + + AMALLOC(gfxpipes[i], gfxpipe_data, 1, "initgfxpipes"); + AMALLOC(gfxpipes[i]->buffers, buffered_data *, NBUFFERS, + "init_gfxpipes"); + gfxpipes[i]->gfxpipenum = i; + } + + for (j = 0; j < NBUFFERS; j++) { + AMALLOC(gfxpipes[0]->buffers[j], buffered_data, 1, + "init_gfxpipes"); + init_buffered_data(gfxpipes[0]->buffers[j]); + } +} + +void init_buffered_data(buffered_data *buffered) +{ + int i; + perfobj_t *pobj; + + pobj = &(buffered->viewer_pos_obj); + pobj->flags = buffered->viewer_pos_flags; + pobj->vdata = buffered->viewer_position; + + *(buffered->viewer_pos_flags) = PD_VIEWER_POS; + *(buffered->viewer_pos_flags + 1) = PD_END; + + for (i = 0; i < NUM_PLANES; i++) { + pobj = &(buffered->paper_plane_pos_obj[i]); + pobj->flags = buffered->paper_plane_pos_flags; + pobj->vdata = buffered->paper_plane_position[i]; + } + *(buffered->paper_plane_pos_flags) = PD_PAPER_PLANE_POS; + *(buffered->paper_plane_pos_flags + 1) = PD_END; +} + +/* ARGSUSED */ +void init_gl(int gfxpipenum) +{ + glDrawBuffer(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT); + if (!rgbmode) + glIndexi(0); + + set_fog(fog); + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + set_dither(dither); + + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); + + init_texture_and_lighting(); + + glMatrixMode(GL_PROJECTION); + gluPerspective(FOV * RAD_TO_DEG, (float)Wxsize/(float)Wysize, + .1, far_cull *.95); + glMatrixMode(GL_MODELVIEW); + glHint(GL_FOG_HINT, GL_FASTEST); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fog_density); + + if (rgbmode) { + glFogfv(GL_FOG_COLOR, fog_params); + if (fog && fog_density > 0) + glEnable(GL_FOG); + } else if (FOG_LEVELS > 1) { + glFogi(GL_FOG_INDEX, FOG_LEVELS-1); + if (fog) + glEnable(GL_FOG); + } +} + +unsigned char* read_bwimage(char *name, int *w, int *h); + +void init_texture_and_lighting(void) +{ + + unsigned char *bwimage256, *bwimage128; + int w, h; + + if(!(bwimage256 = (unsigned char*) read_bwimage("terrain.bw", &w, &h))) + if(!(bwimage256 = (unsigned char *) + read_bwimage("/usr/demos/data/textures/terrain.bw", &w, &h))) + err_msg(ERR_FATAL, "init_texture_and_lighting()", + "Can't open terrain.bw"); + + if(w != 256 || h != 256) + err_msg(ERR_FATAL, "init_texture_and_lighting()", + "terrain.bw must be 256x256"); + + if (!(bwimage128 = (unsigned char *) read_bwimage("clouds.bw", &w, &h))) + if (!(bwimage128 = (unsigned char *) + read_bwimage("/usr/demos/data/textures/clouds.bw", &w, &h))) + err_msg(ERR_FATAL, "init_misc()", "Can't open clouds.bw"); + + if (w != 128 || h != 128) + err_msg(ERR_FATAL, "init_misc()", "clouds.bw must be 128x128"); + + if (mipmap) + texmode = GL_LINEAR_MIPMAP_LINEAR; + else + texmode = GL_NEAREST; + + if (!threecomp) { + /* + * 1 and 2-component textures offer the highest performance on SkyWriter + * so they are the most recommended. + */ + glBindTexture(GL_TEXTURE_2D, 1); + if (!mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texmode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texmode); + if (mipmap) + gluBuild2DMipmaps(GL_TEXTURE_2D, /*0,*/ 1, 256, 256, /*0,*/ GL_LUMINANCE, GL_UNSIGNED_BYTE, bwimage256); + else if (rgbmode) + glTexImage2D(GL_TEXTURE_2D, 0, 1, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, bwimage256); + else { +#define TXSIZE 128 + GLubyte buf[TXSIZE*TXSIZE]; + int ii; + gluScaleImage(GL_LUMINANCE, 256, 256, GL_UNSIGNED_BYTE, bwimage256, + TXSIZE, TXSIZE, GL_UNSIGNED_BYTE, buf); + for (ii = 0; ii < TXSIZE*TXSIZE; ii++) { + buf[ii] = terr_base + + FOG_LEVELS * (buf[ii] >> (8-TERR_BITS)); + } +#ifdef GL_COLOR_INDEX8_EXT /* Requires SGI_index_texture and EXT_paletted_texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, TXSIZE, TXSIZE, + 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buf); +#endif +#undef TXSIZE + } + + glBindTexture(GL_TEXTURE_2D, 2); + if (!mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texmode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texmode); + if (mipmap) + gluBuild2DMipmaps(GL_TEXTURE_2D, /*0,*/ 1, 128, 128, /*0,*/ GL_LUMINANCE, GL_UNSIGNED_BYTE, bwimage128); + else if (rgbmode) + glTexImage2D(GL_TEXTURE_2D, 0, 1, 128, 128, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, bwimage128); + else { +#define TXSIZE 64 + GLubyte buf[TXSIZE*TXSIZE]; + int ii; + gluScaleImage(GL_LUMINANCE, 128, 128, GL_UNSIGNED_BYTE, bwimage128, + TXSIZE, TXSIZE, GL_UNSIGNED_BYTE, buf); + for (ii = 0; ii < TXSIZE*TXSIZE; ii++) { + buf[ii] = sky_base + + FOG_LEVELS * (buf[ii] >> (8-SKY_BITS)); + } +#ifdef GL_COLOR_INDEX8_EXT /* Requires SGI_index_texture and EXT_paletted_texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, TXSIZE, TXSIZE, + 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buf); +#endif +#undef TXSIZE + } + } else { + float r0, r1, g0, g1, b0, b1; + int i; + unsigned char *t256 = (unsigned char *)malloc(256*256*3); + + /* terrain */ + r0 = 0.40f; r1 = 0.30f; + g0 = 0.30f; g1 = 0.70f; + b0 = 0.15f; b1 = 0.10f; + + for(i = 0; i < 256*256; i++) { + float t = bwimage256[i] / 255.0f; + t256[3*i+0] = (unsigned char) (255.0f * (r0 + t*t * (r1-r0))); + t256[3*i+1] = (unsigned char) (255.0f * (g0 + t * (g1-g0))); + t256[3*i+2] = (unsigned char) (255.0f * (b0 + t*t * (b1-b0))); + } + glBindTexture(GL_TEXTURE_2D, 1); + if (!mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texmode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texmode); + if (mipmap) + gluBuild2DMipmaps(GL_TEXTURE_2D, /*0,*/ 3, 256, 256, /*0,*/ GL_RGB, GL_UNSIGNED_BYTE, t256); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, t256); + + + /* sky without fog */ + r0 = 0.23; r1 = 1.0f; + g0 = 0.35; g1 = 1.0f; + b0 = 0.78; b1 = 1.0f; + for(i = 0; i < 128*128; i++) { + float t = bwimage128[i] / 255.0f; + t256[3*i+0] = (unsigned char) (255.0f * (r0 + t * (r1-r0))); + t256[3*i+1] = (unsigned char) (255.0f * (g0 + t * (g1-g0))); + t256[3*i+2] = (unsigned char) (255.0f * (b0 + t * (b1-b0))); + } + glBindTexture(GL_TEXTURE_2D, 2); + if (!mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texmode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texmode); + if (mipmap) + gluBuild2DMipmaps(GL_TEXTURE_2D, /*0,*/ 3, 128, 128, /*0,*/ GL_RGB, GL_UNSIGNED_BYTE, t256); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, t256); + + /* sky with fog */ + r0 = fog_params[0]; r1 = 1.0f; + g0 = fog_params[1]; g1 = 1.0f; + b0 = fog_params[2]; b1 = 1.0f; + for(i = 0; i < 128*128; i++) { + float t = bwimage128[i] / 255.0f; + t256[3*i+0] = (unsigned char) (255.0f * (r0 + t * (r1-r0))); + t256[3*i+1] = (unsigned char) (255.0f * (g0 + t * (g1-g0))); + t256[3*i+2] = (unsigned char) (255.0f * (b0 + t * (b1-b0))); + } + glBindTexture(GL_TEXTURE_2D, 3); + if (!mipmap) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texmode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texmode); + if (mipmap) + gluBuild2DMipmaps(GL_TEXTURE_2D, /*0,*/ 3, 128, 128, /*0,*/ GL_RGB, GL_UNSIGNED_BYTE, t256); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, t256); + free(t256); + } + + free(bwimage256); + free(bwimage128); + + /* both textures use BLEND environment */ + if (rgbmode) { + if (threecomp) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + } + } else if (FOG_LEVELS > 1) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); + } else { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + + { + GLfloat position[] = { LX, LY, LZ, 0., }; + GLfloat one[] = { 1.0, 1.0, 1.0, 1.0 }; + + if (rgbmode) + glLightfv(GL_LIGHT0, GL_AMBIENT, one); + glLightfv(GL_LIGHT0, GL_POSITION, position); + glLightfv(GL_LIGHT0, GL_DIFFUSE, one); + glLightfv(GL_LIGHT0, GL_SPECULAR, one); + } + + if (rgbmode) { + GLfloat ambient[] = { 0.3, 0.3, 0.1, 0.0 }; + GLfloat diffuse[] = { 0.7, 0.7, 0.1, 0.0 }; + GLfloat zero[] = { 0.0, 0.0, 0.0, 0.0 }; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero); + } else { + glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, plane_colors); + } + + { + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0); + glEnable(GL_LIGHT0); + } +} + +void lightpos(void) +{ + GLfloat position[] = { LX, LY, LZ, 0., }; + glLightfv(GL_LIGHT0, GL_POSITION, position); +} + +void texenv(int env) +{ + GLfloat colors[3][4] = { { 0., 0., 0., 0., }, + { .1, .1, .1, 0., }, /* terrain */ + { 1., 1., 1., 0., }, }; /* sky */ + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, colors[env]); +} + +/*-------------------------------- Utility ---------------------------------*/ + +void err_msg(int type, char* func, char* error) +{ + char msg[512]; + + if (type & ERR_WARNING) { + fprintf(stderr, "Warning: "); + sprintf(msg, "Warning: %s", error); + } + else if (type & ERR_FATAL) { + fprintf(stderr, "FATAL: "); + sprintf(msg, "FATAL: %s", error); + } + + fprintf(stderr, "%s: %s\n", func, error); + if (type & ERR_SYSERR) { + perror("perror() = "); + fprintf(stderr, "errno = %d\n", errno); + } + fflush(stderr); + + if (type & ERR_FATAL) { + exit(-1); + } +} + +void set_fog(int enable) +{ + fog = enable; + if (fog) { + glEnable(GL_FOG); + if (rgbmode) + glClearColor(fog_params[0], fog_params[1], fog_params[2], 1.0); + else { + glClearIndex(sky_base + FOG_LEVELS - 1); + } + } else { + glDisable(GL_FOG); + if (rgbmode) + glClearColor(0.23, 0.35, 0.78, 1.0); + else { + glClearIndex(sky_base); + } + } +} + +void set_dither(int enable) +{ + dither = enable; + if (dither) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } +} + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/skyfly.dsp b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.dsp new file mode 100644 index 0000000000..9e0e07b3f3 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.dsp @@ -0,0 +1,116 @@ +# Microsoft Developer Studio Project File - Name="skyfly" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=skyfly - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "skyfly.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "skyfly.mak" CFG="skyfly - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "skyfly - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "skyfly - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "skyfly - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "skyfly - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "skyfly - Win32 Release" +# Name "skyfly - Win32 Debug" +# Begin Source File + +SOURCE=.\database.c +# End Source File +# Begin Source File + +SOURCE=.\fly.c +# End Source File +# Begin Source File + +SOURCE=.\gm_main.c +# End Source File +# Begin Source File + +SOURCE=.\image.c +# End Source File +# Begin Source File + +SOURCE=.\perfdraw.c +# End Source File +# Begin Source File + +SOURCE=.\random.c +# End Source File +# Begin Source File + +SOURCE=.\skyfly.c +# End Source File +# Begin Source File + +SOURCE=.\skyfly.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/skyfly/skyfly.h b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.h new file mode 100644 index 0000000000..9ccc41341a --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/skyfly.h @@ -0,0 +1,206 @@ +/* + * skyfly.h $Revision: 1.3 $ +*/ + +#ifdef _WIN32 +#pragma warning(disable : 4244) +#endif + +/* buttons */ +#define ESCKEY 0 +#define RKEY 1 +#define PERIODKEY 2 +#define SPACEKEY 3 + +#define DOWNARROWKEY 4 +#define UPARROWKEY 5 +#define LEFTARROWKEY 6 +#define RIGHTARROWKEY 7 + +#define PAGEDOWNKEY 8 +#define PAGEUPKEY 9 + +#define LEFTMOUSE 10 +#define MIDDLEMOUSE 11 +#define RIGHTMOUSE 12 +#define BUTCOUNT 13 + +/* valuators */ +#define MOUSEX 0 +#define MOUSEY 1 +#define VALCOUNT 2 + +#ifdef _WIN32 +#undef random +extern long random(void); +#else +/* random is defined in stdlib.h, return type varies depending on headers*/ +#endif + +#undef MIN +#undef MAX +#define MIN(a,b) (((a)<(b)) ? (a) : (b)) +#define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#define RAD_TO_DEG (180/M_PI) +#define IRND(x) ((int)((float)(x) * ((float)random()/(float)0x7fffffff))) +#define M_PI 3.14159265358979323846 + +#define NUM_PLANES 20 +#define GRID_RANGE 200 /* 200 kilometers */ +#define FOV (M_PI / 4.) /* 45 degrees */ + +/* + * Light vector +*/ +#define LX 0.0 +#define LY 0.707 +#define LZ 0.707 + +#define FLOATS_PER_VERT_PAIR 16 + +#define NBUFFERS 2 + +#define SKY_CYCLOPS 0 +#define SKY_DUALCHANNEL 1 +#define SKY_SINGLECHANNEL 2 + +/* + * perfobj flags +*/ +#define PD_TEXTURE_BIND 0 +#define PD_DRAW_PAPER_PLANE 1 +#define PD_DRAW_TERRAIN_CELL 2 +#define PD_PAPER_PLANE_MODE 3 +#define PD_PAPER_PLANE_POS 4 +#define PD_VIEWER_POS 5 +#define PD_DRAW_CLOUDS 6 +#define PD_END 0x3fff + +#define PLANES_START 0 +#define PLANES_SECOND_PASS 1 +#define PLANES_END 2 + +/* + * Offsets to data in perfobj_vert_t +*/ +#define PD_V_POINT 0 +#define PD_V_CPACK 3 +#define PD_V_NORMAL 4 +#define PD_V_COLOR 8 +#define PD_V_TEX 12 +#define PD_V_SIZE 16 + +/* + * Padding ensures that vertex data remains quad-word aligned within struct +*/ +typedef struct perfobj_vert_t { + float vert[3]; + unsigned long vpad; + + float normal[3]; + unsigned long npad; + + float color[3]; + unsigned long cpad; + + float texture[2]; + unsigned long tpad[2]; +} perfobj_vert_t; + +/* + * A perfobj is a structure designed for fast rendering. Flags are separated + * from vertex data to improve cacheing behavior. Typically the flags are + * tokens which determine the drawing operation to perform and the vdata are + * perfobj_vert_t's or other floating point data. +*/ +typedef struct perfobj_t { + unsigned int *flags; + float *vdata; +} perfobj_t; + +extern void drawperfobj( perfobj_t *perfptr ); + +extern void putv3fdata( float *source, perfobj_vert_t *vertptr ); +extern void putn3fdata( float *source, perfobj_vert_t *vertptr ); +extern void putc3fdata( float *source, perfobj_vert_t *vertptr ); +extern void putt2fdata( float *source, perfobj_vert_t *vertptr ); + +/* + * This is the structure which contains the database. It is amalloc'ed + * in shared memory so that forked processes can access it. Notice how + * the flags and vertex data are separated to improve cacheing behavior. +*/ +typedef struct shared_data_struct { + /* objects */ + perfobj_t paper_plane_obj; + perfobj_t paper_plane_start_obj; + perfobj_t paper_plane_2ndpass_obj; + perfobj_t paper_plane_end_obj; + perfobj_t terrain_texture_obj; + perfobj_t *terrain_cells; + perfobj_t clouds_texture_obj; + perfobj_t clouds_obj; + + /* flags */ + unsigned int paper_plane_flags[2]; + unsigned int paper_plane_start_flags[3]; + unsigned int paper_plane_2ndpass_flags[3]; + unsigned int paper_plane_end_flags[3]; + unsigned int terrain_texture_flags[3]; + unsigned int **terrain_cell_flags; + unsigned int clouds_texture_flags[3]; + unsigned int clouds_flags[2]; + + /* data */ + perfobj_vert_t paper_plane_verts[22]; + perfobj_vert_t **terrain_cell_verts; + perfobj_vert_t clouds_verts[4]; + +} shared_data; + +/* + * See skyfly.c for comments +*/ +extern shared_data *SharedData; +extern float ScaleZ; +extern int CellDim; +extern int NumCells; +extern int GridDim; +extern float FarCull; +extern float XYScale, CellSize; +extern int Wxsize, Wysize; + +extern int Init_pos; +extern float Init_x, Init_y, Init_z, Init_azimuth; + +extern float far_cull; +extern int rgbmode; +extern float fog_params[4]; +extern int dither, fog; +extern int mipmap; + +/* Color index ramp info */ +extern int sky_base, terr_base; +extern int plane_colors[3]; + +#define SKY_BITS 4 +#define SKY_COLORS (1 << SKY_BITS) + +#define TERR_BITS 4 +#define TERR_COLORS (1 << TERR_BITS) + +#define PLANE_BITS 4 +#define PLANE_COLORS (1 << PLANE_BITS) + +#define FOG_LEVELS 6 + +#define SKY_HIGH 5.0f + +extern void set_fog(int enable); +extern void set_dither(int enable); + +#define cosf(a) cos((float)a) +#define sinf(a) sin((float)a) +#define sqrtf(a) sqrt((float)a) +#define expf(a) exp((float)a) + diff --git a/lib/glut-3.7.6/progs/demos/skyfly/terrain.bw b/lib/glut-3.7.6/progs/demos/skyfly/terrain.bw new file mode 100644 index 0000000000..64de86f660 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/skyfly/terrain.bw @@ -0,0 +1,42 @@ +FFt{i²´·žéæÌËȵ°lôŸ}$#t¼èŠÇÂq]ñgp½;1V{úC¸¢¡·> 9.69?_dIR4.177/75+400/*/&*($51/-Pßô\ð#&((.8[Q)'13G\HCAD;K[O#g÷Ö‚æéZ¹„ùr{v]Fº¶_*-+2=B5JYY`AAKF[ip{xÜë@CTUv°éfxÈú@q{äjôž½Ûìoyqså|ìüéçànS:4A6:Ÿ«ŽžÿœœÞ¨ÞŸ±ôºú{þºS 5LÞìl(^èâ{tjâr+.&ùêmŸwbóüèåÝÐø÷ýÊǹüa8xP5~XêñvéëÁ­†°àÝýÍ ÷F_]o‰†Þ¾øe¹Ãþ蛾èqxYW3釯…‹â+6>3(HZX<=JWQN:)<9+7512+.)((%%&/3%.+,2+%!'28, Pü}e5%-)'.49K\NOBG<6HM-1¹Žž|u›tŸäãµþåhFF=61>:]oLâÜ`;EIJPmî°²¼¶j½ÝsóýÜ[ÿ‹¯êtâxbã²|iìþ|oZMKkfO_aGnxb.çùÈ۴öü»›ß÷ÿŸÜ²îê­ï[BF_P#ZïXX{CFD$74f¥Àbl´Ýwï²u`mv®·åÛDz¿Â¹²Zxeâzy÷’vP÷¼ç¯ùÿee©tI|ãÒŠù®Ïy<¹íPkdigvàì½L¶Žyà¡Ô^0_scUoü·t6!372=K;'&0,(?)$-+-66/7ŸœAð+.'+/CVja7;335>0;..+-/,-344- +-ܦR!(!%+,7Ec^=C;>V[I1Súœyt¹½€Âl!4XXB68;9BOdxŸ{YYVJhçéêvçûú­}âøv±”©]ifŸåoèh}ÿä}}óž§îO>61%:-N\H7>îæ­Û ÏæÃ¬Ûžµø­ûœÝûÝôñd:Nž¼±;JßÞãK446Npxº´²jÛÝ]&^Èå[Päñ¦Ð·««pzæñlnãuwµøåžüôø÷ܹt_åœÔó q›i±úóÑÊÌ€°°}åpâïšÌ†Ïûë[1uÞg`àÁÙCGzcEmp#!+äÜQ*&õ%*'-45?LUC;JQR8@fd¹Ç»ñbâÖÝ/8E19<>BINmvVhèåhTRcëý¦¼›¼xS»ífÅ…ëëma­Æàpsom±Ÿãês{¦¼ÈÜqFNVYQT^3s·µê¿¬¿þëôø´ºôüäûžœœœtwhäæ›BrŸs9+30?bsë®Ýq`óåKð4nq^u½ÛºžÖæbŸ§¾Èåe½þÞ†äsñ÷ËÕê¼ùxb’¡ºÊ¼çÝ_¦ÕÉ ËÏåó®yrµÓÿƒª²þvåÿëž­ëTêâìSFéíK;A=G3JE;G=;?32',400+3ObmCSŸäuI%*$!3CKOLKD?>ML6Hꎑ«êN|©tGUC:B32>;O`àu[~ïzfcf~¦¸ž›©ÜµßGj÷w»ŒôèåkžÇ²žãWzþêêàm﮹¼ž}XS__NZçu|®¿­«Ñ¨µ¶¼¼©©øÿ½²µ¼ßêQvp=íÛ2 +]ôv2)01:G~íìçàRHtQð$@à|S{¹ºÈíä®îóêèê§ŸêëœÕ€¨œçøÛü¦œçq÷«Ð‚¼¬Þ«ÎÄ£‘əчجÁüoîùÝé®»Ž¿ûô_äpg?izh^pU>J0+<.26A70MQÜéýæF*YAõNT õ$+9E<7>=LkTa°¾åJíøf_jPIZcþ¹mQNžìèãîyv|yèÛ{lãóty¹ïúPqúퟲžúݸÈꈻntîž¼çYìÁ›û›ïûêtL<]C*óÃÀÕÉÙÅÉϸµ¦©´µ°_98©Y EãyhV930`±î_2[udlM"".1 9kmRdº‹ˆïÜy®íëýÖØÎ‰Ç‰ÎÇÍÐÊ¡•Ì ¤•΢ˆ‹”öÚ——––ö£‰üȰxiwô‡¨°¼Ý©ñk_éoGacZlwú©ŸøªªêH37DGRfeJE>4WGVM_lë­X0`^3!Lûz3 #::19C<[_@xôtyÇë9MRWhY\îînã{þôÝêèvgyâï»åSäë}jé¾úøçkxŸ›¬¯ïÞ¹ûدâvâèÛ·ýú}°žÞÜô||±l-&"ZèôÕ… ‚Ճ׾¸æ´´æ°åg#Z)J°çàsE42FXhw[7R`hN!E415( xr\©•”Ýû¾Ç¥Ç¡š‰Œš¬’‰‰™ÍɌΠ‹¤¢ö¤ÌŒ””“ö”ö–Ä£•tåèVTä°Ûº´žœµú²|?aâsV3f´„¬¿§µýi<OûœcBsàâ}nüés8(+4[ºßÅ‘òÎÐΗ¡ŒÎ¢Š‚‹†¥ ÙΕ׈¢•¢Ú“£ÎÊš„‚öòÚÚ”Ú“–ö‚zéÞhnÜèsäzé°åþí™imzEEmúÒõ´»µµc@k`]Xk{y{àóXWNQI@C>897-PèÞ¹Û¶¸­Að$%8QK6Hlªþ’ÿº½å}órUloç²¹ÛߺÈêŸquwluñ÷Ne{å{¿´|鵿÷fC}ÁÏy-ïšÕþcf{¹ŽÜúÛ›Û{àêpä­ñé. -871ݾ¯­«‡…ÂÍÓÏÍÀ‹µõ1UkkíªLY\:DŸüeoT½wåŸk@46MjÞëìí÷waiznzú­œ­›Ÿ÷ûg^âìw~¬pH\{{º€®°²ý¿ôj?u›÷EêØìnA`쪹uôùøìŸíàå÷îÛ±c.3374)KŹ…ƒÌ¥×éÀÏY FI~¢‘o½ùÿbå®Üµäsk°ø½rCíÂÞmB==0mñ…ºžÌЬ¼ÔŸ°¯¬!;G<<4{ëøâ$5&"œ’¿«Ëµ÷§™¿ºÝø•}"":L2;Rs[|²rMUID~©ê2N>:;#%18!FFGx}*½¡Š•Œ¡ØØÊƒ¤‹…™ÔËჄÔÖ‘…¢ÓŽÍŃ£öÚ—…cÇ“–£ŒÖñôϕὣ¡ÇÑÏus¨Ãìž¿ñ»›ÍÀ|Rrçµþ|xz­¸ëEEIbkbWHL\ptwwóxL64:HDP<@3+53/*/56?72;M÷ãkbqþâmã|isÿêßwé«ÝúÀå@Lxï¦Ëãú÷úÒµ}rüýºkg{½Uî÷ÕíUzÛæú{/HÈþã{~óähTl\>F2?.U`Jêè-hłׇ•á„™™ËÎˆŠ‡ÔÔ™ËØÔ‘ ƒÇ€Ð€×ØÓ’ÆÎòÚÜŠ¡£òò—£ÄÄ–Æ¿ò””ÏñÁíÍ·uR_ZTWQkŸ§ã`}žû»Ñ’ªm>Wcf\WNx½âu\UYV\oyxv[>;KH3L_@7@:2093;0;?>CWjcTwqVUjsFrÈç|쪾¯­/GRZWmgrjpiltwWf¼ãåµ×žé­4[W›orâêsëìÿº­Üy[éüçœ{Èírxû¾®÷ºv(kýÙýÞϯÞêqt{X[o}qVgHQ<(#=, 鮦ŒÏœý¦»žêþ°|.DkOx²}MW|q~=9RdsYTuç~wX=R]MDYfjb^W@;K@HKYarqjXuì²þ~S÷œfz§ê~9ecD;\jbXbãì¹¶±â{WÜz´Þó%rÆÙÍ˵è:{ulÜܲøÈÝþuHpïžwktèéêz?).zªª‚«ñÜêuã¹Þ¸¼âzJmë¶¾aVäìL4_óT9MVSR^}Q66AfãhjóH1í¤‘Ìƒá ØÌÕÖÔá Ò™…á•ÚáÑÆÏÓÐÒÆÆÖÕÉáÌýì®ØÒéãúàäœË•ŒÖ­Ø‘öڴ”–£¢ånëcAuà@úü=TgTfWo÷viÈ®sv]JÜ¢Úí;?IHNN`lZJT1y^GjcjYB]fVSENBMS]ZKYJ>1?Mn¹ÜäqÛŸ­¬Ý°~ûù{wâfQURVENP^yë½nàdpu{­º°l`®Ðüþûà{|äìúªÜºªý­t22M|º²miàúÜwJ1/&>ݎ̵æßäzþ½žùïr|y½s'IhZEEFNY]RTX_N\[IMQARbkâî_;šÙ ‡ …ІÖÊÓÖšÖÌÕ‘“…šÑÊÕÓÖ×ÉÑÑÆÕ·îÁ²8V´´àÛûï›È×Ìþwü½vÈ¢ô™„×–€StìüKT/]vêoUMUO`ëvRî÷yqxTS»‹”‘rDYBûî²êÿéó©o412BQCOIãÈí^RKIK\þi}Ýê@5AEhhlóZB1-5BUSNZLLdfeœ¶±t++')8*756莾÷±­Ûïyänzç½vUmpWurX[aWN6hgZ«ÊS ÿ­ÃÑñ±ú¹¶Üt›Ç®îí²à(1>éwAé{ku°ž~2",Kï¼…™¿±fãºîÿür»ì¦¸êe|â[je2BLUNMiefXGBKKdh`DS;|ôÑ‘ŒÌË™Íə᠅ჇÓЙÒÓÉÉÕÖ’ÓØÐÖÀÀÀ¶¬ø©²±©¶®¦Ž ÕÝãÞÜÝí|zX.BLD5DTR²ñɰRhtà½óëåíåä^àóVQd==ÿéZêôäM?⾈ΌÓþ_SJ[[XàÛ~``9C?,6vô®®ëXSacsc`êß¼©÷üåž§|Vmâ¹çéúaKu^]_l^kâtìÀ²íÛ«ÇÏÑÀ´ùž½lÿÅæ¼ï{k][àžç°Ürâ|m|ïG;?=/9kôÁ¨’¶å^aZ{ŸíßÛzâ¦ôt/@]ZNUciìçQ>QgOBCI@G=HL}ÝÍŠŒŠ„ŠŠˆ×Ï™ÌÔÑÉÉÉÉÕÍ¥ÇËᆥәǀЂ™Ø‰¢¢¶ìû ¶Üä¶L /úÒÙ¼ügI_W`Z,4/4èüÜ‘”Âc2ûùuFâÈôFCE7GiRK½ù¯Šb­¶PâýÅùãïÞÞéçì¶›Zhÿçph[MTYE6i¹Øàí¾éM2HNSIWvüñ°ëçÞ€ñ{RVwàtéâ@[]\`_RjêþŸ´µ§ý«ÖÔÓÅÍùºà`îšîºë~`^N^ä±ëqwŸ¼ªíxNM89N6`¶ƒ Õ¿­Bxvyܽ²äxï¹¹ÞXUOBNT]]lkIY`XNM@=CG>N~›ªùMTzT%>2.K²¾Ý¯‘âo>q;{gClrîSqP3væø­ï½¬…¹í©×¡Ñøÿ±¯ôÝŸÞ]GLFONAESXi]CïŨdfù‡·ó7C.@ME:Nµý°íü«½u\oQjüz>Y`aX\ü¼¹²÷ÇÐÅÉšÂûüqv§ÂóÞôÝlU]cóLDlyݦ¹lâîy^;OH"u·ƒÙÁÜlÜ~cyàÛûçïêÿŸûúkOFWXZheYN[bPQN@DOOK[;Eë´Éጇ †Ì  ÌØØšÕÒÖÓÓ†ÏÏ‚…ÌÌ‘„ÊÙ᪾ΊÜÿãx²êÝê"Rmüº½íTüµàï™®%@[*08>O%'÷ééŠÀêNTcîy>@H{|=0CãîO8àBæêúÓŸ}é¼Ê¯ÛåÞ‹ÃÝì^I4\çnXWC?ApìR[÷Ãÿdœ†Àºþa[GIPJ0éžÜêŸÝý»þêtkwÝleSjiXûù›¶¾ýÁŽÂ´¶¿»Ýžsi›ë󱬺âQ`qìþuRoâãçt;_±s]adT8føôàúª½s\pïøûþÜüÿ±Ýtlm`]ffpë÷n>=AXœÂx±‡þ²»p+ $$*$!:G9(=°›T2?KE5OíuŸôÞªç-j>7);'&A:S½ä±ÖÕ¼êxO\Xjïê½}ÜÁ§íNZVçv~úvKô¾å{éóézVCORSMdsâ±È|h¹Ò]DW²·ÿeí·Àñ©¦±´Àҫ޻ݸ°çîÞ½fþœ±­}qYgçlóÿã±ûuv}qíëm>zç½èh;KVKCH;GDGfoZ2+09I\k^}ri~óåé´ÆëïÑ\^H\y°©xkß›÷ý°÷ªéogibii_Yijv½ê…üdKà›­§¼¯¦¹¶·ÖËÁÁ­ëÿµ­þêûãóiÝçG]bfàoIQièzvlfíîv{xUUB9AOü¶Þû}hn|_Fjäèûú{m`Qaj`Mlóãäãunqjooqéÿ}uaTVÝÌÆ™¡×ÅÕÕÔÊÊÇÓÊÑŠ“áØ¡„ÌÙƒ‡ÕìУÚÊÃÙ»ñ}rçü{rtZ²ïqüæü(SzU}i=E/)-3*/2.1aôp'7QH4J6)3(&'7<6CTCFJ@KF>KUzhBHHJxþpYggíåªâyïåþÿbYé­¼íyŸ»é²€ôŸÛÞmèêþÿwnsV_`lî¼®ÞèeÆÒ¹Þ®Àƺý‡ÐÝëñ†¥ô®¸æ»çÛàmz|WkÛþü|NGovJ22.2GD@JI49UHCXIP[UFFJC?R]rìè~àfëÿäüú~jyâßl`ax}_Ÿùêk_ç¦ëè}­¾®~cóìúgbrytrsŸ©j}ûÁΚ×Ò®¼ø§¦äªßœ†Þlà›æ®ïôùª|àìKTþûóvþàTrlVxqiå²±ÝîTB]]WR}­’Ðù¸ý›êv[{²Ý°~LKaYií{ãüïŸþóhcM[v_dWVnàÞÁšØÑš ÌÏ̙ӈ†¤¢ŒÙ¡¤¤ö…†Ú¡‹‰‹§ôgpø¾ÝÒ‘®½ëhub_WOVaqsoX7%;KaI>*03AD8:C7=T?9EVFAQZF?JG?F@KK@?SUZs¹ôäéé^tnoyrob_i~›îeXuûã⛲ú÷©ú\WhèëogzwzhvÝÝïüïØšÇ€¸±ï©÷ëÿ¹Èî°Ê´âî­¨ú¹¶Ûé~g;:Ov½wzcClì~oV~°Üº±ï}]ihI`ë€À¹ye½ìè~]YmêyÜÞèêêäâyrvREve}^hqåôÏ¥†Ö€¥ËÒəؤΓŒ‘‘‹ö‹ö‹Ù¤Ù Ñ†Þ»ÙƒšØ†¤«²²éÿnûfdUQZWóÛìÜ·%&ID?RYM653504;@92614OWCH3HfS9?D@?B@cúbç»ñ€ìâžâÿþmþ±P\½èg^hqÛ›{ioy½ßºœí~±îßþQ2Tn_`efjsÞô²ªÿåùÓÉÒÒÕÖÑÁ„ÃøÒ¹ÿü}{Ÿ±÷ß}pójgw@Clèëäí}ERóç~Vwüüäîîÿ÷ãaeää¿Ç¸ø¯ªäVUNXþ›jku\u÷åqwëçifäãëiâSTâ÷ß™Í×áÖÍχÖК„¢““‰†¢”Œ“ˆÍšÂ¨©‰šÜ¦ŠÎˆÓÕ˼{éà|{fHfkQN[róÿø:?@98+28.3;//40AB=:E=54,258@@<9HNXD?RBM@|­ÿœÀñÿïå²²yܹvôãëéu½sxtàhlÿë`fséúçìèìÛ¼›íßûyoèë|yg_WKFd­øµ¦ßØ…Ò„ˆØÌ„¾›œ±¶Üú÷Þ¯äîízpvñ€ÛqIgnzúœœûvú¼}q}Z{ååvuèÝÝçe]Zlâvïô×Ô±óëdJK>TTyt{pvYl~o_p`Gq`NRwpr~ÞЃáÊË Ñ™™„“•¢Š‘‚¡ÎÎ΋ÌÐýʵµª¯§Àú¶¤ŒØ¡Ö›¼ólŸé{\`ãdEACeXZCI=6EEH;6F1%2@LJEOUOIGDY\|Û®ªÿ»ÏýãDbþâïퟟÞí½Ý{eç|WVmkvnp|ÿ±þäî÷ô÷û®­Ý}{~zsrp^]Mhþݛѩ»ÞñÀñ€¶¦øœÈ›÷°ÏÈóäž»xXþᬹêYopmúýÓÖ›xîâóz{äàf|ïüÛûfJVQN34Tå®Ô»lm|k}wàv{óäëÜêzm_]RciSè{h]zt{z÷ÍáÊÉÕš¥ÕÔ•¢¢“‚„‡¡ˆÎ‡ÃÁÆ·¥×¤ƒæËµ½Æ–ö––ý÷êlÜ›žŸâsJ/3P>wûîN\BPTET`E?=AH]hK&FêÅ’çyuÛÛú¶·¦ž°åãÿúètsïÿêàþy^onû®¨ÒÆÑÕÒÊÑÊÐÙˆ¤”‹‡‹š®æŸÿ¹ô´Ã™÷Õ…™’ÖÂÖö—•¤ ƒûwç}ž­x½þQSGb±îcFe`[N>?B=DSfPXCIho}zdGGUL\þ´žfeWBccKé©uHå²êjH?}wbú°mstþ{âÜÜÛ}xhy|ãìêãë±²Ûû÷›ýÝܧ¼­ß½ã}g^Vv²Ýì¸ÖÌšÇЃ¡‘ÇÝí}ëjïßèy»Ïíwëâçüü©çêÛâ@Lþªý¶ª¦é~àà}Ûúêëø¼oBI8Tíþ^@IQHulM_{tXzº§²û²²¹÷åíéyuåžþëê|íë›ÀÆÇŽ¥ÉÕÓÅÖ­üîóßÈ­âó²Þýýñ»ùÈÁûvlgâéruYã4r¹|\LHTG:@9@J?:2GG5=cp?$9LYó¹ôël1wÿœýóŸ¸ëSVSKt±V9<8RHDPAY_SREC@JXQWUjklfpåmij[er]PY_P6;3S䟨ů¹÷ïã~ãoú²çûdMN]IÝucœ·Öˠμ™…´Ûüþôûzãçóyä°ëïë^IY_câÛ›ªÂùÃ’™´xYãÛà÷É×›ëJ=VUQNM^XNUeå{½üô­Ü±íëìçìþééíàëúâ÷§ÂÇ¥ÆÇ€ÉÏ«žµ¶«ªµëíÈ«æñ´¼ýæ·©¯Ð¾¦óTiçÝå÷v?NTT69C77D:;=JRQBY@Qç}^kèäcP[E2F?x’ülåÛÝîÛó/Hq~<,9769:JA9BBEPKEDRSZKD@:DJRRNZq[ben]__Yh`BEjmeR9*,PQåžôܱްþ°üôÜqík`LHBnîFÿø­ßÿýòÐæ›®µÈ¹»æµ°êàuéêåxçî^GKUM]û·§Þ¶¯¿ˆÖú~ÿÝß›¶žk}JCT`SPRXTTXhþžûôŸ›úÝÛéåêêîïüéç¹ÿó¹ÝóìýÒÑÓÒ€ŠÙÔ¸Ž¦¹ž©ø°ŸøŽ¸¼¼ªªù¯œÇô´úoä¹ïnrf==DCCB>?F;;Z\RYAG]mrå¼¾Åvhd>IŽ•î>O÷©Ûê}_YOE3E4=:5AE=?;5OTA>MRSfSAMMFA>@=?2CkZÿû™‚¼ÛÝ{[YMºÎ‰Ð¸`-'í¿|4ckGHBCF=G98?GEB?;@DKC>ENH]UEA@LZb`U^hiyéåhRBENjh^{åîíjëxgÝ®ÜÜßþûúŸúâžzkbvTA;`åW9KqÞÔѧ¾ù¦¼©©ìÿÝÿä~çäãíþóséî[FQPTQkçvwÛßätü߱ſx­®>U´¿±JGRZRMU[[Npìß»ôôß›²ÛÜ÷þäxäãéèéåé±¹±Þ¯ÉÒÕ’ŽÇÃÍ€ý·§µúâàüœñ´Ð‘ÒÆùµ®|jJSúæüOyLUDVYAJHFLVOB28KRfAà©rÉÍ·÷tsäxRfvíšôÓûmMIüÆ÷D7Y:C@DF;QH<=8AD:=E@EEK<;MRYWGDNURZWebk~ycMDFGD<526Góú~úÖ¾¨y}åvjjR]ST{‡Áúx¶…‘ÐÉ»`0A=GDQLQ8;6;F:>HCAHBCAMOWcLMTPKQX`hkL9DmèÝ~ijxâóóçädHnéëÜ›ôÝ÷÷ßÜûãú©xkïé`X^T<:Läq{ý²Þô­«­÷Þ»Þ}uó÷Ÿüêê{oäÿZ=HGIDJr~\bRD[jâvU0L~gâÿsq½êINKJTRVWRU✻œºž¹Üúüïÿëí÷þçãâþëîÂÑùœ²º’¶ÞÞÝ寯›¦ñÜóVo¹±55;?FLP<+?NZëK>:8>C=D_b;wµ¦²pg²ìÝÜpHúßíåpgnan†‚²}}8r¾ØÕÆ„h8VA6;TEG6579?=GDHMhgZZs_@YósywG9Gv±RHhMNFIUa`VWlãè¹ô°Ü¹ß¹Ÿíîï齟²êêü½ççí©©œÈôãœÝÛüª¶ìþúè¶¾êé²eAbn[qß­ù¾zm`PWAD/A~ïÝÿ{oë}®Œšx=BLkyß²ûŸudWPWeyVGIKJGE?;7@I@DHL?EMQOPQOJMMXXVmb}ïÿâfE;>AA;ECUPE;]óœ®ÈžíìÞô²Û±½í›®îŸþÞœþh16<=^X›¦±íåë챩­ÜÞûîúŸüüåü¼žlBHLodLQNWNF:t·ýpH_{TSSU^fepîo1w´±Ya[[eaPC6BVDFKNNSJM^`RPRQ]TWYjuSgcaOD9152@84[IQ`vä½Ûñ·žŸß­Ûܺ²›»¦îå­÷ÿ²|ODC{[/íµ­›Ûêü›ÜêÿßµÜã~û¹Üýœd8GE^þçmm\^fëèóyh~éäïrí_WdaQEKahg]ddâûíïûèíéúû½çíéåíŸywã|âëÝž©Þ½°»¦æ­­žôíyü¯€à}雸ŒÇ±?9BJNKGIJJ>FSDYUPQTRNKGOI9Hn¹²ÜNWTU`[Wl{EaÛ­»ìQeÀ·ÍôàQEUG?CMF9-D|sp[R[U\bJDMFDIIMUGRfh[UVSUV]VWmv[F><>77EHAOhàyvéì½å魵߸Û²²­©ù­úúêºæ©nAlu=è«´œ©ºßô®¦œô­ºâó}ûôÞÜí`_z]eéu{u[I_àãô±h}ª_YXZTTWLP\e`GNâ±éëéíêîàâïï÷ïîìçàçâwêãì÷÷îô¦ñ¨Ò’øúí±ütë»ÞíßÑÐôá¡­à\EN[WCZóódNZckWWls[gh][XnµÎ°­Xyuz|fiTEPZú´°bUü°‡Àéh988GKIGDDE?A9@g`SWR\kirWHIIGLMQKO=GUNVTZTSQWXR@919LOb°œvrëíåbwïÿè즺úï›¶¹œ¹±Þ¦±ÜÜíì°°qZ]m>.ÈÉ®›°Ý»›°œŽñ½nk{°ô»­åQcàeNäçàé½VJ_L[ûûho±âvïàY[^aYXitVIgŸüççy||vläíûß÷ïïàóãç½èúèóçú¹ŽË¯«Žæ¶ôãkQâÿìëþ¯‚„šØÒÍĘ̈h*½Ü²²êäۻȭÛÀ¨ê}sàüß®®éDRXG\ó_nz÷}nbo~a|ºŸ~~ãêVLYWTR\us{ú²ï}üextvâìîäï¹÷dtçèv~éäâì°ÿÛű{{åxó`LQìùÓ¡ˆ‚Èb}ûÁüad}ndbESdXuÿëät{åñŸrrfbea_YbésmêlE\VL9ì¿ûúÈ´€¶¦èû^URQKFBFSPLODJFLNT{xXQ\^mpe`KRVRIPMXVNX^VZQYejlû°E;A;::KlUzàäiozfwª÷þÞ´Ž´ž›þ~wznjþ·¦í½±úXE;휹ŸêéééÝ›°É×ÿlkäïúº¼ó?QMRqXYohty}xcqà|óûÞxâkU_RU]gu}ûßúéä›°hadjããç½sróãhhpoyêâãâë}âì®{ux÷°Üºãxxú¦è}Üübuz>î͵ÿnV]YYp|{iãìlp[bqìãmk_\\bmSóÞìj_cZZKC5uÝßz\®žëà¹hR[SDGDUf?HPMC;ACDOb^Zj^fvygz|mTLIFVUWe^TT]\lA71.1eà½ëó|{è¹›þü›Ðìøºéngw~ó|ß¾ñtéñ~DQO÷»ùÈ©žœ®Þ©²Ý²üÝÞ÷ßì8:C3DzåN}jWbqȼۜéMCmçQfsSJïÁ¬¹ø¬´»È±ï²évosàã}sg^iqhZUW^jvíàjzüÜÿ}|èrÿÜê®§xì}yãgI;CDTzyàkûûÜäQgss}zz}v{]do^kqóxhukWjc^_Ts]jeLVuT.;E=HMOSMILRWVTXORJFIEKJWQB:HG:CRSVTW`{ŸsãïÿuUPXadXcf`\k`Zhls\N`P,)EXB9Uf|çèäãþ±›®›†Ð’ùø»žpvâ}½ååûÜKwýþJELþüœ¨µ¬¬ží·’Þc{äàó[5FHKEU~ëeiffOgÝñÛþê^}qVR\\n¬Â¿Àè⦪Èܽ²]aäuzäynme_XW[RRXjóé|uzãxåït]i¹À±vêca^tc^sxwsâ²à›{ìzà±¹}z¸ÿxo}§ŽÈì|ämjea}|S]qpic\ì®ü]D@@:BHODIONOO[IQU]WPLFVXAFLM\RB:IDDPUOO`]Uo½t{sp}l]\URZahacadknuzjhéü`:?6JNYjuçëìïè÷¯À¯Ž¾Ö·¿¾Ápb||üÿzí|FúÛCHN^orî©îå¯È¯’¶°qzsaltK8G:EThãìwZDICLàŸ±äèíP]ZMVa÷¦ª»üt{yep|¶|HmoqqugfeSQUZSU[bàíïre{uŸ~uûÝÀÜVZcN{Ûê~û±±¦øîã÷rjdé´ýµÑŽè{ܱ©ø¹žëyvkYOMYlutslVZµÂr6MTHGGKKMAHYPSPTWRXRNNOMBKOK[Y[H=HLHGQY_`^WZ_^g]__owi_^iZnbrOLON_Q@e~}yewh^g{|à½êþÿŸ¹Í€·¥ÅÁ¾Ã’èefå÷íxfsåQSêcESUic`°}úþ¿ØÍ´²é{en|àS8LCGJILNSMKQQXV[VKLADDJPQSa_R?HIBFEMGZ_PKL_nYXUgvmlzsivszU@DEE=?;=Pbdzbboêóu}ã½²²Ÿ«ŽÂÉ·ØÇ’¯ýçfâè~{gZäãERSIK^n_R妩œ¸ŽùŽ’À¦þ{jpmçéR8JK;]fåçé\c½´ÆÀ¬¯¸¨¯Ûóoqsjwþn5&JNajwhswnS_`KZ|wSYUZtkghdsëž©ßߎ¼~Qwvg_nxãmCERXU_YZh\]YneI[±ÂþxXs°þÝÅÁ©ÁÂæ›ß¼ßåñüûâêëç½çú®¨©ÛßÎ̾žëÈýÝßÈ©ëßíª}~§ROSUHN[MQKQTWHFN\WTÜïDOI=MMDQLNQLVMHKLHS_VXfab`\_`_kuà|wó½ìïútqãûþäçä{ìí}y|åèìçݯ®¯€€¯¬¹ztìÿçpZldXrëh[Giµ…šªâdo²Òɒ;›âp}rcsí°²ã^G66ICByä^bloj][NZ_Zlszm_黼߰ü±«ÇîÜȺ¹»©ñ­ãQZ_^h[qm]mUg·‹Ç¸¦ïu}}þÝôÞìÿçã²þÞºïï¹Ûܲüäã}zj[\9JI=~µªäzûî{þèsÜxFrR@NXRUODEMQSPCIWPFEIMKEGKTVO°üDQ>:IMOPNNWQLJNUPOPj`RZc_fjhi[Xn|u{ókZWxþïuûÞŸ|xàãþÿâzäå}èyåûµ¶¯¨¬µ›¹Ÿ}q²æÿHkbjèìcUGQÛÑÖ¼²jxïÔ…ØÛpbt½wkaiíâAE@JM?6Säu\urkrr]|ä|Qoyîê}ÛȦŸÿþÛ§ª®Þú¶Èú±œß²Ý­àZ\]^]waOårWý×y^{vç}oYlóëêé½½½î±é¹ìîíÞœþ¦÷ägT[3%4*-#,AD'$2,3Ki°ãoW^OBPQJTQGLNVVCEO[E:NPJHFILTSs}GYCCEGNUUQRRGR^VPRWeaY\c_^ongfdsyxó|_ZRâ²þ½ûßþwiäâ½ëãó½å~|x|ãê¦ùª¼ª¶¦ºùæÝàîþvSbmhî›xD9@Ÿ¶»Ümåߨý¯¿ºUdéåiL=UYVTNWJ?RaVS^r|z~àtŸ©÷anå}}û©žžÿú©æíûêâܺÿ½êééúß°pZYMmè`^ëyHú¸~Vpxçàgil^ãüþþè½î°©¼œ¹ÜÿªßÜÜܪû`}nPMNBW=5;<:DܪÜîàgfyû©ëþüéípTv}[KE9GYYSQJ@dkTMeèìþîããüžëkhå{eí›ë{û¼ù÷Þëì›ïzããëÛûì°ãY^küíÿøç=R}±åilä{hjlSèÛìܹú÷¼¿¹Ü»´êbg|ìÝ­²›­þrSYog½ßîru]A;6Tûëq^RP@HRCN_QNJNUBJFACNSTIBKDGTagWVW^P;?EMMOVQOSWWUZX[ZSanmmroyklwwâ{|wqduèuiêé~âvle_gltnr}y|ç¦ñ®­±íûß¾¯©´«ÞLgdç­žVJ1]ýÈúþÿqVuoíëuïåäóTR^UKLNNOTYLVBE]\T赸µ­ÿ›¶ýßÿs_pã°œï|ãå·É±´Üúßìàçç~ãêóïíbåøÂ„…þVefjn|yâvjgegÛñºô°›ì¹±²ÝûèÝñüóï÷ªøûvë°ÜÿzåþÞôÜîîûO9:4ã›|]WRDT[OPYPKfKLCNFBBAQQKMDLKMNN\U^Y\HFCIUJUWJVPU]_`^bdmzwuäy}xu}}â{~âêíólewwoã~wmlgefhvzä½åë~œ·Í§ª¸µÈñæÞê›Û~UfYëÜœaC2s®»´ùíó|óÿ÷ŸúÿçêäaKWaPQW^ZTV]SMMTVdãã¹´´¼Èª¸Þúäm[íûàû½r²ôí©›úûtvqsrþ÷ìÈswýÆÆÃûwszpttârqhkdk^Y±¦ºu±¹èm÷çób뛟¹°ß§­xpftŸô›©ž±êÿú];7/ã¹fb\YHUbTNUYJOONJBMLJPQUYNKPUPMNZ`PSZYTUSSPS]UPd^\]b]hsóufk{|à~}âä½ëåéì²íb`]bwyslfb\gw|íû÷ÿ~仨ùœ¦ñ·À¹Þ¼®®yZH}Þ»}C0Rîíâ²ñª°{±±²è{ìãäíhSb`V]d\UvkPMN9Wî㞦¹ÈÜô©Þ¹÷ãq\_x}få¹²Ÿàâàjâçx{óç~âýù§Ã¸~ë~óâtj|ç{uxÝ{hk^SDO÷ªyPv÷óC\øô`g°ÿï²ô»ûéyazèøïž´Ü­œŸyD861\wi\R[UVX_VV]oïh46=_f\OP`kfWOMPSTW]IY\OIEMOQV`[NPc]mZZdowttsxzu~½xãâàéíèŸÜxSXm~wri\V]kad}êêälå¶›ÞÛ¼´´°ŸÜ¹®«§½nXîÈâA$R¶žeqºÃªøÜç릲éyãçàcPWV_VPimTX@:ú殲۹¹¶ñ±©»»ÞëÝçgWgóbUpâí»þì}}íçäêêx~óžÐÀèi{zr~ó~óº´î²¼ý¦žïçrTçªþXK:fèßìããxäî~ž®J¸°Ew§·vD@VpqjXMNOKGß²wpbs¶È²µªœ¥…ÊÂÞ^º¶sè²plóã}{tßÝæ±Y~Ýàlã~uä½ã{khÿwmïîxóâz~xvóàååâkó~ngfoyxrgbR[dslmiãÝîfhz`r®¼ÈœôªÈ©­üèÿÿÛuóèÿÝb+eÜsUqz›®ìwi`j½^tú÷~kçãzoo½ôúånüx}ºÞ÷ôÈ»°îŸ­Û²û¹ŒÃì|keX]STXbh^hëìåûþúë÷ûåãï~~íèú²èÞ¥¶¼ù´ý¾©Ýüœ»åzXTI3A?BZܸ›êïçsacr^KȺhÞ¸±dWSV^\XXVPJRBxîûåha{ksù¬Ï¤Ì¬Êªç¾•‚¤ãñ«§~à›®wþ¿ß|våêlâ|ó~rag]kãäå~xtm|~}{ózà}uuh_hfounakYelvmpnà°ïS}ê\WåéœôúܹžàMLf|\é÷ÞïN5ÛÀë9+8÷«ݲêwŸ{°½vtâìŸêsè²ä_c~èîèäÞ±°º»ºûûûÛêí±øÙÂài{osãm_idd[v¹î_êäë½½ëÛë~즒§©î¬§®µÈµ¾»{î¼Æ¹±ìãO8C>]èÝùþsó}tâyLFZyqîyovo^XW^RPUOIPDZ}©ÝbQo{mŸäæÎÔ™‹Ö°¹ÕÕ¡žë€Ö’ÁfpÞ{ä¹äﯞ|z|}nxwp½ÿyY`}üàwéztzlwàyzz}âjghm|^afsekgowu~ryçûèKâcZ{u~ݼ±ÿ­ÈȰèv87C@UŸû\4žÔøãGAtë°Ÿ®Ü°ïpîÞâçÿ}úþíï°ë|zèÛŸÞøßŸôô­ßÞ°žüþüŸ±¹Ÿqyig~âshgi_\÷þiìè{àó䵸ÛÛÜ€Ó¸§´üŸ¿ññ»æ«¸üž¬ôú®ýñ¸®xA8RêÿœìZi½ptètTOWmYMVbhpkdcSWTWOENO[­œm=jéçåïÈÁÙŒŒÌ±¤éƶ¨´ú`O±ÞÝû|nÿís}óähfbdóíìróvpsuqroxóà~}ãàó{uftxvvgdfxnhqwy|~~½äï{Rm½l_íyeèôôÝž¶ý»âGUWqóîÿŸ´œzÛ”ø¦‘Å‹ˆªÊŒáÖ¥§²téóéï쟟ëéïŸêüjäþåÿàal{cbjrqoäâ~å}ã|yxzgm÷ëSfvjnqtî½çéé½ypm[lßÜWixSzÛÞߺýß½¹Ÿ^xnXPLžž»·©¶ºÝç`óïëëâyvçwahvri{~m[{°©û°íéô¹í|jzâwt}ypkq}w}yeanwoou~ú¶À¨íµ©®¸Û®Àæ§»üœæýýå츻ûÿý‘Ùñÿ››ß´›obVbârro~ìtOeUbXT^WUNPTZW\c]]GRBFIHCNGCGOCGPc»ÇáÛwânj±¾É®œÛ±¶œ©ä»ûMY_WQZ^UUR\TRbhkhabjuvàâè~}å}zìy®«½nfjü{g`mrtx|çìçwjZR]WŸ¿žãëë`?DDLMUÿ­zåór{²ÛGW{mtìåg÷÷âþ®}EWLR^gãjo~¹µ®›~kvssàüë~ê½óêabeZdb_XUUU`RHUemxuéy¸È¹÷±¶«æýù¬ÕÓÇæª²\k½ttÜÿíîéíîÒèyz±æ¥×ÿ¨Žÿwäãätok{½éblbd±°nZbt\NUTWPZe`NMG?DC;E>CLNVBMMGè¿Á›»¹x}žù¼Ý÷µ§º¶ÃšÛIUPV\^\VUX[[V^[Ubqi^xnvpäââ½åçãwz]p著sïhmtyymt~êíãgLSY`MnÈæ°çåwB:9PSIb»ãl]óü}\\Xcod⪟찦ÛSRXKXV]a]ë›ß®¨ªèlmodc~½v}²ªóMYjabfb]`TTQIQVX__jj`ëȶ¦¶ýæ·«¦ªæ§¨Ï„Ö´ª±±Ýeporéïíþ÷úëôƪžßû¬Ù×ÅîvSwåäàpUgsþílfZJViSEZJJTTRPZTaPGQKK@?HDJFIPOF@A?eìûÞ»~[²©¿ÈÅù©¨®rKb[TXT]T\\``U^VLbuxkstuit}ìèçssxi[w®©ôîcktãym{âèí{cNPZVPS²ªûûßí[VlMSJW|û½anéeG\_^rt^²ñ±ïºžoL_ZW[`TWq±ª±~í®±{qneTghlíÛœì]^olhkb\XRGMSTU[_YWcZ骞®È®ª´¶ñªµ«’ÑÃÂñ±›ûê÷ìëÿþû÷Ÿûz­Ú¨æÂâ½±¼™šº{ìåU^vo]kXêë霶®A8Ca[TWFLX]_`LQPKKGBCLHIMMKKG8:P\Sì®üçú¹Ÿì§Ç»›sb]a[SYSUUZc]kW[_[bjnkpxrhbk½½àã}xtvî°Ÿ­»î]m}{im}ãéêäsPRQQd\©Á›²¸È^IlTOSRFoàmzëuQOb[cmN[îèq±ãRcYUa^VtݜȺéizçíäiflolz±êéþi]hkfe_N;ANQXN\g^aQTg²ùž¹ôœñøÈžœÇŽÀ’ÃÕÜßÜøüçãïíÛ»½}еüíuì¯ÏÛqï~{îpvs~e]crüæÛ±ÞÜôN1WZQQZ_kXMNLNGIF?MMPOJNGKIFJENü­îfu꟯ÖÔûRZ`][`WY\\S`U^ibjk`W\erpiihcsvyäç}yí±ràëþàSpåo`w½ïéåíwOLQ]ndŸ¸®°Òè=?TPTMHQakß÷}óaLdvZ=5iÈ©yqld_WdbEVŸÈÞݸ°½n}änrãyåè½ëó_`fcZIOXWZVaWpedlh[Yãôß¹ßÝÝÞ¼¶Èßœ´¬ŽÇÏŒ¤ƒÐ®¿¦ý¹ìãkz›œ½í¿Âž÷›®ôí`Xh]~ÜruhpoW^[Xfgtèüñôh}V\Z;H^d]LNVJILALGOMVPDKMI;@NCDXèï~fvåñýÝøŸàZLTURVUXU^UX\]^`]VW\jh_yqiisqmz{tqß°Yuàë½^zà_eçîúäêë~^Z_\cZkî›îž±T;?SYNZXN[ûçïvK[qå½M[æý~Rgv[@@GBDZÜt_b^^béû°žçc\SX]VZ[PW_WUXR[Zegfpaqeefnllsxy}yópàè½ó÷àmóìudYkthprgcYZWRPjU<àègÜÿ^BSMXTXV_SS`[ZZC@_ûíqs¦údmââí±ïâþœš§È¹ûôïëü½Ü°é~àëüçêxqäjMZeZ]^]eWbbmzvnukgyêžž²ÛÝßÈÀý›»©²ÿüì|yÕ¶JEK鯻écQÞ¥µ¦·Íƒø°ÈÇ·½U[dabRãæÂÁ²d]c^Xdohkú¯jaYe[eí^2HCGJST\ZOLYZRC:A>=FY½ZYX[^k[WkísGOMYi]TRTVdNKPVWbmhlvmkcamqtt{ãóxÛümx½ü~âxå|TGZcjrók`xe[VTQFéü[jreþ{wnYERTZUTTU]X]Qbvl§›kiû›véîî»ãä||þ§œó^hå|ûÞÿüíw½è±ëåóaX[YZ^Z`_^X_\c÷åêôŸéëܶºÞÞ±¹¼À¥À²­ßߺºéäþÿªüaZP°ÀßI@tµ´Ô϶¿†ØÕß½Üyhóg_g_YbnîîZRf`e{wbf]levxfnCSgGKACPJWNaULV\UEBF@=GOwwfçÿlistobofTY]lfQR]VVM[XKQhrm_dgh^mvbozâ}ä½ú¹âw½uwäâhUVOP[kg÷¹sncRUTKYÞøçXKV]RëîTGK^YKMV`VYin›¼þüüks~tkôýœ»àä`sëÀéyu]hàvì¼æ½²ôüìèîã}w\Ycd^nV[\iZ^mvŸë}Û÷zu麦›Þ­»¼œ»ÁÏ®²žÞÜÞÛì÷æ÷êvcyaLbX;E]±¼À¨ÜÝô’Ç»óç}mjxqghsk`Z^ehmmèÞ~bij^YdvmàtRcbAKHBEPV`YOISQB?IA;OPfèSŸ»íngdb^e`Xhfa_RMHGZVV[]b`c\]krrs|{dswu|éï÷|y~ììdVZRO^hokì¼sdZUSXP]h½â__`vezûMXRY\]`_YZ]gÿ›ÿ\dm`ü°sç¾¼ûáÛyïâûaß­jhz{ÿµ¦zëÿœÿpçà½bOUT[g`]hcphoyqq|~~}s}ÿÈôßÛ¦­þûÈøœÝÛž»²Þ­ôú»{Zçë[YYVN_xí¿¬§ïãókf}ê}W^gfrnnszzz|âéxlà|cf|óq[íì~ï±oaaHG=CAOXXPTMVRAGKBCRO[âfQcsaiovtjVZaex\WWWRjfoz{zqkxwsxxâà}w~}óçèìâpwh~ÛqZ_\PZfmi]qïl_\WYQW_HES^]]ëìC±cT_[TW[cg]]täéXS]ëÿàk÷ù’°~Ü­ÿjï}ewsa^ow{ìݺççàíû½úÿychgb`\W]`^b_êwemyä~½Üçx­øžºÜûô¦œìú®µ¼›œ›¦üüÞçocdåâd^_^Njéÿ«§ûàzåxãwqvsrxqv~þ°ÿèàv}}{|l|Û~\|ràÿžé_bWBECBGPSKMSLMJCAFDKJ_rûó[fnc{îàwstrxâïçàRàã\Zãþë{vå½ãzyããî½àã½êém}sqãïjji]^^lqf^s~hg`SY]htaLPWRZyìGçíUZ`_]ck^Y_iàäT_ܶûYGÛÉÏü{¼²çû÷é}uikâàäèxvîêÿî±þêäudt{id\_`^bc|œçû°íåè°°}­ôœ»­Ýû¶¶­û÷©¿ùÜÛ»æëÛºíiqwuhek_dcnéïyüœî½xô°utvrfm}k{wóÝß›ëkgw÷­}vnaxs]snvtvoy{cGIEDDJMRMSOPRMOGCKJ\Zë¹ecurwçîëuåéóukwlç’ËìbWs÷¦þky|zãtçëì~ääååbix{åxvto`a`fo^grànobR_tnYSWWKQ]lvOUêgQ_aUgèws½tqçcwøœx<äÑÏí]½êitàâu½}lyûß¹Üîpeäéûêëíãàxqìíeadhccagó±tv­œyå~oãvóqû¦¹›Û»»ºÝüú®ù›Ý¹¦½ô¶Û²ég`ctm[`Zaqüxçåsëç|zonrvpu{oìä}÷ÿœ²rnnqrk[tg\gnsokhq|êìsSINPADNWXPRRNORECHV[Obôèlhvyuü°ã¬²»èmNëùéjú¹ófçÿkztussàâ|}ãà~zmuz}soh^[\bfc_h{zäcerfXKBRTRSRgW½^JegPLlhkíéí½þvÿçå½ìÝÆ¸xNOn`c|Ýüœïhcþºûxóà|tàìêûììåäày}þÿâûçeaiejdXgâoXlmjuksfü¦ž›°Þ¹±±üà繪È´»§­éìw_[hcNU\g_xsgküÝkoàtmrtyrlüûïÿéíåfnfrhokrrotumijhqyàäëaLJOG=G[VOMPLIRHHLQ_T\›î]_oâwã¾×‚€®Þ©½Dræ»oyîlRqjmwwnndzàusrãxââãw|½q`^YUU\ol`djüp{atbD[pTN^XYiUàÝ[F``u›žê½êåyàpp\zç°¥ƒ´ôrE\nsmú¶µâksîþshgx{û÷îí²úççãytt|ã}èüilnklbaonxçt{ã{óåíß›¹Û¹›²üÛüçs~°åž¸¸¼øÞwy÷ãdhgrvmû~uunjjë÷óè½souytdfzííäwhbhgkmqrsdkoidkhlmtosçã|UNTQCISROLORSMMHJMR]a|ÿêézüùΉѡ˰¦°HAùvcì°wskXãxXcãtjqvvâ~tãììóxàl^UUVWZlpgnyÛzhkqmROktUSYW^ièê¼ûTaawœ®ìmnrþÿ­Mhÿ¶»¦´¯ÐÁ÷xnnžìzXmŸ½bkxmrà²ûí²÷ÿêê}{yqmilitiqmiunuvzüÿâóéêäú›îè|²Þܱíéå|lqdrµ´ºÈ¸®éÿŸêçéêàtóàíztiîÛÿ½àuhnnidlbqwf_grlhSegnbb]ldggfhuxoãçdUKIHPMSNOXSSPROESGbb^²Ûè̅ÉߊҪ|Prަó~Üøéþzwéàekzpjk~à~|yóïäçzsj[YW\ebhpu{åÿxlq]TH]aNQRUc½»«Üÿ^W_`gxoYRwþã]`yûî¶üøÉùùú¯ôßç]K`àlYenuvííëÿü°úûââà{u{àspqmkpkouuóîçxz{xyãèž°yéqãí÷±vyå~kp]Rå¿¶§ÌÙ¬ïìÛþíåïåtäíâíëÝ›û~sàwspokoibexh`lnife_]ea_]bxkgkjbhlfjrywWJISQHSWRSOPPQLITLWbZå¹±²©«Ž¬ùþ´ÖÂûü­‚Ÿyîúó}¶èïêxiróxifwyqwqàv{åóq^XW]chhpvzóäåoskZMbxTEQZv©·Ï¿üVbqkVHMS|ôâYdèâéwœôwê¶’¹ó­ßìé½çtVg`S_cjwàízëîç±°ûâ½ózóótjmqpvqfswã÷üó}åëóx}«þã÷þãÿí÷}zîvgp][K›»©”—¤ñíÿóxÝ»þ°œï÷ܹž›Üïsvóxkjcs`hnf\cmihemqc^co`xxafoncddgkgm`UQOKOPXTHQRQGIJQVVdU`±ª°ä¹¿€Žœ¸©¦‚ÌÔ…µóÜxqîäàtfW|ïkdoywhqu|owàïucaaegcpsv~ãàåxna_QdwkQPbhvÝ­­úîcbpvcVfyúßäâݹôÛŸî_hûëclëŸhoûïãìègbebfpë½óêþåþîëê~xxpiogkyåsrrààçÿþëêÿú°ë²¾²çìÜüŸ½~{nån[pdYPQå¨É•öÕúë뜲ãßýœÜéôæ¸ùºàp}hlwVg\muohibjwwkhgXgxq{g]hm_crbYcqk~yTaUMYTUVSPMOGSIORYYTYj÷°ü®×Á­ù¶¾Èü®§Ûë»øêineapdwày{}àógatvä}{úleffdfcps}íåx|zdYZPJLLNOarqr›½îûþsWjìp|»¦ßçwüñÁ¦WvwyûÝŸçãÝêâéâÜîú²aandnéÛèëïþå½è½ïâuuvrhtrnà÷zzê÷þúì±ûîì°·ªüÿè÷±úósâx}r^gaU]CaÊžßχ¬­ôçéþú±âyî¹ñ¯ºìvuhyÿp]Y^fwpilrzxoll\\ausb[ciaiwsjefoàÿ^lcUZZYVYLDNOSOPPVXX_Tpûôº’Íþëèû­åžúûût|²àomwrkks}~~{uó~pväïí{hoj_X\c~çìþó}xod`STQTOTb]elRjoìüÛþt~zblûékàíܦlJþéû»©È€øÕÒ†™’ôžý­½o~ÿßßÿ°åìîÿäèêüüé|âógeqr½êß÷ìãþ±çÝÛìû±ýæºÞ¹îìܱëþôzxvbgbWYJàžóô€È°©øzëûçãîxl_ç°éçrssevãqcW]mtlkhqgehpfa\aoiX_a_cbà¼~_k{~f[bSR\YYXRLLIHOHIT]_Z[Vtúúª§ßél}è²ëÿüââê|cå°½k}|npmdWZkilþ±ä|çüq`tqe^V`yêîä}èxj`b_YZXWmybfdHa|îî±ûïëb\]ayc䮫¶ìÜèV`½½ïÿçû¦¯áÏŽ¾ñœ±úé½¹ñÛå²çäßÞíåüééÜŸ½xnltå­ê¦¹äãêî­©©Û©ô¼¯¾Áô÷Ÿœ»ºîÿìbaX\`[IÞø²î°ÝžëìçüŸîìäxèœÜq}äã{vìäxpsjgrsknsruiqgjn``egjba^]|íuro~rp_c_YVZeQVPFPLSSUVQ``ZR_vè²ý¶ôè¹èçì¹÷uxíåiê²|mlln`TR]ZTZr{upxëìüvcjjiXXk{éêèéàvgZ\eåüãóåtVjoMS}±»ÜíìsQTZg}Üœ÷wQq_g©¯üíüânþ€æùÝ}{½ÿÛ°÷íÞÛxå°²ú­›ú±¹œèw|ãôñý©ÝÿÞâÝÈžæø¾ù ̊¦ñ©®ñ¸Á¬ÆÇ´rg]jb\R}¨Ÿ¶¯þÿÞvàîüàyàßžqXoãäuutt`gwvu½äh]cgpqaedqXadkiV_VbwkèäpiqâlW\[SW[^XLHLGHDRTTU^c_bZZŸ÷àŸº¸xjíüxë½bfS\wdZUU[[YUckdbbkpãíüêkZidTbr}èíév|pk`S[cltiPHOb_ZP\éwzÜŸoLQtdXŸ­üâÞÈçCbiWkí¦þíÞ|l}qäí½ëçàí÷²ûñÓÈúûãܶÜÜûºŸsüvx~±¼´­ÛÀµ§æ¼®ÇÓšÂÍךŽ®ý¨¶Æ|agbnÞÞhüžŸÜ®§úïÜݽäé½âã}hhiit|ÿîóâypzàupsmq⦴TKTNS_[mmij[nqqèÞ÷íâãäl^\VZ[`]RJKONKTOTTV`ihcXiüçïû¦¸ü{êû~{íú{pãn`]ibdiVachh\ijm{kûÿŸbYnmptr|}ãëuugg[ZaZQXZ[XFYmSWb`]ìíüêP\úœ{Pêk½¹qm^÷éxà­©{jwÛë÷÷ÛþûûŸräž¹æ©ïsÝ´Ÿèܸ·ž¬ßtêºýñÀ¦¶ñµ¸¯´¼ý€Ì«ÂÁ¼µøºµÐÂÜ’Ïãki^àøúYkÝ­º»Üëäây{óuzàwvsthueé÷½­ïsxi_`alnbêå`Zxr^T_mngkrvstwyvå~âœè`fYXd^VTOTPSOLTVQUWTfjf]Uk½º¦Û÷ä}ibt~eûnmoe^hgfgaW`pmXbd\âãœzZqxppkkwàëó{{l\\XSTSTQUX_]`RiZUmmñÜR|Âì>hbsp9âߟìªïïé{÷¸¶ÿœ­Ÿëã|릻ýÃÆÀŽæéúœßÞ´§¼È®ªþ¶¯¹­¨ù´ùµ·¬¶ø¬Ñ¢¥Â¨ýŸ¹®ßÞ¦À´¸ý`Ÿmlcwà[㛲¹Þ÷±»Ûoåx}vãuóèxå|fwvèî÷²àfjjgcP_u\Ekoqã}m]Unpdops||yçü¦ÿ÷¹g_caa`ZZVNROVVXKVSOQbupb_\l­È²ëâ}êä~àufNXm_[\][demaivmrebclxäÁëeqztlhr}èäyã|jaTZSUNNV^[TX^YamerV¹²fåÛ²ãNP^]Zú÷ìiiåàXcv~±Ûã²¼¬¨Þ~겞¶€ŽÍ·’޾žÜ¼¯Ð€µ®º§¯¸Üî¦Âùñ¸¸´¼ø·Ó‹ÍŒùœÜÛ¿ùæÊ’¿¬V€ªo^hieîïßœó㺺ìózpäzpsãtouz|yvpêüûv[]qw_[oܲOVmlxweqretjujóäó~Ý›êî|[bkc^ccVXXNSQKN[SQXclnf]dYZà©üŸþäì¹äÿmegeacRRQ_hi`_fjlvcó{p¦ßulhbksyxyâ{êzaZ]^PVWOfb`b_aZg_ot[nºôú­ÿyMâcjݶªèHcâóeEgiã¹ëø’€ñµ®Ý¬¿ÅÁ¥Á’ÏÁ§çžÓÔ´µ¨žžø©©ôÞ¼¿«µ¸æªÏ„ŒË¼Ü欭æ·ÝÅśͯùñaqklà›ßÝœ¹Üïÿéàzä½äyxyvv|åàóhncvqdvzä±ì~äÝñZVZqsjofcfnrrytuw|~û¹¹÷ÝwfiifecbZXRVSRQKNPN[efj_\chhúºŸÞþäîúêèykŸœ`_Z_Z[alnrifwsxo{Ÿuijlyzzyrurywf[bZWbSZddg_agae^xokasÝ÷|jeXda»®ë|°ä]oywêâqarÿœ¾¬«´°®¾ÅÆÒÉÓÉÍÍÀÑÆÏ¾©¼ŽÇŽÁæ¶ž®·¶÷¦§¦ý¿¾¿ý¼“ˆ†¡¥Áýùß»¿¾§Ç¬ÈÇ»ùûcxiro޼ܒ·~å}vŸîê|ãân}î±éèéZmv¬éuQt¼¶ã¦vkluà59WyjŽáH9â»þyo½©ya``EG4m¬µµøœo]íú¹­ÛüþëgVFie[e}à]Vt90ãlOitl\l}Z+=\Ǹ¾è¾§µªÝݱso½ONjOdNrtFµ¦ûà°bUie_fh\pâ}êzWUf_TcUMQizbT~ãlhv}zyvówSatàë°²›º»íXXt}r`FIYbzÿ­´®²ëªƒ…™××™ÐÏÑÔÉÐÇ€ÍÆŽ’ÂŽÂÅǧùÇÃÂÁÁ¨¨ÀŽ€ÇÏÑÉÒÓÒ§Áßžæ»®ýßžÁ€«Ý¬¶bý¼Lt¨’ŨRWcT÷z[ >¶Émé€÷S9åýFE)GVeOteKjÞvi±´ãaL:Á»êñ챱ﱟÛܺ¶ºZ6N›jPtwdjYTkmeìycp{vkor\R:p¥Ï¬¸¾«¾¬ùú««SL{«a-Vi5ª´›yrëßxeUT^`egf|ì|_]le[^ZVA[cT_åå}rtã|{àh`Zsìê½íäó÷¸ÜLPZuq\ACT^c\~ÜßÝë~ë… Õ™ÊÓ¥¥¥¥ÑÑϬ€’’ÃÅÍÀ’’€ÂÀÂŽŽ’’ÆÇÅÏÒ¥ÒÒɬøÁ¾º›Ü¦·¼¿]i©Üy껾©ªµ¯gåµÁ€¿ÈýwThk8[Z&Lníôçîâ\1 +Rez²yU3knnݺ¯¿u][ªùæMø¨Üç²ÞÜßÛÛ»÷[7k§N%qþ]fm_g~nâpltórrtq]7$&çÉͬÂÁ¨¾Èý¼V8fn>Cäµ< ,¶¦rçuoºª½]NQdp|ewâlixhXcfhS8RYN]â|}~}}glzóé½x{tXóÜyJ[FRGPI=BMXEAg÷°m_yáÌØÕÊÒÔ™ÑÒ¥ÑÑ€’€€ÃÍ’€Ç€¿€ÃÃÃÅæÂÉÏ€ÀÃÅŬ¼€æ¼÷ì4CM@hpp»«ý¶¨GFs´´’ÅŽ€ùßêyShh±Ë¼JV]è;#r¬®å}`[{©zr«µ²¬±VBÞªéutì¹›žóCDi:ãt'UÜoV|ÿ»ão{lnóåîî{k:#$pÉÍÂÃ€ŽŽÂÀÁ§w(ArU1õDmåêå휱åkbWcynkrlilejmhf\@H[^_xàâèåà|vâä||½èovkCuŸv-:-6>P_VJGNO>?tÛz`cÿ áËËØÊÔÑÓÒÒÑÍÆÇÆÃ€ÅÃ€Å€ÃÆÆÆÆÅÇÇ€Ž¿È»¶Èª»ªý¿Á¿ô›årc2X_êRC`ç¼ÈÞªf,c·Â¹ŸÑ3j®jñÞ0 Q%^ØæPChäNZyåì¹ÛävãzPX窷žÂÂøGa­Üvn﮼V<%E°NBc"y´üv{ìîsxàfV]­´À²«Â¾ßý¾ø›½q©ÈNY#}¼Å€ÆŽ¾Æ¨ÿ»ùeÝ´íý¶›È»½ôtfht°êpí}dfgtàtPPLYHRaGGfkóãèèêÿîéåoU:rôßë~oUKMLZìûÿ½{rl~ëôôã{äèèç{Ã…á×ÓÊ×Õ™Ôʙҥ¥ÐÏÏÅÆÉ¥Ï§µÈȶªžÞœ¼®æ§§·µª©¦¼¶©žw©Çó;r¼Þ{©¿ÁÏæŸÁÉTõRëñ›[ii{™¼CݵD]_Cçï;"4i_hEyÞ»stzK8[qýÒÏfÆôúü¾¿ßŸµ«®caìC·zhKa¯ïLK@\ꫨÒ´©ùüUõBcfgõ + ;â¥Ã¬¿ÅÁÃ¯Ž®dZïtéãé¹›oÞ­e`iã~ãtäçsg]{éhD_LWOHVLixvìåååoxè½èvZI)<çÛôãOTxuperg{pcKlÞþåž°yyuåêìxÜ …ËÕרÕÖÊÊÊ™ÒÑÑÐÉÏÏÉÒ¥ÍÀñùýÈù´æý¯ù¸·ùÁµññø¼›·¬¬ÉÇDݲN/k·’ÐÅñÐÇj)Mät~µ´ÍÇÀ«bl²Ê=Zzëù´åMHPzrågPlIFªÃÒ¼A§cXܶ¾¬Ü²¦ªø½/^!\¨­±[¹’œŸ­µ¨ÀbhÇÅ«ñ®aK`H_g]ÑÍó›¾Û¦ÁÀ¨§®ùÝâûøø©þrôÛ½UMjèï}xurjtz\MTMHJ][[Rl~çíåw\Vó~zjD424$qóîí1MÜ}xjQg{Zddåí?oúÞåä½þîꛃ áØËØØÕ×ÖÕ™Ô™ÑÆ¥ÉÆÉÉÇÐÐÅÁ©»¼æ´´¶ùµ¾´«´æùýÃÁ’ÇÂÈîªÛÁ´È©ÂÅ©¸~Vóàgâ÷þÅÊgýÔ¸ég_[F@èŹwãíTK>DRSWwøÛ®Òœ¼Ñ]F:^üœ±ºñ°ÜùžÝyeâÀ«¯œ½pô»®€’¾w=BngnYBè|ãg꥾ÝÞ¾ÿXëÀ«¾¨ù¯·þÝ®àvÝœüs]PäâyåzbpìwJ`KJ7;däëyp}xy{gV}èïåY6EVN4uêxr&5ëmqS,FSZÿëçû~Tfå·¼±ì²Ÿï²…ƒ…áËËØ×Ø××™™ÓÒÒÒÐÇÃÐÒÐÍÏÍÆ¾©®¬Àµñææñ®µ¼’ÍÇǧ¯«ýÂÍùÍż›ŽnSWº¿ÁÃä$MvÜíÔÐÂÁù0\ÂÏÁSF7,ThlZ@Mè÷Ý’ÆÆyøÆm*un°ç¹®÷ëºT6¨«ÁŽëDãoSúãZ- <7?nÿT Aã»O  PåýÈgÀž¬ø{²çŸ­üží°ópa~~éà_Z_}àsjàíx\VVPILp÷g]fUMbhO_êåãèsìþi+LoeY7&Kg_/ 1?%VvFNqxikݾœÝô­©êÆ  ÌÌÌÖÐØÕ×Ê™ÔÓ¥ÉÉ¥ÏÃÇÏÃÅ’øæ««ù·ù·ù¸ñø¶¯ø€¹fOOè»`üÆÁ’Ñl:¨ø±Æ¥Íl ?¶»è^G»Ñɵ¿¥A°Ñ¯·ïYh>WT"Odxsû§î¼ô§XJVÿÃÁÞžº›¯¬ûrÂý=u€’ÀÃqµÈRIB à¹?ìß,}/t§ÇX;TEgë)e`{¾ýݱ°º}ßùlM%UH7AU÷vcjrqââvca{zpi_ZQP]gkZIRw]5JXxëäàåóàîçp@/(5lèk@(+YwP&1õ-,gžªÜ÷²®ØÍÕÌÏ×á×ÖšËÖØ××ÓÔÕÕՙɻ|øÊÑÏÐÇÀ«µ²ãavùaMês°®€Å¨€¯ý¨ºŽÐÉv¦üÇÅÇä>I(0ä͵ǙôÞÀɥƀé|ßR2ÿ¥ãIIYl_C'7aÍÖÁ\Ã}Ht^À€®_LÞ´øª`/[ê4€ŽäuhIUj[fº:)åt:ìrStžýíf`TY| Ac;sƾ¦ª®Þ¶§ñ®ßÿ·øè©æ´œûrf`dYp~q\zcWLAWZPjV^>HJ:eçåézd|½qw½ïŸ°V"1dçP05ju_-2"&Z½ípWUyèÇá«Ó…ËÔØ×ÕÖª¾×ØÒtôÕÔÆ¨œoÉÊÓÐЀ«Í’ýþïzUv÷îȺº­¾¬ŽÏÑùY©ÍìHvÃÞÏ™¸­§Ç®]P#[æéRGçÐæ·ùÃÉÀ€riíy+;]cOJ`bQI'H¼ÈŽ×·Lêtilhjž§±æÀ¿¿S-_i­ãüñ[YdCeaãŸÁÑquׯë}néîhh©§œµ€ŽVr½e8’xcÂÏûLAo`W¶çNú¼ÇÅ’¿ÇÒN!%/2w€ÂÁºº­ª›Û»«¾¦›§È¹ócnidd[fzkYWYfcIBXP<=@Efà{zewèég;6K>z±ê²ÝäD>}^2)^kkcB8)0ð + + nótnl?^íî­¬€¯¯š®ŸÓá ;] Dvèwg|üÓÖ×ÕÕÑýÐÖÑÂùý®«À¿ÇÑÆ’ÉÑÇ͸͵Ɵ^ìä½m[ýµÅÅñâpŸ¥Å¯Ž¶tÔЧ¦SKCEìÜHSr}ßÃÜxjs²bT^\àóPPlap´ºoRÜÜ_ 0WãpGT}~8@Z$*½€ô²tí²ñífãu* + a¾Ãñæ’Àµñü¦ß¼½²îyyhor]]o^PJTcOI[XD?;âàëykccgWD9& (këzqOGjèÅÓý®s[kTAêÐÒ§Æ»}q7ð;WgwâdVx®§Â™™ÔÔÒÇÐŬèÁ­ÑÉÇ¥¥ÈæVzÔϬÁ«å¼€½09Mçæµ¨ã-€ÆÆæ~k|ìûÀj+HJÿ¨u/9T½îïq[h^u{'_Ûtf²Ÿrñ¯f`uw ''d^]x\qëteÈ´X@EACJWVH7>LTA-1=àxTrâääëzwëïíèë±îóy|ÿ­ÝúÿàéÜîà÷Üþëäo?4+V®­êŸûêùÔÙÙÌ™ÒÇÔËÇ¿ÒÇÑ€ÀŽšÔý«¼±ýûïî}ù÷æ¿ÑÓ¥ÑÔÕ›@ßÒ¥ÔÒÇÑÖÍ÷í©µdVv[Vý¸¨À¾âž­ºÉжl`RhOá wigOg2%N _ê÷ëè꯫óÈþÀ€·¯ÇÈÐÒ·_óØÝú®ÿdÛ¾’÷OVôþpTžÛUEtJ/EA"-G-iR'kÒÁãÖ¼MÝ´déëóã_`a\c~Ÿþ±êghTM_`SIS>+KuF1>Eë~Zx~eaultè{vhtíü½Ÿ°ìéꜦ۟½ïóâ²÷ê÷åe_Q,^Þ|mäúÝКá„ÙËÔÑÃÓ™™™ÒÍÏÁ¶ÐÌ¥¨¶¼´·¿ŸÆÇÑÑÑ™ÔÒÔ׺9ÓÕǾÆÏ¥ÉŸñÔ`\Z/Bçî´ÒÊÉǧjqÀ®NLuArvÓnÝ×O)n5$.-#8DTbô°ôÈù¼ªÐÖÇÑÆøŽùŽ«ü´ÑÉÏ®©Ãê{°í·ÅÐi W{yÒWÒÈTŸÞzlð,9*L% 7z<t©þ¥¥æûzrë°í½lcdfaTWtú°âWUjvl]G7:Tïpsr~©è{íxSf|våîzxr²ôèäÿ­¸´ä¶žÞŸàc|ä½±ìo17qsisìäiyçßš ËÙÙƒË×ÔÐÏÔšÔÉ¥ÓÆ¦ÓËÒÇÁ­ß¸€§Ž¾¿ÒÔÕšÊZ8Õ¨è~syù¸´§ÿÑžeN?orÒÝû¶Íèí¹ÅšÀN!ìè'2ir3œçù|1Rñ½¦À¸œ¸_L`vϨqdTÂÿ§ü»Ò¶(ø€¶œ½°[UCTkÔǵ€ÂàÍÍÏG ! õ,# 9>*hWmìGDã5ð!jüÀ:FÜ­ÃïDjÐÁ²ŽûÞæ­îÑÒÍÈ»v+EëÒøÑLRæ»/ õç­SjBìþa\x^VoýÊÇZpaUf[Z[qú±ÿ{aäï;9P©øú{`QGLF7OOFcãüééãîìORqe\~îëëúéßÜïíî¹›ucrìßå›ôzþuraAw±l9wÝxçî}VXbцš×ÕÊ áƒËØÐÓÕÔÌš™Ï¯ÂÕÊš™¼ýÜ÷}måµÑßÛЫy`x¨Á}ýéw?lïã·Õ¥ÁÉÅàdÒÇ¥Àµ¾ñ¿ù_fÂ¥Ãv&fWîŸ÷oxÏ¥}c[pëÝàîôC:;ë¼íxsnZSdlgfp½kãïYeyj`]H>B|½ääÈîÞ°½÷±±®êennwþÞälÔ¸ÅÛü½þóIQ|åóçààât̆Ìá…ƒ…áƒÌÌËÂæ’ÔÔÓ™ÑÓרÊʾ«ÀÅìäzžÉ¸¿¯çŸô»ÏÌŽ×X´´ry¾«©’¨tÂiÏ¥`ÑæǼ=SÔ¨šßÁÏc0`ø€h^X@Suךëõ<Žâ&ç|AfU =j^°ÏÍŽÁÆÂaHÓÔÍÏÒÕÅÀ¨›µÐÒÉfQ’Ò¬ÆÍÏœny,  +I°æ~aOwE +\º¿äЭh°æ¬°tpvgûaïFB,6caYfh\YtH"LZfOuw1,6>0$1&4\P3<Ÿ¯©|{ÿíªÀrK²ttt[ÿÖÌÌŰ¼¼µ®xVjÿuånÉ„ÐჅ ÌËššË˵ÇÃÀ€ÓËË™¿ù¥Ð~h|piìÃk{¹ÿ™ÔÕÀÀǯîì·ÊÊʬ±Ñ€»ó¶Ï¬¶¯Â¯êL`ެýlNÓÁçcåéâ\[­îOC/00'WÌå°©S ððo«çé!½P9ŽzþÏÍœã¼VC¥Ò¨ÉÒÒ¥§uãQ:pfyzAÔÐ¥ÑÉs-ð +Dè·¼ûÜú^p''|¬¶äXLÛÛUUcíf^g]°­&.F;7?(:hq4)60&%.- (íéruëÿ÷´ä'ovp²ÞØÙ ÌÒÅžãÿåß×ßlåyàä±où̯™ … áášØÊØ™¥ÉÓ™ÒÐ¥ÓÖËÌÉøÿ Q^EoñdPݶršÖ˧¾¥íbàÃø×šÂ´ø×Á’É¥Á±tgnt¦Æt?WßåZôç{ÂÔœuíf0D+%Mêº8Y-R÷UW½åQÞ\I{ÅÔgsÓÒÇûÇ»ÍÉÓÓÑ«d¸ÐÉ…ÊèsQëʬ¨Ñê2$'_äV}ÿž¸ôžV?WHA$ túãïÞêYhÈóìÞiQe?Zûî8849=56C?:Gcg+-/:]a]9㹺ŸY69FIK.$,B4JãÝúìÛf[㻇ך…Š„€¼åœ½ãËš»²ääô¹ÿš‘Öš áˆ‘…ááØ¥ÖÏÒÕÇÊÊÕËËñê;\VKÖ¯¹åbçÅÔái}{nvë`ãåý͵ºüåÏØ™½ÒœxúñÜçßøþ¶æ±ÁÓÏÒÊÔÒ¶øì\5r#÷Þ8B3EްT_|lljMw¿xj»©øÆÕÓÏÒËÈD­¨¼ŽÖ¯èiÉÀ¨Ô¼3Z›Üåž{x¶æV $#6+izviSzçwãîcaürXeWätI%+1&09?9+1K^S`auyLD*5WuÈôèéoesîf=1=:?yžßÝÞ_‚ˆ‚„Ç׆ŠÔ’ùª®í±Ó׎´ù´¿¶†Šƒƒ†šÕƒ„… „Ùš××ÕřӥәÕÌËåz+ìûKo·æ§ßtEq§¾€ÏÔÛîe&(QZsdot|gÍ¥§¼säÛÞàv¶¶êxó°e>ÏÊÈÖÖÔÑ™¿ÔÖÉ¥º¯ÆîxwäñÅÆýÂÑ’·ûk_[o[&[€¥ÑÀÇÇÓÑз_üØÉª®×ùñt+yÆ™šT=rledyîþ%5GuèŸþótdnlPëôm[ZpìwGR>mpu_DID0-*2FUeqääàfTM@7.k²žÛ½óQkèzZQQ9h­ª¬žìù‘Š…Ùáá‘ØÒÖ»éíì÷ªùÏÔÕÔÊኑ„‘Ë×Ì……ÌØÙËÊ€ÁÓ¯¸Â¿Çǰ±âwßÑÿy¿Òŵwa`Þ·¿«×}½úGB T=_üDZqbtª°›’ý¯æéàóg?eÓ›¶Ê¯§™Òøµ×ŨÑÁµÑÒõ¸×ÕÍ¥ÒÑй±ªžéo]ÝÑÅÐÉŽ¯¿¥©Wâl½¥væ¥pFnɲîµýnZC õe+jÞê9=K=yçÁ…  €~úªàpyåk`M{oko}xse[bRH>7@JhXIyëólrL089KGTlçÞ°^4{çwtpWuܰ¾Ì×Á×ÅÊ˃……žƒ†ÃØášÁÏÉÓÒËË ×̇‡†‘ƒÌ…  ØÊ†ƒÇ¦ÀØ¥ÃÆÉÓÿ¹Žôü¨®uvûŽ’¸·÷jJeçÝÛºdYvToULþ÷ç^Olþ}ârRÐôÕÞå~ê*o¸µœÃеw晀̀šºã×íÀпʿµ¨¯ñ¼ÉÊž§¯¨¸Â¥·r÷©¥ÑÀ¬«¨yïý¿uaeu\^nÓdݾngûH õ"9õ²h  +Ÿ¸ãØ’´¶žîqãê_nzþŸëvruttdJ?DVMVT[^FmãuaWQN9.IO-Aþu=AO;PgUh½´œ»ÒÏÆÓØá ‡†ƒÙÙ‡„ØŠ‚ŠÙŠ„ÉÂÑšÙ  ‚ŠŠ‡ƒËš…ƒËÖ„‡áÑÀÉÕ× ÌËš¬wºçu²°RNèŸÛßÈçUXcZVw›h#"yíb™áÙ€èéžÔíaÉŪÁxzæXâ¯ê¹™Ê÷ñáÒá÷S¿×ÕšÑÕšªäÀÑÑÐÿ¬ñœ¦æ¯ÈçÿåýÍÑѾ«ÂÝû¥øÑjKôÊÖôO@¯ØÓƒƒûw*)6NZL + +  [Dàßœûéh\ÿÜkpêíìëyokmjM@HCO[`E5CWMrscK[]- (1! (G:+" ;1BZîÃÀÊÓÇË‚‚‘‡ˆ‚‚‡‡ØÂ„Ù†‘‡„ÖŽùáƒÙƒ„‡‡ƒƒËš…á×…† ƒØÖ¯¿ÓؙȷÒóV{êì¼ëiž¬ŽÃ¼zsÿvtŽŸ­~jíÒQ{~P²s±ÁÔÒsq¿Â¬éÁã°«Ãü>v»zþ¨Ê×Ó’Ï¿»™›ø µDãÒá …¥øËšžøÍØÓÅ«§¸ñæµ¸Ž¿Ð¬ÛCäžâªÇÆ^-ÍÕ€ÉÐ¥Ó½ ½®{ÿ›¾Üžø=&GO  Aú­ëüÛvafûØŸjÞóàâ~ykqpK>EISM^kQ72YctwL(!.-*%%&1&/0*60:;Cû×ÌÕƒ‡‚‡‘‚ˆ‚‡‘áÖ‡ÙÙ„ƒƒ…šæ|íˇ̅†‡‘‡…¥Ìƒ×ÖËË …ÊǬ¨€ÍØÅÖÌr.u®¬ÒÿÕÊšÉ×Â`TûËת¦ÊÊÆƒxeÑÔvZU®«k1uÆÂ½^±­¸§¿æ™¸YfÆ××ÕÑŨ¾§øŸÆÇ¨¨¶¸Õºx¼ÕÒÕ¯ÏÑÒÔ¥ÃÉÊ€ÅÓ™’ãék1eا^?Oìɾ«×¦Q7å{7BcQpx6  8aE +õféG,Uzîuä»ñâs¥nm}~kodTbPAU[Xkw]_otvoG6/  )!&(.A1(.,%-052[¸Ó…‚Ї‚‚ˆˆ‰ˆ‡‘‘ׇ‡ÙƒÙÙƒÌÕÿ^ó„™Ñ‡†‘† Å™†áØšÖË„„¨Âš™Ê™™ ËÿE÷Í›ñ€ššÊÖùªÅ­Uder¬´oTwÑîÊÖýÓÏßÿºàuüû|môçÀ¾·ÀØï[·ÔÇ’×µ·ç­½±ÇÍÒÏín¹«¨Çظ_r´Õ€ùÊ×ÖÕÏÅ¥¬œºÒšÑ;uÛœýdVâm_€ßßÓóºr+zCNüK>G@7,. R,+`Ûº°u_{owsàn}l]fgvrgRNOBPóêekêxoäo=$.&+2CFD1?<"+UZWQd°¹¸  „‡Š‡‡‘ŠŠÙ‡°Éˆ‘††ƒ† Ø™îlíÉËÙ‚‚ŠáË …á˾ˑê«¿ÊÇÆÑØ¾¬ÒôþÕË֫૚’ÒšØoMÜšáØÏêxÉÕÿê’Çß~g꬛Uå¶î¬Á¬ÃÌñWçØ¿Þ¦ÂøŸ§×’¶ªÒÕîk±žý€ÇÑÉ›Ýñ¾ñ»Å™ÇÓ€·¾ç\qžÖy}\àf IqsÀ¸ÔbÊìnÒqgr\s½šµ_%;2/$*BA0 ElyBPaìÛøm Uà1ntva5MA<;LfYV_VDKpK=>dþjãûi>2ObftãyS6(%'7YFXW[ï½ã­¥¥‡‰‰ˆˆˆ‰‡ÌÁ’ˆ†Ù„ƒ…Ô˃só®ÞÇ‚ˆ‚ ¥«šáÕÀÇ×gÛæ’…ÓÀ·µ’«våÌÕÔÈ­ñϬí¨Ì×qxך״boär·kuýµØÔsAã§0TØÉÇÆ¯æÖM<»Õ«¾ÍËÀªæœÞÜýù¬Ô™§»¸ùÒ×ÖÊ¿¥¥ìz¦ÀÖËÃz~xznILqoFg)Aw`Ü’ÁÂvê.CµÖÊÖúë¥ÁÃù6ëq,)u8TC  %ftu4 =yàÜßd9WQdde05XUc}~p]f\DYg_63B0UWi}âystdP<2H=)1J53*#4@`îâ~©æË;ÒËËÌš¸²×ŠƒËÌê°¸¶ówú¼ÿ¨Ù‡‚ŠƒÖÁÃÍÌÖÔ…µßÌÌÊáÅý«¨ÃìêÊ…  Øá™ÅŸêîþ½øzRãËÌ¥ê²sµªùš™àÞýMMÛsH¶¾ÂÍŽÀ¶ZV¶Í¿¿¯ÜZc>812Z½u92TàÏ×ÑšCPçÕƒ«ùšµlݾôÿxx?Nàì2 G?)nZ(vÛ `XëO).kwm´ÓÒì[îôžô,>&81/iìN'àukíþ^!6AD4biwbbkvspóâfbjVetëG-.+7P\brymåóoQ7>FOKVY[?4TcgäíyúÛÿ¹™ÍÜúêíójH\]#T Àù¦ªù›ì±®ÅƦ……ƒÙ …ƨÁ·¯áÆû¦ÑÔ×רñÅ’ihÉÖ…ÌÒÏØëqGbfHM%Zû«ÇÏ’Ò¦ßìnWP@=üë oͨ€¨èLd°ÅÖ™ÁuG^taD#Nnb`°çÇ×­ÝÛÞ°Psƒ¾zÛ›§»bnM][7Ÿüq\*8‡Zvêݰú.µ™ÓÞiüº-qµx2#õ 2'PR;½HMK>C<7N9=TTaM?ió{gp|njehgMFk3074Rfuÿâcqºèó|8'//FE9;^k@5q÷Û¦œîä·ÌÜݯšËÝãÜ›Euƒ ÊšÐ’À­ÛëxrÜÖ€ÏÍѨƒ‘Ê× æ}¿¶Èÿ¥ǨÏÀÅd:­‘áËÍÈzûüíªýÍÜhl_"Rfp«ÏÂýžÜlQPB½ŸTaø¿Ç™š…ùp7B÷¿÷c¦ÁÒÂù«ÈQ_g(qå×ʹ¼­»¦j^ì°êoüåxí ,3??$ 9æ’ÇÒk±ÒרÑáÕÅxR¸ñeÿYâ}ß_ +/$ +'4'þQ! .+%,2:M_S^PHràq^kxklg~y`"óO(.'Tï÷Þåtï¬ìèg6,=FF@BVLDA5^qo¯µ»øÓп¿¨È¹ÿÜü©UãÊá…ƒËÓ’±úç⨬ÕÔµ’‘Xì…Ë·ôÀè¿ÓØÌ„Ã4NØÌ š€Žïîl`ŸÌ׺ï¯ëï»Å¼€ÓÌÖºkrŸ­ÕÔfpÇŽÑÖÓïѬíZ6p¼žûââV4LcN)Câ\'sàru=ð , 4G,õ  +.I)B,ð + A} šÁ=Qä¥Å’ÌšçIYoäpd {! .15|X#,*39CxósX\mj\Tpâukcãtk)Lf=3%9ÿßíî½â®~vNkY$+8;8SQ:3Dãàÿ¾ü|鸪É×ÐËÔªÈ|V_UµƒáËØ…‘ ¥œã󬥯ÁŽÈÞ˸ÛÏÙšñ««¸ÆÕÓÊÒØ† o2gµšØƒÌØþ@]ve€ÇÁОeþºնœÒ’«ŽÒ™ÈóuÒé\hgúwü¯­Anu½ççgWT;F<+OT+HJ  +õ"õ54)d|Oð   ð\܃¾ô¹ýѯÌj0q©eAQ_nlq[ ð$! _O#!*+.@39Uj|qv_k{`VâóbLçvàz(nN6;7[m6R›óÝåyIaûh-(952>Aàüâüþ¬·ß †‘ÓáÙŽÒëzf6눈…Ö„ŠˆÙšÍäüÖ…ÐÒÆzÁ§¶  ÕÍÏÀÅÕ… šÖ…Ò™ñ<^ËÏ¥ƒØ„¸5åzdÏ¥ÃˬoVàšÔþÓ¦…×ô¿ÒÓžtœÛ_oì¼äero^&Br[iè)92-1 ð$2* +#PR-#õ(?P.  õð u»áÃ)e…ÕÊ’R=°ÈªbbN;4ÿ¼Uõõð #-!#*($49769KAx};_½c3qyQ9iyrû:täP90:O8*ó|ÿ®äP=÷ÝsAAE>m½ç߲̄ØÒÍ…†ÑÔƒÊÃÖø½-MÜØƒÌ‘†ÙÌቅÀ·¸Í ƒ«¿ØÊÔÔÖÌѬÀã…ÙÖôÅ˃ËF6¾ÌŽÆƒáƒ®´Ûè¬Ѓ’îàkñíÒµÞÉë§™Y¶}#bioåZeIJ`fF-ZQ]tkYc=187+-#1!##,"*7õ /$("#)'õ+ëpbVâhj;`za=F_=`vzŸpt÷~E65HE7Båž¼¹\<óŸ{tgB16[xz~Ýô‡‘ѾÁÃÒ×ÕÅÒ§f d‡‡†Š ÊÕƒŠŠŠÒ¯Ž«Ö‚ ÓÖ…Õ†ÁPzá·E´…† ?KÆÐ¶« Ù‚ÔÇÊŽÒÏË×ø¶k½wáù´Êb{xb3,XA\ìíz^p[_\KFIbwh5$#Fc|CGObb_i\S@F9,AVyhîüW&+)*/LDAbVFN=)8;206{r?  $`ÿj*1:d½µ’k%(ð(.al +%)!.o™Œ÷I>{Fo­üc{å鹨ô±dúzqpeNbkà›í©ú^`eu½nsçzóîÞüé°×†š™ÑኂÖÉÊ¥ÆÔ„…À~oôšáššÌ……Ö’š šáÙáµ­ÿ»«ÖŠ·bP© ×Ôá×|s™ÊÐáÌÐÁ€Óš××ɶñ{2NøÖØÿQJOu÷E><&Zã²)óÏôJK)DVZ>IdkZS@*!3m|Y000'"<.DxuKamT5L,GJ9?++'ð69 +  +.'v¡Ð8 $%ðõ õ.-uo&0# SÂÍŸX=dA'iª{!?bíïžšv»ÌƯºzâîeorawÇæßŽtlzju~r|úϹœè¼‚ÔÓÔ¥šŠÉ«ÌÅŽŽ‰ŽN±ËÊÕÉÆáƒµÒ„†Á‚‚Žøªœïþ«ýšË{cmÉ„ÕÍÌÝ|ÙϨÇÕÌÌÖ´ÑÌÌʹ¾iüŠÙÙ.(qïúY*FC`sþêV$ï­P:gbjrC5RINBHR*;JC(Jj#)%"0FBfaa^j½b7'% #3!  YOSr' õÝæ9 $"  ,r{9ð#,(*R:D4]mF@ääS "L±t’‚¥†¯rBiu|çF|ËÛÛ¶ótçvg{w¯¥ÏäÒ€¨šÓ¯ÍƦ¾„ ™Éƒâ,Iª¥ÀÉÏ „ŽËƒÆ·ØÙا¿Á·øçu^ÁË´Þk|ØÖ€Ïª©Ë’¸ÂÒËá Ç§ƒÙ׿ÀПæË‡±yy±ìg6Xegâçåw]à DíbEfíâ{ä]"/hnV`n$;UkTKc+$@CLk]&+:`p9)VjI*ethc7P6!" >T2)a| ;l^8 ' +±©kX1Mó6ð2>-=jQz¦¸v++"sÙ ÷ûÜsVMH÷vèÖÞ¹¦zëãfcyxw»©¨Ê»ú›ÂæÞžÝÔñ~y×ÆÕºíA |ÆÃÉ™šÙ†Ò™ ƒ „ÙᎩݨ Á|ºÛ¬ÀØñïÁÉ¿€ÇÀ¸þ´Ø ƒ‘á§©ÿmvãâ{ïqÇüþ}FKiUhw^?8 J:opOdsptY7J][))5]akéV1Poú¶lX+0PcQGEõlm*!7Nipí­Ö¾ÿ»b|ó-  K) #, \,õ$õëc!#õOů»D}»^õ/:008BR"!õq×Àþœh4@Kci& ±ÜNk­Ýêeó¹èÙž·›csycYiv~ßìÒ¾ëéû¦æô~}ãÞÜh]èɾ…Öšµc N®šÔÑÑ ƒØÌÙ̆‚‡Ù…ÒÅ ˆŠŠÅPRáˆÃާÝÞ·ÑÔ¸»kÞ’Ìˈ…`Hglwv°YF0m\èe3FI\C/>B]lP:CîrOj{k5[t~WGð0Eüçm_2XúšÇÞÞkBe;_UJ/R÷{õ2,cºÝgkài±ÿuzg0V|(!  bf !"!õï·à+}ŸÿA7?5.68y|i/ +kåuû°`')'1&OsZã®ãê¯d<âú­á÷ZbääW:sœÍª§»êó身§¦±ç½éŸô¹ÊÒᆇÕnð(ã»ÒÑÏÕ¥ÅÙáËÇÌ…ÖÒ…‡Å‰†½-HÆ¥»¬¨¦Ü¾šÓùdí±èüŽÓÃìÞ¸ñ›Èp_@fn8c[-"C^dGN40eZ;3DJ7;hpä5&*5\}çU*këÝÈÏôóMB9h:uó~zd_f^4;8!?`Wãüíàÿí}ûÛHq"38"!"&ðõõ3i-'"&i½a|ur¼iCD2/?@DpûíU5woaެEú{(su{ºúsßúOC䜜†ètq©»nQ󷎽ûéßÜxÿþãß©àzüúü¼ÐœÒ‘‘íÂ5!`ïÃÆÒÖ’ˆ«ùÁÊ™ÕÒ·¹Éª‘†‚†€¨Éɬ·¾Ãʶàdo¨ªúª¹Þý繺Ý|qh:k^Yiü°cZyÿè~_SV$cc3.&)P`F(4I!)R3ð8B.Xddÿaüt]#;>T0êâxÇØÈpiʯàBfmÃs4+09@8FqÛ÷]è¬kà‹ëz+ +&.#Uÿqh÷ÞŸîô÷hÿþÒ´©ëã÷|Rxµ·Ÿ±üìôèvsw{ïž½~žÓÈ캽fé‘t j븎ÊÅ„ÙÖÊƒŠŠšÒÅÁ¬¬øÔÃÙ¿«¿¾ù¬¿¬’üA\ËÔÂåglxf~¾ü7)Qcç½èïßúÛª®œü½r7GW@E!>óóx`#*VR%°° aID!|ïÿ{,4vzo-AVå|nCxæ{gènÌžVyóf5/s¦ûÀÂëÉš¸Þi! +(,%$"ð:5**'0Yl%"Ü©7+42?;67{²ý„}9­‚´}W?õ!ùôaz±øïæÓvþú¨ƒÜ~sºÈ^k­œ»úÞ±ü|oiëþú½­¸â¶îþžîü¦›ƒY&fìÜÀÍÌŒ‚Öׂ‰ Š‰ÙáÊ´À·¿À¨Ö¯›æÂÉͨÂôÛ…¨ÀÓüYPSstuÿ:?óadß½åéééôô÷î÷»Ÿz-17"4G(4E8IpZH +aƒ¶?éªÞg¬å+$#ü´oa|oÛÀócèùåqnŸœ®þóëþ°üúºïu|}äŸçìñôœÿ›¦àßýžôëÕ¦êåî°®ÉøæÔ‘¿ʃÊÙ‰‡‡‘䪒ÃÖ¥·µ¬¦­ÃÉ·’’¸ßÅ€ÝáënhF*Fjëeåä½éïüŸíqSWâÛŸÛ~^?F!8à»êäãëàûslv[bÞÿ0cŸ½zè{UIfqW\\$3^D/D;(5>/UŸg$.<*5qå±äóß×Õ†‘µSð !(KN¹÷ãgmZçÊjUêN +Vp<(9.yãb{¦þ6Fk/D<-"6;' !!(.)$.,!;ô5,3@qœûN*íýÃ|Ê©ÞjàÁÉÜsvX\VoÜnvØÒÏÊÈ›¹ï{þžélQäü­œ­s`~ói|éû²å~§ûßêû±ßͱó_éËØ‹Š‚‹‹ §æË‘™ÒÏÇ sÜÌË…ƒÉ`óƒÍÀ¨’¿îs:RUcŸ­²íåþèìêïîVYgs|sI$\ìúçêk'B>KZQDSC++8GRdLQ7AþibãKK>kébjz_X¼Ž×áÓøÂ¶a2L¼wxþšÇucuËê66=090(- $#GR-#y¨p%+33($(õð# '(,)%$%*$üç<2 ð >O%ð$B]&Wãå_'H²g19@TZh]â››s05värzlgYF11EHâÂŃ„Ÿ|aU:N܃ýþ€Ö…æc *;$=Aõ(1'A]L=3#")%+ 0$ð$-(#.7_þú²4))õõõ- AHD=H=PF6?_»àüOgÊÌÓšØýihm3Q-Ḩë÷Óq^& (L}Y:ZZ?<1B#8Na6 &(*-( #!)múúþioâ)åvK& õ()+=:4AIF.*A-/AGtŽÖ¿øéú¾§†„¬çÞØÃÁ´È­xóåd}ÛêqlùÝ~ÇØÐÃÁÛS0rÅý¾šÙˆ‚ÖÆáÌšÓÍوᦿŽÒ™ƒ‚Ï¥Ãëîñ¸oxir÷›ýúâxàï{5$,8Täó{LFkë{ìhpóK;hWhN1.96.T^S;BCJCnCBN@tôíxmcJK½íSó…ËóÐÍèÂͬԃ̺Øne¬…Ùš¼Ý÷­„ …¾QonzCmH295A4E' &/6&.7E\jpqbkãqW<8MFLOaÿ§áÊÆÅ¼èû›ÝÀ†‡ÊÆÓ§»éÞpsôû²jvv]¹Â~§¿Ô׸°O4m¦Þ»Ê‡Œ‹Š§Ö‡‚‰‚ˆ‡áѥњˆ‡…šÍ ­bÜ«pç}§Å›ïèâ½ëåP>^tãÝåihzwîp›û~=7Maãå[CF2B<}raJ<>I8(=ji?÷¹H_VWyœlkÒã|†Å[éÖµÍÔˆÆÂ‡ŸKrjû¼ÅÆ‘¥ñ{hÏšÊÏ™áÙXíà:93RXxy}T_qYwãxn^h\M\V]SFjy궨Ȓ¯¸¬Üê{|é²ÏÇÉЧ»Ûu­wN®»âTv®~ç±vÔ¯¾Ý«²<-ìñúøÇ‡Œ‘¨Ô¡ˆ‚‚Їˆ ÁÏá„„‚ÉÙ¤ ó¸ÒÖ±{›Þéìíïo;6Loã±ûddãz­tqó±ÝêYf~x}x;1`(RUQl4N~G;cI4pn\kN/%2_:>8sV{xUÛÙš¼Ðë¨Ãá…Ö  …Õ§´ëã¸ÕÀá×þWe㙑¿ÒÆWN?!+"+15A."=^PnzI:b]*& %-1.'"'pwEB~›dð&?U|±ÝäxUz]BSQaxq\WUDHjjZZ2?Z>xã÷H%'#/*,$&.$6P4+02,2"7CILqyafpT?7.2.#23M>\÷ÂÂÁÀ›°°ôãfix½»¬©Þþìì½GDéAjíõqäìR_œÂЫÐÝVc­ÐÇÔÙšÍÍÉÇÒ‰ˆ¡ƒ‰‹Œ¡Ù˄¨¨†ˆŒ¦‰É›€¸îóãÜ»øt_mÒÎg[svu7XRq÷ëµpìþtjp@>|ôÞtvZ@?a_àümji7Ic2<ý¸^çW¹©œšÔº›©o_^xóÛ}îÅÓ»ú›bdN±Ü/`µ½{áÞOçÈléÇÇætVEzsoâêiCAXk_B9 J@").$$8K)'",'01629`4'6;cxhSL?&F3#!!'6'RIHX⟬„…Ʀô§ÁÅàZZlzŸ´ºýœýPDrN4VUvmUçüå›z¾¶¼Ž]}®Ã’¥ÖÐÅ¿É Š‰‘Ø‹ŒÎØ„‡ÀÑ׋‹Ñ×ÿþ²çèççããh{{ldå{rrof6?E1)äúçmtÛïuXI5=\nmiwpBí›ãsWC_^M^sj]›â qÝÂÖÒÊz6ŸÌ†¯eûL^õpž§ÜÜÞvtC..6½ê̓ñzüÅìM°Æqkª™‡‰ˆnFyîë~zëT#.BKd,!;$01)%ðM~-$0" .'!-1.2sj:-(&3'õ%:ð>;EOH+>[F;Qÿ¿Éƨ¿’ÍÒ®uXxàÞªÝÝÈoW1uM]üžþuyŸ Ôèz°þy¦§e½¬ÁÀË‘ŽýæÀ¥ÍÂ¥‚ˆ‚Τ‚†‡Ïኅ¤…€Å­Ç·üÿèäàOH2,. 50ML:aYâv<@EÛçíïÛwY}nKrP9TyeelkhH1AKMUTîãaMóåÙ‹ƒ’ÃÐÏʃÒá’ÇÓ_g.õ ðN=F[=QܯϚRþƒ€9&Rvâîluâ}ëÉÙ‰ªX°‡ƒ§l]î3!226Þþ;24#('3H!1-#"#$01.650rk~k*/(#3?GEDZjSG@LMIfë¶Í¿æ´ûô’€ˆÁF8;¦ªy™ûþoiUsݱþ½y›Ô¿þü¹úçäû¼¸Ç‘Ѩ«»¯§»ªÍ„¡¡‹¤‹‰ ¥Ò¥ÀÙ Ž€Ýô¥éulluqfU@AQCKFDJ,;~R_C<ièœä°è`ï²gVUCTsy5H9HhUpTHG5Q{n~„ˆ‡ŠŠš€ÇÔР Ñ†×ŠÍyŸ}äüL/`´Åá ¸ŽÂþŽÉÊ¥Ùâ=h²¬¼ì_®ßÀÓ…†h8s¿Ôìi¤ÈQR`KRW1iK" '5-80/ $"+%##d­Í×Õ¯l\èï­´´åìÏÒÃÜœàtüz簾В™ƒ¿Ð¬ý¼œžµ¯øÑ¡„†ƒÊÖÖÆÒÏ’¸›ûž¦ìk[_T[uwwxliaW^UcpD/ð-EP"0oûûvvgr°ilíþQXk{czä`9X\WW!ãܺ̌ґ‰…ÙÙ…‘ ÇÙ ‡ƒ¾Æ×Öš¡ÒTè‚áÐf»zÃÃÅ·À„ÉÖy CkZþüàúÒ†wœ®{akb½rg±}HB_=)UfE,5,* 8+-'0"!ðQl@??)_nfä^  õ&R[@cW@9D2+99D8KclÜÏöܺñ®ûÝý¯´ô­\l­šÆÖÉA-wqåþÇÑÃ’ïrâ¹n¬µ¿¥ÔÔÇý¯ù±èﲟíéšÔÂÑÔÖÓŽÇÁŽÃ­îìú°éíûÝ­¼î°ëú­ïocvl7$g16"?jé±åå±¹êXvugA.4mOF`?6wcl{`Ý…ŠÀ>¦†‚¡‰ƒÅƒƒ™ÃÒ‘ÉØ…ÐÒñjýÙÜÂïE¾zsÉØÆáËšÁôq䀴¯Ðƒ„‘ÁÒo{íéy[8Oqn½yJ@pW5SJ*+#&2-@K3*&)&[¶X,8›hp"L]: #;7:~`_qQ4)7&-aàéï´Ö¦çåŸÝ±ßã÷þ›ÈÜ»Ýè›þÝÊÖn63k{ê¹ÀÊÖÇžsê¶÷󒝍ɯÍɾñêÿûîêퟒÓÒØÓÔ™¯¾¿Æžè÷°ÞôÈ«ºôüüråžäoÝ¿æ­ÿç{með0(I7e²®Ÿ¹»ó@h]H.Þrj_97Frs@giÞÿÓƒ‘Ũ…¡Ôu¿ˆ×ÕÜ„áÙÇ„‚ÕŽ±mƇ\Wæ™ôohþиù¿Ö »«‚©þ¾°µ‚µrñ’|lžlVAE*_æÜsbcRG8#1</6? $6/E`>Bàœ¦yãZ 2+/ 7W.HgX0%%*E4C\híü¶ÖžéëÜ·©ïãøûܶ›¶¹wg{~tœ×ñ±âK`ÿ÷uå¯ù¼xMóÃ}VÛÃÅÐÔÉÉÏ¥«ùŽºŸôÛþúô­´Á‡‰ÌÌ™À¾Ýú±©«€Ã¨ïllàí{ú²t/°ûã}dìùhNO">MZ°Ê´¾ÈóTVW:ôwUIKAqã6Tݬ Ì…ÙÙƒ‘‰Œ…©ƒákâ¾áÙƒƒ¬ØÙƒšþdñ¨Tå­ïÁghª¾Ü®Ûè¬Ø¹ûß`18fwpsÂÜá„mw„·x[KfL(kà[wrP*%9=+*6(+&7G1+-'[{íý²púú`pd_@4? + '8<&.1-$=LA8vôÏÁûžßþ›ú`j½êþºüÿüåbàßp禹êâíôÞ÷ýûw¦é^oÛ¦w|ëïæ¿¾Â¿ÌÌô©¾º²ÜŸÈñ¬ ƒ …ÊÍÊ×­ï®§ÉÖ…±OZj}ë{ô²ã~;iljàvy.ngJ!QîjG°«ª‘kWPC]E=-]kcWh®ÙËš†ƒ„‘‘‚áÏ ×¶ûç¥ô¨ÀùÃņ‘‰§{¨ƒË‘™ŸÙ›So›¶Æ¼üžÊ²ÇjQè^ojúš€Ž±››óºÕë_s}MðZŸÿà÷~7.$Rv.5E8N89+",+N÷aR°uê}­îÿâÛ};[5!Dc)6/$!6>SK\ÞɜߺþŸíèqlûûŸ©ëxîÜä^fý~îÜrhí¨žmíÍüwž°k­éùÁ«Å€€µ¦·ÏšÝ÷´Èûí÷¦ñ¦øÀ™„‡ÙáØƒ†¬¹ÆÉÖ´¾›]ó½pov»ë½øÛ?$+jœG:joeaxîP7èñšÇ|DJuWS/:Büuemq© …Ì‘ƒ‘ˆ‚Ëùcuªâ¦ªï¬›Ñ¿¨ÒÒҎتûºÅ„‰Óqqkôûž¹ÉøÙËsq߅ᥡ¸o胦àbúÙ¥¹Žøebâc3tiD«B#/]ft10R<,/B>nœÈ½Tvr²î›ÿÝ:2?,(Rå,)/(&.)9WUY°ýݯ¼°÷åè½zžœª¦÷Ý{il~±óvfcy®§óz›¦ÁÈìà´ÝÛ¥‡‘ÌØÌÆ·Ž¸æ›­ýÞíãÿ›¼ñ·ÀË¡ˆÖƒ†Ù…Á’’ÂÀ½åœüݲ°ûqÜéfÝžO24Q½|>I]äWKè±`d­·årIUao½B@wiþçùÙ„‘ „†‡Ù±¶²Ûœú¥Ã ‹ÊƆƒÂèúiàídZlóûjNï¶ø¹ÞßßíãÈÇÌÙÙŠƒtÖ±÷í½Ø¥Å„Ͽŵ||Ÿi=dO>ÿëI%0.œ±''@9,C7LÛê仺çUÜàuqïãwf!*%"2GH, .(1$ -01H漮ïìÿëz±üå©ÔŽ¿¾îcnsÝeuh9p~ÿÇÈàô‡Çâéî÷®Ñ¥À’€€ÅÇ«ý››±¯²ê½ÿÝùŽÂ…‹¡ƒÖ ƒÖÏÓ¦¹Ûªœí§œïຽé~~êàn!`9 Ypq`bnênXuzëpfNftNXx3pÓ¾…‰‚†‚ƦÞ̓‰Ì¸øÑ‘ˆˆˆ«ùƒ†§é¥üâýÜp`ïǰ·Ù±·É¸ù»Y]쥃í×Çkhçn×¥¥ŽÂŽ…‚…¤¾gôbijnikUÝ8%¹x21C4,C)AmYUúÃ/heckWhfh|f+'($+F/-' --(#:à®ýæœôüôŸ÷|±µóÿÉÞú§·žpï®~þaBsnvØÊqøÁçpsçªÀÊ’°­ÂñœÛ²Ÿñ­üíþ²ºýš‹‹‘šËÙÕÓӥǾýø­µÈüýü¼yþ›xm}rpï°`Jp5,9]~geIlr0^âa]yx<,DP8W½Ò†ˆ†‚Ïzì|ç¨ÀÙ‡™Ê„ ƒ‡Õ ÀŽƒ¥×¥€…Ðá†Ø‘Á®È¯š‚„’‡|s}ðV»r.nWe­Z܃ÛÁ¿æ¦þ{­g7;[tyv¥‡å04,'12,-CS1sÛùœþûîàè鲸œ¹ª½lܹîúãäxW3\{åý…ÆÝÛù÷ûï¹½¼ÀÕÇžôÜÝô±¦°Ý÷ìë÷ž¾Æ‘‰ÙÌááÙÖÍÁ¾ÏɲíæÅÀ·î¹y|éçêsP8]­gÁë<Epj½yizxc[shäK15@=,|œ’„†ÙÂǯk €ØÐÆÕ‰‰‚‡Æš„‘‘Їɇƒ€„‘ƒÓØÆi²oýËá’Á½Dü¼Nõ*>&%žµíÛï{ªÔÍÂÆ€ºå&W¹ämVB`{pXuž¦ùç!)+/)/ki2Mn3:9(:'7wóe÷©Ÿû©ßxoVEFäºyzí|Q%).(9=Xïœà~èžúñ÷žúï}äûd\[e]_Zçm6eêù®ÀœåÉ¡‚ˆ‘Ñ«Ž¾¨ÃºÝ²¹ôûéì±Ýœ¹œ®§Ø‹¡Ì„„á×ïæÍÆ­¦Å¨Ü°|±~çþåûÿjbklqüy`C-Om²èm}½mPKcL573;.6÷†„ ¥Ùƨ  þÀ¥„‡ˆ‘†á¶Ó‚ב†×ÇÔÙÙ‰†ÖÓÐ¥™ŸLÿÙÂâlãA[猡]*<8]n1:pdwÿþ’Áñ¨ùâ;k}fT>?]÷›t>LH|ªâ10-;'QsD-]t2;58F-3bré­x²Ãç\txovvgóg\nã›óMKE:Ykí¸ýÈú±ùÀ¶¹ÿÞ¯±}îÿA.;$Dó²Éä4&xøÂ¼©žÛéj⠥ÈŒÑÐ™ÌØ…šÝúìlypãž´ž¶»‚¤Œ„‚ …¥Â’ÍÅÍÝúô½ìíîÞä|ßÿéûâ÷÷ztgçó;RºN'=VuëäãwL_zL#<8!)óþ»Ñ ‡Š‘áøÒÇÇ×Ò‘Š ÓÔá‘ÿ¼ÍÒ…‘ ÍÓÓЬ¨×…ËÊjNâœhˆ•åR:UàA*2Nð6¦âjà9CvãLhpfeþ™ú÷Þid±êE84V,]>2&H\6'4;=Rnhrïvcçýúãóvúàru½ünjäÛ²ussêŸÈ¥’Ʀ}èÝœåŸÈžß±²óþC*HDꬰLq¦…¼Ÿñ›~t¼«Á¥ Ç€ Ò¿ÐŽÝÛåmvtû»´«¯ñÂŒ‚†‡†ˆŠÔÑÒÒÃÞ·û÷¸²ÿﱜþ|úÿÿû{aa`PD=,4?k½A6êãqj3-9+,Xh ))?ræ†áÍШùÇÖÔŽÓÒÖ†ƒ Ù‡ šÌšÂ€†…ƒÊÕÖÉÍÔÂÀÇÇŽ’ÉÓ¸Þ‡‡žš™Ý½såЭ.>,-(묰kA4Kibj}›ÈçpÛ¬Ÿpîä?=uG%C2*'01.1=Amçcmq`Yxïü°½Ý·ÿz~{~o[}÷ߪñ¦ùÖýüô¦ä[yžººÜñ¦ûû»žÝ^D\lóúfp½î¾Û÷¦ÿQ|¦¸Á’µÁ¾ýÒ€Ážï›àó{}¼®ô¨«ý‘Œ‚‚ˆ‡¡ŠØÍÂÇÁßœýÈîÿ|œœÿì{ïüujwwjê?,4:nßJ59féf$4RH,)-G0ê‚Ô¯¿§ÕÐÐÅÅÔÔØ†Ôªñ¸¿™Ì†„ÌÓÕÒ’´©ÞÆÏ޶´Ã¥ÊúôryŸñxEn½°E*0'93#JÁÿT"SO7P@L`0.Hasóïæ²í†ÇéN.T0=+*34,*20(5@mè|epxkyvç²äwacY:èôý¼ôß°¬™ëüêéxXNì§Ë…þ|²ÿ`°ã7\~wªåYnku°ÛìZè§´¯€€¿Ã޹¬¬ÞªûßâëtóÁ´®´Üþ™ˆš‚‘‰„ÒÁ­È´®È’ªª«©îÿôÿ}ï°ëuk}ݽmT]ð.ówT&b±y  0 "(?GªËŽÁÏÓÉÆÒÔÉÔÕÒÆ×ÏÍÙÕÉÆÒ‘×ÓÖÔ™ÀŽŽ€ÔØÑÉÐÆ’ÃÒñGâü»Š·FKvWzx:5$-/FTB~âe[fmT]ü¹°oVer:Pw>$ãË×¹V5/'@C0152& <.H8?iàî\k²ÝèêúozhVZ^²±ß½¹øÞ¸ÌDZâhpholVUyÝǾ¼Û÷÷q)9i|¹±èyåàéÀ©ûražÜ¹ª¥Ï¿Ÿ±ª²ÜºŸèåÀ¬øº¹ÇšÔˆËØ‚¥ÆŽ’©Þ©´ºçÿø©±­üú÷íœþâäofzìvâû~2wÜg=­ž;GnIC(ëǬåMóó?çiFOWÿ¶™…Ë¥ÆÇÅÐÏÒÓˇ×ÑáÌÔƒËÓÌÑ× ûRfü½¼¿bß‘…è%g{ookû¡•Óä²y7ÿD*äºüã»ÿêô§üÈä>3/,)%5-1,()%õ 3!&RUJA\ú1,=%"LWëÝÿîèêÝœÛþü~hçxBu±ŸäyÿøµrHSyüÿ½XHû´ÛŸúl!qZkvÿÛÈ®ý¯¯»»§Â¦ýæÓŽÍÇ™áÖÆÐÐø®¦²›Þ»ß®ž­º~â럨žì°}ú¬Þ±x{ão½ßïàëäuÝéî}oèü~àplîºßyq6&qlcîþâT3#('~^qŸª‚¡‡ ×ØÑÇÏ™üäíq‘áÔÐ{b®}:¹çh6õõõ(jŽƒÞâ‘ÇÉÅŠ“¸x蟈ö΢¢‡¯À[Uä^/vR#>bÝݺŽîbG)$/=C/-*,53.7GF*:C/+5qA =3DWD}­Ýxpè~½ÔÈ{ózÜë[Keiiê­±›rQFßéwê÷pvéïÝžëD:UUYyÿ±»ÈÈ·¸¼º¯ÐŽÀÁ¿¿Í̈Ù˙ԭ»ýíÛôªœ´œ©ÿú÷盾ޞ±ã±žþåç÷íç¹èWäóã¦mg|wrsb~êbh~ìú´b%3LNpȪkTãçh)#%&;D?5<1o챉‡ÐÕÍÂǶvêxr¸æº…Խ͢ýʞîP4yíju枀ƒÍ¬†…ÅúÔ’¨“•¡¤¢©vœN=+>@EV?'5P{믱@W34"1440/79"qT!%7DEL;&2#(0:jD&;<[F9zœÜc4`wjíÉuOãèqp@7LN|þì»elwºètxpVMlïïÿvYagMD[½üúÞ®¼æ¯È®’ťŬ¬™¡‹Ù ‡¥§ºþ´ºïⰺȪµÃ´î÷­ûßµ»ú±éžßßãéí~ßycxãäwYkzlMe}âkJ_{²Œ¹ï_(60"|î)]Ûó,õõDRL!.5Ü‹ ƒ™Ç’®bn|hqípsÍ¥ÍËÈîy±¾‡‹ˆø©¨Æ´¹ÿÞ„™É„ ®¤Œœ‚Ú•“‡y-?75-=G@lT*03Hä§ú,W>8! '3-.8BdÛ^ð/26@=1EA0H 7c)KDGS%mÜæªêkXl»ª]qjKW>6FFI]þ»a8uô÷âbZpnåÜçvKLzc=3MxîŸïº´¬ñ¦ÁÏÊÅ€ʄ¡šÈ©©½Þ¦Ûëì÷ߺ«ÜîŸ÷úœæ›îÛ鹺çmäÿqåÛw\épuhlhk[nulnfeo›„ÙÿU/ #&I€¦ûe6TCð=4@> $íݰ ƒÓÇr/?coQUâêÈé±ô²±‘̾ŽËÉÏ¥èsãҨÉ‘«Ûí†×¯‹ö¢Àt6-AWZLHHIYO<9/@{ž÷?D9;* (.,5=GnSC%0<-$>4"LI6Q"8W"4GG5!}íí ûF^,Iüâhu{s:<_75ûßYEéèvW~©¼±zmsv[a\M\Zs䟭¶ø«æ»ÃÏÃŽ™šÔ‚¤Œá¨ŽÅŸì»Ÿôž±üìÝ»¦±ß÷œýã»’ÜûÞ²°}yì°èhìüD½óuiyãl[lsmpvtej}±ùp\843+úÀôâzvþâ}t3*:* 0ç§„¨±Q /'(,;K{|ýŠÚ•Êíо¿¥Åïj~t÷ÃÓÙÙü篂΢•‚Ìq-@JPWHKB.4GE1,APvœm1J7%$%-=CEi<= IC-) 3?$'.N\9 4- Zçè]e®®åq}6VwóüÝïKAoD9âëzKFqwViãûªé23g~ãNbpm]ìÿôȧýø·ùÂÇÁÉ„ƒ…¤¤†Ì™á ñÝÆôïÛ²ÞçÿÜ­ýæ±¹Ÿb߬ž¶Þ¹ôlì»ãzåíísq~tåwÿubw}ä~phEhþßl~waK*ð²À°¹ãäÛñúc<,) Z­ï·›^+5.3/&YgYÙÊ¢ˆz™‘ׯ’ºÞ¿¶©­ƒËÑØÓÞŠ”Úö•ŠÌº_=?@1+X]7+ð.Q:Je¼§Üg½#'-=!_3,=daE!(#í¥šÐɎʈŒŒ«§Œ¬­ëlÊ¡“Ì¡—×ëœXR²ˆ†Ì½|µƒ¶ûÔ |!!M_';R67D$73>i6$IG,62+;H;>CP-1-'+%ìæµ„ÈûïÞñ«¸ôÛŸ±t=âV>40,EJUaRZpq¹]Ràót}wëä]gwã°ß›ß¨§€¿»Â‘ŠÔÒጊΡÊÏÆý´æ¸Ã϶ºÇÕíthèœß¨®­çwž§¼©å²{ÛâåôâvpŸŸt9Gfã^|Rê­²ìmzŸ°ãkŸôíhܪcHXB.-õ#QcQ1y©bð#A53C0AV4"`¹ÃÇÒÉ…‰Õpd™ÙÂçxtᤂÀ»‘€Nî‚¶ÞØÅWž¿úÛ’ý¾ƒëRHp{7OJUA=-&ILI?:Qio|qdqë’ì|npíxw{pt빟°î¦Ê’À´¥„ÑŽÉØˆˆ‡¤†Ìš¯¿ÀùÀ©¶ñÞéýspž¦¾Ô¾¼ž°ÞýâÐxwú²íí±íéãuääP:vYq~`w°÷½qk{si~¦žŸê«²Dbd(&-7- ( EO~i,!%%ð 9@$5<29*K·¼€¯™ˆƒ€Âá‹ËÖÖ›tèÔáØ¸ÙÊß§æ]E^ÝÉ‘„´þ÷çŸ{¬Ò¸Õ€éF5J>7B/=Idï÷v-õ,!8M6xV@4*(L@í¦Þùïû±Ü~|åâì¹ÞþÛÞêN@VOdVTyêék{ªq|Ujyyztyêå~Ÿ°ì²¸ÓÔ×ÑÅ©»‚ÍÅÓá…Ì¡ƒÙ ÆÁ¸€¸ø·¦²®ÃÈ|åꮀžúªœëÜåï€Èz`ïºé|°åhzœ²EMNMûhJjóìûx[rAÝôrhfâPvp)ð(.)/.55.')0'02!3!õõ õ0/-:$5m~iw›²¦Ù†‚¡„ˆÑrq®á”šÏÙœksU,rÒɈÕ»x^S*g‘„é~ø„Ê€ô[X%7jV)"ð'' $õ$"õFPŒ‹ˆúq«øvœ‡‹Óø„à_­Ù‡¢rYlz°½~ô¡ÎùkzÝņ¿¨ÀŸV;J=2k÷í½? 2IIQW.õ %'1*$E5)!(&.80J<(õ&. BHD*)  I݈•ŠÂ‰‹Ò­×Â÷úèæ¬ÿ~fI+C.1CEHEJ>3@M3^dAXhGELJtMs²­þZ;zsiG-6MA +>¶ì "0E2TûlDAM}ä|mXäÞ²mYE2;30DMMqj[Z<,*4NbmhYQLGWíªFméQ4EN/0ã¾ÌŽºÜ°ï{÷áÕªœïûøù±¼€¦Þæ°éݨ«±uU}ôÞ½þ›åüôüîìÈV4dB]ÜVE0#,89)HS1IzïîS)3kµÂ_D3"&#*()#=8(*#'8720HHB<,)$yª´B (%-?< t¼€ƒáˆÎšâÁû~gþ_29-ALITN7/>8 *+R93Q^TKLgóÝôzxaNäàè{;;aOW’¦n('$?H(Cçuhp<'Xè|mêî½y|_43/=20Tbyp??>>BTehaTNKGDçµÛNiYKI^N/`ž©žÇø°àE&Sâ›ÜþíäÛ¶´ññøß©¯¸Ÿ÷þåÞp.FsëܲûúíìÜÆžßê~KH'$:=7'(@L5 (<5'O3HXlàco~!õ #(",)+,/91)&;75+#,=T/,-%('&õa½žD %$%0,"+zºá”¤‡îéšÝU`{îÀ»10GELLBI^G%SqïtB?ABPsû|@~½úèi|íóìI\›W$SZ8’¼tïH+AG=*Kx±úG,@Wnlóär|Ý÷h='*29QNZljWPXNT\cbSJWf_mû¦mriFMsT2Qççv÷©ÞºÞv +h¦÷þÝîì¶§»´°¶ñçúÛèM>~®|wÈ»´±tóq¾¥ójºž,.5)("*?dW#]kzâ^=@GHMYêfq|å÷óü1 CicXlxmkobhfywdSO}fzã{oàïo>^\9*K~sdX÷칫»~6(ã®¶¸œîœ›ëßݯœãíÊÿàžüóm>CNmêyÜÛÈ­i.nº«µß½0110. yú1,oâûã|o*.Sy*  $%%53*+8?@443)5*"'";,0/%E=$!*"<5%!#& $!½Úö”ÓÚ¢Øÿ²ïô‘ºnMosRrÂ†Š¡Öþož83PJ+mߪ«éÛŸ½kûq*-pa6ãâ6 êÀ±}ÿs7^ïÿsdbFEYPL4]ïVLNOãTú™ïómc|nB÷ën»Ú¦u_dB8M?;=8)@:&0dèç|rèübKnósOJBADB9içìís8óèã÷À¦yroI9DBDH:58;:H`|wEl½ÿºsyŸó/')Ls~h"jzré÷OZQ;+0çžßÃÏ®Þêù®®Ü|èë²Å·ã½x}`FCX°¨Ã±úŸ¬¡ÎDZ©[*,2A7';W_EcpyçßÌÞ!  + +3G?(1,3<)$0,.051( 1>+&'4& 83õ!-2,#"!+$2JFñ¡Ì†„šÓwC­…‘ˆÒ’­¦«íycMl²ºï¬ã9C®Û:`úÞÝJ1½¦S+4qÞZ0$OY#A°±[9RâíkRwmwþlNWvókg~í½>566:?tçåv`a=A4-6B@D>;xãoìO\ºã~omþë/ð).._ëa$SfuêëljW%)$äȬ™zÍ™×±^üŸ½Ò±ÚÝ}ÿp3qß¹žàÿìŤŒŠž& ð:A(9wþjMîýÙ™»P% + +  'G.,-!&).0/70756E.(()34*'+T@$&#*3$ )% #4^Zu’¢ŠŠáÐÔšÊÍÒÌÁÿW®÷I?\IyÜêâa Vœ±âäìz@2=K4.<;e›è;7;N@'CsãgEjjszà{úþåó½þüyéÜçã=QZ@3:eìüm8D]sa?64-,5-j½|èó-{§ìf_}ÝZ4/,SgN_zãì°çqiPF6îÁ¼ßÿqï¬Ýé®îãþÀ‹ûú½èpk56jþíŸ¼Ž·ÒÖšÜ  -&&WçP?ããþ™Ãx:@,  96-@C;323.+)6/'15-%/1)-2//4FA8*'))#*)&$ !%<ëîㄒҌʚÙÖù÷à¦í1&}ªãêïQe÷åUjqX0àžêìsSGD:75)*9eúôK1JC;:nå[L^›pEfyÿûéååèúô¦ôçîÿåHE>9C\âèãäëgF[M;@86/Cíÿ~úŸ]îçw\kê~Q1;J12^m|íéx{ú°eTQT0@úúÝžíëÞÿçôû}å÷ÑÔ›þsó÷²lL9dèêø€­þ¬Š©1"db+>\U~·ˆ•÷/8EDCo_# &7::A?:D7ÕÛþìéóþÛêouë»Õüomj{íäZ4.TbªŽ°žÐÃweH<  1_z`[Fâê‘ô#A?2UtdL1:E>6936[^D26.O|RCH130?0%,*.436*%,+"*52-'0+%*$&)$#!-^b~¾Š­¦¯Ÿ²~zã/F:3E¼’͈þ.v»ßîF<61#EèZ;q`;*4F5;TtrP[NYyŸüm<]vwè­­ÿåB((D^lvì÷ŸúíêtjxéåD9197WÛß¹©àãÞ²ìn]bmxçêãtGEs`agÜNuüÛégY^Cð*{ЏŲâåàuëÛeûÇÙ±àQ]taMD*$G½Ü{Ü€ÿOsO_íxaVujr½êŸÞšÛx<år0?äUIþÞ}BU*#->43AEGFCHUODnìN7:C1!/+&29..0,&&212(.)$&! ! ,,9iÆ´t|XQólEI^GB:ÌéŸÝo').:A915D:14/:W=Kx>FgS/,Q]66jz|I_JGäéäâ?>î±þÿèè±ìYhóVtÝÜîäy|qZT|çYIMJ=oÝ›ž¸êeé›üäd`hm}~çèfNjW7LüqMOzüüóoiK79+®ØÐæçèrZêÓ»]oí‹ÎàëâéçW:7<8n²øí_UmCJÝÆªôÜûçw}›²ä¶Á·Ûzq2èôN&àáýP6CP2=OIGJ94Opnvo~M44.0.(&16618,&*/-0-*3.(&"!! *("+/PúbLq*0âã6,K@BE#rკíñ«l_ä>=9JPDU?*(9YP=Gî²b@:7ERCbäWB9LFlàRT½ãSV{}ââçóÛådc[íÈ­ÿçm[ga=P_RMNKHÿµ®ýž÷é¹Ý÷âXdjwzà°ÛoaY+Dnâ_6Ky}rc[U\R õsË¿û}ï²­èó¹ìbh쨯¶ãt4/10Tþµ~)n~hvê­scï»ÈèjßÜ[}î·¤ïv_ãxK"5®Øë÷fm}|M7?8DI736GrÛŸ[/UJE2=0%/<772*+-/%11*0(#&&! #*"//5bV\ël']G2?H8;•‰ávó¡×žÿ9FEBI8ad5%5:>.?¹îbK94984`vN_dqóóX79^äêL0VyåítóæßR7hï­íçé_<>6.'69<5,<úæùº²þ²íœ¨››äpfkx{úºãP<3A`ä],Yå½XN½zdp½¸žçmfa_J@L=,! $(-1KF47zæú|éŸlzžô»¹ë|w}îô±|2=@KdTF8Gîíg[NQN+1?Û›jmxy®çXßÊ¿sR~­gfÈìgfA \ No newline at end of file diff --git a/lib/glut-3.7.6/progs/demos/smooth/Imakefile b/lib/glut-3.7.6/progs/demos/smooth/Imakefile new file mode 100644 index 0000000000..f600ec5cd0 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/Imakefile @@ -0,0 +1,23 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../../Glut.cf" + +TARGETS = smooth + +SRCS = glm.c gltx.c smooth.c trackball.c gltb.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(smooth,glm.o gltx.o smooth.o gltb.o trackball.o) + +LinkFile(trackball.c, ../../examples/trackball.c) +LinkFile(trackball.h, ../../examples/trackball.h) + +trackball.o: trackball.h +gltb.o: trackball.h gltb.h + +/* some old imake configs do setup "make depend" dependencies on linked files */ +depend:: trackball.c trackball.h + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.mtl b/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.mtl new file mode 100644 index 0000000000..dffbc4c3e1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.mtl @@ -0,0 +1,25 @@ +# +# dolphins.mtl +# + +newmtl dolph01 +Ka 0.4000 0.4000 0.4000 +Kd 0.0000 0.2000 1.0000 +Ks 0.5000 0.5000 0.5000 +illum 2 +Ns 60.0000 + +newmtl dolph02 +Ka 0.4000 0.4000 0.4000 +Kd 0.0000 0.5000 1.0000 +Ks 0.7000 0.7000 0.7000 +illum 2 +Ns 65.8900 + +newmtl dolph03 +Ka 0.4000 0.4000 0.4000 +Kd 0.0000 0.7000 0.8000 +Ks 0.7000 0.7000 0.7000 +illum 2 +Ns 60.0000 + diff --git a/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.obj b/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.obj new file mode 100644 index 0000000000..4486db54a8 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/data/dolphins.obj @@ -0,0 +1,2562 @@ +# +# dolphins.obj +# + +mtllib dolphins.mtl + +v 45.72071 330.25390 8.39974 +v 40.21416 331.03907 0.00044 +v 80.09274 366.99179 0.00049 +v 87.96514 365.67971 6.30254 +v 114.20649 383.52171 0.00051 +v 117.62613 380.38111 3.67843 +v 146.74990 385.88759 0.00051 +v 148.58885 381.42449 1.31257 +v 165.37711 380.89767 0.00051 +v 147.27679 320.28422 10.23868 +v 146.74990 338.91150 0.00045 +v 157.77332 313.19702 0.00042 +v 106.33408 328.41489 12.06732 +v 121.82061 350.46181 6.30252 +v 132.84405 362.52868 3.67840 +v -131.15011 228.43952 0.00030 +v -136.65667 220.30884 7.87270 +v -141.90492 216.37264 0.00029 +v -113.03945 244.71122 0.00032 +v -116.97564 238.15086 14.43306 +v -91.51947 259.67088 5.50690 +v -86.53981 264.65052 0.00035 +v -51.37228 289.05293 0.00038 +v -52.42606 282.76113 18.89621 +v -90.47601 257.56326 14.43308 +v -7.28888 310.31460 0.00041 +v -8.07406 304.79768 23.09072 +v 42.56968 314.77767 25.45659 +v 102.66650 313.19699 27.55383 +v 160.65574 300.86148 20.99348 +v 229.15186 263.60703 12.06724 +v 230.46392 267.80155 0.00036 +v 272.45006 231.59057 0.00031 +v 264.57769 222.13744 15.21821 +v 291.07729 207.18816 0.00027 +v 280.83906 194.32577 12.33576 +v 303.93970 182.51719 0.00024 +v 294.22832 170.70854 8.13091 +v 310.23142 161.78238 0.00021 +v 304.45626 154.17856 9.96985 +v 306.29522 142.36997 0.00019 +v 302.10075 146.30616 7.61432 +v -93.10016 251.00291 23.09065 +v -76.30155 249.69085 33.85580 +v -45.86573 268.32843 30.96308 +v -7.54716 285.38528 33.06035 +v 42.56968 296.40868 36.99656 +v 94.79409 295.09661 35.16793 +v 157.24643 286.95562 29.39275 +v 225.73222 256.51979 18.89618 +v -88.36845 236.31187 37.79199 +v -98.86499 237.88221 32.80200 +v -106.73739 230.53671 28.33889 +v -123.53598 212.95297 21.52026 +v -138.22700 198.26196 10.49680 +v -86.01293 226.07361 36.99647 +v -97.29464 230.53671 32.01682 +v -140.06595 190.38956 14.43299 +v -132.97872 180.41989 15.48677 +v -160.53216 156.53408 7.61433 +v -165.78043 158.89993 7.61433 +v -170.77039 154.96376 4.19469 +v -172.08247 156.53409 0.00021 +v -147.68009 189.07750 0.00025 +v -144.78734 191.44335 5.24852 +v -107.53290 216.37259 31.48990 +v -99.91876 224.50328 31.74819 +v -106.47911 213.47982 31.74818 +v -120.38496 208.75849 27.29541 +v -116.97564 203.25193 26.76851 +v -129.04254 176.48371 16.79883 +v -153.97182 155.49061 8.65779 +v -110.15703 191.95989 26.76849 +v -100.97256 207.70466 35.68438 +v -77.35534 199.57399 35.95298 +v -107.53290 186.19505 28.33884 +v -95.72428 213.22155 35.95300 +v -93.61672 222.66433 35.68440 +v -79.45258 211.64086 39.88919 +v -127.47219 171.23543 18.89606 +v -150.03562 152.59789 11.28192 +v -103.32808 163.88990 17.58399 +v -89.68052 194.32575 32.80194 +v -66.59019 173.59094 23.09055 +v -121.43874 163.09442 10.49676 +v -126.94529 167.55751 17.84227 +v -37.19782 195.63778 44.61055 +v -35.36918 185.39953 36.21124 +v -74.98949 212.69467 41.72816 +v -34.05711 226.86912 50.91264 +v -69.74123 231.06362 41.45957 +v -68.68743 244.44260 37.79200 +v -37.46643 251.27152 44.08373 +v -4.92302 261.24114 47.76166 +v 7.41247 235.25806 52.74129 +v 47.29105 263.60700 49.60063 +v 52.53932 244.18429 52.74130 +v 96.89134 268.85527 47.76167 +v 98.98858 244.44257 50.64406 +v 154.62229 262.55319 45.39581 +v 154.09541 234.74152 46.18095 +v 215.76257 236.83879 34.11406 +v 205.26603 213.74846 29.39266 +v 252.24218 211.12432 24.14439 +v 237.02426 190.64784 22.56368 +v 270.61114 186.19508 14.43299 +v 259.58771 174.90302 14.69125 +v 282.94662 169.13821 10.23848 +v 271.92318 162.05098 11.02365 +v 297.63764 150.24233 18.89604 +v 2.94937 201.41293 42.51332 +v 54.12000 209.01676 38.83541 +v 93.21341 211.12429 39.36230 +v 143.07198 208.50021 32.01679 +v 194.51120 194.58403 17.84231 +v 229.15186 173.85958 9.96988 +v 250.66149 165.20201 7.34573 +v 272.45006 147.61822 5.77536 +v 282.15113 139.21894 12.33568 +v -8.07406 169.65467 76.10014 +v -8.85923 166.77226 73.73428 +v 14.75798 181.20500 66.65739 +v 39.16037 165.46018 79.77805 +v 24.46935 162.57778 83.44563 +v 3.47627 165.20192 82.66047 +v 50.44208 195.37956 0.00026 +v 5.57351 185.14130 0.00025 +v 140.71645 197.20818 0.00026 +v 197.92052 190.13131 0.00025 +v 246.99390 162.57788 0.00022 +v 272.18148 145.52101 0.00019 +v -61.86882 170.96685 0.00023 +v -25.91609 178.32267 0.00024 +v -95.19739 160.99718 0.00021 +v -118.54599 160.99718 0.00021 +v -144.27079 148.14512 0.00020 +v -147.41148 149.45722 8.13088 +v -163.68318 139.74583 0.00019 +v -161.32765 142.10135 4.72157 +v 309.97315 87.52131 89.47898 +v 294.75522 115.07473 75.57317 +v 308.66107 96.44751 65.34521 +v 307.34903 120.85000 9.96981 +v 301.57384 135.54098 17.05706 +v 305.76831 129.24929 0.00017 +v 312.07040 111.66552 6.03359 +v 308.13420 119.01103 0.00016 +v 295.79866 147.61820 24.92948 +v -168.14628 149.45723 3.93640 +v -168.67317 149.71550 0.00020 +v -166.30732 144.20894 4.99018 +v -168.14628 143.41344 0.00019 +v 24.72763 161.26570 81.87529 +v 3.99283 162.30918 80.82150 +v 156.46125 360.43143 0.00048 +v 168.52814 372.50862 0.00049 +v 95.05237 199.04716 0.00026 +v 226.00085 173.07441 0.00023 +v 282.41971 136.59482 0.00018 +v 292.91627 113.23576 75.57317 +v 287.66799 128.72234 54.05321 +v 290.81902 131.87335 54.05322 +v 310.23142 104.57829 22.30528 +v -89.94912 262.55324 0.00035 +v 87.96514 365.67971 -6.30157 +v 45.72071 330.25390 -8.39886 +v 117.62613 380.38111 -3.67742 +v 148.58885 381.42449 -1.31156 +v 147.27679 320.28422 -10.23783 +v 121.82061 350.46181 -6.30159 +v 106.33408 328.41495 -12.06645 +v 132.84405 362.52868 -3.67744 +v -136.65667 220.30887 -7.87211 +v -116.97564 238.15089 -14.43243 +v -91.51947 259.67088 -5.50621 +v -90.47601 257.56332 -14.43240 +v -52.42606 282.76119 -18.89546 +v -8.07406 304.79774 -23.08992 +v 42.56968 314.77773 -25.45575 +v 102.66650 313.19705 -27.55300 +v 160.65574 300.86154 -20.99268 +v 229.15186 263.60708 -12.06654 +v 264.57769 222.13747 -15.21762 +v 280.83906 194.32580 -12.33524 +v 294.22832 170.70857 -8.13046 +v 304.45626 154.17859 -9.96944 +v 302.10075 146.30619 -7.61393 +v -93.10016 251.00297 -23.08999 +v -76.30155 249.69094 -33.85514 +v -45.86573 268.32849 -30.96237 +v -7.54716 285.38534 -33.05959 +v 42.56968 296.40880 -36.99577 +v 94.79409 295.09673 -35.16715 +v 157.24643 286.95568 -29.39199 +v 225.73222 256.51985 -18.89550 +v -98.86499 237.88230 -32.80137 +v -88.36845 236.31196 -37.79136 +v -106.73739 230.53680 -28.33828 +v -123.53598 212.95303 -21.51969 +v -138.22700 198.26199 -10.49628 +v -97.29464 230.53680 -32.01621 +v -86.01293 226.07370 -36.99587 +v -140.06595 190.38959 -14.43249 +v -165.78043 158.89996 -7.61391 +v -160.53216 156.53411 -7.61392 +v -132.97872 180.41992 -15.48629 +v -144.78734 191.44335 -5.24802 +v -170.77039 154.96376 -4.19428 +v -106.47911 213.47991 -31.74761 +v -99.91876 224.50337 -31.74760 +v -107.53290 216.37268 -31.48933 +v -120.38496 208.75855 -27.29486 +v -116.97564 203.25199 -26.76797 +v -153.97182 155.49064 -8.65737 +v -129.04254 176.48374 -16.79836 +v -110.15703 191.95995 -26.76798 +v -100.97256 207.70475 -35.68383 +v -107.53290 186.19514 -28.33834 +v -77.35534 199.57408 -35.95245 +v -95.72428 213.22164 -35.95243 +v -93.61672 222.66442 -35.68381 +v -79.45258 211.64098 -39.88864 +v -150.03562 152.59792 -11.28151 +v -127.47219 171.23549 -18.89561 +v -89.68052 194.32583 -32.80143 +v -103.32808 163.88996 -17.58355 +v -66.59019 173.59100 -23.09009 +v -126.94529 167.55757 -17.84183 +v -121.43874 163.09445 -10.49632 +v -35.36918 185.39962 -36.21075 +v -37.19782 195.63790 -44.61003 +v -34.05711 226.86927 -50.91204 +v -74.98949 212.69479 -41.72759 +v -69.74123 231.06374 -41.45896 +v -68.68743 244.44269 -37.79135 +v -37.46643 251.27164 -44.08306 +v 7.41247 235.25821 -52.74066 +v -4.92302 261.24126 -47.76097 +v 52.53932 244.18443 -52.74065 +v 47.29105 263.60711 -49.59993 +v 98.98858 244.44272 -50.64341 +v 96.89134 268.85539 -47.76096 +v 154.09541 234.74164 -46.18033 +v 154.62229 262.55330 -45.39511 +v 205.26603 213.74854 -29.39209 +v 215.76257 236.83888 -34.11344 +v 237.02426 190.64790 -22.56317 +v 252.24218 211.12438 -24.14383 +v 259.58771 174.90305 -14.69079 +v 270.61114 186.19511 -14.43249 +v 271.92318 162.05101 -11.02322 +v 282.94662 169.13824 -10.23803 +v 297.63764 150.24239 -18.89564 +v 2.94937 201.41305 -42.51278 +v 54.12000 209.01684 -38.83485 +v 93.21341 211.12441 -39.36174 +v 143.07198 208.50030 -32.01624 +v 194.51120 194.58409 -17.84179 +v 229.15186 173.85961 -9.96941 +v 250.66149 165.20204 -7.34529 +v 272.45006 147.61825 -5.77497 +v 282.15113 139.21897 -12.33531 +v -8.85923 166.77247 -73.73383 +v -8.07406 169.65488 -76.09969 +v 14.75798 181.20518 -66.65691 +v 39.16037 165.46039 -79.77761 +v 3.47627 165.20213 -82.66003 +v 24.46935 162.57799 -83.44520 +v -147.41148 149.45725 -8.13049 +v -161.32765 142.10135 -4.72119 +v 308.66107 96.44769 -65.34496 +v 294.75522 115.07493 -75.57287 +v 309.97315 87.52155 -89.47874 +v 301.57384 135.54104 -17.05669 +v 307.34903 120.85003 -9.96948 +v 312.07040 111.66553 -6.03330 +v 295.79866 147.61826 -24.92908 +v -168.14628 149.45723 -3.93600 +v -166.30732 144.20894 -4.98980 +v 3.99283 162.30939 -80.82107 +v 24.72763 161.26591 -81.87485 +v 290.81902 131.87350 -54.05287 +v 287.66799 128.72249 -54.05287 +v 292.91627 113.23596 -75.57287 +v 310.23142 104.57835 -22.30501 +v -202.71629 4.05145 8.39930 +v -208.22284 4.83661 0.00001 +v -168.34426 40.78934 0.00005 +v -160.47184 39.47725 6.30211 +v -134.23049 57.31926 0.00008 +v -130.81086 54.17865 3.67799 +v -101.68710 59.68516 0.00008 +v -99.84814 55.22205 1.31214 +v -83.05987 54.69522 0.00007 +v -101.16021 -5.91822 10.23825 +v -101.68710 12.70904 0.00002 +v -90.66367 -13.00542 -0.00002 +v -142.10290 2.21245 12.06689 +v -126.61637 24.25935 6.30209 +v -115.59293 36.32624 3.67797 +v -380.28240 -74.08581 -0.00010 +v -386.44332 -81.73260 7.87230 +v -391.99954 -85.22066 -0.00011 +v -360.88654 -59.36971 -0.00008 +v -365.35245 -65.58160 14.43265 +v -338.20167 -46.24349 5.50649 +v -332.82676 -41.69326 -0.00006 +v -295.75926 -20.28685 -0.00003 +v -297.33047 -26.46976 18.89580 +v -337.33633 -48.43026 14.43268 +v -250.06667 -2.74869 -0.00000 +v -251.30594 -8.18160 23.09031 +v -205.86731 -11.42478 25.45616 +v -145.77049 -13.00546 27.55340 +v -87.78126 -25.34096 20.99304 +v -31.09289 -37.63949 12.06684 +v -31.39079 -33.25778 -0.00004 +v 10.99649 -46.55334 -0.00006 +v 10.31595 -58.67256 15.21784 +v 36.43377 -55.44978 -0.00007 +v 37.37618 -71.75347 12.33540 +v 60.69592 -65.00439 -0.00009 +v 62.59307 -80.13814 8.13058 +v 79.92756 -74.19450 -0.00010 +v 82.04545 -83.51736 9.96953 +v 92.79140 -89.36668 -0.00012 +v 86.68838 -90.33798 7.61400 +v -340.49472 -54.75075 23.09025 +v -323.86243 -57.44941 33.85540 +v -291.98778 -41.39616 30.96267 +v -252.38836 -27.57101 33.05993 +v -205.86731 -29.79374 36.99613 +v -153.64291 -31.10582 35.16750 +v -91.19055 -39.24683 29.39232 +v -31.44574 -45.48701 18.89578 +v -336.99578 -69.78319 37.79158 +v -347.32625 -67.34903 32.80159 +v -355.77983 -74.01739 28.33849 +v -373.97680 -90.14968 21.51985 +v -389.83390 -103.57370 10.49640 +v -335.49613 -80.18133 36.99606 +v -346.36956 -74.79933 32.01641 +v -392.31846 -111.26679 14.43259 +v -386.08119 -121.78911 15.48637 +v -415.51796 -143.31122 7.61393 +v -420.55216 -140.51889 7.61394 +v -425.85102 -144.02835 4.19429 +v -427.02854 -142.35474 -0.00019 +v -400.01512 -111.94383 -0.00015 +v -396.93633 -109.82565 5.24812 +v -357.74559 -88.06700 31.48950 +v -349.48429 -80.59475 31.74779 +v -356.93491 -91.03709 31.74778 +v -371.18396 -94.59070 27.29501 +v -368.24235 -100.36067 26.76811 +v -382.48444 -126.03772 16.79843 +v -409.06647 -144.89436 8.65739 +v -362.38220 -112.17857 26.76809 +v -351.92552 -97.24841 35.68397 +v -329.06270 -107.30685 35.95257 +v -360.24451 -118.14089 28.33843 +v -346.23843 -92.18507 35.95259 +v -343.35616 -82.94926 35.68399 +v -330.15350 -95.10776 39.88879 +v -381.35409 -131.39801 18.89566 +v -405.38335 -148.10310 11.28152 +v -357.90116 -140.71764 17.58358 +v -341.78013 -111.51647 32.80153 +v -320.48610 -134.09211 23.09014 +v -376.01548 -140.01067 10.49635 +v -381.13356 -135.10692 17.84187 +v -289.36905 -114.55493 44.61014 +v -288.39448 -124.90944 36.21083 +v -325.61845 -94.42715 41.72775 +v -283.65293 -83.69093 50.91223 +v -318.86712 -76.55590 41.45916 +v -316.70907 -63.31014 37.79159 +v -285.02977 -59.09002 44.08332 +v -251.77258 -51.84949 47.76125 +v -241.63106 -78.76479 52.74087 +v -201.14596 -62.59543 49.60020 +v -195.89767 -82.01815 52.74087 +v -151.54566 -57.34718 47.76124 +v -149.44842 -81.75988 50.64363 +v -93.81470 -63.64924 45.39538 +v -94.34158 -91.46092 46.18052 +v -33.03974 -67.44740 34.11366 +v -34.37822 -92.76628 29.39225 +v 6.69442 -74.46204 24.14401 +v 4.52149 -99.81760 22.56329 +v 34.88636 -84.45007 14.43263 +v 33.12358 -100.13976 14.69089 +v 55.54843 -89.20217 10.23814 +v 51.90705 -101.96728 11.02330 +v 80.40079 -91.35308 18.89572 +v -248.88150 -112.12412 42.51290 +v -194.31700 -117.18569 38.83497 +v -155.22359 -115.07814 39.36186 +v -105.36502 -117.70225 32.01636 +v -37.87756 -114.48038 17.84190 +v 6.23831 -118.28458 9.96949 +v 31.53467 -113.31566 7.34536 +v 62.82552 -112.05474 5.77501 +v 77.33899 -110.58293 12.33535 +v -262.49689 -128.20391 76.09975 +v -263.51810 -130.05745 73.73388 +v -238.78682 -121.85273 66.65698 +v -215.77203 -133.54595 79.77765 +v -230.65132 -134.63925 83.44524 +v -251.35499 -131.76502 82.66008 +v -197.99490 -130.82288 -0.00017 +v -247.61380 -128.55718 -0.00017 +v -107.72054 -128.99427 -0.00017 +v -32.68514 -117.44504 -0.00016 +v 29.86724 -117.64511 -0.00016 +v 64.17918 -113.73506 -0.00015 +v -315.99826 -137.09818 -0.00018 +v -279.55988 -132.74477 -0.00018 +v -350.03796 -144.27370 -0.00019 +v -373.30633 -142.34023 -0.00019 +v -400.00701 -153.01794 -0.00020 +v -403.02831 -151.45029 8.13048 +v -420.04830 -159.78089 -0.00021 +v -417.50577 -157.62852 4.72117 +v 145.17573 -114.86977 89.47871 +v 107.78645 -115.14030 75.57286 +v 135.51375 -112.07570 65.34494 +v 111.95905 -100.84556 9.96951 +v 95.16476 -97.36089 17.05675 +v 103.48855 -97.52264 -0.00013 +v 123.55499 -101.41847 6.03331 +v 114.15189 -101.14615 -0.00013 +v 81.14748 -94.47977 24.92915 +v -423.69190 -149.73328 3.93600 +v -424.19559 -149.43224 -0.00020 +v -422.29384 -155.11581 4.98978 +v -424.19240 -155.75629 -0.00021 +v -230.50253 -135.51663 81.87489 +v -251.07977 -133.69650 80.82110 +v -91.97574 34.22897 0.00005 +v -79.90885 46.30619 0.00006 +v -153.38463 -127.15527 -0.00017 +v 3.59861 -120.57324 -0.00016 +v 79.65890 -112.11184 -0.00015 +v 107.98807 -117.79920 75.57286 +v 90.36504 -112.97680 54.05289 +v 90.20912 -108.43933 54.05290 +v 128.88226 -106.66257 22.30500 +v -336.39801 -43.50104 -0.00006 +v -160.47184 39.47726 -6.30200 +v -202.71629 4.05147 -8.39929 +v -130.81086 54.17866 -3.67785 +v -99.84814 55.22205 -1.31199 +v -101.16021 -5.91820 -10.23826 +v -126.61637 24.25937 -6.30202 +v -142.10290 2.21249 -12.06688 +v -115.59293 36.32625 -3.67787 +v -386.44332 -81.73259 -7.87251 +v -365.35245 -65.58155 -14.43283 +v -338.20167 -46.24347 -5.50661 +v -337.33633 -48.43023 -14.43281 +v -297.33047 -26.46971 -18.89587 +v -251.30594 -8.18154 -23.09033 +v -205.86731 -11.42471 -25.45619 +v -145.77049 -13.00539 -27.55343 +v -87.78126 -25.34090 -20.99311 +v -31.09289 -37.63946 -12.06694 +v 10.31595 -58.67252 -15.21799 +v 37.37618 -71.75344 -12.33559 +v 62.59307 -80.13812 -8.13079 +v 82.04545 -83.51733 -9.96976 +v 86.68838 -90.33796 -7.61424 +v -340.49472 -54.75069 -23.09039 +v -323.86243 -57.44932 -33.85555 +v -291.98778 -41.39608 -30.96278 +v -252.38836 -27.57092 -33.06000 +v -205.86731 -29.79364 -36.99621 +v -153.64291 -31.10573 -35.16758 +v -91.19055 -39.24676 -29.39243 +v -31.44574 -45.48696 -18.89590 +v -347.32625 -67.34894 -32.80177 +v -336.99578 -69.78308 -37.79177 +v -355.77983 -74.01732 -28.33869 +v -373.97680 -90.14962 -21.52009 +v -389.83390 -103.57367 -10.49668 +v -346.36956 -74.79924 -32.01661 +v -335.49613 -80.18123 -36.99628 +v -392.31846 -111.26675 -14.43289 +v -420.55216 -140.51886 -7.61431 +v -415.51796 -143.31119 -7.61431 +v -386.08119 -121.78906 -15.48669 +v -396.93633 -109.82563 -5.24842 +v -425.85102 -144.02835 -4.19467 +v -356.93491 -91.03701 -31.74802 +v -349.48429 -80.59466 -31.74800 +v -357.74559 -88.06691 -31.48973 +v -371.18396 -94.59063 -27.29526 +v -368.24235 -100.36059 -26.76837 +v -409.06647 -144.89433 -8.65777 +v -382.48444 -126.03769 -16.79876 +v -362.38220 -112.17850 -26.76839 +v -351.92552 -97.24832 -35.68423 +v -360.24451 -118.14082 -28.33875 +v -329.06270 -107.30676 -35.95285 +v -346.23843 -92.18498 -35.95284 +v -343.35616 -82.94917 -35.68421 +v -330.15350 -95.10765 -39.88904 +v -405.38335 -148.10307 -11.28191 +v -381.35409 -131.39795 -18.89601 +v -341.78013 -111.51638 -32.80183 +v -357.90116 -140.71758 -17.58396 +v -320.48610 -134.09205 -23.09050 +v -381.13356 -135.10686 -17.84223 +v -376.01548 -140.01064 -10.49672 +v -288.39448 -124.90935 -36.21116 +v -289.36905 -114.55481 -44.61044 +v -283.65293 -83.69079 -50.91245 +v -325.61845 -94.42704 -41.72800 +v -318.86712 -76.55580 -41.45936 +v -316.70907 -63.31003 -37.79176 +v -285.02977 -59.08990 -44.08347 +v -241.63106 -78.76465 -52.74108 +v -251.77258 -51.84936 -47.76138 +v -195.89767 -82.01802 -52.74108 +v -201.14596 -62.59530 -49.60036 +v -149.44842 -81.75974 -50.64384 +v -151.54566 -57.34705 -47.76139 +v -94.34158 -91.46080 -46.18076 +v -93.81470 -63.64912 -45.39555 +v -34.37822 -92.76621 -29.39250 +v -33.03974 -67.44731 -34.11384 +v 4.52149 -99.81754 -22.56356 +v 6.69442 -74.46198 -24.14421 +v 33.12358 -100.13971 -14.69116 +v 34.88636 -84.45003 -14.43285 +v 51.90705 -101.96725 -11.02357 +v 55.54843 -89.20214 -10.23838 +v 80.40079 -91.35304 -18.89596 +v -248.88150 -112.12400 -42.51320 +v -194.31700 -117.18559 -38.83529 +v -155.22359 -115.07803 -39.36217 +v -105.36502 -117.70216 -32.01667 +v -37.87756 -114.48033 -17.84220 +v 6.23831 -118.28455 -9.96980 +v 31.53467 -113.31564 -7.34566 +v 62.82552 -112.05472 -5.77531 +v 77.33899 -110.58290 -12.33565 +v -263.51810 -130.05725 -73.73422 +v -262.49689 -128.20370 -76.10009 +v -238.78682 -121.85255 -66.65731 +v -215.77203 -133.54574 -79.77801 +v -251.35499 -131.76481 -82.66042 +v -230.65132 -134.63904 -83.44559 +v -403.02831 -151.45026 -8.13089 +v -417.50577 -157.62852 -4.72159 +v 135.51375 -112.07552 -65.34524 +v 107.78645 -115.14011 -75.57318 +v 145.17573 -114.86953 -89.47901 +v 95.16476 -97.36085 -17.05700 +v 111.95905 -100.84553 -9.96978 +v 123.55499 -101.41846 -6.03358 +v 81.14748 -94.47971 -24.92940 +v -423.69190 -149.73328 -3.93640 +v -422.29384 -155.11581 -4.99019 +v -251.07977 -133.69629 -80.82146 +v -230.50253 -135.51642 -81.87525 +v 90.20912 -108.43918 -54.05319 +v 90.36504 -112.97665 -54.05319 +v 107.98807 -117.79901 -75.57318 +v 128.88226 -106.66251 -22.30529 +v 93.99940 -251.01325 8.39896 +v 88.49286 -250.22811 -0.00033 +v 128.37143 -214.27538 -0.00028 +v 136.24384 -215.58747 6.30177 +v 162.48520 -197.74546 -0.00026 +v 165.90483 -200.88606 3.67765 +v 195.02860 -195.37956 -0.00026 +v 196.86754 -199.84266 1.31180 +v 213.65581 -200.36949 -0.00027 +v 195.55548 -260.98293 10.23791 +v 195.02860 -242.35567 -0.00032 +v 206.05202 -268.07013 -0.00036 +v 154.61278 -252.85226 12.06655 +v 170.09930 -230.80537 6.30175 +v 181.12274 -218.73847 3.67763 +v -81.06457 -300.66425 -0.00040 +v -88.78847 -306.67168 7.87200 +v -95.01029 -308.72506 -0.00041 +v -59.30696 -290.47790 -0.00039 +v -64.86207 -295.63197 14.43235 +v -35.26598 -281.90029 5.50618 +v -29.40112 -278.35038 -0.00037 +v 8.45369 -262.68244 -0.00035 +v 6.19893 -268.61122 18.89548 +v -34.83292 -284.20424 14.43236 +v 52.39871 -249.89958 -0.00033 +v 50.84696 -255.21874 23.08998 +v 90.84838 -266.48948 25.45582 +v 150.94519 -268.07016 27.55306 +v 208.93443 -280.40567 20.99271 +v 258.30457 -283.44262 12.06651 +v 257.31510 -279.18223 -0.00037 +v 294.19634 -281.39371 -0.00037 +v 298.14175 -292.82492 15.21753 +v 317.46763 -279.18425 -0.00037 +v 326.18260 -292.81196 12.33511 +v 340.31105 -274.64417 -0.00036 +v 350.63425 -285.51456 8.13031 +v 359.25335 -269.80183 -0.00036 +v 366.83893 -275.15960 9.96928 +v 378.09575 -271.42754 -0.00036 +v 374.67644 -276.66983 7.61376 +v -38.96789 -289.85876 23.08994 +v -23.49540 -295.37284 33.85508 +v 9.33527 -284.09457 30.96235 +v 48.31438 -274.45754 33.05960 +v 90.84838 -284.85847 36.99579 +v 143.07278 -286.17054 35.16716 +v 205.52513 -294.31152 29.39198 +v 259.39310 -291.21229 18.89545 +v -38.31227 -305.27192 37.79127 +v -47.87081 -300.96841 32.80129 +v -57.36535 -305.85158 28.33818 +v -78.57035 -317.73791 21.51955 +v -97.36509 -327.05557 10.49611 +v -38.71889 -315.76946 36.99575 +v -48.36608 -308.46316 32.01610 +v -101.73644 -333.89530 14.43230 +v -98.06335 -345.64888 15.48607 +v -133.70489 -358.57388 7.61365 +v -138.05124 -354.43836 7.61365 +v -144.47005 -356.23577 4.19401 +v -145.17748 -354.28199 -0.00047 +v -109.58333 -332.58528 -0.00044 +v -105.97645 -331.33015 5.24783 +v -62.15228 -319.20549 31.48919 +v -52.53142 -313.54681 31.74748 +v -61.96433 -322.27916 31.74747 +v -76.81173 -322.69251 27.29471 +v -75.17189 -328.97359 26.76780 +v -95.44338 -350.65499 16.79813 +v -127.52579 -361.92381 8.65710 +v -71.87407 -341.79482 26.76779 +v -58.25461 -329.38397 35.68367 +v -37.14569 -343.61330 35.95226 +v -70.99153 -348.08293 28.33813 +v -51.58934 -325.54856 35.95228 +v -46.96583 -317.03731 35.68368 +v -36.08085 -331.41154 39.88848 +v -95.58270 -356.13570 18.89536 +v -124.60607 -366.03838 11.28123 +v -73.45205 -370.64976 17.58328 +v -50.85280 -345.38397 32.80123 +v -32.99331 -371.50303 23.08983 +v -92.14051 -365.79731 10.49605 +v -96.25251 -359.79119 17.84157 +v 2.43018 -356.97418 44.60982 +v 2.05272 -367.36822 36.21050 +v -31.41700 -331.53304 41.72743 +v 12.21421 -327.09467 50.91191 +v -21.73452 -315.03382 41.45885 +v -17.52141 -302.29929 37.79127 +v 13.85211 -302.50973 44.08299 +v 46.92536 -298.70307 47.76092 +v 54.81669 -326.33492 52.74054 +v 95.56974 -317.66015 49.59986 +v 100.81802 -337.08286 52.74053 +v 145.17002 -312.41187 47.76090 +v 147.26728 -336.82460 50.64329 +v 202.90099 -318.71393 45.39504 +v 202.37410 -346.52561 46.18018 +v 261.93878 -313.06806 34.11333 +v 265.35967 -338.19771 29.39193 +v 300.93679 -308.74965 24.14370 +v 308.59086 -333.04185 22.56298 +v 330.49938 -304.99727 14.43234 +v 336.97408 -319.41187 14.69060 +v 350.53504 -297.09294 10.23786 +v 355.05557 -309.63799 11.02302 +v 370.95693 -281.99202 18.89546 +v 44.70988 -359.00652 42.51257 +v 102.39870 -372.25041 38.83464 +v 141.49211 -370.14285 39.36153 +v 191.35067 -372.76694 32.01602 +v 265.51765 -360.24252 17.84157 +v 317.93487 -349.25774 9.96918 +v 342.35424 -331.59325 7.34507 +v 370.84159 -310.07600 5.77475 +v 381.84530 -298.11019 12.33510 +v 28.89168 -361.85995 76.09944 +v 27.61571 -363.59668 73.73357 +v 54.47518 -357.65219 66.65667 +v 78.15071 -370.73794 79.77734 +v 62.17428 -370.98047 83.44492 +v 40.34184 -366.48944 82.65977 +v 98.72077 -385.88759 -0.00051 +v 44.60053 -375.48837 -0.00050 +v 188.99515 -384.05898 -0.00051 +v 272.35380 -362.03855 -0.00048 +v 342.95446 -336.27528 -0.00045 +v 373.10812 -310.36770 -0.00041 +v -28.78862 -375.23565 -0.00050 +v 10.33007 -376.28388 -0.00050 +v -65.97063 -375.81852 -0.00050 +v -89.87661 -368.71034 -0.00049 +v -120.35207 -372.25127 -0.00049 +v -123.07309 -369.91337 8.13019 +v -143.09712 -373.04825 -0.00049 +v -139.83206 -371.73662 4.72088 +v 427.02854 -240.19788 89.47854 +v 407.08911 -275.63509 75.57265 +v 420.25936 -248.23506 65.34476 +v 398.57063 -263.36142 9.96930 +v 385.39526 -274.98233 17.05651 +v 390.89349 -268.38532 -0.00036 +v 405.53746 -253.59112 6.03311 +v 400.08771 -261.65968 -0.00035 +v 373.62060 -283.69701 24.92890 +v -143.93197 -362.34054 3.93572 +v -144.36097 -361.90197 -0.00048 +v -144.06516 -367.91119 4.98950 +v -146.21551 -367.95524 -0.00049 +v 62.27292 -371.86587 81.87458 +v 40.45544 -368.43809 80.82079 +v 204.73994 -220.83575 -0.00029 +v 216.80684 -208.75852 -0.00028 +v 143.33108 -382.21997 -0.00051 +v 315.91809 -352.56323 -0.00047 +v 384.73922 -297.38295 -0.00039 +v 409.30533 -277.05216 75.57265 +v 393.46552 -289.30265 54.05266 +v 390.02597 -286.38589 54.05266 +v 412.52294 -251.64774 22.30481 +v -33.08011 -279.51699 -0.00037 +v 136.24384 -215.58744 -6.30234 +v 93.99940 -251.01325 -8.39963 +v 165.90483 -200.88606 -3.67819 +v 196.86754 -199.84266 -1.31233 +v 195.55548 -260.98293 -10.23860 +v 170.09930 -230.80534 -6.30236 +v 154.61278 -252.85220 -12.06722 +v 181.12274 -218.73847 -3.67821 +v -88.78847 -306.67168 -7.87281 +v -64.86207 -295.63192 -14.43313 +v -35.26598 -281.90029 -5.50692 +v -34.83292 -284.20419 -14.43312 +v 6.19893 -268.61116 -18.89619 +v 50.84696 -255.21868 -23.09066 +v 90.84838 -266.48942 -25.45653 +v 150.94519 -268.07010 -27.55377 +v 208.93443 -280.40561 -20.99345 +v 258.30457 -283.44256 -12.06726 +v 298.14175 -292.82486 -15.21830 +v 326.18260 -292.81190 -12.33589 +v 350.63425 -285.51456 -8.13106 +v 366.83893 -275.15960 -9.97001 +v 374.67644 -276.66983 -7.61449 +v -38.96789 -289.85870 -23.09070 +v -23.49540 -295.37272 -33.85586 +v 9.33527 -284.09451 -30.96310 +v 48.31438 -274.45748 -33.06033 +v 90.84838 -284.85835 -36.99654 +v 143.07278 -286.17042 -35.16792 +v 205.52513 -294.31146 -29.39277 +v 259.39310 -291.21223 -18.89622 +v -47.87081 -300.96835 -32.80208 +v -38.31227 -305.27180 -37.79208 +v -57.36535 -305.85152 -28.33899 +v -78.57035 -317.73785 -21.52039 +v -97.36509 -327.05557 -10.49697 +v -48.36608 -308.46310 -32.01692 +v -38.71889 -315.76934 -36.99658 +v -101.73644 -333.89524 -14.43318 +v -138.05124 -354.43836 -7.61459 +v -133.70489 -358.57388 -7.61460 +v -98.06335 -345.64883 -15.48699 +v -105.97645 -331.33015 -5.24871 +v -144.47005 -356.23577 -4.19496 +v -61.96433 -322.27910 -31.74832 +v -52.53142 -313.54675 -31.74831 +v -62.15228 -319.20543 -31.49004 +v -76.81173 -322.69245 -27.29556 +v -75.17189 -328.97353 -26.76868 +v -127.52579 -361.92381 -8.65806 +v -95.44338 -350.65493 -16.79906 +v -71.87407 -341.79476 -26.76869 +v -58.25461 -329.38385 -35.68454 +v -70.99153 -348.08287 -28.33905 +v -37.14569 -343.61318 -35.95317 +v -51.58934 -325.54844 -35.95315 +v -46.96583 -317.03719 -35.68452 +v -36.08085 -331.41142 -39.88935 +v -124.60607 -366.03832 -11.28220 +v -95.58270 -356.13564 -18.89631 +v -50.85280 -345.38391 -32.80214 +v -73.45205 -370.64970 -17.58426 +v -32.99331 -371.50297 -23.09081 +v -96.25251 -359.79113 -17.84253 +v -92.14051 -365.79731 -10.49702 +v 2.05272 -367.36810 -36.21148 +v 2.43018 -356.97407 -44.61076 +v 12.21421 -327.09455 -50.91278 +v -31.41700 -331.53293 -41.72831 +v -21.73452 -315.03370 -41.45968 +v -17.52141 -302.29917 -37.79208 +v 13.85211 -302.50961 -44.08380 +v 54.81669 -326.33480 -52.74141 +v 46.92536 -298.70296 -47.76171 +v 100.81802 -337.08274 -52.74142 +v 95.56974 -317.66003 -49.60070 +v 147.26728 -336.82448 -50.64418 +v 145.17002 -312.41176 -47.76173 +v 202.37410 -346.52549 -46.18110 +v 202.90099 -318.71381 -45.39589 +v 265.35967 -338.19765 -29.39282 +v 261.93878 -313.06794 -34.11417 +v 308.59086 -333.04179 -22.56387 +v 300.93679 -308.74959 -24.14452 +v 336.97408 -319.41181 -14.69145 +v 330.49938 -304.99721 -14.43315 +v 355.05557 -309.63799 -11.02384 +v 350.53504 -297.09294 -10.23865 +v 370.95693 -281.99196 -18.89621 +v 44.70988 -359.00640 -42.51353 +v 102.39870 -372.25029 -38.83563 +v 141.49211 -370.14273 -39.36251 +v 191.35067 -372.76688 -32.01701 +v 265.51765 -360.24246 -17.84253 +v 317.93487 -349.25774 -9.97011 +v 342.35424 -331.59325 -7.34595 +v 370.84159 -310.07600 -5.77557 +v 381.84530 -298.11013 -12.33589 +v 27.61571 -363.59650 -73.73454 +v 28.89168 -361.85977 -76.10039 +v 54.47518 -357.65201 -66.65763 +v 78.15071 -370.73770 -79.77832 +v 40.34184 -366.48920 -82.66073 +v 62.17428 -370.98023 -83.44591 +v -123.07309 -369.91337 -8.13118 +v -139.83206 -371.73662 -4.72187 +v 420.25936 -248.23488 -65.34541 +v 407.08911 -275.63491 -75.57338 +v 427.02854 -240.19764 -89.47918 +v 385.39526 -274.98227 -17.05724 +v 398.57063 -263.36142 -9.96999 +v 405.53746 -253.59112 -6.03378 +v 373.62060 -283.69695 -24.92966 +v -143.93197 -362.34054 -3.93668 +v -144.06516 -367.91119 -4.99048 +v 40.45544 -368.43786 -80.82177 +v 62.27292 -371.86563 -81.87556 +v 390.02597 -286.38577 -54.05342 +v 393.46552 -289.30253 -54.05343 +v 409.30533 -277.05199 -75.57338 +v 412.52294 -251.64768 -22.30548 + +g dolph01 +usemtl dolph01 +f 3 2 1 +f 1 4 3 +f 5 3 4 +f 4 6 5 +f 7 5 6 +f 6 8 7 +f 9 7 8 +f 12 11 10 +f 4 1 13 +f 13 14 4 +f 6 4 14 +f 14 15 6 +f 8 6 15 +f 18 17 16 +f 19 16 17 +f 17 20 19 +f 23 22 21 +f 21 24 23 +f 24 21 25 +f 26 23 24 +f 24 27 26 +f 2 26 27 +f 27 1 2 +f 28 1 27 +f 13 1 28 +f 28 29 13 +f 10 13 29 +f 29 30 10 +f 12 10 30 +f 12 30 31 +f 31 32 12 +f 33 32 31 +f 31 34 33 +f 35 33 34 +f 34 36 35 +f 37 35 36 +f 36 38 37 +f 39 37 38 +f 38 40 39 +f 41 39 40 +f 40 42 41 +f 25 20 43 +f 25 43 44 +f 25 44 45 +f 45 24 25 +f 27 24 45 +f 45 46 27 +f 28 27 46 +f 46 47 28 +f 29 28 47 +f 47 48 29 +f 30 29 48 +f 48 49 30 +f 31 30 49 +f 49 50 31 +f 34 31 50 +f 52 51 44 +f 44 43 52 +f 53 52 43 +f 43 20 53 +f 54 53 20 +f 20 17 54 +f 55 54 17 +f 57 56 51 +f 51 52 57 +f 53 57 52 +f 55 58 54 +f 61 60 59 +f 59 58 61 +f 64 63 62 +f 62 65 64 +f 65 55 17 +f 17 18 65 +f 64 65 18 +f 67 53 66 +f 66 68 67 +f 53 54 69 +f 69 66 53 +f 68 66 69 +f 69 70 68 +f 70 69 58 +f 58 59 70 +f 71 59 60 +f 60 72 71 +f 70 59 71 +f 71 73 70 +f 74 68 70 +f 75 74 73 +f 73 76 75 +f 58 55 65 +f 67 68 77 +f 78 67 77 +f 56 78 77 +f 79 56 77 +f 74 79 77 +f 68 74 77 +f 72 81 80 +f 80 71 72 +f 71 80 76 +f 76 73 71 +f 83 76 82 +f 82 75 83 +f 75 82 84 +f 85 82 76 +f 76 86 85 +f 87 75 84 +f 84 88 87 +f 89 75 87 +f 87 90 89 +f 89 79 75 +f 56 79 89 +f 89 91 56 +f 44 51 56 +f 56 92 44 +f 92 56 91 +f 93 91 89 +f 89 90 93 +f 94 93 90 +f 90 95 94 +f 96 94 95 +f 95 97 96 +f 98 96 97 +f 97 99 98 +f 100 98 99 +f 99 101 100 +f 102 100 101 +f 101 103 102 +f 104 102 103 +f 103 105 104 +f 106 104 105 +f 105 107 106 +f 108 106 107 +f 107 109 108 +f 92 91 93 +f 45 92 93 +f 44 92 45 +f 46 45 93 +f 93 94 46 +f 47 46 94 +f 94 96 47 +f 48 47 96 +f 96 98 48 +f 49 48 98 +f 98 100 49 +f 50 49 100 +f 100 102 50 +f 34 50 102 +f 102 104 34 +f 36 34 104 +f 104 106 36 +f 38 36 106 +f 106 108 38 +f 40 38 108 +f 108 110 40 +f 42 40 110 +f 95 90 87 +f 87 111 95 +f 97 95 111 +f 111 112 97 +f 99 97 112 +f 112 113 99 +f 101 99 113 +f 113 114 101 +f 103 101 114 +f 114 115 103 +f 105 103 115 +f 115 116 105 +f 107 105 116 +f 116 117 107 +f 109 107 117 +f 117 118 109 +f 119 109 118 +f 120 87 88 +f 88 121 120 +f 111 87 120 +f 120 122 111 +f 123 122 120 +f 120 124 123 +f 124 120 125 +f 126 112 111 +f 111 127 126 +f 115 114 128 +f 128 129 115 +f 118 117 130 +f 130 131 118 +f 88 84 132 +f 132 133 88 +f 111 88 133 +f 133 127 111 +f 84 82 134 +f 134 132 84 +f 82 85 135 +f 135 134 82 +f 85 137 136 +f 136 135 85 +f 85 86 137 +f 139 138 136 +f 136 137 139 +f 142 141 140 +f 42 144 143 +f 143 145 42 +f 145 143 146 +f 146 147 145 +f 148 110 108 +f 108 109 148 +f 119 148 109 +f 61 58 65 +f 65 62 61 +f 150 149 62 +f 62 63 150 +f 61 62 149 +f 149 60 61 +f 76 80 86 +f 81 137 86 +f 86 80 81 +f 137 81 139 +f 151 139 81 +f 81 72 151 +f 149 151 72 +f 72 60 149 +f 138 139 151 +f 151 152 138 +f 149 150 152 +f 152 151 149 +f 57 53 67 +f 78 56 57 +f 75 79 74 +f 58 69 54 +f 67 78 57 +f 154 153 124 +f 124 125 154 +f 125 120 121 +f 121 154 125 +f 123 124 153 +f 122 121 88 +f 88 111 122 +f 123 153 154 +f 154 122 123 +f 122 154 121 +f 11 14 13 +f 13 10 11 +f 11 155 15 +f 15 14 11 +f 155 156 9 +f 9 15 155 +f 15 9 8 +f 114 113 157 +f 157 128 114 +f 157 113 112 +f 112 126 157 +f 130 117 116 +f 116 158 130 +f 129 158 116 +f 116 115 129 +f 118 131 159 +f 159 119 118 +f 161 160 141 +f 141 162 161 +f 162 148 119 +f 119 161 162 +f 140 141 160 +f 42 145 41 +f 119 159 147 +f 147 146 163 +f 163 119 147 +f 119 163 161 +f 163 142 160 +f 160 161 163 +f 160 142 140 +f 141 142 163 +f 163 162 141 +f 163 146 143 +f 143 162 163 +f 162 143 144 +f 162 144 148 +f 144 42 110 +f 110 148 144 +f 22 164 21 +f 20 21 164 +f 164 19 20 +f 20 25 21 +f 2 3 165 +f 165 166 2 +f 3 5 167 +f 167 165 3 +f 5 7 168 +f 168 167 5 +f 168 7 9 +f 169 11 12 +f 166 165 170 +f 170 171 166 +f 165 167 172 +f 172 170 165 +f 172 167 168 +f 16 173 18 +f 16 19 174 +f 174 173 16 +f 175 22 23 +f 23 176 175 +f 176 23 177 +f 23 26 178 +f 178 177 23 +f 26 2 166 +f 166 178 26 +f 178 166 179 +f 166 171 180 +f 180 179 166 +f 171 169 181 +f 181 180 171 +f 181 169 12 +f 181 12 32 +f 32 182 181 +f 32 33 183 +f 183 182 32 +f 33 35 184 +f 184 183 33 +f 35 37 185 +f 185 184 35 +f 37 39 186 +f 186 185 37 +f 39 41 187 +f 187 186 39 +f 188 174 176 +f 189 188 176 +f 189 176 177 +f 177 190 189 +f 177 178 191 +f 191 190 177 +f 178 179 192 +f 192 191 178 +f 179 180 193 +f 193 192 179 +f 180 181 194 +f 194 193 180 +f 181 182 195 +f 195 194 181 +f 195 182 183 +f 197 196 188 +f 188 189 197 +f 196 198 174 +f 174 188 196 +f 174 198 199 +f 199 173 174 +f 173 199 200 +f 202 201 196 +f 196 197 202 +f 196 201 198 +f 199 203 200 +f 205 204 203 +f 203 206 205 +f 63 64 207 +f 207 208 63 +f 200 207 18 +f 18 173 200 +f 18 207 64 +f 198 210 209 +f 209 211 198 +f 199 198 211 +f 211 212 199 +f 211 209 213 +f 213 212 211 +f 212 213 206 +f 206 203 212 +f 206 215 214 +f 214 205 206 +f 206 213 216 +f 216 215 206 +f 213 209 217 +f 217 219 218 +f 218 216 217 +f 207 200 203 +f 220 209 210 +f 220 210 221 +f 220 221 202 +f 220 202 222 +f 220 222 217 +f 220 217 209 +f 223 214 215 +f 215 224 223 +f 224 215 216 +f 216 218 224 +f 226 218 225 +f 225 227 226 +f 227 225 219 +f 226 229 228 +f 228 218 226 +f 219 231 230 +f 230 227 219 +f 219 233 232 +f 232 231 219 +f 219 222 233 +f 222 202 234 +f 234 233 222 +f 202 197 189 +f 189 234 202 +f 234 189 235 +f 234 236 232 +f 232 233 234 +f 236 238 237 +f 237 232 236 +f 238 240 239 +f 239 237 238 +f 240 242 241 +f 241 239 240 +f 242 244 243 +f 243 241 242 +f 244 246 245 +f 245 243 244 +f 246 248 247 +f 247 245 246 +f 248 250 249 +f 249 247 248 +f 250 252 251 +f 251 249 250 +f 236 234 235 +f 236 235 190 +f 190 235 189 +f 190 191 238 +f 238 236 190 +f 191 192 240 +f 240 238 191 +f 192 193 242 +f 242 240 192 +f 193 194 244 +f 244 242 193 +f 194 195 246 +f 246 244 194 +f 195 183 248 +f 248 246 195 +f 183 184 250 +f 250 248 183 +f 184 185 252 +f 252 250 184 +f 185 186 253 +f 253 252 185 +f 253 186 187 +f 232 237 254 +f 254 231 232 +f 237 239 255 +f 255 254 237 +f 239 241 256 +f 256 255 239 +f 241 243 257 +f 257 256 241 +f 243 245 258 +f 258 257 243 +f 245 247 259 +f 259 258 245 +f 247 249 260 +f 260 259 247 +f 249 251 261 +f 261 260 249 +f 261 251 262 +f 231 264 263 +f 263 230 231 +f 231 254 265 +f 265 264 231 +f 264 265 266 +f 266 267 264 +f 267 266 268 +f 255 126 127 +f 127 254 255 +f 257 258 129 +f 129 128 257 +f 260 261 131 +f 131 130 260 +f 227 230 133 +f 133 132 227 +f 230 254 127 +f 127 133 230 +f 226 227 132 +f 132 134 226 +f 229 226 134 +f 134 135 229 +f 269 229 135 +f 135 136 269 +f 269 228 229 +f 138 270 269 +f 269 136 138 +f 273 272 271 +f 274 187 145 +f 145 275 274 +f 275 145 147 +f 147 276 275 +f 253 277 251 +f 251 252 253 +f 251 277 262 +f 203 204 208 +f 208 207 203 +f 278 150 63 +f 63 208 278 +f 208 204 205 +f 205 278 208 +f 228 224 218 +f 269 223 224 +f 224 228 269 +f 270 223 269 +f 270 279 214 +f 214 223 270 +f 279 278 205 +f 205 214 279 +f 270 138 152 +f 152 279 270 +f 150 278 279 +f 279 152 150 +f 210 198 201 +f 201 202 221 +f 217 222 219 +f 199 212 203 +f 201 221 210 +f 281 280 267 +f 267 268 281 +f 264 267 280 +f 280 263 264 +f 281 268 266 +f 263 265 254 +f 254 230 263 +f 280 281 266 +f 266 263 280 +f 263 266 265 +f 170 11 169 +f 169 171 170 +f 155 11 170 +f 170 172 155 +f 9 156 155 +f 155 168 9 +f 168 155 172 +f 256 257 128 +f 128 157 256 +f 256 157 126 +f 126 255 256 +f 260 130 158 +f 158 259 260 +f 158 129 258 +f 258 259 158 +f 131 261 262 +f 262 159 131 +f 284 283 282 +f 282 272 284 +f 277 282 283 +f 283 262 277 +f 284 272 273 +f 41 145 187 +f 147 159 262 +f 285 276 147 +f 147 283 285 +f 283 147 262 +f 271 285 283 +f 283 284 271 +f 273 271 284 +f 271 272 282 +f 282 285 271 +f 276 285 282 +f 282 275 276 +f 274 275 282 +f 277 274 282 +f 187 274 277 +f 277 253 187 +f 175 164 22 +f 175 174 19 +f 19 164 175 +f 175 176 174 +f 217 216 213 +f 70 73 74 + +g dolph02 +usemtl dolph02 +f 288 287 286 +f 286 289 288 +f 290 288 289 +f 289 291 290 +f 292 290 291 +f 291 293 292 +f 294 292 293 +f 297 296 295 +f 289 286 298 +f 298 299 289 +f 291 289 299 +f 299 300 291 +f 293 291 300 +f 303 302 301 +f 304 301 302 +f 302 305 304 +f 308 307 306 +f 306 309 308 +f 309 306 310 +f 311 308 309 +f 309 312 311 +f 287 311 312 +f 312 286 287 +f 313 286 312 +f 298 286 313 +f 313 314 298 +f 295 298 314 +f 314 315 295 +f 297 295 315 +f 297 315 316 +f 316 317 297 +f 318 317 316 +f 316 319 318 +f 320 318 319 +f 319 321 320 +f 322 320 321 +f 321 323 322 +f 324 322 323 +f 323 325 324 +f 326 324 325 +f 325 327 326 +f 310 305 328 +f 310 328 329 +f 310 329 330 +f 330 309 310 +f 312 309 330 +f 330 331 312 +f 313 312 331 +f 331 332 313 +f 314 313 332 +f 332 333 314 +f 315 314 333 +f 333 334 315 +f 316 315 334 +f 334 335 316 +f 319 316 335 +f 337 336 329 +f 329 328 337 +f 338 337 328 +f 328 305 338 +f 339 338 305 +f 305 302 339 +f 340 339 302 +f 342 341 336 +f 336 337 342 +f 338 342 337 +f 340 343 339 +f 346 345 344 +f 344 343 346 +f 349 348 347 +f 347 350 349 +f 350 340 302 +f 302 303 350 +f 349 350 303 +f 352 338 351 +f 351 353 352 +f 338 339 354 +f 354 351 338 +f 353 351 354 +f 354 355 353 +f 355 354 343 +f 343 344 355 +f 356 344 345 +f 345 357 356 +f 355 344 356 +f 356 358 355 +f 359 353 355 +f 360 359 358 +f 358 361 360 +f 343 340 350 +f 352 353 362 +f 363 352 362 +f 341 363 362 +f 364 341 362 +f 359 364 362 +f 353 359 362 +f 357 366 365 +f 365 356 357 +f 356 365 361 +f 361 358 356 +f 368 361 367 +f 367 360 368 +f 360 367 369 +f 370 367 361 +f 361 371 370 +f 372 360 369 +f 369 373 372 +f 374 360 372 +f 372 375 374 +f 374 364 360 +f 341 364 374 +f 374 376 341 +f 329 336 341 +f 341 377 329 +f 377 341 376 +f 378 376 374 +f 374 375 378 +f 379 378 375 +f 375 380 379 +f 381 379 380 +f 380 382 381 +f 383 381 382 +f 382 384 383 +f 385 383 384 +f 384 386 385 +f 387 385 386 +f 386 388 387 +f 389 387 388 +f 388 390 389 +f 391 389 390 +f 390 392 391 +f 393 391 392 +f 392 394 393 +f 377 376 378 +f 330 377 378 +f 329 377 330 +f 331 330 378 +f 378 379 331 +f 332 331 379 +f 379 381 332 +f 333 332 381 +f 381 383 333 +f 334 333 383 +f 383 385 334 +f 335 334 385 +f 385 387 335 +f 319 335 387 +f 387 389 319 +f 321 319 389 +f 389 391 321 +f 323 321 391 +f 391 393 323 +f 325 323 393 +f 393 395 325 +f 327 325 395 +f 380 375 372 +f 372 396 380 +f 382 380 396 +f 396 397 382 +f 384 382 397 +f 397 398 384 +f 386 384 398 +f 398 399 386 +f 388 386 399 +f 399 400 388 +f 390 388 400 +f 400 401 390 +f 392 390 401 +f 401 402 392 +f 394 392 402 +f 402 403 394 +f 404 394 403 +f 405 372 373 +f 373 406 405 +f 396 372 405 +f 405 407 396 +f 408 407 405 +f 405 409 408 +f 409 405 410 +f 411 397 396 +f 396 412 411 +f 400 399 413 +f 413 414 400 +f 403 402 415 +f 415 416 403 +f 373 369 417 +f 417 418 373 +f 396 373 418 +f 418 412 396 +f 369 367 419 +f 419 417 369 +f 367 370 420 +f 420 419 367 +f 370 422 421 +f 421 420 370 +f 370 371 422 +f 424 423 421 +f 421 422 424 +f 427 426 425 +f 327 429 428 +f 428 430 327 +f 430 428 431 +f 431 432 430 +f 433 395 393 +f 393 394 433 +f 404 433 394 +f 346 343 350 +f 350 347 346 +f 435 434 347 +f 347 348 435 +f 346 347 434 +f 434 345 346 +f 361 365 371 +f 366 422 371 +f 371 365 366 +f 422 366 424 +f 436 424 366 +f 366 357 436 +f 434 436 357 +f 357 345 434 +f 423 424 436 +f 436 437 423 +f 434 435 437 +f 437 436 434 +f 342 338 352 +f 363 341 342 +f 360 364 359 +f 343 354 339 +f 352 363 342 +f 439 438 409 +f 409 410 439 +f 410 405 406 +f 406 439 410 +f 408 409 438 +f 407 406 373 +f 373 396 407 +f 408 438 439 +f 439 407 408 +f 407 439 406 +f 296 299 298 +f 298 295 296 +f 296 440 300 +f 300 299 296 +f 440 441 294 +f 294 300 440 +f 300 294 293 +f 399 398 442 +f 442 413 399 +f 442 398 397 +f 397 411 442 +f 415 402 401 +f 401 443 415 +f 414 443 401 +f 401 400 414 +f 403 416 444 +f 444 404 403 +f 446 445 426 +f 426 447 446 +f 447 433 404 +f 404 446 447 +f 425 426 445 +f 327 430 326 +f 404 444 432 +f 432 431 448 +f 448 404 432 +f 404 448 446 +f 448 427 445 +f 445 446 448 +f 445 427 425 +f 426 427 448 +f 448 447 426 +f 448 431 428 +f 428 447 448 +f 447 428 429 +f 447 429 433 +f 429 327 395 +f 395 433 429 +f 307 449 306 +f 305 306 449 +f 449 304 305 +f 305 310 306 +f 287 288 450 +f 450 451 287 +f 288 290 452 +f 452 450 288 +f 290 292 453 +f 453 452 290 +f 453 292 294 +f 454 296 297 +f 451 450 455 +f 455 456 451 +f 450 452 457 +f 457 455 450 +f 457 452 453 +f 301 458 303 +f 301 304 459 +f 459 458 301 +f 460 307 308 +f 308 461 460 +f 461 308 462 +f 308 311 463 +f 463 462 308 +f 311 287 451 +f 451 463 311 +f 463 451 464 +f 451 456 465 +f 465 464 451 +f 456 454 466 +f 466 465 456 +f 466 454 297 +f 466 297 317 +f 317 467 466 +f 317 318 468 +f 468 467 317 +f 318 320 469 +f 469 468 318 +f 320 322 470 +f 470 469 320 +f 322 324 471 +f 471 470 322 +f 324 326 472 +f 472 471 324 +f 473 459 461 +f 474 473 461 +f 474 461 462 +f 462 475 474 +f 462 463 476 +f 476 475 462 +f 463 464 477 +f 477 476 463 +f 464 465 478 +f 478 477 464 +f 465 466 479 +f 479 478 465 +f 466 467 480 +f 480 479 466 +f 480 467 468 +f 482 481 473 +f 473 474 482 +f 481 483 459 +f 459 473 481 +f 459 483 484 +f 484 458 459 +f 458 484 485 +f 487 486 481 +f 481 482 487 +f 481 486 483 +f 484 488 485 +f 490 489 488 +f 488 491 490 +f 348 349 492 +f 492 493 348 +f 485 492 303 +f 303 458 485 +f 303 492 349 +f 483 495 494 +f 494 496 483 +f 484 483 496 +f 496 497 484 +f 496 494 498 +f 498 497 496 +f 497 498 491 +f 491 488 497 +f 491 500 499 +f 499 490 491 +f 491 498 501 +f 501 500 491 +f 498 494 502 +f 502 504 503 +f 503 501 502 +f 492 485 488 +f 505 494 495 +f 505 495 506 +f 505 506 487 +f 505 487 507 +f 505 507 502 +f 505 502 494 +f 508 499 500 +f 500 509 508 +f 509 500 501 +f 501 503 509 +f 511 503 510 +f 510 512 511 +f 512 510 504 +f 511 514 513 +f 513 503 511 +f 504 516 515 +f 515 512 504 +f 504 518 517 +f 517 516 504 +f 504 507 518 +f 507 487 519 +f 519 518 507 +f 487 482 474 +f 474 519 487 +f 519 474 520 +f 519 521 517 +f 517 518 519 +f 521 523 522 +f 522 517 521 +f 523 525 524 +f 524 522 523 +f 525 527 526 +f 526 524 525 +f 527 529 528 +f 528 526 527 +f 529 531 530 +f 530 528 529 +f 531 533 532 +f 532 530 531 +f 533 535 534 +f 534 532 533 +f 535 537 536 +f 536 534 535 +f 521 519 520 +f 521 520 475 +f 475 520 474 +f 475 476 523 +f 523 521 475 +f 476 477 525 +f 525 523 476 +f 477 478 527 +f 527 525 477 +f 478 479 529 +f 529 527 478 +f 479 480 531 +f 531 529 479 +f 480 468 533 +f 533 531 480 +f 468 469 535 +f 535 533 468 +f 469 470 537 +f 537 535 469 +f 470 471 538 +f 538 537 470 +f 538 471 472 +f 517 522 539 +f 539 516 517 +f 522 524 540 +f 540 539 522 +f 524 526 541 +f 541 540 524 +f 526 528 542 +f 542 541 526 +f 528 530 543 +f 543 542 528 +f 530 532 544 +f 544 543 530 +f 532 534 545 +f 545 544 532 +f 534 536 546 +f 546 545 534 +f 546 536 547 +f 516 549 548 +f 548 515 516 +f 516 539 550 +f 550 549 516 +f 549 550 551 +f 551 552 549 +f 552 551 553 +f 540 411 412 +f 412 539 540 +f 542 543 414 +f 414 413 542 +f 545 546 416 +f 416 415 545 +f 512 515 418 +f 418 417 512 +f 515 539 412 +f 412 418 515 +f 511 512 417 +f 417 419 511 +f 514 511 419 +f 419 420 514 +f 554 514 420 +f 420 421 554 +f 554 513 514 +f 423 555 554 +f 554 421 423 +f 558 557 556 +f 559 472 430 +f 430 560 559 +f 560 430 432 +f 432 561 560 +f 538 562 536 +f 536 537 538 +f 536 562 547 +f 488 489 493 +f 493 492 488 +f 563 435 348 +f 348 493 563 +f 493 489 490 +f 490 563 493 +f 513 509 503 +f 554 508 509 +f 509 513 554 +f 555 508 554 +f 555 564 499 +f 499 508 555 +f 564 563 490 +f 490 499 564 +f 555 423 437 +f 437 564 555 +f 435 563 564 +f 564 437 435 +f 495 483 486 +f 486 487 506 +f 502 507 504 +f 484 497 488 +f 486 506 495 +f 566 565 552 +f 552 553 566 +f 549 552 565 +f 565 548 549 +f 566 553 551 +f 548 550 539 +f 539 515 548 +f 565 566 551 +f 551 548 565 +f 548 551 550 +f 455 296 454 +f 454 456 455 +f 440 296 455 +f 455 457 440 +f 294 441 440 +f 440 453 294 +f 453 440 457 +f 541 542 413 +f 413 442 541 +f 541 442 411 +f 411 540 541 +f 545 415 443 +f 443 544 545 +f 443 414 543 +f 543 544 443 +f 416 546 547 +f 547 444 416 +f 569 568 567 +f 567 557 569 +f 562 567 568 +f 568 547 562 +f 569 557 558 +f 326 430 472 +f 432 444 547 +f 570 561 432 +f 432 568 570 +f 568 432 547 +f 556 570 568 +f 568 569 556 +f 558 556 569 +f 556 557 567 +f 567 570 556 +f 561 570 567 +f 567 560 561 +f 559 560 567 +f 562 559 567 +f 472 559 562 +f 562 538 472 +f 460 449 307 +f 460 459 304 +f 304 449 460 +f 460 461 459 +f 502 501 498 +f 355 358 359 + +g dolph03 +usemtl dolph03 +f 573 572 571 +f 571 574 573 +f 575 573 574 +f 574 576 575 +f 577 575 576 +f 576 578 577 +f 579 577 578 +f 582 581 580 +f 574 571 583 +f 583 584 574 +f 576 574 584 +f 584 585 576 +f 578 576 585 +f 588 587 586 +f 589 586 587 +f 587 590 589 +f 593 592 591 +f 591 594 593 +f 594 591 595 +f 596 593 594 +f 594 597 596 +f 572 596 597 +f 597 571 572 +f 598 571 597 +f 583 571 598 +f 598 599 583 +f 580 583 599 +f 599 600 580 +f 582 580 600 +f 582 600 601 +f 601 602 582 +f 603 602 601 +f 601 604 603 +f 605 603 604 +f 604 606 605 +f 607 605 606 +f 606 608 607 +f 609 607 608 +f 608 610 609 +f 611 609 610 +f 610 612 611 +f 595 590 613 +f 595 613 614 +f 595 614 615 +f 615 594 595 +f 597 594 615 +f 615 616 597 +f 598 597 616 +f 616 617 598 +f 599 598 617 +f 617 618 599 +f 600 599 618 +f 618 619 600 +f 601 600 619 +f 619 620 601 +f 604 601 620 +f 622 621 614 +f 614 613 622 +f 623 622 613 +f 613 590 623 +f 624 623 590 +f 590 587 624 +f 625 624 587 +f 627 626 621 +f 621 622 627 +f 623 627 622 +f 625 628 624 +f 631 630 629 +f 629 628 631 +f 634 633 632 +f 632 635 634 +f 635 625 587 +f 587 588 635 +f 634 635 588 +f 637 623 636 +f 636 638 637 +f 623 624 639 +f 639 636 623 +f 638 636 639 +f 639 640 638 +f 640 639 628 +f 628 629 640 +f 641 629 630 +f 630 642 641 +f 640 629 641 +f 641 643 640 +f 644 638 640 +f 645 644 643 +f 643 646 645 +f 628 625 635 +f 637 638 647 +f 648 637 647 +f 626 648 647 +f 649 626 647 +f 644 649 647 +f 638 644 647 +f 642 651 650 +f 650 641 642 +f 641 650 646 +f 646 643 641 +f 653 646 652 +f 652 645 653 +f 645 652 654 +f 655 652 646 +f 646 656 655 +f 657 645 654 +f 654 658 657 +f 659 645 657 +f 657 660 659 +f 659 649 645 +f 626 649 659 +f 659 661 626 +f 614 621 626 +f 626 662 614 +f 662 626 661 +f 663 661 659 +f 659 660 663 +f 664 663 660 +f 660 665 664 +f 666 664 665 +f 665 667 666 +f 668 666 667 +f 667 669 668 +f 670 668 669 +f 669 671 670 +f 672 670 671 +f 671 673 672 +f 674 672 673 +f 673 675 674 +f 676 674 675 +f 675 677 676 +f 678 676 677 +f 677 679 678 +f 662 661 663 +f 615 662 663 +f 614 662 615 +f 616 615 663 +f 663 664 616 +f 617 616 664 +f 664 666 617 +f 618 617 666 +f 666 668 618 +f 619 618 668 +f 668 670 619 +f 620 619 670 +f 670 672 620 +f 604 620 672 +f 672 674 604 +f 606 604 674 +f 674 676 606 +f 608 606 676 +f 676 678 608 +f 610 608 678 +f 678 680 610 +f 612 610 680 +f 665 660 657 +f 657 681 665 +f 667 665 681 +f 681 682 667 +f 669 667 682 +f 682 683 669 +f 671 669 683 +f 683 684 671 +f 673 671 684 +f 684 685 673 +f 675 673 685 +f 685 686 675 +f 677 675 686 +f 686 687 677 +f 679 677 687 +f 687 688 679 +f 689 679 688 +f 690 657 658 +f 658 691 690 +f 681 657 690 +f 690 692 681 +f 693 692 690 +f 690 694 693 +f 694 690 695 +f 696 682 681 +f 681 697 696 +f 685 684 698 +f 698 699 685 +f 688 687 700 +f 700 701 688 +f 658 654 702 +f 702 703 658 +f 681 658 703 +f 703 697 681 +f 654 652 704 +f 704 702 654 +f 652 655 705 +f 705 704 652 +f 655 707 706 +f 706 705 655 +f 655 656 707 +f 709 708 706 +f 706 707 709 +f 712 711 710 +f 612 714 713 +f 713 715 612 +f 715 713 716 +f 716 717 715 +f 718 680 678 +f 678 679 718 +f 689 718 679 +f 631 628 635 +f 635 632 631 +f 720 719 632 +f 632 633 720 +f 631 632 719 +f 719 630 631 +f 646 650 656 +f 651 707 656 +f 656 650 651 +f 707 651 709 +f 721 709 651 +f 651 642 721 +f 719 721 642 +f 642 630 719 +f 708 709 721 +f 721 722 708 +f 719 720 722 +f 722 721 719 +f 627 623 637 +f 648 626 627 +f 645 649 644 +f 628 639 624 +f 637 648 627 +f 724 723 694 +f 694 695 724 +f 695 690 691 +f 691 724 695 +f 693 694 723 +f 692 691 658 +f 658 681 692 +f 693 723 724 +f 724 692 693 +f 692 724 691 +f 581 584 583 +f 583 580 581 +f 581 725 585 +f 585 584 581 +f 725 726 579 +f 579 585 725 +f 585 579 578 +f 684 683 727 +f 727 698 684 +f 727 683 682 +f 682 696 727 +f 700 687 686 +f 686 728 700 +f 699 728 686 +f 686 685 699 +f 688 701 729 +f 729 689 688 +f 731 730 711 +f 711 732 731 +f 732 718 689 +f 689 731 732 +f 710 711 730 +f 612 715 611 +f 689 729 717 +f 717 716 733 +f 733 689 717 +f 689 733 731 +f 733 712 730 +f 730 731 733 +f 730 712 710 +f 711 712 733 +f 733 732 711 +f 733 716 713 +f 713 732 733 +f 732 713 714 +f 732 714 718 +f 714 612 680 +f 680 718 714 +f 592 734 591 +f 590 591 734 +f 734 589 590 +f 590 595 591 +f 572 573 735 +f 735 736 572 +f 573 575 737 +f 737 735 573 +f 575 577 738 +f 738 737 575 +f 738 577 579 +f 739 581 582 +f 736 735 740 +f 740 741 736 +f 735 737 742 +f 742 740 735 +f 742 737 738 +f 586 743 588 +f 586 589 744 +f 744 743 586 +f 745 592 593 +f 593 746 745 +f 746 593 747 +f 593 596 748 +f 748 747 593 +f 596 572 736 +f 736 748 596 +f 748 736 749 +f 736 741 750 +f 750 749 736 +f 741 739 751 +f 751 750 741 +f 751 739 582 +f 751 582 602 +f 602 752 751 +f 602 603 753 +f 753 752 602 +f 603 605 754 +f 754 753 603 +f 605 607 755 +f 755 754 605 +f 607 609 756 +f 756 755 607 +f 609 611 757 +f 757 756 609 +f 758 744 746 +f 759 758 746 +f 759 746 747 +f 747 760 759 +f 747 748 761 +f 761 760 747 +f 748 749 762 +f 762 761 748 +f 749 750 763 +f 763 762 749 +f 750 751 764 +f 764 763 750 +f 751 752 765 +f 765 764 751 +f 765 752 753 +f 767 766 758 +f 758 759 767 +f 766 768 744 +f 744 758 766 +f 744 768 769 +f 769 743 744 +f 743 769 770 +f 772 771 766 +f 766 767 772 +f 766 771 768 +f 769 773 770 +f 775 774 773 +f 773 776 775 +f 633 634 777 +f 777 778 633 +f 770 777 588 +f 588 743 770 +f 588 777 634 +f 768 780 779 +f 779 781 768 +f 769 768 781 +f 781 782 769 +f 781 779 783 +f 783 782 781 +f 782 783 776 +f 776 773 782 +f 776 785 784 +f 784 775 776 +f 776 783 786 +f 786 785 776 +f 783 779 787 +f 787 789 788 +f 788 786 787 +f 777 770 773 +f 790 779 780 +f 790 780 791 +f 790 791 772 +f 790 772 792 +f 790 792 787 +f 790 787 779 +f 793 784 785 +f 785 794 793 +f 794 785 786 +f 786 788 794 +f 796 788 795 +f 795 797 796 +f 797 795 789 +f 796 799 798 +f 798 788 796 +f 789 801 800 +f 800 797 789 +f 789 803 802 +f 802 801 789 +f 789 792 803 +f 792 772 804 +f 804 803 792 +f 772 767 759 +f 759 804 772 +f 804 759 805 +f 804 806 802 +f 802 803 804 +f 806 808 807 +f 807 802 806 +f 808 810 809 +f 809 807 808 +f 810 812 811 +f 811 809 810 +f 812 814 813 +f 813 811 812 +f 814 816 815 +f 815 813 814 +f 816 818 817 +f 817 815 816 +f 818 820 819 +f 819 817 818 +f 820 822 821 +f 821 819 820 +f 806 804 805 +f 806 805 760 +f 760 805 759 +f 760 761 808 +f 808 806 760 +f 761 762 810 +f 810 808 761 +f 762 763 812 +f 812 810 762 +f 763 764 814 +f 814 812 763 +f 764 765 816 +f 816 814 764 +f 765 753 818 +f 818 816 765 +f 753 754 820 +f 820 818 753 +f 754 755 822 +f 822 820 754 +f 755 756 823 +f 823 822 755 +f 823 756 757 +f 802 807 824 +f 824 801 802 +f 807 809 825 +f 825 824 807 +f 809 811 826 +f 826 825 809 +f 811 813 827 +f 827 826 811 +f 813 815 828 +f 828 827 813 +f 815 817 829 +f 829 828 815 +f 817 819 830 +f 830 829 817 +f 819 821 831 +f 831 830 819 +f 831 821 832 +f 801 834 833 +f 833 800 801 +f 801 824 835 +f 835 834 801 +f 834 835 836 +f 836 837 834 +f 837 836 838 +f 825 696 697 +f 697 824 825 +f 827 828 699 +f 699 698 827 +f 830 831 701 +f 701 700 830 +f 797 800 703 +f 703 702 797 +f 800 824 697 +f 697 703 800 +f 796 797 702 +f 702 704 796 +f 799 796 704 +f 704 705 799 +f 839 799 705 +f 705 706 839 +f 839 798 799 +f 708 840 839 +f 839 706 708 +f 843 842 841 +f 844 757 715 +f 715 845 844 +f 845 715 717 +f 717 846 845 +f 823 847 821 +f 821 822 823 +f 821 847 832 +f 773 774 778 +f 778 777 773 +f 848 720 633 +f 633 778 848 +f 778 774 775 +f 775 848 778 +f 798 794 788 +f 839 793 794 +f 794 798 839 +f 840 793 839 +f 840 849 784 +f 784 793 840 +f 849 848 775 +f 775 784 849 +f 840 708 722 +f 722 849 840 +f 720 848 849 +f 849 722 720 +f 780 768 771 +f 771 772 791 +f 787 792 789 +f 769 782 773 +f 771 791 780 +f 851 850 837 +f 837 838 851 +f 834 837 850 +f 850 833 834 +f 851 838 836 +f 833 835 824 +f 824 800 833 +f 850 851 836 +f 836 833 850 +f 833 836 835 +f 740 581 739 +f 739 741 740 +f 725 581 740 +f 740 742 725 +f 579 726 725 +f 725 738 579 +f 738 725 742 +f 826 827 698 +f 698 727 826 +f 826 727 696 +f 696 825 826 +f 830 700 728 +f 728 829 830 +f 728 699 828 +f 828 829 728 +f 701 831 832 +f 832 729 701 +f 854 853 852 +f 852 842 854 +f 847 852 853 +f 853 832 847 +f 854 842 843 +f 611 715 757 +f 717 729 832 +f 855 846 717 +f 717 853 855 +f 853 717 832 +f 841 855 853 +f 853 854 841 +f 843 841 854 +f 841 842 852 +f 852 855 841 +f 846 855 852 +f 852 845 846 +f 844 845 852 +f 847 844 852 +f 757 844 847 +f 847 823 757 +f 745 734 592 +f 745 744 589 +f 589 734 745 +f 745 746 744 +f 787 786 783 +f 640 643 644 diff --git a/lib/glut-3.7.6/progs/demos/smooth/dirent32.h b/lib/glut-3.7.6/progs/demos/smooth/dirent32.h new file mode 100644 index 0000000000..02608c4b32 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/dirent32.h @@ -0,0 +1,96 @@ +/* + + Win32 lacks unix dirent support. But, we can fake it. Many + thanks to Dave Lubrik (lubrik@jaka.ece.uiuc.edu) who found and + fixed many bugs in the original code. + + */ + + +#ifndef _WIN32 +#include +#else + +#include + + + +struct dirent { + char d_name[MAX_PATH]; +}; + +typedef struct { + WIN32_FIND_DATA wfd; + HANDLE hFind; + struct dirent de; +} DIR; + + +static DIR * +opendir(char *pSpec) +{ + DIR *pDir = malloc(sizeof(DIR)); + char pathnamespec[MAX_PATH]; + int l; /* length of directory specifier */ + char c; /* last char of directory specifier */ + + /* Given a directory pathname in pSpec, add \ (if necessary) and * + to yield a globbable expression describing all the files in that + directory */ + strcpy(pathnamespec, pSpec); + + /* Add a \ to separate the directory name from the filename-wildcard + "*", unless it already ends in a \ (don't create \\ sequences), + or it is a drivespec (since "C:*" differs in meaning from "C:\*") */ + if (((l = strlen(pSpec)) > 0) && ((c = pSpec[l-1]) != '\\') && (c != ':')) + strcat(pathnamespec, "\\"); + + /* Add the filename wildcard "*" */ + strcat(pathnamespec,"*"); + + /* Find files matching that expression (all the files in that + directory) */ + pDir->hFind = FindFirstFile(pathnamespec, &pDir->wfd); + + return pDir; +} + + +/* closedir takes a pointer to a DIR structure created by opendir, and + frees up resources allocated by opendir. Call it when done with a + directory. */ +static void +closedir(DIR * pDir) +{ + FindClose(pDir->hFind); /* Release system resources */ + free(pDir); /* release memory */ +} + +/* readdir is used to iterate through the files in a directory. It + takes a pointer to a DIR structure created by opendir, and each + time it is called it returns the name of another file in the + directory passed to opendir. Returns: a pointer to a dirent + structure, containing the file name. NULL if there are no more + files in the directory. */ +static struct dirent * +readdir(DIR *pDir) +{ + /* The previous call to opendir or readdir has already found the next + file (using FindFirstFile or FindNextFile respectively). Return + that file name to the caller, and silently find the next one. */ + + if (*(pDir->wfd.cFileName)) { /* If we haven't exhausted the files */ + strcpy(pDir->de.d_name, pDir->wfd.cFileName); /* copy name */ + + if (!FindNextFile(pDir->hFind, &pDir->wfd)) /* get next */ + *(pDir->wfd.cFileName) = 0; + /* if no more, zero next filename, so that next time through, + we don't even try. */ + + return &pDir->de; /* return dirent struct w/filename */ + } + + return NULL; /* No more files to find. */ +} + +#endif diff --git a/lib/glut-3.7.6/progs/demos/smooth/glm.c b/lib/glut-3.7.6/progs/demos/smooth/glm.c new file mode 100644 index 0000000000..7cd33c5fe1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/glm.c @@ -0,0 +1,1837 @@ +/* + glm.c + Nate Robins, 1997 + ndr@pobox.com, http://www.pobox.com/~ndr/ + + Wavefront OBJ model file format reader/writer/manipulator. + + Includes routines for generating smooth normals with + preservation of edges, welding redundant vertices & texture + coordinate generation (spheremap and planar projections) + more. + + */ + + +#include +#include +#include +#include +#include +#include "glm.h" + + +#define T(x) (model->triangles[(x)]) + + +/* _GLMnode: general purpose node + */ +typedef struct _GLMnode { + GLuint index; + GLboolean averaged; + struct _GLMnode* next; +} GLMnode; + + +/* glmMax: returns the maximum of two floats */ +static GLfloat +glmMax(GLfloat a, GLfloat b) +{ + if (b > a) + return b; + return a; +} + +/* glmAbs: returns the absolute value of a float */ +static GLfloat +glmAbs(GLfloat f) +{ + if (f < 0) + return -f; + return f; +} + +/* glmDot: compute the dot product of two vectors + * + * u - array of 3 GLfloats (GLfloat u[3]) + * v - array of 3 GLfloats (GLfloat v[3]) + */ +static GLfloat +glmDot(GLfloat* u, GLfloat* v) +{ + assert(u); assert(v); + + return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]; +} + +/* glmCross: compute the cross product of two vectors + * + * u - array of 3 GLfloats (GLfloat u[3]) + * v - array of 3 GLfloats (GLfloat v[3]) + * n - array of 3 GLfloats (GLfloat n[3]) to return the cross product in + */ +static GLvoid +glmCross(GLfloat* u, GLfloat* v, GLfloat* n) +{ + assert(u); assert(v); assert(n); + + 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]; +} + +/* glmNormalize: normalize a vector + * + * v - array of 3 GLfloats (GLfloat v[3]) to be normalized + */ +static GLvoid +glmNormalize(GLfloat* v) +{ + GLfloat l; + + assert(v); + + l = (GLfloat)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + v[0] /= l; + v[1] /= l; + v[2] /= l; +} + +/* glmEqual: compares two vectors and returns GL_TRUE if they are + * equal (within a certain threshold) or GL_FALSE if not. An epsilon + * that works fairly well is 0.000001. + * + * u - array of 3 GLfloats (GLfloat u[3]) + * v - array of 3 GLfloats (GLfloat v[3]) + */ +static GLboolean +glmEqual(GLfloat* u, GLfloat* v, GLfloat epsilon) +{ + if (glmAbs(u[0] - v[0]) < epsilon && + glmAbs(u[1] - v[1]) < epsilon && + glmAbs(u[2] - v[2]) < epsilon) + { + return GL_TRUE; + } + return GL_FALSE; +} + +/* glmWeldVectors: eliminate (weld) vectors that are within an + * epsilon of each other. + * + * vectors - array of GLfloat[3]'s to be welded + * numvectors - number of GLfloat[3]'s in vectors + * epsilon - maximum difference between vectors + * + */ +GLfloat* +glmWeldVectors(GLfloat* vectors, GLuint* numvectors, GLfloat epsilon) +{ + GLfloat* copies; + GLuint copied; + GLuint i, j; + + copies = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (*numvectors + 1)); + memcpy(copies, vectors, (sizeof(GLfloat) * 3 * (*numvectors + 1))); + + copied = 1; + for (i = 1; i <= *numvectors; i++) { + for (j = 1; j <= copied; j++) { + if (glmEqual(&vectors[3 * i], &copies[3 * j], epsilon)) { + goto duplicate; + } + } + + /* must not be any duplicates -- add to the copies array */ + copies[3 * copied + 0] = vectors[3 * i + 0]; + copies[3 * copied + 1] = vectors[3 * i + 1]; + copies[3 * copied + 2] = vectors[3 * i + 2]; + j = copied; /* pass this along for below */ + copied++; + + duplicate: + /* set the first component of this vector to point at the correct + index into the new copies array */ + vectors[3 * i + 0] = (GLfloat)j; + } + + *numvectors = copied-1; + return copies; +} + +/* glmFindGroup: Find a group in the model + */ +GLMgroup* +glmFindGroup(GLMmodel* model, char* name) +{ + GLMgroup* group; + + assert(model); + + group = model->groups; + while(group) { + if (!strcmp(name, group->name)) + break; + group = group->next; + } + + return group; +} + +/* glmAddGroup: Add a group to the model + */ +GLMgroup* +glmAddGroup(GLMmodel* model, char* name) +{ + GLMgroup* group; + + group = glmFindGroup(model, name); + if (!group) { + group = (GLMgroup*)malloc(sizeof(GLMgroup)); + group->name = strdup(name); + group->material = 0; + group->numtriangles = 0; + group->triangles = NULL; + group->next = model->groups; + model->groups = group; + model->numgroups++; + } + + return group; +} + +/* glmFindGroup: Find a material in the model + */ +GLuint +glmFindMaterial(GLMmodel* model, char* name) +{ + GLuint i; + + /* XXX doing a linear search on a string key'd list is pretty lame, + but it works and is fast enough for now. */ + for (i = 0; i < model->nummaterials; i++) { + if (!strcmp(model->materials[i].name, name)) + goto found; + } + + /* didn't find the name, so print a warning and return the default + material (0). */ + printf("glmFindMaterial(): can't find material \"%s\".\n", name); + i = 0; + +found: + return i; +} + + +/* glmDirName: return the directory given a path + * + * path - filesystem path + * + * NOTE: the return value should be free'd. + */ +static char* +glmDirName(char* path) +{ + char* dir; + char* s; + + dir = strdup(path); + + s = strrchr(dir, '/'); + if (s) + s[1] = '\0'; + else + dir[0] = '\0'; + + return dir; +} + + +/* glmReadMTL: read a wavefront material library file + * + * model - properly initialized GLMmodel structure + * name - name of the material library + */ +static GLvoid +glmReadMTL(GLMmodel* model, char* name) +{ + FILE* file; + char* dir; + char* filename; + char buf[128]; + GLuint nummaterials, i; + + dir = glmDirName(model->pathname); + filename = (char*)malloc(sizeof(char) * (strlen(dir) + strlen(name) + 1)); + strcpy(filename, dir); + strcat(filename, name); + free(dir); + + file = fopen(filename, "r"); + if (!file) { + fprintf(stderr, "glmReadMTL() failed: can't open material file \"%s\".\n", + filename); + exit(1); + } + free(filename); + + /* count the number of materials in the file */ + nummaterials = 1; + while(fscanf(file, "%s", buf) != EOF) { + switch(buf[0]) { + case '#': /* comment */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + case 'n': /* newmtl */ + fgets(buf, sizeof(buf), file); + nummaterials++; + sscanf(buf, "%s %s", buf, buf); + break; + default: + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + } + } + + rewind(file); + + model->materials = (GLMmaterial*)malloc(sizeof(GLMmaterial) * nummaterials); + model->nummaterials = nummaterials; + + /* set the default material */ + for (i = 0; i < nummaterials; i++) { + model->materials[i].name = NULL; + model->materials[i].shininess = 65.0; + model->materials[i].diffuse[0] = 0.8; + model->materials[i].diffuse[1] = 0.8; + model->materials[i].diffuse[2] = 0.8; + model->materials[i].diffuse[3] = 1.0; + model->materials[i].ambient[0] = 0.2; + model->materials[i].ambient[1] = 0.2; + model->materials[i].ambient[2] = 0.2; + model->materials[i].ambient[3] = 1.0; + model->materials[i].specular[0] = 0.0; + model->materials[i].specular[1] = 0.0; + model->materials[i].specular[2] = 0.0; + model->materials[i].specular[3] = 1.0; + } + model->materials[0].name = strdup("default"); + + /* now, read in the data */ + nummaterials = 0; + while(fscanf(file, "%s", buf) != EOF) { + switch(buf[0]) { + case '#': /* comment */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + case 'n': /* newmtl */ + fgets(buf, sizeof(buf), file); + sscanf(buf, "%s %s", buf, buf); + nummaterials++; + model->materials[nummaterials].name = strdup(buf); + break; + case 'N': + fscanf(file, "%f", &model->materials[nummaterials].shininess); + /* wavefront shininess is from [0, 1000], so scale for OpenGL */ + model->materials[nummaterials].shininess /= 1000.0; + model->materials[nummaterials].shininess *= 128.0; + break; + case 'K': + switch(buf[1]) { + case 'd': + fscanf(file, "%f %f %f", + &model->materials[nummaterials].diffuse[0], + &model->materials[nummaterials].diffuse[1], + &model->materials[nummaterials].diffuse[2]); + break; + case 's': + fscanf(file, "%f %f %f", + &model->materials[nummaterials].specular[0], + &model->materials[nummaterials].specular[1], + &model->materials[nummaterials].specular[2]); + break; + case 'a': + fscanf(file, "%f %f %f", + &model->materials[nummaterials].ambient[0], + &model->materials[nummaterials].ambient[1], + &model->materials[nummaterials].ambient[2]); + break; + default: + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + } + break; + default: + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + } + } +} + +/* glmWriteMTL: write a wavefront material library file + * + * model - properly initialized GLMmodel structure + * modelpath - pathname of the model being written + * mtllibname - name of the material library to be written + */ +static GLvoid +glmWriteMTL(GLMmodel* model, char* modelpath, char* mtllibname) +{ + FILE* file; + char* dir; + char* filename; + GLMmaterial* material; + GLuint i; + + dir = glmDirName(modelpath); + filename = (char*)malloc(sizeof(char) * (strlen(dir)+strlen(mtllibname))); + strcpy(filename, dir); + strcat(filename, mtllibname); + free(dir); + + /* open the file */ + file = fopen(filename, "w"); + if (!file) { + fprintf(stderr, "glmWriteMTL() failed: can't open file \"%s\".\n", + filename); + exit(1); + } + free(filename); + + /* spit out a header */ + fprintf(file, "# \n"); + fprintf(file, "# Wavefront MTL generated by GLM library\n"); + fprintf(file, "# \n"); + fprintf(file, "# GLM library\n"); + fprintf(file, "# Nate Robins\n"); + fprintf(file, "# ndr@pobox.com\n"); + fprintf(file, "# http://www.pobox.com/~ndr\n"); + fprintf(file, "# \n\n"); + + for (i = 0; i < model->nummaterials; i++) { + material = &model->materials[i]; + fprintf(file, "newmtl %s\n", material->name); + fprintf(file, "Ka %f %f %f\n", + material->ambient[0], material->ambient[1], material->ambient[2]); + fprintf(file, "Kd %f %f %f\n", + material->diffuse[0], material->diffuse[1], material->diffuse[2]); + fprintf(file, "Ks %f %f %f\n", + material->specular[0],material->specular[1],material->specular[2]); + fprintf(file, "Ns %f\n", material->shininess / 128.0 * 1000.0); + fprintf(file, "\n"); + } +} + + +/* glmFirstPass: first pass at a Wavefront OBJ file that gets all the + * statistics of the model (such as #vertices, #normals, etc) + * + * model - properly initialized GLMmodel structure + * file - (fopen'd) file descriptor + */ +static GLvoid +glmFirstPass(GLMmodel* model, FILE* file) +{ + GLuint numvertices; /* number of vertices in model */ + GLuint numnormals; /* number of normals in model */ + GLuint numtexcoords; /* number of texcoords in model */ + GLuint numtriangles; /* number of triangles in model */ + GLMgroup* group; /* current group */ + unsigned v, n, t; + char buf[128]; + + /* make a default group */ + group = glmAddGroup(model, "default"); + + numvertices = numnormals = numtexcoords = numtriangles = 0; + while(fscanf(file, "%s", buf) != EOF) { + switch(buf[0]) { + case '#': /* comment */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + case 'v': /* v, vn, vt */ + switch(buf[1]) { + case '\0': /* vertex */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + numvertices++; + break; + case 'n': /* normal */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + numnormals++; + break; + case 't': /* texcoord */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + numtexcoords++; + break; + default: + printf("glmFirstPass(): Unknown token \"%s\".\n", buf); + exit(1); + break; + } + break; + case 'm': + fgets(buf, sizeof(buf), file); + sscanf(buf, "%s %s", buf, buf); + model->mtllibname = strdup(buf); + glmReadMTL(model, buf); + break; + case 'u': + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + case 'g': /* group */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); +#if SINGLE_STRING_GROUP_NAMES + sscanf(buf, "%s", buf); +#else + buf[strlen(buf)-1] = '\0'; /* nuke '\n' */ +#endif + group = glmAddGroup(model, buf); + break; + case 'f': /* face */ + v = n = t = 0; + fscanf(file, "%s", buf); + /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */ + if (strstr(buf, "//")) { + /* v//n */ + sscanf(buf, "%d//%d", &v, &n); + fscanf(file, "%d//%d", &v, &n); + fscanf(file, "%d//%d", &v, &n); + numtriangles++; + group->numtriangles++; + while(fscanf(file, "%d//%d", &v, &n) > 0) { + numtriangles++; + group->numtriangles++; + } + } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) { + /* v/t/n */ + fscanf(file, "%d/%d/%d", &v, &t, &n); + fscanf(file, "%d/%d/%d", &v, &t, &n); + numtriangles++; + group->numtriangles++; + while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) { + numtriangles++; + group->numtriangles++; + } + } else if (sscanf(buf, "%d/%d", &v, &t) == 2) { + /* v/t */ + fscanf(file, "%d/%d", &v, &t); + fscanf(file, "%d/%d", &v, &t); + numtriangles++; + group->numtriangles++; + while(fscanf(file, "%d/%d", &v, &t) > 0) { + numtriangles++; + group->numtriangles++; + } + } else { + /* v */ + fscanf(file, "%d", &v); + fscanf(file, "%d", &v); + numtriangles++; + group->numtriangles++; + while(fscanf(file, "%d", &v) > 0) { + numtriangles++; + group->numtriangles++; + } + } + break; + + default: + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + } + } + + /* set the stats in the model structure */ + model->numvertices = numvertices; + model->numnormals = numnormals; + model->numtexcoords = numtexcoords; + model->numtriangles = numtriangles; + + /* allocate memory for the triangles in each group */ + group = model->groups; + while(group) { + group->triangles = (GLuint*)malloc(sizeof(GLuint) * group->numtriangles); + group->numtriangles = 0; + group = group->next; + } +} + +/* glmSecondPass: second pass at a Wavefront OBJ file that gets all + * the data. + * + * model - properly initialized GLMmodel structure + * file - (fopen'd) file descriptor + */ +static GLvoid +glmSecondPass(GLMmodel* model, FILE* file) +{ + GLuint numvertices; /* number of vertices in model */ + GLuint numnormals; /* number of normals in model */ + GLuint numtexcoords; /* number of texcoords in model */ + GLuint numtriangles; /* number of triangles in model */ + GLfloat* vertices; /* array of vertices */ + GLfloat* normals; /* array of normals */ + GLfloat* texcoords; /* array of texture coordinates */ + GLMgroup* group; /* current group pointer */ + GLuint material; /* current material */ + GLuint v, n, t; + char buf[128]; + + /* set the pointer shortcuts */ + vertices = model->vertices; + normals = model->normals; + texcoords = model->texcoords; + group = model->groups; + + /* on the second pass through the file, read all the data into the + allocated arrays */ + numvertices = numnormals = numtexcoords = 1; + numtriangles = 0; + material = 0; + while(fscanf(file, "%s", buf) != EOF) { + switch(buf[0]) { + case '#': /* comment */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + case 'v': /* v, vn, vt */ + switch(buf[1]) { + case '\0': /* vertex */ + fscanf(file, "%f %f %f", + &vertices[3 * numvertices + 0], + &vertices[3 * numvertices + 1], + &vertices[3 * numvertices + 2]); + numvertices++; + break; + case 'n': /* normal */ + fscanf(file, "%f %f %f", + &normals[3 * numnormals + 0], + &normals[3 * numnormals + 1], + &normals[3 * numnormals + 2]); + numnormals++; + break; + case 't': /* texcoord */ + fscanf(file, "%f %f", + &texcoords[2 * numtexcoords + 0], + &texcoords[2 * numtexcoords + 1]); + numtexcoords++; + break; + } + break; + case 'u': + fgets(buf, sizeof(buf), file); + sscanf(buf, "%s %s", buf, buf); + group->material = material = glmFindMaterial(model, buf); + break; + case 'g': /* group */ + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); +#if SINGLE_STRING_GROUP_NAMES + sscanf(buf, "%s", buf); +#else + buf[strlen(buf)-1] = '\0'; /* nuke '\n' */ +#endif + group = glmFindGroup(model, buf); + group->material = material; + break; + case 'f': /* face */ + v = n = t = 0; + fscanf(file, "%s", buf); + /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */ + if (strstr(buf, "//")) { + /* v//n */ + sscanf(buf, "%d//%d", &v, &n); + T(numtriangles).vindices[0] = v; + T(numtriangles).nindices[0] = n; + fscanf(file, "%d//%d", &v, &n); + T(numtriangles).vindices[1] = v; + T(numtriangles).nindices[1] = n; + fscanf(file, "%d//%d", &v, &n); + T(numtriangles).vindices[2] = v; + T(numtriangles).nindices[2] = n; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + while(fscanf(file, "%d//%d", &v, &n) > 0) { + T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; + T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; + T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; + T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; + T(numtriangles).vindices[2] = v; + T(numtriangles).nindices[2] = n; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + } + } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) { + /* v/t/n */ + T(numtriangles).vindices[0] = v; + T(numtriangles).tindices[0] = t; + T(numtriangles).nindices[0] = n; + fscanf(file, "%d/%d/%d", &v, &t, &n); + T(numtriangles).vindices[1] = v; + T(numtriangles).tindices[1] = t; + T(numtriangles).nindices[1] = n; + fscanf(file, "%d/%d/%d", &v, &t, &n); + T(numtriangles).vindices[2] = v; + T(numtriangles).tindices[2] = t; + T(numtriangles).nindices[2] = n; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) { + T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; + T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; + T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; + T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; + T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; + T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; + T(numtriangles).vindices[2] = v; + T(numtriangles).tindices[2] = t; + T(numtriangles).nindices[2] = n; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + } + } else if (sscanf(buf, "%d/%d", &v, &t) == 2) { + /* v/t */ + T(numtriangles).vindices[0] = v; + T(numtriangles).tindices[0] = t; + fscanf(file, "%d/%d", &v, &t); + T(numtriangles).vindices[1] = v; + T(numtriangles).tindices[1] = t; + fscanf(file, "%d/%d", &v, &t); + T(numtriangles).vindices[2] = v; + T(numtriangles).tindices[2] = t; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + while(fscanf(file, "%d/%d", &v, &t) > 0) { + T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; + T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; + T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; + T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; + T(numtriangles).vindices[2] = v; + T(numtriangles).tindices[2] = t; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + } + } else { + /* v */ + sscanf(buf, "%d", &v); + T(numtriangles).vindices[0] = v; + fscanf(file, "%d", &v); + T(numtriangles).vindices[1] = v; + fscanf(file, "%d", &v); + T(numtriangles).vindices[2] = v; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + while(fscanf(file, "%d", &v) > 0) { + T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; + T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; + T(numtriangles).vindices[2] = v; + group->triangles[group->numtriangles++] = numtriangles; + numtriangles++; + } + } + break; + + default: + /* eat up rest of line */ + fgets(buf, sizeof(buf), file); + break; + } + } + +#if 0 + /* announce the memory requirements */ + printf(" Memory: %d bytes\n", + numvertices * 3*sizeof(GLfloat) + + numnormals * 3*sizeof(GLfloat) * (numnormals ? 1 : 0) + + numtexcoords * 3*sizeof(GLfloat) * (numtexcoords ? 1 : 0) + + numtriangles * sizeof(GLMtriangle)); +#endif +} + + + + +/* glmUnitize: "unitize" a model by translating it to the origin and + * scaling it to fit in a unit cube around the origin (-1 to 1 in all + * dimensions). + * Returns the scalefactor used. + * + * model - properly initialized GLMmodel structure + */ +GLfloat +glmUnitize(GLMmodel* model) +{ + GLuint i; + GLfloat maxx, minx, maxy, miny, maxz, minz; + GLfloat cx, cy, cz, w, h, d; + GLfloat scale; + + assert(model); + assert(model->vertices); + + /* get the max/mins */ + maxx = minx = model->vertices[3 + 0]; + maxy = miny = model->vertices[3 + 1]; + maxz = minz = model->vertices[3 + 2]; + for (i = 1; i <= model->numvertices; i++) { + if (maxx < model->vertices[3 * i + 0]) + maxx = model->vertices[3 * i + 0]; + if (minx > model->vertices[3 * i + 0]) + minx = model->vertices[3 * i + 0]; + + if (maxy < model->vertices[3 * i + 1]) + maxy = model->vertices[3 * i + 1]; + if (miny > model->vertices[3 * i + 1]) + miny = model->vertices[3 * i + 1]; + + if (maxz < model->vertices[3 * i + 2]) + maxz = model->vertices[3 * i + 2]; + if (minz > model->vertices[3 * i + 2]) + minz = model->vertices[3 * i + 2]; + } + + /* calculate model width, height, and depth */ + w = glmAbs(maxx) + glmAbs(minx); + h = glmAbs(maxy) + glmAbs(miny); + d = glmAbs(maxz) + glmAbs(minz); + + /* calculate center of the model */ + cx = (maxx + minx) / 2.0; + cy = (maxy + miny) / 2.0; + cz = (maxz + minz) / 2.0; + + /* calculate unitizing scale factor */ + scale = 2.0 / glmMax(glmMax(w, h), d); + + /* translate around center then scale */ + for (i = 1; i <= model->numvertices; i++) { + model->vertices[3 * i + 0] -= cx; + model->vertices[3 * i + 1] -= cy; + model->vertices[3 * i + 2] -= cz; + model->vertices[3 * i + 0] *= scale; + model->vertices[3 * i + 1] *= scale; + model->vertices[3 * i + 2] *= scale; + } + + return scale; +} + +/* glmDimensions: Calculates the dimensions (width, height, depth) of + * a model. + * + * model - initialized GLMmodel structure + * dimensions - array of 3 GLfloats (GLfloat dimensions[3]) + */ +GLvoid +glmDimensions(GLMmodel* model, GLfloat* dimensions) +{ + GLuint i; + GLfloat maxx, minx, maxy, miny, maxz, minz; + + assert(model); + assert(model->vertices); + assert(dimensions); + + /* get the max/mins */ + maxx = minx = model->vertices[3 + 0]; + maxy = miny = model->vertices[3 + 1]; + maxz = minz = model->vertices[3 + 2]; + for (i = 1; i <= model->numvertices; i++) { + if (maxx < model->vertices[3 * i + 0]) + maxx = model->vertices[3 * i + 0]; + if (minx > model->vertices[3 * i + 0]) + minx = model->vertices[3 * i + 0]; + + if (maxy < model->vertices[3 * i + 1]) + maxy = model->vertices[3 * i + 1]; + if (miny > model->vertices[3 * i + 1]) + miny = model->vertices[3 * i + 1]; + + if (maxz < model->vertices[3 * i + 2]) + maxz = model->vertices[3 * i + 2]; + if (minz > model->vertices[3 * i + 2]) + minz = model->vertices[3 * i + 2]; + } + + /* calculate model width, height, and depth */ + dimensions[0] = glmAbs(maxx) + glmAbs(minx); + dimensions[1] = glmAbs(maxy) + glmAbs(miny); + dimensions[2] = glmAbs(maxz) + glmAbs(minz); +} + +/* glmScale: Scales a model by a given amount. + * + * model - properly initialized GLMmodel structure + * scale - scalefactor (0.5 = half as large, 2.0 = twice as large) + */ +GLvoid +glmScale(GLMmodel* model, GLfloat scale) +{ + GLuint i; + + for (i = 1; i <= model->numvertices; i++) { + model->vertices[3 * i + 0] *= scale; + model->vertices[3 * i + 1] *= scale; + model->vertices[3 * i + 2] *= scale; + } +} + +/* glmReverseWinding: Reverse the polygon winding for all polygons in + * this model. Default winding is counter-clockwise. Also changes + * the direction of the normals. + * + * model - properly initialized GLMmodel structure + */ +GLvoid +glmReverseWinding(GLMmodel* model) +{ + GLuint i, swap; + + assert(model); + + for (i = 0; i < model->numtriangles; i++) { + swap = T(i).vindices[0]; + T(i).vindices[0] = T(i).vindices[2]; + T(i).vindices[2] = swap; + + if (model->numnormals) { + swap = T(i).nindices[0]; + T(i).nindices[0] = T(i).nindices[2]; + T(i).nindices[2] = swap; + } + + if (model->numtexcoords) { + swap = T(i).tindices[0]; + T(i).tindices[0] = T(i).tindices[2]; + T(i).tindices[2] = swap; + } + } + + /* reverse facet normals */ + for (i = 1; i <= model->numfacetnorms; i++) { + model->facetnorms[3 * i + 0] = -model->facetnorms[3 * i + 0]; + model->facetnorms[3 * i + 1] = -model->facetnorms[3 * i + 1]; + model->facetnorms[3 * i + 2] = -model->facetnorms[3 * i + 2]; + } + + /* reverse vertex normals */ + for (i = 1; i <= model->numnormals; i++) { + model->normals[3 * i + 0] = -model->normals[3 * i + 0]; + model->normals[3 * i + 1] = -model->normals[3 * i + 1]; + model->normals[3 * i + 2] = -model->normals[3 * i + 2]; + } +} + +/* glmFacetNormals: Generates facet normals for a model (by taking the + * cross product of the two vectors derived from the sides of each + * triangle). Assumes a counter-clockwise winding. + * + * model - initialized GLMmodel structure + */ +GLvoid +glmFacetNormals(GLMmodel* model) +{ + GLuint i; + GLfloat u[3]; + GLfloat v[3]; + + assert(model); + assert(model->vertices); + + /* clobber any old facetnormals */ + if (model->facetnorms) + free(model->facetnorms); + + /* allocate memory for the new facet normals */ + model->numfacetnorms = model->numtriangles; + model->facetnorms = (GLfloat*)malloc(sizeof(GLfloat) * + 3 * (model->numfacetnorms + 1)); + + for (i = 0; i < model->numtriangles; i++) { + model->triangles[i].findex = i+1; + + u[0] = model->vertices[3 * T(i).vindices[1] + 0] - + model->vertices[3 * T(i).vindices[0] + 0]; + u[1] = model->vertices[3 * T(i).vindices[1] + 1] - + model->vertices[3 * T(i).vindices[0] + 1]; + u[2] = model->vertices[3 * T(i).vindices[1] + 2] - + model->vertices[3 * T(i).vindices[0] + 2]; + + v[0] = model->vertices[3 * T(i).vindices[2] + 0] - + model->vertices[3 * T(i).vindices[0] + 0]; + v[1] = model->vertices[3 * T(i).vindices[2] + 1] - + model->vertices[3 * T(i).vindices[0] + 1]; + v[2] = model->vertices[3 * T(i).vindices[2] + 2] - + model->vertices[3 * T(i).vindices[0] + 2]; + + glmCross(u, v, &model->facetnorms[3 * (i+1)]); + glmNormalize(&model->facetnorms[3 * (i+1)]); + } +} + +/* glmVertexNormals: Generates smooth vertex normals for a model. + * First builds a list of all the triangles each vertex is in. Then + * loops through each vertex in the the list averaging all the facet + * normals of the triangles each vertex is in. Finally, sets the + * normal index in the triangle for the vertex to the generated smooth + * normal. If the dot product of a facet normal and the facet normal + * associated with the first triangle in the list of triangles the + * current vertex is in is greater than the cosine of the angle + * parameter to the function, that facet normal is not added into the + * average normal calculation and the corresponding vertex is given + * the facet normal. This tends to preserve hard edges. The angle to + * use depends on the model, but 90 degrees is usually a good start. + * + * model - initialized GLMmodel structure + * angle - maximum angle (in degrees) to smooth across + */ +GLvoid +glmVertexNormals(GLMmodel* model, GLfloat angle) +{ + GLMnode* node; + GLMnode* tail; + GLMnode** members; + GLfloat* normals; + GLuint numnormals; + GLfloat average[3]; + GLfloat dot, cos_angle; + GLuint i, avg; + + assert(model); + assert(model->facetnorms); + + /* calculate the cosine of the angle (in degrees) */ + cos_angle = cos(angle * M_PI / 180.0); + + /* nuke any previous normals */ + if (model->normals) + free(model->normals); + + /* allocate space for new normals */ + model->numnormals = model->numtriangles * 3; /* 3 normals per triangle */ + model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1)); + + /* allocate a structure that will hold a linked list of triangle + indices for each vertex */ + members = (GLMnode**)malloc(sizeof(GLMnode*) * (model->numvertices + 1)); + for (i = 1; i <= model->numvertices; i++) + members[i] = NULL; + + /* for every triangle, create a node for each vertex in it */ + for (i = 0; i < model->numtriangles; i++) { + node = (GLMnode*)malloc(sizeof(GLMnode)); + node->index = i; + node->next = members[T(i).vindices[0]]; + members[T(i).vindices[0]] = node; + + node = (GLMnode*)malloc(sizeof(GLMnode)); + node->index = i; + node->next = members[T(i).vindices[1]]; + members[T(i).vindices[1]] = node; + + node = (GLMnode*)malloc(sizeof(GLMnode)); + node->index = i; + node->next = members[T(i).vindices[2]]; + members[T(i).vindices[2]] = node; + } + + /* calculate the average normal for each vertex */ + numnormals = 1; + for (i = 1; i <= model->numvertices; i++) { + /* calculate an average normal for this vertex by averaging the + facet normal of every triangle this vertex is in */ + node = members[i]; + if (!node) + fprintf(stderr, "glmVertexNormals(): vertex w/o a triangle\n"); + average[0] = 0.0; average[1] = 0.0; average[2] = 0.0; + avg = 0; + while (node) { + /* only average if the dot product of the angle between the two + facet normals is greater than the cosine of the threshold + angle -- or, said another way, the angle between the two + facet normals is less than (or equal to) the threshold angle */ + dot = glmDot(&model->facetnorms[3 * T(node->index).findex], + &model->facetnorms[3 * T(members[i]->index).findex]); + if (dot > cos_angle) { + node->averaged = GL_TRUE; + average[0] += model->facetnorms[3 * T(node->index).findex + 0]; + average[1] += model->facetnorms[3 * T(node->index).findex + 1]; + average[2] += model->facetnorms[3 * T(node->index).findex + 2]; + avg = 1; /* we averaged at least one normal! */ + } else { + node->averaged = GL_FALSE; + } + node = node->next; + } + + if (avg) { + /* normalize the averaged normal */ + glmNormalize(average); + + /* add the normal to the vertex normals list */ + model->normals[3 * numnormals + 0] = average[0]; + model->normals[3 * numnormals + 1] = average[1]; + model->normals[3 * numnormals + 2] = average[2]; + avg = numnormals; + numnormals++; + } + + /* set the normal of this vertex in each triangle it is in */ + node = members[i]; + while (node) { + if (node->averaged) { + /* if this node was averaged, use the average normal */ + if (T(node->index).vindices[0] == i) + T(node->index).nindices[0] = avg; + else if (T(node->index).vindices[1] == i) + T(node->index).nindices[1] = avg; + else if (T(node->index).vindices[2] == i) + T(node->index).nindices[2] = avg; + } else { + /* if this node wasn't averaged, use the facet normal */ + model->normals[3 * numnormals + 0] = + model->facetnorms[3 * T(node->index).findex + 0]; + model->normals[3 * numnormals + 1] = + model->facetnorms[3 * T(node->index).findex + 1]; + model->normals[3 * numnormals + 2] = + model->facetnorms[3 * T(node->index).findex + 2]; + if (T(node->index).vindices[0] == i) + T(node->index).nindices[0] = numnormals; + else if (T(node->index).vindices[1] == i) + T(node->index).nindices[1] = numnormals; + else if (T(node->index).vindices[2] == i) + T(node->index).nindices[2] = numnormals; + numnormals++; + } + node = node->next; + } + } + + model->numnormals = numnormals - 1; + + /* free the member information */ + for (i = 1; i <= model->numvertices; i++) { + node = members[i]; + while (node) { + tail = node; + node = node->next; + free(tail); + } + } + free(members); + + /* pack the normals array (we previously allocated the maximum + number of normals that could possibly be created (numtriangles * + 3), so get rid of some of them (usually alot unless none of the + facet normals were averaged)) */ + normals = model->normals; + model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1)); + for (i = 1; i <= model->numnormals; i++) { + model->normals[3 * i + 0] = normals[3 * i + 0]; + model->normals[3 * i + 1] = normals[3 * i + 1]; + model->normals[3 * i + 2] = normals[3 * i + 2]; + } + free(normals); +} + + +/* glmLinearTexture: Generates texture coordinates according to a + * linear projection of the texture map. It generates these by + * linearly mapping the vertices onto a square. + * + * model - pointer to initialized GLMmodel structure + */ +GLvoid +glmLinearTexture(GLMmodel* model) +{ + GLMgroup *group; + GLfloat dimensions[3]; + GLfloat x, y, scalefactor; + GLuint i; + + assert(model); + + if (model->texcoords) + free(model->texcoords); + model->numtexcoords = model->numvertices; + model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1)); + + glmDimensions(model, dimensions); + scalefactor = 2.0 / + glmAbs(glmMax(glmMax(dimensions[0], dimensions[1]), dimensions[2])); + + /* do the calculations */ + for(i = 1; i <= model->numvertices; i++) { + x = model->vertices[3 * i + 0] * scalefactor; + y = model->vertices[3 * i + 2] * scalefactor; + model->texcoords[2 * i + 0] = (x + 1.0) / 2.0; + model->texcoords[2 * i + 1] = (y + 1.0) / 2.0; + } + + /* go through and put texture coordinate indices in all the triangles */ + group = model->groups; + while(group) { + for(i = 0; i < group->numtriangles; i++) { + T(group->triangles[i]).tindices[0] = T(group->triangles[i]).vindices[0]; + T(group->triangles[i]).tindices[1] = T(group->triangles[i]).vindices[1]; + T(group->triangles[i]).tindices[2] = T(group->triangles[i]).vindices[2]; + } + group = group->next; + } + +#if 0 + printf("glmLinearTexture(): generated %d linear texture coordinates\n", + model->numtexcoords); +#endif +} + +/* glmSpheremapTexture: Generates texture coordinates according to a + * spherical projection of the texture map. Sometimes referred to as + * spheremap, or reflection map texture coordinates. It generates + * these by using the normal to calculate where that vertex would map + * onto a sphere. Since it is impossible to map something flat + * perfectly onto something spherical, there is distortion at the + * poles. This particular implementation causes the poles along the X + * axis to be distorted. + * + * model - pointer to initialized GLMmodel structure + */ +GLvoid +glmSpheremapTexture(GLMmodel* model) +{ + GLMgroup* group; + GLfloat theta, phi, rho, x, y, z, r; + GLuint i; + + assert(model); + assert(model->normals); + + if (model->texcoords) + free(model->texcoords); + model->numtexcoords = model->numnormals; + model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1)); + + for (i = 1; i <= model->numnormals; i++) { + z = model->normals[3 * i + 0]; /* re-arrange for pole distortion */ + y = model->normals[3 * i + 1]; + x = model->normals[3 * i + 2]; + r = sqrt((x * x) + (y * y)); + rho = sqrt((r * r) + (z * z)); + + if(r == 0.0) { + theta = 0.0; + phi = 0.0; + } else { + if(z == 0.0) + phi = 3.14159265 / 2.0; + else + phi = acos(z / rho); + + if(y == 0.0) + theta = 3.141592365 / 2.0; + else + theta = asin(y / r) + (3.14159265 / 2.0); + } + + model->texcoords[2 * i + 0] = theta / 3.14159265; + model->texcoords[2 * i + 1] = phi / 3.14159265; + } + + /* go through and put texcoord indices in all the triangles */ + group = model->groups; + while(group) { + for (i = 0; i < group->numtriangles; i++) { + T(group->triangles[i]).tindices[0] = T(group->triangles[i]).nindices[0]; + T(group->triangles[i]).tindices[1] = T(group->triangles[i]).nindices[1]; + T(group->triangles[i]).tindices[2] = T(group->triangles[i]).nindices[2]; + } + group = group->next; + } +} + +/* glmDelete: Deletes a GLMmodel structure. + * + * model - initialized GLMmodel structure + */ +GLvoid +glmDelete(GLMmodel* model) +{ + GLMgroup* group; + GLuint i; + + assert(model); + + if (model->pathname) free(model->pathname); + if (model->mtllibname) free(model->mtllibname); + if (model->vertices) free(model->vertices); + if (model->normals) free(model->normals); + if (model->texcoords) free(model->texcoords); + if (model->facetnorms) free(model->facetnorms); + if (model->triangles) free(model->triangles); + if (model->materials) { + for (i = 0; i < model->nummaterials; i++) + free(model->materials[i].name); + } + free(model->materials); + while(model->groups) { + group = model->groups; + model->groups = model->groups->next; + free(group->name); + free(group->triangles); + free(group); + } + + free(model); +} + +/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file. + * Returns a pointer to the created object which should be free'd with + * glmDelete(). + * + * filename - name of the file containing the Wavefront .OBJ format data. + */ +GLMmodel* +glmReadOBJ(char* filename) +{ + GLMmodel* model; + FILE* file; + + /* open the file */ + file = fopen(filename, "r"); + if (!file) { + fprintf(stderr, "glmReadOBJ() failed: can't open data file \"%s\".\n", + filename); + exit(1); + } + + /* allocate a new model */ + model = (GLMmodel*)malloc(sizeof(GLMmodel)); + model->pathname = strdup(filename); + model->mtllibname = NULL; + model->numvertices = 0; + model->vertices = NULL; + model->numnormals = 0; + model->normals = NULL; + model->numtexcoords = 0; + model->texcoords = NULL; + model->numfacetnorms = 0; + model->facetnorms = NULL; + model->numtriangles = 0; + model->triangles = NULL; + model->nummaterials = 0; + model->materials = NULL; + model->numgroups = 0; + model->groups = NULL; + model->position[0] = 0.0; + model->position[1] = 0.0; + model->position[2] = 0.0; + + /* make a first pass through the file to get a count of the number + of vertices, normals, texcoords & triangles */ + glmFirstPass(model, file); + + /* allocate memory */ + model->vertices = (GLfloat*)malloc(sizeof(GLfloat) * + 3 * (model->numvertices + 1)); + model->triangles = (GLMtriangle*)malloc(sizeof(GLMtriangle) * + model->numtriangles); + if (model->numnormals) { + model->normals = (GLfloat*)malloc(sizeof(GLfloat) * + 3 * (model->numnormals + 1)); + } + if (model->numtexcoords) { + model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * + 2 * (model->numtexcoords + 1)); + } + + /* rewind to beginning of file and read in the data this pass */ + rewind(file); + + glmSecondPass(model, file); + + /* close the file */ + fclose(file); + + return model; +} + +/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to + * a file. + * + * model - initialized GLMmodel structure + * filename - name of the file to write the Wavefront .OBJ format data to + * mode - a bitwise or of values describing what is written to the file + * GLM_NONE - render with only vertices + * GLM_FLAT - render with facet normals + * GLM_SMOOTH - render with vertex normals + * GLM_TEXTURE - render with texture coords + * GLM_COLOR - render with colors (color material) + * GLM_MATERIAL - render with materials + * GLM_COLOR and GLM_MATERIAL should not both be specified. + * GLM_FLAT and GLM_SMOOTH should not both be specified. + */ +GLvoid +glmWriteOBJ(GLMmodel* model, char* filename, GLuint mode) +{ + GLuint i; + FILE* file; + GLMgroup* group; + + assert(model); + + /* do a bit of warning */ + if (mode & GLM_FLAT && !model->facetnorms) { + printf("glmWriteOBJ() warning: flat normal output requested " + "with no facet normals defined.\n"); + mode &= ~GLM_FLAT; + } + if (mode & GLM_SMOOTH && !model->normals) { + printf("glmWriteOBJ() warning: smooth normal output requested " + "with no normals defined.\n"); + mode &= ~GLM_SMOOTH; + } + if (mode & GLM_TEXTURE && !model->texcoords) { + printf("glmWriteOBJ() warning: texture coordinate output requested " + "with no texture coordinates defined.\n"); + mode &= ~GLM_TEXTURE; + } + if (mode & GLM_FLAT && mode & GLM_SMOOTH) { + printf("glmWriteOBJ() warning: flat normal output requested " + "and smooth normal output requested (using smooth).\n"); + mode &= ~GLM_FLAT; + } + if (mode & GLM_COLOR && !model->materials) { + printf("glmWriteOBJ() warning: color output requested " + "with no colors (materials) defined.\n"); + mode &= ~GLM_COLOR; + } + if (mode & GLM_MATERIAL && !model->materials) { + printf("glmWriteOBJ() warning: material output requested " + "with no materials defined.\n"); + mode &= ~GLM_MATERIAL; + } + if (mode & GLM_COLOR && mode & GLM_MATERIAL) { + printf("glmDraw() warning: color and material output requested " + "outputting only materials.\n"); + mode &= ~GLM_COLOR; + } + + + /* open the file */ + file = fopen(filename, "w"); + if (!file) { + fprintf(stderr, "glmWriteOBJ() failed: can't open file \"%s\" to write.\n", + filename); + exit(1); + } + + /* spit out a header */ + fprintf(file, "# \n"); + fprintf(file, "# Wavefront OBJ generated by GLM library\n"); + fprintf(file, "# \n"); + fprintf(file, "# GLM library\n"); + fprintf(file, "# Nate Robins\n"); + fprintf(file, "# ndr@pobox.com\n"); + fprintf(file, "# http://www.pobox.com/~ndr\n"); + fprintf(file, "# \n"); + + if (mode & GLM_MATERIAL && model->mtllibname) { + fprintf(file, "\nmtllib %s\n\n", model->mtllibname); + glmWriteMTL(model, filename, model->mtllibname); + } + + /* spit out the vertices */ + fprintf(file, "\n"); + fprintf(file, "# %d vertices\n", model->numvertices); + for (i = 1; i <= model->numvertices; i++) { + fprintf(file, "v %f %f %f\n", + model->vertices[3 * i + 0], + model->vertices[3 * i + 1], + model->vertices[3 * i + 2]); + } + + /* spit out the smooth/flat normals */ + if (mode & GLM_SMOOTH) { + fprintf(file, "\n"); + fprintf(file, "# %d normals\n", model->numnormals); + for (i = 1; i <= model->numnormals; i++) { + fprintf(file, "vn %f %f %f\n", + model->normals[3 * i + 0], + model->normals[3 * i + 1], + model->normals[3 * i + 2]); + } + } else if (mode & GLM_FLAT) { + fprintf(file, "\n"); + fprintf(file, "# %d normals\n", model->numfacetnorms); + for (i = 1; i <= model->numnormals; i++) { + fprintf(file, "vn %f %f %f\n", + model->facetnorms[3 * i + 0], + model->facetnorms[3 * i + 1], + model->facetnorms[3 * i + 2]); + } + } + + /* spit out the texture coordinates */ + if (mode & GLM_TEXTURE) { + fprintf(file, "\n"); + fprintf(file, "# %d texcoords\n", model->texcoords); + for (i = 1; i <= model->numtexcoords; i++) { + fprintf(file, "vt %f %f\n", + model->texcoords[2 * i + 0], + model->texcoords[2 * i + 1]); + } + } + + fprintf(file, "\n"); + fprintf(file, "# %d groups\n", model->numgroups); + fprintf(file, "# %d faces (triangles)\n", model->numtriangles); + fprintf(file, "\n"); + + group = model->groups; + while(group) { + fprintf(file, "g %s\n", group->name); + if (mode & GLM_MATERIAL) + fprintf(file, "usemtl %s\n", model->materials[group->material].name); + for (i = 0; i < group->numtriangles; i++) { + if (mode & GLM_SMOOTH && mode & GLM_TEXTURE) { + fprintf(file, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).nindices[0], + T(group->triangles[i]).tindices[0], + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).nindices[1], + T(group->triangles[i]).tindices[1], + T(group->triangles[i]).vindices[2], + T(group->triangles[i]).nindices[2], + T(group->triangles[i]).tindices[2]); + } else if (mode & GLM_FLAT && mode & GLM_TEXTURE) { + fprintf(file, "f %d/%d %d/%d %d/%d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).findex, + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).findex, + T(group->triangles[i]).vindices[2], + T(group->triangles[i]).findex); + } else if (mode & GLM_TEXTURE) { + fprintf(file, "f %d/%d %d/%d %d/%d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).tindices[0], + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).tindices[1], + T(group->triangles[i]).vindices[2], + T(group->triangles[i]).tindices[2]); + } else if (mode & GLM_SMOOTH) { + fprintf(file, "f %d//%d %d//%d %d//%d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).nindices[0], + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).nindices[1], + T(group->triangles[i]).vindices[2], + T(group->triangles[i]).nindices[2]); + } else if (mode & GLM_FLAT) { + fprintf(file, "f %d//%d %d//%d %d//%d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).findex, + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).findex, + T(group->triangles[i]).vindices[2], + T(group->triangles[i]).findex); + } else { + fprintf(file, "f %d %d %d\n", + T(group->triangles[i]).vindices[0], + T(group->triangles[i]).vindices[1], + T(group->triangles[i]).vindices[2]); + } + } + fprintf(file, "\n"); + group = group->next; + } + + fclose(file); +} + +/* glmDraw: Renders the model to the current OpenGL context using the + * mode specified. + * + * model - initialized GLMmodel structure + * mode - a bitwise OR of values describing what is to be rendered. + * GLM_NONE - render with only vertices + * GLM_FLAT - render with facet normals + * GLM_SMOOTH - render with vertex normals + * GLM_TEXTURE - render with texture coords + * GLM_COLOR - render with colors (color material) + * GLM_MATERIAL - render with materials + * GLM_COLOR and GLM_MATERIAL should not both be specified. + * GLM_FLAT and GLM_SMOOTH should not both be specified. + */ +GLvoid +glmDraw(GLMmodel* model, GLuint mode) +{ + static GLuint i; + static GLMgroup* group; + static GLMtriangle* triangle; + static GLMmaterial* material; + + assert(model); + assert(model->vertices); + + /* do a bit of warning */ + if (mode & GLM_FLAT && !model->facetnorms) { + printf("glmDraw() warning: flat render mode requested " + "with no facet normals defined.\n"); + mode &= ~GLM_FLAT; + } + if (mode & GLM_SMOOTH && !model->normals) { + printf("glmDraw() warning: smooth render mode requested " + "with no normals defined.\n"); + mode &= ~GLM_SMOOTH; + } + if (mode & GLM_TEXTURE && !model->texcoords) { + printf("glmDraw() warning: texture render mode requested " + "with no texture coordinates defined.\n"); + mode &= ~GLM_TEXTURE; + } + if (mode & GLM_FLAT && mode & GLM_SMOOTH) { + printf("glmDraw() warning: flat render mode requested " + "and smooth render mode requested (using smooth).\n"); + mode &= ~GLM_FLAT; + } + if (mode & GLM_COLOR && !model->materials) { + printf("glmDraw() warning: color render mode requested " + "with no materials defined.\n"); + mode &= ~GLM_COLOR; + } + if (mode & GLM_MATERIAL && !model->materials) { + printf("glmDraw() warning: material render mode requested " + "with no materials defined.\n"); + mode &= ~GLM_MATERIAL; + } + if (mode & GLM_COLOR && mode & GLM_MATERIAL) { + printf("glmDraw() warning: color and material render mode requested " + "using only material mode.\n"); + mode &= ~GLM_COLOR; + } + if (mode & GLM_COLOR) + glEnable(GL_COLOR_MATERIAL); + else if (mode & GLM_MATERIAL) + glDisable(GL_COLOR_MATERIAL); + + /* perhaps this loop should be unrolled into material, color, flat, + smooth, etc. loops? since most cpu's have good branch prediction + schemes (and these branches will always go one way), probably + wouldn't gain too much? */ + + group = model->groups; + while (group) { + if (mode & GLM_MATERIAL) { + material = &model->materials[group->material]; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material->specular); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess); + } + + if (mode & GLM_COLOR) { + material = &model->materials[group->material]; + glColor3fv(material->diffuse); + } + + glBegin(GL_TRIANGLES); + for (i = 0; i < group->numtriangles; i++) { + triangle = &T(group->triangles[i]); + + if (mode & GLM_FLAT) + glNormal3fv(&model->facetnorms[3 * triangle->findex]); + + if (mode & GLM_SMOOTH) + glNormal3fv(&model->normals[3 * triangle->nindices[0]]); + if (mode & GLM_TEXTURE) + glTexCoord2fv(&model->texcoords[2 * triangle->tindices[0]]); + glVertex3fv(&model->vertices[3 * triangle->vindices[0]]); + + if (mode & GLM_SMOOTH) + glNormal3fv(&model->normals[3 * triangle->nindices[1]]); + if (mode & GLM_TEXTURE) + glTexCoord2fv(&model->texcoords[2 * triangle->tindices[1]]); + glVertex3fv(&model->vertices[3 * triangle->vindices[1]]); + + if (mode & GLM_SMOOTH) + glNormal3fv(&model->normals[3 * triangle->nindices[2]]); + if (mode & GLM_TEXTURE) + glTexCoord2fv(&model->texcoords[2 * triangle->tindices[2]]); + glVertex3fv(&model->vertices[3 * triangle->vindices[2]]); + + } + glEnd(); + + group = group->next; + } +} + +/* glmList: Generates and returns a display list for the model using + * the mode specified. + * + * model - initialized GLMmodel structure + * mode - a bitwise OR of values describing what is to be rendered. + * GLM_NONE - render with only vertices + * GLM_FLAT - render with facet normals + * GLM_SMOOTH - render with vertex normals + * GLM_TEXTURE - render with texture coords + * GLM_COLOR - render with colors (color material) + * GLM_MATERIAL - render with materials + * GLM_COLOR and GLM_MATERIAL should not both be specified. + * GLM_FLAT and GLM_SMOOTH should not both be specified. */ +GLuint +glmList(GLMmodel* model, GLuint mode) +{ + GLuint list; + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + glmDraw(model, mode); + glEndList(); + + return list; +} + +/* glmWeld: eliminate (weld) vectors that are within an epsilon of + * each other. + * + * model - initialized GLMmodel structure + * epsilon - maximum difference between vertices + * ( 0.00001 is a good start for a unitized model) + * + */ +GLuint +glmWeld(GLMmodel* model, GLfloat epsilon) +{ + GLfloat* vectors; + GLfloat* copies; + GLuint numvectors; + GLuint i, welded; + + /* vertices */ + numvectors = model->numvertices; + vectors = model->vertices; + copies = glmWeldVectors(vectors, &numvectors, epsilon); + welded = model->numvertices - numvectors - 1; + + for (i = 0; i < model->numtriangles; i++) { + T(i).vindices[0] = (GLuint)vectors[3 * T(i).vindices[0] + 0]; + T(i).vindices[1] = (GLuint)vectors[3 * T(i).vindices[1] + 0]; + T(i).vindices[2] = (GLuint)vectors[3 * T(i).vindices[2] + 0]; + } + + /* free space for old vertices */ + free(vectors); + + /* allocate space for the new vertices */ + model->numvertices = numvectors; + model->vertices = (GLfloat*)malloc(sizeof(GLfloat) * + 3 * (model->numvertices + 1)); + + /* copy the optimized vertices into the actual vertex list */ + for (i = 1; i <= model->numvertices; i++) { + model->vertices[3 * i + 0] = copies[3 * i + 0]; + model->vertices[3 * i + 1] = copies[3 * i + 1]; + model->vertices[3 * i + 2] = copies[3 * i + 2]; + } + + free(copies); + + return welded; +} + + +#if 0 + /* normals */ + if (model->numnormals) { + numvectors = model->numnormals; + vectors = model->normals; + copies = glmOptimizeVectors(vectors, &numvectors); + + printf("glmOptimize(): %d redundant normals.\n", + model->numnormals - numvectors); + + for (i = 0; i < model->numtriangles; i++) { + T(i).nindices[0] = (GLuint)vectors[3 * T(i).nindices[0] + 0]; + T(i).nindices[1] = (GLuint)vectors[3 * T(i).nindices[1] + 0]; + T(i).nindices[2] = (GLuint)vectors[3 * T(i).nindices[2] + 0]; + } + + /* free space for old normals */ + free(vectors); + + /* allocate space for the new normals */ + model->numnormals = numvectors; + model->normals = (GLfloat*)malloc(sizeof(GLfloat) * + 3 * (model->numnormals + 1)); + + /* copy the optimized vertices into the actual vertex list */ + for (i = 1; i <= model->numnormals; i++) { + model->normals[3 * i + 0] = copies[3 * i + 0]; + model->normals[3 * i + 1] = copies[3 * i + 1]; + model->normals[3 * i + 2] = copies[3 * i + 2]; + } + + free(copies); + } + + /* texcoords */ + if (model->numtexcoords) { + numvectors = model->numtexcoords; + vectors = model->texcoords; + copies = glmOptimizeVectors(vectors, &numvectors); + + printf("glmOptimize(): %d redundant texcoords.\n", + model->numtexcoords - numvectors); + + for (i = 0; i < model->numtriangles; i++) { + for (j = 0; j < 3; j++) { + T(i).tindices[j] = (GLuint)vectors[3 * T(i).tindices[j] + 0]; + } + } + + /* free space for old texcoords */ + free(vectors); + + /* allocate space for the new texcoords */ + model->numtexcoords = numvectors; + model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * + 2 * (model->numtexcoords + 1)); + + /* copy the optimized vertices into the actual vertex list */ + for (i = 1; i <= model->numtexcoords; i++) { + model->texcoords[2 * i + 0] = copies[2 * i + 0]; + model->texcoords[2 * i + 1] = copies[2 * i + 1]; + } + + free(copies); + } +#endif + +#if 0 + /* look for unused vertices */ + /* look for unused normals */ + /* look for unused texcoords */ + for (i = 1; i <= model->numvertices; i++) { + for (j = 0; j < model->numtriangles; i++) { + if (T(j).vindices[0] == i || + T(j).vindices[1] == i || + T(j).vindices[1] == i) + break; + } + } +#endif diff --git a/lib/glut-3.7.6/progs/demos/smooth/glm.h b/lib/glut-3.7.6/progs/demos/smooth/glm.h new file mode 100644 index 0000000000..bd31b98b14 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/glm.h @@ -0,0 +1,247 @@ +/* + glm.h + Nate Robins, 1997 + ndr@pobox.com, http://www.pobox.com/~ndr/ + + Wavefront OBJ model file format reader/writer/manipulator. + + Includes routines for generating smooth normals with + preservation of edges, welding redundant vertices & texture + coordinate generation (spheremap and planar projections) + more. + + */ + + +#include + + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +#define GLM_NONE (0) /* render with only vertices */ +#define GLM_FLAT (1 << 0) /* render with facet normals */ +#define GLM_SMOOTH (1 << 1) /* render with vertex normals */ +#define GLM_TEXTURE (1 << 2) /* render with texture coords */ +#define GLM_COLOR (1 << 3) /* render with colors */ +#define GLM_MATERIAL (1 << 4) /* render with materials */ + + +/* GLMmaterial: Structure that defines a material in a model. + */ +typedef struct _GLMmaterial +{ + char* name; /* name of material */ + GLfloat diffuse[4]; /* diffuse component */ + GLfloat ambient[4]; /* ambient component */ + GLfloat specular[4]; /* specular component */ + GLfloat emmissive[4]; /* emmissive component */ + GLfloat shininess; /* specular exponent */ +} GLMmaterial; + +/* GLMtriangle: Structure that defines a triangle in a model. + */ +typedef struct _GLMtriangle { + GLuint vindices[3]; /* array of triangle vertex indices */ + GLuint nindices[3]; /* array of triangle normal indices */ + GLuint tindices[3]; /* array of triangle texcoord indices*/ + GLuint findex; /* index of triangle facet normal */ +} GLMtriangle; + +/* GLMgroup: Structure that defines a group in a model. + */ +typedef struct _GLMgroup { + char* name; /* name of this group */ + GLuint numtriangles; /* number of triangles in this group */ + GLuint* triangles; /* array of triangle indices */ + GLuint material; /* index to material for group */ + struct _GLMgroup* next; /* pointer to next group in model */ +} GLMgroup; + +/* GLMmodel: Structure that defines a model. + */ +typedef struct _GLMmodel { + char* pathname; /* path to this model */ + char* mtllibname; /* name of the material library */ + + GLuint numvertices; /* number of vertices in model */ + GLfloat* vertices; /* array of vertices */ + + GLuint numnormals; /* number of normals in model */ + GLfloat* normals; /* array of normals */ + + GLuint numtexcoords; /* number of texcoords in model */ + GLfloat* texcoords; /* array of texture coordinates */ + + GLuint numfacetnorms; /* number of facetnorms in model */ + GLfloat* facetnorms; /* array of facetnorms */ + + GLuint numtriangles; /* number of triangles in model */ + GLMtriangle* triangles; /* array of triangles */ + + GLuint nummaterials; /* number of materials in model */ + GLMmaterial* materials; /* array of materials */ + + GLuint numgroups; /* number of groups in model */ + GLMgroup* groups; /* linked list of groups */ + + GLfloat position[3]; /* position of the model */ + +} GLMmodel; + + +/* glmUnitize: "unitize" a model by translating it to the origin and + * scaling it to fit in a unit cube around the origin. Returns the + * scalefactor used. + * + * model - properly initialized GLMmodel structure + */ +GLfloat +glmUnitize(GLMmodel* model); + +/* glmDimensions: Calculates the dimensions (width, height, depth) of + * a model. + * + * model - initialized GLMmodel structure + * dimensions - array of 3 GLfloats (GLfloat dimensions[3]) + */ +GLvoid +glmDimensions(GLMmodel* model, GLfloat* dimensions); + +/* glmScale: Scales a model by a given amount. + * + * model - properly initialized GLMmodel structure + * scale - scalefactor (0.5 = half as large, 2.0 = twice as large) + */ +GLvoid +glmScale(GLMmodel* model, GLfloat scale); + +/* glmReverseWinding: Reverse the polygon winding for all polygons in + * this model. Default winding is counter-clockwise. Also changes + * the direction of the normals. + * + * model - properly initialized GLMmodel structure + */ +GLvoid +glmReverseWinding(GLMmodel* model); + +/* glmFacetNormals: Generates facet normals for a model (by taking the + * cross product of the two vectors derived from the sides of each + * triangle). Assumes a counter-clockwise winding. + * + * model - initialized GLMmodel structure + */ +GLvoid +glmFacetNormals(GLMmodel* model); + +/* glmVertexNormals: Generates smooth vertex normals for a model. + * First builds a list of all the triangles each vertex is in. Then + * loops through each vertex in the the list averaging all the facet + * normals of the triangles each vertex is in. Finally, sets the + * normal index in the triangle for the vertex to the generated smooth + * normal. If the dot product of a facet normal and the facet normal + * associated with the first triangle in the list of triangles the + * current vertex is in is greater than the cosine of the angle + * parameter to the function, that facet normal is not added into the + * average normal calculation and the corresponding vertex is given + * the facet normal. This tends to preserve hard edges. The angle to + * use depends on the model, but 90 degrees is usually a good start. + * + * model - initialized GLMmodel structure + * angle - maximum angle (in degrees) to smooth across + */ +GLvoid +glmVertexNormals(GLMmodel* model, GLfloat angle); + +/* glmLinearTexture: Generates texture coordinates according to a + * linear projection of the texture map. It generates these by + * linearly mapping the vertices onto a square. + * + * model - pointer to initialized GLMmodel structure + */ +GLvoid +glmLinearTexture(GLMmodel* model); + +/* glmSpheremapTexture: Generates texture coordinates according to a + * spherical projection of the texture map. Sometimes referred to as + * spheremap, or reflection map texture coordinates. It generates + * these by using the normal to calculate where that vertex would map + * onto a sphere. Since it is impossible to map something flat + * perfectly onto something spherical, there is distortion at the + * poles. This particular implementation causes the poles along the X + * axis to be distorted. + * + * model - pointer to initialized GLMmodel structure + */ +GLvoid +glmSpheremapTexture(GLMmodel* model); + +/* glmDelete: Deletes a GLMmodel structure. + * + * model - initialized GLMmodel structure + */ +GLvoid +glmDelete(GLMmodel* model); + +/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file. + * Returns a pointer to the created object which should be free'd with + * glmDelete(). + * + * filename - name of the file containing the Wavefront .OBJ format data. + */ +GLMmodel* +glmReadOBJ(char* filename); + +/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to + * a file. + * + * model - initialized GLMmodel structure + * filename - name of the file to write the Wavefront .OBJ format data to + * mode - a bitwise or of values describing what is written to the file + * GLM_NONE - write only vertices + * GLM_FLAT - write facet normals + * GLM_SMOOTH - write vertex normals + * GLM_TEXTURE - write texture coords + * GLM_FLAT and GLM_SMOOTH should not both be specified. + */ +GLvoid +glmWriteOBJ(GLMmodel* model, char* filename, GLuint mode); + +/* glmDraw: Renders the model to the current OpenGL context using the + * mode specified. + * + * model - initialized GLMmodel structure + * mode - a bitwise OR of values describing what is to be rendered. + * GLM_NONE - render with only vertices + * GLM_FLAT - render with facet normals + * GLM_SMOOTH - render with vertex normals + * GLM_TEXTURE - render with texture coords + * GLM_FLAT and GLM_SMOOTH should not both be specified. + */ +GLvoid +glmDraw(GLMmodel* model, GLuint mode); + +/* glmList: Generates and returns a display list for the model using + * the mode specified. + * + * model - initialized GLMmodel structure + * mode - a bitwise OR of values describing what is to be rendered. + * GLM_NONE - render with only vertices + * GLM_FLAT - render with facet normals + * GLM_SMOOTH - render with vertex normals + * GLM_TEXTURE - render with texture coords + * GLM_FLAT and GLM_SMOOTH should not both be specified. + */ +GLuint +glmList(GLMmodel* model, GLuint mode); + +/* glmWeld: eliminate (weld) vectors that are within an epsilon of + * each other. + * + * model - initialized GLMmodel structure + * epsilon - maximum difference between vertices + * ( 0.00001 is a good start for a unitized model) + * + */ +GLuint +glmWeld(GLMmodel* model, GLfloat epsilon); diff --git a/lib/glut-3.7.6/progs/demos/smooth/gltb.c b/lib/glut-3.7.6/progs/demos/smooth/gltb.c new file mode 100644 index 0000000000..f666370139 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/gltb.c @@ -0,0 +1,173 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +#include +#include +#include +#include +#include "gltb.h" + + +#define GLTB_TIME_EPSILON 10 + + +static GLuint gltb_lasttime; +static GLfloat gltb_lastposition[3]; + +static GLfloat gltb_angle = 0.0; +static GLfloat gltb_axis[3]; +static GLfloat gltb_transform[4][4]; + +static GLuint gltb_width; +static GLuint gltb_height; + +static GLint gltb_button = -1; +static GLboolean gltb_tracking = GL_FALSE; +static GLboolean gltb_animate = GL_TRUE; + + +static void +_gltbPointToVector(int x, int y, int width, int height, float v[3]) +{ + float d, a; + + /* project x, y onto a hemi-sphere centered within width, height. */ + v[0] = (2.0 * x - width) / width; + v[1] = (height - 2.0 * y) / height; + d = sqrt(v[0] * v[0] + v[1] * v[1]); + v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0)); + a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] *= a; + v[1] *= a; + v[2] *= a; +} + +static void +_gltbAnimate(void) +{ + glutPostRedisplay(); +} + +void +_gltbStartMotion(int x, int y, int button, int time) +{ + assert(gltb_button != -1); + + gltb_tracking = GL_TRUE; + gltb_lasttime = time; + _gltbPointToVector(x, y, gltb_width, gltb_height, gltb_lastposition); +} + +void +_gltbStopMotion(int button, unsigned time) +{ + assert(gltb_button != -1); + + gltb_tracking = GL_FALSE; + + if (time - gltb_lasttime < GLTB_TIME_EPSILON && gltb_animate) { + glutIdleFunc(_gltbAnimate); + } else { + gltb_angle = 0; + if (gltb_animate) + glutIdleFunc(0); + } +} + +void +gltbAnimate(GLboolean animate) +{ + gltb_animate = animate; +} + +void +gltbInit(GLuint button) +{ + gltb_button = button; + gltb_angle = 0.0; + + /* put the identity in the trackball transform */ + glPushMatrix(); + glLoadIdentity(); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)gltb_transform); + glPopMatrix(); +} + +void +gltbMatrix(void) +{ + assert(gltb_button != -1); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(gltb_angle, gltb_axis[0], gltb_axis[1], gltb_axis[2]); + glMultMatrixf((GLfloat*)gltb_transform); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)gltb_transform); + glPopMatrix(); + + glMultMatrixf((GLfloat*)gltb_transform); +} + +void +gltbReshape(int width, int height) +{ + assert(gltb_button != -1); + + gltb_width = width; + gltb_height = height; +} + +void +gltbMouse(int button, int state, int x, int y) +{ + assert(gltb_button != -1); + + if (state == GLUT_DOWN && button == gltb_button) + _gltbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP && button == gltb_button) + _gltbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); +} + +void +gltbMotion(int x, int y) +{ + GLfloat current_position[3], dx, dy, dz; + + assert(gltb_button != -1); + + if (gltb_tracking == GL_FALSE) + return; + + _gltbPointToVector(x, y, gltb_width, gltb_height, current_position); + + /* calculate the angle to rotate by (directly proportional to the + length of the mouse movement) */ + dx = current_position[0] - gltb_lastposition[0]; + dy = current_position[1] - gltb_lastposition[1]; + dz = current_position[2] - gltb_lastposition[2]; + gltb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); + + /* calculate the axis of rotation (cross product) */ + gltb_axis[0] = gltb_lastposition[1] * current_position[2] - + gltb_lastposition[2] * current_position[1]; + gltb_axis[1] = gltb_lastposition[2] * current_position[0] - + gltb_lastposition[0] * current_position[2]; + gltb_axis[2] = gltb_lastposition[0] * current_position[1] - + gltb_lastposition[1] * current_position[0]; + + /* XXX - constrain motion */ + gltb_axis[2] = 0; + + /* reset for next time */ + gltb_lasttime = glutGet(GLUT_ELAPSED_TIME); + gltb_lastposition[0] = current_position[0]; + gltb_lastposition[1] = current_position[1]; + gltb_lastposition[2] = current_position[2]; + + /* remember to draw new position */ + glutPostRedisplay(); +} diff --git a/lib/glut-3.7.6/progs/demos/smooth/gltb.h b/lib/glut-3.7.6/progs/demos/smooth/gltb.h new file mode 100644 index 0000000000..01666eb1e9 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/gltb.h @@ -0,0 +1,95 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + * + * + * Usage: + * + * o call gltbInit() in before any other gltb call + * o call gltbReshape() from the reshape callback + * o call gltbMatrix() to get the trackball matrix rotation + * o call gltbStartMotion() to begin trackball movememt + * o call gltbStopMotion() to stop trackball movememt + * o call gltbMotion() from the motion callback + * o call gltbAnimate(GL_TRUE) if you want the trackball to continue + * spinning after the mouse button has been released + * o call gltbAnimate(GL_FALSE) if you want the trackball to stop + * spinning after the mouse button has been released + * + * Typical setup: + * + * + void + init(void) + { + gltbInit(GLUT_MIDDLE_BUTTON); + gltbAnimate(GL_TRUE); + . . . + } + + void + reshape(int width, int height) + { + gltbReshape(width, height); + . . . + } + + void + display(void) + { + glPushMatrix(); + + gltbMatrix(); + . . . draw the scene . . . + + glPopMatrix(); + } + + void + mouse(int button, int state, int x, int y) + { + gltbMouse(button, state, x, y); + . . . + } + + void + motion(int x, int y) + { + gltbMotion(x, y); + . . . + } + + int + main(int argc, char** argv) + { + . . . + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutMotionFunc(motion); + . . . + } + * + * */ + + +/* functions */ +void +gltbInit(GLuint button); + +void +gltbMatrix(void); + +void +gltbReshape(int width, int height); + +void +gltbMouse(int button, int state, int x, int y); + +void +gltbMotion(int x, int y); + +void +gltbAnimate(GLboolean animate); diff --git a/lib/glut-3.7.6/progs/demos/smooth/gltx.c b/lib/glut-3.7.6/progs/demos/smooth/gltx.c new file mode 100644 index 0000000000..047f0d12d7 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/gltx.c @@ -0,0 +1,240 @@ +/* + * Simple SGI .rgb (IRIS RGB) image file reader ripped off from + * texture.c (written by David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include +#include +#include +#include +#include "gltx.h" + + +/* private typedefs */ +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; + unsigned long rleEnd; + GLuint *rowStart; + GLint *rowSize; +} rawImageRec; + + +/* private functions */ +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 ConvertLong(GLuint *array, unsigned int 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(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) { + return NULL; + } + if ((raw->file = fopen(fileName, "rb")) == NULL) { + 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->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL || + raw->tmpB == NULL) { + 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) { + 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, x/sizeof(GLuint)); + ConvertLong((GLuint *)raw->rowSize, 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); + + free(raw); +} + +static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) +{ + unsigned char *iPtr, *oPtr, pixel; + int count; + + 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; + 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(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, GLTXimage *image) +{ + unsigned char *ptr; + int i, j; + + image->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4); + if (image->data == NULL) { + return; + } + + ptr = image->data; + for (i = 0; i < raw->sizeY; i++) { + RawImageGetRow(raw, raw->tmpR, i, 0); + RawImageGetRow(raw, raw->tmpG, i, 1); + RawImageGetRow(raw, raw->tmpB, i, 2); + for (j = 0; j < raw->sizeX; j++) { + *ptr++ = *(raw->tmpR + j); + *ptr++ = *(raw->tmpG + j); + *ptr++ = *(raw->tmpB + j); + } + } +} + + + +/* public functions */ + +/* gltxDelete: Deletes a texture image + * + * image - properly initialized GLTXimage structure + */ +void +gltxDelete(GLTXimage* image) +{ + assert(image); + + free(image->data); + free(image); +} + +/* gltxReadRGB: Reads and returns data from an IRIS RGB image file. + * + * filename - name of the IRIS RGB file to read data from + */ +GLTXimage* +gltxReadRGB(char *filename) +{ + rawImageRec *raw; + GLTXimage* image; + + raw = RawImageOpen(filename); + if(!raw) { + fprintf(stderr, "gltxReadRGB() failed: can't open image file \"%s\".\n", + filename); + return NULL; + } + image = (GLTXimage*)malloc(sizeof(GLTXimage)); + if (image == NULL) { + fprintf(stderr, "gltxReadRGB() failed: insufficient memory.\n"); + return NULL; + } + + image->width = raw->sizeX; + image->height = raw->sizeY; + image->components = raw->sizeZ; + RawImageGetData(raw, image); + RawImageClose(raw); + + return image; +} diff --git a/lib/glut-3.7.6/progs/demos/smooth/gltx.h b/lib/glut-3.7.6/progs/demos/smooth/gltx.h new file mode 100644 index 0000000000..3dc4bb3034 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/gltx.h @@ -0,0 +1,35 @@ +/* + * Simple SGI .rgb (IRIS RGB) image file reader ripped off from + * texture.c (written by David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include + + +/* typedefs */ + +/* GLTXimage: Structure containing a texture image */ +typedef struct { + GLuint width; /* width of image */ + GLuint height; /* height of image */ + GLuint components; /* number of components in image */ + GLubyte* data; /* image data */ +} GLTXimage; + + +/* gltxDelete: Deletes a texture image + * + * image - properly initialized GLTXimage structure + */ +void +gltxDelete(GLTXimage* image); + +/* gltxReadRGB: Reads and returns data from an IRIS RGB image file. + * + * name - name of the IRIS RGB file to read data from + */ +GLTXimage* +gltxReadRGB(char *name); diff --git a/lib/glut-3.7.6/progs/demos/smooth/smooth.c b/lib/glut-3.7.6/progs/demos/smooth/smooth.c new file mode 100644 index 0000000000..7a918cb949 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/smooth.c @@ -0,0 +1,574 @@ +/* + smooth.c + Nate Robins, 1998 + + Model viewer program. Exercises the glm library. + */ + + +#include +#include +#include +#include +#include +#include +#include "gltb.h" +#include "glm.h" +#include "dirent32.h" + +#define DATA_DIR "data/" + +char* model_file = NULL; /* name of the obect file */ +GLuint model_list = 0; /* display list for object */ +GLMmodel* model; /* glm model data structure */ +GLfloat scale; /* original scale factor */ +GLfloat smoothing_angle = 90.0; /* smoothing angle */ +GLfloat weld_distance = 0.00001; /* epsilon for welding vertices */ +GLboolean facet_normal = GL_FALSE; /* draw with facet normal? */ +GLboolean bounding_box = GL_FALSE; /* bounding box on? */ +GLboolean performance = GL_FALSE; /* performance counter on? */ +GLboolean stats = GL_FALSE; /* statistics on? */ +GLuint material_mode = 0; /* 0=none, 1=color, 2=material */ +GLint entries = 0; /* entries in model menu */ +GLdouble pan_x = 0.0; +GLdouble pan_y = 0.0; +GLdouble pan_z = 0.0; + +#if defined(_WIN32) +#include +#else +#include +#include +#include +#include +#endif +#ifndef CLK_TCK +#define CLK_TCK 1000 +#endif +float +elapsed(void) +{ + static long begin = 0; + static long finish, difference; + +#if defined(_WIN32) + static struct timeb tb; + ftime(&tb); + finish = tb.time*1000+tb.millitm; +#else + static struct tms tb; + finish = times(&tb); +#endif + + difference = finish - begin; + begin = finish; + + return (float)difference/(float)CLK_TCK; +} + +void +shadowtext(int x, int y, char* s) +{ + int lines; + char* p; + + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), + 0, glutGet(GLUT_WINDOW_HEIGHT), -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glColor3ub(0, 0, 0); + glRasterPos2i(x+1, y-1); + for(p = s, lines = 0; *p; p++) { + if (*p == '\n') { + lines++; + glRasterPos2i(x+1, y-1-(lines*18)); + } + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p); + } + glColor3ub(0, 128, 255); + glRasterPos2i(x, y); + for(p = s, lines = 0; *p; p++) { + if (*p == '\n') { + lines++; + glRasterPos2i(x, y-(lines*18)); + } + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p); + } + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); +} + +void +lists(void) +{ + GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 }; + GLfloat diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; + GLfloat specular[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat shininess = 65.0; + + glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, specular); + glMaterialf(GL_FRONT, GL_SHININESS, shininess); + + if (model_list) + glDeleteLists(model_list, 1); + + /* generate a list */ + if (material_mode == 0) { + if (facet_normal) + model_list = glmList(model, GLM_FLAT); + else + model_list = glmList(model, GLM_SMOOTH); + } else if (material_mode == 1) { + if (facet_normal) + model_list = glmList(model, GLM_FLAT | GLM_COLOR); + else + model_list = glmList(model, GLM_SMOOTH | GLM_COLOR); + } else if (material_mode == 2) { + if (facet_normal) + model_list = glmList(model, GLM_FLAT | GLM_MATERIAL); + else + model_list = glmList(model, GLM_SMOOTH | GLM_MATERIAL); + } +} + +void +init(void) +{ + gltbInit(GLUT_LEFT_BUTTON); + + /* read in the model */ + model = glmReadOBJ(model_file); + scale = glmUnitize(model); + glmFacetNormals(model); + glmVertexNormals(model, smoothing_angle); + + if (model->nummaterials > 0) + material_mode = 2; + + /* create new display lists */ + lists(); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + glEnable(GL_DEPTH_TEST); + + glEnable(GL_CULL_FACE); +} + +void +reshape(int width, int height) +{ + gltbReshape(width, height); + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, (GLfloat)height / (GLfloat)width, 1.0, 128.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -3.0); +} + +#define NUM_FRAMES 5 +void +display(void) +{ + static char s[256], t[32]; + static char* p; + static int frames = 0; + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + glTranslatef(pan_x, pan_y, 0.0); + + gltbMatrix(); + +#if 0 /* glmDraw() performance test */ + if (material_mode == 0) { + if (facet_normal) + glmDraw(model, GLM_FLAT); + else + glmDraw(model, GLM_SMOOTH); + } else if (material_mode == 1) { + if (facet_normal) + glmDraw(model, GLM_FLAT | GLM_COLOR); + else + glmDraw(model, GLM_SMOOTH | GLM_COLOR); + } else if (material_mode == 2) { + if (facet_normal) + glmDraw(model, GLM_FLAT | GLM_MATERIAL); + else + glmDraw(model, GLM_SMOOTH | GLM_MATERIAL); + } +#else + glCallList(model_list); +#endif + + glDisable(GL_LIGHTING); + if (bounding_box) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glColor4f(1.0, 0.0, 0.0, 0.25); + glutSolidCube(2.0); + glDisable(GL_BLEND); + } + + glPopMatrix(); + + if (stats) { + /* XXX - this could be done a _whole lot_ faster... */ + int height = glutGet(GLUT_WINDOW_HEIGHT); + glColor3ub(0, 0, 0); + sprintf(s, "%s\n%d vertices\n%d triangles\n%d normals\n" + "%d texcoords\n%d groups\n%d materials", + model->pathname, model->numvertices, model->numtriangles, + model->numnormals, model->numtexcoords, model->numgroups, + model->nummaterials); + shadowtext(5, height-(5+18*1), s); + } + + /* spit out frame rate. */ + frames++; + if (frames > NUM_FRAMES) { + sprintf(t, "%g fps", frames/elapsed()); + frames = 0; + } + if (performance) { + shadowtext(5, 5, t); + } + + glutSwapBuffers(); + glEnable(GL_LIGHTING); +} + +void +keyboard(unsigned char key, int x, int y) +{ + GLint params[2]; + + switch (key) { + case 'h': + printf("help\n\n"); + printf("w - Toggle wireframe/filled\n"); + printf("c - Toggle culling\n"); + printf("n - Toggle facet/smooth normal\n"); + printf("b - Toggle bounding box\n"); + printf("r - Reverse polygon winding\n"); + printf("m - Toggle color/material/none mode\n"); + printf("p - Toggle performance indicator\n"); + printf("s/S - Scale model smaller/larger\n"); + printf("t - Show model stats\n"); + printf("o - Weld vertices in model\n"); + printf("+/- - Increase/decrease smoothing angle\n"); + printf("W - Write model to file (out.obj)\n"); + printf("q/escape - Quit\n\n"); + break; + + case 't': + stats = !stats; + break; + + case 'p': + performance = !performance; + break; + + case 'm': + material_mode++; + if (material_mode > 2) + material_mode = 0; + printf("material_mode = %d\n", material_mode); + lists(); + break; + + case 'd': + glmDelete(model); + init(); + lists(); + break; + + case 'w': + glGetIntegerv(GL_POLYGON_MODE, params); + if (params[0] == GL_FILL) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + + case 'c': + if (glIsEnabled(GL_CULL_FACE)) + glDisable(GL_CULL_FACE); + else + glEnable(GL_CULL_FACE); + break; + + case 'b': + bounding_box = !bounding_box; + break; + + case 'n': + facet_normal = !facet_normal; + lists(); + break; + + case 'r': + glmReverseWinding(model); + lists(); + break; + + case 's': + glmScale(model, 0.8); + lists(); + break; + + case 'S': + glmScale(model, 1.25); + lists(); + break; + + case 'o': + printf("Welded %d\n", glmWeld(model, weld_distance)); + glmVertexNormals(model, smoothing_angle); + lists(); + break; + + case 'O': + weld_distance += 0.01; + printf("Weld distance: %.2f\n", weld_distance); + glmWeld(model, weld_distance); + glmFacetNormals(model); + glmVertexNormals(model, smoothing_angle); + lists(); + break; + + case '-': + smoothing_angle -= 1.0; + printf("Smoothing angle: %.1f\n", smoothing_angle); + glmVertexNormals(model, smoothing_angle); + lists(); + break; + + case '+': + smoothing_angle += 1.0; + printf("Smoothing angle: %.1f\n", smoothing_angle); + glmVertexNormals(model, smoothing_angle); + lists(); + break; + + case 'W': + glmScale(model, 1.0/scale); + glmWriteOBJ(model, "out.obj", GLM_SMOOTH | GLM_MATERIAL); + break; + + case 'R': + { + GLuint i; + GLfloat swap; + for (i = 1; i <= model->numvertices; i++) { + swap = model->vertices[3 * i + 1]; + model->vertices[3 * i + 1] = model->vertices[3 * i + 2]; + model->vertices[3 * i + 2] = -swap; + } + glmFacetNormals(model); + lists(); + break; + } + + case 27: + exit(0); + break; + } + + glutPostRedisplay(); +} + +void +menu(int item) +{ + int i = 0; + DIR* dirp; + char* name; + struct dirent* direntp; + + if (item > 0) { + keyboard((unsigned char)item, 0, 0); + } else { + dirp = opendir(DATA_DIR); + while ((direntp = readdir(dirp)) != NULL) { + if (strstr(direntp->d_name, ".obj")) { + i++; + if (i == -item) + break; + } + } + if (!direntp) + return; + name = (char*)malloc(strlen(direntp->d_name) + strlen(DATA_DIR) + 1); + strcpy(name, DATA_DIR); + strcat(name, direntp->d_name); + model = glmReadOBJ(name); + scale = glmUnitize(model); + glmFacetNormals(model); + glmVertexNormals(model, smoothing_angle); + + if (model->nummaterials > 0) + material_mode = 2; + else + material_mode = 0; + + lists(); + free(name); + + glutPostRedisplay(); + } +} + +static GLint mouse_state; +static GLint mouse_button; + +void +mouse(int button, int state, int x, int y) +{ + GLdouble model[4*4]; + GLdouble proj[4*4]; + GLint view[4]; + + /* fix for two-button mice -- left mouse + shift = middle mouse */ + if (button == GLUT_LEFT_BUTTON && glutGetModifiers() & GLUT_ACTIVE_SHIFT) + button = GLUT_MIDDLE_BUTTON; + + gltbMouse(button, state, x, y); + + mouse_state = state; + mouse_button = button; + + if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON) { + glGetDoublev(GL_MODELVIEW_MATRIX, model); + glGetDoublev(GL_PROJECTION_MATRIX, proj); + glGetIntegerv(GL_VIEWPORT, view); + gluProject((GLdouble)x, (GLdouble)y, 0.0, + model, proj, view, + &pan_x, &pan_y, &pan_z); + gluUnProject((GLdouble)x, (GLdouble)y, pan_z, + model, proj, view, + &pan_x, &pan_y, &pan_z); + pan_y = -pan_y; + } + + glutPostRedisplay(); +} + +void +motion(int x, int y) +{ + GLdouble model[4*4]; + GLdouble proj[4*4]; + GLint view[4]; + + gltbMotion(x, y); + + if (mouse_state == GLUT_DOWN && mouse_button == GLUT_MIDDLE_BUTTON) { + glGetDoublev(GL_MODELVIEW_MATRIX, model); + glGetDoublev(GL_PROJECTION_MATRIX, proj); + glGetIntegerv(GL_VIEWPORT, view); + gluProject((GLdouble)x, (GLdouble)y, 0.0, + model, proj, view, + &pan_x, &pan_y, &pan_z); + gluUnProject((GLdouble)x, (GLdouble)y, pan_z, + model, proj, view, + &pan_x, &pan_y, &pan_z); + pan_y = -pan_y; + } + + glutPostRedisplay(); +} + +int +main(int argc, char** argv) +{ + int buffering = GLUT_DOUBLE; + struct dirent* direntp; + DIR* dirp; + int models; + + glutInitWindowSize(512, 512); + glutInit(&argc, argv); + + while (--argc) { + if (strcmp(argv[argc], "-sb") == 0) + buffering = GLUT_SINGLE; + else + model_file = argv[argc]; + } + + if (!model_file) { + model_file = "data/dolphins.obj"; + } + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | buffering); + glutCreateWindow("Smooth"); + + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + models = glutCreateMenu(menu); + dirp = opendir(DATA_DIR); + if (!dirp) { + fprintf(stderr, "%s: can't open data directory.\n", argv[0]); + } else { + while ((direntp = readdir(dirp)) != NULL) { + if (strstr(direntp->d_name, ".obj")) { + entries++; + glutAddMenuEntry(direntp->d_name, -entries); + } + } + closedir(dirp); + } + + glutCreateMenu(menu); + glutAddMenuEntry("Smooth", 0); + glutAddMenuEntry("", 0); + glutAddSubMenu("Models", models); + glutAddMenuEntry("", 0); + glutAddMenuEntry("[w] Toggle wireframe/filled", 'w'); + glutAddMenuEntry("[c] Toggle culling on/off", 'c'); + glutAddMenuEntry("[n] Toggle face/smooth normals", 'n'); + glutAddMenuEntry("[b] Toggle bounding box on/off", 'b'); + glutAddMenuEntry("[p] Toggle frame rate on/off", 'p'); + glutAddMenuEntry("[t] Toggle model statistics", 't'); + glutAddMenuEntry("[m] Toggle color/material/none mode", 'm'); + glutAddMenuEntry("[r] Reverse polygon winding", 'r'); + glutAddMenuEntry("[s] Scale model smaller", 's'); + glutAddMenuEntry("[S] Scale model larger", 'S'); + glutAddMenuEntry("[o] Weld redundant vertices", 'o'); + glutAddMenuEntry("[+] Increase smoothing angle", '+'); + glutAddMenuEntry("[-] Decrease smoothing angle", '-'); + glutAddMenuEntry("[W] Write model to file (out.obj)", 'W'); + glutAddMenuEntry("", 0); + glutAddMenuEntry("[Esc] Quit", 27); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + init(); + + glutMainLoop(); + return 0; +} diff --git a/lib/glut-3.7.6/progs/demos/smooth/smooth.dsp b/lib/glut-3.7.6/progs/demos/smooth/smooth.dsp new file mode 100644 index 0000000000..6344049eee --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/smooth.dsp @@ -0,0 +1,126 @@ +# Microsoft Developer Studio Project File - Name="smooth" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=smooth - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "smooth.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "smooth.mak" CFG="smooth - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "smooth - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "smooth - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "smooth - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glut32.lib glu32.lib opengl32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "smooth - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glut32.lib glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "smooth - Win32 Release" +# Name "smooth - Win32 Debug" +# Begin Source File + +SOURCE=.\dirent32.h +# End Source File +# Begin Source File + +SOURCE=.\glm.c +# End Source File +# Begin Source File + +SOURCE=.\glm.h +# End Source File +# Begin Source File + +SOURCE=.\gltb.c +# End Source File +# Begin Source File + +SOURCE=.\gltb.h +# End Source File +# Begin Source File + +SOURCE=.\gltx.c +# End Source File +# Begin Source File + +SOURCE=.\gltx.h +# End Source File +# Begin Source File + +SOURCE=.\smooth.c +# End Source File +# Begin Source File + +SOURCE=.\trackball.c +# End Source File +# Begin Source File + +SOURCE=.\trackball.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/smooth/trackball.c b/lib/glut-3.7.6/progs/demos/smooth/trackball.c new file mode 100644 index 0000000000..c2501e8f45 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/trackball.c @@ -0,0 +1,169 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include +#include +#include +#include "trackball.h" + + +/* globals */ +static GLuint tb_lasttime; +static GLfloat tb_lastposition[3]; + +static GLfloat tb_angle = 0.0; +static GLfloat tb_axis[3]; +static GLfloat tb_transform[4][4]; + +static GLuint tb_width; +static GLuint tb_height; + +static GLint tb_button = -1; +static GLboolean tb_tracking = GL_FALSE; +static GLboolean tb_animate = GL_TRUE; + + +/* functions */ +static void +_tbPointToVector(int x, int y, int width, int height, float v[3]) +{ + float d, a; + + /* project x, y onto a hemi-sphere centered within width, height. */ + v[0] = (2.0 * x - width) / width; + v[1] = (height - 2.0 * y) / height; + d = sqrt(v[0] * v[0] + v[1] * v[1]); + v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0)); + a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] *= a; + v[1] *= a; + v[2] *= a; +} + +static void +_tbAnimate(void) +{ + glutPostRedisplay(); +} + +void +_tbStartMotion(int x, int y, int button, int time) +{ + assert(tb_button != -1); + + tb_tracking = GL_TRUE; + tb_lasttime = time; + _tbPointToVector(x, y, tb_width, tb_height, tb_lastposition); +} + +void +_tbStopMotion(int button, unsigned time) +{ + assert(tb_button != -1); + + tb_tracking = GL_FALSE; + + if (time == tb_lasttime && tb_animate) { + glutIdleFunc(_tbAnimate); + } else { + tb_angle = 0.0; + if (tb_animate) + glutIdleFunc(0); + } +} + +void +tbAnimate(GLboolean animate) +{ + tb_animate = animate; +} + +void +tbInit(GLuint button) +{ + tb_button = button; + tb_angle = 0.0; + + /* put the identity in the trackball transform */ + glPushMatrix(); + glLoadIdentity(); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform); + glPopMatrix(); +} + +void +tbMatrix() +{ + assert(tb_button != -1); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(tb_angle, tb_axis[0], tb_axis[1], tb_axis[2]); + glMultMatrixf((GLfloat *)tb_transform); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform); + glPopMatrix(); + + glMultMatrixf((GLfloat *)tb_transform); +} + +void +tbReshape(int width, int height) +{ + assert(tb_button != -1); + + tb_width = width; + tb_height = height; +} + +void +tbMouse(int button, int state, int x, int y) +{ + assert(tb_button != -1); + + if (state == GLUT_DOWN && button == tb_button) + _tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP && button == tb_button) + _tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); +} + +void +tbMotion(int x, int y) +{ + GLfloat current_position[3], dx, dy, dz; + + assert(tb_button != -1); + + if (tb_tracking == GL_FALSE) + return; + + _tbPointToVector(x, y, tb_width, tb_height, current_position); + + /* calculate the angle to rotate by (directly proportional to the + length of the mouse movement */ + dx = current_position[0] - tb_lastposition[0]; + dy = current_position[1] - tb_lastposition[1]; + dz = current_position[2] - tb_lastposition[2]; + tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); + + /* calculate the axis of rotation (cross product) */ + tb_axis[0] = tb_lastposition[1] * current_position[2] - + tb_lastposition[2] * current_position[1]; + tb_axis[1] = tb_lastposition[2] * current_position[0] - + tb_lastposition[0] * current_position[2]; + tb_axis[2] = tb_lastposition[0] * current_position[1] - + tb_lastposition[1] * current_position[0]; + + /* reset for next time */ + tb_lasttime = glutGet(GLUT_ELAPSED_TIME); + tb_lastposition[0] = current_position[0]; + tb_lastposition[1] = current_position[1]; + tb_lastposition[2] = current_position[2]; + + /* remember to draw new position */ + glutPostRedisplay(); +} diff --git a/lib/glut-3.7.6/progs/demos/smooth/trackball.h b/lib/glut-3.7.6/progs/demos/smooth/trackball.h new file mode 100644 index 0000000000..de0f00c6bd --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/smooth/trackball.h @@ -0,0 +1,95 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + * + * + * Usage: + * + * o call tbInit() in before any other tb call + * o call tbReshape() from the reshape callback + * o call tbMatrix() to get the trackball matrix rotation + * o call tbStartMotion() to begin trackball movememt + * o call tbStopMotion() to stop trackball movememt + * o call tbMotion() from the motion callback + * o call tbAnimate(GL_TRUE) if you want the trackball to continue + * spinning after the mouse button has been released + * o call tbAnimate(GL_FALSE) if you want the trackball to stop + * spinning after the mouse button has been released + * + * Typical setup: + * + * + void + init(void) + { + tbInit(GLUT_MIDDLE_BUTTON); + tbAnimate(GL_TRUE); + . . . + } + + void + reshape(int width, int height) + { + tbReshape(width, height); + . . . + } + + void + display(void) + { + glPushMatrix(); + + tbMatrix(); + . . . draw the scene . . . + + glPopMatrix(); + } + + void + mouse(int button, int state, int x, int y) + { + tbMouse(button, state, x, y); + . . . + } + + void + motion(int x, int y) + { + tbMotion(x, y); + . . . + } + + int + main(int argc, char** argv) + { + . . . + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutMotionFunc(motion); + . . . + } + * + * */ + + +/* functions */ +void +tbInit(GLuint button); + +void +tbMatrix(void); + +void +tbReshape(int width, int height); + +void +tbMouse(int button, int state, int x, int y); + +void +tbMotion(int x, int y); + +void +tbAnimate(GLboolean animate); diff --git a/lib/glut-3.7.6/progs/demos/sunlight/Imakefile b/lib/glut-3.7.6/progs/demos/sunlight/Imakefile new file mode 100644 index 0000000000..9b5d15868b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/sunlight/Imakefile @@ -0,0 +1,15 @@ + +/* Copyright (c) Mark J. Kilgard, 1998. */ + +#include "../../../Glut.cf" + +TARGETS = sunlight + +SRCS = sunlight.c +OBJS = sunlight.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(sunlight,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/sunlight/globe.raw b/lib/glut-3.7.6/progs/demos/sunlight/globe.raw new file mode 100644 index 0000000000000000000000000000000000000000..7ac4dc6f4b319f0646b223ff8e2795c7bfe825e7 GIT binary patch literal 196612 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%0A3l8i;pMC6PhY=$2pUm;{^ZHC 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

    es3L&PdxEC#!Obv` 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

    !V&kpJGz{?yk17G?F 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

    dm&i>6y`|jUqd`XQ9ZV_$v36g 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�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 +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* menu constants */ +#define MENU_SHOW_GLOBE 1 +#define MENU_SHOW_MAP 2 +#define MENU_ADJUST_GLOBE 3 +#define MENU_ADJUST_DAY 4 +#define MENU_ADJUST_TIME 5 +#define MENU_QUIT 6 + +static int mapMode = 0; +static int adjustMode = 0; +static GLdouble aspectRatio = 1.0; +static double timeOfDay = 0.0; +static double timeOfYear = 0.0; + +/* + * sun direction functions + */ + +static const double radPerDeg = M_PI / 180.0; +static const double radPerHour = M_PI / 12.0; +static const double siderealHoursPerHour = 1.002737908; +static const double epoch = 2415020.0; + +static double getGreenwichSideral(double julianDay) +{ + double jdMidnight; + double dayFraction; + double T; /* time (fractions of a century) */ + double greenwichMidnight; + + /* true position requires sidereal time of midnight at prime meridian. + get midnight of given julian day (midnight has decimal of .5). */ + jdMidnight = floor(julianDay); + if (julianDay - jdMidnight >= 0.5) jdMidnight += 0.5; + else jdMidnight -= 0.5; + + T = (jdMidnight - epoch) / 36525.0; + + /* get fraction of a day */ + dayFraction = (julianDay - jdMidnight) * 24.0; + + /* get Greenwich midnight sidereal time (in hours) */ + greenwichMidnight = + fmod((0.00002581 * T + 2400.051262) * T + 6.6460656, 24.0); + + /* return Greenwich sidereal time */ + return radPerHour * (greenwichMidnight + dayFraction * siderealHoursPerHour); +} + +static void getTruePosition(double julianDay, + float latitude, float longitude, + double sx, double sy, double sz, + float pos[3]) +{ + double tx, ty, tz; + double localSidereal; + + /* convert to radians */ + latitude *= radPerDeg; + longitude *= radPerDeg; + + /* get local sidereal time */ + localSidereal = getGreenwichSideral(julianDay) - longitude; + + /* rotate around polar axis (y-axis) by local sidereal time */ + tx = sx * cos(localSidereal) - sz * sin(localSidereal); + ty = sy; + tz = sz * cos(localSidereal) + sx * sin(localSidereal); + + /* rotate by latitude to local position */ + pos[0] = (float)tx; + pos[1] = (float)(ty * cos(latitude) - tz * sin(latitude)); + pos[2] = (float)(tz * cos(latitude) + ty * sin(latitude)); +} + +static void getSunDirection(double julianDay, float latitude, + float longitude, float pos[3]) +{ + double C; + double T; /* time (fractions of a century) */ + double sx, sy, sz; /* sun direction */ + double obliquity; /* earth's tilt */ + double meanAnomaly; + double geometricMeanLongitude; + double trueLongitude; + + T = (julianDay - epoch) / 36525.0; + + obliquity = radPerDeg * + (23.452294 + (-0.0130125 + (-0.00000164 + + 0.000000503 * T) * T) * T); + + meanAnomaly = radPerDeg * (358.47583 + + ((0.0000033 * T + 0.000150) * T + 35999.04975) * T); + + geometricMeanLongitude = radPerDeg * + ((0.0003025 * T + 36000.76892) * T + 279.69668); + + C = radPerDeg * + (sin(meanAnomaly) * (1.919460 - (0.004789 + 0.000014 * T) * T) + + sin(2.0 * meanAnomaly) * (0.020094 - 0.0001 * T) + + sin(3.0 * meanAnomaly) * 0.000293); + + trueLongitude = geometricMeanLongitude + C; + + /* position of sun if earth didn't rotate: */ + sx = sin(trueLongitude) * cos(obliquity); + sy = sin(trueLongitude) * sin(obliquity); + sz = cos(trueLongitude); + + /* get true position */ + getTruePosition(julianDay, latitude, longitude, sx, sy, sz, pos); +} + +/* + * globe/map calculation + */ + +#define LAT_GRID 20 +#define LON_GRID 40 +static GLfloat sphere[LAT_GRID + 1][LON_GRID + 1][3]; +static GLfloat map[LAT_GRID + 1][LON_GRID + 1][2]; +static GLfloat uv[LAT_GRID + 1][LON_GRID + 1][2]; + +static void initSphere(void) +{ + int lat, lon; + + for (lat = 0; lat <= LAT_GRID; lat++) { + const float y = (float)-cos(M_PI * (double)lat / (double)LAT_GRID); + const float r = (float)sin(M_PI * (double)lat / (double)LAT_GRID); + for (lon = 0; lon <= LON_GRID; lon++) { + sphere[lat][lon][0] = r * (float)sin(-M_PI + 2.0 * M_PI * + (double)lon / (double)LON_GRID); + sphere[lat][lon][1] = y; + sphere[lat][lon][2] = r * (float)cos(-M_PI + 2.0 * M_PI * + (double)lon / (double)LON_GRID); + } + } +} + +static void initMap(void) +{ + int lat, lon; + + for (lat = 0; lat <= LAT_GRID; lat++) { + const float y = 1.0f * ((float)lat / (float)LAT_GRID - 0.5f); + for (lon = 0; lon <= LON_GRID; lon++) { + map[lat][lon][0] = 2.0f * ((float)lon / (float)LON_GRID - 0.5f); + map[lat][lon][1] = y; + } + } +} + +static int isPowerOfTwo(int x) +{ + if (x <= 0) return 0; + while ((x & 1) == 0) x >>= 1; + return x == 1; +} + +static void initTexture(const char* filename) +{ + FILE* imageFile; + int lat, lon; + unsigned char buffer[4]; + unsigned char* image; + int dx, dy; + + /* initialize texture coordinates */ + for (lat = 0; lat <= LAT_GRID; lat++) { + const float y = (float)lat / (float)LAT_GRID; + for (lon = 0; lon <= LON_GRID; lon++) { + uv[lat][lon][0] = (float)lon / (float)LON_GRID; + uv[lat][lon][1] = y; + } + } + + /* open image file */ + imageFile = fopen(filename, "rb"); + if (!imageFile) { + fprintf(stderr, "cannot open image file %s for reading\n", filename); + exit(1); + } + + /* read image size */ + fread(buffer, 1, 4, imageFile); + dx = (int)((buffer[0] << 8) | buffer[1]); + dy = (int)((buffer[2] << 8) | buffer[3]); + if (!isPowerOfTwo(dx) || !isPowerOfTwo(dy)) { + fprintf(stderr, "image %s has an illegal size: %dx%d\n", filename, dx, dy); + exit(1); + } + + /* read image */ + image = (unsigned char*)malloc(3 * dx * dy * sizeof(unsigned char)); + fread(image, 3 * dx, dy, imageFile); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 3, dx, dy, 0, + GL_RGB, GL_UNSIGNED_BYTE, image); + + /* tidy up */ + free(image); + fclose(imageFile); +} + +/* + * misc OpenGL stuff + */ + +static const GLfloat sunColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; +static GLfloat sunDirection[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; +static const GLfloat surfaceColor[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + +static void initProjection(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if (mapMode) { + /* orthographic for map */ + if (aspectRatio < 2.0) + glOrtho(-1.0, 1.0, -1.0 / aspectRatio, 1.0 / aspectRatio, 2.0, 4.0); + else + glOrtho(-0.5 * aspectRatio, 0.5 * aspectRatio, -0.5, 0.5, 2.0, 4.0); + } + + else { + /* prespective for globe */ + gluPerspective(40.0, aspectRatio, 1.0, 5.0); + } + + glMatrixMode(GL_MODELVIEW); +} + +static void initSunlight(void) +{ + getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, + 0.0f, 0.0f, sunDirection); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + glLightfv(GL_LIGHT0, GL_DIFFUSE, sunColor); + glLightfv(GL_LIGHT0, GL_POSITION, sunDirection); + glEnable(GL_LIGHT0); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, surfaceColor); +} + +/* + * glut callbacks + */ + +static GLfloat angle = 0; /* in degrees */ +static GLfloat angle2 = 0; /* in degrees */ +static int moving = 0, startx, starty; + +static void reshapeCB(GLsizei w, GLsizei h) +{ + aspectRatio = (GLdouble)w / (GLdouble)h; + glViewport(0, 0, w, h); + initProjection(); + glutPostRedisplay(); +} + +static void redrawCB(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + + /* Perform scene rotations based on user mouse input. */ + if (!mapMode) { + glRotatef(angle2, 1.0f, 0.0f, 0.0f); + glRotatef(angle, 0.0f, 1.0f, 0.0f); + } + + glLightfv(GL_LIGHT0, GL_POSITION, sunDirection); + + if (mapMode) { + /* use the normals for a sphere on a flat surface to get + * the lighting as if we unwrapped a lighted sphere. */ + + int lat, lon; + for (lat = 0; lat < LAT_GRID; lat++) { + glBegin(GL_TRIANGLE_STRIP); + + for (lon = 0; lon <= LON_GRID; lon++) { + glTexCoord2fv(uv[lat + 1][lon]); + glNormal3fv(sphere[lat + 1][lon]); + glVertex2fv(map[lat + 1][lon]); + + glTexCoord2fv(uv[lat][lon]); + glNormal3fv(sphere[lat][lon]); + glVertex2fv(map[lat][lon]); + } + + glEnd(); + } + } + + else { + /* draw a sphere */ + int lat, lon; + for (lat = 0; lat < LAT_GRID; lat++) { + glBegin(GL_TRIANGLE_STRIP); + + for (lon = 0; lon <= LON_GRID; lon++) { + glTexCoord2fv(uv[lat + 1][lon]); + glNormal3fv(sphere[lat + 1][lon]); + glVertex3fv(sphere[lat + 1][lon]); + + glTexCoord2fv(uv[lat][lon]); + glNormal3fv(sphere[lat][lon]); + glVertex3fv(sphere[lat][lon]); + } + + glEnd(); + } + } + + glPopMatrix(); + + glutSwapBuffers(); +} + +static void mouseCB(int button, int state, int x, int y) +{ + if (button == GLUT_LEFT_BUTTON) { + if (state == GLUT_DOWN) { + moving = 1; + startx = x; + starty = y; + } + else if (state == GLUT_UP) { + moving = 0; + } + } +} + +static void motionCB(int x, int y) +{ + if (moving) { + switch (adjustMode) { + case 0: + /* move globe */ + if (!mapMode) { + angle = angle + (x - startx); + angle2 = angle2 + (y - starty); + glutPostRedisplay(); + } + break; + + case 1: + /* change day of year */ + timeOfYear = timeOfYear + (y - starty) / 365.0; + while (timeOfYear < 0) timeOfYear += 1.0; + while (timeOfYear >= 1.0) timeOfYear -= 1.0; + getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, + 0.0f, 0.0f, sunDirection); + glutPostRedisplay(); + break; + + case 2: + /* change time of day (by 4 minute increments (24 hrs / 360)) */ + timeOfDay = timeOfDay + (y - starty) / 360.0; + while (timeOfDay < 0) timeOfDay += 1.0; + while (timeOfDay >= 1.0) timeOfDay -= 1.0; + getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, + 0.0f, 0.0f, sunDirection); + glutPostRedisplay(); + break; + } + + startx = x; + starty = y; + } +} + +static void keyCB(unsigned char c, int x, int y) +{ + if (c == 27) { + exit(0); + } + glutPostRedisplay(); +} + + +/* + * menu handling + */ + +static void handleMenu(int value) +{ + switch (value) { + default: + break; + + case MENU_SHOW_GLOBE: + mapMode = 0; + initProjection(); + glutPostRedisplay(); + glutChangeToMenuEntry(2, "Show Globe *", MENU_SHOW_GLOBE); + glutChangeToMenuEntry(3, "Show Map", MENU_SHOW_MAP); + break; + + case MENU_SHOW_MAP: + mapMode = 1; + initProjection(); + glutPostRedisplay(); + glutChangeToMenuEntry(2, "Show Globe", MENU_SHOW_GLOBE); + glutChangeToMenuEntry(3, "Show Map *", MENU_SHOW_MAP); + break; + + case MENU_ADJUST_GLOBE: + adjustMode = 0; + glutChangeToMenuEntry(4, "Adjust Globe *", MENU_ADJUST_GLOBE); + glutChangeToMenuEntry(5, "Adjust Day", MENU_ADJUST_DAY); + glutChangeToMenuEntry(6, "Adjust Time", MENU_ADJUST_TIME); + break; + + case MENU_ADJUST_DAY: + adjustMode = 1; + glutChangeToMenuEntry(4, "Adjust Globe", MENU_ADJUST_GLOBE); + glutChangeToMenuEntry(5, "Adjust Day *", MENU_ADJUST_DAY); + glutChangeToMenuEntry(6, "Adjust Time", MENU_ADJUST_TIME); + break; + + case MENU_ADJUST_TIME: + adjustMode = 2; + glutChangeToMenuEntry(4, "Adjust Globe", MENU_ADJUST_GLOBE); + glutChangeToMenuEntry(5, "Adjust Day", MENU_ADJUST_DAY); + glutChangeToMenuEntry(6, "Adjust Time *", MENU_ADJUST_TIME); + break; + + case MENU_QUIT: + exit(0); + } +} + +/* + * main + */ + +int main(int argc, char** argv) +{ + /* + * initialize GLUT and open a window + */ + glutInit(&argc, argv); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutCreateWindow("Sunlight"); + glutDisplayFunc(redrawCB); + glutReshapeFunc(reshapeCB); + glutMouseFunc(mouseCB); + glutMotionFunc(motionCB); + glutKeyboardFunc(keyCB); + + /* + * make the menu + */ + glutCreateMenu(handleMenu); + glutAddMenuEntry("SUNLIGHT", 0); + glutAddMenuEntry("Show Globe *", MENU_SHOW_GLOBE); + glutAddMenuEntry("Show Map", MENU_SHOW_MAP); + glutAddMenuEntry("Adjust Globe *", MENU_ADJUST_GLOBE); + glutAddMenuEntry("Adjust Day", MENU_ADJUST_DAY); + glutAddMenuEntry("Adjust Time", MENU_ADJUST_TIME); + glutAddMenuEntry("Quit", MENU_QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + /* + * initialize GL + */ + initProjection(); + gluLookAt(0.0, 0.0, 3.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + initSunlight(); + glEnable(GL_LIGHTING); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + /* + * initialize data structures + */ + initSphere(); + initMap(); + initTexture("globe.raw"); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/sunlight/sunlight.dsp b/lib/glut-3.7.6/progs/demos/sunlight/sunlight.dsp new file mode 100644 index 0000000000..1c247ebc03 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/sunlight/sunlight.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="sunlight" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sunlight - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sunlight.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sunlight.mak" CFG="sunlight - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sunlight - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sunlight - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sunlight - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sunlight - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sunlight - Win32 Release" +# Name "sunlight - Win32 Debug" +# Begin Source File + +SOURCE=.\sunlight.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/sysview/README b/lib/glut-3.7.6/progs/demos/sysview/README new file mode 100644 index 0000000000..9e39faa591 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/sysview/README @@ -0,0 +1,27 @@ + +This is a nice 3D system monitor written with GLUT. The operating +system dependent code for querying system statistics is only for IRIX, +but maybe someone could adapt the code to work on other operating +systems. + +Be warned that on a multiprocessor SGI systems, some of the +measurements go "off the chart". The program was written on a single +processor machine so the top of the chart is 100% of one processor. + +- Mark + +Javier writes: +> I am sending attached a very simple program that uses OpenGL and GLUT. +> As you will see it resembles a little bit the gr_osview SGI application. +> I hope you find it useful to be included as a contribution to GLUT +> distribution. +> +> Keep on working with GLUT, it is a great starting point for OpenGL +> users. +> +> Greetings from Spain! +> +> -- +> Javier Velasco +> fjvelasco@sfe.indra.es +> fjvelasco@sinix.net diff --git a/lib/glut-3.7.6/progs/demos/sysview/sysview.c b/lib/glut-3.7.6/progs/demos/sysview/sysview.c new file mode 100644 index 0000000000..67df7f357f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/sysview/sysview.c @@ -0,0 +1,442 @@ + +/* + * Systems statistics viewing application + * (C) Javier Velasco '97 (almost '98) + * fjvelasco@sinix.net + * + * This application was developed on an INDIGO2 Extreme and makes use of + * a SGI system call (sginap) that sleeps the process for a given number of + * clock ticks. For other UNIX systems, this call should be substituted for + * another proper call. + * The default number of ticks between samples is 20. This can be changed + * through the mouse right button menu. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* GL includes */ +#include +#include +#include + +#include +#include + + +/* + * Macros + */ +#define GRID 0x22 +#define ZGRID 0x23 +#define XGRID 0x24 +#define YGRID 0x25 + +float lastx=0; /* mouse track */ +float lasty=0; + +void *font1 = GLUT_BITMAP_9_BY_15; /* used fonts */ +void *font2 = GLUT_BITMAP_8_BY_13; + +long nPeriod=20; /* default sampling rate in ticks */ +GLsizei nWidth, nHeight; /* current window size */ +GLboolean bMotion=False; + +struct sysinfo SysInfo, LastSysInfo; /* system information */ + +/* + * Mouse motion track + */ +void MouseMove(int x, int y) +{ + if(bMotion) + { + lastx = x; + lasty = y; + glutPostRedisplay(); + } +} + +/* + * 3D Perspective projection setup + */ +void Make3DLook(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, 4.0/3.0, 0.0, 500.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +/* + * 2D Orthographic projections setup + */ +void Make2DLook(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, nWidth, nHeight, 0); + glMatrixMode(GL_MODELVIEW); +} + +/* + * Toggle line antialias + */ +void ToggleAAlias(void) +{ + if(glIsEnabled(GL_LINE_SMOOTH)) + { + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + } + else + { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); + } +} + + +/* + * Draw a string + */ +void glPuts(GLint x, GLint y, char *string, void *font) +{ + int len, i; + + glRasterPos2i(x, y); + len = (int) strlen(string); + for (i = 0; i < len; i++) { + glutBitmapCharacter(font, string[i]); + } +} + +/* + * Draw the 3d grid + */ +void DrawGrid(void) +{ + glCallList(GRID); +} + +/* + * Display the legend + */ +void Legend(void) +{ + glPuts(5, 40, "User", font2); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + glTranslatef(10.0, 50.0, 0.0); + glColor3f(0.0, 0.0, 1.0); + glRecti(0, 0, 20, 20); + glPopAttrib(); + glPopMatrix(); + + glPuts(5, 90, "Kernel", font2); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + glTranslatef(10.0, 100.0, 0.0); + glColor3f(1.0, 0.0, 0.0); + glRecti(0, 0, 20, 20); + glPopAttrib(); + glPopMatrix(); + + glPuts(5, 140, "Intr", font2); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + glTranslatef(10.0, 150.0, 0.0); + glColor3f(1.0, 1.0, 0.0); + glRecti(0, 0, 20, 20); + glPopAttrib(); + glPopMatrix(); + + glPuts(5, 190, "Idle", font2); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + glTranslatef(10.0, 200.0, 0.0); + glColor3f(0.0, 1.0, 0.0); + glRecti(0, 0, 20, 20); + glPopAttrib(); + glPopMatrix(); + + glPuts(5, 240, "Wait", font2); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + glTranslatef(10.0, 250.0, 0.0); + glColor3f(0.0, 1.0, 1.0); + glRecti(0, 0, 20, 20); + glPopAttrib(); + glPopMatrix(); + + glPuts(nWidth-30, nHeight-30, "0", font1); + glPuts(nWidth-45, 45, "100", font1); +} + + + +/* + * Construct the grid display list + */ +void MakeGrid(void) +{ + int i; + + /* let's divide the grid in three pieces */ + glNewList(ZGRID, GL_COMPILE_AND_EXECUTE); + glBegin(GL_LINES); + for(i=0;i<=30;i+=3) + { + glVertex2d(i, 0); + glVertex2d(i, 30); + glVertex2d(0, i); + glVertex2d(30, i); + } + glEnd(); + glEndList(); + + + glNewList(XGRID, GL_COMPILE_AND_EXECUTE); + glPushMatrix(); + glRotatef(90.0, 1.0, 0.0, 0.0); + glBegin(GL_LINES); + for(i=0;i<=6;i+=3) + { + glVertex2d(0, i); + glVertex2d(30, i); + } + for(i=0;i<=30;i+=3) + { + glVertex2d(i, 0); + glVertex2d(i, 6); + } + glEnd(); + glPopMatrix(); + glEndList(); + + glNewList(YGRID, GL_COMPILE_AND_EXECUTE); + glPushMatrix(); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glBegin(GL_LINES); + for(i=0;i<=30;i+=3) + { + glVertex2d(0, i); + glVertex2d(6, i); + } + for(i=0;i<=6;i+=3) + { + glVertex2d(i, 0); + glVertex2d(i, 30); + } + glEnd(); + glPopMatrix(); + glEndList(); + + /* now call them all */ + glNewList(GRID, GL_COMPILE_AND_EXECUTE); + glLineWidth(2.0); + glColor3f(0.7, 0.7, 0.7); + glCallList(ZGRID); + glCallList(XGRID); + glCallList(YGRID); + glLineWidth(1.0); + glEndList(); +} + +/* + * System statistics collection routine + */ +void ComputeStatistics(void) +{ + memcpy(&LastSysInfo, &SysInfo, sizeof(SysInfo)); + sysmp(MP_SAGET, MPSA_SINFO, &SysInfo, sizeof(SysInfo)); + sginap(nPeriod); + glutPostRedisplay(); +} + +/* + * Draw a coloured cube for each one of the monitored parameters + */ +void Draw3DStatistics(void) +{ + GLdouble fSize; + + glPushMatrix(); + glTranslatef(0.0, 0.0, 1.5); + /* Time in user mode */ + glPushMatrix(); + fSize = SysInfo.cpu[CPU_USER] - LastSysInfo.cpu[CPU_USER] ; + fSize = fSize*30/nPeriod; + glTranslatef(3.0, fSize/2, 0.0); + glScalef(6.0, fSize, 3.0); + glColor3f(0.0, 0.0, 1.0); + glutSolidCube(1.0); + glColor3f(0.0, 0.0, 0.0); + glutWireCube(1.0); + glPopMatrix(); + + /* Time in kernel mode */ + glPushMatrix(); + fSize = SysInfo.cpu[CPU_KERNEL] - LastSysInfo.cpu[CPU_KERNEL] ; + fSize = fSize*30/nPeriod; + glTranslatef(9.0, fSize/2, 0.0); + glScalef(6.0, fSize, 3.0); + glColor3f(1.0, 0.0, 0.0); + glutSolidCube(1.0); + glColor3f(0.0, 0.0, 0.0); + glutWireCube(1.0); + glPopMatrix(); + + /* Time in interrupt mode */ + glPushMatrix(); + fSize = SysInfo.cpu[CPU_INTR] - LastSysInfo.cpu[CPU_INTR] ; + fSize = fSize*30/nPeriod; + glTranslatef(15.0, fSize/2, 0.0); + glScalef(6.0, fSize, 3.0); + glColor3f(1.0, 1.0, 0.0); + glutSolidCube(1.0); + glColor3f(0.0, 0.0, 0.0); + glutWireCube(1.0); + glPopMatrix(); + + /* Time in idle */ + glPushMatrix(); + fSize = SysInfo.cpu[CPU_IDLE] - LastSysInfo.cpu[CPU_IDLE] ; + fSize = fSize*30/nPeriod; + glTranslatef(21.0, fSize/2, 0.0); + glScalef(6.0, fSize, 3.0); + glColor3f(0.0, 1.0, 0.0); + glutSolidCube(1.0); + glColor3f(0.0, 0.0, 0.0); + glutWireCube(1.0); + glPopMatrix(); + + /* Time in wait mode */ + glPushMatrix(); + fSize = SysInfo.cpu[CPU_WAIT] - LastSysInfo.cpu[CPU_WAIT] ; + fSize = fSize*30/nPeriod; + glTranslatef(27.0, fSize/2, 0.0); + glScalef(6.0, fSize, 3.0); + glColor3f(0.0, 1.0, 1.0); + glutSolidCube(1.0); + glColor3f(0.0, 0.0, 0.0); + glutWireCube(1.0); + glPopMatrix(); + + glPopMatrix(); +} + + +/* + * Resize routine + */ +void Resize3DWindow(int newWidth, int newHeight) +{ + glViewport(0, 0, (GLint)newWidth, (GLint)newHeight); + nWidth = newWidth; + nHeight = newHeight; + Make3DLook(); + glClear(GL_COLOR_BUFFER_BIT); +} + + +/* + * Display routine + */ +void Doit3D(void) +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + Make2DLook(); + glColor3f(1.0, 1.0, 0.0); + glPuts(15, 15, "CPU Activity", font1); + Legend(); + Make3DLook(); + glPushMatrix(); + glTranslatef(-15.0, -15.0, -50.0); + glRotatef (lastx, 0.0, 1.0, 0.0); + glRotatef (lasty, 1.0, 0.0, 0.0); + DrawGrid(); + Draw3DStatistics(); + glFlush(); + glPopMatrix(); + glutSwapBuffers(); +} + +/* + * Menus routines + */ +void SelectSampleRate(int pick) +{ + nPeriod = pick; +} + +void MainMenu(int pick) +{ + switch(pick) + { + case 0: + bMotion = !bMotion; + break; + case 1: + ToggleAAlias(); + break; + case 2: + exit(0); + break; + } +} + +/* + * Menu creation + */ +void SetUpMenu(void) +{ + int SampleMenu; + + SampleMenu = glutCreateMenu(SelectSampleRate); + glutAddMenuEntry("1", 1); + glutAddMenuEntry("5", 5); + glutAddMenuEntry("10", 10); + glutAddMenuEntry("20", 20); + glutCreateMenu(MainMenu); + glutAddMenuEntry("Mouse Motion", 0); + glutAddMenuEntry("Line antialias", 1); + glutAddSubMenu("Sample rate", SampleMenu); + glutAddMenuEntry("Quit", 2); + glutAttachMenu(GLUT_RIGHT_BUTTON); + +} + +/* + * MAIN STUFF + */ +int main(int argc, char **argv) +{ + GLenum type; + + type = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH; + glutInit(&argc, argv); + glutInitDisplayMode(type); + glutCreateWindow(argv[0]); + SetUpMenu(); + + MakeGrid(); + + glutReshapeFunc(Resize3DWindow); + glutDisplayFunc(Doit3D); + glutMotionFunc(MouseMove); + glutIdleFunc(ComputeStatistics); + glutMainLoop(); + return(0); +} + diff --git a/lib/glut-3.7.6/progs/demos/sysview/sysview.dsp b/lib/glut-3.7.6/progs/demos/sysview/sysview.dsp new file mode 100644 index 0000000000..82c4febec2 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/sysview/sysview.dsp @@ -0,0 +1,89 @@ +# Microsoft Developer Studio Project File - Name="sysview" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sysview - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sysview.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sysview.mak" CFG="sysview - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sysview - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sysview - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sysview - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sysview - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sysview - Win32 Release" +# Name "sysview - Win32 Debug" +# Begin Source File + +SOURCE=.\sysview.c +# PROP Exclude_From_Build 1 +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/underwater/Imakefile b/lib/glut-3.7.6/progs/demos/underwater/Imakefile new file mode 100644 index 0000000000..08002c3ca2 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/underwater/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = underwater + +SRCS = underwater.c texload.c dino.c + +OBJS = underwater.o texload.o dino.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(underwater,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust00.bw b/lib/glut-3.7.6/progs/demos/underwater/caust00.bw new file mode 100644 index 0000000000000000000000000000000000000000..ebd44bc2c475e3e9c0fc812cc9672eebfa9381b9 GIT binary patch literal 5337 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 tojG&b1Jz`!cNz`z>9z`#0#fr0f70|T1^ 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 XZth#RdiA<>YZgvzuVTz&%wPZj)i`n4 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust03.bw b/lib/glut-3.7.6/progs/demos/underwater/caust03.bw new file mode 100644 index 0000000000000000000000000000000000000000..18dad2910e69a1b0723ed8cfb60223dcf7fa0495 GIT binary patch literal 5358 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 VLtECaTE1e%qM04FjHQfu3;@DQkV^mn literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust04.bw b/lib/glut-3.7.6/progs/demos/underwater/caust04.bw new file mode 100644 index 0000000000000000000000000000000000000000..76eb706dacaf6819ead9c79e38f5544f74f1b9a1 GIT binary patch literal 5357 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 MFWn7{wTz_<0Q~@s1^@s6 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust05.bw b/lib/glut-3.7.6/progs/demos/underwater/caust05.bw new file mode 100644 index 0000000000000000000000000000000000000000..2e0214a18a15a6f95f86f1305077c50b2b6e85ae GIT binary patch literal 5365 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust07.bw b/lib/glut-3.7.6/progs/demos/underwater/caust07.bw new file mode 100644 index 0000000000000000000000000000000000000000..058080b31334af6195686915b8f858064d4a30ca GIT binary patch literal 5357 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 S*Up{N*VonF!raQ(&Hw-k52{80 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust08.bw b/lib/glut-3.7.6/progs/demos/underwater/caust08.bw new file mode 100644 index 0000000000000000000000000000000000000000..40efbb238e743e4a1d173b9f11b8438ef704fee1 GIT binary patch literal 5362 zcmZR)#mLCO#Nfc-z`)4Bz!1d1!0?ZOfq@|}Um-6sHx1Jz`!cNz`z>9z`#14fr0fl0|T2J z0|Q$k0|VP)1_rk03=Hhr3=Hh~3=Hg>85r2VGca&iGca(}Gca%*W?f5d#Ca8Uq7&76SwKItB*rPYet^W(*8GRSXO~`xqE_ znHU&&T^Ja6I~W*vPcSg>@h~v(1u!u1O<`c*yTQP~FT=pVpTNMtzl4E-{{;hsfDQwL zKmh}Tz!nAufgcPEf;J2cf(;A|f=3t_gg6)&gnSqngeEXB2wh=d5SCzI5RPGB5T3`t zApD4dK}3y#K_rWTL1Y~R1A_||>T{QiDnMPFS>PDW;CPHFw*EjQmi+Bd(qzO+Xj~`xf-n7UkyU6;-uOVqC$vlVSVqci(^h{{8FC=~a_ETIwoF3bK;p zW20l@Q*$f3R^9pWv|R)e*Es~iREpT1+Gc;fR z^q1w&_McAR6BXc^FKeHp4v2jN@r7TZC!Kk!tIw|JimW* zMOSTcZcbKqen~xJKjR{XeFtCv{rl(7-@o7PA6`3mLPtYYadvu2a&mfpMf;+&AOHM( zcy#-!#j~ePo;qXhs(lykJ-&5u&$0;(McG;D=~?*|jIE4Q7@9ZT|HblW`|n?$o}Aya za?XT~+LHX7?CiXX=BZome*5+D{MOaW)~;Q*Y4^bsSMEP~aP`>U4Ga4lN^-N(Q`57H z7;6~27+Mye{_>mo5A*LWzdk-WzjMXx{+623lG4hS2}_Q?`~CgV{uMK4Em*nz^u6bA zKY#ylWB9nvus?#@NKrGVj=z-z3%WyYfQhadj@@oeARp5}(Oz6HDPfBpOO?UgNads~{Cn`+7maLC zuUWcq{<8IZFWkLP_h&cGo7B_Y**j_W@-6!g?Af|u#e&&$7q8jM zym$WE*}cv6ZPPa#IkJ9ccWp&kS$SDmX+>>gYe!el)FrzaZ!msf*!Snp=UaQ0PVQ`P zZEo+KGJnn1?OWEbUN(RBoOz2^Y}m19>*|HmCokT0{``h%Efx8>xdkPq<(0K9JyYi_ zTDAMy8^#}uzZg1xezGXerG~NlwkkEvjtlnZ9_#uCot5{QSfCi}4S`zDMT|ZeO!-YEN5BYuDsCOE>P> zyJOSx1+!<(oH2X;svRe8zkK)Z(~sXTcTK3wN{Wk(OG?kHY@fOI=#3{|e*gaSoADRp zPlkPa)~#H%V$sY=-EHmN(?MR@wtnfnnbW3DnKEtm(k*9S{QUFh_n*Jd*R&L+#zsa) z$0g@fbuB*f?vCy1le1KP84avMV|{x4Lijm5;xEGyiG&{etl%;|2!izIhX;&tEie z=9CFjW-nQ_cIEu3eVuJhP0cNxJyVw)02wjs_s@GPS_)I*A|oTBQ}Svit-ti{$FIMC zf4@D;xR!Ai!@{PfmiGQxiB*@71s5yJoWVL*WZ7B+}h4Khq0GoYF%A@YuD68tJkbpx_IHz#dD{0)K``< zmo6)>sBUPTxZ=W>zkhyxe}8ND?53j3l%%B8?2^X5l?TpWd;aCi`>SghCo;A$?5nS> zZfu({fA!XFo7SvYws3l1b9G5!etuzbaam16*Zf0IKE8W=_59f*>n1mp=4EB&7FM-R zSh{}ufopHRez>uoaWZ2Y!@j1v%DUE`87p=iJhXSyss)p~>Pri9bFy;_ic2eMJLc@U zdh7I#_3O9o-@Rg5TV-)kX=P*g80UksTyt$@ZDZTS1)GnaJG*b= zqRAaK#d$e7**STIr4{wv^Y)xNv|-__*^4&q-MbD{3N$sfb#{Xal#RE3{{DWAaW&&4 zhJCGd6&2O>?bB8syn5%#p^bBUYfJO9b8_!PW> z-RmXuc1we~OF ze`epR>D?_Y9aER@KXZKR(&>He&Gl8~AmjIc{Qc`a<7vjF4EvfZ3-Ypai)tnpH&z~=kET7O?TiejuIdQ?(3r`*%U)Eb+R!~@4+r8xY z-CGBjPin3#%+1csEo)oz=FjghjE5MfFzhSLNKQ;hOvx#4pS|_!m)}31onAY$w|C;~ zrCUxu{_yU~y8i0IoQ$lT(xzGaAHKM-eo|veZf06~R!Pf-cYl7rVqC}A$*?acB`zi= zJ~6$prhD$r$3Or4`f&HirVZPVTzU58*T<`C`>XQOlao@?@~S57diM3X`}^mY_pjf7`SJV5<3o$ODzcN~ zV`Acyvr4qK5g`fB*e;hH)ZeIm3k1_{fOx$hd^moYMOKHCMhf z|7rZo{BQZ6KR@nno6%I7ofH!p9v&5!R@Axi)$bqoH}zB(<>wXEOxW}8_n+@a7<(DZ z875~WL`OwN#U!L;=9e|i*!k@DpTDesmi>IVX-ZRZR&s1aSZHWOOmacTmN!3tzBxLp zxu&wJv47)(Uq63;*vB}5v4UZ0c1m1qOl(|2QfgLydFSFw-+%x4^PBn4vZp&|G?!$h z#6^XLgoK92Bo}qh&M^>z2p-F6RD=e<45IFqq~p`|1{C7varGch?Wr=)4- z@h@zD7Q8+*zq2YoGbJu6B0M}IGA_M*;^Ft-e|>*)dh^N^8&5oE{?YR5=ZABQOF=Qx zQj(LFl9HU1n3$ZAUp-;(hrfUR{QC9b%*u()<@s4@iLudUI0 zPhYzK;rGw4Z=bzpFdx3?N~6et)Zr}ytKHuATPhPwrk$rN8f&Zd-L$lt%q+vetdj-!`x}p7wx>t z_>A!(!^C%2x6Wv*D#}SuNlDME>fio``Om61M;A}*Xlkf$sBdg)ZSR^mYuWB=?|=UJ z_3`no>vx{Le|CAt{NDPS+V8+LdIXT6R(;0U$K4aMTPb}+eswyk5ZJWI2`nO;256$bUt0*h4Zs?q`?!>e2 z-@kr(`|`zy??1kN{qX+f<8wV&fAtN*J3#x&Fx8-+%tRJHKLbOI3MoWB0s6 zuYWw*GpntptfZu@x^?2h9T%>jKeBnn;^o`Vzxnm&&+o5~_fMC4z{$R)S=8EEig5t8;&Kb)$uAAG}SW{lzIs53RKY#!J zdA@s6MP_15baYf~QWj$wV;e)ulB4f`GymE6e8=>*hT6K8No%fse6nkLb9q5-USUaP z^MqM*CpVSlq^D*U)Xcc@>+kPBZ}(0v&q|76j&6=m$!08NY-ZRuXT!OdzyJRIaClx< zV{KjYgq7!BJ>EUDwXz^LH@~p7u5)5^Vux|RiwMUI+k1!b5^WA`=QGocZFGZzkS zSiWffoH_Fs&R@1_>8y^jtiAjmbuG_fd$e9~Y-@JWxZqvN}*5-~$^VT1``}Pat zC&rfy`wnbbzhc?)m8;fo*>&W~i*LWb-rPE?yRojmYxed#-~asn_2%J?%a^ZQzw_kP ztJm*8etLaz`_k#X-Mv$0Enc_lKi}Ruy{)>e zyuNeJfmgqOeSiJv_T5L%-+li2<-?n|Z$G@hacKR5>60c+o-%djoW&~`S2M0>*f)2< zk`=2rZQr?L$NuA2o_+iM@!Gmc%@xJPrPbZ5Z~XlG^X;SCcOE`|^5og$JGUP^egEOb z^~0MM&Ym`5LSJ|Hgei>E8D}!=n>cOmvW?q!@7b|&>-PO;ZaulZZ(e6jQEqNtasAXo z?|=XP_~horGspMu*tK)>?&H_re0=}(!k(3Lru21z`WKyy-Hbg9(TUbBFYc`^&SlPAnpfVn>B+C3pC4b?zhUXjNs}f{n!V=G-M8e3u8Md*Y;1Hv1H4UllwO=oZLTU`rLW5`szw@)02}^G78()-2eIe%fsXAXZ1AK h)>PNEPhWHT>AM$aw=A62-O^a!(9qV-*vZ(<002`Ao(}*3 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/underwater/caust09.bw b/lib/glut-3.7.6/progs/demos/underwater/caust09.bw new file mode 100644 index 0000000000000000000000000000000000000000..ab62dec5c855132c4f9551227e34da825352625c GIT binary patch literal 5364 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

    CN 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 XBE;Xt#oNu%+t)>g5wxv~k%<8S@0Wna literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f00 b/lib/glut-3.7.6/progs/data/flame/f00 new file mode 100644 index 0000000000000000000000000000000000000000..d43a935fb3b1af75423f0c760b0f389afe057146 GIT binary patch literal 16896 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 I5WpD%0NRSytpET3 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f01 b/lib/glut-3.7.6/progs/data/flame/f01 new file mode 100644 index 0000000000000000000000000000000000000000..74564d4bc0faeb44bc1805cba7683c0301c3a6b5 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f02 b/lib/glut-3.7.6/progs/data/flame/f02 new file mode 100644 index 0000000000000000000000000000000000000000..b003e3baf99e4a090ba55fdd45b90ceecd80cd44 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f04 b/lib/glut-3.7.6/progs/data/flame/f04 new file mode 100644 index 0000000000000000000000000000000000000000..d01562cd0beb52c857921f9885105324ffd6b1e3 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f05 b/lib/glut-3.7.6/progs/data/flame/f05 new file mode 100644 index 0000000000000000000000000000000000000000..89316c69dcf1c4cf18219fd6e16f568472352752 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f06 b/lib/glut-3.7.6/progs/data/flame/f06 new file mode 100644 index 0000000000000000000000000000000000000000..b105026e4a60eed8cb9a8dca68cd29dcd6cc1be8 GIT binary patch literal 16896 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 F002yqLx2DP literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f07 b/lib/glut-3.7.6/progs/data/flame/f07 new file mode 100644 index 0000000000000000000000000000000000000000..50e422f9f6219b9bc3228740c27c8b1b37c9682f GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f08 b/lib/glut-3.7.6/progs/data/flame/f08 new file mode 100644 index 0000000000000000000000000000000000000000..7c10d06cfa73f72e4c53af3d52d420a4430dca34 GIT binary patch literal 16896 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 QE(r-ha&?dD8`L2H0FYBIzW@LL literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f09 b/lib/glut-3.7.6/progs/data/flame/f09 new file mode 100644 index 0000000000000000000000000000000000000000..158a464b5fec4650911714dda1c321eb093056b6 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f10 b/lib/glut-3.7.6/progs/data/flame/f10 new file mode 100644 index 0000000000000000000000000000000000000000..ef495342efa4f03e194e4b16808cd3f5ce1fe03c GIT binary patch literal 16896 zcmZR)#lXnG%;3P_z`())0e?YMUcN$JVs0vkNlnbczyvnVo`D%mg9!l!e+w{Ulo$@XLu%pkHuqotG9b*)Cvv{EWHC*3ZBuD=W-K zzIFyC1!<&Go-~6PSr`~aSl0v#c-+gY@=~pT7P1{N?YT4wQ31$ky)oIDSLgW0kKcd)`uX?o_Ya>weOxeUVx*cHL8}=U7}&VxeR>`wQ~UA# zw?BXX{`&Rz@0X9CJ|A1WreBOG>v<)1e|l%7vFyXgAAkP-{qz0LpHCk?empg~eS;=3 z)-!NguYdhKMtSw851;=0`Th6Dub=NfetNQS;==U?jKt(c_NttY1C8OQzI^`h^Vj#^ zfBt;^@cG4wU6-CcNn#P=AnXLjc-!3jFOPou^y$Oj4= zVf_pi`Sahsd-w6v=MSK~^Yhn-Pwy7^uKWD?)4N`eU?TLhEqeC(!Gn(N1Pp?0|`TXU}mygdj zuB>_b>C2bJ@%2QdK$&%)KYaT1`SYoBPoEyR_U^;S7n?F}efW6GTggwD82i~gUVZxb z`R(V=??0ceY`ys5{fD>D-oJTv%11?v80`!UEU~-$&wl>=<>SYt|r#N&EEi)2B}#Kizxt85H!N z_oSF`6BBtbJKR8#|MBCe&!0bk`gCsj+P*wRm=sa8T*vdzpFr@_=jTft1>}sQNhy69 z7#KNfK7afOvi-S-3aAZ0isQj93Sqv7_V8sRCc{JQ!z9_5i74+dwT+65hQMeDjE2By z2v8gXjEqd=mi{2SnH;ouSt&3;%8ZXs0#x~e3?l<`adQYzRE026X-H_|+(RFJeEahC;F4DZAwEy(I*FS##{PFcv&xFR} zC?`_^k_<51f8+VP4`2WM{dIr$qFJ+x+_XekaYQv%Vbi78etduZ@$cWiPmUbi+?grH zEvAH3Ar3*m%^!aL{rvUs-*2b(9N1j!Da4^EheIj4Ff$_q15?EA&)@%i{r30or~Pa8 z?8>keVv{3s7)QWYR)B#$=D_Ele}4b^`}fE7Rcp7pnwd(m66t^EB^8oPx=S8{`tQGg z|NZ-E&+_R}4z6ZI20v5Cy2-pO9%n!Q0`>oY{Q3Lw%%-+*bA1mYt>^S;uaIK)SbXB+ zpTB?p{`~#(`nrYH_NMmkL?%KFMdKhH(TLVrkAD6B`RC7{ulpyKhWo}ARmd?A5M&(pWT1;>(_(T4R(S) zQ>HC0H02RTk7{guhvK&M{Pic79ei?P!@nC+i zDhiTBSBs6$nl^9u{=HilRrFPK*0;3ulzX{oX3gm+caha0YB-kJYwGc}i)VL5L}zD) zBvl{S+2|>kP*a*D%q&D)bs*Zfu&1Y@v#M!gl!kud(c9Z9Dw_-P!UaJ23Y&v5#FTa*VD-lOI4hF6a>~ng zuUWlf|C03l-sQ8}s=ESZNE?S2o3wWQ&J9}^PMAJr#e!HD4`U_R>@0?Fu?n!6HO^c# zb6(%#jk9aqco|uEWQfW%=Fp(J_NiT>gRljD*!oH$@B1cU@T2Qcb z)5cwM>q_bjQACO6Fltv%TAUo^Z%bOZBg|*>OAX}VVB;n&+!6X2SmXqSkhr7F(GVC7 zfzc2c4S|sp0xYCfx@bW|Tzd&k(h#>LJg^z(8F05vrYm*L~jApYzuJ z`LioNAjE^8g+%QP0s$+Ie%`S4*N>S&jsbo`q;wuQK@rXqy5Pd6*LVN?Jzr$+dRrQIlfB!yt{^$3m0Bc)Mms+0N!t%uLM0>SttNW@BVvm)5Vp|MK$Nuip*@s|&HQ zunQ8^_Xfu@BbN}Xw2?(z_0cnT|NPw*D#y&sB4O%4Y&KwI<`WchwbBhNZz%1*_qg6c zikX2!Q`>@v$T(ycl;IR~iLnl;jCKiYXm%5nVPQ~kl-8CIC$2DHRB<#GG|Gq$%lC6r zGq&SrVr65}_ET0cl_4?@@H?6c>xTqbCzx4_E2*$CGqEyBIjhTSfD$n*dE=vbj01v$ zJk3SagyqGgq?JY4m>IbY<@nebLFp2oMyMRSR=d9|;4| zvgXQ4!t#RB>gOIMc!(Oifck)e zfl*o4-aRTpi<4C%EMxhL)3yudAn- znvSNe87B)XaY+ZH5sKMl^(^#_RV-W$BuNN)sAdqwr0glEtEpm3)R+@U13DIWurycU zQzdfI2D)wr21!>xV^IMK65<`j3`P+R3m!IBA~P+DRtSfUgR~?A(KSkrhQMeDjE2By z2n>!8AhOMZ-LZT^%EUH1u^Aw|q%GKxv}sRdW7rdC1qG%XAPbSi=Ctu~i?AYV^*O{I zb|ob-b_kO!l37iG*j7J=`HZX#j1tP^4&F0x_{uSgyGrqKlGbd4JHw!iomtV--oQcv zE<_STLYR}4A*(B?Kgrk|)b}JwGf1)Y)?$Y{KR^HY{{Ce-Ic_ld{`UE=-@icMTC5tl zO9?WTXl(QI*RS7y{`~&^``3?mm)GQan2L~;l_Gxq`t|$wpFe-VZuoX}-K;QDwo)*+ zfLsomzJ?g^dP_?JaSPBPKIESA>(`$@zkdJy`xoqh`$@hjxezI$NWKlfe*gIkvLCGd z!>%azrc9!AGB7KOu`(#^L(zY2S-3-PBvAp#=(r=>OTg$XNdI5Z6gWe)xN>ZrF4Y(3b3-@ktSxG<-GyFM}2 zGjKa^`}8hZbMr4y*#G(a=g*&Czka=5Ib+2(GbUpCuN+OK6OMN#TmYv&kQaXc`t|PI z!5eR0XR?VA(I96`cP)MT{>%?h^7-=z6n?+HuGw_x=dWKE4E=S9@Pb{%vM-;%fV6{B zFev?gT@kkR*RNk+rUph6p`UH#n_thKLG^>ES3h({Se7q7g2ef-XsU%%e(EPU|&`-5POaH9HxY1JSHVAj;hgM`7at*0T34|nD(6BBq)HGDY`ZNHv?!|>;?!?{)@Z3OiG1~mXgU0Jtf zS~*dBFQC>lFevqdqa39B-5L)eCCg-@_FlmCGjcWm`t=>8{k^{?s0~1JJsJtlf**e! z;e{JY3WF^Lr2prqul1zpLZ}sL{PyeTt;>g(ITIc22+bgt=AOsPf6QsCD2olR;XJBAr=V2#SIl4OOR6ZstH5CySMsyjX_)O7z zc!fe-bR`AEiBgZQh&R=jMZt1}aQ(yk_a8sL|M2Nno)8BMX%Wf2`_re-A3lEk`Sa`h zkDuP|YjV`%A;l5gdq2GY`2OS9KYzY``1tYjmkVV%&eDW@jU+F5?Zf-`@85s@`}fb+ z_a8rhz8n+iXF!4%3~qe*@cHZeFMt33{rUdG$IrJNtt!GWgK~(<4IH^=`n46y z-o5|)>(B2$fB*je^zqZDvz>i@5_-hs1s1WbpB`A5E&licC?*#^EXZu zgtZUxdYxTt=f|h&zQ^Bx`u^wd-@m{A{Qmgy%e9>?jdSGj>VrwLYcBcl$k+P92XNT` z{r>&ShtHqi%`YhJRAXQyA^_PvBNm*kOuzp5irfBgRO_2Z{6pDr$2xO0&SBO4L< zh}lju<>j3VpFe+k_woDJ&)>d(`26MU`tz?ozMHM6qX2Uy9$Hz4A3uKj@b1H>kMG}qeDis_)A`R2KOVar zbR<`R5NGK7RQ4 z@%e|(XL~A-mp=UT>ec5{#k%XW2xbgY!<#|zo zqA)f1X#PcCK7RW2>GPpe*RJoo_~g^4OWiI9pB`Ri#HUR}{4p>v8a?^^@%@bt4{v>1 z>K?l0(}y=Fc3wKNtyxQuDD4akOu?IajvRgT?DMA!jov+C^GOo7M0+8byv# zM%LrW`_G>~etMfb`Qyh=pFe%NvA$dYMGXOt-N#R#KY#i3cJ783pTB&3`FfI{3JIkb z1B1$)&mi#W&AU&ZKW=Mn2{tFK8s`YT{qf7^FCRaA{&KZOhl5{1k0k3E7?{Ieem?#2 z^Sw{^jHHN3wHV={_ww`WPj5CoUqM8s$I#5cz@U8T^QUV!_MHyLCP`R~(dP2Qi+=gB zR^&AR7#KLS+WeSVIC!`T+l5_)h_4h06%H0N$P73vCXEV>hQMeDjE2CF3jq>)E$IFe zHP9A97bAhsWE!YUcJa@^z@XwECQDSK8;6^GVyros$*%>NWi{!~hCN zRs}`|CT8+oFB{0nD8|dm1Rbs>*(LH~49r}XG6G}=!(ZyYJ3%I$|iR!&T_48Kk`}F(ommh!s{{8m)^o|-| z2^LLRs2l-`nTv^mLAd$wk6(YkfB*aU*ZXTb*A+WUvxq1X&hz$Tb3_PH8c@nB(62d6tp~-o6ULihp&JC{{8#s@1GB=>nq}HJi_@w^XKFCjyPXE9UCG`GFInlMZz4(hwpy|+5h9`ms4~4i)@wD42W|+1Fx8K zl!k2Dv<>(F{QCL(*Y{_O+uEa@?0p@GOn_WW@`b61T{D(Ee)r@1*B?J0Piu^Hk1c3# zvSVc@CIzyv=$4e%ZdkbZ?88@g9(?_NWjmQfa-EY62lBUDnQb4E+{taB$W-Z;2n@}dpprh#$F9cv1*tMU|x z>H~6TFPNA!`Q*_Zmo{uJZR&|M(g;;8pPQRi6{$khP$qNa#1-qdZd=_or+I2^V@qYS zrG-*LUwVwav@lWS5TjGezSYa-cLhhpCk4gkuUwpA#2uIw?7{_~poDr97sXpVqrE=0 zIyJT0kw@5V&Ec8hfr-K1y2K9!%la6Hg{0?Ao0F}}Z?f#np{Wa&#QJ*@<#~vkn3;ug z%6sN*T2-!W*|%lI%*6}R-8G2JKM)gyy5>*p>s{Pp<54!FyE3=TT!;kg85kHi3MNmS zHF;J~L21pTE?+}^VIosM#C8S-2FbLVhStWSrU~^aI_wOLETj~kU_)dICq`6N=5`f= ziZieXX#{U>Z&gE~XMqoC+Tf~L;^t1zND7D`ZrBm74bI?=Ey@yBmF6TW&BApdF_iR4 zsW6Z-M7DV$$}va| zcCsrkuvv_h`5tV>KoOKWowVi_c3)B!`V0(AEQ}0{Oyso!Se02B1Y}j@bnLab$q5U7 z4^ctCq^$0l)lq6ZWEjBX;Go|+d&$Fxy9-=xWw=T9gk*fOXTgG9-@cq`4h+yy<|5Sz z3dw0HAO^BI+MOsCPjmQMV z$RWte?-pnoRTk~+S5f0EBFV%csKX_|PUK23Mg=`tKK;a)l|CH+!{QKT#Kyrz zyzLAO42QCCs2kY#2T)>Rbb79u+LKy))O2y3e8YZxf=@QY|Dv67JcVfq=lMa5*qxuw)Z zNiVy>W-#)pvk40dD2RZ0WDwlSViLT}{6vjeVKbh?Sci{;h1gt&X#$(DFo|V8ni(X= z8Jhl4?q~>%hQMeDjD`TYAs{F(Mt1eVz`(#6KA|I&GJCHK3>*v$%$)q3L^e4w zESJj>V3O0(l3*pz0H&nF0-`ZKCbGg(7)BE#Adnlvs_Hl|H$+>7lbi%3=c;NT%sGEY zcS2rmyR$6GiI_=X^4n_1tKUC9|MctE?OJ7$(*WCsU(fIU`t|Gg?_a-uJ}49ABylAT z-(j%k-+%u6{`KqEm!q9tCVZr{pm~q}0vqu6FW7)z*Xm2WiCKLOiyYZ|ApO5UUD!V$ z)~&RtaB~tGWajsO{rdd}q5q+mb7KMtV?xf)fBpXR7qtHVFDL-M?oTji&Lu7uM69G3 zc|tz?`h%qZ<@zLp=u)EQ@Hk5@Pcu}n{|0tDXa*l-|CNbTLuE{f@jt87-e1og?N2Y*2e5Pto-eW0gnu?kT`ARPK@e!L8I zx&G@HX!*e3KYu{c_j!3`-9#Ot*8g(`C9JsIQ~-+pzkmMx{R2+G*VnE*u+o~5oruj~ z%x<#T?;c$TrI}xU{y@_2EceSHem|MSbCSDJUO75b* kP!?7$exla=py-5h#KYuBsBoZ~kSS8?TV#Es>=6_K0ISO1yZ`_I literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f12 b/lib/glut-3.7.6/progs/data/flame/f12 new file mode 100644 index 0000000000000000000000000000000000000000..34042c3a39c1f29d7cfe78b18ff3a11e06330f77 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f13 b/lib/glut-3.7.6/progs/data/flame/f13 new file mode 100644 index 0000000000000000000000000000000000000000..1173973e336afa14dbcc5b83bf0c311ca95ce0b7 GIT binary patch literal 16896 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 F1OR|aar*!O literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f14 b/lib/glut-3.7.6/progs/data/flame/f14 new file mode 100644 index 0000000000000000000000000000000000000000..1c84e8d460fae3f7cc8ea8a5abf87ba08e2c166f GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f17 b/lib/glut-3.7.6/progs/data/flame/f17 new file mode 100644 index 0000000000000000000000000000000000000000..71e985d6c79bfd1da0e96faf2245bf1f4dd17f15 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f20 b/lib/glut-3.7.6/progs/data/flame/f20 new file mode 100644 index 0000000000000000000000000000000000000000..7aa1db15fc278f76c8225ca735bfc2696f9a77b9 GIT binary patch literal 16896 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 Tq=*z7@*_Az`g2s-z=Z$+aIN9I literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f22 b/lib/glut-3.7.6/progs/data/flame/f22 new file mode 100644 index 0000000000000000000000000000000000000000..6c644aeacc788ad75a93641d13b0d3b4b741ae8f GIT binary patch literal 16896 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 bbRn4B8pKvQ2t6n)K_crM6iuU?5fuUe2YQb_ literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f25 b/lib/glut-3.7.6/progs/data/flame/f25 new file mode 100644 index 0000000000000000000000000000000000000000..a72176aafdebcf0ffaf3abc051085a9457836c2f GIT binary patch literal 16896 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 N+;P}FDm*ko005|xu4MoK literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f26 b/lib/glut-3.7.6/progs/data/flame/f26 new file mode 100644 index 0000000000000000000000000000000000000000..d592ea9b0dba2bedb97ae30dfd95ec94d727acae GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/flame/f31 b/lib/glut-3.7.6/progs/data/flame/f31 new file mode 100644 index 0000000000000000000000000000000000000000..5d7b0db1f758e6dfd22f96825560e2d8e89e5721 GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/light.bw b/lib/glut-3.7.6/progs/data/light.bw new file mode 100644 index 0000000000000000000000000000000000000000..5708ae6ae41a66688feabad016a54c631393b5a7 GIT binary patch literal 11979 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 Mln+wZM}dI>0GXh;T>t<8 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/mandrill.rgb b/lib/glut-3.7.6/progs/data/mandrill.rgb new file mode 100644 index 0000000000000000000000000000000000000000..8b935608ee48cd756931acde50abbce8a57cea71 GIT binary patch literal 53783 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/sgi.bw b/lib/glut-3.7.6/progs/data/sgi.bw new file mode 100644 index 0000000000000000000000000000000000000000..f02f807240d65007df5372c0225b5c9a47f673b9 GIT binary patch literal 12800 zcmZR)#lXnG%;3P_z`)D^0slc%UcN$JVs0vkIf_R^067HQm>IlbX$4svlg;GMz~qH4 z%=^im@iRuk5|U+*5Jy)U_Jzshvml!2=6^>y{(a>}6=ghjli}PYCR9PrPycvV{yW5o zB5LsG-wWP<|JI=hGC2PE!|?lWAgbWJfB&Q|{rh8sEXwlq-@li9|Ni~fMiymz`|lsa z-+v!DkOdWf{re|<_20kOY)GO-eamPxjz5< z_Z#H?U;q9cg9V|ihTakMW;>4FCRW{QmcEE=2#mfB!ynf%S8n{rUH=9W46o z-@g-#5d93EfB*djCph7s|Nd=b0PAO1{_o!}8IV%mzyJP*GeGn+?)vxd2S||N-@m^i z3{d@y*Z%#B0Ew>r_wO4YR6p03fB*J_1g-!5d%y(M&%pop-#@TZ|NZ;R1JloN^xwaD zkkSwT{^c=1^)tl%`}Y+j=q=ifg$kkXI;{)NN!yZ`(5 z4J0V^@82I=nEnO-{{03CGR*$>@3#)b{VdP^{rd=x?ETca zZ80ePxfOr?`?nS>$oc8tzsFqQ@GtuN@2?+7kU{0ozkjo!?(h2d?~egk)Zx#+zl~u1 zytn@S`@+M>z`&Tm5cK!oUrVt5Z~y+CV^Wm>sonJN-!ECP{h)NbpOKM)L0E_J@V|dQ z!1}fS{`;HA5W~cv_)U%J^1pu(VEzC8{ghyNbdrI=kDcf1zkip&`j7ql_g#=Jgn{9} zb5_Cc|Nbojx!?ZZzdOvb-?SLo{@rJm`uQ&ss=tdN`|mFXhR+ij(*FMY3fBMO-`_HZ zrY{T(KmS%TRQ`qNclh^9iRt>k$qXz0{Y_%%gXw?A&inP>Uj~+cKP8#(L-l|B_l#Be z$3IqvKmWc9u)c)ppT`jT_umeNmH+;I;bwmq`R}FJzk`1q88-j>_m_eF-@l7Ys=p!j zfBd7*c$pEx-`|NFNKr2pSa2A7C`FZKQ%Jj@760AT%p zeHj*g{qs-u-`|fL865xo`^N>+|HqtR`;vc}SO3`uG0gi1)BjtY(c<4r!+!^bKm{4Z z{(m3XxnBMGxBuVY7d)VX45I(vOIE(c|Fp0E(`EuC0I>Z({{6ep%mLQV07?K*{r@I0 z1pfJV>fhg322eo;*8k_<-)aW1ejeuA|Ni{|>o5HK?{6|UNdFP8Z~y*X1nd9v@83@; zMzDS+Py+Y^)_?Thzwf-uLG}y8{QdX05UgM2>c4;I>p=QH+Wh_ZQxdHIBPjYA!1@_Z z|NHm-F<8IwkAHt%UxM`ao%r|fzA#w7qU^6N*ZB9h`oX_R3}F3lvi|=2A@ld& zsek`ezy14Lc^j;sq2ce-oWK9nF8}*!{PVXOKSV#njQL0Y{X4?_@85UxckEF8%#Z(d zUj6rP?caa*YX81uh3aQ}ZTU?~fH+ zKZDz+fB)_>T=@6ziyb3a|DS&h40^x+{hP+9^yD9?S_0WW=bs`&>%V`0+{(GLLB_Cw z>}UJ;hJj(uzkk227|eeC`?rPxrXQ3(KE(25+5P_aZz|aSIsX(zfBgHmd$q^XB_MA! z!t~4k`uA_;cJ2e9;zbjtzu@n`zrkx3`EFeYDpMi$E1&-N@0(=&n?Lq*4*dJ~L-^lc z2DX21m~Q_2_r=HOxNF46fBzn_fc*dGAK$ls|ITz-|9&4T`{m!it3v;FG0gdw`uE@8 zVwTQ-|DHPweE;|F7({>c-+zDOcFp~}baTMpe}A(e`gi>M_fyRF>A!yy*^>YM`)&rPrVIc6eSP?ki{a0|KmY!9Fckd# z2g=^}{{8z7*8lI{Z#~8npvv;Q0H`hl>;Lob-!Da`8~^_OyT>f~6I5w}^n>awkRL$V zTjdux|IPUaD!yI*{`>p$-@k*5#(zNhpABT%9EJ!`W&Jmqp%=sj>;GfVukL zyBKEw`1f04F*~8+u=7T`d$A*^nVv(0cqv3`19}Ibdd9Q zGF1P2z%2gr-@m=nx%~e8``g5j^Y<46+rNL8nUsG2`?rc=5vWzfcpOxI{rFo03gEw? zB9lO#kY&35Zw7?lqF?04 zKQ@NLFIoA&|ND1#hV*6UumApCXOjJH$iSEluCz-Zz2y6C@%`Vw5#gFJW!BxwKd-xYZK zfeY4t`1kLxFkJuTfB&LDNJ??>@Z!!Uxm;{olW%u=bPl-+zC> z)%S;g|8n5%k65UFQ2Qwu=KgK}{`~~m#L)cr-yd5@__4kF_wN-bq!`x!`}dUx>V8l~ zcMPob$-jS}I3VE%s_3SI1wp0X8(whz-SO|=9}BRc#4k{`g1CSFzkk1#!J@jq|NWZ* z)-Ui3lm)5qDiT2bhkrl8?NqQJLj|n=@D$O1V7dq@H9-A`f431G zGv<4+_J0RNE0_coTcG|6tnm#N1QlDL_WQqIieNs305!ou_P>KPz9E7P#()03-~**& zC?8DqLHiHT#y41u0aU6;UHSLN9?FGM+y0&61jRU%3#LG&8pB_B;~y->z`*tCAKzN^ z{u=||XMe`8=};vw%JuJGhChFUU|c92{*BrCs}Pg}rvh0Rq7cCZ5oSF8fZ^I@cr-x- z8JOZ2nBg57s2Bq%e?wCaT!?`|Se-#$5{VCCf?B;07Ud-4g2`?U2xCA-GogC}DxI;1 zNt?le0nr;}WME=uVPIurXW-!EV&LZCW#Ho%U=S2SbPS<7iJ`D|)v;^DHdKJMtIk0D zPyyDiIs?%|1)vr#MpvDIljxxWPzx87)sVaD3=BjM6@Xf}kgNtS{Gq`HDtJIyjo?rL z)~-4O@k0ezyXp)?4;6sw7mTht1E_gH+)x45t~vwJLj_p7>I|TAinyTytX*{m;)e>b zcGW>u9g#x?Si9;Z3>9GQs*^BOfVHbm!cYMNmaaMj@k0ezyXp)KL=P2U?Wz+$RDiv! zPW(^-_O3edLj~;rKy7*St~yCW1=zdl#19qx!`4;*NAyqu_OALrqK68wch!j>D!|@V zCw{2l4Kuc`ItfDs*t_b)4;3(AcGds>V<2*<0DD*c?>`12hYCRYv3AvoA1c7wRc9c6 zs300!R~^*NCT^$zdsiLQ%_eTB0DD)R_@RP-|Ndd=suMp{0P3lMDoeDk`oFhqAU_Z> zRDiXs4r*b8df7w_6=3PA6F*ddy{rD`AF)FP*t_b)4;3(A?W&V7RDiXsPQp+D1JY(-$kwXR8yXwRb6)<4!s*^BO zz<{-@zW(1oB8LhXuy)l+7%E`E+EpihsDOb1TUVWgp#lc1U3E|s9MpdyVyJ)tYgc{Y zzkfsy6)<4!s*^BOfW50u{7?b3%Z5ggFjRo16Uqhk=b=no)J+wLBGAASXas_h3BG0n zRSWi^0v1*_26hfk1}<(M23|gX1_41K266@fuy)l^9RTBD9V)=uRc9c2sDKk&SDgXt zssgM-1=zak3=G&-6<{4Iz}i)3z`Cjc+fV`4t~$5{1sat@Syg~_r~qqM9W)sS8C67D zRe*J<0Mz=x=&CbdT~&Z}r~q46odHy@VXP{^I#d8ECosC|44|QKj8z3#hYGNE)j>m= z7^@1f4i$i^8qBUb)>Q>qhYGNF)v>NBz&ccby{nFORRPwa0_ zK2(5pRv+uC0_;NtfB#|cs$*SMfPJU{TUY%b)>Q>qhYGNE)&Kp&vZ?_4PyyDi`VVZY z3a}3qVC|}7T~&a6r~vD%KGszQ*oO+Rbk$e>!@jBj`%nR9SAFF_MXaj|unZMooz=&> zssPm0CvsLF>#72feyl?U*k<*yuPVSgQ~>JcVszE9uPTVfHdKJMtB!S50rsH+tX*}i zs|v6W6=0p!$GWNj`%nS)t~$0=1vrKZFlY5~tt!AeRDh+cJ_j`Y3To7&tt!AWRDiXs zj&)T5_Mrl-U3ILh3a}3qVC|}7T~&a6sDJ@mR~`GR0<1#?3|PDBSXUKbA1c7!RmZlf z0Mw-V#0i}h2Q{Ve%<5xZRe*J<0DD*c-@m_@s|v6V6@c1Lm|b#73mLj_o8^|7uhz&=#KfVHcRbyWfOp#rS4`dC*LU>_=Az}i*Ex~c&C zPyu+h45O=#ZB+sGp#to)`k*E_sQ-epssQ^?0rpvatg8yJ4;3(A?W$v2Re*h{0Q;;y z)>Q@AhYGMS0Km4Y0M-pAhK6+Q@u|c*tB*qiwxI$RRt7e94hBvxZU!D+J_ddPK?WgV E00@NPO#lD@ literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/smoke.bw b/lib/glut-3.7.6/progs/data/smoke.bw new file mode 100644 index 0000000000000000000000000000000000000000..43d2058441def8923000784868648b520f5bc7d2 GIT binary patch literal 25430 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/spheremap.rgb b/lib/glut-3.7.6/progs/data/spheremap.rgb new file mode 100644 index 0000000000000000000000000000000000000000..aefc52d738b25e356ec8f9b180d4c129fe86bc75 GIT binary patch literal 12045 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/data/water.bw b/lib/glut-3.7.6/progs/data/water.bw new file mode 100644 index 0000000000000000000000000000000000000000..b600a0477cf84127265a72c469a43034d00075f4 GIT binary patch literal 4608 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 + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name atlantis + End Project Dependency + Begin Project Dependency + Project_Dep_Name bluepony + End Project Dependency + Begin Project Dependency + Project_Dep_Name bounce + End Project Dependency + Begin Project Dependency + Project_Dep_Name chess + End Project Dependency + Begin Project Dependency + Project_Dep_Name geoface + End Project Dependency + Begin Project Dependency + Project_Dep_Name glflare + End Project Dependency + Begin Project Dependency + Project_Dep_Name glutmech + End Project Dependency + Begin Project Dependency + Project_Dep_Name ideas + End Project Dependency + Begin Project Dependency + Project_Dep_Name lorenz + End Project Dependency + Begin Project Dependency + Project_Dep_Name newave + End Project Dependency + Begin Project Dependency + Project_Dep_Name opengl_logo + End Project Dependency + Begin Project Dependency + Project_Dep_Name particle + End Project Dependency + Begin Project Dependency + Project_Dep_Name rollercoaster + End Project Dependency + Begin Project Dependency + Project_Dep_Name skyfly + End Project Dependency + Begin Project Dependency + Project_Dep_Name smooth + End Project Dependency + Begin Project Dependency + Project_Dep_Name sunlight + End Project Dependency + Begin Project Dependency + Project_Dep_Name sysview + End Project Dependency + Begin Project Dependency + Project_Dep_Name underwater + End Project Dependency + Begin Project Dependency + Project_Dep_Name walker + End Project Dependency + Begin Project Dependency + Project_Dep_Name yacme + End Project Dependency +}}} + +############################################################################### + +Project: "atlantis"=".\demos\atlantis\atlantis.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bluepony"=".\demos\bluepony\bluepony.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bounce"=".\demos\bounce\bounce.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "chess"=".\demos\chess\chess.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "geoface"=".\demos\geoface\geoface.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "glflare"=".\demos\glflare\glflare.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gliq"=".\demos\gliq\gliq.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "glutmech"=".\demos\glutmech\glutmech.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "ideas"=".\demos\ideas\ideas.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lorenz"=".\demos\lorenz\lorenz.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "newave"=".\demos\newave\newave.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "opengl_logo"=".\demos\opengl_logo\opengl_logo.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "particle"=".\demos\particle\particle.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rollercoaster"=".\demos\rollercoaster\rollercoaster.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "skyfly"=".\demos\skyfly\skyfly.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "smooth"=".\demos\smooth\smooth.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sunlight"=".\demos\sunlight\sunlight.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "sysview"=".\demos\sysview\sysview.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "underwater"=".\demos\underwater\underwater.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "walker"=".\demos\walker\walker.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "yacme"=".\demos\yacme\yacme.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/glut-3.7.6/progs/demos/Imakefile b/lib/glut-3.7.6/progs/demos/Imakefile new file mode 100644 index 0000000000..5dcc2328de --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/Imakefile @@ -0,0 +1,13 @@ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */ + +#define IHaveSubdirs +#define PassCDebugFlags + +SUBDIRS = ideas atlantis walker yacme glutmech geoface \ + chess rollercoaster underwater opengl_logo bluepony \ + lorenz smooth gliq glflare bounce skyfly particle \ + newave sunlight + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) diff --git a/lib/glut-3.7.6/progs/demos/_all.dsp b/lib/glut-3.7.6/progs/demos/_all.dsp new file mode 100644 index 0000000000..2e26c30f32 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/_all.dsp @@ -0,0 +1,63 @@ +# Microsoft Developer Studio Project File - Name="_all" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Generic Project" 0x010a + +CFG=_all - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "_all.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "_all.mak" CFG="_all - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "_all - Win32 Release" (based on "Win32 (x86) Generic Project") +!MESSAGE "_all - Win32 Debug" (based on "Win32 (x86) Generic Project") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +MTL=midl.exe + +!IF "$(CFG)" == "_all - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "_all - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "_all - Win32 Release" +# Name "_all - Win32 Debug" +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/atlantis/Imakefile b/lib/glut-3.7.6/progs/demos/atlantis/Imakefile new file mode 100644 index 0000000000..85e1551455 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/Imakefile @@ -0,0 +1,14 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../../Glut.cf" + +TARGETS = atlantis + +SRCS = atlantis.c dolphin.c shark.c swim.c whale.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(atlantis,atlantis.o whale.o dolphin.o shark.o swim.o) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/atlantis/atlantis.c b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.c new file mode 100644 index 0000000000..205e338780 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.c @@ -0,0 +1,262 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/** + * (c) Copyright 1993, 1994, 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. + */ +#include +#include +#include +#include +#include +#include "atlantis.h" + +fishRec sharks[NUM_SHARKS]; +fishRec momWhale; +fishRec babyWhale; +fishRec dolph; + +GLboolean moving; + +void +InitFishs(void) +{ + int i; + + for (i = 0; i < NUM_SHARKS; i++) { + sharks[i].x = 70000.0 + rand() % 6000; + sharks[i].y = rand() % 6000; + sharks[i].z = rand() % 6000; + sharks[i].psi = rand() % 360 - 180.0; + sharks[i].v = 1.0; + } + + dolph.x = 30000.0; + dolph.y = 0.0; + dolph.z = 6000.0; + dolph.psi = 90.0; + dolph.theta = 0.0; + dolph.v = 3.0; + + momWhale.x = 70000.0; + momWhale.y = 0.0; + momWhale.z = 0.0; + momWhale.psi = 90.0; + momWhale.theta = 0.0; + momWhale.v = 3.0; + + babyWhale.x = 60000.0; + babyWhale.y = -2000.0; + babyWhale.z = -2000.0; + babyWhale.psi = 90.0; + babyWhale.theta = 0.0; + babyWhale.v = 3.0; +} + +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, 1.0, 0.0, 0.0}; + static float mat_shininess[] = + {90.0}; + static float mat_specular[] = + {0.8, 0.8, 0.8, 1.0}; + static float mat_diffuse[] = + {0.46, 0.66, 0.795, 1.0}; + static float mat_ambient[] = + {0.0, 0.1, 0.2, 1.0}; + static float lmodel_ambient[] = + {0.4, 0.4, 0.4, 1.0}; + static float lmodel_localviewer[] = + {0.0}; + + glFrontFace(GL_CW); + + glDepthFunc(GL_LEQUAL); + 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_LOCAL_VIEWER, lmodel_localviewer); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + 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); + + InitFishs(); + + glClearColor(0.0, 0.5, 0.9, 0.0); +} + +void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(400.0, 2.0, 10000.0, 400000.0); + glMatrixMode(GL_MODELVIEW); +} + +void +Animate(void) +{ + int i; + + for (i = 0; i < NUM_SHARKS; i++) { + SharkPilot(&sharks[i]); + SharkMiss(i); + } + WhalePilot(&dolph); + dolph.phi++; + glutPostRedisplay(); + WhalePilot(&momWhale); + momWhale.phi++; + WhalePilot(&babyWhale); + babyWhale.phi++; +} + +/* ARGSUSED1 */ +void +Key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: /* Esc will quit */ + exit(1); + break; + case ' ': /* space will advance frame */ + if (!moving) { + Animate(); + } + } +} + +void +Display(void) +{ + int i; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + for (i = 0; i < NUM_SHARKS; i++) { + glPushMatrix(); + FishTransform(&sharks[i]); + DrawShark(&sharks[i]); + glPopMatrix(); + } + + glPushMatrix(); + FishTransform(&dolph); + DrawDolphin(&dolph); + glPopMatrix(); + + glPushMatrix(); + FishTransform(&momWhale); + DrawWhale(&momWhale); + glPopMatrix(); + + glPushMatrix(); + FishTransform(&babyWhale); + glScalef(0.45, 0.45, 0.3); + DrawWhale(&babyWhale); + glPopMatrix(); + + glutSwapBuffers(); +} + +void +Visible(int state) +{ + if (state == GLUT_VISIBLE) { + if (moving) + glutIdleFunc(Animate); + } else { + if (moving) + glutIdleFunc(NULL); + } +} + +void +menuSelect(int value) +{ + switch (value) { + case 1: + moving = GL_TRUE; + glutIdleFunc(Animate); + break; + case 2: + moving = GL_FALSE;; + glutIdleFunc(NULL); + break; + case 3: + exit(0); + break; + } +} + +int +main(int argc, char **argv) +{ + glutInitWindowSize(500, 250); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow("GLUT Atlantis Demo"); + Init(); + glutDisplayFunc(Display); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + moving = GL_TRUE; + glutIdleFunc(Animate); + glutVisibilityFunc(Visible); + glutCreateMenu(menuSelect); + glutAddMenuEntry("Start motion", 1); + glutAddMenuEntry("Stop motion", 2); + glutAddMenuEntry("Quit", 3); + glutAttachMenu(GLUT_RIGHT_BUTTON); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/atlantis/atlantis.dsp b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.dsp new file mode 100644 index 0000000000..f1fa16d4c6 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="atlantis" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=atlantis - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "atlantis.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "atlantis.mak" CFG="atlantis - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "atlantis - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "atlantis - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "atlantis - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "atlantis - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "atlantis - Win32 Release" +# Name "atlantis - Win32 Debug" +# Begin Source File + +SOURCE=.\atlantis.c +# End Source File +# Begin Source File + +SOURCE=.\atlantis.h +# End Source File +# Begin Source File + +SOURCE=.\dolphin.c +# End Source File +# Begin Source File + +SOURCE=.\shark.c +# End Source File +# Begin Source File + +SOURCE=.\swim.c +# End Source File +# Begin Source File + +SOURCE=.\whale.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/atlantis/atlantis.h b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.h new file mode 100644 index 0000000000..539141b3d6 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/atlantis.h @@ -0,0 +1,65 @@ +/** + * (c) Copyright 1993, 1994, 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. + */ +#define RAD 57.295 +#define RRAD 0.01745 + +#define NUM_SHARKS 4 +#define SHARKSIZE 6000 +#define SHARKSPEED 100.0 + +#define WHALESPEED 250.0 + +typedef struct _fishRec { + float x, y, z, phi, theta, psi, v; + float xt, yt, zt; + float htail, vtail; + float dtheta; + int spurt, attack; +} fishRec; + +extern fishRec sharks[NUM_SHARKS]; +extern fishRec momWhale; +extern fishRec babyWhale; +extern fishRec dolph; + +extern void FishTransform(fishRec *); +extern void WhalePilot(fishRec *); +extern void SharkPilot(fishRec *); +extern void SharkMiss(int); +extern void DrawWhale(fishRec *); +extern void DrawShark(fishRec *); +extern void DrawDolphin(fishRec *); diff --git a/lib/glut-3.7.6/progs/demos/atlantis/dolphin.c b/lib/glut-3.7.6/progs/demos/atlantis/dolphin.c new file mode 100644 index 0000000000..6c3015f113 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/dolphin.c @@ -0,0 +1,1934 @@ +/** + * (c) Copyright 1993, 1994, 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. + */ +#include +#include +#include "atlantis.h" +/* *INDENT-OFF* */ +static float N001[3] = {-0.005937 ,-0.101998 ,-0.994767}; +static float N002[3] = {0.936780 ,-0.200803 ,0.286569}; +static float N003[3] = {-0.233062 ,0.972058 ,0.028007}; +static float N005[3] = {0.898117 ,0.360171 ,0.252315}; +static float N006[3] = {-0.915437 ,0.348456 ,0.201378}; +static float N007[3] = {0.602263 ,-0.777527 ,0.180920}; +static float N008[3] = {-0.906912 ,-0.412015 ,0.088061}; +static float N012[3] = {0.884408 ,-0.429417 ,-0.182821}; +static float N013[3] = {0.921121 ,0.311084 ,-0.234016}; +static float N014[3] = {0.382635 ,0.877882 ,-0.287948}; +static float N015[3] = {-0.380046 ,0.888166 ,-0.258316}; +static float N016[3] = {-0.891515 ,0.392238 ,-0.226607}; +static float N017[3] = {-0.901419 ,-0.382002 ,-0.203763}; +static float N018[3] = {-0.367225 ,-0.911091 ,-0.187243}; +static float N019[3] = {0.339539 ,-0.924846 ,-0.171388}; +static float N020[3] = {0.914706 ,-0.378617 ,-0.141290}; +static float N021[3] = {0.950662 ,0.262713 ,-0.164994}; +static float N022[3] = {0.546359 ,0.801460 ,-0.243218}; +static float N023[3] = {-0.315796 ,0.917068 ,-0.243431}; +static float N024[3] = {-0.825687 ,0.532277 ,-0.186875}; +static float N025[3] = {-0.974763 ,-0.155232 ,-0.160435}; +static float N026[3] = {-0.560596 ,-0.816658 ,-0.137119}; +static float N027[3] = {0.380210 ,-0.910817 ,-0.160786}; +static float N028[3] = {0.923772 ,-0.358322 ,-0.135093}; +static float N029[3] = {0.951202 ,0.275053 ,-0.139859}; +static float N030[3] = {0.686099 ,0.702548 ,-0.188932}; +static float N031[3] = {-0.521865 ,0.826719 ,-0.210220}; +static float N032[3] = {-0.923820 ,0.346739 ,-0.162258}; +static float N033[3] = {-0.902095 ,-0.409995 ,-0.134646}; +static float N034[3] = {-0.509115 ,-0.848498 ,-0.144404}; +static float N035[3] = {0.456469 ,-0.880293 ,-0.129305}; +static float N036[3] = {0.873401 ,-0.475489 ,-0.105266}; +static float N037[3] = {0.970825 ,0.179861 ,-0.158584}; +static float N038[3] = {0.675609 ,0.714187 ,-0.183004}; +static float N039[3] = {-0.523574 ,0.830212 ,-0.191360}; +static float N040[3] = {-0.958895 ,0.230808 ,-0.165071}; +static float N041[3] = {-0.918285 ,-0.376803 ,-0.121542}; +static float N042[3] = {-0.622467 ,-0.774167 ,-0.114888}; +static float N043[3] = {0.404497 ,-0.908807 ,-0.102231}; +static float N044[3] = {0.930538 ,-0.365155 ,-0.027588}; +static float N045[3] = {0.921920 ,0.374157 ,-0.100345}; +static float N046[3] = {0.507346 ,0.860739 ,0.041562}; +static float N047[3] = {-0.394646 ,0.918815 ,-0.005730}; +static float N048[3] = {-0.925411 ,0.373024 ,-0.066837}; +static float N049[3] = {-0.945337 ,-0.322309 ,-0.049551}; +static float N050[3] = {-0.660437 ,-0.750557 ,-0.022072}; +static float N051[3] = {0.488835 ,-0.871950 ,-0.027261}; +static float N052[3] = {0.902599 ,-0.421397 ,0.087969}; +static float N053[3] = {0.938636 ,0.322606 ,0.122020}; +static float N054[3] = {0.484605 ,0.871078 ,0.079878}; +static float N055[3] = {-0.353607 ,0.931559 ,0.084619}; +static float N056[3] = {-0.867759 ,0.478564 ,0.134054}; +static float N057[3] = {-0.951583 ,-0.296030 ,0.082794}; +static float N058[3] = {-0.672355 ,-0.730209 ,0.121384}; +static float N059[3] = {0.528336 ,-0.842452 ,0.105525}; +static float N060[3] = {0.786913 ,-0.564760 ,0.248627}; +static float N062[3] = {0.622098 ,0.765230 ,0.165584}; +static float N063[3] = {-0.631711 ,0.767816 ,0.106773}; +static float N064[3] = {-0.687886 ,0.606351 ,0.398938}; +static float N065[3] = {-0.946327 ,-0.281623 ,0.158598}; +static float N066[3] = {-0.509549 ,-0.860437 ,0.002776}; +static float N067[3] = {0.462594 ,-0.876692 ,0.131977}; +static float N071[3] = {0.000000 ,1.000000 ,0.000000}; +static float N077[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N078[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N079[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N080[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N081[3] = {-0.571197 ,0.816173 ,0.087152}; +static float N082[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N083[3] = {-0.571197 ,0.816173 ,0.087152}; +static float N084[3] = {-0.571197 ,0.816173 ,0.087152}; +static float N085[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N086[3] = {-0.571197 ,0.816173 ,0.087152}; +static float N087[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N088[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N089[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N090[3] = {-0.880770 ,0.461448 ,0.106351}; +static float N091[3] = {0.000000 ,1.000000 ,0.000000}; +static float N092[3] = {0.000000 ,1.000000 ,0.000000}; +static float N093[3] = {0.000000 ,1.000000 ,0.000000}; +static float N094[3] = {1.000000 ,0.000000 ,0.000000}; +static float N095[3] = {-1.000000 ,0.000000 ,0.000000}; +static float N097[3] = {-0.697296 ,0.702881 ,0.140491}; +static float N098[3] = {0.918864 ,0.340821 ,0.198819}; +static float N099[3] = {-0.932737 ,0.201195 ,0.299202}; +static float N100[3] = {0.029517 ,0.981679 ,0.188244}; +static float N102[3] = {0.813521 ,-0.204936 ,0.544229}; +static float N110[3] = {-0.781480 ,-0.384779 ,0.491155}; +static float N111[3] = {-0.722243 ,0.384927 ,0.574627}; +static float N112[3] = {-0.752278 ,0.502679 ,0.425901}; +static float N113[3] = {0.547257 ,0.367910 ,0.751766}; +static float N114[3] = {0.725949 ,-0.232568 ,0.647233}; +static float N115[3] = {-0.747182 ,-0.660786 ,0.071280}; +static float N116[3] = {0.931519 ,0.200748 ,0.303270}; +static float N117[3] = {-0.828928 ,0.313757 ,0.463071}; +static float N118[3] = {0.902554 ,-0.370967 ,0.218587}; +static float N119[3] = {-0.879257 ,-0.441851 ,0.177973}; +static float N120[3] = {0.642327 ,0.611901 ,0.461512}; +static float N121[3] = {0.964817 ,-0.202322 ,0.167910}; +static float N122[3] = {0.000000 ,1.000000 ,0.000000}; +static float P001[3] = {5.68, -300.95, 1324.70}; +static float P002[3] = {338.69, -219.63, 9677.03}; +static float P003[3] = {12.18, 474.59, 9138.14}; +static float P005[3] = {487.51, 198.05, 9350.78}; +static float P006[3] = {-457.61, 68.74, 9427.85}; +static float P007[3] = {156.52, -266.72, 10311.68}; +static float P008[3] = {-185.56, -266.51, 10310.47}; +static float P009[3] = {124.39, -261.46, 1942.34}; +static float P010[3] = {-130.05, -261.46, 1946.03}; +static float P011[3] = {141.07, -320.11, 1239.38}; +static float P012[3] = {156.48, -360.12, 2073.41}; +static float P013[3] = {162.00, -175.88, 2064.44}; +static float P014[3] = {88.16, -87.72, 2064.02}; +static float P015[3] = {-65.21, -96.13, 2064.02}; +static float P016[3] = {-156.48, -180.96, 2064.44}; +static float P017[3] = {-162.00, -368.93, 2082.39}; +static float P018[3] = {-88.16, -439.22, 2082.39}; +static float P019[3] = {65.21, -440.32, 2083.39}; +static float P020[3] = {246.87, -356.02, 2576.95}; +static float P021[3] = {253.17, -111.15, 2567.15}; +static float P022[3] = {132.34, 51.41, 2559.84}; +static float P023[3] = {-97.88, 40.44, 2567.15}; +static float P024[3] = {-222.97, -117.49, 2567.15}; +static float P025[3] = {-252.22, -371.53, 2569.92}; +static float P026[3] = {-108.44, -518.19, 2586.75}; +static float P027[3] = {97.88, -524.79, 2586.75}; +static float P028[3] = {370.03, -421.19, 3419.70}; +static float P029[3] = {351.15, -16.98, 3423.17}; +static float P030[3] = {200.66, 248.46, 3430.37}; +static float P031[3] = {-148.42, 235.02, 3417.91}; +static float P032[3] = {-360.21, -30.27, 3416.84}; +static float P033[3] = {-357.90, -414.89, 3407.04}; +static float P034[3] = {-148.88, -631.35, 3409.90}; +static float P035[3] = {156.38, -632.59, 3419.70}; +static float P036[3] = {462.61, -469.21, 4431.51}; +static float P037[3] = {466.60, 102.25, 4434.98}; +static float P038[3] = {243.05, 474.34, 4562.02}; +static float P039[3] = {-191.23, 474.40, 4554.42}; +static float P040[3] = {-476.12, 111.05, 4451.11}; +static float P041[3] = {-473.36, -470.74, 4444.78}; +static float P042[3] = {-266.95, -748.41, 4447.78}; +static float P043[3] = {211.14, -749.91, 4429.73}; +static float P044[3] = {680.57, -370.27, 5943.46}; +static float P045[3] = {834.01, 363.09, 6360.63}; +static float P046[3] = {371.29, 804.51, 6486.26}; +static float P047[3] = {-291.43, 797.22, 6494.28}; +static float P048[3] = {-784.13, 370.75, 6378.01}; +static float P049[3] = {-743.29, -325.82, 5943.46}; +static float P050[3] = {-383.24, -804.77, 5943.46}; +static float P051[3] = {283.47, -846.09, 5943.46}; +static float iP001[3] = {5.68, -300.95, 1324.70}; +static float iP009[3] = {124.39, -261.46, 1942.34}; +static float iP010[3] = {-130.05, -261.46, 1946.03}; +static float iP011[3] = {141.07, -320.11, 1239.38}; +static float iP012[3] = {156.48, -360.12, 2073.41}; +static float iP013[3] = {162.00, -175.88, 2064.44}; +static float iP014[3] = {88.16, -87.72, 2064.02}; +static float iP015[3] = {-65.21, -96.13, 2064.02}; +static float iP016[3] = {-156.48, -180.96, 2064.44}; +static float iP017[3] = {-162.00, -368.93, 2082.39}; +static float iP018[3] = {-88.16, -439.22, 2082.39}; +static float iP019[3] = {65.21, -440.32, 2083.39}; +static float iP020[3] = {246.87, -356.02, 2576.95}; +static float iP021[3] = {253.17, -111.15, 2567.15}; +static float iP022[3] = {132.34, 51.41, 2559.84}; +static float iP023[3] = {-97.88, 40.44, 2567.15}; +static float iP024[3] = {-222.97, -117.49, 2567.15}; +static float iP025[3] = {-252.22, -371.53, 2569.92}; +static float iP026[3] = {-108.44, -518.19, 2586.75}; +static float iP027[3] = {97.88, -524.79, 2586.75}; +static float iP028[3] = {370.03, -421.19, 3419.70}; +static float iP029[3] = {351.15, -16.98, 3423.17}; +static float iP030[3] = {200.66, 248.46, 3430.37}; +static float iP031[3] = {-148.42, 235.02, 3417.91}; +static float iP032[3] = {-360.21, -30.27, 3416.84}; +static float iP033[3] = {-357.90, -414.89, 3407.04}; +static float iP034[3] = {-148.88, -631.35, 3409.90}; +static float iP035[3] = {156.38, -632.59, 3419.70}; +static float iP036[3] = {462.61, -469.21, 4431.51}; +static float iP037[3] = {466.60, 102.25, 4434.98}; +static float iP038[3] = {243.05, 474.34, 4562.02}; +static float iP039[3] = {-191.23, 474.40, 4554.42}; +static float iP040[3] = {-476.12, 111.05, 4451.11}; +static float iP041[3] = {-473.36, -470.74, 4444.78}; +static float iP042[3] = {-266.95, -748.41, 4447.78}; +static float iP043[3] = {211.14, -749.91, 4429.73}; +static float iP044[3] = {680.57, -370.27, 5943.46}; +static float iP045[3] = {834.01, 363.09, 6360.63}; +static float iP046[3] = {371.29, 804.51, 6486.26}; +static float iP047[3] = {-291.43, 797.22, 6494.28}; +static float iP048[3] = {-784.13, 370.75, 6378.01}; +static float iP049[3] = {-743.29, -325.82, 5943.46}; +static float iP050[3] = {-383.24, -804.77, 5943.46}; +static float iP051[3] = {283.47, -846.09, 5943.46}; +static float P052[3] = {599.09, -300.15, 7894.03}; +static float P053[3] = {735.48, 306.26, 7911.92}; +static float P054[3] = {246.22, 558.53, 8460.50}; +static float P055[3] = {-230.41, 559.84, 8473.23}; +static float P056[3] = {-698.66, 320.83, 7902.59}; +static float P057[3] = {-643.29, -299.16, 7902.59}; +static float P058[3] = {-341.47, -719.30, 7902.59}; +static float P059[3] = {252.57, -756.12, 7902.59}; +static float P060[3] = {458.39, -265.31, 9355.44}; +static float P062[3] = {224.04, 338.75, 9450.30}; +static float P063[3] = {-165.71, 341.04, 9462.35}; +static float P064[3] = {-298.11, 110.13, 10180.37}; +static float P065[3] = {-473.99, -219.71, 9355.44}; +static float P066[3] = {-211.97, -479.87, 9355.44}; +static float P067[3] = {192.86, -491.45, 9348.73}; +static float P068[3] = {-136.29, -319.84, 1228.73}; +static float P069[3] = {1111.17, -314.14, 1314.19}; +static float P070[3] = {-1167.34, -321.61, 1319.45}; +static float P071[3] = {1404.86, -306.66, 1235.45}; +static float P072[3] = {-1409.73, -314.14, 1247.66}; +static float P073[3] = {1254.01, -296.87, 1544.58}; +static float P074[3] = {-1262.09, -291.70, 1504.26}; +static float P075[3] = {965.71, -269.26, 1742.65}; +static float P076[3] = {-900.97, -276.74, 1726.07}; +static float iP068[3] = {-136.29, -319.84, 1228.73}; +static float iP069[3] = {1111.17, -314.14, 1314.19}; +static float iP070[3] = {-1167.34, -321.61, 1319.45}; +static float iP071[3] = {1404.86, -306.66, 1235.45}; +static float iP072[3] = {-1409.73, -314.14, 1247.66}; +static float iP073[3] = {1254.01, -296.87, 1544.58}; +static float iP074[3] = {-1262.09, -291.70, 1504.26}; +static float iP075[3] = {965.71, -269.26, 1742.65}; +static float iP076[3] = {-900.97, -276.74, 1726.07}; +static float P077[3] = {1058.00, -448.81, 8194.66}; +static float P078[3] = {-1016.51, -456.43, 8190.62}; +static float P079[3] = {-1515.96, -676.45, 7754.93}; +static float P080[3] = {1856.75, -830.34, 7296.56}; +static float P081[3] = {1472.16, -497.38, 7399.68}; +static float P082[3] = {-1775.26, -829.51, 7298.46}; +static float P083[3] = {911.09, -252.51, 7510.99}; +static float P084[3] = {-1451.94, -495.62, 7384.30}; +static float P085[3] = {1598.75, -669.26, 7769.90}; +static float P086[3] = {-836.53, -250.08, 7463.25}; +static float P087[3] = {722.87, -158.18, 8006.41}; +static float P088[3] = {-688.86, -162.28, 7993.89}; +static float P089[3] = {-626.92, -185.30, 8364.98}; +static float P090[3] = {647.72, -189.46, 8354.99}; +static float P091[3] = {0.00, 835.01, 5555.62}; +static float P092[3] = {0.00, 1350.18, 5220.86}; +static float P093[3] = {0.00, 1422.94, 5285.27}; +static float P094[3] = {0.00, 1296.75, 5650.19}; +static float P095[3] = {0.00, 795.63, 6493.88}; +static float iP091[3] = {0.00, 835.01, 5555.62}; +static float iP092[3] = {0.00, 1350.18, 5220.86}; +static float iP093[3] = {0.00, 1422.94, 5285.27}; +static float iP094[3] = {0.00, 1296.75, 5650.19}; +static float iP095[3] = {0.00, 795.63, 6493.88}; +static float P097[3] = {-194.91, -357.14, 10313.32}; +static float P098[3] = {135.35, -357.66, 10307.94}; +static float iP097[3] = {-194.91, -357.14, 10313.32}; +static float iP098[3] = {135.35, -357.66, 10307.94}; +static float P099[3] = {-380.53, -221.14, 9677.98}; +static float P100[3] = {0.00, 412.99, 9629.33}; +static float P102[3] = {59.51, -412.55, 10677.58}; +static float iP102[3] = {59.51, -412.55, 10677.58}; +static float P103[3] = {6.50, 484.74, 9009.94}; +static float P105[3] = {-41.86, 476.51, 9078.17}; +static float P108[3] = {49.20, 476.83, 9078.24}; +static float P110[3] = {-187.62, -410.04, 10674.12}; +static float iP110[3] = {-187.62, -410.04, 10674.12}; +static float P111[3] = {-184.25, -318.70, 10723.88}; +static float iP111[3] = {-184.25, -318.70, 10723.88}; +static float P112[3] = {-179.61, -142.81, 10670.26}; +static float P113[3] = {57.43, -147.94, 10675.26}; +static float P114[3] = {54.06, -218.90, 10712.44}; +static float P115[3] = {-186.35, -212.09, 10713.76}; +static float P116[3] = {205.90, -84.61, 10275.97}; +static float P117[3] = {-230.96, -83.26, 10280.09}; +static float iP118[3] = {216.78, -509.17, 10098.94}; +static float iP119[3] = {-313.21, -510.79, 10102.62}; +static float P118[3] = {216.78, -509.17, 10098.94}; +static float P119[3] = {-313.21, -510.79, 10102.62}; +static float P120[3] = {217.95, 96.34, 10161.62}; +static float P121[3] = {71.99, -319.74, 10717.70}; +static float iP121[3] = {71.99, -319.74, 10717.70}; +static float P122[3] = {0.00, 602.74, 5375.84}; +static float iP122[3] = {0.00, 602.74, 5375.84}; +static float P123[3] = {-448.94, -203.14, 9499.60}; +static float P124[3] = {-442.64, -185.20, 9528.07}; +static float P125[3] = {-441.07, -148.05, 9528.07}; +static float P126[3] = {-443.43, -128.84, 9499.60}; +static float P127[3] = {-456.87, -146.78, 9466.67}; +static float P128[3] = {-453.68, -183.93, 9466.67}; +static float P129[3] = {428.43, -124.08, 9503.03}; +static float P130[3] = {419.73, -142.14, 9534.56}; +static float P131[3] = {419.92, -179.96, 9534.56}; +static float P132[3] = {431.20, -199.73, 9505.26}; +static float P133[3] = {442.28, -181.67, 9475.96}; +static float P134[3] = {442.08, -143.84, 9475.96}; +/* *INDENT-ON* */ + +void +Dolphin001(void) +{ + glNormal3fv(N071); + glBegin(GL_POLYGON); + glVertex3fv(P001); + glVertex3fv(P068); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P068); + glVertex3fv(P076); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P068); + glVertex3fv(P070); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P076); + glVertex3fv(P070); + glVertex3fv(P074); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P070); + glVertex3fv(P072); + glVertex3fv(P074); + glEnd(); + glNormal3fv(N119); + glBegin(GL_POLYGON); + glVertex3fv(P072); + glVertex3fv(P070); + glVertex3fv(P074); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P074); + glVertex3fv(P070); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P070); + glVertex3fv(P068); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P076); + glVertex3fv(P068); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P068); + glVertex3fv(P001); + glVertex3fv(P010); + glEnd(); +} + +void +Dolphin002(void) +{ + glNormal3fv(N071); + glBegin(GL_POLYGON); + glVertex3fv(P011); + glVertex3fv(P001); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P075); + glVertex3fv(P011); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P069); + glVertex3fv(P011); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P069); + glVertex3fv(P075); + glVertex3fv(P073); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P071); + glVertex3fv(P069); + glVertex3fv(P073); + glEnd(); + glNormal3fv(N119); + glBegin(GL_POLYGON); + glVertex3fv(P001); + glVertex3fv(P011); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P009); + glVertex3fv(P011); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P011); + glVertex3fv(P069); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P069); + glVertex3fv(P073); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P069); + glVertex3fv(P071); + glVertex3fv(P073); + glEnd(); +} + +void +Dolphin003(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N019); + glVertex3fv(P019); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N012); + glVertex3fv(P012); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N018); + glVertex3fv(P018); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N016); + glVertex3fv(P016); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N012); + glVertex3fv(P012); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N015); + glVertex3fv(P015); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N013); + glVertex3fv(P013); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N014); + glVertex3fv(P014); + glEnd(); +} + +void +Dolphin004(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N022); + glVertex3fv(P022); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N023); + glVertex3fv(P023); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N024); + glVertex3fv(P024); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N025); + glVertex3fv(P025); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N021); + glVertex3fv(P021); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N020); + glVertex3fv(P020); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N026); + glVertex3fv(P026); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N027); + glVertex3fv(P027); + glEnd(); +} + +void +Dolphin005(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N031); + glVertex3fv(P031); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N031); + glVertex3fv(P031); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N028); + glVertex3fv(P028); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N028); + glVertex3fv(P028); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N035); + glVertex3fv(P035); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N033); + glVertex3fv(P033); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N034); + glVertex3fv(P034); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N034); + glVertex3fv(P034); + glEnd(); +} + +void +Dolphin006(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N093); + glVertex3fv(P093); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N093); + glVertex3fv(P093); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N091); + glVertex3fv(P091); + glNormal3fv(N095); + glVertex3fv(P095); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N091); + glVertex3fv(P091); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N094); + glVertex3fv(P094); + glNormal3fv(N095); + glVertex3fv(P095); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N122); + glVertex3fv(P122); + glNormal3fv(N095); + glVertex3fv(P095); + glNormal3fv(N091); + glVertex3fv(P091); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N122); + glVertex3fv(P122); + glNormal3fv(N091); + glVertex3fv(P091); + glNormal3fv(N095); + glVertex3fv(P095); + glEnd(); +} + +void +Dolphin007(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N038); + glVertex3fv(P038); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N038); + glVertex3fv(P038); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N037); + glVertex3fv(P037); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N037); + glVertex3fv(P037); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N036); + glVertex3fv(P036); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N036); + glVertex3fv(P036); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N043); + glVertex3fv(P043); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N042); + glVertex3fv(P042); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N042); + glVertex3fv(P042); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N041); + glVertex3fv(P041); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N039); + glVertex3fv(P039); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N040); + glVertex3fv(P040); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N040); + glVertex3fv(P040); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N041); + glVertex3fv(P041); + glEnd(); +} + +void +Dolphin008(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N051); + glVertex3fv(P051); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N047); + glVertex3fv(P047); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N046); + glVertex3fv(P046); + glEnd(); +} + +void +Dolphin009(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N058); + glVertex3fv(P058); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N059); + glVertex3fv(P059); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N053); + glVertex3fv(P053); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N058); + glVertex3fv(P058); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N057); + glVertex3fv(P057); + glNormal3fv(N056); + glVertex3fv(P056); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N056); + glVertex3fv(P056); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N055); + glVertex3fv(P055); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); +} + +void +Dolphin010(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N080); + glVertex3fv(P080); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N085); + glVertex3fv(P085); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N077); + glVertex3fv(P077); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N090); + glVertex3fv(P090); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N080); + glVertex3fv(P080); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N085); + glVertex3fv(P085); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N077); + glVertex3fv(P077); + glNormal3fv(N090); + glVertex3fv(P090); + glEnd(); +} + +void +Dolphin011(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N082); + glVertex3fv(P082); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N079); + glVertex3fv(P079); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N078); + glVertex3fv(P078); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N089); + glVertex3fv(P089); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N089); + glVertex3fv(P089); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N089); + glVertex3fv(P089); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N078); + glVertex3fv(P078); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N082); + glVertex3fv(P082); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); +} + +void +Dolphin012(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N066); + glVertex3fv(P066); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N052); + glVertex3fv(P052); + glNormal3fv(N060); + glVertex3fv(P060); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N067); + glVertex3fv(P067); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N065); + glVertex3fv(P065); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N057); + glVertex3fv(P057); + glNormal3fv(N065); + glVertex3fv(P065); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N006); + glVertex3fv(P006); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N063); + glVertex3fv(P063); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N055); + glVertex3fv(P055); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N005); + glVertex3fv(P005); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N052); + glVertex3fv(P052); + glNormal3fv(N053); + glVertex3fv(P053); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N060); + glVertex3fv(P060); + glEnd(); +} + +void +Dolphin013(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N116); + glVertex3fv(P116); + glNormal3fv(N117); + glVertex3fv(P117); + glNormal3fv(N112); + glVertex3fv(P112); + glNormal3fv(N113); + glVertex3fv(P113); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N114); + glVertex3fv(P114); + glNormal3fv(N113); + glVertex3fv(P113); + glNormal3fv(N112); + glVertex3fv(P112); + glNormal3fv(N115); + glVertex3fv(P115); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N114); + glVertex3fv(P114); + glNormal3fv(N116); + glVertex3fv(P116); + glNormal3fv(N113); + glVertex3fv(P113); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N114); + glVertex3fv(P114); + glNormal3fv(N007); + glVertex3fv(P007); + glNormal3fv(N116); + glVertex3fv(P116); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N007); + glVertex3fv(P007); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N116); + glVertex3fv(P116); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P002); + glVertex3fv(P007); + glVertex3fv(P008); + glVertex3fv(P099); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P007); + glVertex3fv(P114); + glVertex3fv(P115); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N117); + glVertex3fv(P117); + glNormal3fv(N099); + glVertex3fv(P099); + glNormal3fv(N008); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N117); + glVertex3fv(P117); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N112); + glVertex3fv(P112); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N112); + glVertex3fv(P112); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N115); + glVertex3fv(P115); + glEnd(); +} + +void +Dolphin014(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N111); + glVertex3fv(P111); + glNormal3fv(N110); + glVertex3fv(P110); + glNormal3fv(N102); + glVertex3fv(P102); + glNormal3fv(N121); + glVertex3fv(P121); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N111); + glVertex3fv(P111); + glNormal3fv(N097); + glVertex3fv(P097); + glNormal3fv(N110); + glVertex3fv(P110); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N097); + glVertex3fv(P097); + glNormal3fv(N119); + glVertex3fv(P119); + glNormal3fv(N110); + glVertex3fv(P110); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N097); + glVertex3fv(P097); + glNormal3fv(N099); + glVertex3fv(P099); + glNormal3fv(N119); + glVertex3fv(P119); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N099); + glVertex3fv(P099); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N119); + glVertex3fv(P119); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N119); + glVertex3fv(P119); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P098); + glVertex3fv(P097); + glVertex3fv(P111); + glVertex3fv(P121); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P002); + glVertex3fv(P099); + glVertex3fv(P097); + glVertex3fv(P098); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N110); + glVertex3fv(P110); + glNormal3fv(N119); + glVertex3fv(P119); + glNormal3fv(N118); + glVertex3fv(P118); + glNormal3fv(N102); + glVertex3fv(P102); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N119); + glVertex3fv(P119); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N118); + glVertex3fv(P118); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N118); + glVertex3fv(P118); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N118); + glVertex3fv(P118); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N098); + glVertex3fv(P098); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N118); + glVertex3fv(P118); + glNormal3fv(N098); + glVertex3fv(P098); + glNormal3fv(N102); + glVertex3fv(P102); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N102); + glVertex3fv(P102); + glNormal3fv(N098); + glVertex3fv(P098); + glNormal3fv(N121); + glVertex3fv(P121); + glEnd(); +} + +void +Dolphin015(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N063); + glVertex3fv(P063); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N100); + glVertex3fv(P100); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N062); + glVertex3fv(P062); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N064); + glVertex3fv(P064); + glNormal3fv(N120); + glVertex3fv(P120); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N064); + glVertex3fv(P064); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N064); + glVertex3fv(P064); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N064); + glVertex3fv(P064); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N099); + glVertex3fv(P099); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N064); + glVertex3fv(P064); + glNormal3fv(N099); + glVertex3fv(P099); + glNormal3fv(N117); + glVertex3fv(P117); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N120); + glVertex3fv(P120); + glNormal3fv(N064); + glVertex3fv(P064); + glNormal3fv(N117); + glVertex3fv(P117); + glNormal3fv(N116); + glVertex3fv(P116); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N099); + glVertex3fv(P099); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N120); + glVertex3fv(P120); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N120); + glVertex3fv(P120); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N120); + glVertex3fv(P120); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N120); + glVertex3fv(P120); + glNormal3fv(N116); + glVertex3fv(P116); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); +} + +void +Dolphin016(void) +{ + + glDisable(GL_DEPTH_TEST); + glBegin(GL_POLYGON); + glVertex3fv(P123); + glVertex3fv(P124); + glVertex3fv(P125); + glVertex3fv(P126); + glVertex3fv(P127); + glVertex3fv(P128); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P129); + glVertex3fv(P130); + glVertex3fv(P131); + glVertex3fv(P132); + glVertex3fv(P133); + glVertex3fv(P134); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P103); + glVertex3fv(P105); + glVertex3fv(P108); + glEnd(); + glEnable(GL_DEPTH_TEST); +} + +void +DrawDolphin(fishRec * fish) +{ + float seg0, seg1, seg2, seg3, seg4, seg5, seg6, seg7; + float pitch, thrash, chomp; + + fish->htail = (int) (fish->htail - (int) (10.0 * fish->v)) % 360; + + thrash = 70.0 * fish->v; + + seg0 = 1.0 * thrash * sin((fish->htail) * RRAD); + seg3 = 1.0 * thrash * sin((fish->htail) * RRAD); + seg1 = 2.0 * thrash * sin((fish->htail + 4.0) * RRAD); + seg2 = 3.0 * thrash * sin((fish->htail + 6.0) * RRAD); + seg4 = 4.0 * thrash * sin((fish->htail + 10.0) * RRAD); + seg5 = 4.5 * thrash * sin((fish->htail + 15.0) * RRAD); + seg6 = 5.0 * thrash * sin((fish->htail + 20.0) * RRAD); + seg7 = 6.0 * thrash * sin((fish->htail + 30.0) * RRAD); + + pitch = fish->v * sin((fish->htail + 180.0) * RRAD); + + if (fish->v > 2.0) { + chomp = -(fish->v - 2.0) * 200.0; + } + chomp = 100.0; + + P012[1] = iP012[1] + seg5; + P013[1] = iP013[1] + seg5; + P014[1] = iP014[1] + seg5; + P015[1] = iP015[1] + seg5; + P016[1] = iP016[1] + seg5; + P017[1] = iP017[1] + seg5; + P018[1] = iP018[1] + seg5; + P019[1] = iP019[1] + seg5; + + P020[1] = iP020[1] + seg4; + P021[1] = iP021[1] + seg4; + P022[1] = iP022[1] + seg4; + P023[1] = iP023[1] + seg4; + P024[1] = iP024[1] + seg4; + P025[1] = iP025[1] + seg4; + P026[1] = iP026[1] + seg4; + P027[1] = iP027[1] + seg4; + + P028[1] = iP028[1] + seg2; + P029[1] = iP029[1] + seg2; + P030[1] = iP030[1] + seg2; + P031[1] = iP031[1] + seg2; + P032[1] = iP032[1] + seg2; + P033[1] = iP033[1] + seg2; + P034[1] = iP034[1] + seg2; + P035[1] = iP035[1] + seg2; + + P036[1] = iP036[1] + seg1; + P037[1] = iP037[1] + seg1; + P038[1] = iP038[1] + seg1; + P039[1] = iP039[1] + seg1; + P040[1] = iP040[1] + seg1; + P041[1] = iP041[1] + seg1; + P042[1] = iP042[1] + seg1; + P043[1] = iP043[1] + seg1; + + P044[1] = iP044[1] + seg0; + P045[1] = iP045[1] + seg0; + P046[1] = iP046[1] + seg0; + P047[1] = iP047[1] + seg0; + P048[1] = iP048[1] + seg0; + P049[1] = iP049[1] + seg0; + P050[1] = iP050[1] + seg0; + P051[1] = iP051[1] + seg0; + + P009[1] = iP009[1] + seg6; + P010[1] = iP010[1] + seg6; + P075[1] = iP075[1] + seg6; + P076[1] = iP076[1] + seg6; + + P001[1] = iP001[1] + seg7; + P011[1] = iP011[1] + seg7; + P068[1] = iP068[1] + seg7; + P069[1] = iP069[1] + seg7; + P070[1] = iP070[1] + seg7; + P071[1] = iP071[1] + seg7; + P072[1] = iP072[1] + seg7; + P073[1] = iP073[1] + seg7; + P074[1] = iP074[1] + seg7; + + P091[1] = iP091[1] + seg3; + P092[1] = iP092[1] + seg3; + P093[1] = iP093[1] + seg3; + P094[1] = iP094[1] + seg3; + P095[1] = iP095[1] + seg3; + P122[1] = iP122[1] + seg3 * 1.5; + + P097[1] = iP097[1] + chomp; + P098[1] = iP098[1] + chomp; + P102[1] = iP102[1] + chomp; + P110[1] = iP110[1] + chomp; + P111[1] = iP111[1] + chomp; + P121[1] = iP121[1] + chomp; + P118[1] = iP118[1] + chomp; + P119[1] = iP119[1] + chomp; + + glPushMatrix(); + + glRotatef(pitch, 1.0, 0.0, 0.0); + + glTranslatef(0.0, 0.0, 7000.0); + + glRotatef(180.0, 0.0, 1.0, 0.0); + + glEnable(GL_CULL_FACE); + Dolphin014(); + Dolphin010(); + Dolphin009(); + Dolphin012(); + Dolphin013(); + Dolphin006(); + Dolphin002(); + Dolphin001(); + Dolphin003(); + Dolphin015(); + Dolphin004(); + Dolphin005(); + Dolphin007(); + Dolphin008(); + Dolphin011(); + Dolphin016(); + glDisable(GL_CULL_FACE); + + glPopMatrix(); +} diff --git a/lib/glut-3.7.6/progs/demos/atlantis/shark.c b/lib/glut-3.7.6/progs/demos/atlantis/shark.c new file mode 100644 index 0000000000..0ec499f66f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/shark.c @@ -0,0 +1,1308 @@ +/** + * (c) Copyright 1993, 1994, 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. + */ +#include +#include +#include "atlantis.h" +/* *INDENT-OFF* */ +static float N002[3] = {0.000077 ,-0.020611 ,0.999788}; +static float N003[3] = {0.961425 ,0.258729 ,-0.093390}; +static float N004[3] = {0.510811 ,-0.769633 ,-0.383063}; +static float N005[3] = {0.400123 ,0.855734 ,-0.328055}; +static float N006[3] = {-0.770715 ,0.610204 ,-0.183440}; +static float N007[3] = {-0.915597 ,-0.373345 ,-0.149316}; +static float N008[3] = {-0.972788 ,0.208921 ,-0.100179}; +static float N009[3] = {-0.939713 ,-0.312268 ,-0.139383}; +static float N010[3] = {-0.624138 ,-0.741047 ,-0.247589}; +static float N011[3] = {0.591434 ,-0.768401 ,-0.244471}; +static float N012[3] = {0.935152 ,-0.328495 ,-0.132598}; +static float N013[3] = {0.997102 ,0.074243 ,-0.016593}; +static float N014[3] = {0.969995 ,0.241712 ,-0.026186}; +static float N015[3] = {0.844539 ,0.502628 ,-0.184714}; +static float N016[3] = {-0.906608 ,0.386308 ,-0.169787}; +static float N017[3] = {-0.970016 ,0.241698 ,-0.025516}; +static float N018[3] = {-0.998652 ,0.050493 ,-0.012045}; +static float N019[3] = {-0.942685 ,-0.333051 ,-0.020556}; +static float N020[3] = {-0.660944 ,-0.750276 ,0.015480}; +static float N021[3] = {0.503549 ,-0.862908 ,-0.042749}; +static float N022[3] = {0.953202 ,-0.302092 ,-0.012089}; +static float N023[3] = {0.998738 ,0.023574 ,0.044344}; +static float N024[3] = {0.979297 ,0.193272 ,0.060202}; +static float N025[3] = {0.798300 ,0.464885 ,0.382883}; +static float N026[3] = {-0.756590 ,0.452403 ,0.472126}; +static float N027[3] = {-0.953855 ,0.293003 ,0.065651}; +static float N028[3] = {-0.998033 ,0.040292 ,0.048028}; +static float N029[3] = {-0.977079 ,-0.204288 ,0.059858}; +static float N030[3] = {-0.729117 ,-0.675304 ,0.111140}; +static float N031[3] = {0.598361 ,-0.792753 ,0.116221}; +static float N032[3] = {0.965192 ,-0.252991 ,0.066332}; +static float N033[3] = {0.998201 ,-0.002790 ,0.059892}; +static float N034[3] = {0.978657 ,0.193135 ,0.070207}; +static float N035[3] = {0.718815 ,0.680392 ,0.142733}; +static float N036[3] = {-0.383096 ,0.906212 ,0.178936}; +static float N037[3] = {-0.952831 ,0.292590 ,0.080647}; +static float N038[3] = {-0.997680 ,0.032417 ,0.059861}; +static float N039[3] = {-0.982629 ,-0.169881 ,0.074700}; +static float N040[3] = {-0.695424 ,-0.703466 ,0.146700}; +static float N041[3] = {0.359323 ,-0.915531 ,0.180805}; +static float N042[3] = {0.943356 ,-0.319387 ,0.089842}; +static float N043[3] = {0.998272 ,-0.032435 ,0.048993}; +static float N044[3] = {0.978997 ,0.193205 ,0.065084}; +static float N045[3] = {0.872144 ,0.470094 ,-0.135565}; +static float N046[3] = {-0.664282 ,0.737945 ,-0.119027}; +static float N047[3] = {-0.954508 ,0.288570 ,0.075107}; +static float N048[3] = {-0.998273 ,0.032406 ,0.048993}; +static float N049[3] = {-0.979908 ,-0.193579 ,0.048038}; +static float N050[3] = {-0.858736 ,-0.507202 ,-0.072938}; +static float N051[3] = {0.643545 ,-0.763887 ,-0.048237}; +static float N052[3] = {0.955580 ,-0.288954 ,0.058068}; +static float N058[3] = {0.000050 ,0.793007 ,-0.609213}; +static float N059[3] = {0.913510 ,0.235418 ,-0.331779}; +static float N060[3] = {-0.807970 ,0.495000 ,-0.319625}; +static float N061[3] = {0.000000 ,0.784687 ,-0.619892}; +static float N062[3] = {0.000000 ,-1.000000 ,0.000000}; +static float N063[3] = {0.000000 ,1.000000 ,0.000000}; +static float N064[3] = {0.000000 ,1.000000 ,0.000000}; +static float N065[3] = {0.000000 ,1.000000 ,0.000000}; +static float N066[3] = {-0.055784 ,0.257059 ,0.964784}; +static float N069[3] = {-0.000505 ,-0.929775 ,-0.368127}; +static float N070[3] = {0.000000 ,1.000000 ,0.000000}; +static float P002[3] = {0.00, -36.59, 5687.72}; +static float P003[3] = {90.00, 114.73, 724.38}; +static float P004[3] = {58.24, -146.84, 262.35}; +static float P005[3] = {27.81, 231.52, 510.43}; +static float P006[3] = {-27.81, 230.43, 509.76}; +static float P007[3] = {-46.09, -146.83, 265.84}; +static float P008[3] = {-90.00, 103.84, 718.53}; +static float P009[3] = {-131.10, -165.92, 834.85}; +static float P010[3] = {-27.81, -285.31, 500.00}; +static float P011[3] = {27.81, -285.32, 500.00}; +static float P012[3] = {147.96, -170.89, 845.50}; +static float P013[3] = {180.00, 0.00, 2000.00}; +static float P014[3] = {145.62, 352.67, 2000.00}; +static float P015[3] = {55.62, 570.63, 2000.00}; +static float P016[3] = {-55.62, 570.64, 2000.00}; +static float P017[3] = {-145.62, 352.68, 2000.00}; +static float P018[3] = {-180.00, 0.01, 2000.00}; +static float P019[3] = {-178.20, -352.66, 2001.61}; +static float P020[3] = {-55.63, -570.63, 2000.00}; +static float P021[3] = {55.62, -570.64, 2000.00}; +static float P022[3] = {179.91, -352.69, 1998.39}; +static float P023[3] = {150.00, 0.00, 3000.00}; +static float P024[3] = {121.35, 293.89, 3000.00}; +static float P025[3] = {46.35, 502.93, 2883.09}; +static float P026[3] = {-46.35, 497.45, 2877.24}; +static float P027[3] = {-121.35, 293.90, 3000.00}; +static float P028[3] = {-150.00, 0.00, 3000.00}; +static float P029[3] = {-152.21, -304.84, 2858.68}; +static float P030[3] = {-46.36, -475.52, 3000.00}; +static float P031[3] = {46.35, -475.53, 3000.00}; +static float P032[3] = {155.64, -304.87, 2863.50}; +static float P033[3] = {90.00, 0.00, 4000.00}; +static float P034[3] = {72.81, 176.33, 4000.00}; +static float P035[3] = {27.81, 285.32, 4000.00}; +static float P036[3] = {-27.81, 285.32, 4000.00}; +static float P037[3] = {-72.81, 176.34, 4000.00}; +static float P038[3] = {-90.00, 0.00, 4000.00}; +static float P039[3] = {-72.81, -176.33, 4000.00}; +static float P040[3] = {-27.81, -285.31, 4000.00}; +static float P041[3] = {27.81, -285.32, 4000.00}; +static float P042[3] = {72.81, -176.34, 4000.00}; +static float P043[3] = {30.00, 0.00, 5000.00}; +static float P044[3] = {24.27, 58.78, 5000.00}; +static float P045[3] = {9.27, 95.11, 5000.00}; +static float P046[3] = {-9.27, 95.11, 5000.00}; +static float P047[3] = {-24.27, 58.78, 5000.00}; +static float P048[3] = {-30.00, 0.00, 5000.00}; +static float P049[3] = {-24.27, -58.78, 5000.00}; +static float P050[3] = {-9.27, -95.10, 5000.00}; +static float P051[3] = {9.27, -95.11, 5000.00}; +static float P052[3] = {24.27, -58.78, 5000.00}; +static float P058[3] = {0.00, 1212.72, 2703.08}; +static float P059[3] = {50.36, 0.00, 108.14}; +static float P060[3] = {-22.18, 0.00, 108.14}; +static float P061[3] = {0.00, 1181.61, 6344.65}; +static float P062[3] = {516.45, -887.08, 2535.45}; +static float P063[3] = {-545.69, -879.31, 2555.63}; +static float P064[3] = {618.89, -1005.64, 2988.32}; +static float P065[3] = {-635.37, -1014.79, 2938.68}; +static float P066[3] = {0.00, 1374.43, 3064.18}; +static float P069[3] = {0.00, -418.25, 5765.04}; +static float P070[3] = {0.00, 1266.91, 6629.60}; +static float P071[3] = {-139.12, -124.96, 997.98}; +static float P072[3] = {-139.24, -110.18, 1020.68}; +static float P073[3] = {-137.33, -94.52, 1022.63}; +static float P074[3] = {-137.03, -79.91, 996.89}; +static float P075[3] = {-135.21, -91.48, 969.14}; +static float P076[3] = {-135.39, -110.87, 968.76}; +static float P077[3] = {150.23, -78.44, 995.53}; +static float P078[3] = {152.79, -92.76, 1018.46}; +static float P079[3] = {154.19, -110.20, 1020.55}; +static float P080[3] = {151.33, -124.15, 993.77}; +static float P081[3] = {150.49, -111.19, 969.86}; +static float P082[3] = {150.79, -92.41, 969.70}; +static float iP002[3] = {0.00, -36.59, 5687.72}; +static float iP004[3] = {58.24, -146.84, 262.35}; +static float iP007[3] = {-46.09, -146.83, 265.84}; +static float iP010[3] = {-27.81, -285.31, 500.00}; +static float iP011[3] = {27.81, -285.32, 500.00}; +static float iP023[3] = {150.00, 0.00, 3000.00}; +static float iP024[3] = {121.35, 293.89, 3000.00}; +static float iP025[3] = {46.35, 502.93, 2883.09}; +static float iP026[3] = {-46.35, 497.45, 2877.24}; +static float iP027[3] = {-121.35, 293.90, 3000.00}; +static float iP028[3] = {-150.00, 0.00, 3000.00}; +static float iP029[3] = {-121.35, -304.84, 2853.86}; +static float iP030[3] = {-46.36, -475.52, 3000.00}; +static float iP031[3] = {46.35, -475.53, 3000.00}; +static float iP032[3] = {121.35, -304.87, 2853.86}; +static float iP033[3] = {90.00, 0.00, 4000.00}; +static float iP034[3] = {72.81, 176.33, 4000.00}; +static float iP035[3] = {27.81, 285.32, 4000.00}; +static float iP036[3] = {-27.81, 285.32, 4000.00}; +static float iP037[3] = {-72.81, 176.34, 4000.00}; +static float iP038[3] = {-90.00, 0.00, 4000.00}; +static float iP039[3] = {-72.81, -176.33, 4000.00}; +static float iP040[3] = {-27.81, -285.31, 4000.00}; +static float iP041[3] = {27.81, -285.32, 4000.00}; +static float iP042[3] = {72.81, -176.34, 4000.00}; +static float iP043[3] = {30.00, 0.00, 5000.00}; +static float iP044[3] = {24.27, 58.78, 5000.00}; +static float iP045[3] = {9.27, 95.11, 5000.00}; +static float iP046[3] = {-9.27, 95.11, 5000.00}; +static float iP047[3] = {-24.27, 58.78, 5000.00}; +static float iP048[3] = {-30.00, 0.00, 5000.00}; +static float iP049[3] = {-24.27, -58.78, 5000.00}; +static float iP050[3] = {-9.27, -95.10, 5000.00}; +static float iP051[3] = {9.27, -95.11, 5000.00}; +static float iP052[3] = {24.27, -58.78, 5000.00}; +static float iP061[3] = {0.00, 1181.61, 6344.65}; +static float iP069[3] = {0.00, -418.25, 5765.04}; +static float iP070[3] = {0.00, 1266.91, 6629.60}; +/* *INDENT-ON* */ + +void +Fish001(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N006); + glVertex3fv(P006); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N016); + glVertex3fv(P016); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N008); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N008); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N017); + glVertex3fv(P017); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N018); + glVertex3fv(P018); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N009); + glVertex3fv(P009); + glNormal3fv(N018); + glVertex3fv(P018); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N009); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N007); + glVertex3fv(P007); + glNormal3fv(N010); + glVertex3fv(P010); + glNormal3fv(N009); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N009); + glVertex3fv(P009); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N018); + glVertex3fv(P018); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N009); + glVertex3fv(P009); + glNormal3fv(N010); + glVertex3fv(P010); + glNormal3fv(N019); + glVertex3fv(P019); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N010); + glVertex3fv(P010); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N019); + glVertex3fv(P019); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N010); + glVertex3fv(P010); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N020); + glVertex3fv(P020); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N004); + glVertex3fv(P004); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N010); + glVertex3fv(P010); + glNormal3fv(N007); + glVertex3fv(P007); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N004); + glVertex3fv(P004); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N011); + glVertex3fv(P011); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N011); + glVertex3fv(P011); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N021); + glVertex3fv(P021); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N015); + glVertex3fv(P015); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N003); + glVertex3fv(P003); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N059); + glVertex3fv(P059); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N003); + glVertex3fv(P003); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N059); + glVertex3fv(P059); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N003); + glVertex3fv(P003); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N012); + glVertex3fv(P012); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P071); + glVertex3fv(P072); + glVertex3fv(P073); + glVertex3fv(P074); + glVertex3fv(P075); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P077); + glVertex3fv(P078); + glVertex3fv(P079); + glVertex3fv(P080); + glVertex3fv(P081); + glVertex3fv(P082); + glEnd(); +} + +void +Fish002(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N023); + glVertex3fv(P023); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N024); + glVertex3fv(P024); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N026); + glVertex3fv(P026); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N027); + glVertex3fv(P027); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N022); + glVertex3fv(P022); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N031); + glVertex3fv(P031); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N021); + glVertex3fv(P021); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N028); + glVertex3fv(P028); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); +} + +void +Fish003(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N042); + glVertex3fv(P042); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N041); + glVertex3fv(P041); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N033); + glVertex3fv(P033); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N034); + glVertex3fv(P034); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N040); + glVertex3fv(P040); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N035); + glVertex3fv(P035); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N036); + glVertex3fv(P036); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N037); + glVertex3fv(P037); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N038); + glVertex3fv(P038); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N039); + glVertex3fv(P039); + glEnd(); +} + +void +Fish004(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N052); + glVertex3fv(P052); + glNormal3fv(N051); + glVertex3fv(P051); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N043); + glVertex3fv(P043); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N046); + glVertex3fv(P046); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N047); + glVertex3fv(P047); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N061); + glVertex3fv(P061); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N061); + glVertex3fv(P061); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N061); + glVertex3fv(P061); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N061); + glVertex3fv(P061); + glNormal3fv(N070); + glVertex3fv(P070); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N061); + glVertex3fv(P061); + glEnd(); +} + +void +Fish005(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N052); + glVertex3fv(P052); + glNormal3fv(N043); + glVertex3fv(P043); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N047); + glVertex3fv(P047); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N069); + glVertex3fv(P069); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N069); + glVertex3fv(P069); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); +} + +void +Fish006(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N026); + glVertex3fv(P026); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N025); + glVertex3fv(P025); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N026); + glVertex3fv(P026); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N016); + glVertex3fv(P016); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N066); + glVertex3fv(P066); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N016); + glVertex3fv(P016); + glEnd(); +} + +void +Fish007(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N064); + glVertex3fv(P064); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N064); + glVertex3fv(P064); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); +} + +void +Fish008(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N065); + glVertex3fv(P065); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); +} + +void +Fish009(void) +{ + glBegin(GL_POLYGON); + glVertex3fv(P059); + glVertex3fv(P012); + glVertex3fv(P009); + glVertex3fv(P060); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P012); + glVertex3fv(P004); + glVertex3fv(P007); + glVertex3fv(P009); + glEnd(); +} + +void +Fish_1(void) +{ + Fish004(); + Fish005(); + Fish003(); + Fish007(); + Fish006(); + Fish002(); + Fish008(); + Fish009(); + Fish001(); +} + +void +Fish_2(void) +{ + Fish005(); + Fish004(); + Fish003(); + Fish008(); + Fish006(); + Fish002(); + Fish007(); + Fish009(); + Fish001(); +} + +void +Fish_3(void) +{ + Fish005(); + Fish004(); + Fish007(); + Fish003(); + Fish002(); + Fish008(); + Fish009(); + Fish001(); + Fish006(); +} + +void +Fish_4(void) +{ + Fish005(); + Fish004(); + Fish008(); + Fish003(); + Fish002(); + Fish007(); + Fish009(); + Fish001(); + Fish006(); +} + +void +Fish_5(void) +{ + Fish009(); + Fish006(); + Fish007(); + Fish001(); + Fish002(); + Fish003(); + Fish008(); + Fish004(); + Fish005(); +} + +void +Fish_6(void) +{ + Fish009(); + Fish006(); + Fish008(); + Fish001(); + Fish002(); + Fish007(); + Fish003(); + Fish004(); + Fish005(); +} + +void +Fish_7(void) +{ + Fish009(); + Fish001(); + Fish007(); + Fish005(); + Fish002(); + Fish008(); + Fish003(); + Fish004(); + Fish006(); +} + +void +Fish_8(void) +{ + Fish009(); + Fish008(); + Fish001(); + Fish002(); + Fish007(); + Fish003(); + Fish005(); + Fish004(); + Fish006(); +} + +void +DrawShark(fishRec * fish) +{ + float mat[4][4]; + int n; + float seg1, seg2, seg3, seg4, segup; + float thrash, chomp; + + fish->htail = (int) (fish->htail - (int) (5.0 * fish->v)) % 360; + + thrash = 50.0 * fish->v; + + seg1 = 0.6 * thrash * sin(fish->htail * RRAD); + seg2 = 1.8 * thrash * sin((fish->htail + 45.0) * RRAD); + seg3 = 3.0 * thrash * sin((fish->htail + 90.0) * RRAD); + seg4 = 4.0 * thrash * sin((fish->htail + 110.0) * RRAD); + + chomp = 0.0; + if (fish->v > 2.0) { + chomp = -(fish->v - 2.0) * 200.0; + } + P004[1] = iP004[1] + chomp; + P007[1] = iP007[1] + chomp; + P010[1] = iP010[1] + chomp; + P011[1] = iP011[1] + chomp; + + P023[0] = iP023[0] + seg1; + P024[0] = iP024[0] + seg1; + P025[0] = iP025[0] + seg1; + P026[0] = iP026[0] + seg1; + P027[0] = iP027[0] + seg1; + P028[0] = iP028[0] + seg1; + P029[0] = iP029[0] + seg1; + P030[0] = iP030[0] + seg1; + P031[0] = iP031[0] + seg1; + P032[0] = iP032[0] + seg1; + P033[0] = iP033[0] + seg2; + P034[0] = iP034[0] + seg2; + P035[0] = iP035[0] + seg2; + P036[0] = iP036[0] + seg2; + P037[0] = iP037[0] + seg2; + P038[0] = iP038[0] + seg2; + P039[0] = iP039[0] + seg2; + P040[0] = iP040[0] + seg2; + P041[0] = iP041[0] + seg2; + P042[0] = iP042[0] + seg2; + P043[0] = iP043[0] + seg3; + P044[0] = iP044[0] + seg3; + P045[0] = iP045[0] + seg3; + P046[0] = iP046[0] + seg3; + P047[0] = iP047[0] + seg3; + P048[0] = iP048[0] + seg3; + P049[0] = iP049[0] + seg3; + P050[0] = iP050[0] + seg3; + P051[0] = iP051[0] + seg3; + P052[0] = iP052[0] + seg3; + P002[0] = iP002[0] + seg4; + P061[0] = iP061[0] + seg4; + P069[0] = iP069[0] + seg4; + P070[0] = iP070[0] + seg4; + + fish->vtail += ((fish->dtheta - fish->vtail) * 0.1); + + if (fish->vtail > 0.5) { + fish->vtail = 0.5; + } else if (fish->vtail < -0.5) { + fish->vtail = -0.5; + } + segup = thrash * fish->vtail; + + P023[1] = iP023[1] + segup; + P024[1] = iP024[1] + segup; + P025[1] = iP025[1] + segup; + P026[1] = iP026[1] + segup; + P027[1] = iP027[1] + segup; + P028[1] = iP028[1] + segup; + P029[1] = iP029[1] + segup; + P030[1] = iP030[1] + segup; + P031[1] = iP031[1] + segup; + P032[1] = iP032[1] + segup; + P033[1] = iP033[1] + segup * 5.0; + P034[1] = iP034[1] + segup * 5.0; + P035[1] = iP035[1] + segup * 5.0; + P036[1] = iP036[1] + segup * 5.0; + P037[1] = iP037[1] + segup * 5.0; + P038[1] = iP038[1] + segup * 5.0; + P039[1] = iP039[1] + segup * 5.0; + P040[1] = iP040[1] + segup * 5.0; + P041[1] = iP041[1] + segup * 5.0; + P042[1] = iP042[1] + segup * 5.0; + P043[1] = iP043[1] + segup * 12.0; + P044[1] = iP044[1] + segup * 12.0; + P045[1] = iP045[1] + segup * 12.0; + P046[1] = iP046[1] + segup * 12.0; + P047[1] = iP047[1] + segup * 12.0; + P048[1] = iP048[1] + segup * 12.0; + P049[1] = iP049[1] + segup * 12.0; + P050[1] = iP050[1] + segup * 12.0; + P051[1] = iP051[1] + segup * 12.0; + P052[1] = iP052[1] + segup * 12.0; + P002[1] = iP002[1] + segup * 17.0; + P061[1] = iP061[1] + segup * 17.0; + P069[1] = iP069[1] + segup * 17.0; + P070[1] = iP070[1] + segup * 17.0; + + glPushMatrix(); + + glTranslatef(0.0, 0.0, -3000.0); + + glGetFloatv(GL_MODELVIEW_MATRIX, &mat[0][0]); + n = 0; + if (mat[0][2] >= 0.0) { + n += 1; + } + if (mat[1][2] >= 0.0) { + n += 2; + } + if (mat[2][2] >= 0.0) { + n += 4; + } + glScalef(2.0, 1.0, 1.0); + + glEnable(GL_CULL_FACE); + switch (n) { + case 0: + Fish_1(); + break; + case 1: + Fish_2(); + break; + case 2: + Fish_3(); + break; + case 3: + Fish_4(); + break; + case 4: + Fish_5(); + break; + case 5: + Fish_6(); + break; + case 6: + Fish_7(); + break; + case 7: + Fish_8(); + break; + } + glDisable(GL_CULL_FACE); + + glPopMatrix(); +} diff --git a/lib/glut-3.7.6/progs/demos/atlantis/swim.c b/lib/glut-3.7.6/progs/demos/atlantis/swim.c new file mode 100644 index 0000000000..021bb0a671 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/swim.c @@ -0,0 +1,188 @@ +/** + * (c) Copyright 1993, 1994, 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. + */ +#include +#include /* For rand(). */ +#include +#include "atlantis.h" + +void +FishTransform(fishRec * fish) +{ + + glTranslatef(fish->y, fish->z, -fish->x); + glRotatef(-fish->psi, 0.0, 1.0, 0.0); + glRotatef(fish->theta, 1.0, 0.0, 0.0); + glRotatef(-fish->phi, 0.0, 0.0, 1.0); +} + +void +WhalePilot(fishRec * fish) +{ + + fish->phi = -20.0; + fish->theta = 0.0; + fish->psi -= 0.5; + + fish->x += WHALESPEED * fish->v * cos(fish->psi / RAD) * cos(fish->theta / RAD); + fish->y += WHALESPEED * fish->v * sin(fish->psi / RAD) * cos(fish->theta / RAD); + fish->z += WHALESPEED * fish->v * sin(fish->theta / RAD); +} + +void +SharkPilot(fishRec * fish) +{ + static int sign = 1; + float X, Y, Z, tpsi, ttheta, thetal; + + fish->xt = 60000.0; + fish->yt = 0.0; + fish->zt = 0.0; + + X = fish->xt - fish->x; + Y = fish->yt - fish->y; + Z = fish->zt - fish->z; + + thetal = fish->theta; + + ttheta = RAD * atan(Z / (sqrt(X * X + Y * Y))); + + if (ttheta > fish->theta + 0.25) { + fish->theta += 0.5; + } else if (ttheta < fish->theta - 0.25) { + fish->theta -= 0.5; + } + if (fish->theta > 90.0) { + fish->theta = 90.0; + } + if (fish->theta < -90.0) { + fish->theta = -90.0; + } + fish->dtheta = fish->theta - thetal; + + tpsi = RAD * atan2(Y, X); + + fish->attack = 0; + + if (fabs(tpsi - fish->psi) < 10.0) { + fish->attack = 1; + } else if (fabs(tpsi - fish->psi) < 45.0) { + if (fish->psi > tpsi) { + fish->psi -= 0.5; + if (fish->psi < -180.0) { + fish->psi += 360.0; + } + } else if (fish->psi < tpsi) { + fish->psi += 0.5; + if (fish->psi > 180.0) { + fish->psi -= 360.0; + } + } + } else { + if (rand() % 100 > 98) { + sign = 1 - sign; + } + fish->psi += sign; + if (fish->psi > 180.0) { + fish->psi -= 360.0; + } + if (fish->psi < -180.0) { + fish->psi += 360.0; + } + } + + if (fish->attack) { + if (fish->v < 1.1) { + fish->spurt = 1; + } + if (fish->spurt) { + fish->v += 0.2; + } + if (fish->v > 5.0) { + fish->spurt = 0; + } + if ((fish->v > 1.0) && (!fish->spurt)) { + fish->v -= 0.2; + } + } else { + if (!(rand() % 400) && (!fish->spurt)) { + fish->spurt = 1; + } + if (fish->spurt) { + fish->v += 0.05; + } + if (fish->v > 3.0) { + fish->spurt = 0; + } + if ((fish->v > 1.0) && (!fish->spurt)) { + fish->v -= 0.05; + } + } + + fish->x += SHARKSPEED * fish->v * cos(fish->psi / RAD) * cos(fish->theta / RAD); + fish->y += SHARKSPEED * fish->v * sin(fish->psi / RAD) * cos(fish->theta / RAD); + fish->z += SHARKSPEED * fish->v * sin(fish->theta / RAD); +} + +void +SharkMiss(int i) +{ + int j; + float avoid, thetal; + float X, Y, Z, R; + + for (j = 0; j < NUM_SHARKS; j++) { + if (j != i) { + X = sharks[j].x - sharks[i].x; + Y = sharks[j].y - sharks[i].y; + Z = sharks[j].z - sharks[i].z; + + R = sqrt(X * X + Y * Y + Z * Z); + + avoid = 1.0; + thetal = sharks[i].theta; + + if (R < SHARKSIZE) { + if (Z > 0.0) { + sharks[i].theta -= avoid; + } else { + sharks[i].theta += avoid; + } + } + sharks[i].dtheta += (sharks[i].theta - thetal); + } + } +} diff --git a/lib/glut-3.7.6/progs/demos/atlantis/whale.c b/lib/glut-3.7.6/progs/demos/atlantis/whale.c new file mode 100644 index 0000000000..b53e286c29 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/atlantis/whale.c @@ -0,0 +1,1798 @@ +/** + * (c) Copyright 1993, 1994, 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. + */ +#include +#include +#include "atlantis.h" +/* *INDENT-OFF* */ +static float N001[3] = {0.019249 ,0.011340 ,-0.999750}; +static float N002[3] = {-0.132579 ,0.954547 ,0.266952}; +static float N003[3] = {-0.196061 ,0.980392 ,-0.019778}; +static float N004[3] = {0.695461 ,0.604704 ,0.388158}; +static float N005[3] = {0.870600 ,0.425754 ,0.246557}; +static float N006[3] = {-0.881191 ,0.392012 ,0.264251}; +static float N008[3] = {-0.341437 ,0.887477 ,0.309523}; +static float N009[3] = {0.124035 ,-0.992278 ,0.000000}; +static float N010[3] = {0.242536 ,0.000000 ,-0.970143}; +static float N011[3] = {0.588172 ,0.000000 ,0.808736}; +static float N012[3] = {0.929824 ,-0.340623 ,-0.139298}; +static float N013[3] = {0.954183 ,0.267108 ,-0.134865}; +static float N014[3] = {0.495127 ,0.855436 ,-0.151914}; +static float N015[3] = {-0.390199 ,0.906569 ,-0.160867}; +static float N016[3] = {-0.923605 ,0.354581 ,-0.145692}; +static float N017[3] = {-0.955796 ,-0.260667 ,-0.136036}; +static float N018[3] = {-0.501283 ,-0.853462 ,-0.142540}; +static float N019[3] = {0.405300 ,-0.901974 ,-0.148913}; +static float N020[3] = {0.909913 ,-0.392746 ,-0.133451}; +static float N021[3] = {0.936494 ,0.331147 ,-0.115414}; +static float N022[3] = {0.600131 ,0.793724 ,-0.099222}; +static float N023[3] = {-0.231556 ,0.968361 ,-0.093053}; +static float N024[3] = {-0.844369 ,0.525330 ,-0.105211}; +static float N025[3] = {-0.982725 ,-0.136329 ,-0.125164}; +static float N026[3] = {-0.560844 ,-0.822654 ,-0.093241}; +static float N027[3] = {0.263884 ,-0.959981 ,-0.093817}; +static float N028[3] = {0.842057 ,-0.525192 ,-0.122938}; +static float N029[3] = {0.921620 ,0.367565 ,-0.124546}; +static float N030[3] = {0.613927 ,0.784109 ,-0.090918}; +static float N031[3] = {-0.448754 ,0.888261 ,-0.098037}; +static float N032[3] = {-0.891865 ,0.434376 ,-0.126077}; +static float N033[3] = {-0.881447 ,-0.448017 ,-0.149437}; +static float N034[3] = {-0.345647 ,-0.922057 ,-0.174183}; +static float N035[3] = {0.307998 ,-0.941371 ,-0.137688}; +static float N036[3] = {0.806316 ,-0.574647 ,-0.140124}; +static float N037[3] = {0.961346 ,0.233646 ,-0.145681}; +static float N038[3] = {0.488451 ,0.865586 ,-0.110351}; +static float N039[3] = {-0.374290 ,0.921953 ,-0.099553}; +static float N040[3] = {-0.928504 ,0.344533 ,-0.138485}; +static float N041[3] = {-0.918419 ,-0.371792 ,-0.135189}; +static float N042[3] = {-0.520666 ,-0.833704 ,-0.183968}; +static float N043[3] = {0.339204 ,-0.920273 ,-0.195036}; +static float N044[3] = {0.921475 ,-0.387382 ,-0.028636}; +static float N045[3] = {0.842465 ,0.533335 ,-0.076204}; +static float N046[3] = {0.380110 ,0.924939 ,0.002073}; +static float N047[3] = {-0.276128 ,0.961073 ,-0.009579}; +static float N048[3] = {-0.879684 ,0.473001 ,-0.049250}; +static float N049[3] = {-0.947184 ,-0.317614 ,-0.044321}; +static float N050[3] = {-0.642059 ,-0.764933 ,-0.051363}; +static float N051[3] = {0.466794 ,-0.880921 ,-0.077990}; +static float N052[3] = {0.898509 ,-0.432277 ,0.076279}; +static float N053[3] = {0.938985 ,0.328141 ,0.103109}; +static float N054[3] = {0.442420 ,0.895745 ,0.043647}; +static float N055[3] = {-0.255163 ,0.966723 ,0.018407}; +static float N056[3] = {-0.833769 ,0.540650 ,0.111924}; +static float N057[3] = {-0.953653 ,-0.289939 ,0.080507}; +static float N058[3] = {-0.672357 ,-0.730524 ,0.119461}; +static float N059[3] = {0.522249 ,-0.846652 ,0.102157}; +static float N060[3] = {0.885868 ,-0.427631 ,0.179914}; +static float N062[3] = {0.648942 ,0.743116 ,0.163255}; +static float N063[3] = {-0.578967 ,0.807730 ,0.111219}; +static float N065[3] = {-0.909864 ,-0.352202 ,0.219321}; +static float N066[3] = {-0.502541 ,-0.818090 ,0.279610}; +static float N067[3] = {0.322919 ,-0.915358 ,0.240504}; +static float N068[3] = {0.242536 ,0.000000 ,-0.970143}; +static float N069[3] = {0.000000 ,1.000000 ,0.000000}; +static float N070[3] = {0.000000 ,1.000000 ,0.000000}; +static float N071[3] = {0.000000 ,1.000000 ,0.000000}; +static float N072[3] = {0.000000 ,1.000000 ,0.000000}; +static float N073[3] = {0.000000 ,1.000000 ,0.000000}; +static float N074[3] = {0.000000 ,1.000000 ,0.000000}; +static float N075[3] = {0.031220 ,0.999025 ,-0.031220}; +static float N076[3] = {0.000000 ,1.000000 ,0.000000}; +static float N077[3] = {0.446821 ,0.893642 ,0.041889}; +static float N078[3] = {0.863035 ,-0.100980 ,0.494949}; +static float N079[3] = {0.585597 ,-0.808215 ,0.062174}; +static float N080[3] = {0.000000 ,1.000000 ,0.000000}; +static float N081[3] = {1.000000 ,0.000000 ,0.000000}; +static float N082[3] = {0.000000 ,1.000000 ,0.000000}; +static float N083[3] = {-1.000000 ,0.000000 ,0.000000}; +static float N084[3] = {-0.478893 ,0.837129 ,-0.264343}; +static float N085[3] = {0.000000 ,1.000000 ,0.000000}; +static float N086[3] = {0.763909 ,0.539455 ,-0.354163}; +static float N087[3] = {0.446821 ,0.893642 ,0.041889}; +static float N088[3] = {0.385134 ,-0.908288 ,0.163352}; +static float N089[3] = {-0.605952 ,0.779253 ,-0.159961}; +static float N090[3] = {0.000000 ,1.000000 ,0.000000}; +static float N091[3] = {0.000000 ,1.000000 ,0.000000}; +static float N092[3] = {0.000000 ,1.000000 ,0.000000}; +static float N093[3] = {0.000000 ,1.000000 ,0.000000}; +static float N094[3] = {1.000000 ,0.000000 ,0.000000}; +static float N095[3] = {-1.000000 ,0.000000 ,0.000000}; +static float N096[3] = {0.644444 ,-0.621516 ,0.445433}; +static float N097[3] = {-0.760896 ,-0.474416 ,0.442681}; +static float N098[3] = {0.636888 ,-0.464314 ,0.615456}; +static float N099[3] = {-0.710295 ,0.647038 ,0.277168}; +static float N100[3] = {0.009604 ,0.993655 ,0.112063}; +static float iP001[3] = {18.74, 13.19, 3.76}; +static float P001[3] = {18.74, 13.19, 3.76}; +static float P002[3] = {0.00, 390.42, 10292.57}; +static float P003[3] = {55.80, 622.31, 8254.35}; +static float P004[3] = {20.80, 247.66, 10652.13}; +static float P005[3] = {487.51, 198.05, 9350.78}; +static float P006[3] = {-457.61, 199.04, 9353.01}; +static float P008[3] = {-34.67, 247.64, 10663.71}; +static float iP009[3] = {97.46, 67.63, 593.82}; +static float iP010[3] = {-84.33, 67.63, 588.18}; +static float iP011[3] = {118.69, 8.98, -66.91}; +static float P009[3] = {97.46, 67.63, 593.82}; +static float P010[3] = {-84.33, 67.63, 588.18}; +static float P011[3] = {118.69, 8.98, -66.91}; +static float iP012[3] = {156.48, -31.95, 924.54}; +static float iP013[3] = {162.00, 110.22, 924.54}; +static float iP014[3] = {88.16, 221.65, 924.54}; +static float iP015[3] = {-65.21, 231.16, 924.54}; +static float iP016[3] = {-156.48, 121.97, 924.54}; +static float iP017[3] = {-162.00, -23.93, 924.54}; +static float iP018[3] = {-88.16, -139.10, 924.54}; +static float iP019[3] = {65.21, -148.61, 924.54}; +static float iP020[3] = {246.87, -98.73, 1783.04}; +static float iP021[3] = {253.17, 127.76, 1783.04}; +static float iP022[3] = {132.34, 270.77, 1783.04}; +static float iP023[3] = {-97.88, 285.04, 1783.04}; +static float iP024[3] = {-222.97, 139.80, 1783.04}; +static float iP025[3] = {-225.29, -86.68, 1783.04}; +static float iP026[3] = {-108.44, -224.15, 1783.04}; +static float iP027[3] = {97.88, -221.56, 1783.04}; +static float iP028[3] = {410.55, -200.66, 3213.87}; +static float iP029[3] = {432.19, 148.42, 3213.87}; +static float iP030[3] = {200.66, 410.55, 3213.87}; +static float iP031[3] = {-148.42, 432.19, 3213.87}; +static float iP032[3] = {-407.48, 171.88, 3213.87}; +static float iP033[3] = {-432.19, -148.42, 3213.87}; +static float iP034[3] = {-148.88, -309.74, 3213.87}; +static float iP035[3] = {156.38, -320.17, 3213.87}; +static float iP036[3] = {523.39, -303.81, 4424.57}; +static float iP037[3] = {574.66, 276.84, 4424.57}; +static float iP038[3] = {243.05, 492.50, 4424.57}; +static float iP039[3] = {-191.23, 520.13, 4424.57}; +static float iP040[3] = {-523.39, 304.01, 4424.57}; +static float iP041[3] = {-574.66, -231.83, 4424.57}; +static float iP042[3] = {-266.95, -578.17, 4424.57}; +static float iP043[3] = {211.14, -579.67, 4424.57}; +static float iP044[3] = {680.57, -370.27, 5943.46}; +static float iP045[3] = {834.01, 363.09, 5943.46}; +static float iP046[3] = {371.29, 614.13, 5943.46}; +static float iP047[3] = {-291.43, 621.86, 5943.46}; +static float iP048[3] = {-784.13, 362.60, 5943.46}; +static float iP049[3] = {-743.29, -325.82, 5943.46}; +static float iP050[3] = {-383.24, -804.77, 5943.46}; +static float iP051[3] = {283.47, -846.09, 5943.46}; +static float P012[3] = {156.48, -31.95, 924.54}; +static float P013[3] = {162.00, 110.22, 924.54}; +static float P014[3] = {88.16, 221.65, 924.54}; +static float P015[3] = {-65.21, 231.16, 924.54}; +static float P016[3] = {-156.48, 121.97, 924.54}; +static float P017[3] = {-162.00, -23.93, 924.54}; +static float P018[3] = {-88.16, -139.10, 924.54}; +static float P019[3] = {65.21, -148.61, 924.54}; +static float P020[3] = {246.87, -98.73, 1783.04}; +static float P021[3] = {253.17, 127.76, 1783.04}; +static float P022[3] = {132.34, 270.77, 1783.04}; +static float P023[3] = {-97.88, 285.04, 1783.04}; +static float P024[3] = {-222.97, 139.80, 1783.04}; +static float P025[3] = {-225.29, -86.68, 1783.04}; +static float P026[3] = {-108.44, -224.15, 1783.04}; +static float P027[3] = {97.88, -221.56, 1783.04}; +static float P028[3] = {410.55, -200.66, 3213.87}; +static float P029[3] = {432.19, 148.42, 3213.87}; +static float P030[3] = {200.66, 410.55, 3213.87}; +static float P031[3] = {-148.42, 432.19, 3213.87}; +static float P032[3] = {-407.48, 171.88, 3213.87}; +static float P033[3] = {-432.19, -148.42, 3213.87}; +static float P034[3] = {-148.88, -309.74, 3213.87}; +static float P035[3] = {156.38, -320.17, 3213.87}; +static float P036[3] = {523.39, -303.81, 4424.57}; +static float P037[3] = {574.66, 276.84, 4424.57}; +static float P038[3] = {243.05, 492.50, 4424.57}; +static float P039[3] = {-191.23, 520.13, 4424.57}; +static float P040[3] = {-523.39, 304.01, 4424.57}; +static float P041[3] = {-574.66, -231.83, 4424.57}; +static float P042[3] = {-266.95, -578.17, 4424.57}; +static float P043[3] = {211.14, -579.67, 4424.57}; +static float P044[3] = {680.57, -370.27, 5943.46}; +static float P045[3] = {834.01, 363.09, 5943.46}; +static float P046[3] = {371.29, 614.13, 5943.46}; +static float P047[3] = {-291.43, 621.86, 5943.46}; +static float P048[3] = {-784.13, 362.60, 5943.46}; +static float P049[3] = {-743.29, -325.82, 5943.46}; +static float P050[3] = {-383.24, -804.77, 5943.46}; +static float P051[3] = {283.47, -846.09, 5943.46}; +static float P052[3] = {599.09, -332.24, 7902.59}; +static float P053[3] = {735.48, 306.26, 7911.92}; +static float P054[3] = {321.55, 558.53, 7902.59}; +static float P055[3] = {-260.54, 559.84, 7902.59}; +static float P056[3] = {-698.66, 320.83, 7902.59}; +static float P057[3] = {-643.29, -299.16, 7902.59}; +static float P058[3] = {-341.47, -719.30, 7902.59}; +static float P059[3] = {252.57, -756.12, 7902.59}; +static float P060[3] = {458.39, -265.31, 9355.44}; +static float P062[3] = {224.04, 438.98, 9364.77}; +static float P063[3] = {-165.71, 441.27, 9355.44}; +static float P065[3] = {-473.99, -219.71, 9355.44}; +static float P066[3] = {-211.97, -479.87, 9355.44}; +static float P067[3] = {192.86, -504.03, 9355.44}; +static float iP068[3] = {-112.44, 9.25, -64.42}; +static float iP069[3] = {1155.63, 0.00, -182.46}; +static float iP070[3] = {-1143.13, 0.00, -181.54}; +static float iP071[3] = {1424.23, 0.00, -322.09}; +static float iP072[3] = {-1368.01, 0.00, -310.38}; +static float iP073[3] = {1255.57, 2.31, 114.05}; +static float iP074[3] = {-1149.38, 0.00, 117.12}; +static float iP075[3] = {718.36, 0.00, 433.36}; +static float iP076[3] = {-655.90, 0.00, 433.36}; +static float P068[3] = {-112.44, 9.25, -64.42}; +static float P069[3] = {1155.63, 0.00, -182.46}; +static float P070[3] = {-1143.13, 0.00, -181.54}; +static float P071[3] = {1424.23, 0.00, -322.09}; +static float P072[3] = {-1368.01, 0.00, -310.38}; +static float P073[3] = {1255.57, 2.31, 114.05}; +static float P074[3] = {-1149.38, 0.00, 117.12}; +static float P075[3] = {718.36, 0.00, 433.36}; +static float P076[3] = {-655.90, 0.00, 433.36}; +static float P077[3] = {1058.00, -2.66, 7923.51}; +static float P078[3] = {-1016.51, -15.47, 7902.87}; +static float P079[3] = {-1363.99, -484.50, 7593.38}; +static float P080[3] = {1478.09, -861.47, 7098.12}; +static float P081[3] = {1338.06, -284.68, 7024.15}; +static float P082[3] = {-1545.51, -860.64, 7106.60}; +static float P083[3] = {1063.19, -70.46, 7466.60}; +static float P084[3] = {-1369.18, -288.11, 7015.34}; +static float P085[3] = {1348.44, -482.50, 7591.41}; +static float P086[3] = {-1015.45, -96.80, 7474.86}; +static float P087[3] = {731.04, 148.38, 7682.58}; +static float P088[3] = {-697.03, 151.82, 7668.81}; +static float P089[3] = {-686.82, 157.09, 7922.29}; +static float P090[3] = {724.73, 147.75, 7931.39}; +static float iP091[3] = {0.00, 327.10, 2346.55}; +static float iP092[3] = {0.00, 552.28, 2311.31}; +static float iP093[3] = {0.00, 721.16, 2166.41}; +static float iP094[3] = {0.00, 693.42, 2388.80}; +static float iP095[3] = {0.00, 389.44, 2859.97}; +static float P091[3] = {0.00, 327.10, 2346.55}; +static float P092[3] = {0.00, 552.28, 2311.31}; +static float P093[3] = {0.00, 721.16, 2166.41}; +static float P094[3] = {0.00, 693.42, 2388.80}; +static float P095[3] = {0.00, 389.44, 2859.97}; +static float iP096[3] = {222.02, -183.67, 10266.89}; +static float iP097[3] = {-128.90, -182.70, 10266.89}; +static float iP098[3] = {41.04, 88.31, 10659.36}; +static float iP099[3] = {-48.73, 88.30, 10659.36}; +static float P096[3] = {222.02, -183.67, 10266.89}; +static float P097[3] = {-128.90, -182.70, 10266.89}; +static float P098[3] = {41.04, 88.31, 10659.36}; +static float P099[3] = {-48.73, 88.30, 10659.36}; +static float P100[3] = {0.00, 603.42, 9340.68}; +static float P104[3] = {-9.86, 567.62, 7858.65}; +static float P105[3] = {31.96, 565.27, 7908.46}; +static float P106[3] = {22.75, 568.13, 7782.83}; +static float P107[3] = {58.93, 568.42, 7775.94}; +static float P108[3] = {55.91, 565.59, 7905.86}; +static float P109[3] = {99.21, 566.00, 7858.65}; +static float P110[3] = {-498.83, 148.14, 9135.10}; +static float P111[3] = {-495.46, 133.24, 9158.48}; +static float P112[3] = {-490.82, 146.23, 9182.76}; +static float P113[3] = {-489.55, 174.11, 9183.66}; +static float P114[3] = {-492.92, 189.00, 9160.28}; +static float P115[3] = {-497.56, 176.02, 9136.00}; +static float P116[3] = {526.54, 169.68, 9137.70}; +static float P117[3] = {523.49, 184.85, 9161.42}; +static float P118[3] = {518.56, 171.78, 9186.06}; +static float P119[3] = {516.68, 143.53, 9186.98}; +static float P120[3] = {519.73, 128.36, 9163.26}; +static float P121[3] = {524.66, 141.43, 9138.62}; +/* *INDENT-ON* */ + +void +Whale001(void) +{ + + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N010); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N076); + glVertex3fv(P076); + glNormal3fv(N010); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N076); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N076); + glVertex3fv(P076); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N074); + glVertex3fv(P074); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N072); + glVertex3fv(P072); + glNormal3fv(N074); + glVertex3fv(P074); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N072); + glVertex3fv(P072); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N074); + glVertex3fv(P074); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N074); + glVertex3fv(P074); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N076); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N070); + glVertex3fv(P070); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N076); + glVertex3fv(P076); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N076); + glVertex3fv(P076); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N010); + glVertex3fv(P010); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N068); + glVertex3fv(P068); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N010); + glVertex3fv(P010); + glEnd(); +} + +void +Whale002(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N009); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N075); + glVertex3fv(P075); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N009); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N075); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N075); + glVertex3fv(P075); + glNormal3fv(N073); + glVertex3fv(P073); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N071); + glVertex3fv(P071); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N073); + glVertex3fv(P073); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N009); + glVertex3fv(P009); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N009); + glVertex3fv(P009); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N075); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N011); + glVertex3fv(P011); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N075); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N073); + glVertex3fv(P073); + glNormal3fv(N075); + glVertex3fv(P075); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N069); + glVertex3fv(P069); + glNormal3fv(N071); + glVertex3fv(P071); + glNormal3fv(N073); + glVertex3fv(P073); + glEnd(); +} + +void +Whale003(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N019); + glVertex3fv(P019); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N012); + glVertex3fv(P012); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N018); + glVertex3fv(P018); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N016); + glVertex3fv(P016); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N012); + glVertex3fv(P012); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N015); + glVertex3fv(P015); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N013); + glVertex3fv(P013); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N001); + glVertex3fv(P001); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N014); + glVertex3fv(P014); + glEnd(); +} + +void +Whale004(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N022); + glVertex3fv(P022); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N015); + glVertex3fv(P015); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N023); + glVertex3fv(P023); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N016); + glVertex3fv(P016); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N024); + glVertex3fv(P024); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N017); + glVertex3fv(P017); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N025); + glVertex3fv(P025); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N014); + glVertex3fv(P014); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N021); + glVertex3fv(P021); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N013); + glVertex3fv(P013); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N020); + glVertex3fv(P020); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N018); + glVertex3fv(P018); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N026); + glVertex3fv(P026); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N019); + glVertex3fv(P019); + glNormal3fv(N012); + glVertex3fv(P012); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N027); + glVertex3fv(P027); + glEnd(); +} + +void +Whale005(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N022); + glVertex3fv(P022); + glNormal3fv(N030); + glVertex3fv(P030); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N023); + glVertex3fv(P023); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N031); + glVertex3fv(P031); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N031); + glVertex3fv(P031); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N024); + glVertex3fv(P024); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N032); + glVertex3fv(P032); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N021); + glVertex3fv(P021); + glNormal3fv(N029); + glVertex3fv(P029); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N028); + glVertex3fv(P028); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N020); + glVertex3fv(P020); + glNormal3fv(N028); + glVertex3fv(P028); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N035); + glVertex3fv(P035); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N025); + glVertex3fv(P025); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N033); + glVertex3fv(P033); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N034); + glVertex3fv(P034); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N026); + glVertex3fv(P026); + glNormal3fv(N027); + glVertex3fv(P027); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N034); + glVertex3fv(P034); + glEnd(); +} + +void +Whale006(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N093); + glVertex3fv(P093); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N093); + glVertex3fv(P093); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N091); + glVertex3fv(P091); + glNormal3fv(N095); + glVertex3fv(P095); + glNormal3fv(N094); + glVertex3fv(P094); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N091); + glVertex3fv(P091); + glNormal3fv(N092); + glVertex3fv(P092); + glNormal3fv(N094); + glVertex3fv(P094); + glNormal3fv(N095); + glVertex3fv(P095); + glEnd(); +} + +void +Whale007(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N038); + glVertex3fv(P038); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N030); + glVertex3fv(P030); + glNormal3fv(N038); + glVertex3fv(P038); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N037); + glVertex3fv(P037); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N029); + glVertex3fv(P029); + glNormal3fv(N037); + glVertex3fv(P037); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N036); + glVertex3fv(P036); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N028); + glVertex3fv(P028); + glNormal3fv(N036); + glVertex3fv(P036); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N043); + glVertex3fv(P043); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N035); + glVertex3fv(P035); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N042); + glVertex3fv(P042); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N034); + glVertex3fv(P034); + glNormal3fv(N042); + glVertex3fv(P042); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N041); + glVertex3fv(P041); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N031); + glVertex3fv(P031); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N039); + glVertex3fv(P039); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N040); + glVertex3fv(P040); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N032); + glVertex3fv(P032); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N040); + glVertex3fv(P040); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N033); + glVertex3fv(P033); + glNormal3fv(N041); + glVertex3fv(P041); + glEnd(); +} + +void +Whale008(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N043); + glVertex3fv(P043); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N051); + glVertex3fv(P051); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N042); + glVertex3fv(P042); + glNormal3fv(N050); + glVertex3fv(P050); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N036); + glVertex3fv(P036); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N044); + glVertex3fv(P044); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N041); + glVertex3fv(P041); + glNormal3fv(N049); + glVertex3fv(P049); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N040); + glVertex3fv(P040); + glNormal3fv(N048); + glVertex3fv(P048); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N047); + glVertex3fv(P047); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N037); + glVertex3fv(P037); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N045); + glVertex3fv(P045); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N038); + glVertex3fv(P038); + glNormal3fv(N039); + glVertex3fv(P039); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N046); + glVertex3fv(P046); + glEnd(); +} + +void +Whale009(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N058); + glVertex3fv(P058); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N051); + glVertex3fv(P051); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N059); + glVertex3fv(P059); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N044); + glVertex3fv(P044); + glNormal3fv(N053); + glVertex3fv(P053); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N050); + glVertex3fv(P050); + glNormal3fv(N058); + glVertex3fv(P058); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N049); + glVertex3fv(P049); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N057); + glVertex3fv(P057); + glNormal3fv(N056); + glVertex3fv(P056); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N048); + glVertex3fv(P048); + glNormal3fv(N056); + glVertex3fv(P056); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N055); + glVertex3fv(P055); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N045); + glVertex3fv(P045); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N046); + glVertex3fv(P046); + glNormal3fv(N047); + glVertex3fv(P047); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); +} + +void +Whale010(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N080); + glVertex3fv(P080); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N085); + glVertex3fv(P085); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N077); + glVertex3fv(P077); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N090); + glVertex3fv(P090); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N080); + glVertex3fv(P080); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N081); + glVertex3fv(P081); + glNormal3fv(N085); + glVertex3fv(P085); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N085); + glVertex3fv(P085); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N083); + glVertex3fv(P083); + glNormal3fv(N077); + glVertex3fv(P077); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N087); + glVertex3fv(P087); + glNormal3fv(N077); + glVertex3fv(P077); + glNormal3fv(N090); + glVertex3fv(P090); + glEnd(); +} + +void +Whale011(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N082); + glVertex3fv(P082); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N079); + glVertex3fv(P079); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N078); + glVertex3fv(P078); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N089); + glVertex3fv(P089); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N088); + glVertex3fv(P088); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N089); + glVertex3fv(P089); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N089); + glVertex3fv(P089); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N086); + glVertex3fv(P086); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N078); + glVertex3fv(P078); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N078); + glVertex3fv(P078); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N084); + glVertex3fv(P084); + glNormal3fv(N082); + glVertex3fv(P082); + glNormal3fv(N079); + glVertex3fv(P079); + glEnd(); +} + +void +Whale012(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N066); + glVertex3fv(P066); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N052); + glVertex3fv(P052); + glNormal3fv(N060); + glVertex3fv(P060); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N059); + glVertex3fv(P059); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N067); + glVertex3fv(P067); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N065); + glVertex3fv(P065); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N058); + glVertex3fv(P058); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N057); + glVertex3fv(P057); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N057); + glVertex3fv(P057); + glNormal3fv(N065); + glVertex3fv(P065); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N006); + glVertex3fv(P006); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N063); + glVertex3fv(P063); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N056); + glVertex3fv(P056); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N055); + glVertex3fv(P055); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N005); + glVertex3fv(P005); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N053); + glVertex3fv(P053); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N053); + glVertex3fv(P053); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N060); + glVertex3fv(P060); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N053); + glVertex3fv(P053); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N052); + glVertex3fv(P052); + glEnd(); +} + +void +Whale013(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N096); + glVertex3fv(P096); + glNormal3fv(N097); + glVertex3fv(P097); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N097); + glVertex3fv(P097); + glNormal3fv(N096); + glVertex3fv(P096); + glNormal3fv(N098); + glVertex3fv(P098); + glNormal3fv(N099); + glVertex3fv(P099); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N066); + glVertex3fv(P066); + glNormal3fv(N097); + glVertex3fv(P097); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N067); + glVertex3fv(P067); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N096); + glVertex3fv(P096); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N060); + glVertex3fv(P060); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N096); + glVertex3fv(P096); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N096); + glVertex3fv(P096); + glNormal3fv(N005); + glVertex3fv(P005); + glNormal3fv(N098); + glVertex3fv(P098); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N065); + glVertex3fv(P065); + glNormal3fv(N097); + glVertex3fv(P097); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N097); + glVertex3fv(P097); + glNormal3fv(N099); + glVertex3fv(P099); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P005); + glVertex3fv(P006); + glVertex3fv(P099); + glVertex3fv(P098); + glEnd(); +} + +void +Whale014(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N004); + glVertex3fv(P004); + glNormal3fv(N005); + glVertex3fv(P005); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P006); + glVertex3fv(P005); + glVertex3fv(P004); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N006); + glVertex3fv(P006); + glNormal3fv(N008); + glVertex3fv(P008); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N008); + glVertex3fv(P008); + glNormal3fv(N004); + glVertex3fv(P004); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N062); + glVertex3fv(P062); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N004); + glVertex3fv(P004); + glEnd(); +} + +void +Whale015(void) +{ + glBegin(GL_POLYGON); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N055); + glVertex3fv(P055); + glNormal3fv(N063); + glVertex3fv(P063); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N100); + glVertex3fv(P100); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N003); + glVertex3fv(P003); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N054); + glVertex3fv(P054); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N054); + glVertex3fv(P054); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N062); + glVertex3fv(P062); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N063); + glVertex3fv(P063); + glNormal3fv(N002); + glVertex3fv(P002); + glEnd(); + glBegin(GL_POLYGON); + glNormal3fv(N100); + glVertex3fv(P100); + glNormal3fv(N002); + glVertex3fv(P002); + glNormal3fv(N062); + glVertex3fv(P062); + glEnd(); +} + +void +Whale016(void) +{ + glBegin(GL_POLYGON); + glVertex3fv(P104); + glVertex3fv(P105); + glVertex3fv(P106); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P107); + glVertex3fv(P108); + glVertex3fv(P109); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P110); + glVertex3fv(P111); + glVertex3fv(P112); + glVertex3fv(P113); + glVertex3fv(P114); + glVertex3fv(P115); + glEnd(); + glBegin(GL_POLYGON); + glVertex3fv(P116); + glVertex3fv(P117); + glVertex3fv(P118); + glVertex3fv(P119); + glVertex3fv(P120); + glVertex3fv(P121); + glEnd(); +} + +void +DrawWhale(fishRec * fish) +{ + float seg0, seg1, seg2, seg3, seg4, seg5, seg6, seg7; + float pitch, thrash, chomp; + + fish->htail = (int) (fish->htail - (int) (5.0 * fish->v)) % 360; + + thrash = 70.0 * fish->v; + + seg0 = 1.5 * thrash * sin((fish->htail) * RRAD); + seg1 = 2.5 * thrash * sin((fish->htail + 10.0) * RRAD); + seg2 = 3.7 * thrash * sin((fish->htail + 15.0) * RRAD); + seg3 = 4.8 * thrash * sin((fish->htail + 23.0) * RRAD); + seg4 = 6.0 * thrash * sin((fish->htail + 28.0) * RRAD); + seg5 = 6.5 * thrash * sin((fish->htail + 35.0) * RRAD); + seg6 = 6.5 * thrash * sin((fish->htail + 40.0) * RRAD); + seg7 = 6.5 * thrash * sin((fish->htail + 55.0) * RRAD); + + pitch = fish->v * sin((fish->htail - 160.0) * RRAD); + + chomp = 0.0; + if (fish->v > 2.0) { + chomp = -(fish->v - 2.0) * 200.0; + } + P012[1] = iP012[1] + seg5; + P013[1] = iP013[1] + seg5; + P014[1] = iP014[1] + seg5; + P015[1] = iP015[1] + seg5; + P016[1] = iP016[1] + seg5; + P017[1] = iP017[1] + seg5; + P018[1] = iP018[1] + seg5; + P019[1] = iP019[1] + seg5; + + P020[1] = iP020[1] + seg4; + P021[1] = iP021[1] + seg4; + P022[1] = iP022[1] + seg4; + P023[1] = iP023[1] + seg4; + P024[1] = iP024[1] + seg4; + P025[1] = iP025[1] + seg4; + P026[1] = iP026[1] + seg4; + P027[1] = iP027[1] + seg4; + + P028[1] = iP028[1] + seg2; + P029[1] = iP029[1] + seg2; + P030[1] = iP030[1] + seg2; + P031[1] = iP031[1] + seg2; + P032[1] = iP032[1] + seg2; + P033[1] = iP033[1] + seg2; + P034[1] = iP034[1] + seg2; + P035[1] = iP035[1] + seg2; + + P036[1] = iP036[1] + seg1; + P037[1] = iP037[1] + seg1; + P038[1] = iP038[1] + seg1; + P039[1] = iP039[1] + seg1; + P040[1] = iP040[1] + seg1; + P041[1] = iP041[1] + seg1; + P042[1] = iP042[1] + seg1; + P043[1] = iP043[1] + seg1; + + P044[1] = iP044[1] + seg0; + P045[1] = iP045[1] + seg0; + P046[1] = iP046[1] + seg0; + P047[1] = iP047[1] + seg0; + P048[1] = iP048[1] + seg0; + P049[1] = iP049[1] + seg0; + P050[1] = iP050[1] + seg0; + P051[1] = iP051[1] + seg0; + + P009[1] = iP009[1] + seg6; + P010[1] = iP010[1] + seg6; + P075[1] = iP075[1] + seg6; + P076[1] = iP076[1] + seg6; + + P001[1] = iP001[1] + seg7; + P011[1] = iP011[1] + seg7; + P068[1] = iP068[1] + seg7; + P069[1] = iP069[1] + seg7; + P070[1] = iP070[1] + seg7; + P071[1] = iP071[1] + seg7; + P072[1] = iP072[1] + seg7; + P073[1] = iP073[1] + seg7; + P074[1] = iP074[1] + seg7; + + P091[1] = iP091[1] + seg3 * 1.1; + P092[1] = iP092[1] + seg3; + P093[1] = iP093[1] + seg3; + P094[1] = iP094[1] + seg3; + P095[1] = iP095[1] + seg3 * 0.9; + + P099[1] = iP099[1] + chomp; + P098[1] = iP098[1] + chomp; + P097[1] = iP097[1] + chomp; + P096[1] = iP096[1] + chomp; + + glPushMatrix(); + + glRotatef(pitch, 1.0, 0.0, 0.0); + + glTranslatef(0.0, 0.0, 8000.0); + + glRotatef(180.0, 0.0, 1.0, 0.0); + + glScalef(3.0, 3.0, 3.0); + + glEnable(GL_CULL_FACE); + + Whale001(); + Whale002(); + Whale003(); + Whale004(); + Whale005(); + Whale006(); + Whale007(); + Whale008(); + Whale009(); + Whale010(); + Whale011(); + Whale012(); + Whale013(); + Whale014(); + Whale015(); + Whale016(); + + glDisable(GL_CULL_FACE); + + glPopMatrix(); +} diff --git a/lib/glut-3.7.6/progs/demos/bluepony/Imakefile b/lib/glut-3.7.6/progs/demos/bluepony/Imakefile new file mode 100644 index 0000000000..51c04fa639 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bluepony/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = bluepony + +SRCS = bluepony.c readtex.c + +OBJS = bluepony.o readtex.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(bluepony,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/bluepony/bluepony.c b/lib/glut-3.7.6/progs/demos/bluepony/bluepony.c new file mode 100644 index 0000000000..6c692e8a8e --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bluepony/bluepony.c @@ -0,0 +1,507 @@ +/* pony.c */ + +/* + * By Brian Paul, written July 31, 1997 for Mark. + */ + +#include +#include +#include +#include +#include +#include "readtex.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/************************ Pony-specific code *********************************/ + +static float BodyDepth = 0.216; + +static GLfloat BodyVerts[][2] = +{ + {-0.993334, 0.344444}, + {-0.72, 0.462964}, + {-0.58, -0.411113}, + {-0.406667, -0.692593}, + {0.733334, -0.633334}, + {0.846666, -0.225926}, + {0.873335, -0.55926}, + {0.879998, -0.988888}, + {0.933332, -0.974074}, + {0.953334, -0.537037}, + {0.906667, -0.0777776}, + {0.806666, 0.0333334}, + {-0.26, 0.0111111}, + {-0.406667, 0.27037}, + {-0.54, 0.781481}, + {-0.673333, 1.00371}, + {-0.653332, 0.803704}, + {-1.05333, 0.44815} +}; + +static float LegDepth = 0.144; + +static float FrontLegPos[3] = +{-0.36, -0.324, 0.108}; +static GLfloat FrontLegVerts[][2] = +{ + {-0.23, -0.113481}, + {-0.123333, -0.528296}, + {-0.0926752, -0.728103}, + {-0.0766667, -1.232}, + {0.0233333, -1.232}, + {0.0433332, -0.743111}, + {0.0366667, -0.424593}, + {0.0699998, -0.157926}, + {0.116667, 0.049482}, + {-0.0166667, 0.197629}, + {-0.196667, 0.13837} +}; + +static float BackLegPos[3] = +{0.684, -0.324, 0.108}; +static GLfloat BackLegVerts[][2] = +{ + {-0.24, -0.195556}, + {-0.0933332, -0.41037}, + {-0.04, -0.684445}, + {-0.113333, -1.26222}, + {0, -1.26222}, + {0.1, -0.677037}, + {0.213333, -0.121482}, + {0.153333, 0.108148}, + {-0.0533333, 0.211853}, + {-0.26, 0.063702} +}; + +static float ManeDepth = 0.288; +static GLfloat ManeVerts[][2] = +{ + {-0.512667, 0.578519}, + {-0.419333, 0.267407}, + {-0.299333, -0.00666719}, + {-0.239333, -0.0140724}, + {-0.226, 0.0896296}, + {-0.319333, 0.422963}, + {-0.532667, 0.741481} +}; + +static float EyePos[3] = +{-0.702, 0.648, 0.1116}; +static float EyeSize = 0.025; + +/* Display lists */ +static GLuint Body = 0, FrontLeg = 0, BackLeg = 0, Mane = 0; + +/* Generate an extruded, capped part from a 2-D polyline. */ +static void +ExtrudePart(int n, GLfloat v[][2], float depth) +{ + static GLUtriangulatorObj *tobj = NULL; + int i; + float z0 = 0.5 * depth; + float z1 = -0.5 * depth; + GLdouble vertex[3]; + + if (tobj == NULL) { + tobj = gluNewTess(); /* create and initialize a GLU polygon * * + tesselation object */ + gluTessCallback(tobj, GLU_BEGIN, glBegin); + gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ + gluTessCallback(tobj, GLU_END, glEnd); + } + /* +Z face */ + glPushMatrix(); + glTranslatef(0.0, 0.0, z0); + glNormal3f(0.0, 0.0, 1.0); + gluBeginPolygon(tobj); + for (i = 0; i < n; i++) { + vertex[0] = v[i][0]; + vertex[1] = v[i][1]; + vertex[2] = 0.0; + gluTessVertex(tobj, vertex, v[i]); + } + gluEndPolygon(tobj); + glPopMatrix(); + + /* -Z face */ + glFrontFace(GL_CW); + glPushMatrix(); + glTranslatef(0.0, 0.0, z1); + glNormal3f(0.0, 0.0, -1.0); + gluBeginPolygon(tobj); + for (i = 0; i < n; i++) { + vertex[0] = v[i][0]; + vertex[1] = v[i][1]; + vertex[2] = z1; + gluTessVertex(tobj, vertex, v[i]); + } + gluEndPolygon(tobj); + glPopMatrix(); + + glFrontFace(GL_CCW); + /* edge polygons */ + glBegin(GL_TRIANGLE_STRIP); + for (i = 0; i <= n; i++) { + float x = v[i % n][0]; + float y = v[i % n][1]; + float dx = v[(i + 1) % n][0] - x; + float dy = v[(i + 1) % n][1] - y; + glVertex3f(x, y, z0); + glVertex3f(x, y, z1); + glNormal3f(dy, -dx, 0.0); + } + glEnd(); + +} + +/* + * Build the four display lists which make up the pony. + */ +static void +MakePony(void) +{ + static GLfloat blue[4] = + {0.1, 0.1, 1.0, 1.0}; + static GLfloat black[4] = + {0.0, 0.0, 0.0, 1.0}; + static GLfloat pink[4] = + {1.0, 0.5, 0.5, 1.0}; + + Body = glGenLists(1); + glNewList(Body, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + ExtrudePart(sizeof(BodyVerts) / sizeof(GLfloat) / 2, BodyVerts, BodyDepth); + + /* eyes */ + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, black); + glNormal3f(0.0, 0.0, 1.0); + glBegin(GL_POLYGON); + glVertex3f(EyePos[0] - EyeSize, EyePos[1] - EyeSize, EyePos[2]); + glVertex3f(EyePos[0] + EyeSize, EyePos[1] - EyeSize, EyePos[2]); + glVertex3f(EyePos[0] + EyeSize, EyePos[1] + EyeSize, EyePos[2]); + glVertex3f(EyePos[0] - EyeSize, EyePos[1] + EyeSize, EyePos[2]); + glEnd(); + glNormal3f(0.0, 0.0, -1.0); + glBegin(GL_POLYGON); + glVertex3f(EyePos[0] - EyeSize, EyePos[1] + EyeSize, -EyePos[2]); + glVertex3f(EyePos[0] + EyeSize, EyePos[1] + EyeSize, -EyePos[2]); + glVertex3f(EyePos[0] + EyeSize, EyePos[1] - EyeSize, -EyePos[2]); + glVertex3f(EyePos[0] - EyeSize, EyePos[1] - EyeSize, -EyePos[2]); + glEnd(); + glEndList(); + + Mane = glGenLists(1); + glNewList(Mane, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pink); + ExtrudePart(sizeof(ManeVerts) / sizeof(GLfloat) / 2, ManeVerts, ManeDepth); + glEndList(); + + FrontLeg = glGenLists(1); + glNewList(FrontLeg, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + ExtrudePart(sizeof(FrontLegVerts) / sizeof(GLfloat) / 2, + FrontLegVerts, LegDepth); + glEndList(); + + BackLeg = glGenLists(1); + glNewList(BackLeg, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + ExtrudePart(sizeof(BackLegVerts) / sizeof(GLfloat) / 2, + BackLegVerts, LegDepth); + glEndList(); +} + +/* + * Draw the pony. legAngle should be in [-15,15] or so. + * The pony display lists will be constructed the first time this is called. + */ +static void +DrawPony(float legAngle) +{ + if (!Body) { + MakePony(); + } + assert(Body); + + /* BODY */ + glCallList(Body); + + /* MANE */ + glCallList(Mane); + + /* FRONT +Z LEG */ + glPushMatrix(); + glTranslatef(FrontLegPos[0], FrontLegPos[1], FrontLegPos[2]); + glRotatef(legAngle, 0.0, 0.0, 1.0); + glCallList(FrontLeg); + glPopMatrix(); + + /* FRONT -Z LEG */ + glPushMatrix(); + glTranslatef(FrontLegPos[0], FrontLegPos[1], -FrontLegPos[2]); + glRotatef(-legAngle, 0.0, 0.0, 1.0); + glCallList(FrontLeg); + glPopMatrix(); + + /* BACK +Z LEG */ + glPushMatrix(); + glTranslatef(BackLegPos[0], BackLegPos[1], BackLegPos[2]); + glRotatef(-legAngle, 0.0, 0.0, 1.0); + glCallList(BackLeg); + glPopMatrix(); + + /* BACK -Z LEG */ + glPushMatrix(); + glTranslatef(BackLegPos[0], BackLegPos[1], -BackLegPos[2]); + glRotatef(legAngle, 0.0, 0.0, 1.0); + glCallList(BackLeg); + glPopMatrix(); +} + +/************************* end of pony code **********************************/ + +static float Speed = 2.0; + +static float LegAngleStep = 0.75; +static float LegMaxAngle = 15.0; +static float LegAngle = 0.0, LegDeltaAngle = 0.5; + +static float WalkAngle = -90.0, DeltaWalkAngle = 0.225; +static float WalkRadius = 4.0; + +static float Xrot = 0, Yrot = 30.0; + +static GLboolean AnimFlag = GL_TRUE; + +static void +Idle(void) +{ + /* update animation vars */ + LegAngle += LegDeltaAngle * Speed; + if (LegAngle > LegMaxAngle) { + LegDeltaAngle = -LegAngleStep; + } else if (LegAngle < -LegMaxAngle) { + LegDeltaAngle = LegAngleStep; + } + WalkAngle += DeltaWalkAngle * Speed; + + glutPostRedisplay(); +} + +static void +DrawGround(void) +{ + static GLuint ground = 0; + + if (ground == 0) { + const int rows = 20, columns = 20; + float sizeA = 1.25, sizeB = 0.2; + float x, z; + int i, j; + GLfloat mat[2][4] = + { + {0.0, 0.6, 0.0, 1.0}, + {0.1, 0.8, 0.1, 1.0} + }; + + ground = glGenLists(1); + glNewList(ground, GL_COMPILE); + + glNormal3f(0.0, 1.0, 0.0); + + x = -(columns * (sizeA + sizeB)) / 4; + for (i = 0; i <= rows; i++) { + float size = (i & 1) ? sizeA : sizeB; + z = -(rows * (sizeA + sizeB)) / 4; + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= columns; j++) { + /* glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat[(i+j)%2]); */ + glColor4fv(mat[(i + j) % 2]); + glVertex3f(x + size, 0.0, z); + glVertex3f(x, 0.0, z); + if (j & 1) + z += sizeA; + else + z += sizeB; + } + glEnd(); + x += size; + } + + glEndList(); + } + glCallList(ground); +} + +static void +DrawLogo(void) +{ + glEnable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + glBegin(GL_POLYGON); + glColor3f(1, 0, 0); + glTexCoord2f(0, 0); + glVertex2f(-1.0, -0.5); + glColor3f(0, 1, 0); + glTexCoord2f(1, 0); + glVertex2f(1.0, -0.5); + glColor3f(0, 0, 1); + glTexCoord2f(1, 1); + glVertex2f(1.0, 0.5); + glColor3f(1, 1, 0); + glTexCoord2f(0, 1); + glVertex2f(-1.0, 0.5); + glEnd(); + glDisable(GL_TEXTURE_2D); + glShadeModel(GL_FLAT); +} + +static void +Display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* viewing */ + glPushMatrix(); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + + /* ground */ + glDisable(GL_LIGHTING); + glPushMatrix(); + glTranslatef(0.0, -1.6, 0.0); + DrawGround(); + glPopMatrix(); + + /* logo */ + glPushMatrix(); + glScalef(2.5, 2.5, 2.5); + DrawLogo(); + glPopMatrix(); + + /* pony */ + { + float xPos, zPos; + xPos = WalkRadius * cos(WalkAngle * M_PI / 180.0); + zPos = WalkRadius * sin(WalkAngle * M_PI / 180.0); + glEnable(GL_LIGHTING); + glPushMatrix(); + glTranslatef(xPos, 0.0, zPos); + glRotatef(-WalkAngle + 90.0, 0.0, 1.0, 0.0); + DrawPony(LegAngle); + glPopMatrix(); + } + + glPopMatrix(); + glutSwapBuffers(); +} + +static void +Reshape(int width, int height) +{ + float ar; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + ar = (float) width / (float) height; + glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -23.0 / 2.5); +} + +/* ARGSUSED1 */ +static void +Key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + case ' ': + AnimFlag = !AnimFlag; + if (AnimFlag) { + glutIdleFunc(Idle); + } else { + glutIdleFunc(NULL); + } + break; + } + glutPostRedisplay(); +} + +/* ARGSUSED1 */ +static void +SpecialKey(int key, int x, int y) +{ + float step = 2.0; + 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) +{ + GLfloat lightPos[4] = + {1.0, 10.0, 10.0, 0.0}; + glClearColor(0.5, 0.8, 0.99, 1.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glShadeModel(GL_FLAT); + + LoadRGBMipmaps("logo.bw", 1); +} + +static void +vis(int visible) +{ + if (visible == GLUT_VISIBLE) { + if (AnimFlag) + glutIdleFunc(Idle); + } else { + if (AnimFlag) + glutIdleFunc(NULL); + } +} + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(640, 480); + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + + glutCreateWindow("Blue Pony"); + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Display); + glutVisibilityFunc(vis); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/bluepony/bluepony.dsp b/lib/glut-3.7.6/progs/demos/bluepony/bluepony.dsp new file mode 100644 index 0000000000..74d5f0c962 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bluepony/bluepony.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="bluepony" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=bluepony - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bluepony.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bluepony.mak" CFG="bluepony - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bluepony - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bluepony - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bluepony - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "bluepony - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bluepony - Win32 Release" +# Name "bluepony - Win32 Debug" +# Begin Source File + +SOURCE=.\bluepony.c +# End Source File +# Begin Source File + +SOURCE=.\readtex.c +# End Source File +# Begin Source File + +SOURCE=.\readtex.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/bluepony/logo.bw b/lib/glut-3.7.6/progs/demos/bluepony/logo.bw new file mode 100644 index 0000000000000000000000000000000000000000..e7d1fd13e27781e4efe02a20f0d37244d4b1bee8 GIT binary patch literal 16401 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%0A=H+)}{@?G* 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 NuB`wqv7q8;1OQ$EY4ZR8 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/bluepony/readtex.c b/lib/glut-3.7.6/progs/demos/bluepony/readtex.c new file mode 100644 index 0000000000..2898538c1a --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bluepony/readtex.c @@ -0,0 +1,307 @@ +/* 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 "readtex.h" + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +/* RGB Image Structure */ + +typedef struct _TK_RGBImageRec { + GLint sizeX, sizeY; + GLint components; + unsigned char *data; +} TK_RGBImageRec; + +/******************************************************************************/ + +typedef struct _rawImageRec { + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short sizeX, sizeY, sizeZ; + unsigned long min, max; + unsigned long wasteBytes; + char name[80]; + unsigned long colorMap; + FILE *file; + unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA; + unsigned long rleEnd; + GLuint *rowStart; + GLint *rowSize; +} rawImageRec; + +/******************************************************************************/ + +static void +ConvertShort(unsigned short *array, size_t length) +{ + unsigned short b1, b2; + unsigned char *ptr; + + ptr = (unsigned char *) array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + *array++ = (b1 << 8) | (b2); + } +} + +static void +ConvertLong(GLuint * array, size_t 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); + if (raw->tmp == NULL) { + fprintf(stderr, "Out of memory!\n"); + return NULL; + } + raw->tmpR = (unsigned char *) malloc(raw->sizeX * 256); + if (raw->tmpR == NULL) { + fprintf(stderr, "Out of memory!\n"); + return NULL; + } + if (raw->sizeZ > 1) { + raw->tmpG = (unsigned char *) malloc(raw->sizeX * 256); + raw->tmpB = (unsigned char *) malloc(raw->sizeX * 256); + if (raw->tmpG == NULL || raw->tmpB == NULL) { + fprintf(stderr, "Out of memory!\n"); + return NULL; + } + if (raw->sizeZ == 4) { + raw->tmpA = (unsigned char *) malloc(raw->sizeX * 256); + if (raw->tmpA == 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, x / sizeof(GLuint)); + ConvertLong((GLuint *) raw->rowSize, 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; + + if ((raw->type & 0xFF00) == 0x0100) { + fseek(raw->file, (long) raw->rowStart[y + z * raw->sizeY], SEEK_SET); + fread(raw->tmp, 1, (size_t) raw->rowSize[y + z * raw->sizeY], + raw->file); + + iPtr = raw->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(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); + if (raw->sizeZ > 1) { + 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); + if (raw->sizeZ > 1) { + *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); + 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 if (image->components == 1) { + format = GL_LUMINANCE; + intFormat = 1; + } 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; +} diff --git a/lib/glut-3.7.6/progs/demos/bluepony/readtex.h b/lib/glut-3.7.6/progs/demos/bluepony/readtex.h new file mode 100644 index 0000000000..1c0015b0fd --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bluepony/readtex.h @@ -0,0 +1,10 @@ +/* readtex.h */ + +#ifndef READTEX_H +#define READTEX_H + +#include + +extern GLboolean LoadRGBMipmaps(const char *imageFile, GLint intFormat); + +#endif diff --git a/lib/glut-3.7.6/progs/demos/bounce/Imakefile b/lib/glut-3.7.6/progs/demos/bounce/Imakefile new file mode 100644 index 0000000000..45151d3cf2 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/Imakefile @@ -0,0 +1,24 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../../Glut.cf" + +TARGETS = bounce + +SRCS = bounce.c glui.c tb.c trackball.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(bounce,bounce.o glui.o tb.o trackball.o) + +LinkFile(trackball.c, ../../examples/trackball.c) +LinkFile(trackball.h, ../../examples/trackball.h) + +trackball.o: trackball.h +tb.o: tb.h trackball.h +bounce.o: tb.h glui.c glui.h + +/* some old imake configs do setup "make depend" dependencies on linked files */ +depend:: trackball.c trackball.h tb.c tb.h + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/bounce/bounce.c b/lib/glut-3.7.6/progs/demos/bounce/bounce.c new file mode 100644 index 0000000000..ac8747e41f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/bounce.c @@ -0,0 +1,943 @@ + +/************************************************************************** + * * + * Copyright (C) 1988, 1989, 1990, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +/* + * foo $Revision: 1.4 $ + */ +#include +#include +#include +#include +#include +#include +#include + +#include "tb.h" +#include "glui.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define UDIV 12 +#define VDIV 12 + +#define WALLGRIDMAX 32 +#define EYEZ 3.3 + +#define TOTALBALLS 3 + +#define R 0 +#define G 1 +#define B 2 + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + +int wallgrid = 8; /* sqrt of the number of quads in a wall */ +float fatt = 1.0; + +int freeze = GL_FALSE; +int spin = GL_FALSE; +int spinning = GL_FALSE; +int objecton = GL_FALSE; +int normson = GL_FALSE; +int lighton[3] = {GL_TRUE, GL_TRUE, GL_TRUE}; + +int window; /* main window id */ + +GLboolean performance = GL_FALSE; /* performance indicator */ + +struct { + float p[3]; + float d[3]; + unsigned char color[3]; +} balls[TOTALBALLS]; + +float ballobj[UDIV+1][VDIV+1][4]; +float wallobj[WALLGRIDMAX+1][WALLGRIDMAX+1][4]; +float wallnorms[WALLGRIDMAX+1][WALLGRIDMAX+1][3]; +float wallnorm[3] = { 0.0, 0.0, -1.0 }; + +int orx, ory; + +float ballscale; +float ballsize; + +int DELTAX, DELTAY; + +int lflag = 0; + +float newpos[] = { 0.0, 0.0, 0.0, 1.0 }; + +GLfloat light_Ka[] = { 0.3, 0.3, 0.3, 1.0 }; /* ambient */ +GLfloat light_Ks[] = { 0.0, 0.0, 0.0, 1.0 }; /* specular */ + +GLfloat light0_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */ +GLfloat light0_Kd[] = { 1.0, 0.1, 0.1, 1.0 }; /* diffuse */ +GLfloat light0_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */ + +GLfloat light1_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */ +GLfloat light1_Kd[] = { 0.1, 1.0, 0.1, 1.0 }; /* diffuse */ +GLfloat light1_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */ + +GLfloat light2_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */ +GLfloat light2_Kd[] = { 0.1, 0.1, 1.0, 1.0 }; /* diffuse */ +GLfloat light2_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */ + +GLfloat attenuation[] = { 1.0, 3.0 }; + +GLfloat plane_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */ +GLfloat plane_Kd[] = { 0.4, 0.4, 0.4, 1.0 }; /* diffuse */ +GLfloat plane_Ks[] = { 1.0, 1.0, 1.0, 1.0 }; /* specular */ +GLfloat plane_Ke[] = { 0.0, 0.0, 0.0, 1.0 }; /* emission */ +GLfloat plane_Se = 30.0; /* shininess */ + +GLfloat wall_Ka[] = { 0.1, 0.1, 0.1, 1.0 }; /* ambient */ +GLfloat wall_Kd[] = { 0.8, 0.8, 0.8, 1.0 }; /* diffuse */ +GLfloat wall_Ks[] = { 1.0, 1.0, 1.0, 1.0 }; /* specular */ +GLfloat wall_Ke[] = { 0.0, 0.0, 0.0, 1.0 }; /* emission */ +GLfloat wall_Se = 20.0; /* shininess */ + +GLuint wall_material, plane_material; /* material display lists */ + +char ofile[80]; + + +/************************************************************/ +/* XXX - The following is an excerpt from spin.h from spin */ +/************************************************************/ + +#define POLYGON 1 +#define LINES 2 +#define TRANSPERENT 3 +#define DISPLAY 4 +#define LMATERIAL 5 + +#define FASTMAGIC 0x5423 + +typedef struct fastobj { + int npoints; + int colors; + int type; + int material; + int display; + int ablend; + GLint *data; +} fastobj; + +/* + * Wrappers to do either lines or polygons + */ +#define PolyOrLine() if (lflag == LINES) { \ + glBegin(GL_LINE_LOOP); \ + } else { \ + glBegin(GL_POLYGON); \ + } + +#define EndPolyOrLine() if (lflag == LINES) { \ + glEnd(); \ + } else { \ + glEnd(); \ + } + +/************************* end of spin.h excerpt *************************/ + + +fastobj *obj = NULL; + +/* + + general purpose text routine. draws a string according to the + format in a stroke font at x, y after scaling it by the scale + specified. x, y and scale are all in window-space [i.e., pixels] + with origin at the lower-left. + +*/ + +void +text(GLuint x, GLuint y, GLfloat scale, char* format, ...) +{ + va_list args; + char buffer[255], *p; + GLfloat font_scale = 119.05 + 33.33; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT)); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glTranslatef(x, y, 0.0); + + glScalef(scale/font_scale, scale/font_scale, scale/font_scale); + + for(p = buffer; *p; p++) + glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); + + glPopAttrib(); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +float +frand(void) +{ + return 2.0*(rand()/32768.0 - .5); +} + + +void +resetballs(void) +{ + register short i; + + balls[0].color[R] = 255; + balls[0].color[G] = 64; + balls[0].color[B] = 64; + balls[1].color[R] = 64; + balls[1].color[G] = 255; + balls[1].color[B] = 64; + balls[2].color[R] = 64; + balls[2].color[G] = 64; + balls[2].color[B] = 255; + for (i = 0; i < TOTALBALLS; i++) { + balls[i].p[0] = 0.0; + balls[i].p[1] = 0.0; + balls[i].p[2] = 0.0; + balls[i].d[0] = .1*frand(); + balls[i].d[1] = .1*frand(); + balls[i].d[2] = .1*frand(); + } +} + + +void +drawface(void) +{ + register int i,j; + + glNormal3fv(wallnorm); + for (i=0; i < wallgrid; i++) { + glBegin(GL_TRIANGLE_STRIP); + for (j=0; j <= wallgrid; j++) { + glVertex3fv(wallobj[i][j]); + glVertex3fv(wallobj[i+1][j]); + } + glEnd(); + } +} + + +void +drawnorms(void) +{ + register int i,j; + + glDisable(GL_LIGHTING); + glColor3ub(255, 255, 0); + for (i=0; i <= wallgrid; i++) { + for (j=0; j <= wallgrid; j++) { + glBegin(GL_LINES); + glVertex3fv(wallobj[i][j]); + glVertex3fv(wallnorms[i][j]); + glEnd(); + } + } + glEnable(GL_LIGHTING); +} + + +void +drawbox(void) +{ + glPushMatrix(); + +/* drawface(); */ + glRotatef(90.0, 0.0, 1.0, 0.0); + drawface(); + if (normson) drawnorms(); + glRotatef(90.0, 0.0, 1.0, 0.0); + drawface(); + if (normson) drawnorms(); + glRotatef(90.0, 0.0, 1.0, 0.0); +/* drawface(); */ + glRotatef(-90.0, 1.0, 0.0, 0.0); + drawface(); + if (normson) drawnorms(); + glRotatef(180.0, 1.0, 0.0, 0.0); +/* drawface(); */ + glPopMatrix(); +} + + +void +drawfastobj(fastobj *obj) +{ + register GLint *p, *end; + register int npolys; + + p = obj->data; + end = p + 8 * obj->npoints; + + if(obj->colors) { + npolys = obj->npoints/4; + while(npolys--) { + PolyOrLine(); + glColor3iv(p); + glVertex3fv((float *)p+4); + glColor3iv(p+8); + glVertex3fv((float *)p+12); + glColor3iv(p+16); + glVertex3fv((float *)p+20); + glColor3iv(p+24); + glVertex3fv((float *)p+28); + EndPolyOrLine(); + p += 32; + } + } else { + while ( p < end) { + PolyOrLine(); + glNormal3fv((float *)p); + glVertex3fv((float *)p+4); + glNormal3fv((float *)p+8); + glVertex3fv((float *)p+12); + glNormal3fv((float *)p+16); + glVertex3fv((float *)p+20); + glNormal3fv((float *)p+24); + glVertex3fv((float *)p+28); + EndPolyOrLine(); + p += 32; + } + } +} + +void +drawball(void) +{ + register int i,j; + + for (i=0; i < UDIV; i++) { + for (j=0; j < VDIV; j++) { + glBegin(GL_POLYGON); + glVertex4fv( ballobj[i][j] ); + glVertex4fv( ballobj[i+1][j] ); + glVertex4fv( ballobj[i+1][j+1] ); + glVertex4fv( ballobj[i][j+1] ); + glEnd(); + } + } +} + + + +void +drawimage(void) +{ + register short i; + static int start, end, last; + + glutSetWindow(window); + + if (performance) + start = glutGet(GLUT_ELAPSED_TIME); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + tbMatrix(); + + for (i=0; i < TOTALBALLS; i++) { + newpos[0] = balls[i].p[0]; + newpos[1] = balls[i].p[1]; + newpos[2] = balls[i].p[2]; + glLightfv(GL_LIGHT0 + i, GL_POSITION, newpos); + } + + glCallList(wall_material); + glEnable(GL_LIGHTING); + drawbox(); + + glEnable(GL_DEPTH_TEST); + + if (objecton) + { + glCallList(plane_material); + glPushMatrix(); + glScalef(1.5, 1.5, 1.5); + glRotatef(180.0, 0.0, 0.0, 1.0); + if (spin) + { + orx += 50; + ory += 50; + } + glRotatef(orx/10.0, 1.0, 0.0, 0.0); + glRotatef(ory/10.0, 0.0, 1.0, 0.0); + drawfastobj(obj); + glPopMatrix(); + } + + glDisable(GL_LIGHTING); + + for (i=0; i < TOTALBALLS; i++) { + if (lighton[i]) + { + glPushMatrix(); + glTranslatef(balls[i].p[0],balls[i].p[1],balls[i].p[2]); + glColor3ubv(balls[i].color); + drawball(); + glPopMatrix(); + } + } + + glColor3f(1.0, 1.0, 1.0); + if (performance) { + if (end - last == 0) { + text(10, 73, 20, "unknown fps"); + } else { + text(10, 73, 20, "%.0f fps", 1.0 / ((end - last) / 1000.0)); + } + last = start; + } + text(10, 43, 14, "Attenuation [%.2f]", fatt); + text(10, 13, 14, "Tesselation [%3d]", wallgrid); + + + glPopMatrix(); + glutSwapBuffers(); + + if (performance) + end = glutGet(GLUT_ELAPSED_TIME); +} + + +void +initobjects(void) +{ + register float u,v,du,dv; + register short i,j; + + du = 2.0*M_PI/UDIV; + dv = M_PI/VDIV; + + u = 0.; + for (i=0; i <= UDIV; i++) { + v = 0.; + for (j=0; j <= VDIV; j++) { + ballobj[i][j][X] = ballsize*cos(u)*sin(v); + ballobj[i][j][Y] = ballsize*sin(u)*sin(v); + ballobj[i][j][Z] = ballsize*cos(v); + ballobj[i][j][W] = 1.0; + v += dv; + } + u += du; + } + + for (i=0; i <= wallgrid; i++) { + for (j=0; j <= wallgrid; j++) { + wallobj[i][j][X] = -1.0 + 2.0*i/wallgrid; + wallobj[i][j][Y] = -1.0 + 2.0*j/wallgrid; + wallobj[i][j][Z] = 1.0; + wallobj[i][j][W] = 1.0; + } + } + + for (i=0; i <= wallgrid; i++) { + for (j=0; j <= wallgrid; j++) { + wallnorms[i][j][X] = wallobj[i][j][X] + wallnorm[X]*0.1; + wallnorms[i][j][Y] = wallobj[i][j][Y] + wallnorm[Y]*0.1; + wallnorms[i][j][Z] = wallobj[i][j][Z] + wallnorm[Z]*0.1; + } + } +} + +int MOUSEX, MOUSEY; + +static void +mouse(int button, int state, int x, int y) +{ + MOUSEX = x; + MOUSEY = y; + tbMouse(button, state, x, y); +} + +static void +motion(int x, int y) +{ + DELTAX -= MOUSEX - x; + DELTAY += MOUSEY - y; + MOUSEX = x; + MOUSEY = y; + tbMotion(x, y); +} + +/* ARGSUSED1 */ +void +keyboard(unsigned char key, int x, int y) +{ + switch(key) { + case 27: /* ESC */ + exit(0); + break; + + case '+': + wallgrid++; + if (wallgrid > WALLGRIDMAX) + wallgrid = WALLGRIDMAX; + initobjects(); + break; + + case '-': + wallgrid--; + if (wallgrid < 1) + wallgrid = 1; + initobjects(); + break; + } +} + +void +initialize(void) +{ + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); + window = glutCreateWindow("bounce"); + + initobjects(); + + srand(glutGet(GLUT_ELAPSED_TIME)); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_Ka); + + plane_material = glGenLists(1); + glNewList(plane_material, GL_COMPILE); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, plane_Ka); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, plane_Kd); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, plane_Ks); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, plane_Ke); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, plane_Se); + glEndList(); + + wall_material = glGenLists(1); + glNewList(wall_material, GL_COMPILE); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, wall_Ka); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, wall_Kd); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, wall_Ks); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, wall_Ke); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, wall_Se); + glEndList(); + + glLightfv(GL_LIGHT0, GL_AMBIENT, light0_Ka); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_Kd); + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, attenuation[0]); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, attenuation[1]); + /* OpenGL's light0 has different specular properties than the rest + of the lights.... */ + glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks); + + glLightfv(GL_LIGHT1, GL_AMBIENT, light1_Ka); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_Kd); + glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, attenuation[0]); + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, attenuation[1]); + + glLightfv(GL_LIGHT2, GL_AMBIENT, light2_Ka); + glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_Kd); + glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, attenuation[0]); + glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, attenuation[1]); + + glutMotionFunc(motion); + glutMouseFunc(mouse); + glutKeyboardFunc(keyboard); +} + + +void +calcball(void) +{ + register short i,j; + + for (j=0; j < TOTALBALLS; j++) { + for (i=0; i < 3; i++) { + balls[j].p[i] += balls[j].d[i]; + if (fabs(balls[j].p[i]) > ballscale) { + balls[j].p[i] = (balls[j].p[i] > 0.0) ? + ballscale : -ballscale; + balls[j].d[i] = -balls[j].d[i]; + } + } + } +} + +static void menu(int value); +static void idle(void); + +static void +make_menu(void) +{ + static int main_menu = 0; + + if (main_menu) + glutDestroyMenu(main_menu); + + main_menu = glutCreateMenu(menu); + glutAddMenuEntry("bounce", 0); + glutAddMenuEntry("", 0); + if (lighton[0]) + glutAddMenuEntry("red light off", 1); + else + glutAddMenuEntry("red light on", 1); + if (lighton[1]) + glutAddMenuEntry("green light off", 2); + else + glutAddMenuEntry("green light on", 2); + if (lighton[2]) + glutAddMenuEntry("blue light off", 3); + else + glutAddMenuEntry("blue light on", 3); + + if (freeze) + glutAddMenuEntry("unfreeze lights", 4); + else + glutAddMenuEntry("freeze lights", 4); + + if (normson) + glutAddMenuEntry("normals off", 7); + else + glutAddMenuEntry("normals on", 7); + + if (performance) + glutAddMenuEntry("frame rate off", 8); + else + glutAddMenuEntry("frame rate on", 8); + + if (obj) + { + if (objecton) + glutAddMenuEntry("object off", 5); + else + glutAddMenuEntry("object on", 5); + if (spin) + glutAddMenuEntry("object spin off", 6); + else + glutAddMenuEntry("object spin on", 6); + } + + glutAddMenuEntry("", 0); + glutAddMenuEntry("exit", 9); + + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +static void +menu(int value) +{ + switch(value) { + case 1: + if ((lighton[0] = !lighton[0])) + glEnable(GL_LIGHT0); + else + glDisable(GL_LIGHT0); + break; + case 2: + if ((lighton[1] = !lighton[1])) + glEnable(GL_LIGHT1); + else + glDisable(GL_LIGHT1); + break; + case 3: + if ((lighton[2] = !lighton[2])) + glEnable(GL_LIGHT2); + else + glDisable(GL_LIGHT2); + break; + case 4: + freeze = !freeze; + if (!freeze || spinning) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } + break; + case 5: + if (obj) + objecton = !objecton; + else + exit(1); + break; + case 6: + spin = !spin; + break; + case 7: + normson = !normson; + break; + case 8: + performance = !performance; + break; + case 9: + exit(0); + break; + } + glutPostWindowRedisplay(window); + make_menu(); +} + +/**********************************************************/ +/* XXX - The following is a clone of fastobj.c from spin */ +/**********************************************************/ + + +fastobj* +readfastobj(char *name) +{ + FILE *inf; + fastobj *obj; + int i; + int nlongs; + int magic; + GLint *ip; + char filename[512]; + + inf = fopen(name,"r"); + if(!inf) { + sprintf(filename,"%s",name); + inf = fopen(filename,"r"); + if(!inf) { + fprintf(stderr,"readfast: can't open input file %s\n",name); + exit(1); + } + } + fread(&magic,sizeof(int),1,inf); + if(magic != FASTMAGIC) { + fprintf(stderr,"readfast: bad magic in object file\n"); + fclose(inf); + exit(1); + } + obj = (fastobj *)malloc(sizeof(fastobj)); + fread(&obj->npoints,sizeof(int),1,inf); + fread(&obj->colors,sizeof(int),1,inf); + + /* + * Insure that the data is quad-word aligned and begins on a page + * boundary. This shields us from the performance loss which occurs + * whenever we try to fetch data which straddles a page boundary (the OS + * has to map in the next virtual page and re-start the DMA transfer). + */ + nlongs = 8 * obj->npoints; + obj->data = (GLint *) malloc(nlongs*sizeof(int) + 4096); + obj->data = (GLint *) (((int)(obj->data)) + 0xfff); + obj->data = (GLint *) (((int)(obj->data)) & 0xfffff000); + + /* XXX Careful, sizeof(GLint) could change from implementation + to implementation making this file format implementation + dependent. -mjk */ + for (i = 0, ip = obj->data; i < nlongs/4; i++, ip += 4) + fread(ip, 3 * sizeof(GLint), 1, inf); + fclose(inf); + return obj; +} + + +/* + * objmaxpoint + * + * find the vertex farthest from the origin, + * so we can set the near and far clipping planes tightly. + */ + +#define MAXVERT(v) if ( (len = sqrt( (*(v)) * (*(v)) + \ + (*(v+1)) * (*(v+1)) + \ + (*(v+2)) * (*(v+2)) )) > max) \ + max = len; + +float +objmaxpoint(obj) +fastobj *obj; +{ + register float *p, *end; + register int npolys; + register float len; + register float max = 0.0; + + p = (float *) (obj->data); + + if (obj->colors) { + npolys = obj->npoints/4; + while(npolys--) { + MAXVERT(p+4); + MAXVERT(p+12); + MAXVERT(p+20); + MAXVERT(p+28); + p += 32; + } + } else { + end = p + 8 * obj->npoints; + while ( p < end) { + MAXVERT(p+4); + MAXVERT(p+12); + MAXVERT(p+20); + MAXVERT(p+28); + p += 32; + } + } + + return max; +} + +static void +idle(void) +{ + assert(!freeze || spinning); + if (!freeze) { + calcball(); + } + if (spinning) { + tbStepAnimation(); + } + glutPostWindowRedisplay(window); +} + +/* When not visible, stop animating. Restart when visible again. */ +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) { + if (!freeze || spinning) + glutIdleFunc(idle); + } else { + if (!freeze || spinning) + glutIdleFunc(NULL); + } +} + +static void +reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, (float)width/height, EYEZ-2.0, EYEZ+2.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.25, -EYEZ); + + tbReshape(width, height); + gluiReshape(width, height); +} + +void +update_fatt(float value) +{ + fatt = 5 * value; + glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, fatt); + glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, fatt); + glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, fatt); + glutPostWindowRedisplay(window); +} + +void +update_grid(float value) +{ + wallgrid = WALLGRIDMAX*value; + if (wallgrid < 1) + wallgrid = 1; + initobjects(); + glutPostWindowRedisplay(window); +} + +void +spinChange(int state) +{ + spinning = state; + if (spinning || !freeze) { + glutIdleFunc(idle); + } else { + glutIdleFunc(NULL); + } +} + +int +main(int argc, char **argv) +{ + glutInitWindowSize(512, 512); + glutInitWindowPosition(64, 64); + glutInit(&argc, argv); + + if (argc > 1) + { + int i; + + for (i=0; argv[1][i] != '/' && argv[1][i] != '\0'; i++); + if (argv[1][i] != '/') + { + strcpy(ofile, "/usr/demos/data/models/"); + strcat(ofile, argv[1]); + } + else + strcpy(ofile, argv[1]); + + if (obj = readfastobj(ofile)) + objecton = GL_TRUE; + } + + ballsize = .04; + ballscale = 1.0 - ballsize; + + initialize(); + + make_menu(); + + resetballs(); + + /* Use local lights for the box */ + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHT2); + + make_menu(); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutDisplayFunc(drawimage); + glutReshapeFunc(reshape); + glutVisibilityFunc(visible); + + gluiHorizontalSlider(window, 130, -10, -10, 20, + (float)wallgrid/WALLGRIDMAX, update_grid); + gluiHorizontalSlider(window, 130, -40, -10, 20, fatt/5.0, update_fatt); + + tbInit(GLUT_LEFT_BUTTON); + tbAnimate(1); + tbAnimateFunc(spinChange); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/bounce/bounce.dsp b/lib/glut-3.7.6/progs/demos/bounce/bounce.dsp new file mode 100644 index 0000000000..a5531005ea --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/bounce.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="bounce" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=bounce - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bounce.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bounce.mak" CFG="bounce - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bounce - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bounce - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bounce - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "bounce - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bounce - Win32 Release" +# Name "bounce - Win32 Debug" +# Begin Source File + +SOURCE=.\bounce.c +# End Source File +# Begin Source File + +SOURCE=.\glui.c +# End Source File +# Begin Source File + +SOURCE=.\glui.h +# End Source File +# Begin Source File + +SOURCE=.\tb.c +# End Source File +# Begin Source File + +SOURCE=.\tb.h +# End Source File +# Begin Source File + +SOURCE=.\trackball.c +# End Source File +# Begin Source File + +SOURCE=.\trackball.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/bounce/glui.c b/lib/glut-3.7.6/progs/demos/bounce/glui.c new file mode 100644 index 0000000000..b29aba72f7 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/glui.c @@ -0,0 +1,509 @@ + +/* + glui.c + Nate Robins, 1997. + + OpenGL based user interface. + + */ + +#include +#include +#include + +#define GLUI_BORDER 3 +#define GLUI_KNOB 40 + +#define GLUI_RAISED 1 +#define GLUI_SUNKEN 0 + +#define GLUI_HORIZONTAL 0 +#define GLUI_VERTICAL 1 + +#define GLUI_LESS -1 +#define GLUI_HIT 0 +#define GLUI_MORE 1 + +#define GLUI_HILITE 0.15 + +typedef struct _GLUIslider { + int type; /* vertical/horizontal */ + int parent; /* parent of this slider */ + int window; /* this sliders window */ + int win_x; /* slider window x (parent relative) */ + int win_y; /* slider window y (parent relative) */ + int win_w; /* slider window width */ + int win_h; /* slider window height */ + int length; /* length of the slider in pixels */ + int knob; /* position of the knob in pixels */ + int lit; /* currently lit? */ + void (*update)(float); /* callback for updating (returns %) */ + struct _GLUIslider* next; +} GLUIslider; + +static GLUIslider* _gluiSliders = NULL; +static GLUIslider* _gluiHit = NULL; + +static GLUIslider* +_gluiCurrentSlider(void) +{ + GLUIslider* slider = _gluiSliders; + int window = glutGetWindow(); + + while(slider) { + if (slider->window == window) + break; + slider = slider->next; + } + + if (!slider) + printf("glui: _gluiCurrentSlider() failed!\n"); + + return slider; +} + +static void +_gluiEmboss(int raised, int lit, int x, int y, int width, int height) +{ + int i; + float c; + + for (i = 0; i < GLUI_BORDER; i++) { + c = (float)i / (GLUI_BORDER * 5) + (lit ? GLUI_HILITE : 0.0); + if (raised) + glColor3f(0.275+c, 0.2+c, 0.2+c); + else + glColor3f(0.875-c, 0.8-c, 0.8-c); + glBegin(GL_LINE_STRIP); + glVertex2f(x+i+1, y+i); + glVertex2f(x+width-i-1, y+i); + glVertex2f(x+width-i-1, y+height-i); + glEnd(); + } + + for (i = 0; i < GLUI_BORDER; i++) { + c = (float)i / (GLUI_BORDER * 5); + if (raised) + glColor3f(0.875-c, 0.8-c, 0.8-c); + else + glColor3f(0.275+c, 0.2+c, 0.2+c); + glBegin(GL_LINE_STRIP); + glVertex2f(x+i, y+i); + glVertex2f(x+i, y+height-i-1); + glVertex2f(x+width-i-1, y+height-i-1); + glEnd(); + } + + c = lit ? GLUI_HILITE : 0.0; + + if (raised) + glColor3f(0.575+c, 0.5+c, 0.5+c); + else + glColor3f(0.475+c, 0.3+c, 0.3+c); + glRectf(x+i, y+i, x+width-i, y+height-i); +} + +static void +_gluiDisplay(void) +{ + int lit; + GLUIslider* slider = _gluiCurrentSlider(); + + lit = slider->lit ? GLUI_HILITE : 0.0; + + glClear(GL_COLOR_BUFFER_BIT); + if (slider->type == GLUI_HORIZONTAL) { + _gluiEmboss(GLUI_SUNKEN, 0, /* never lit */ + 0, 0, slider->length, slider->win_h); + _gluiEmboss(GLUI_RAISED, slider->lit, + slider->knob - GLUI_KNOB/2, GLUI_BORDER, + GLUI_KNOB + GLUI_BORDER, slider->win_h - GLUI_BORDER*2); + /* XXX why is it GLUI_KNOB+GLUI_BORDER ? */ + glColor3f(0.975+lit, 0.9+lit, 0.9+lit); + glBegin(GL_LINES); + glVertex2f(slider->knob-2, GLUI_BORDER*2-1); + glVertex2f(slider->knob-2, slider->win_h-GLUI_BORDER*2+1); + glVertex2f(slider->knob+1, GLUI_BORDER*2-1); + glVertex2f(slider->knob+1, slider->win_h-GLUI_BORDER*2+1); + glVertex2f(slider->knob+4, GLUI_BORDER*2-1); + glVertex2f(slider->knob+4, slider->win_h-GLUI_BORDER*2+1); + glEnd(); + glColor3f(0.175+lit, 0.1+lit, 0.1+lit); + glBegin(GL_LINES); + glVertex2f(slider->knob-3, GLUI_BORDER*2-1); + glVertex2f(slider->knob-3, slider->win_h-GLUI_BORDER*2+1); + glVertex2f(slider->knob+0, GLUI_BORDER*2-1); + glVertex2f(slider->knob+0, slider->win_h-GLUI_BORDER*2+1); + glVertex2f(slider->knob+3, GLUI_BORDER*2-1); + glVertex2f(slider->knob+3, slider->win_h-GLUI_BORDER*2+1); + glEnd(); + } else { + _gluiEmboss(GLUI_SUNKEN, 0, /* never lit */ + 0, 0, slider->win_w, slider->length); + _gluiEmboss(GLUI_RAISED, slider->lit, + GLUI_BORDER, slider->knob - GLUI_KNOB/2, + slider->win_w - GLUI_BORDER*2, GLUI_KNOB + GLUI_BORDER); + /* XXX why is it GLUI_KNOB+GLUI_BORDER ? */ + glColor3f(0.175+lit, 0.1+lit, 0.1+lit); + glBegin(GL_LINES); + glVertex2f(GLUI_BORDER*2-1, slider->knob-2); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob-2); + glVertex2f(GLUI_BORDER*2-1, slider->knob+1); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob+1); + glVertex2f(GLUI_BORDER*2-1, slider->knob+4); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob+4); + glEnd(); + glColor3f(0.975+lit, 0.9+lit, 0.9+lit); + glBegin(GL_LINES); + glVertex2f(GLUI_BORDER*2-1, slider->knob-3); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob-3); + glVertex2f(GLUI_BORDER*2-1, slider->knob+0); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob+0); + glVertex2f(GLUI_BORDER*2-1, slider->knob+3); + glVertex2f(slider->win_w-GLUI_BORDER*2+1, slider->knob+3); + glEnd(); + } + + glutSwapBuffers(); +} + +static int +_gluiHitKnob(GLUIslider* slider, int x, int y) +{ + if (slider->type == GLUI_HORIZONTAL) { + /* we know that we don't have to test the y coordinate because + the mouse came down in the window (this means that they can + hit the borders and still move the knob, but that's okay). + */ + if (x > slider->knob - GLUI_KNOB/2 && x < slider->knob + GLUI_KNOB/2) + return GLUI_HIT; + else if (x < slider->knob) + return GLUI_LESS; + else + return GLUI_MORE; + } else { + /* we know that we don't have to test the x coordinate because + the mouse came down in the window (this means that they can + hit the borders and still move the knob, but that's okay). + */ + if (y > slider->knob - GLUI_KNOB/2 && y < slider->knob + GLUI_KNOB/2) + return GLUI_HIT; + else if (y < slider->knob) + return GLUI_LESS; + else + return GLUI_MORE; + } +} + +static void +_gluiConstrainKnob(GLUIslider* slider) +{ + if (slider->knob > slider->length - GLUI_BORDER*2 - GLUI_KNOB/2) + slider->knob = slider->length - GLUI_BORDER*2 - GLUI_KNOB/2; + else if (slider->knob < GLUI_BORDER + GLUI_KNOB/2) + slider->knob = GLUI_BORDER + GLUI_KNOB/2; +} + + +static float +_gluiKnobPercent(GLUIslider* slider) +{ + return (float)(slider->knob - GLUI_KNOB/2 - GLUI_BORDER) / + (slider->length - GLUI_BORDER*3 - GLUI_KNOB); +} + +static int +_gluiKnobPosition(GLUIslider* slider, float percent) +{ + return GLUI_BORDER + GLUI_KNOB/2 + percent * + (slider->length - GLUI_BORDER*3 - GLUI_KNOB); +} + +static int _gluiX; +static int _gluiY; +static int _gluiMouseDown; + +static void +_gluiTimer(int value) +{ + GLUIslider* slider = (GLUIslider*)value; + float percent; + + percent = _gluiKnobPercent(slider); + + if (_gluiMouseDown != 0 && percent > 0.0 && percent < 1.0) { + if (_gluiMouseDown == GLUI_LESS) { + slider->knob -= slider->length / 25.0; + _gluiConstrainKnob(slider); + } else { + slider->knob += slider->length / 25.0; + _gluiConstrainKnob(slider); + } + glutSetWindow(slider->window); + glutPostRedisplay(); + slider->update(_gluiKnobPercent(slider)); + glutTimerFunc(20, _gluiTimer, (int)slider); + } +} + +static void +_gluiConvertY(GLUIslider* slider, int* y) +{ + if (slider->win_h < 0) { + glutSetWindow(slider->parent); + *y = glutGet(GLUT_WINDOW_HEIGHT) + slider->win_h - slider->win_y - *y; + glutSetWindow(slider->window); + } else { + *y = slider->win_h - *y; + } +} + +/* ARGSUSED */ +static void +_gluiMouse(int button, int state, int x, int y) +{ + GLUIslider* slider = _gluiCurrentSlider(); + int side; + + _gluiConvertY(slider, &y); + + _gluiX = x; + _gluiY = y; + _gluiHit = NULL; + _gluiMouseDown = GL_FALSE; + + if (state == GLUT_DOWN) { + side = _gluiHitKnob(slider, x, y); + if (side == GLUI_HIT) { + _gluiHit = slider; + } else if (side == GLUI_LESS) { + slider->knob -= slider->length / 25.0; + _gluiConstrainKnob(slider); + } else { + slider->knob += slider->length / 25.0; + _gluiConstrainKnob(slider); + } + glutPostRedisplay(); + slider->update(_gluiKnobPercent(slider)); + _gluiMouseDown = side; + if (side != 0) { + glutTimerFunc(500, _gluiTimer, (int)slider); + } + } else { + slider->lit = GL_FALSE; + } +} + +static void +_gluiMotion(int x, int y) +{ + GLUIslider* slider = _gluiHit; + + if (slider) { + _gluiConvertY(slider, &y); + + if (slider->type == GLUI_HORIZONTAL) { + /* clamp the incoming old position, or else the knob will + possibly "jump" due to the false delta. */ + if (_gluiX < GLUI_BORDER+1) + _gluiX = GLUI_BORDER+1; + if (_gluiX > slider->length - GLUI_BORDER*2) + _gluiX = slider->length - GLUI_BORDER*2; + /* we don't want to take any action if the mouse pointer + has moved passed the extents of the slider. */ + if (x > GLUI_BORDER && x < slider->length - GLUI_BORDER*2) { + slider->knob -= _gluiX - x; + _gluiX = x; + } + } else { + /* clamp the incoming old position, or else the knob will + possibly "jump" due to the false delta. */ + if (_gluiY < GLUI_BORDER+1) + _gluiY = GLUI_BORDER+1; + if (_gluiY > slider->length - GLUI_BORDER*2) + _gluiY = slider->length - GLUI_BORDER*2; + /* we don't want to take any action if the mouse pointer + has moved passed the extents of the slider. */ + if (y > GLUI_BORDER && y < slider->length - GLUI_BORDER*2) { + slider->knob -= _gluiY - y; + _gluiY = y; + } + } + _gluiConstrainKnob(slider); + + /* post a display _before_ updating the user, so that the knob + won't lag behind. */ + glutPostRedisplay(); + + /* make sure to set the parent window current, otherwise if + there is OpenGL state being changed in the update callback, + it will be done to the sliders context! */ + glutSetWindow(slider->parent); + slider->update(_gluiKnobPercent(slider)); + } +} + +static void +_gluiPassive(int x, int y) +{ + GLUIslider* slider = _gluiCurrentSlider(); + + _gluiConvertY(slider, &y); + + if (_gluiHitKnob(slider, x, y) == 0) + slider->lit = GL_TRUE; + else + slider->lit = GL_FALSE; + + glutPostRedisplay(); +} + +/* ARGSUSED */ +static void +_gluiEntry(int state) +{ + GLUIslider* slider = _gluiCurrentSlider(); + + /* set the lit flag to false whether we are coming or going + because if we are doing either, we can't be on top of the knob! */ + slider->lit = GL_FALSE; + glutPostRedisplay(); +} + +void +gluiReshape(int width, int height) +{ + float percent; + int x, y, w, h; + GLUIslider* slider = _gluiSliders; + + while (slider) { + /* we need to get the width and height of the parent, so set + it current. */ + glutSetWindow(slider->parent); + + /* all this mumbo jumbo takes care of the negative arguments + to attach the slider to different sides of the window. */ + x = slider->win_x; + if (x < 0) + x = width - slider->win_w + x + 1; + y = slider->win_y; + if (y < 0) + y = height - slider->win_h + y + 1; + w = slider->win_w; + if (w < 0) + w = glutGet(GLUT_WINDOW_WIDTH) + slider->win_w - slider->win_x; + h = slider->win_h; + if (h < 0) + h = glutGet(GLUT_WINDOW_HEIGHT) + slider->win_h - slider->win_y; + + glutSetWindow(slider->window); + glutPositionWindow(x, y); + glutReshapeWindow(w, h); + + percent = _gluiKnobPercent(slider); + + if (slider->type == GLUI_HORIZONTAL) + slider->length = w; + else + slider->length = h; + + slider->knob = _gluiKnobPosition(slider, percent); + + _gluiConstrainKnob(slider); + + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, w, 0, h); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + slider = slider->next; + } +} + + + +int +gluiVerticalSlider(int parent, int x, int y, int width, int height, + float percent, void (*update)(float)) +{ + GLUIslider* slider = (GLUIslider*)malloc(sizeof(GLUIslider)); + slider->next = _gluiSliders; + _gluiSliders = slider; + + slider->type = GLUI_VERTICAL; + slider->parent = parent; + slider->window = glutCreateSubWindow(parent, x, y, width, height); + slider->win_x = x; + slider->win_y = y; + slider->win_w = width; + slider->win_h = height; + slider->update = update; + slider->lit = GL_FALSE; + +/* glutSetCursor(GLUT_CURSOR_LEFT_RIGHT); */ + glutDisplayFunc(_gluiDisplay); + glutEntryFunc(_gluiEntry); + glutMouseFunc(_gluiMouse); + glutMotionFunc(_gluiMotion); + glutPassiveMotionFunc(_gluiPassive); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + slider->length = height; + if (height < 0) { + glutSetWindow(parent); + slider->length = glutGet(GLUT_WINDOW_HEIGHT) + height - slider->win_y; + } + + slider->knob = _gluiKnobPosition(slider, percent); + _gluiConstrainKnob(slider); + + return slider->window; +} + + +/* On a horizontal slider, the height must be non-negative. */ + +int +gluiHorizontalSlider(int parent, int x, int y, int width, int height, + float percent, void (*update)(float)) +{ + GLUIslider* slider = (GLUIslider*)malloc(sizeof(GLUIslider)); + slider->next = _gluiSliders; + _gluiSliders = slider; + + slider->type = GLUI_HORIZONTAL; + slider->parent = parent; + slider->window = glutCreateSubWindow(parent, x, y, width, height); + slider->win_x = x; + slider->win_y = y; + slider->win_w = width; + slider->win_h = height; + slider->update = update; + slider->lit = GL_FALSE; + +/* glutSetCursor(GLUT_CURSOR_LEFT_RIGHT); */ + glutDisplayFunc(_gluiDisplay); + glutEntryFunc(_gluiEntry); + glutMouseFunc(_gluiMouse); + glutMotionFunc(_gluiMotion); + glutPassiveMotionFunc(_gluiPassive); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + slider->length = width; + if (width < 0) { + glutSetWindow(parent); + slider->length = glutGet(GLUT_WINDOW_WIDTH) + width - slider->win_x; + } + + slider->knob = _gluiKnobPosition(slider, percent); + _gluiConstrainKnob(slider); + + return slider->window; +} diff --git a/lib/glut-3.7.6/progs/demos/bounce/glui.h b/lib/glut-3.7.6/progs/demos/bounce/glui.h new file mode 100644 index 0000000000..24770f3ac3 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/glui.h @@ -0,0 +1,18 @@ +/* + glui.h + Nate Robins, 1997. + + OpenGL based user interface. + + */ + +int +gluiHorizontalSlider(int parent, int x, int y, int width, int height, + float percent, void (*update)(float)); + +int +gluiVerticalSlider(int parent, int x, int y, int width, int height, + float percent, void (*update)(float)); + +void +gluiReshape(int width, int height); diff --git a/lib/glut-3.7.6/progs/demos/bounce/tb.c b/lib/glut-3.7.6/progs/demos/bounce/tb.c new file mode 100644 index 0000000000..73bbc9c522 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/tb.c @@ -0,0 +1,147 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include +#include +#include +#include "tb.h" +#include "trackball.h" + +/* globals */ +static GLuint tb_lasttime; + +float curquat[4]; +float lastquat[4]; +int beginx, beginy; + +static GLuint tb_width; +static GLuint tb_height; + +static GLint tb_button = -1; +static GLboolean tb_tracking = GL_FALSE; +static GLboolean tb_animate = GL_TRUE; + +void +tbStepAnimation(void) +{ + add_quats(lastquat, curquat, curquat); +} + +void +_tbAnimate(void) +{ + tbStepAnimation(); + glutPostRedisplay(); +} + +static void +defaultAnimateFunc(int animate) +{ + if (animate) { + glutIdleFunc(_tbAnimate); + } else { + glutIdleFunc(0); + } +} + +void (*animateFunc)(int animate) = defaultAnimateFunc; + +void +_tbStartMotion(int x, int y, int time) +{ + assert(tb_button != -1); + + animateFunc(0); + tb_tracking = GL_TRUE; + tb_lasttime = time; + beginx = x; + beginy = y; +} + +void +_tbStopMotion(unsigned time) +{ + assert(tb_button != -1); + + tb_tracking = GL_FALSE; + + if (time == tb_lasttime && tb_animate) { + animateFunc(1); + } else { + if (tb_animate) { + animateFunc(0); + } + } +} + +void +tbAnimate(GLboolean animate) +{ + tb_animate = animate; +} + +void +tbInit(GLuint button) +{ + tb_button = button; + trackball(curquat, 0.0, 0.0, 0.0, 0.0); +} + +void +tbMatrix(void) +{ + GLfloat m[4][4]; + + assert(tb_button != -1); + build_rotmatrix(m, curquat); + glMultMatrixf(&m[0][0]); +} + +void +tbReshape(int width, int height) +{ + assert(tb_button != -1); + + tb_width = width; + tb_height = height; +} + +void +tbMouse(int button, int state, int x, int y) +{ + assert(tb_button != -1); + + if (state == GLUT_DOWN && button == tb_button) + _tbStartMotion(x, y, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP && button == tb_button) + _tbStopMotion(glutGet(GLUT_ELAPSED_TIME)); +} + +void +tbMotion(int x, int y) +{ + if (tb_tracking) { + trackball(lastquat, + (2.0 * beginx - tb_width) / tb_width, + (tb_height - 2.0 * beginy) / tb_height, + (2.0 * x - tb_width) / tb_width, + (tb_height - 2.0 * y) / tb_height + ); + beginx = x; + beginy = y; + tb_animate = 1; + tb_lasttime = glutGet(GLUT_ELAPSED_TIME); + tbStepAnimation(); + } +} + +void +tbAnimateFunc(void (*func)(int animate)) +{ + animateFunc = func; +} diff --git a/lib/glut-3.7.6/progs/demos/bounce/tb.h b/lib/glut-3.7.6/progs/demos/bounce/tb.h new file mode 100644 index 0000000000..c999bd583c --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/tb.h @@ -0,0 +1,86 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + * + * + * Usage: + * + * o call tbInit() in before any other tb call + * o call tbReshape() from the reshape callback + * o call tbMatrix() to get the trackball matrix rotation + * o call tbStartMotion() to begin trackball movememt + * o call tbStopMotion() to stop trackball movememt + * o call tbMotion() from the motion callback + * o call tbAnimate(GL_TRUE) if you want the trackball to continue + * spinning after the mouse button has been released + * o call tbAnimate(GL_FALSE) if you want the trackball to stop + * spinning after the mouse button has been released + * + * Typical setup: + * + * + void + init(void) + { + tbInit(GLUT_MIDDLE_BUTTON); + tbAnimate(GL_TRUE); + . . . + } + + void + reshape(int width, int height) + { + tbReshape(width, height); + . . . + } + + void + display(void) + { + glPushMatrix(); + + tbMatrix(); + . . . draw the scene . . . + + glPopMatrix(); + } + + void + mouse(int button, int state, int x, int y) + { + tbMouse(button, state, x, y); + . . . + } + + void + motion(int x, int y) + { + tbMotion(x, y); + . . . + } + + int + main(int argc, char** argv) + { + . . . + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutMotionFunc(motion); + . . . + } + * + * */ + + +/* functions */ +extern void tbInit(GLuint button); +extern void tbMatrix(void); +extern void tbReshape(int width, int height); +extern void tbMouse(int button, int state, int x, int y); +extern void tbMotion(int x, int y); +extern void tbAnimate(GLboolean animate); +extern void tbAnimateFunc(void (*func)(int animate)); +extern void tbStepAnimation(void); diff --git a/lib/glut-3.7.6/progs/demos/bounce/trackball.c b/lib/glut-3.7.6/progs/demos/bounce/trackball.c new file mode 100644 index 0000000000..cce919b5ac --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/trackball.c @@ -0,0 +1,346 @@ +#include +/* + * (c) Copyright 1993, 1994, 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. + */ +/* + * Trackball code: + * + * Implementation of a virtual trackball. + * Implemented by Gavin Bell, lots of ideas from Thant Tessman and + * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129. + * + * Vector manip code: + * + * Original code from: + * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli + * + * Much mucking with by: + * Gavin Bell + */ +#if defined(_WIN32) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#endif +#include +#include "trackball.h" + +/* + * This size should really be based on the distance from the center of + * rotation to the point on the object underneath the mouse. That + * point would then track the mouse as closely as possible. This is a + * simple example, though, so that is left as an Exercise for the + * Programmer. + */ +#define TRACKBALLSIZE (0.8f) + +/* + * Local function prototypes (not defined in trackball.h) + */ +static float tb_project_to_sphere(float, float, float); +static void normalize_quat(float [4]); + +void +vzero(float *v) +{ + v[0] = 0.0; + v[1] = 0.0; + v[2] = 0.0; +} + +void +vset(float *v, float x, float y, float z) +{ + v[0] = x; + v[1] = y; + v[2] = z; +} + +void +vsub(const float *src1, const float *src2, float *dst) +{ + dst[0] = src1[0] - src2[0]; + dst[1] = src1[1] - src2[1]; + dst[2] = src1[2] - src2[2]; +} + +void +vcopy(const float *v1, float *v2) +{ + register int i; + for (i = 0 ; i < 3 ; i++) + v2[i] = v1[i]; +} + +void +vcross(const float *v1, const float *v2, float *cross) +{ + float temp[3]; + + temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + vcopy(temp, cross); +} + +float +vlength(const float *v) +{ + return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +void +vscale(float *v, float div) +{ + v[0] *= div; + v[1] *= div; + v[2] *= div; +} + +void +vnormal(float *v) +{ + vscale(v,1.0/vlength(v)); +} + +float +vdot(const float *v1, const float *v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void +vadd(const float *src1, const float *src2, float *dst) +{ + dst[0] = src1[0] + src2[0]; + dst[1] = src1[1] + src2[1]; + dst[2] = src1[2] + src2[2]; +} + +/* + * Ok, simulate a track-ball. Project the points onto the virtual + * trackball, then figure out the axis of rotation, which is the cross + * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) + * Note: This is a deformed trackball-- is a trackball in the center, + * but is deformed into a hyperbolic sheet of rotation away from the + * center. This particular function was chosen after trying out + * several variations. + * + * It is assumed that the arguments to this routine are in the range + * (-1.0 ... 1.0) + */ +void +trackball(float q[4], float p1x, float p1y, float p2x, float p2y) +{ + float a[3]; /* Axis of rotation */ + float phi; /* how much to rotate about axis */ + float p1[3], p2[3], d[3]; + float t; + + if (p1x == p2x && p1y == p2y) { + /* Zero rotation */ + vzero(q); + q[3] = 1.0; + return; + } + + /* + * First, figure out z-coordinates for projection of P1 and P2 to + * deformed sphere + */ + vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y)); + vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y)); + + /* + * Now, we want the cross product of P1 and P2 + */ + vcross(p2,p1,a); + + /* + * Figure out how much to rotate around that axis. + */ + vsub(p1,p2,d); + t = vlength(d) / (2.0*TRACKBALLSIZE); + + /* + * Avoid problems with out-of-control values... + */ + if (t > 1.0) t = 1.0; + if (t < -1.0) t = -1.0; + phi = 2.0 * asin(t); + + axis_to_quat(a,phi,q); +} + +/* + * Given an axis and angle, compute quaternion. + */ +void +axis_to_quat(float a[3], float phi, float q[4]) +{ + vnormal(a); + vcopy(a,q); + vscale(q,sin(phi/2.0)); + q[3] = cos(phi/2.0); +} + +/* + * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet + * if we are away from the center of the sphere. + */ +static float +tb_project_to_sphere(float r, float x, float y) +{ + float d, t, z; + + d = sqrt(x*x + y*y); + if (d < r * 0.70710678118654752440) { /* Inside sphere */ + z = sqrt(r*r - d*d); + } else { /* On hyperbola */ + t = r / 1.41421356237309504880; + z = t*t / d; + } + return z; +} + +/* + * Given two rotations, e1 and e2, expressed as quaternion rotations, + * figure out the equivalent single rotation and stuff it into dest. + * + * This routine also normalizes the result every RENORMCOUNT times it is + * called, to keep error from creeping in. + * + * NOTE: This routine is written so that q1 or q2 may be the same + * as dest (or each other). + */ + +#define RENORMCOUNT 97 + +void +negate_quat(float q[4], float nq[4]) +{ + nq[0] = -q[0]; + nq[1] = -q[1]; + nq[2] = -q[2]; + nq[3] = q[3]; +} + +void +add_quats(float q1[4], float q2[4], float dest[4]) +{ + static int count=0; + float t1[4], t2[4], t3[4]; + float tf[4]; + +#if 0 +printf("q1 = %f %f %f %f\n", q1[0], q1[1], q1[2], q1[3]); +printf("q2 = %f %f %f %f\n", q2[0], q2[1], q2[2], q2[3]); +#endif + + vcopy(q1,t1); + vscale(t1,q2[3]); + + vcopy(q2,t2); + vscale(t2,q1[3]); + + vcross(q2,q1,t3); + vadd(t1,t2,tf); + vadd(t3,tf,tf); + tf[3] = q1[3] * q2[3] - vdot(q1,q2); + +#if 0 +printf("tf = %f %f %f %f\n", tf[0], tf[1], tf[2], tf[3]); +#endif + + dest[0] = tf[0]; + dest[1] = tf[1]; + dest[2] = tf[2]; + dest[3] = tf[3]; + + if (++count > RENORMCOUNT) { + count = 0; + normalize_quat(dest); + } +} + +/* + * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0 + * If they don't add up to 1.0, dividing by their magnitued will + * renormalize them. + * + * Note: See the following for more information on quaternions: + * + * - Shoemake, K., Animating rotation with quaternion curves, Computer + * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985. + * - Pletinckx, D., Quaternion calculus as a basic tool in computer + * graphics, The Visual Computer 5, 2-13, 1989. + */ +static void +normalize_quat(float q[4]) +{ + int i; + float mag; + + mag = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); + for (i = 0; i < 4; i++) q[i] /= mag; +} + +/* + * Build a rotation matrix, given a quaternion rotation. + * + */ +void +build_rotmatrix(float m[4][4], float q[4]) +{ + m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]); + m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]); + m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]); + m[0][3] = 0.0; + + m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]); + m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]); + m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]); + m[1][3] = 0.0; + + m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]); + m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]); + m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[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; +} + diff --git a/lib/glut-3.7.6/progs/demos/bounce/trackball.h b/lib/glut-3.7.6/progs/demos/bounce/trackball.h new file mode 100644 index 0000000000..61a1d8c354 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/bounce/trackball.h @@ -0,0 +1,81 @@ +/* + * (c) Copyright 1993, 1994, 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. + */ +/* + * trackball.h + * A virtual trackball implementation + * Written by Gavin Bell for Silicon Graphics, November 1988. + */ + +/* + * Pass the x and y coordinates of the last and current positions of + * the mouse, scaled so they are from (-1.0 ... 1.0). + * + * The resulting rotation is returned as a quaternion rotation in the + * first paramater. + */ +void +trackball(float q[4], float p1x, float p1y, float p2x, float p2y); + +void +negate_quat(float *q, float *qn); + +/* + * Given two quaternions, add them together to get a third quaternion. + * Adding quaternions to get a compound rotation is analagous to adding + * translations to get a compound translation. When incrementally + * adding rotations, the first argument here should be the new + * rotation, the second and third the total rotation (which will be + * over-written with the resulting new total rotation). + */ +void +add_quats(float *q1, float *q2, float *dest); + +/* + * A useful function, builds a rotation matrix in Matrix based on + * given quaternion. + */ +void +build_rotmatrix(float m[4][4], float q[4]); + +/* + * This function computes a quaternion based on an axis (defined by + * the given vector) and an angle about which to rotate. The angle is + * expressed in radians. The result is put into the third argument. + */ +void +axis_to_quat(float a[3], float phi, float q[4]); + diff --git a/lib/glut-3.7.6/progs/demos/chess/Imakefile b/lib/glut-3.7.6/progs/demos/chess/Imakefile new file mode 100644 index 0000000000..ffe65cd2b9 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = chess + +SRCS = chess.c main.c animate.c pathplan.c texture.c + +OBJS = chess.o main.o animate.o pathplan.o texture.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(chess,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/chess/animate.c b/lib/glut-3.7.6/progs/demos/chess/animate.c new file mode 100644 index 0000000000..2375d15d31 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/animate.c @@ -0,0 +1,131 @@ +/* + * animate.c - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +#include +#include +#include +#include "chess.h" + +#define MOVE_FRAC 8 + +int frac; +int stage; +int piece; +int piece2; +int X, Y, NX, NY, XD, YD; +GLfloat CX1, CY1; +GLfloat CX2, CY2, CZ2; + +FILE *inpf = NULL; + +extern int path[10][10]; +extern int board[10][10]; +extern int cycle[10][10], cyclem, cycle2; +extern int stunt[10][10], stuntm, stunt2; + +void read_move(void) +{ + char buf[256]; + + if (!inpf) + inpf = fopen("chess.inp", "r"); + + if (!inpf) + { + fprintf(stderr, "Could not open file chess.inp for reading.\n"); + exit(1); + } + + if (feof(inpf)) + return; + + fgets(buf, 200, inpf); + + CX1 = NX = X = buf[0]-'a'+1; + CY1 = NY = Y = buf[1]-'0'; + CX2 = XD = buf[2]-'a'+1; + CY2 = YD = buf[3]-'0'; + + piece = board[X][Y]; + piece2 = board[XD][YD]; + board[X][Y] = 0; + board[XD][YD] = 0; + solve_path(X, Y, XD, YD); + stage = 0; + frac = 0; + cyclem = cycle[X][Y]; + cycle2 = cycle[XD][YD]; + stuntm = stunt[X][Y]; + stunt2 = stunt[XD][YD]; + switch(path[X][Y]) + { + case NORTH: NY--; break; + case SOUTH: NY++; break; + case WEST: NX--; break; + case EAST: NX++; break; + case NORTHWEST: NX--; NY--; break; + case NORTHEAST: NX++; NY--; break; + case SOUTHWEST: NX--; NY++; break; + case SOUTHEAST: NX++; NY++; break; + } + if (NY == YD && NX == XD) + stage = 1; +} + +void proceed(void) +{ + frac ++; + if (stage == 1) + { + if (piece2 && frac <= MOVE_FRAC * 2) + { + CZ2 = -((GLfloat) frac)/MOVE_FRAC/1.8; + return; + } + frac = 0; + piece2 = 0; + stage ++; + return; + } + else if (stage == 3) + return; + else + CZ2 = 0.0; + + if (frac >= MOVE_FRAC) + { + frac = 0; + X = NX; + Y = NY; + if (NX == XD && NY == YD) + { + board[XD][YD] = piece; + cycle[XD][YD] = cyclem; + stunt[XD][YD] = stuntm; + piece = 0; + read_move(); + return; + } + switch(path[X][Y]) + { + case NORTH: NY--; break; + case SOUTH: NY++; break; + case WEST: NX--; break; + case EAST: NX++; break; + case NORTHWEST: NX--; NY--; break; + case NORTHEAST: NX++; NY--; break; + case SOUTHWEST: NX--; NY++; break; + case SOUTHEAST: NX++; NY++; break; + } + if (NX == XD && NY == YD) + stage ++; + } + CX1 = ((GLfloat) (X*(MOVE_FRAC-frac) + NX*frac))/ MOVE_FRAC; + CY1 = ((GLfloat) (Y*(MOVE_FRAC-frac) + NY*frac))/ MOVE_FRAC; +} diff --git a/lib/glut-3.7.6/progs/demos/chess/chess.c b/lib/glut-3.7.6/progs/demos/chess/chess.c new file mode 100644 index 0000000000..87aee65240 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/chess.c @@ -0,0 +1,995 @@ +/* + * chess.c - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +#include +#include +#include +#include +#include "chess.h" + +#if 0 +/* Uncomment to debug various scenarios. */ +#undef GL_VERSION_1_1 +#undef GL_EXT_texture_object +#undef GL_EXT_texture +#endif + +#ifndef GL_VERSION_1_1 + +#if defined(GL_EXT_texture_object) && defined(GL_EXT_texture) +#define glGenTextures glGenTexturesEXT +#define glBindTexture glBindTextureEXT +#else +#define USE_DISPLAY_LISTS +#endif + +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +int texturing = 0; +int reflection = 0; +int chaos = 0; +int chaosPieces = 0; +int animating = 1; +static GLuint texName[3]; + +extern int path[10][10], piece, piece2; + +extern GLfloat CX1, CY1, CX2, CY2, CZ2; + +#define WIT 0 +#define ZWART 16 + +int board[10][10]; + +GLubyte white_square[TXSX][TXSY][3]; +GLubyte black_square[TXSX][TXSY][3]; +GLubyte wood[TXSX][TXSY][3]; + +extern GLfloat lightpos[]; + +GLfloat buf[256], phase; +GLfloat transl[48]; +int list[48]; + +GLfloat width[144], height[144]; +GLfloat bwidth, bheight; + +int cycle[10][10], cyclem, cycle2; +int stunt[10][10], stuntm, stunt2; + +GLfloat blackamb[4] = { 0.2, 0.1, 0.1, 0.5 }; +GLfloat blackdif[4] = { 0.2, 0.1, 0.0, 0.5 }; +GLfloat blackspec[4] = { 0.5, 0.5, 0.5, 0.5 }; + +GLfloat whiteamb[4] = { 0.7, 0.7, 0.4, 0.5 }; +GLfloat whitedif[4] = { 0.8, 0.7, 0.4, 0.5 }; +GLfloat whitespec[4] = { 0.8, 0.7, 0.4, 0.5 }; + +GLfloat copperamb[4] = { 0.24, 0.2, 0.07, 1.0 }; +GLfloat copperdif[4] = { 0.75, 0.61, 0.22, 1.0 }; +GLfloat copperspec[4] = { 0.32, 0.25, 0.17, 1.0 }; + +GLfloat darkamb[4] = { 0.10, 0.10, 0.10, 1.0 }; +GLfloat darkdif[4] = { 0.6, 0.6, 0.6, 1.0 }; +GLfloat darkspec[4] = { 0.25, 0.25, 0.25, 1.0 }; + +GLdouble ClipPlane[4] = { 0.0, 1.0, 0.0, 0.0 }; + +void white_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, whitedif); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, whiteamb); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, whitespec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); +} + +void black_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blackdif); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, blackamb); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blackspec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); +} + +void copper_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, copperdif); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, copperamb); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, copperspec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); +} + +void dark_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, darkdif); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, darkamb); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, darkspec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.0); +} + +void border_texture(void) +{ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, copperdif); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, copperamb); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, copperspec); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 90.0); +} + +void init_textures(void) +{ +#if !defined(USE_DISPLAY_LISTS) + glGenTextures(3, texName); +#else + texName[0] = 1000; + texName[1] = 1001; + texName[2] = 1002; +#endif + GenerateTextures(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[0]); +#else + glNewList(texName[0], GL_COMPILE); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, + GL_UNSIGNED_BYTE, &wood[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_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +#if defined(USE_DISPLAY_LISTS) + glEndList(); +#endif + +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[1]); +#else + glNewList(texName[1], GL_COMPILE); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, + GL_UNSIGNED_BYTE, &white_square[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_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +#if defined(USE_DISPLAY_LISTS) + glEndList(); +#endif + +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[2]); +#else + glNewList(texName[2], GL_COMPILE); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, 3, TXSX, TXSY, 0, GL_RGB, + GL_UNSIGNED_BYTE, &black_square[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_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +#if defined(USE_DISPLAY_LISTS) + glEndList(); +#endif +} + +void do_border(void) +{ + glPushMatrix(); + glTranslatef(-0.5, 0.0, -0.5); + if (texturing) + { +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[0]); +#else + glCallList(texName[0]); +#endif + glEnable(GL_TEXTURE_2D); + } else + border_texture(); + + glBegin(GL_QUADS); + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.6); glVertex3f(8.5, 0.08, -0.5); + glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, 0.08, -0.5); + + glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.6); glVertex3f(8.5, 0.08, 8.5); + glTexCoord2f(0.0, 0.6); glVertex3f(8.5, 0.08, -0.5); + + glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, 0.08, 8.5); + glTexCoord2f(0.0, 0.6); glVertex3f(8.5, 0.08, 8.5); + + glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, 0.08, -0.5); + glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, 0.08, 8.5); + glEnd(); + + glBegin(GL_QUADS); + glNormal3f(0.0, 0.0, 1.0); + glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.6); glVertex3f(8.0, -0.08, 0.0); + glTexCoord2f(0.0, 0.6); glVertex3f(0.0, -0.08, 0.0); + + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.0); glVertex3f(8.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.6); glVertex3f(8.0, -0.08, 8.0); + glTexCoord2f(0.0, 0.6); glVertex3f(8.0, -0.08, 0.0); + + glNormal3f(0.0, 0.0, 1.0); + glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.6); glVertex3f(0.0, -0.08, 8.0); + glTexCoord2f(0.0, 0.6); glVertex3f(8.0, -0.08, 8.0); + + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.08, 8.0); + glTexCoord2f(0.6, 0.0); glVertex3f(0.0, 0.08, 0.0); + glTexCoord2f(0.6, 0.6); glVertex3f(0.0, -0.08, 0.0); + glTexCoord2f(0.0, 0.6); glVertex3f(0.0, -0.08, 8.0); + glEnd(); + + glBegin(GL_QUADS); + glNormal3f(0.0, 0.0, 1.0); + glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.08, -0.5); + glTexCoord2f(0.6, 0.0); glVertex3f(8.5, 0.08, -0.5); + glTexCoord2f(0.6, 0.6); glVertex3f(8.5, -0.08, -0.5); + glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, -0.08, -0.5); + + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); glVertex3f(8.5, 0.08, -0.5); + glTexCoord2f(0.6, 0.0); glVertex3f(8.5, 0.08, 8.5); + glTexCoord2f(0.6, 0.6); glVertex3f(8.5, -0.08, 8.5); + glTexCoord2f(0.0, 0.6); glVertex3f(8.5, -0.08, -0.5); + + glNormal3f(0.0, 0.0, 1.0); + glTexCoord2f(0.0, 0.0); glVertex3f(8.5, 0.08, 8.5); + glTexCoord2f(0.6, 0.0); glVertex3f(-0.5, 0.08, 8.5); + glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, -0.08, 8.5); + glTexCoord2f(0.0, 0.6); glVertex3f(8.5, -0.08, 8.5); + + glNormal3f(0.0, 1.0, 0.0); + glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.08, 8.5); + glTexCoord2f(0.6, 0.0); glVertex3f(-0.5, 0.08, -0.5); + glTexCoord2f(0.6, 0.6); glVertex3f(-0.5, -0.08, -0.5); + glTexCoord2f(0.0, 0.6); glVertex3f(-0.5, -0.08, 8.5); + glEnd(); + + if (texturing) + glDisable(GL_TEXTURE_2D); + + glPopMatrix(); +} + +void do_vlakje(void) +{ + glColor4f(1.0, 1.0, 1.0, 1.0); + glDisable(GL_LIGHTING); + glPushMatrix(); + glTranslatef(-0.5, 0.0, -0.5); + glBegin(GL_QUADS); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(8.0, 0.0, 0.0); + glVertex3f(8.0, 0.0, 8.0); + glVertex3f(0.0, 0.0, 8.0); + glEnd(); + glPopMatrix(); + glEnable(GL_LIGHTING); +} + +void do_board(void) +{ + int x,y; + + glPushMatrix(); + glTranslatef(-0.5, 0.0, -0.5); + white_texture(); + if (texturing) + { +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[1]); +#else + glCallList(texName[1]); +#endif + glEnable(GL_TEXTURE_2D); + } + + glBegin(GL_QUADS); + glNormal3f(0.0, 1.0, 0.0); + for (x=0;x<8;x++) + { + for (y=x%2;y<8;y+=2) + { + glTexCoord2f(0.2*x, 0.2*y); glVertex3f(x, 0, y); + glTexCoord2f(0.17+0.2*x, 0.2*y); glVertex3f(x+1, 0, y); + glTexCoord2f(0.17+0.2*x, 0.17+0.2*y); glVertex3f(x+1, 0, y+1); + glTexCoord2f(0.2*x, 0.17+0.2*y); glVertex3f(x, 0, y+1); + } + } + glEnd(); + if (texturing) + { + glDisable(GL_TEXTURE_2D); + +#if !defined(USE_DISPLAY_LISTS) + glBindTexture(GL_TEXTURE_2D, texName[2]); +#else + glCallList(texName[2]); +#endif + glEnable(GL_TEXTURE_2D); + } else + black_texture(); + + glBegin(GL_QUADS); + glNormal3f(0.0, 1.0, 0.0); + for (x=0;x<8;x++) + { + for (y=1-(x%2);y<8;y+=2) + { + glTexCoord2f(0.2*x, 0.2*y); glVertex3f(x, 0, y); + glTexCoord2f(0.17+0.2*x, 0.2*y); glVertex3f(x+1, 0, y); + glTexCoord2f(0.17+0.2*x, 0.17+0.2*y); glVertex3f(x+1, 0, y+1); + glTexCoord2f(0.2*x, 0.17+0.2*y); glVertex3f(x, 0, y+1); + } + } + glEnd(); + if (texturing) + glDisable(GL_TEXTURE_2D); + glPopMatrix(); +} + +void do_solid(GLfloat *f, int sz, GLfloat width) +{ + GLfloat nx, ny, s; + GLfloat length; + int i,j; + + for (i=0;i bwidth) + bwidth = buf[i]; +*/ + if (buf[i+1] > bheight) + bheight = buf[i+1]; + } + + glBegin(GL_QUAD_STRIP); + for (i=2;i bwidth) + bwidth = buf[i]; + if (buf[i+1] > bheight) + bheight = buf[i+1]; + } + + for (i=2;i= 0) + (*cl)++; + if (*cl < 0 && ((rand()%300) < 4) && chaos) + { + chaosPieces++; + *cl = 0; + *st = rand() % 6; + } + if (*cl >= 48) { + chaosPieces--; + if (chaosPieces == 0 && !chaos) { + if (!animating && (speed == 0)) + glutIdleFunc(NULL); + } + *cl = -1; + } + + if (*cl < 0) + { + glPushMatrix(); + glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); + if (color == ZWART && pc == PAARD) + glRotatef(180.0, 0.0, 1.0, 0.0); + glScalef(1.2, 1.2, 1.2); + glCallList(pc+list[0]); + glPopMatrix(); + return; + } + + glPushMatrix(); + switch (*st) + { + case 0: + glTranslatef(x - 1.0, transl[(*cl)>=0?*cl:0] + + ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); + if (color == ZWART && pc == PAARD) + glRotatef(180.0, 0.0, 1.0, 0.0); + glScalef(1.2, 1.2, 1.2); + glCallList(list[(*cl)>=0?*cl:0]+pc); + break; + case 1: + case 2: + glTranslatef(x - 1.0, transl[(*cl)>=0?*cl:0] + + ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); + if (color == ZWART && pc == PAARD) + glRotatef(180.0, 0.0, 1.0, 0.0); + if ((*cl > 16) && (*cl < 32)) + { + glTranslatef(0.0, height[list[*cl]+pc]/2, 0.0); + if (*st == 1) + glRotatef(((*cl)-16) * 22.5, 1.0, 0.0, 0.0); + else + glRotatef(-((*cl)-16) * 22.5, 1.0, 0.0, 0.0); + glTranslatef(0.0, -height[list[*cl]+pc]/2, 0.0); + } + glScalef(1.2, 1.2, 1.2); + glCallList(list[*cl]+pc); + break; + case 3: + glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); + if (color == ZWART && pc == PAARD) + glRotatef(180.0, 0.0, 1.0, 0.0); + a = ((GLfloat) (*cl)) * M_PI / 12; + s = sin(a); + glRotatef(15*s, 0.0, 0.0, 1.0); + glTranslatef(0.0, width[list[0]+pc]*s*s, 0.0); + glScalef(1.2, 1.2, 1.2); + glCallList(list[0] + pc); + break; + default: + glTranslatef(x - 1.0, ((x==CX2 && y==CY2)?CZ2:0.0), 8.0 - y); + if (color == ZWART && pc == PAARD) + glRotatef(180.0, 0.0, 1.0, 0.0); + a = ((GLfloat) (*cl)) * M_PI / 12; + s = sin(a); + glRotatef(15*s, 0.0, 0.0, 1.0); + glRotatef((*cl) * 30, 0.0, 1.0, 0.0); + glTranslatef(0.0, width[list[0]+pc]*s*s, 0.0); + glScalef(1.2, 1.2, 1.2); + glCallList(list[0]+pc); + break; + } + glPopMatrix(); +} + +void do_pieces(void) +{ + int i,j; + + copper_texture(); + for (i=0;i<10;i++) + { + for (j=0;j<10;j++) + { + if (board[i][j]&16 || !(board[i][j]&15)) + continue; + do_piece(board[i][j]&15, i, j, &stunt[i][j], &cycle[i][j], WIT); + } + } + + if ((piece&16) == WIT && piece > 0) + { + glPushMatrix(); + glTranslatef(0.0, 0.2, 0.0); + do_piece(piece&15, CX1, CY1, &stuntm, &cyclem, WIT); + glPopMatrix(); + } + + if ((piece2&16) == WIT && piece2 > 0) + do_piece(piece2&15, CX2, CY1, &stunt2, &cycle2, WIT); + + dark_texture(); + for (i=0;i<10;i++) + { + for (j=0;j<10;j++) + { + if (!(board[i][j]&16) || !board[i][j]) + continue; + do_piece(board[i][j]&15, i, j, &stunt[i][j], &cycle[i][j], ZWART); + } + } + + if ((piece&16) == ZWART && piece > 0) + { + glPushMatrix(); + glTranslatef(0.0, 0.2, 0.0); + do_piece(piece&15, CX1, CY1, &stuntm, &cyclem, ZWART); + glPopMatrix(); + } + + if ((piece2&16) == ZWART && piece2 > 0) + do_piece(piece2&15, CX2, CY2, &stunt2, &cycle2, ZWART); +} + +void do_display(void) +{ + glDisable(GL_DEPTH_TEST); + /* glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); */ + if (reflection) { + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 1, 0xffffffff); + } + do_vlakje(); + glEnable(GL_DEPTH_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + if (reflection) + { + glStencilFunc(GL_EQUAL, 1, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + glPushMatrix(); + glScalef(1.0, -1.0, 1.0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glClipPlane(GL_CLIP_PLANE1, ClipPlane); + glEnable(GL_CLIP_PLANE1); + do_pieces(); + glPopMatrix(); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_STENCIL_TEST); + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + } + +/* + * Also without texturing I want to blend, to keep the contrast of the board + * consistent. + */ + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + do_board(); + + glDisable(GL_BLEND); + + do_border(); + + glClipPlane(GL_CLIP_PLANE1, ClipPlane); + glEnable(GL_CLIP_PLANE1); + do_pieces(); + glDisable(GL_CLIP_PLANE1); +} diff --git a/lib/glut-3.7.6/progs/demos/chess/chess.dsp b/lib/glut-3.7.6/progs/demos/chess/chess.dsp new file mode 100644 index 0000000000..0657d0c5fb --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/chess.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="chess" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=chess - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "chess.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "chess.mak" CFG="chess - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "chess - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "chess - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "chess - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "chess - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "chess - Win32 Release" +# Name "chess - Win32 Debug" +# Begin Source File + +SOURCE=.\animate.c +# End Source File +# Begin Source File + +SOURCE=.\chess.c +# End Source File +# Begin Source File + +SOURCE=.\chess.h +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\pathplan.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/chess/chess.h b/lib/glut-3.7.6/progs/demos/chess/chess.h new file mode 100644 index 0000000000..4347d132ce --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/chess.h @@ -0,0 +1,36 @@ +/* + * chess.h - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +#define PION 1 +#define TOREN 2 +#define PAARD 3 +#define LOPER 4 +#define KONING 5 +#define DAME 6 + +#define NORTH 1 +#define SOUTH 2 +#define EAST 3 +#define WEST 4 +#define NORTHWEST 5 +#define NORTHEAST 6 +#define SOUTHWEST 7 +#define SOUTHEAST 8 + +#define ACC 8 +#define TXSX 128 +#define TXSY 128 + +extern void GenerateTextures(void); +extern void read_move(void); +extern int solve_path(int x1, int y1, int x2, int y2); +extern void proceed(void); +extern void init(void); +extern void do_display(void); +extern void init_lists(void); diff --git a/lib/glut-3.7.6/progs/demos/chess/chess.inp b/lib/glut-3.7.6/progs/demos/chess/chess.inp new file mode 100644 index 0000000000..f4e91be526 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/chess.inp @@ -0,0 +1,62 @@ +d2d4 +g8f6 +c2c4 +g7g6 +b1c3 +f8g7 +e2e4 +d7d6 +f2f3 +e8g8 +h8f8 +c1e3 +c7c6 +f1d3 +a7a6 +g1e2 +b7b5 +e1g1 +h1f1 +b8d7 +a1c1 +e7e5 +a2a3 +e5d4 +e2d4 +c8b7 +c4b5 +c6b5 +f1e1 +d7e5 +d3f1 +f8e8 +e3f2 +d6d5 +e4d5 +f6d5 +c3d5 +d8d5 +a3a4 +g7h6 +c1a1 +e5c4 +a4b5 +a6b5 +a1a8 +e8a8 +d1b3 +b7c6 +f1d3 +c4d6 +b3d5 +c6d5 +d4b5 +d6b5 +d3b5 +h6g7 +b2b4 +g7c3 +e1d1 +d5b3 +d1b1 +b3a2 diff --git a/lib/glut-3.7.6/progs/demos/chess/main.c b/lib/glut-3.7.6/progs/demos/chess/main.c new file mode 100644 index 0000000000..fa0bc7db46 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/main.c @@ -0,0 +1,200 @@ +/* + * main.c - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +#include +#include +#include + +#include "chess.h" + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define M_TEXTURING 1 +#define M_REFLECTION 2 +#define M_CHAOS 3 +#define M_ANIMATION 4 + +extern int reflection, texturing, animating, chaos; + +GLfloat lightpos[4] = { 2.0, 1.0, 1.0, 0.0 }; +GLfloat lightamb[4] = { 1.0, 1.0, 1.0, 1.0 }; +GLfloat lightdif[4] = { 1.0, 1.0, 1.0, 1.0 }; + +float angle = 0.0, a2 = 45.0; +int speed = 0; +GLfloat px = -3.5, py = -16.5, pz = 9.5; + +void SetCamera(void) +{ + gluLookAt(0.0,2.0,2.0, 0.0,2.0,0.0, 0.0,1.0,0.0); + glRotatef(a2, 1.0, 0.0, 0.0); + glRotatef(angle, 0.0, 1.0, 0.0); + glTranslatef(px, -pz, py); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); +} + +void display(void) +{ + glLoadIdentity(); + SetCamera(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + do_display(); + glutSwapBuffers(); +} + +void myinit(void) +{ + glShadeModel (GL_SMOOTH); + glFrontFace(GL_CCW); + glEnable(GL_DEPTH_TEST); + + glLoadIdentity(); + glClearColor(0.0, 0.0, 0.0, 1.0); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightdif); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + init_lists(); +} + +void Animate(void) +{ + px -= speed * 0.02 * sin(angle*M_PI/180); + py += speed * 0.02 * cos(angle*M_PI/180); + if (animating) + proceed(); + glutPostRedisplay(); +} + +extern int chaosPieces; + +/* ARGSUSED1 */ +void parsekey(unsigned char key, int x, int y) +{ + switch (key) + { + case 27: exit(0); + case 13: speed = 0; break; + case 'a': a2 += 5; break; + case 'z': a2 -= 5; break; + case 'A': pz += 0.5; break; + case 'Z': pz -= 0.5; break; + default: + return; + } + glutPostRedisplay(); + if (animating || (chaosPieces > 0) || (speed != 0)) + glutIdleFunc(Animate); + else + glutIdleFunc(NULL); +} + +/* ARGSUSED1 */ +void parsekey_special(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP: speed += 1; break; + case GLUT_KEY_DOWN: speed -= 1; break; + case GLUT_KEY_RIGHT: angle += 5; break; + case GLUT_KEY_LEFT: angle -= 5; break; + case GLUT_KEY_HOME: + angle = 0.0, a2 = 45.0; + speed = 0; + px = -3.5, py = -16.5, pz = 9.5; + break; + default: + return; + } + glutPostRedisplay(); + if (animating || (chaosPieces > 0) || (speed != 0)) + glutIdleFunc(Animate); + else + glutIdleFunc(NULL); +} + +void handle_main_menu(int item) +{ + switch(item) { + case M_REFLECTION: + reflection = !reflection; + glutPostRedisplay(); + break; + case M_TEXTURING: + texturing = !texturing; + glutPostRedisplay(); + break; + case M_ANIMATION: + animating = !animating; + if (animating || (chaosPieces > 0) || (speed != 0)) + glutIdleFunc(Animate); + else + glutIdleFunc(NULL); + break; + case M_CHAOS: + chaos = !chaos; + if (animating || chaos || (speed != 0)) + glutIdleFunc(Animate); + break; + } +} + +void +Visible(int visible) +{ + if (visible == GLUT_VISIBLE) { + if (animating || (chaosPieces > 0) || (speed != 0)) + glutIdleFunc(Animate); + } else { + glutIdleFunc(NULL); + } +} + +void myReshape(int w, int h) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum (-0.1, 0.1, -0.1, 0.1, 0.3, 200.0); + glMatrixMode (GL_MODELVIEW); + glViewport(0, 0, w, h); + glLoadIdentity(); + SetCamera(); +} + +int main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE | GLUT_STENCIL); + glutCreateWindow("Chess"); + glutDisplayFunc(display); + glutInitWindowPosition(200, 0); + glutInitWindowSize(300, 300); + glutKeyboardFunc(parsekey); + glutSpecialFunc(parsekey_special); + glutReshapeFunc(myReshape); + glutVisibilityFunc(Visible); + myinit(); + + glutCreateMenu(handle_main_menu); + glutAddMenuEntry("Toggle texturing", M_TEXTURING); + glutAddMenuEntry("Toggle reflection", M_REFLECTION); + glutAddMenuEntry("-----------------", -1); + glutAddMenuEntry("Toggle animation", M_ANIMATION); + glutAddMenuEntry("Toggle CHAOS!", M_CHAOS); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutSwapBuffers(); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/chess/pathplan.c b/lib/glut-3.7.6/progs/demos/chess/pathplan.c new file mode 100644 index 0000000000..8feeb44062 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/pathplan.c @@ -0,0 +1,85 @@ +/* + * pathplan.c - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +#include "chess.h" + +extern int board[10][10]; + +int path[10][10]; +int hops[10][10]; + +int steps; +int cur_hops; + +void init_board(void) +{ + int i,j; + for (i=0;i<10;i++) + { + for(j=0;j<10;j++) + { + hops[i][j] = 0; + path[i][j] = (board[i][j]?-1:0); + } + } +} + +void test_exit(int i, int j, int dir) +{ + if (i<0 || i>9 || j<0 || j>9) + return; + if (path[i][j]) + return; + steps ++; + path[i][j] = dir; + hops[i][j] = cur_hops + 1; +} + +int solve_path(int x1, int y1, int x2, int y2) +{ + int i,j; + init_board(); + path[x2][y2] = 9; + hops[x2][y2] = 1; + path[x1][y1] = 0; + cur_hops = 1; + for (;;) + { + steps = 0; + for (i=0;i<10;i++) + { + for (j=0;j<10;j++) + { + if (hops[i][j] != cur_hops) + continue; + test_exit(i, j-1, SOUTH); + test_exit(i, j+1, NORTH); + test_exit(i-1, j, EAST); + test_exit(i+1, j, WEST); + } + } + for (i=0;i<10;i++) + { + for (j=0;j<10;j++) + { + if (hops[i][j] != cur_hops) + continue; + test_exit(i-1, j-1, SOUTHEAST); + test_exit(i+1, j-1, SOUTHWEST); + test_exit(i-1, j+1, NORTHEAST); + test_exit(i+1, j+1, NORTHWEST); + } + } + cur_hops++; + if (path[x1][y1]) + return 1; + if (steps == 0) + return 0; + } +} diff --git a/lib/glut-3.7.6/progs/demos/chess/texture.c b/lib/glut-3.7.6/progs/demos/chess/texture.c new file mode 100644 index 0000000000..4c78a0eb10 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/chess/texture.c @@ -0,0 +1,203 @@ +/* + * chess.c - part of the chess demo in the glut distribution. + * + * (C) Henk Kok (kok@wins.uva.nl) + * + * This file can be freely copied, changed, redistributed, etc. as long as + * this copyright notice stays intact. + */ + +/* + * Marble texture - shamelessly ripped from siggraph92_C23.shar + */ + +#include +#include +#include +#include +#include "chess.h" + +#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 GLfloat g[B + B + 2][3]; +static int start = 1; + +#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.; + +GLfloat noise3(GLfloat vec[3]) +{ + int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; + GLfloat rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; + register int i, j; + + if (start) { + start = 0; + init(); + } + + 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 +init(void) +{ + int i, j, k; + GLfloat v[3], s; + +/* Create an array of random gradient vectors uniformly on the unit sphere */ + + srand(1); + for (i = 0 ; i < B ; i++) { + do { /* Choose uniformly in a cube */ + for (j=0 ; j<3 ; j++) + v[j] = (GLfloat)((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]; + } +} + +GLfloat turbulence(GLfloat x, GLfloat y, GLfloat z, GLfloat lofreq, GLfloat hifreq) +{ + GLfloat freq, t, p[3]; + + p[0] = x + 123.456; + p[1] = y; + p[2] = z; + + 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 */ +} + +GLfloat marble(GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat m; + m = turbulence(x, y, z, 0.3, 400.0); + if (m > 1.0) + m = 1.0; + if (m < 0.0) + m = 0.0; + return m; +} + +extern GLubyte white_square[TXSX][TXSY][3]; +extern GLubyte black_square[TXSX][TXSY][3]; +extern GLubyte wood[TXSX][TXSY][3]; + +void GenerateTextures(void) +{ + int i,j,k; + GLfloat x,y,t,w,b; + for (i=0;i 1.0) + t = 1.0; + + wood[i][j][0] = (0.6*t)*255; + wood[i][j][1] = (0.4*t)*255; + wood[i][j][2] = (0.5-0.4*t)*255; + + x = ((GLfloat) i)/20.0; + y = ((GLfloat) j)/20.0; + t = marble(x, y, 0.0); + + t = 0.2 + t; + if (t > 1.0) + t = 1.0; + + w = t; + b = 0.8 -t; + if (b < 0.0 ) + b = 0.0; + + for (k=0;k<3;k++) + { + white_square[i][j][k] = w*255; + black_square[i][TXSY-j][k] = b*255; + } + } + } +} diff --git a/lib/glut-3.7.6/progs/demos/geoface/Imakefile b/lib/glut-3.7.6/progs/demos/geoface/Imakefile new file mode 100644 index 0000000000..30214a6cab --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/Imakefile @@ -0,0 +1,15 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +#include "../../../Glut.cf" + +TARGETS = geoface + +SRCS = display.c fileio.c main.c make_face.c muscle.c +OBJS = display.o fileio.o main.o make_face.o muscle.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(geoface,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/geoface/README b/lib/glut-3.7.6/progs/demos/geoface/README new file mode 100644 index 0000000000..329c5ac4f1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/README @@ -0,0 +1,32 @@ + +The geoface example in this directory is a modified version of the code +presented in Appendix 1 of Frederic I Parke and Keith Waters's most +interesting book "Computer Facial Animation" (A.K. Peters, ISBN +1-56881-014-8). Information about the book can be found at: + + http://www.research.digital.com/CRL/personal/waters/book.html + +From the book's Preface: + + This book is about computer facial models, computer generated facial + images, and facial animation. In particular it concerns the + principles of creating face models and the manipulation or control of + computer generated facial attributes. In addition, various sections + in the book describe and explain the development of specific computer + facial animation techniques over the past twenty years, as well as + those expected in the near future. + +The original Appendix 1 code (using the aux library) can be found at: + + http://www.research.digital.com/CRL/books/facebook/appendix1/appendix1.html + +I've improved the code to add menus, better mouse motion handling, +arrow key support, and less terminal output. + +DEC has a program called DECface that looks even more involved: + + http://www.research.digital.com/CRL/projects/DECface/DECface.html + +If the example here intrigues you, you'll definitely want the book. + +- Mark Kilgard diff --git a/lib/glut-3.7.6/progs/demos/geoface/display.c b/lib/glut-3.7.6/progs/demos/geoface/display.c new file mode 100644 index 0000000000..223d6fc9ce --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/display.c @@ -0,0 +1,313 @@ +/* ========================================================================== + DISPLAY_C +============================================================================= + + FUNCTION NAMES + + void paint_muscles -- displays the muscles. + void paint_polyline -- paint the polyline. + paint_polygons -- display the polygons. + calculate_polygon_vertex_normal -- calculate the vertex norms. + calc_normal -- calculate a normal. + + C SPECIFICATIONS + + void paint_muscles ( HEAD *face ) + void paint_polyline ( HEAD *face ) + paint_polygons ( HEAD *face, int type, int normals ) + calculate_polygon_vertex_normal ( HEAD *face ) + calc_normal ( float *p1, float *p2, float *p3, + float *norm ) + + DESCRIPTION + + This module is responsible for displaying the face geometry. + This module comes as is with no warranties. + + HISTORY + 16-Dec-94 Keith Waters (waters) at DEC's Cambridge Research Lab + Created. + +============================================================================ */ + +#include /* C header for any math functions */ +#include /* C header for standard I/O */ +#include /* For String compare */ +#include +#ifndef _WIN32 +#include +#include +#endif +#include /* OpenGl headers */ + +#include "head.h" /* local header for the face */ + +void calc_normal ( float *p1, float *p2, float *p3, float *norm ); + +/* ========================================================================= */ +/* paint_muscles */ +/* ========================================================================= */ +/* +** Displays the face muscles. +** +*/ + +#define PAINT_MUSCLES_DEBUG 0 +void paint_muscles ( HEAD *face ) +{ + int i,j; + float v1[3], v2[3] ; + + glLineWidth ( 3.0 ) ; + glColor3f ( 100.0, 200.0, 200.0 ) ; + + for ( i=0; inmuscles; i++ ) { + + for (j=0; j<3; j++) { + v1[j] = face->muscle[i]->head[j] ; + v2[j] = face->muscle[i]->tail[j] ; + } + +#if PAINT_MUSCLES_DEBUG + fprintf (stderr, "head x: %f y: %f z: %f\n", v1[0], v1[1], v1[2] ) ; + fprintf (stderr, "tail x: %f y: %f z: %f\n\n", v2[0], v2[1], v2[2] ) ; +#endif + + glBegin ( GL_LINE_STRIP ) ; + glVertex3f ( v1[0], v1[1], v1[2] ) ; + glVertex3f ( v2[0], v2[1], v2[2] ) ; + glEnd ( ) ; + } + glLineWidth ( 1.0 ) ; +} + +/* ========================================================================= */ +/* paint_polyline */ +/* ========================================================================= */ +/* +** Displays the polyline. +** +*/ + +void paint_polyline ( HEAD *face ) +{ + int i,j,cnt ; + float v1[3] ; + static float r ; + + glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; + glLineWidth ( 1.0 ) ; + glColor3f ( 100.0, 100.0, 0.0 ) ; + + glPushMatrix ( ) ; + glRotatef ( r, 1.0, 1.0, 1.0 ) ; + + glBegin ( GL_LINE_STRIP ) ; + for (cnt=0, i=0; inpolylinenodes; i++ ) { + + for (j=0; j<3; j++, cnt++) + v1[j] = face->polyline[cnt] ; + +#if PAINT_POLYLINE_DEBUG + printf ("x: %f y: %f z: %f\n", v1[0], v1[1], v1[2] ) ; +#endif + + glVertex3f ( v1[0], v1[1], v1[2] ) ; + } + + glEnd ( ) ; + + glPopMatrix ( ) ; + glFlush ( ) ; + +} + + +/* ========================================================================= */ +/* paint_polygons */ +/* ========================================================================= */ +/* +** Paints the polygons of the face. +** Type indicates if they are to be +** drawn (type=0), +** flat shaded (type=1), +** smooth shaded (type=2). +*/ + +void paint_polygons ( HEAD *face, int type, int normals ) +{ + int i, j ; + float v1[3], v2[3], v3[3] ; + float norm1[3], norm2[3], norm3[3] ; + float vn1[3], vn2[3], vn3[3] ; + + glLineWidth ( 2.0 ) ; + + for (i=0; inpolygons; i++ ) + { + for (j=0; j<3; j++) { + v1[j] = face->polygon[i]->vertex[0]->xyz[j] ; + v2[j] = face->polygon[i]->vertex[1]->xyz[j] ; + v3[j] = face->polygon[i]->vertex[2]->xyz[j] ; + } + + if ( type == 0 ) { + + for (j=0; j<3; j++) { + norm1[j] = face->polygon[i]->vertex[0]->norm[j] ; + norm2[j] = face->polygon[i]->vertex[1]->norm[j] ; + norm3[j] = face->polygon[i]->vertex[2]->norm[j] ; + } + glBegin ( GL_LINE_LOOP ) ; { + glNormal3f ( norm1[0], norm1[1], norm1[2] ) ; + glVertex3f ( v1[0], v1[1], v1[2] ) ; + glNormal3f ( norm2[0], norm2[1], norm2[2] ) ; + glVertex3f ( v2[0], v2[1], v2[2] ) ; + glNormal3f ( norm3[0], norm3[1], norm3[2] ) ; + glVertex3f ( v3[0], v3[1], v3[2] ) ; + } glEnd ( ) ; + + } /* end if drawn */ + + if ( type == 1 ) { + + for (j=0; j<3; j++) { + norm1[j] = face->polygon[i]->vertex[0]->norm[j] ; + norm2[j] = face->polygon[i]->vertex[1]->norm[j] ; + norm3[j] = face->polygon[i]->vertex[2]->norm[j] ; + } + glBegin ( GL_TRIANGLES ) ; { + glNormal3f ( norm1[0], norm1[1], norm1[2] ) ; + glVertex3f ( v1[0], v1[1], v1[2] ) ; + glNormal3f ( norm2[0], norm2[1], norm2[2] ) ; + glVertex3f ( v2[0], v2[1], v2[2] ) ; + glNormal3f ( norm3[0], norm3[1], norm3[2] ) ; + glVertex3f ( v3[0], v3[1], v3[2] ) ; + } glEnd ( ) ; + + } /* end if drawn */ + + + else if ( type == 1) { + for (j=0; j<3; j++) { + norm1[j] = face->polygon[i]->vertex[0]->norm[j] ; + norm2[j] = face->polygon[i]->vertex[1]->norm[j] ; + norm3[j] = face->polygon[i]->vertex[2]->norm[j] ; + } + } /* end if flat */ + + else if ( type == 2 ) { + + averaged_vertex_normals ( face, i, norm1, norm2, norm3 ) ; + + } /* end if smoothed */ + + if ( type ) { + + glBegin ( GL_TRIANGLES ) ; { + glNormal3f ( norm1[0], norm1[1], norm1[2] ) ; + glVertex3f ( v1[0], v1[1], v1[2] ) ; + glNormal3f ( norm2[0], norm2[1], norm2[2] ) ; + glVertex3f ( v2[0], v2[1], v2[2] ) ; + glNormal3f ( norm3[0], norm3[1], norm3[2] ) ; + glVertex3f ( v3[0], v3[1], v3[2] ) ; + } glEnd ( ) ; + } /* endif painted */ + + if ( normals ) { + for (j=0; j<3; j++) { + vn1[j] = face->polygon[i]->vertex[0]->xyz[j] + norm1[j] ; + vn2[j] = face->polygon[i]->vertex[1]->xyz[j] + norm2[j] ; + vn3[j] = face->polygon[i]->vertex[2]->xyz[j] + norm3[j] ; + } + + glBegin ( GL_LINE_STRIP ) ; { + glVertex3f ( v1[0], v1[1], v1[2] ) ; + glVertex3f ( vn1[0], vn1[1], vn1[2] ) ; + } glEnd ( ) ; + + + glBegin ( GL_LINES ) ; { + glVertex3f ( v2[0], v2[1], v2[2] ) ; + glVertex3f ( vn2[0], vn2[1], vn2[2] ) ; + } glEnd ( ) ; + + + glBegin ( GL_LINES ) ; { + glVertex3f ( v3[0], v3[1], v3[2] ) ; + glVertex3f ( vn3[0], vn3[1], vn3[2] ) ; + } glEnd ( ) ; + + } + } + glLineWidth ( 1.0 ) ; +} + +/* ========================================================================= */ +/* calculate_polygon_vertex_normal. */ +/* ========================================================================= */ +/* +** As it says. +*/ + +void +calculate_polygon_vertex_normal ( HEAD *face ) +{ + int i,j,k ; + float p1[3], p2[3], p3[3] ; + float norm[3] ; + for (i=0; inpolygons; i++ ) + { + for (j=0; j<3; j++) + p1[j] = face->polygon[i]->vertex[0]->xyz[j] ; + for (j=0; j<3; j++) + p2[j] = face->polygon[i]->vertex[1]->xyz[j] ; + for (j=0; j<3; j++) + p3[j] = face->polygon[i]->vertex[2]->xyz[j] ; + + calc_normal ( p1, p2, p3, norm ) ; + + for (j=0; j<3; j++) + for (k=0; k<3; k++) + face->polygon[i]->vertex[j]->norm[k] = norm[k] ; + } +} + +/* ========================================================================= */ +/* calc_normal. */ +/* ========================================================================= */ +/* +** Calculates the normal vector from three vertices. +*/ +void +calc_normal ( float *p1, float *p2, float *p3, float *norm ) +{ + float coa, cob, coc ; + float px1, py1, pz1 ; + float px2, py2, pz2 ; + float px3, py3, pz3 ; + + float absvec ; + + px1 = p1[0] ; + py1 = p1[1] ; + pz1 = p1[2] ; + + px2 = p2[0] ; + py2 = p2[1] ; + pz2 = p2[2] ; + + px3 = p3[0] ; + py3 = p3[1] ; + pz3 = p3[2] ; + + coa = -(py1 * (pz2-pz3) + py2*(pz3-pz1) + py3*(pz1-pz2)) ; + cob = -(pz1 * (px2-px3) + pz2*(px3-px1) + pz3*(px1-px2)) ; + coc = -(px1 * (py2-py3) + px2*(py3-py1) + px3*(py1-py2)) ; + + absvec = sqrt ((double) ((coa*coa) + (cob*cob) + (coc*coc))) ; + + norm[0] = coa/absvec ; + norm[1] = cob/absvec ; + norm[2] = coc/absvec ; +} diff --git a/lib/glut-3.7.6/progs/demos/geoface/faceline.dat b/lib/glut-3.7.6/progs/demos/geoface/faceline.dat new file mode 100644 index 0000000000..0a4a26dc06 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/faceline.dat @@ -0,0 +1,257 @@ +256 + 0.000 -2.280 8.875 + 0.000 -2.456 8.980 + 0.000 -2.701 9.005 + -0.509 -2.230 8.865 + -0.577 -2.414 8.962 + -0.585 -2.670 8.987 + -1.027 -2.201 8.544 + -1.135 -2.372 8.658 + -1.182 -2.556 8.657 + -1.570 -2.221 8.025 + -1.805 -2.354 8.037 + -1.151 -3.134 8.433 + -0.565 -3.181 8.583 + 0.000 -3.216 8.631 + 0.000 -3.545 8.640 + -0.582 -3.517 8.557 + -1.158 -3.443 8.329 + -1.999 -2.568 7.895 + -2.121 -2.222 7.917 + -2.395 -2.073 7.692 + -2.213 -2.797 7.639 + -1.358 -3.775 8.198 + -0.837 -3.880 8.520 + -0.590 -3.910 8.645 + 0.000 -3.914 8.646 + 0.000 -4.564 8.583 + -0.700 -4.532 8.584 + -1.058 -4.461 8.459 + -1.579 -4.290 8.085 + -1.995 -3.660 7.538 + -2.572 -2.969 7.100 + -2.746 -1.859 7.124 + -2.990 -1.690 6.640 + -2.751 -3.033 6.688 + -2.147 -4.156 7.145 + -1.620 -4.770 7.945 + -1.081 -4.944 8.281 + -0.699 -4.994 8.360 + 0.000 -5.021 8.360 + 0.000 -5.412 7.852 + -0.602 -5.444 7.853 + -0.990 -5.418 7.854 + -1.597 -5.169 7.416 + -2.342 -4.202 6.524 + -3.374 -1.344 5.866 + -3.118 -3.043 5.708 + -2.559 -4.377 5.351 + -1.600 -5.205 6.353 + -0.945 -5.501 6.834 + -0.542 -5.601 7.067 + 0.000 -5.636 7.068 + -3.232 -3.283 3.861 + -3.686 -2.281 4.257 + -3.797 -0.831 4.703 + -4.136 -0.236 3.398 + -4.093 -1.041 3.153 + -3.959 -1.660 2.889 + -4.295 0.021 2.170 + -3.485 -2.252 2.286 + -2.740 -3.866 3.388 + -2.315 -4.570 4.819 + -0.966 -5.443 4.589 + -0.556 -5.511 4.589 + 0.000 -5.553 4.589 + 0.000 -7.061 3.726 + -0.436 -6.971 3.553 + -0.926 -6.872 3.196 + -2.414 -4.428 2.801 + -3.120 -3.336 1.701 + -3.204 -2.934 1.002 + -3.120 -5.511 0.149 + -3.119 -5.510 0.702 + -2.343 -6.297 1.993 + -2.389 -6.885 1.708 + -1.053 -8.199 2.359 + -0.336 -8.622 2.554 + 0.000 -8.714 2.559 + 0.000 -2.278 8.878 + 0.000 -2.064 9.078 + 0.000 -1.830 9.119 + -0.484 -1.720 9.116 + -0.512 -2.003 9.070 + -0.521 -2.231 8.876 + -1.170 -1.928 9.000 + -1.083 -2.093 8.703 + -1.032 -2.198 8.549 + -1.773 -2.057 8.299 + -1.572 -2.217 8.022 + -2.039 -1.735 8.072 + -1.285 -1.456 8.655 + -0.456 -1.314 8.986 + 0.000 -1.461 8.920 + 0.000 -0.710 8.876 + -0.237 -0.648 8.971 + -0.446 -0.648 8.971 + -1.316 -0.911 8.428 + -2.206 -1.333 7.855 + -2.274 -1.067 7.654 + -1.276 -0.534 8.239 + -0.753 -0.441 8.580 + -0.534 -0.074 8.714 + -0.191 -0.056 9.150 + -0.171 -0.426 9.051 + 0.000 -0.441 9.053 + 0.000 -0.232 9.570 + -0.168 -0.224 9.570 + -0.560 0.058 9.376 + -0.767 0.046 9.042 + -0.843 -0.128 8.806 + -0.978 -0.276 8.684 + -1.091 -0.204 8.513 + -0.905 -0.325 8.292 + -1.320 -0.188 8.010 + -0.895 0.194 8.202 + -1.002 0.217 8.462 + -1.077 0.307 8.703 + -1.017 0.325 8.904 + -0.900 0.099 9.033 + -0.574 0.252 9.485 + -0.118 -0.099 9.722 + 0.000 -0.098 9.723 + 0.000 0.512 9.855 + -0.158 0.508 9.820 + -0.587 0.550 9.557 + -0.660 0.776 9.277 + -0.242 1.137 9.532 + -0.208 0.854 9.713 + 0.000 0.862 9.749 + 0.000 1.192 9.559 + 0.000 1.445 9.385 + -0.250 1.387 9.361 + -0.495 1.190 9.132 + -0.526 1.443 8.894 + -0.284 1.740 9.158 + 0.000 1.817 9.200 + 0.000 2.180 8.995 + -0.322 2.100 8.927 + -0.667 1.571 8.598 + -1.312 0.849 8.093 + -2.093 0.282 7.775 + -2.327 -0.805 7.560 + -3.108 -0.078 7.267 + -3.182 0.649 7.412 + -3.805 0.868 6.790 + -4.108 1.022 5.942 + -4.360 1.772 4.387 + -4.187 2.611 4.596 + -4.028 1.464 6.118 + -3.708 2.236 6.211 + -3.359 1.693 6.896 + -2.876 1.352 7.271 + -2.100 1.207 7.559 + -1.337 1.263 8.027 + -1.270 1.664 7.809 + -0.723 2.023 8.332 + -0.357 2.487 8.669 + 0.000 2.608 8.699 + 0.000 2.909 8.460 + -0.392 2.825 8.420 + -0.623 2.411 8.173 + -0.853 2.189 7.760 + -1.119 2.259 7.352 + -1.460 1.887 7.332 + -2.095 1.531 7.388 + -2.765 1.605 7.294 + -3.156 1.949 6.974 + -3.399 2.397 6.443 + -3.657 2.603 6.413 + -3.904 2.477 5.990 + -4.092 1.936 5.653 + -3.994 2.776 5.641 + -4.121 3.106 4.611 + -4.105 3.756 4.772 + -3.883 2.972 6.298 + -3.928 4.609 5.060 + -3.866 3.453 6.724 + -3.788 3.260 6.846 + -3.556 2.930 6.956 + -3.201 2.669 6.903 + -3.001 2.353 7.274 + -2.571 2.177 7.578 + -2.113 2.147 7.561 + -1.602 2.246 7.687 + -1.210 2.404 7.438 + -0.967 2.609 7.023 + -0.638 2.684 7.661 + -0.584 3.052 8.055 + -0.431 3.211 8.189 + 0.000 3.262 8.208 + 0.000 3.664 8.101 + -0.487 3.639 8.101 + -0.760 3.420 7.947 + -0.829 3.210 7.554 + -1.006 2.963 7.129 + -1.309 3.290 7.370 + -1.772 3.474 7.615 + -2.268 3.493 7.824 + -2.704 3.315 7.781 + -3.129 3.065 7.391 + -3.421 3.337 7.438 + -3.624 3.650 7.348 + -3.730 3.872 7.238 + -3.285 4.274 7.783 + -2.569 4.558 8.182 + -1.841 4.676 8.353 + -1.067 4.327 8.469 + -1.150 4.072 8.222 + -1.853 4.265 8.296 + -2.509 4.191 8.259 + -3.195 3.970 7.895 + -2.963 3.637 7.879 + -2.381 3.830 8.100 + -1.782 3.850 8.071 + -1.227 3.657 8.072 + -0.450 4.377 8.175 + -0.991 4.862 8.093 + -1.731 5.054 7.962 + -2.474 4.937 7.775 + -3.170 4.658 7.356 + -3.605 4.334 6.861 + -3.890 3.957 6.326 + -3.941 3.197 5.815 + -3.590 5.230 6.286 + -3.102 5.495 6.831 + -2.330 5.690 7.264 + -1.576 5.648 7.632 + -0.888 5.445 7.804 + -0.406 5.084 7.869 + 0.000 4.670 7.912 + 0.000 6.172 7.196 + -0.354 6.247 7.229 + -0.746 6.328 7.263 + -1.426 6.432 7.212 + -2.244 6.373 6.969 + -3.105 6.092 6.495 + -3.639 5.648 5.945 + -3.562 6.154 5.544 + -3.109 6.630 5.986 + -2.176 7.198 6.426 + -1.281 7.365 6.600 + -0.547 7.488 6.717 + -0.286 7.510 6.750 + 0.000 7.522 6.764 + -0.973 2.625 7.123 + -1.041 2.870 7.229 + -1.295 3.155 7.470 + -1.693 3.288 7.715 + -2.196 3.267 7.924 + -2.545 3.146 7.881 + -2.856 2.944 7.491 + -3.091 2.634 7.003 + -2.846 2.481 7.474 + -2.383 2.398 7.878 + -2.012 2.370 7.961 + -1.574 2.388 7.987 + -1.197 2.479 7.638 diff --git a/lib/glut-3.7.6/progs/demos/geoface/fileio.c b/lib/glut-3.7.6/progs/demos/geoface/fileio.c new file mode 100644 index 0000000000..c1f95e35ea --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/fileio.c @@ -0,0 +1,289 @@ +/* ========================================================================== + FILEIO_C +============================================================================= + + FUNCTION NAMES + + read_polygon_indices -- reads the polygon indices file. + read_polygon_line -- read the face polyline. + read_muscles -- reads the face muscles. + read_expression_vectors -- reads a vector of expressions. + add_muscle_to_face -- add a muscle to the face. + + C SPECIFICATIONS + + read_polygon_indices ( FileName, face ) + read_polygon_line ( FileName, face ) + read_muscles ( FileName, face ) + read_expression_vectors ( FileName, face ) + add_muscle_to_face ( m, face ) + + DESCRIPTION + + This module is responsible for reading the face data files. + This module comes as is with no warranties. + + SIDE EFFECTS + Unknown. + + HISTORY + Created 16-Dec-94 Keith Waters at DEC's Cambridge Research Lab. + Modified 22-Nov-96 Sing Bing Kang (sbk@crl.dec.com) + modified function read_expression_vectors() to allocate + memory to face->expression (done once) + +============================================================================ */ + +#include /* C header for any math functions */ +#include /* C header for standard I/O */ +#include /* For String compare */ +#include +#ifndef _WIN32 +#include +#include +#endif + +/* + * from /usr/include/sys/types.h + * Just in case TRUE and FALSE are not defined + */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +#include "head.h" /* local header for the face data structure */ +#include "memory.h" + +void add_muscle_to_face ( MUSCLE *m , HEAD *face ); + +/* ========================================================================= */ +/* read_polygon_indices */ +/* ========================================================================= */ +/* +** Read in the face data file (x,y,z) +** +*/ + +void +read_polygon_indices ( char *FileName, HEAD *face ) + { + FILE *InFile ; + int i, ii ; + + /* + * Check the FileName. + */ + if (( InFile = fopen ( FileName, "r" )) == 0 ) { + fprintf ( stderr, "can't open input file: %s\n", FileName ) ; + exit(-1) ; + } + + fscanf ( InFile,"%d", &face->npindices ) ; + + /* + * Allocate some memory. + */ + face->indexlist = ( int * ) malloc ( face->npindices*4 * sizeof ( int )) ; + + for( i=0, ii=0; inpindices; i++, ii+=4 ) + fscanf(InFile,"%d%d%d%d", + &face->indexlist[ii], &face->indexlist[ii+1], + &face->indexlist[ii+2], &face->indexlist[ii+3] ) ; + + fclose( InFile ) ; + + } + +/* ========================================================================= */ +/* read_polygon_line */ +/* ========================================================================= */ +/* +** Read in the face data file (x,y,z) +** +*/ + +void +read_polygon_line ( char *FileName, HEAD *face ) +{ + FILE *InFile ; + int i, ii ; + + /* + * Check the FileName. + */ + if (( InFile = fopen ( FileName, "r" )) == 0 ) { + fprintf ( stderr, "can't open input file: %s\n", FileName ) ; + exit(-1) ; + } + + fscanf ( InFile, "%d", &face->npolylinenodes ) ; + + /* + * Allocate some memory. + */ + face->polyline = ( float * ) malloc ( face->npolylinenodes*3 * sizeof ( float )) ; + + for ( i=0, ii=0; inpolylinenodes; i++, ii+=3 ) { + + fscanf ( InFile,"%f%f%f", + &face->polyline[ii], + &face->polyline[ii+1], + &face->polyline[ii+2] ) ; + } + + fclose ( InFile ) ; + +} + +/* ============================================================= + read_muscles ( FileName, face ) + ========================================================== */ +/* +** This function reads in the muscles. +** +*/ + +void +read_muscles ( char *FileName, HEAD *face ) +{ + FILE *Infile; + int i, nm ; + MUSCLE *m ; + + /* + * Open the file to be read. + */ + if((Infile = fopen(FileName,"r")) == 0) { + fprintf(stderr,"Opening error on file:%10s\n", FileName) ; + exit(0); + } + fscanf ( Infile, "%d", &nm ) ; + + for ( i=0; i < nm; i++ ) { + + m = _new ( MUSCLE ) ; + + fscanf (Infile, "%s %f %f %f %f %f %f %f %f %f %f", + &(*m->name), + &m->head[0], &m->head[1], &m->head[2], + &m->tail[0], &m->tail[1], &m->tail[2], + &m->fs, &m->fe, &m->zone, &m->clampv ) ; + + m->active = FALSE ; + m->mstat = 0.0 ; + + if (verbose) { + fprintf(stderr,"%s: %d\n========================\nhx: %2.2f hy: %2.2f hz: %2.2f\ntx: %2.2f ty: %2.2f tz: %2.2f\n fall start: %2.2f\n fall end: %2.2f\n zone: %2.2f\n clampv: %2.2f mstat: %2.2f\n\n", + m->name, i, + m->head[0], + m->head[1], + m->head[2], + m->tail[0], + m->tail[1], + m->tail[2], + m->fs, + m->fe, + m->zone, + m->clampv, + m->mstat ) ; + } + + add_muscle_to_face ( m, face ) ; + + } + + fclose(Infile) ; +} + + +/* ========================================================================= */ +/* read_expression_vectors */ +/* ========================================================================= */ +/* sbk - added allocated var - 11/22/96 */ + +/* +** Read in the expression vectors. +*/ +void +read_expression_vectors ( char *FileName, HEAD *face ) +{ + FILE *InFile ; + int i, k ; + EXPRESSION *e ; + static int allocated = 0; + + /* + * Check the FileName. + */ + if (( InFile = fopen ( FileName, "r" )) == 0 ) { +#if 0 /* Silently ignore the lack of expression vectors. I never got the file. -mjk */ + fprintf ( stderr, "can't open input file: %s\n", FileName ) ; +#endif + face->expression = NULL; + return; + } + + fscanf ( InFile, "%d", &face->nexpressions ) ; + fprintf( stderr, "Number of expressions = %d\n", face->nexpressions ) ; + + /* + * Allocate some memory. + */ + if (!allocated) + face->expression = (EXPRESSION **)malloc( face->nexpressions* + sizeof(EXPRESSION *) ); + + for ( i=0; inexpressions; i++) { + if (allocated) + e = face->expression[i]; + else + e = face->expression[i] = _new(EXPRESSION) ; + + fscanf ( InFile, "%s\n", &(*e->name) ) ; + + fprintf ( stderr, "%s\n", e->name ) ; + + for ( k=0; k < 17; k++) { + + fscanf ( InFile,(k==16) ? "%f\n" : "%f ", &e->m[k]) ; + fprintf (stderr,"%2.2f ", e->m[k] ) ; + } + fprintf (stderr, "\n") ; + } + + fclose ( InFile ) ; + + allocated = 1; +} + +/* =============================================================== + add_muscle_to_face ( m, face ) + =============================================================== */ +/* +** adds a muscle to the face muscle list. +** +*/ + +void +add_muscle_to_face ( MUSCLE *m , HEAD *face ) +{ + int nn ; + + if(face->nmuscles == 0) + face->muscle = _new_array(MUSCLE *, 50) ; + else if(face->nmuscles % 50 == 0) + face->muscle = _resize_array(face->muscle,MUSCLE *,face->nmuscles+50) ; + + nn = face->nmuscles ; + face->muscle[nn] = m ; + + face->nmuscles++ ; + +} + diff --git a/lib/glut-3.7.6/progs/demos/geoface/geoface.dsp b/lib/glut-3.7.6/progs/demos/geoface/geoface.dsp new file mode 100644 index 0000000000..c1c8a7d9d1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/geoface.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="geoface" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=geoface - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "geoface.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "geoface.mak" CFG="geoface - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "geoface - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "geoface - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "geoface - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "geoface - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "geoface - Win32 Release" +# Name "geoface - Win32 Debug" +# Begin Source File + +SOURCE=.\display.c +# End Source File +# Begin Source File + +SOURCE=.\fileio.c +# End Source File +# Begin Source File + +SOURCE=.\head.h +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\make_face.c +# End Source File +# Begin Source File + +SOURCE=.\memory.h +# End Source File +# Begin Source File + +SOURCE=.\muscle.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/geoface/head.h b/lib/glut-3.7.6/progs/demos/geoface/head.h new file mode 100644 index 0000000000..8b02cf8ed9 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/head.h @@ -0,0 +1,101 @@ +typedef struct TAG { + + int poly ; /* an index to a tagged polygon */ + int vert ; /* an index to the tagged vertex */ + +} TAG ; + +typedef struct EXPRESSION { + + char name[80] ; /* name of the expression */ + float m[20] ; /* an expression vector */ + float bias ; /* an bias control for the muscles */ + +} EXPRESSION ; + + +typedef struct MUSCLE { + + int active ; /* activity switch for the muscle */ + float head[3] ; /* head of the muscle vector */ + float tail[3] ; /* tail of the muscle vector */ + float zone, /* zone of influence */ + fs, fe, mval ; /* zone, start, end, contraction */ + char name[80] ; /* name of the muscle */ + float clampv ; /* clamping value */ + float mstat ; /* current contraction value */ + +} MUSCLE ; + + +typedef struct VERTEX { + + float xyz[3] ; /* x,y,z of the vertex (modified) */ + float nxyz[3] ; /* x,y,z of the vertex (never modified) */ + int np ; /* number of polygons associated with node */ + int plist[30] ; /* list of polygons associated with node */ + float norm[3] ; /* polygon vertex normal */ + +} VERTEX ; + + +typedef struct POLYGON { + + VERTEX *vertex[3] ; /* pointer to an array of three vertices */ + +} POLYGON ; + + +typedef struct HEAD { + + int npindices ; /* number of polygon indices */ + int *indexlist ; /* integer index list of size npindices*4 */ + + int npolylinenodes ; /* number of nodes in the poly line */ + float *polyline ; /* xyz nodes in the poly line */ + + int npolygons ; /* total number of polygons */ + POLYGON **polygon ; /* pointer to the polygon list */ + + int neyelidtags ; /* number of eyelid tags */ + TAG **eyelidtag ; /* pointer to the eyelid tags */ + float eyelidang ; /* rotation of the eyelids */ + + int njawtags ; /* number of jaw tags */ + TAG **jawtag ; /* pointer to the eyelid tags */ + float jawang ; /* rotation of the jaw */ + + int nmuscles ; /* number of muscles in the face */ + MUSCLE **muscle ; /* pointer to the muscle list */ + + int nexpressions ; /* number of expressions in the */ + EXPRESSION **expression ; /* point to an expression vector */ + +} HEAD ; + +/* main.c */ +extern int verbose; + +/* make_face.c */ +HEAD *create_face ( char *, char * ) ; +void averaged_vertex_normals ( HEAD *face, int p, + float *n1, float *n2, float *n3 ) ; +void face_reset ( HEAD *face ); +void expressions ( HEAD *face, int e ); +void data_struct ( HEAD *face ); + +/* display.c */ +void paint_polyline ( HEAD *face ) ; +void paint_polygons ( HEAD *face, int type, int normals ) ; +void calculate_polygon_vertex_normal ( HEAD *face ); +void paint_muscles ( HEAD *face ); + +/* muscle.c */ +void activate_muscle (HEAD *face, float *vt, float *vh, float fstart, float fin, float ang, float val); + +/* fileio.c */ +void read_polygon_indices ( char *FileName, HEAD *face ); +void read_polygon_line ( char *FileName , HEAD *face ); +void read_muscles ( char *FileName , HEAD *face ); +void read_expression_vectors ( char *FileName , HEAD *face ); + diff --git a/lib/glut-3.7.6/progs/demos/geoface/index.dat b/lib/glut-3.7.6/progs/demos/geoface/index.dat new file mode 100644 index 0000000000..8eafd7f49d --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/index.dat @@ -0,0 +1,239 @@ +238 +1 2 5 4 +2 3 6 5 +7 4 5 8 +8 5 6 9 +1000 11 8 9 +10 7 8 11 +6 3 14 13 +9 6 13 12 +1000 11 9 12 +11 12 17 18 +12 13 16 17 +13 14 15 16 +16 15 25 24 +1000 16 24 23 +17 16 23 22 +18 17 22 21 +1000 19 11 18 +20 19 18 21 +24 25 26 27 +23 24 27 28 +22 23 28 29 +21 22 29 30 +32 20 21 31 +31 21 30 35 +35 30 29 36 +29 28 37 36 +28 27 38 37 +27 26 39 38 +38 39 40 41 +37 38 41 42 +36 37 42 43 +35 36 43 44 +34 31 35 44 +33 32 31 34 +45 33 34 46 +46 34 44 47 +47 44 43 48 +48 43 42 49 +42 41 50 49 +41 40 51 50 +50 51 64 63 +49 50 63 62 +48 49 62 61 +1000 47 48 61 +63 64 65 66 +66 65 77 76 +67 66 76 75 +62 63 66 67 +73 67 75 74 +68 62 67 73 +60 61 62 68 +52 47 61 60 +53 46 47 52 +54 45 46 53 +55 54 53 56 +1000 58 55 56 +1000 58 56 57 +56 53 52 57 +1000 58 57 59 +57 52 60 59 +58 59 69 70 +59 60 68 69 +70 69 72 71 +69 68 73 72 +1000 72 73 74 +1000 58 146 55 +146 145 54 55 +145 144 45 54 +1000 144 142 45 +142 141 33 45 +141 98 32 33 +98 97 20 32 +97 89 19 20 +1000 89 87 19 +1000 19 87 11 +87 88 10 11 +87 85 86 88 +1000 87 84 85 +84 81 82 85 +85 82 83 86 +81 80 79 82 +82 79 78 83 +89 90 84 87 +90 91 81 84 +91 92 80 81 +94 93 92 91 +1000 95 94 91 +96 95 91 90 +97 96 90 89 +98 99 96 97 +99 100 95 96 +100 101 102 95 +102 103 94 95 +103 104 93 94 +106 105 104 103 +1000 102 106 103 +1000 107 106 102 +1000 109 101 100 +1000 110 109 100 +111 110 100 112 +111 117 118 110 +110 118 108 109 +118 119 107 109 +119 120 106 107 +120 121 105 106 +123 122 121 120 +124 123 120 119 +117 124 119 118 +115 116 117 111 +113 112 100 99 +141 113 99 98 +114 115 111 112 +1000 114 112 113 +116 125 124 117 +1000 124 127 123 +127 128 122 123 +126 129 128 127 +125 126 127 124 +131 130 129 126 +132 131 126 125 +115 132 125 116 +134 135 130 131 +133 134 131 132 +133 132 115 114 +139 114 113 140 +140 113 141 142 +1000 143 140 142 +1000 144 143 142 +1000 148 144 145 +170 148 145 146 +1000 147 170 146 +147 171 169 170 +169 149 148 170 +149 150 144 148 +150 151 143 144 +151 152 140 143 +152 153 139 140 +1000 153 138 139 +139 138 133 114 +1000 153 138 139 +138 137 134 133 +137 136 135 134 +156 157 136 137 +155 156 137 138 +154 155 138 153 +1000 152 154 153 +159 158 157 156 +160 159 156 155 +161 160 155 154 +163 162 161 154 +164 163 154 152 +165 164 152 151 +166 165 151 150 +167 166 150 149 +169 168 167 149 +171 174 168 169 +174 177 178 168 +168 178 179 167 +179 180 166 167 +180 181 165 166 +181 182 164 165 +182 183 163 164 +183 184 162 163 +1000 184 185 162 +185 186 161 162 +186 187 160 161 +187 188 159 160 +188 189 158 159 +191 190 189 188 +192 191 188 187 +193 192 187 186 +194 193 186 185 +214 193 194 195 +214 207 192 193 +208 207 214 213 +213 214 195 196 +212 213 196 197 +211 212 197 198 +200 211 198 199 +178 200 199 179 +177 201 200 178 +201 210 211 200 +210 209 212 211 +209 208 213 212 +206 191 192 207 +205 206 207 208 +204 205 208 209 +203 204 209 210 +202 203 210 201 +176 202 201 177 +1000 174 176 177 +1000 191 215 190 +215 228 229 190 +228 231 230 229 +231 242 243 230 +232 241 242 231 +232 231 228 227 +227 228 215 216 +216 215 191 206 +217 216 206 205 +226 227 216 217 +233 232 227 226 +240 241 232 233 +239 240 233 234 +234 233 226 225 +225 226 217 218 +218 217 205 204 +219 218 204 203 +224 225 218 219 +235 234 225 224 +238 239 234 235 +237 238 235 236 +236 235 224 223 +223 224 219 220 +221 220 202 176 +220 219 203 202 +1000 175 237 236 +1000 175 236 223 +175 223 220 221 +222 221 176 174 +1000 222 174 171 +175 221 222 173 +173 222 171 172 +1000 172 171 147 +147 171 169 170 +244 245 194 185 +245 246 195 194 +246 247 196 195 +247 248 197 196 +248 249 198 197 +249 250 199 198 +250 251 179 199 +179 251 252 180 +181 180 252 253 +182 181 253 254 +183 182 254 255 +184 183 255 256 +185 184 256 244 diff --git a/lib/glut-3.7.6/progs/demos/geoface/main.c b/lib/glut-3.7.6/progs/demos/geoface/main.c new file mode 100644 index 0000000000..8545fdfc8f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/main.c @@ -0,0 +1,572 @@ +/* aux2glut conversion Copyright (c) Mark J. Kilgard, 1997 */ + +/* ========================================================================== + MAIN_C +============================================================================= + + FUNCTION NAMES + + movelight -- moves the light source. + rotatexface -- rotates the face about the X axis. + rotateyface -- rotates the face about the Y axis. + myinit -- local initialization. + faceinit -- glutInit(&argc, argv); initialize the face data. + display -- display functions. + myReshape -- window respahe callback. + error_exit -- error function. + usage -- usage function. + GLenum Key -- keyboard mappings. + main -- main program. + + + C SPECIFICATIONS + + void movelight ( int x, int y ) + void rotatexface ( int x, int y ) + void rotateyface ( int x, int y ) + void myinit ( void ) + faceinit ( void ) + void display ( void ) + void myReshape ( GLsizei w, GLsizei h ) + void error_exit ( char *error_message ) + void usage ( char *name ) + static GLenum Key ( int key, GLenum mask ) + void main ( int argc, char** argv ) + + DESCRIPTION + + This module is where everything starts. This module comes as is + with no warranties. + + SIDE EFFECTS + Unknown. + + HISTORY + Created 16-Dec-94 Keith Waters at DEC's Cambridge Research Lab. + Modified 22-Nov-96 Sing Bing Kang (sbk@crl.dec.com) + Added function print_mesg to print out all the keyboard commands + Added the following functionalities: + rereading the expression file + changing the expression (based on the expression file) + quitting the program with 'q' or 'Q' in addition to 'Esc' + +============================================================================ */ + +#include +#include +#include +#include + +#include "memory.h" /* Local memory allocation macros */ +/*#include "window.h" Local window header */ +#include "head.h" /* Local head data structure */ + +int verbose = 0; + +void print_mesg(void); + +int DRAW_MODE = 2 ; + +HEAD *face ; + +static int spinxlight = 0 ; +static int spinylight = 0 ; +static int spinxface = 0 ; +static int spinyface = 0 ; + + +/* ========================================================================= */ +/* motion */ +/* ========================================================================= */ +/* +** Rotate the face and light about. +*/ + +int rotate = 0, movelight = 0, origx, origy; + +void motion ( int x, int y ) +{ + if (rotate) { + spinyface = ( spinyface + (x - origx) ) % 360 ; + spinxface = ( spinxface + (y - origy) ) % 360 ; + origx = x; + origy = y; + glutPostRedisplay(); + } + if (movelight) { + spinylight = ( spinylight + (x - origx ) ) % 360 ; + spinxlight = ( spinxlight + (y - origy ) ) % 360 ; + origx = x; + origy = y; + glutPostRedisplay(); + } +} + +void +mouse(int button, int state, int x, int y) +{ + switch(button) { + case GLUT_LEFT_BUTTON: + if (state == GLUT_DOWN) { + origx = x; + origy = y; + rotate = 1; + } else { + rotate = 0; + } + break; + case GLUT_MIDDLE_BUTTON: + if (state == GLUT_DOWN) { + origx = x; + origy = y; + movelight = 1; + } else { + movelight = 0; + } + break; + } +} + + +/* ========================================================================= */ +/* myinit */ +/* ========================================================================= */ +/* +** Do the lighting thing. +*/ + +void myinit ( void ) +{ + glEnable ( GL_LIGHTING ) ; + glEnable ( GL_LIGHT0 ) ; + glDepthFunc ( GL_LEQUAL ) ; + glEnable ( GL_DEPTH_TEST ) ; +} + + +/* ========================================================================= */ +/* faceinit */ +/* ========================================================================= */ +/* +** Read in the datafiles and glutInit(&argc, argv); initialize the face data structures. +*/ + +void +faceinit ( void ) +{ + face = create_face ( "index.dat", "faceline.dat") ; + read_muscles ("muscle.dat", face ) ; + read_expression_vectors ("expression-vectors.dat", face ) ; + data_struct ( face ) ; +} + +void +read_expressions(void) +{ + read_expression_vectors ("expression-vectors.dat", face ) ; +} + +/* ========================================================================= */ +/* display */ +/* ========================================================================= */ +/* +** Here's were all the display action takes place. +*/ + +void display ( void ) +{ + GLfloat position [] = { 30.0, 70.0, 100.0, 1.0 } ; + + glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; + + glPushMatrix ( ) ; + + glTranslatef ( 0.0, 0.0, -30.0 ) ; + + glRotated ( (GLdouble) spinxface, 1.0, 0.0, 0.0 ) ; + glRotated ( (GLdouble) spinyface, 0.0, 1.0, 0.0 ) ; + + glPushMatrix ( ) ; + glRotated ( (GLdouble) spinxlight, 1.0, 0.0, 0.0 ) ; + glRotated ( (GLdouble) spinylight, 0.0, 1.0, 0.0 ) ; + glLightfv ( GL_LIGHT0, GL_POSITION, position ) ; + + glTranslated ( 0.0, 0.0, 50.0 ) ; + glDisable ( GL_LIGHTING ) ; + glColor3f ( 0.0, 1.0, 1.0 ) ; + glutWireCube ( 0.1 ) ; + glEnable ( GL_LIGHTING ) ; + glPopMatrix ( ) ; + + calculate_polygon_vertex_normal ( face ) ; + + paint_polygons ( face, DRAW_MODE, 0 ) ; + + if ( DRAW_MODE == 0 ) + paint_muscles ( face ) ; + + glPopMatrix(); + + glutSwapBuffers(); +} + + +/* ========================================================================= */ +/* myReshape */ +/* ========================================================================= */ +/* +** What to do of the window is modified. +*/ + +void myReshape ( GLsizei w, GLsizei h ) +{ + glViewport ( 0,0,w,h ) ; + glMatrixMode ( GL_PROJECTION ) ; + glLoadIdentity( ) ; + gluPerspective( 40.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0 ) ; + glMatrixMode ( GL_MODELVIEW ) ; +} + + +/* ========================================================================= */ +/* error_exit */ +/* ========================================================================= */ +/* +** Problems! +*/ + +void error_exit( char *error_message ) +{ + fprintf ( stderr, "%s\n", error_message ) ; + exit( 1 ) ; +} + + +/* ========================================================================= */ +/* usage */ +/* ========================================================================= */ +/* +** At startup provide usage modes. +*/ + +void usage( char *name ) +{ + fprintf( stderr, "\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + "usage: ", name, " [options]\n\n", + " Options:\n", + " -display displayname specify an X server connection\n", + " -geometry geometry specify window geometry in pixels\n", + " -rgba ask for rgba visual\n", + " -index ask for color index visual\n", + " -doublebuffer ask for double buffered visual\n", + " -singlebuffer ask for single buffered visual\n", + " -accum ask for accumulation buffer\n", + " -alpha ask for alpha buffer\n", + " -depth ask for depth buffer\n", + " -stencil ask for stencil buffer\n", + " -aux nauxbuf specify number of aux buffers\n", + " -level planes specify planes (0=main,>0=overlay,<0=underlay\n", + " -transparent ask for transparent overlay\n", + " -opaque ask for opaque overlay\n" + ); + + exit( 1); +} + +/* ========================================================================= */ +/* Key */ +/* ========================================================================= */ +/* +** Actions on a key press. +*/ + +static int m = 0, e = 0; + +/* ARGSUSED1 */ +static void Key ( unsigned char key, int x, int y ) +{ + char title[512]; + + switch ( key ) { + case 27 : + case 'q' : + case 'Q' : + exit (0) ; + + case 'r' : + case 'R' : + printf ("Rereading expression file\n"); + read_expressions(); + e = 0; /* reset the expression count variable */ + glutPostRedisplay(); + break; + + case 'a' : + printf ("increment muscle: %s\n", face->muscle[m]->name ) ; + + /* set the muscle activation */ + face->muscle[m]->mstat += 0.1 ; + + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + 0.1 ) ; + glutPostRedisplay(); + break; + + case 'A' : + printf ("decrement muscle: %s\n", face->muscle[m]->name ) ; + face->muscle[m]->mstat -= 0.1 ; + + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + -0.1 ) ; + glutPostRedisplay(); + break; + + case 'b' : + DRAW_MODE++ ; + + if ( DRAW_MODE >= 3 ) DRAW_MODE = 0 ; + printf ("draw mode: %d\n", DRAW_MODE ) ; + glutPostRedisplay(); + break; + + case 'c' : + face_reset ( face ) ; + glutPostRedisplay(); + break; + + case 'n' : + m++ ; + if ( m >= face->nmuscles ) m = 0 ; + sprintf(title, "geoface (%s)", face->muscle[m]->name); + glutSetWindowTitle(title); + break; + + case 'e' : + if (face->expression) { + face_reset ( face ) ; + expressions ( face, e ) ; + + e++ ; + if ( e >= face->nexpressions ) e = 0 ; + glutPostRedisplay(); + } + break; + + case 'h' : + + print_mesg(); + + } +} + +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + char title[512]; + + switch(key) { + case GLUT_KEY_RIGHT: + m++ ; + if ( m >= face->nmuscles ) m = 0 ; + sprintf(title, "geoface (%s)", face->muscle[m]->name); + glutSetWindowTitle(title); + break; + case GLUT_KEY_LEFT: + m-- ; + if ( m < 0 ) m = face->nmuscles - 1 ; + sprintf(title, "geoface (%s)", face->muscle[m]->name); + glutSetWindowTitle(title); + break; + case GLUT_KEY_UP: + face->muscle[m]->mstat += 0.1 ; + + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + 0.1 ) ; + glutPostRedisplay(); + break; + case GLUT_KEY_DOWN: + face->muscle[m]->mstat -= 0.1 ; + + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + -0.1 ) ; + glutPostRedisplay(); + break; + } +} + + +/* ========================================================================= * + * print_mesg + * Written by: Sing Bing Kang (sbk@crl.dec.com) + * Date: 11/22/96 + * ========================================================================= */ +/* +** Prints out help message +*/ +void +print_mesg(void) +{ +fprintf(stderr,"\n"); +fprintf(stderr,"a: draw mode (to `pull' the current facial muscle)\n"); +fprintf(stderr,"A: draw mode (to `contract' current facial muscle)\n"); +fprintf(stderr,"c: face reset\n"); +fprintf(stderr,"n: next muscle (to select another facial muscle to manipulate)\n"); +fprintf(stderr,"e: next expression\n"); +fprintf(stderr,"b: to change draw mode: wireframe->polygonal patches->smooth surface\n"); +fprintf(stderr,"r,R: reread the expression file (../face-data/expression-vectors.dat)\n (Note: this resets the expression sequence to the beginning)\n"); +fprintf(stderr,"q,Q,Esc: quit\n"); +fprintf(stderr,"h: outputs this message\n"); +fprintf(stderr,"\n"); +} + +void +muscle_select(int value) +{ + char title[512]; + + /* Select muscle. */ + m = value; + sprintf(title, "geoface (%s)", face->muscle[m]->name); + glutSetWindowTitle(title); +} + +void +main_menu_select(int value) +{ + char title[512]; + + switch(value) { + case 1: + face_reset ( face ) ; + glutPostRedisplay(); + break; + case 2: + print_mesg(); + break; + case 3: + face->muscle[m]->mstat += 0.25 ; + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + +0.25 ) ; + glutPostRedisplay(); + break; + case 4: + face->muscle[m]->mstat -= 0.25 ; + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + -0.25 ) ; + glutPostRedisplay(); + break; + case 5: + m++ ; + if ( m >= face->nmuscles ) m = 0 ; + sprintf(title, "geoface (%s)", face->muscle[m]->name); + glutSetWindowTitle(title); + break; + case 666: + exit(0); + break; + } +} + +void +draw_mode_select(int value) +{ + DRAW_MODE = value; + glutPostRedisplay(); +} + +void +make_menus(void) +{ + int i, j, muscle_menu, draw_mode_menu; + char *entry; + + muscle_menu = glutCreateMenu(muscle_select); + for (i=0; inmuscles; i++) { + entry = face->muscle[i]->name; + for(j=(int) strlen(entry)-1; j>=0; j--) { + if (entry[j] == '_') entry[j] = ' '; + } + glutAddMenuEntry(entry, i); + } + draw_mode_menu = glutCreateMenu(draw_mode_select); + glutAddMenuEntry("Wireframe", 0); + glutAddMenuEntry("Polygonal patches", 1); + glutAddMenuEntry("Smooth surface", 2); + glutCreateMenu(main_menu_select); + glutAddMenuEntry("Pull muscle up", 3); + glutAddMenuEntry("Pull muscle down", 4); + glutAddMenuEntry("Next muscle", 5); + glutAddSubMenu("Select muscle", muscle_menu); + glutAddSubMenu("Draw mode", draw_mode_menu); + glutAddMenuEntry("Face reset", 1); + glutAddMenuEntry("Print help", 2); + glutAddMenuEntry("Quit", 666); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +/* ========================================================================= */ +/* main */ +/* ========================================================================= */ +/* +** All the initialization and action takes place here. +*/ + +int main ( int argc, char** argv ) +{ + int i; + + glutInitWindowSize ( 400, 600 ) ; + glutInit(&argc, argv); + for(i=1; i /* C header for any math functions */ +#include /* C header for standard I/O */ +#include /* For String compare */ +#include +#ifndef _WIN32 +#include +#include +#endif + +#include "memory.h" /* Local memory allocation macros */ +#include "head.h" /* local header for the face */ + +void reflect_polygon ( POLYGON *poly, HEAD *face ); +void add_polygon_to_face ( POLYGON *p, HEAD *face ); +void make_face ( HEAD *face ); + +/* ========================================================================= */ +/* face_reset */ +/* ========================================================================= */ +/* +** Resets the geometry of the face to neutral. +** +*/ + +void face_reset ( HEAD *face ) +{ + int i,j,k ; + + + for ( i=0; inpolygons; i++ ) { + + for ( j=0; j<3; j++ ) { + + for ( k=0; k<3; k++ ) { + face->polygon[i]->vertex[j]->xyz[k] = + face->polygon[i]->vertex[j]->nxyz[k] ; + } + } + } +} + + +/* ========================================================================= + expressions + Written by: Sing Bing Kang + Date: 11/22/96 + ========================================================================= */ +/* +** Produces the facial expressions as indicated by the muscle contraction +** vector +** +*/ + +void +expressions ( HEAD *face, int e ) +{ + int m; + + fprintf( stderr, "Expression: %s\n", face->expression[e]->name ); + + for (m=0; mnmuscles; m++) { + float m_val = face->expression[e]->m[m], + m_diff = m_val - face->muscle[m]->mstat; + + face->muscle[m]->mstat = m_val; + activate_muscle ( face, + face->muscle[m]->head, + face->muscle[m]->tail, + face->muscle[m]->fs, + face->muscle[m]->fe, + face->muscle[m]->zone, + m_diff ) ; + } + +} + +/* ========================================================================= */ +/* create_face */ +/* ========================================================================= */ +/* +** create the default structures for the face and retrun a pointer. +** +*/ + +HEAD *create_face ( char *f1, char *f2 ) +{ + HEAD *h ; + + h = _new ( HEAD ) ; + + h->npolygons = 0 ; + h->npindices = 0 ; + h->npolylinenodes = 0 ; + h->nmuscles = 0 ; + + read_polygon_indices ( f1, h ) ; + read_polygon_line ( f2, h ) ; + + make_face ( h ) ; + + return ( h ) ; + +} + +/* ========================================================================= */ +/* make_face */ +/* ========================================================================= */ +/* +** makes the face from the two input files. +** +*/ + +void +make_face ( HEAD *face ) +{ + POLYGON *p ; + int i, ii, j, k, + p1, p2, p3, p4 ; + int parray[4] ; + + for ( i=0, ii=0; i < face->npindices; i++,ii+=4 ) { + + p1 = face->indexlist[ii] -1 ; + p2 = face->indexlist[ii+1] -1 ; + p3 = face->indexlist[ii+2] -1 ; + p4 = face->indexlist[ii+3] -1 ; + + for (j=0; j<4; j++) + parray[j] = face->indexlist[ii+j] -1; + + if ( p1 == 999 ) { + + p = _new ( POLYGON ) ; + for (j=0; j<3; j++) { + p->vertex[j] = _new ( VERTEX ) ; + p->vertex[j]->np = 0 ; + } + + for (j=0; j<3; j++) + p->vertex[0]->nxyz[j] = + p->vertex[0]->xyz[j] = face->polyline[ p2*3 + j ] ; + + for (j=0; j<3; j++) + p->vertex[1]->nxyz[j] = + p->vertex[1]->xyz[j] = face->polyline[ p3*3 + j ] ; + + for (j=0; j<3; j++) + p->vertex[2]->nxyz[j] = + p->vertex[2]->xyz[j] = face->polyline[ p4*3 + j ] ; + + add_polygon_to_face ( p, face ) ; + reflect_polygon ( p, face ) ; + } + else { + p = _new ( POLYGON ) ; + for (j=0; j<3; j++) { + p->vertex[j] = _new ( VERTEX ) ; + p->vertex[j]->np = 0 ; + } + + for (k=0; k<3; k++) { + for (j=0; j<3; j++) + p->vertex[k]->nxyz[j] = + p->vertex[k]->xyz[j] = face->polyline[ parray[k]*3 + j ] ; + } + + add_polygon_to_face ( p, face ) ; + reflect_polygon ( p, face ) ; + + p = _new ( POLYGON ) ; + for (j=0; j<3; j++) { + p->vertex[j] = _new ( VERTEX ) ; + p->vertex[j]->np = 0 ; + } + + for (j=0; j<3; j++) + p->vertex[0]->nxyz[j] = + p->vertex[0]->xyz[j] = face->polyline[ p1*3 + j ] ; + + for (j=0; j<3; j++) + p->vertex[1]->nxyz[j] = + p->vertex[1]->xyz[j] = face->polyline[ p3*3 + j ] ; + + for (j=0; j<3; j++) + p->vertex[2]->nxyz[j] = + p->vertex[2]->xyz[j] = face->polyline[ p4*3 + j ] ; + + add_polygon_to_face ( p, face ) ; + reflect_polygon ( p, face ) ; + } + } + +} + +/* ========================================================================= */ +/* add_polygon_to_face */ +/* ========================================================================= */ +/* +** add a polygon to the face structure. +** +*/ + +void +add_polygon_to_face ( POLYGON *p, HEAD *face ) +{ + int nn ; + + if(face->npolygons == 0) + face->polygon = _new_array(POLYGON *, 500) ; + else if(face->npolygons % 500 == 0) + face->polygon = _resize_array(face->polygon,POLYGON *,face->npolygons+500) ; + + nn = face->npolygons ; + face->polygon[nn] = p ; + + face->npolygons++ ; + +} + + +/* ========================================================================= */ +/* reflect_polygon */ +/* ========================================================================= */ +/* +** Reflects all the polygons in the half-face and adds them to +** the data structure. +** +*/ + +void +reflect_polygon ( POLYGON *poly, HEAD *face ) +{ + POLYGON *newp ; + float temp[3] ; + int i, j ; + + /* + * Allocate memory for the new polygon. + */ + newp = _new ( POLYGON ) ; + for (j=0; j<3; j++) { + newp->vertex[j] = _new ( VERTEX ) ; + newp->vertex[j]->np = 0 ; + } + + /* + * Load the old polygon values. + */ + for (i=0; i<3; i++) + for (j=0; j<3; j++) + newp->vertex[i]->nxyz[j] = + newp->vertex[i]->xyz[j] = poly->vertex[i]->xyz[j] ; + + /* + * flip the X component. + */ + for (i=0; i<3; i++) + newp->vertex[i]->nxyz[0] = + newp->vertex[i]->xyz[0] = -newp->vertex[i]->xyz[0] ; + + /* + * Re-order the vertices, flip 0 and 1. + */ + for (j=0; j<3; j++) + temp[j] = newp->vertex[0]->xyz[j] ; + + for (j=0; j<3; j++) + newp->vertex[0]->nxyz[j] = + newp->vertex[0]->xyz[j] = newp->vertex[1]->xyz[j]; + + for (j=0; j<3; j++) + newp->vertex[1]->nxyz[j] = + newp->vertex[1]->xyz[j] = temp[j] ; + + add_polygon_to_face ( newp, face ) ; + +} + +/* ========================================================================= */ +/* averaged_vertex_normals */ +/* ========================================================================= */ +/* +** Caculates the averaged polygon normal. +*/ + +void averaged_vertex_normals ( HEAD *face, int p, float *n1, float *n2, float *n3 ) +{ + int i,j,np, pt ; + float norm[3] ; + + + for (i=0; i<3; i++) + norm[i] = 0.0 ; + + np = face->polygon[p]->vertex[0]->np ; + + for ( i=0; ipolygon[p]->vertex[0]->plist[i] ; + + for ( j=0; j<3; j++) { + norm[j] += face->polygon[pt]->vertex[0]->norm[j] ; + } + } + + for (i=0; i<3; i++) + norm[i] = norm[i] / (float)np ; + + for (i=0; i<3; i++) + n1[i] = norm[i] ; + + for (i=0; i<3; i++) + norm[i] = 0.0 ; + + np = face->polygon[p]->vertex[1]->np ; + + for ( i=0; ipolygon[p]->vertex[1]->plist[i] ; + + for ( j=0; j<3; j++) { + norm[j] += face->polygon[pt]->vertex[1]->norm[j] ; + } + } + + for (i=0; i<3; i++) + norm[i] = norm[i] / (float) np ; + + for (i=0; i<3; i++) + n2[i] = norm[i] ; + + for (i=0; i<3; i++) + norm[i] = 0.0 ; + + np = face->polygon[p]->vertex[2]->np ; + + for ( i=0; ipolygon[p]->vertex[2]->plist[i] ; + + for ( j=0; j<3; j++) { + norm[j] += face->polygon[pt]->vertex[2]->norm[j] ; + } + } + + for (i=0; i<3; i++) + norm[i] = norm[i]/ (float) np ; + + for (i=0; i<3; i++) + n3[i] = norm[i] ; + +} + +/* ========================================================================= */ +/* data_struct */ +/* ========================================================================= */ +/* +** Create a new data structure for the polygons. +** +*/ +#define DATA_STRUCT_DEBUG 0 + +void +data_struct ( HEAD *face ) +{ + int i,j, n ; + int flag, cptr ; + float x1,y1,z1, x2, y2, z2, x3, y3, z3 ; + float tx1, ty1, tz1, tx2, ty2, tz2, tx3, ty3, tz3 ; + + for (i=0; inpolygons; i++ ){ + + x1 = face->polygon[i]->vertex[0]->xyz[0] ; + y1 = face->polygon[i]->vertex[0]->xyz[1] ; + z1 = face->polygon[i]->vertex[0]->xyz[2] ; + + x2 = face->polygon[i]->vertex[1]->xyz[0] ; + y2 = face->polygon[i]->vertex[1]->xyz[1] ; + z2 = face->polygon[i]->vertex[1]->xyz[2] ; + + x3 = face->polygon[i]->vertex[2]->xyz[0] ; + y3 = face->polygon[i]->vertex[2]->xyz[1] ; + z3 = face->polygon[i]->vertex[2]->xyz[2] ; +#if DATA_STRUCT_DEBUG + fprintf (stderr,"BASE polygon: %d\n", i) ; + fprintf (stderr,"x1: %f y1: %f z1: %f\n", x1,y1,z1) ; + fprintf (stderr,"x1: %f y1: %f z1: %f\n", x2,y2,z2) ; + fprintf (stderr,"x1: %f y1: %f z1: %f\n", x3,y3,z3) ; +#endif + j = 0 ; + flag = 0 ; + while ( !flag && + jnpolygons ) { + + tx1 = face->polygon[j]->vertex[0]->xyz[0] ; + ty1 = face->polygon[j]->vertex[0]->xyz[1] ; + tz1 = face->polygon[j]->vertex[0]->xyz[2] ; + + tx2 = face->polygon[j]->vertex[1]->xyz[0] ; + ty2 = face->polygon[j]->vertex[1]->xyz[1] ; + tz2 = face->polygon[j]->vertex[1]->xyz[2] ; + + tx3 = face->polygon[j]->vertex[2]->xyz[0] ; + ty3 = face->polygon[j]->vertex[2]->xyz[1] ; + tz3 = face->polygon[j]->vertex[2]->xyz[2] ; +#if DATA_STRUCT_DEBUG + fprintf (stderr, "COMPARED TO polygon: %d\n", j) ; + fprintf (stderr,"tx1: %f ty1: %f tz1: %f\n", tx1,ty1,tz1) ; + fprintf (stderr,"tx1: %f ty1: %f tz1: %f\n", tx2,ty2,tz2) ; + fprintf (stderr,"tx1: %f ty1: %f tz1: %f\n", tx3,ty3,tz3) ; +#endif + if ( (x1 == tx1 && y1 == ty1 && z1 == tz1) || + (x1 == tx2 && y1 == ty2 && z1 == tz2) || + (x1 == tx3 && y1 == ty3 && z1 == tz3)) { + cptr = j ; +#if DATA_STRUCT_DEBUG + fprintf (stderr,"found a vertex match on polygon: %d and %d\n", i,j); +#endif + n = face->polygon[i]->vertex[0]->np ; + face->polygon[i]->vertex[0]->plist[n] = cptr ; + face->polygon[i]->vertex[0]->np++ ; +#if DATA_STRUCT_DEBUG + fprintf (stderr,"loaded: %d onto polygon: %d vertex[0]\n", cptr, i) ; + fprintf (stderr,"total on vertex: %d\n", face->polygon[i]->vertex[0]->np); +#endif + } + j++ ; + + } /* end while */ + + + j = 0 ; + flag = 0 ; + while ( !flag && + jnpolygons ) { + tx1 = face->polygon[j]->vertex[0]->xyz[0] ; + ty1 = face->polygon[j]->vertex[0]->xyz[1] ; + tz1 = face->polygon[j]->vertex[0]->xyz[2] ; + + tx2 = face->polygon[j]->vertex[1]->xyz[0] ; + ty2 = face->polygon[j]->vertex[1]->xyz[1] ; + tz2 = face->polygon[j]->vertex[1]->xyz[2] ; + + tx3 = face->polygon[j]->vertex[2]->xyz[0] ; + ty3 = face->polygon[j]->vertex[2]->xyz[1] ; + tz3 = face->polygon[j]->vertex[2]->xyz[2] ; + + if ( (x2 == tx1 && y2 == ty1 && z2 == tz1) || + (x2 == tx2 && y2 == ty2 && z2 == tz2) || + (x2 == tx3 && y2 == ty3 && z2 == tz3)) { + cptr = j ; + + n = face->polygon[i]->vertex[1]->np ; + face->polygon[i]->vertex[1]->plist[n] = j ; + face->polygon[i]->vertex[1]->np++ ; + + } + j++ ; + + } /* end while */ + + j = 0 ; + flag = 0 ; + while ( !flag && + jnpolygons ) { + tx1 = face->polygon[j]->vertex[0]->xyz[0] ; + ty1 = face->polygon[j]->vertex[0]->xyz[1] ; + tz1 = face->polygon[j]->vertex[0]->xyz[2] ; + + tx2 = face->polygon[j]->vertex[1]->xyz[0] ; + ty2 = face->polygon[j]->vertex[1]->xyz[1] ; + tz2 = face->polygon[j]->vertex[1]->xyz[2] ; + + tx3 = face->polygon[j]->vertex[2]->xyz[0] ; + ty3 = face->polygon[j]->vertex[2]->xyz[1] ; + tz3 = face->polygon[j]->vertex[2]->xyz[2] ; + + if ( x3 == tx1 && y3 == ty1 && z3 == tz1 || + x3 == tx2 && y3 == ty2 && z3 == tz2 || + x3 == tx3 && y3 == ty3 && z3 == tz3) { + cptr = j ; + + n = face->polygon[i]->vertex[2]->np ; + face->polygon[i]->vertex[2]->plist[n] = cptr ; + face->polygon[i]->vertex[2]->np++ ; + + } + j++ ; + + } /* end while */ + } /* end for i */ +} diff --git a/lib/glut-3.7.6/progs/demos/geoface/memory.h b/lib/glut-3.7.6/progs/demos/geoface/memory.h new file mode 100644 index 0000000000..07c24f147c --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/memory.h @@ -0,0 +1,29 @@ +/* ========================================================================== + MEMORY_H +============================================================================= + + AUTHOR: Keith Waters + DATE : Tue Jan 7 10:16:52 EST 1992 + + SYNOPSIS + Memory macros. + + DESCRIPTION + Simple memory macros for allocation. + +============================================================================ */ + + +#ifndef MEMORY_H +#define MEMORY_H + + +#define _new(t) ((t*)malloc(sizeof(t))) +#define _new_array(t, n) ((t*)malloc(sizeof(t) * (n))) +#define _resize_array(a, t, n) ((t*)realloc((a), sizeof(t) * (n))) +#define _size_array(a,t,n0,n1) a = (n0 == 0 ? _new_array(t,n1) : \ + _resize_array(a,t,n1)) +#define _delete(object) ((void)(((object)!=NULL) ? \ + free((char*)(object)),(object)=NULL : 0)) +#endif /* _MEMORY_H */ + diff --git a/lib/glut-3.7.6/progs/demos/geoface/muscle.c b/lib/glut-3.7.6/progs/demos/geoface/muscle.c new file mode 100644 index 0000000000..d00eea2c65 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/muscle.c @@ -0,0 +1,213 @@ +/* ========================================================================== + MUSCLE_C +============================================================================= + + FUNCTION NAMES + + float VecLen -- calculates a vector length. + float CosAng -- compute the cosine angle between two vectors. + activate_muscle -- activate a muscle. + act_muscles -- activate muscles. + reset_muscles -- reset all the muscles. + + C SPECIFICATIONS + + float VecLen ( float *v ) + float CosAng ( float *v1, float *v2 ) + activate_muscle ( HEAD *face, float *vt, float *vh, + float fstart, float fin, float ang, float val ) + act_muscles ( HEAD *face ) + reset_muscles ( HEAD *face ) + + DESCRIPTION + + This module is where all the muscle action takes place. This module + comes as is with no warranties. + + SIDE EFFECTS + Unknown. + + HISTORY + Created 16-Dec-94 Keith Waters at DEC's Cambridge Research Lab. + +============================================================================ */ + +#include +#include +#include "head.h" + +#ifdef _WIN32 +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#define DTOR(deg) ((deg)*0.017453292) /* degrees to radians */ +#define RTOD(rad) ((rad)*57.29577951) /* radians to degrees */ +#define RADF 180.0 / M_PI + + +/* ======================================================================== */ +/* float VecLen ( vec ) */ +/* ======================================================================== */ +/* +** Caculates the length of the vector. +*/ + +float VecLen ( float *v ) +{ + return (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); +} + +/* ======================================================================== */ +/* float CosAng ( v1, v2 ) */ +/* ======================================================================== */ +/* +** Rotates the facial muscles 90.0 degrees. +*/ + +float CosAng ( float *v1, float *v2 ) +{ + float ang, a,b ; + + a = VecLen ( v1 ) ; + b = VecLen ( v2 ) ; + + ang = ((v1[0]*v2[0]) + (v1[1]*v2[1] ) + (v1[2]*v2[2])) / (a*b) ; + + return ( ang ) ; +} + +/* ======================================================================== */ +/* activate_muscle ( face, vt, vh, fstart, fin, ang, val ) */ +/* ======================================================================== */ +/* +** activate the muscle. +*/ + +void +activate_muscle (HEAD *face, float *vt, float *vh, float fstart, float fin, float ang, float val) +{ + float newp[3], va[3], vb[3] ; + int i,j,k,l ; + float valen, vblen ; + float cosa, cosv, dif, tot, percent, thet, newv, the, radf ; + + radf = 180.0/ M_PI ; + the = ang / radf ; ; + thet = cos ( the ) ; + + cosa = 0.0 ; + + /* find the length of the muscle */ + for (i=0; i<3; i++) + va[i] = vt[i] - vh[i] ; + valen = VecLen ( va ) ; + + /* loop for all polygons */ + for (i=0; inpolygons; i++) { + + /* loop for all vertices */ + for (j=0; j<3; j++) { + + /* find the length of the muscle head to the mesh node */ + for (k=0; k<3; k++) + vb[k] = face->polygon[i]->vertex[j]->xyz[k] - vh[k] ; + vblen = VecLen ( vb ) ; + + if ( valen > 0.0 && vblen > 0.0) { + cosa = CosAng ( va, vb ) ; + + if ( cosa >= thet ) { + if ( vblen <= fin ) { + cosv = val * ( 1.0 - (cosa/thet) ) ; + + if ( vblen >= fstart && vblen <= fin) { + dif = vblen - fstart ; + tot = fin - fstart ; + percent = dif/tot ; + newv = cos ( DTOR(percent*90.0) ) ; + + for ( l=0; l<3; l++) + newp[l] = (vb[l] * cosv) * newv ; + } + else { + for ( l=0; l<3; l++) + newp[l] = vb[l] * cosv ; + + } /* endif vblen>fin */ + + for (l=0; l<3; l++) + face->polygon[i]->vertex[j]->xyz[l] += newp[l] ; + + } /* endif vblen>fin */ + } /* endif cosa>thet */ + } /* endif mlen&&tlen */ + } /* end for j vertices */ + } /* end for i polygon */ +} + +/* ======================================================================== */ +/* act_muscles ( face ) */ +/* ======================================================================== */ +/* +** activate the muscles +*/ + +void +act_muscles ( HEAD *face ) +{ + int i ; + + /* + * Loop all the muscles. + */ + for (i=0; inmuscles; i++) { + + /* + * Check to see if the muscle is active. + */ + if (face->muscle[i]->active) { + + activate_muscle ( face, face->muscle[i]->head, + face->muscle[i]->tail, + face->muscle[i]->fs, + face->muscle[i]->fe, + face->muscle[i]->zone, + face->muscle[i]->mval ) ; + + /* + * Reset the muscle activity. + */ + face->muscle[i]->active = 1 ; + + } + } +} + +/* ======================================================================== */ +/* reset_muscles ( face ) */ +/* ======================================================================== */ +/* +** Resets the muscles of the face. This is achieved by reversing +** the muscle contraction. +*/ + +void +reset_muscles ( HEAD *face ) +{ + int i,j,k ; + + for ( i=0; inpolygons; i++ ) { + for ( j=0; j<3; j++ ) { + + for ( k=0; k<3; k++ ) + face->polygon[i]->vertex[j]->xyz[k] = + face->polygon[i]->vertex[j]->nxyz[k] ; + + } /* end for j */ + } /* end for i */ +} diff --git a/lib/glut-3.7.6/progs/demos/geoface/muscle.dat b/lib/glut-3.7.6/progs/demos/geoface/muscle.dat new file mode 100644 index 0000000000..45e4dde071 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/geoface/muscle.dat @@ -0,0 +1,91 @@ +18 + +L_Zygomatic_Major +-1.5700 -2.2210 7.8200 +-3.8050 0.8680 6.6000 + 0.1 4.8 45.0 1.0 + +R_Zygomatic_Major +1.5700 -2.2210 7.8200 +3.8050 0.8680 6.6000 +0.1 4.8 45.0 1.0 + +L_Angular_Depressor +-1.5700 -2.2210 8.0250 +-2.5590 -4.2770 5.3510 + 0.3 4.5 65.0 1.0 + +R_Angular_Depressor +1.5700 -2.2210 8.0250 +2.5590 -4.2770 5.3510 +0.3 4.5 65.0 1.0 + +Left_Frontalis_Inner +-0.4870 3.6390 8.1010 +-0.3540 6.2470 7.2290 + 0.1 3.6 35.0 4.0 + +Right_Frontalis_Inner +0.4870 3.6390 8.1010 +0.3540 6.2470 7.2290 +0.1 3.6 35.0 4.0 + +Left_Frontalis_Major +-2.3810 3.8300 8.0000 +-2.2440 6.3630 6.9690 +0.1 3.7 65.0 0.5 + +Right_Frontalis_Major +2.3810 3.8300 8.0000 +2.2440 6.3630 6.9690 +0.1 3.7 65.0 0.5 + +Left_Frontalis_Outer +-3.0950 3.9700 7.8950 +-3.6390 5.6480 5.9450 +0.1 3.5 45.0 2.5 + +Right_Frontalis_Outer +3.0950 3.9700 7.8950 +3.6390 5.6480 5.9450 +0.1 3.5 45.0 2.5 + +Left_Labi_Nasi +-1.7760 -0.8340 8.2390 +-1.5600 1.8870 7.3320 + 0.1 5.2 35.0 3.0 + +Right_Labi_Nasi +1.7760 -0.8340 8.2390 +1.5600 1.8870 7.3320 +0.1 5.2 35.0 3.0 + +Left_Inner_Labi_Nasi +-1.0020 0.2170 8.4620 +-0.6380 2.0840 7.6610 +0.1 4.5 35.0 1.0 + +Right_Inner_Labi_Nasi +1.0020 0.2170 8.4620 +0.6380 2.0840 7.6610 +0.1 4.5 35.0 1.0 + +Left_Lateral_Corigator +-1.1700 4.6580 7.3560 + 0.0000 3.2620 8.2080 + 0.5 3.0 45.0 3.0 + +Right_Lateral_Corigator +1.1700 4.6580 7.3560 +0.0000 3.2620 8.2080 +0.5 3.0 45.0 3.0 + +Left_Secondary_Frontalis +-0.5840 3.0520 8.0550 +-0.9910 4.8620 8.0930 +0.1 4.8 45.0 1.0 + +Right_Secondary_Frontalis +0.5840 3.0520 8.0550 +0.9910 4.8620 8.0930 +0.1 4.8 45.0 1.0 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Flare1.bw b/lib/glut-3.7.6/progs/demos/glflare/Flare1.bw new file mode 100644 index 0000000000000000000000000000000000000000..6ccd9cce283478930b2a6130991538ede713780b GIT binary patch literal 12222 zcmZR)#mLCO#L&Rdz`)1=0e?VLUcN$JVs0vkNlnbczyvm~9!x?B0R|xn2vdKb00SR~ z0E2)4gg;8sJ_Ohp7#P@C85r2O7#P_285r247#P^p7#P^B7#P?B7#P^{7#P@k7#P?# zFfg!PV_;xsVqjo5WME)VV_;yP$-uyViGhKGkAZ>1pMim+hk=3PJOcx#5Ca2eGy?c4_6!VMQy3VyUNA6l+c7Y3Phw!;e#^kX%ss0t*=!1bG=41nU?W1m7|+2qiKw2wh}g5cXhT z5Z=weAY#P8AhMK!K~#Z(L3A1egO~^dgIEs(gE%JxgLo4Ig9H-;gG3zzgTy}u2FYp$ z2Fc$H3{q7L3{t-s7^JHh7^HtOFvwIfFv$F1V2~|iV37UHz#vz^z##XUfk8fvfkFNO z1A{_11B1c^1_nhp1_s5w3=B#}3=B%k85oo$7#Nhh7#Ng)F)*lPF)*myWMEKrWnfU< z#K52?%fO)4#=xNVj)6fvn1Mlk2LpqKGy{W1Jp+TrZ3YHSD+UJ5=?n~-UlI(D zmM}1A{bXR!_F-Vqp3A_X{gQz}$Ap1Fr=Ed9=Qsm{E-wRvt}g?FZZ`vi?r{bNJthVQ zJxc}#y*vg6y#)*mdgmAz^nNff=*u!N=-V?e=*KWH=$A1t=yx+P=+9wb&|ks8pue7h zL4OMagZ@qi1_o9n%+0{Sz{9}6Ai}`FAjZJJAP2=N3=9lv3=9l93=9nV3=9mW3=9m$ z3=9mG3=9l53=9m83=9mm3=9m;Q0&RTz~I5az~BePp$rTRAq)%*VNg1nfq?;p;~5wj zVi_11k{K8nKTZCU|=X?U|^_YU|^_VU|^_aU|^_ZU|?uqU|^_$(jYMqA5;c`Xk-l1 z2f`pVAPh1OgsY%-fXo7!53;wEfq?;pL2fF7x(DPYko!Px1-U&N>X!@#1_n@J3c?`2 zrZ6xt#6bNF@;?YiGB7ZNGcYiK!YY`7fgzBAfx(A?fx#P!LE-7fz`)?Zz`$S!4R>n> z1_pCzd>An>Fz7KbFlaF_FsL#xFeouFFvv16Fi0^lFo-fRFbG29mK`a+S?fRrGJ-H; zU}op%VP-dFU@&B8VrQ4)VP-b~8QaLt&cn>lFT%{v#?!>kuFJrn&Ctls%G1QpFD25% z&(8`H)nZ`K0O?`@3A2eXi}T5_h_ivDS$G=RH9$$IksU0_D$*n_E-BL_F3u{_$PbcL zV_;BW0LeD;vw$SoWSHgoRG8)2Wg5Y1n0Xr6RY0DCs9^@FVU=l;mzPv&l9y+dX%uG> zY2*i~Qet3GfSSZC(kRX<(rB*Qp=MODrMQqHEstj}x0tj`A0#-h?F&n(j@4$~ydz#s#* z17rg;$jQtgJuEs+`uY+kP5Sz*I*sb6nq(Llq#0V+d3eCCVwP!?XI5!c2kT%nVK(Qr zVK!$oY1C&y(FpRp6a#}K*sd0S5fO2O#zuWslO}U>ahoP{a~6=D%pjLCtF*|=$cQtG zwD9xruuC#9NWd&@5toqx+sO=aC5uU;Ihzf$J&y~sJsZS`Mtx?TMs;SeSKGx!L_h{e zFffQSw1Zp?w!1}MMMWK~pV_3*oYkhu-d^0L(Vo?&(VWEurXT76W*%`+fzt)m47a>d zAEcKBq?gr&*`3FS*`3X$(Vhk52xhP$E$S*N^2{>KBFsEupmg4gFam5n%!EdJ7MCV> zcQKzPcXw8oMtf$65fEQ6%d|oKAPOq_(2W2&ff?ikW{?SNKFt2yAdd=>!EQI50#Q7=#(xAZ}rnVOD8T*U549A*lOPoqCu2y-}h40AXu$S`J*|Cn7`>}_n!nN9lj zb##zT69Sb2a91^h1BltA#oWdQ>?UTAn^;1c!ox*l8pByb8vU7l8r_+}o}6TEVuEZM z4-dN_$h3((JfNf|Bcq}M@*>!6E%q)h?qI{1L58u$FvoMJG{wiW#WaSqz)hVBawCSJ z0t^fS3{x-+g}boPpE;y4oF%3yK3)W5CQD3HcsMiI&>8M7E?CXvXJFuGn9k0_BO)S> z$kEIxE%7li;mjd3K>+~{VRWN;K#hi}u#f;J1QQcbqH=Lz_F)cb0l69E zWM+`TtR>9loHfkltR;>4%sGwe%-}$o9Uc;bYQBn!yo?Mupuxt2lLRdGkWFWfX^Brs zNe7$FT+&otE>zQ0Ud{qHeICg5FvD$ZAjueHxVVT24-Y#x0|PfG7WqX)5WxbALvWx# zT;7<^T+&$1TEkq=+0s;B&kC}H8Enad^pq3~JHROg6!iQ&JYXy4Af-Ni6B8sGVq)T% zQPb)(e3wV5w;=XD(TspOb^jcxdpjb1^V*G0cZYth$a4ICxxK+seZu+c|rh+S^%M8ta+C)+|D^1`*5ffCAgH5aJ1F!Zf$B0bAl95)u;w zii4b-eC877n#OvTmZtW0!Jfu;7O)j9{vtwc)@eH!S+{6SLN}yO~=VV~u zWLN_71~isoq2%L(Y(Ys$Imia)md1A0o~HhOjw#IjEFj-7x3tvP)RZ%qFz3vLMTn1& zyNe4r&UJL)J^@>_49O?(;PM9r7t|vqCFM0W^&o3ldK&u$rZn~Uv-GsIx3ttV*DMD4 zCnpEl7JC~TP_9r{QGrA{I|l;;2g6E`cSImX4%j>3@B-Nqlai92lamjzrKP2v8RQq1 zDNWO-bIf6$&N8L3pSh>8ow;Qx$WJ9D`B2-y=@=>SFMuhp3*p7U{2HY>C9lOR)9QKQ&V120!?q=Xo3cwKBx|X@je3fn%$s1r&hHQ<&SzcHw0t@Hnx^H;S-@7VnLcF-+;{L; z3l9kaB}98r*#k?5{9p^&7*>N)2spt*vMsXbKp_cAge@&SJ^fRrOb6M>yrgkCAIL)H zCF|zTnS*2>I8COfq<{j`ACm4NDH2>x@bIuPFt9PK1^EvYmMH#%CXxJ-lA4-&m~C_B z%m-Psi*cEMKx@KJ%PaFh4@m3n&|ay$FdveUKNSsRcBwz_1=zOiTI>f#;Yu2-DY1+P>ZBNto?JQt> z*MWRGXAan2P_Y8d7xAFd3zSYlMG7caK!X-+?M8^T@+$D4#q=g99uc-OZ)x1lyQgtG z^OlY4*Q{B-WC=7r+gn;dL7NXM`C-Wwo_IhZ%frLY0`e(F$bw6JNPdTVw13JJm_I=l zvg~Qx&vv9~|9+M|%v&}f*$c{);1GrsHQ}J@7*u$IN@+-ji5j@#A`mNC7}mi8 zR|R4xsAvNfqo6bdPPUL#JAKZaB}! z67C13V32jWC)?3UVKW_)w z4$88S&;}Js{vn_kPS1g+D_8_CU$bV*mhF4?A31XT%$f6CR~pYVpVMoSc^|0fqGTJ$oS5GGA%D&T^;e`gP_j%x5-3 zZHM@JI;cDbC$D8Fqpq8eFSEd=0ZbB?S`X5ZkAN$|#Vh z_kcWo=FIskSFUs3VZO5U%$egyj(`%`dPr8DG6fXeh}4Z~u?P zZG%dy`Ae3sS-%DBYlyvf?%co6{G{*yTehrOgBt9R=!V&E1B-4@ z^A~LYE>!ywu?_V&#C}lL0{I&h*~ibExpL+Dojdp0pX|JU=gyTY=g*u0c^(w!%fa~z z7UdwjQ$U3nB+4=D-hs<*M2z=g&8DwmV-kc7V`ux|3%pI2+JYie*VgpJ9nNudGqG|moM+%ym|iQKG=R}=tE+jX#01Q zWB>I#_n$m}^M>Wi?)Purfcy_id638_(R#AH53&CJm+ybRd>KglzkH|Iezbg#$amP% z9xVE=L!+M=6#k&-ze9HT?;|z(k3iD?6HxrWf6x48Cn)nllK&Az!9(rjHwTgTLH2_Z zz?0{!Z+3w!2NylC%m*rY<`8W=xVT4@y6B-_gIel=O8euW!v4;k`^-<6pEEz%0m}JT zAmtt?>w|0u)i&)dSgJaVat~{n8v%ix zNTCO@98~B+8W%oT3q5$Di_)4xwH#6KfJ;3{iO+I}`9AZV9oL}+K3bWFZaJcwg|?@_ zbv(FbgJ@eIS9YMb1+12Z#yTk3gPIngDxUq$PKeE*2;T#%Yfxf5Jq6-#gw==|o`qpE zX7d8MSp)9+fGQh!X}|x-5#}?E=b5jtTxYqm{XD3W0ax+hDi#*vEs*vcsBrPNyPzfQf-AaB_V!Z0%|+M+OOb|0n`dsT?N_G+py(w zcuFg;fdu#zQ1uRN%z+v<$63y>o@Y73d}I^2NwFSOv_m}H18Pl`m*7cb;0Ej#WNS@8 zJ!w#P2$aSkr5iMVL7P+SL5)aAyO{&hU~k^PXAkq1wUAaExF-fmUNw+96*-bk&|A(R zi_w~Kuvi8MHQdAVK?MucX4WID$63H#6y`1KK$e0#W8hW2<{dw0k_jZjVExbf(3F2tn~!yoIoQN+ymSI zvKF}zbAg01C|!a3MIg_D`(lue(RxT1kZnKfo-L5>5JpcI>QyYwMM!6im0<-agdvvd zfJQPwgIbUf1~(YXLA?`DPj?FQoMv!;z7cFK7pQ*?@9RPaFCeKH+O3CnNe}@HEjGa2 zYs63*sC5p>K|YXyM^J)78o6Me!@PufP2+mjEo|Fa!QJ`w5Km4A)eZ2@HF)?A7P|(7Lg1}>3kkPbwP=5dvrQkjoXkZ3pVIySNf*WifXxL&c#DmZj1Wvc0 z!U;P11RgGgBwTPO7i{AyShzxqWk{6-9$QTZbwR)Z3mSZy0v>zi~{zdxe3UJ&>#g52CWC#2hAyvLdgZ<#TbYeAz=!!5HxDR0vhe&UegF2>{<;U zd;)cHzypWi7zA}`q5gxFM4-VZc7`>e5JgHiNd8L!^`%kl0}te}E@5BJ3LaSl4IHk7 z46VU!gAR2;#|@$5PT=4KkL5vwQwB0I14=On@4>gv zbIW3|UGR{E4&y;bdZB|q;4#V-;K>hIY5|Y#gU4dPJ$7WvU}K_ebJ*vzLdIWPK;B|* zS%PdAIGMnsO$R=z%nlk=UWzmz3W_)IC_H$S5}GzaV_fx+@mKJWG7rci$e8j<_{b}G zI20U&*u4d|YB7?(z!4j#Z}ox(Al4LqO>8oOQwAG?MQ*@b|T26#Lk z99fWp3^aJn$*=(8CwOFm{RE%BfKM!dY+?ZomGeRdQ@R%6TEDU6pq!B#u&(_1y&jy)V08NxE0gteP2IXLufJ!QG zVt_{w4<~3cW;Wb2pfMwGY5*ra&}0nAk`~aQHFPefv7HZO1!STGH06Ub7XunM1_v05 zPr#NSq6R$i2$^mJ6q1xT!br%6D=ed&l)C1=k*4;TW0*sjeWrlMooztH zn+~YFfy^0lgQg@Akqr(aNJK!*W{!c(>ow&=Oy>tp=pkkep>v+hK2xElBSHt{bZ*dO zDlD48X$d^N15Qlf)P$HzZOmsY;VNeo{|z&q6*QyD4>B7%R|}e8o&%n|0ZjqGXTw1QxR8M11Hf)r*QW)-+uf}qtX{b*)E zmbE}uqp*Nhez1pdhqH$?`m;dRkbs=k0`ez{Q9_^W*OM(Co$0SDP|t%!Yj~vE$G^(CUbM};wK>&X0*jmpmk!<#aH5>g7c8G>1d3or1JFqo!kd=Ih)p?+m zexS8;A|T~#Dvk2UYx(3E7!<*4-I; zEY2nZSz@Q0V3&|nEC(Z#{2g%CQ$gT-mM%%>B&dS5gFA5T5<7s5q0j;ZTVrS>z g;pb-ut)85r227#P^%85r177#P?x85r2|7#P?} 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 z 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Flare6.bw b/lib/glut-3.7.6/progs/demos/glflare/Flare6.bw new file mode 100644 index 0000000000000000000000000000000000000000..8612cb3514ec2b7b738f60f4adf39c077d0d7cf1 GIT binary patch literal 10540 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine0.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine0.bw new file mode 100644 index 0000000000000000000000000000000000000000..2a1182580f272bbf697ea9b7d5158c5cd94a92fb GIT binary patch literal 5756 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 IkN`IG0Ln!H5dZ)H literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine1.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine1.bw new file mode 100644 index 0000000000000000000000000000000000000000..be760792ae567b3f62dacfed1189b566931c11ec GIT binary patch literal 6254 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 R!NWru&CYJmz(D%25dhYSpostg literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine2.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine2.bw new file mode 100644 index 0000000000000000000000000000000000000000..bf45ab484ff4c26010a5dde76b448a40f41134f1 GIT binary patch literal 5880 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 K(0C*QVLSjLTN*_G literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine3.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine3.bw new file mode 100644 index 0000000000000000000000000000000000000000..cac1866e62e97757325eb7030907d0e19e57dd8e GIT binary patch literal 6258 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine4.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine4.bw new file mode 100644 index 0000000000000000000000000000000000000000..c1ba95a8b0516688f54325c4c1027b8054590ab2 GIT binary patch literal 5884 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 Lj}-$0?FJ_R@nl!6 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine5.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine5.bw new file mode 100644 index 0000000000000000000000000000000000000000..bff6f7044fb6aa29e3329cc5e8d11cb14fecca26 GIT binary patch literal 6021 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 A<^TWy literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine6.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine6.bw new file mode 100644 index 0000000000000000000000000000000000000000..decca9efefdef5078776fad535431de0faa3d8f9 GIT binary patch literal 5806 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 AEC2ui literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine7.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine7.bw new file mode 100644 index 0000000000000000000000000000000000000000..91f51226476b6c7351d9e60fd482919aed0964da GIT binary patch literal 6152 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/Shine8.bw b/lib/glut-3.7.6/progs/demos/glflare/Shine8.bw new file mode 100644 index 0000000000000000000000000000000000000000..b17eb331f3465a13ebc7fdc828ecb049b81b7665 GIT binary patch literal 5930 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 literal 0 HcmV?d00001 diff --git a/lib/glut-3.7.6/progs/demos/glflare/glflare.c b/lib/glut-3.7.6/progs/demos/glflare/glflare.c new file mode 100644 index 0000000000..c98f098323 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glflare/glflare.c @@ -0,0 +1,331 @@ + +/* This source code is based on Direct3D-based code written by Stephen + Coy of Microsoft. All credit for the original implementation of the + idea should go to Stephen. While I referenced Stephen's code during + the writing of my code, my code was completely written by me from + scratch. The algorithms are basically the same to ease critical + comparison of the OpenGL and Direct3D versions. */ + +/* The image files used by this program are derived from images + developed by Microsoft. */ + +#include +#include +#include +#include +#include + +#if !defined(GL_VERSION_1_1) +/* Assume the texture object extension is supported. */ +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#endif + +#include "loadlum.h" + +GLfloat red[3] = {1.0, 0.0, 0.0}; +GLfloat green[3] = {0.0, 1.0, 0.0}; +GLfloat blue[3] = {0.0, 0.0, 1.0}; +GLfloat from[3] = {0.0, 0.0, 20.0}; +GLfloat at[3] = {0.0, 0.0, 0.0}; +GLfloat near_clip = 1.0; +int useMipmaps = 0, verbose = 0; +GLuint logoTex, flareTex[6], shineTex[10]; + +typedef struct t_flare { + int type; /* flare texture index, 0..5 */ + float scale; + float loc; /* postion on axis */ + GLfloat color[3]; +} Flare; + +Flare +set_flare(int type, float location, float scale, GLfloat color[3], float colorScale) +{ + Flare ret; + + ret.type = type; + ret.loc = location; + ret.scale = scale; + ret.color[0] = color[0] * colorScale; + ret.color[1] = color[1] * colorScale; + ret.color[2] = color[2] * colorScale; + return ret; +} + +Flare flare[20]; +int num_flares = 0; +static float tic = 0.0; +float position[3]; +int shine_tic = 0; + +void +init_flares(void) +{ + /* Shines */ + flare[0] = set_flare(-1, 1.0, 0.3, blue, 1.0); + flare[1] = set_flare(-1, 1.0, 0.2, green, 1.0); + flare[2] = set_flare(-1, 1.0, 0.25, red, 1.0); + + /* Flares, ordered to eliminate redundant texture binds */ + flare[3] = set_flare(1, 0.5, 0.2f, red, 0.3); + flare[4] = set_flare(2, 1.3, 0.04f, red, 0.6); + flare[5] = set_flare(3, 1.0, 0.1f, red, 0.4); + flare[6] = set_flare(3, 0.2, 0.05f, red, 0.3); + flare[7] = set_flare(0, 0.0, 0.04f, red, 0.3); + flare[8] = set_flare(5, -0.25, 0.07f, red, 0.5); + flare[9] = set_flare(5, -0.4, 0.02f, red, 0.6); + flare[10] = set_flare(5, -0.6, 0.04f, red, 0.4); + flare[11] = set_flare(5, -1.0, 0.03f, red, 0.2); + num_flares = 12; +} + +#include "vec3d.c" /* Simple 3D vector math routines. */ + +void +DoFlares(GLfloat from[3], GLfloat at[3], GLfloat light[3], GLfloat near_clip) +{ + GLfloat view_dir[3], tmp[3], light_dir[3], position[3], dx[3], dy[3], + center[3], axis[3], sx[3], sy[3], dot, global_scale = 1.5; + GLuint bound_to = 0; + int i; + + /* view_dir = normalize(at-from) */ + vdiff(view_dir, at, from); + vnorm(view_dir); + + /* center = from + near_clip * view_dir */ + vscale(tmp, view_dir, near_clip); + vadd(center, from, tmp); + + /* light_dir = normalize(light-from) */ + vdiff(light_dir, light, from); + vnorm(light_dir); + + /* light = from + dot(light,view_dir)*near_clip*light_dir */ + dot = vdot(light_dir, view_dir); + vscale(tmp, light_dir, near_clip / dot); + vadd(light, from, light_dir); + + /* axis = light - center */ + vdiff(axis, light, center); + vcopy(dx, axis); + + /* dx = normalize(axis) */ + vnorm(dx); + + /* dy = cross(dx,view_dir) */ + vcross(dy, dx, view_dir); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_DITHER); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + for (i = 0; i < num_flares; i++) { + vscale(sx, dx, flare[i].scale * global_scale); + vscale(sy, dy, flare[i].scale * global_scale); + + glColor3fv(flare[i].color); + /* Note logic below to eliminate duplicate texture binds. */ + if (flare[i].type < 0) { + if (bound_to) + glEnd(); + glBindTexture(GL_TEXTURE_2D, shineTex[shine_tic]); + bound_to = shineTex[shine_tic]; + shine_tic = (shine_tic + 1) % 10; + glBegin(GL_QUADS); + } else { + if (bound_to != flareTex[flare[i].type]) { + glEnd(); + glBindTexture(GL_TEXTURE_2D, flareTex[flare[i].type]); + bound_to = flareTex[flare[i].type]; + glBegin(GL_QUADS); + } + } + + /* position = center + flare[i].loc * axis */ + vscale(tmp, axis, flare[i].loc); + vadd(position, center, tmp); + + glTexCoord2f(0.0, 0.0); + vadd(tmp, position, sx); + vadd(tmp, tmp, sy); + glVertex3fv(tmp); + + glTexCoord2f(1.0, 0.0); + vdiff(tmp, position, sx); + vadd(tmp, tmp, sy); + glVertex3fv(tmp); + + glTexCoord2f(1.0, 1.0); + vdiff(tmp, position, sx); + vdiff(tmp, tmp, sy); + glVertex3fv(tmp); + + glTexCoord2f(0.0, 1.0); + vadd(tmp, position, sx); + vdiff(tmp, tmp, sy); + glVertex3fv(tmp); + } + glEnd(); +} + +void +DoBackground(void) +{ + glEnable(GL_DITHER); + glDisable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, logoTex); + + glBegin(GL_QUADS); + glColor3f(0.0, 0.0, 1.0); + glTexCoord2f(0.075, 0.1); + glVertex3f(-11.0, -7.0, 0.0); + + glColor3f(0.8, 0.8, 1.0); + glTexCoord2f(1.0, 0.1); + glVertex3f(11.0, -7.0, 0.0); + + glColor3f(0.0, 0.0, 1.0); + glTexCoord2f(1.0, 0.9); + glVertex3f(11.0, 7.0, 0.0); + + glColor3f(0.0, 0.5, 1.0); + glTexCoord2f(0.075, 0.9); + glVertex3f(-11.0, 7.0, 0.0); + glEnd(); +} + +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + position[0] = sin(tic * 0.73) * 6; + position[1] = 4.0 + 8.0 * sin(tic * 0.678); + position[2] = sin(tic * 0.895) * 6; + DoBackground(); + DoFlares(from, at, position, near_clip); + + glutSwapBuffers(); +} + +void +idle(void) +{ + tic += 0.08f; + glutPostRedisplay(); +} + +void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); +} + +void +setup_texture(char *filename, GLuint texobj, + GLenum minFilter, GLenum maxFilter) +{ + unsigned char *buf; + int width, height, components; + + glBindTexture(GL_TEXTURE_2D, texobj); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter); + if (verbose) + printf("Loading %s:", filename); + buf = load_luminance(filename, &width, &height, &components); + if (verbose) + printf(" %dx%dx%d\n", width, height, components); + if (useMipmaps) + gluBuild2DMipmaps(GL_TEXTURE_2D, 1, width, height, + GL_LUMINANCE, GL_UNSIGNED_BYTE, buf); + else + glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, buf); + free(buf); +} + +void +load_textures(void) +{ + char filename[256]; + GLenum minFilter, maxFilter; + int id = 1, i; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if (useMipmaps) { + minFilter = GL_LINEAR_MIPMAP_LINEAR; + maxFilter = GL_LINEAR; + } else { + minFilter = GL_LINEAR; + maxFilter = GL_LINEAR; + } + logoTex = id; + setup_texture("OpenGL.bw", logoTex, minFilter, maxFilter); + id++; + + if (!useMipmaps) { + minFilter = GL_NEAREST; + maxFilter = GL_NEAREST; + } + for (i = 0; i < 10; i++) { + shineTex[i] = id; + sprintf(filename, "Shine%d.bw", i); + setup_texture(filename, shineTex[i], minFilter, maxFilter); + id++; + } + for (i = 0; i < 6; i++) { + flareTex[i] = id; + sprintf(filename, "Flare%d.bw", i + 1); + setup_texture(filename, flareTex[i], minFilter, maxFilter); + id++; + } +} + +int +main(int argc, char **argv) +{ + int i; + + glutInit(&argc, argv); + for (i=1; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=glflare - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "glflare.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "glflare.mak" CFG="glflare - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "glflare - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "glflare - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "glflare - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "glflare - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "glflare - Win32 Release" +# Name "glflare - Win32 Debug" +# Begin Source File + +SOURCE=.\glflare.c +# End Source File +# Begin Source File + +SOURCE=.\loadlum.c +# End Source File +# Begin Source File + +SOURCE=.\loadlum.h +# End Source File +# Begin Source File + +SOURCE=.\vec3d.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/glflare/loadlum.c b/lib/glut-3.7.6/progs/demos/glflare/loadlum.c new file mode 100644 index 0000000000..e3a4676e91 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glflare/loadlum.c @@ -0,0 +1,182 @@ + +/* texture.c - by David Blythe, SGI */ + +/* load_luminace is a simplistic routine for reading an SGI .bw image file. */ + +#include +#include +#include + +#include "loadlum.h" + +typedef struct _ImageRec { + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short xsize, ysize, zsize; + unsigned int min, max; + unsigned int wasteBytes; + char name[80]; + unsigned long colorMap; + FILE *file; + unsigned char *tmp; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +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, 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) { + perror(fileName); + exit(1); + } + 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, "Out 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, "Out 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); + } +} + +unsigned char * +load_luminance(char *name, int *width, int *height, int *components) +{ + unsigned char *base, *lptr; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if (!image) + return NULL; + if (image->zsize != 1) + return NULL; + + *width = image->xsize; + *height = image->ysize; + *components = image->zsize; + + base = (unsigned char *) + malloc(image->xsize * image->ysize * sizeof(unsigned char)); + if (!base) + return NULL; + lptr = base; + for (y = 0; y < image->ysize; y++) { + ImageGetRow(image, lptr, y, 0); + lptr += image->xsize; + } + ImageClose(image); + return base; +} diff --git a/lib/glut-3.7.6/progs/demos/glflare/loadlum.h b/lib/glut-3.7.6/progs/demos/glflare/loadlum.h new file mode 100644 index 0000000000..9c825f26d7 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glflare/loadlum.h @@ -0,0 +1,11 @@ + +/* texture.h - by David Blythe, SGI */ + +/* Simple SGI .bw image file loader routine. */ + +extern unsigned char * load_luminance( + char *name, + int *width, + int *height, + int *components); + diff --git a/lib/glut-3.7.6/progs/demos/glflare/vec3d.c b/lib/glut-3.7.6/progs/demos/glflare/vec3d.c new file mode 100644 index 0000000000..af52f98bca --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glflare/vec3d.c @@ -0,0 +1,73 @@ + +/* 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. */ + +/* Simple 3D vector routines. This file is meant to be included in + a .c file, hence all the routines are defined statically. A + good C compiler should be able to automatically inline all + these routines. */ + +#include + +static void +vnorm(float vec[3]) +{ + float len; + + len = (float)sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]); + vec[0] = vec[0] / len; + vec[1] = vec[1] / len; + vec[2] = vec[2] / len; +} + +static float +vdot(float a[3], float b[3]) +{ + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +static void +vdiff(float dst[3], float a[3], float b[3]) +{ + dst[0] = a[0] - b[0]; + dst[1] = a[1] - b[1]; + dst[2] = a[2] - b[2]; +} + +static void +vadd(float dst[3], float a[3], float b[3]) +{ + dst[0] = a[0] + b[0]; + dst[1] = a[1] + b[1]; + dst[2] = a[2] + b[2]; +} + +static void +vcopy(float dst[3], float src[3]) +{ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; +} + +static void +vscale(float dst[3], float src[3], float scale) +{ + dst[0] = src[0] * scale; + dst[1] = src[1] * scale; + dst[2] = src[2] * scale; +} + +static void +vcross(float cross[3], const float v1[3], const float v2[3]) +{ + float tmp[3]; + + tmp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + tmp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + tmp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + vcopy(cross, tmp); +} diff --git a/lib/glut-3.7.6/progs/demos/gliq/Imakefile b/lib/glut-3.7.6/progs/demos/gliq/Imakefile new file mode 100644 index 0000000000..f3feaad94f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/Imakefile @@ -0,0 +1,29 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../../Glut.cf" + +TARGETS = gliq + +SRCS = board.c game.c gliq.c pick.c score.c tb.c trackball.c + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(gliq,board.o game.o gliq.o pick.o score.o tb.o trackball.o) + +LinkFile(trackball.c, ../../examples/trackball.c) +LinkFile(trackball.h, ../../examples/trackball.h) + +trackball.o: trackball.h +tb.o: trackball.h +gliq.h: trackball.h +board.c: gliq.h +game.c: gliq.h +gliq.c: gliq.h +pick.c: gliq.h +score.c: gliq.h + +/* some old imake configs do setup "make depend" dependencies on linked files */ +depend:: trackball.c trackball.h tb.c tb.h + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/gliq/board.c b/lib/glut-3.7.6/progs/demos/gliq/board.c new file mode 100644 index 0000000000..c6c77f1c34 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/board.c @@ -0,0 +1,343 @@ +/* + * CS 453 - Final project : An OpenGL version of the pegboard game IQ + * Due : June 5, 1997 + * Author : Kiri Wagstaff + * + * File : board.c + * Description : Contains the board readin and selection functions. + * + * + */ + +#include "gliq.h" + +/* functions */ +void selectboard(void); +void readboards(void); +void drawboard(void); +void drawpegs(void); /* Draw all the pegs */ +void drawpeg(void); /* Draw one peg */ +void displaybuttons(void); + +/* globals */ +int numboards, curboard; +int*** boards; +int filled[BOARDSIZE][BOARDSIZE]; /* Current state of the pegs */ + +/* Define the board */ +GLfloat vertices[8*3] = { + -5.0,0.0,5.0, + 5.0,0.0,5.0, + 5.0,0.5,5.0, + -5.0,0.5,5.0, + -5.0,0.0,-5.0, + 5.0,0.0,-5.0, + 5.0,0.5,-5.0, + -5.0,0.5,-5.0 +}; + +GLuint faces[6*4] = { + 0,1,2,3, /*front*/ + 0,3,7,4, /*left*/ + 0,4,5,1, /*bottom*/ + 1,5,6,2, /*right*/ + 3,2,6,7, /*top*/ + 4,7,6,5 /*back*/ +}; + +GLfloat normals[6*3] = { + 0.0, 0.0, 1.0, + -1.0, 0.0, 0.0, + 0.0, -1.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, -1.0, +}; + + +void selectboard(void) +{ + int height=glutGet(GLUT_WINDOW_HEIGHT); + int width=glutGet(GLUT_WINDOW_WIDTH); + static float spin=0.0; + + /* Eventually make it spin */ + /* Display the buttons */ + displaybuttons(); + /* Draw the quit button */ + drawquit(7.0, 9.0, 0.4, 1.0); + /* Quit */ + glColor3f(1.0, 1.0, 1.0); /* white */ + /* text(0.78*width, 0.89*height, 0.1*height, "Quit"); */ + /* Select message */ + glColor3f(0.0, 1.0, 0.0); + text(0.3*width, 0.9*height, 0.07*height, "Select a board"); + + /* Draw the total # of pegs */ + glPushMatrix(); + glColor3f(1.0, 1.0, 0.0); /* yellow */ + glTranslatef(-7.8, 8.8, 0.0); + drawpeg(); + text(0.1*width, 0.9*height, 0.07*height, ": %02d", totalpegs); + glPopMatrix(); + + /* do the trackball rotation. */ + glPushMatrix(); + /* tbMatrix(); */ + glRotatef(45.0, 1.0, 0.0, 0.0); + glRotatef(spin, 0.0, 1.0, 0.0); + drawboard(); + drawpegs(); + glPopMatrix(); + spin++; +} + +void readboards(void) +{ + int i, j, hole; + FILE* fp; + + /* Read in the boards */ + fp = fopen("boards.txt", "r"); + if (!fp) + { + printf("Could not open boards.txt, exiting.\n"); + exit(1); + } + fscanf(fp, "%d", &numboards); + boards = (int***)malloc(numboards*sizeof(int**)); + for (i=0; i0) && (filled[i-1][j]==FULL) && (filled[i-2][j]==EMPTY)) + return 1; + else if ((i+20) && (filled[i][j-1]==FULL) && (filled[i][j-2]==EMPTY)) + return 1; + else if ((j+2=numboards) + curboard = 0; + /* Set up filled array */ + for (i=0; i minpegs)) + { + curstate = HIGHSC; + numentered = 0; + written = 0; + glutKeyboardFunc(keyscores); + glutIdleFunc(idlescore); + break; + } + curstate = SELBOARD; + glutIdleFunc(idle); + totalpegs = 0; + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gliq - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gliq.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gliq.mak" CFG="gliq - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gliq - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gliq - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gliq - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "gliq - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gliq - Win32 Release" +# Name "gliq - Win32 Debug" +# Begin Source File + +SOURCE=.\board.c +# End Source File +# Begin Source File + +SOURCE=.\game.c +# End Source File +# Begin Source File + +SOURCE=.\gliq.c +# End Source File +# Begin Source File + +SOURCE=.\gliq.h +# End Source File +# Begin Source File + +SOURCE=.\pick.c +# End Source File +# Begin Source File + +SOURCE=.\score.c +# End Source File +# Begin Source File + +SOURCE=.\trackball.c +# End Source File +# Begin Source File + +SOURCE=.\trackball.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/gliq/gliq.h b/lib/glut-3.7.6/progs/demos/gliq/gliq.h new file mode 100644 index 0000000000..fa30f48d4d --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/gliq.h @@ -0,0 +1,75 @@ +/* + * CS 453 - Final project : An OpenGL version of the pegboard game IQ + * Due : June 5, 1997 + * Author : Kiri Wagstaff + * + * File : gliq.h + * Description : Main header file + * + */ + +#ifndef GLIQ_H +#define GLIQ_H + +#include +#include +#include +#include +#include "trackball.h" + +/* defines */ +#define BOARDSIZE 9 /* on a side, total of 81 holes */ +#define SELECT_BUFFER 256 + +/* enums */ +enum {UNUSED, EMPTY, FULL, CANMOVE, CANTMOVE}; /* for each hole */ +enum {SELBOARD, PLAY, HIGHSC, VIEWSCORES}; /* current state */ +enum {NONE, LEFTARR=100, SELECT, RIGHTARR, QUIT}; /* board selection */ + +/* from gliq.c */ +extern int curstate; +extern int lastpicked; +extern int pegs; +extern int totalpegs; +extern void display(void); + +/* from board.c */ +extern int*** boards; +extern int curboard; +extern int numboards; +extern int filled[BOARDSIZE][BOARDSIZE]; +extern void selectboard(void); +extern void readboards(void); +extern void drawboard(void); +extern void drawpegs(void); +extern void drawpeg(void); +extern void displaybuttons(void); + +/* from game.c */ +extern int playdone; +extern void playgame(void); +extern int legalmove(void); +extern int canmove(int peg); +extern int movesexist(void); +extern void drawquit(float x, float y, float r1, float r2); + +/* from score.c */ +extern int minscore; +extern int minpegs; +extern int numentered; +extern int written; +extern void highscore(void); +extern void readscores(void); +extern void showhighscores(void); +extern void keyscores(unsigned char key, int x, int y); +extern void idlescore(void); + +/* from pick.c */ +extern int picked; +extern GLuint select_buffer[]; +extern GLboolean selection; +extern GLuint pick(int x, int y); +extern void passive(int x, int y); +extern void text(GLfloat x, GLfloat y, GLfloat scale, char *format, ...); + +#endif diff --git a/lib/glut-3.7.6/progs/demos/gliq/pick.c b/lib/glut-3.7.6/progs/demos/gliq/pick.c new file mode 100644 index 0000000000..b72f419068 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/pick.c @@ -0,0 +1,171 @@ +/* + * CS 453 - Final project : An OpenGL version of the pegboard game IQ + * Due : June 5, 1997 + * Author : Kiri Wagstaff + * + * File : pick.c + * Description : Routines for picking ability. MANY thanks to Nate + * Robins since all of this code is his. I couldn't + * have done it without him. :) + * + */ + +#include +#include "gliq.h" + +int picked=0; /* Which piece has been selected? */ +GLuint select_buffer[SELECT_BUFFER]; +GLboolean selection = GL_FALSE; + +GLuint pick(int x, int y); +void passive(int x, int y); + +GLuint pick(int x, int y) +{ + GLuint i, hits, num_names, picked; + GLuint* p; + GLboolean save; + GLuint depth = (GLuint)-1; + GLint viewport[4]; + int height = glutGet(GLUT_WINDOW_HEIGHT); + int width = glutGet(GLUT_WINDOW_WIDTH); + + /* fill in the current viewport parameters */ + viewport[0] = 0; + viewport[1] = 0; + viewport[2] = width; + viewport[3] = height; + + /* set the render mode to selection */ + glRenderMode(GL_SELECT); + selection = GL_TRUE; + glInitNames(); + glPushName(0); + + /* setup a picking matrix and render into selection buffer */ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + gluPickMatrix(x, viewport[3] - y, 5.0, 5.0, viewport); + gluPerspective(60.0, (GLfloat)viewport[3]/(GLfloat)viewport[2], 1.0, 128.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, -2.0, -15.0); + + switch(curstate) + { + case SELBOARD: + /* Draw the quit button */ + drawquit(7.0, 9.0, 0.4, 1.0); + displaybuttons(); + break; + case PLAY: + /* Draw the quit button */ + drawquit(7.0, 9.0, 0.4, 1.0); + glPushMatrix(); + glRotatef(45.0, 1.0, 0.0, 0.0); + tbMatrix(); + drawpegs(); + glPopMatrix(); + break; + case HIGHSC: + break; + case VIEWSCORES: + break; + default: + printf("Unknown state %d, exiting.\n", curstate); + exit(1); + } + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + hits = glRenderMode(GL_RENDER); + + selection = GL_FALSE; + + p = select_buffer; + picked = 0; + for (i = 0; i < hits; i++) { + save = GL_FALSE; + num_names = *p; /* number of names in this hit */ + p++; + + if (*p <= depth) { /* check the 1st depth value */ + depth = *p; + save = GL_TRUE; + } + p++; + if (*p <= depth) { /* check the 2nd depth value */ + depth = *p; + save = GL_TRUE; + } + p++; + + if (save) + picked = *p; + + p += num_names; /* skip over the rest of the names */ + } + + return picked; +} + +void passive(int x, int y) +{ + picked = pick(x,y); + glutPostRedisplay(); +} + +/* text: general purpose text routine. draws a string according to + * format in a stroke font at x, y after scaling it by the scale + * specified (scale is in window-space (lower-left origin) pixels). + * + * x - position in x (in window-space) + * y - position in y (in window-space) + * scale - scale in pixels + * format - as in printf() + */ +void +text(GLfloat x, GLfloat y, GLfloat scale, char* format, ...) +{ + va_list args; + char buffer[255], *p; + GLfloat font_scale = 119.05 + 33.33; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT)); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glTranslatef(x, y, 0.0); + + glScalef(scale/font_scale, scale/font_scale, scale/font_scale); + + for(p = buffer; *p; p++) + glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); + + glPopAttrib(); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + + diff --git a/lib/glut-3.7.6/progs/demos/gliq/score.c b/lib/glut-3.7.6/progs/demos/gliq/score.c new file mode 100644 index 0000000000..e3b347d67c --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/score.c @@ -0,0 +1,277 @@ +/* + * CS 453 - Final project : An OpenGL version of the pegboard game IQ + * Due : June 5, 1997 + * Author : Kiri Wagstaff + * + * File : score.c + * Description : Maintains and adds to highscores. + * + */ + +#include "gliq.h" + +int scores[10]; +int totpegs[10]; +char inits[10][4]; +int minscore=0; +int minpegs=100; +char newinits[3]; +int numentered=0; +int written=0; +float color1=1.0, color2=1.0, color3=0.0; +int lasthigh=-1; + +void highscore(void); +void readscores(void); +void showhighscores(void); +void keyscores(unsigned char key, int x, int y); + +void highscore(void) +{ + int i, j; + int width = glutGet(GLUT_WINDOW_WIDTH); + int height = glutGet(GLUT_WINDOW_HEIGHT); + FILE* fp; + + /* Prompt for initials */ + glColor3f(1.0, 1.0, 0.0); /* yellow */ + text(0.08*width, 0.85*height, 0.1*height, "CONGRATULATIONS!"); + glColor3f(1.0, 0.0, 0.0); /* red */ + text(0.05*width, 0.7*height, 0.07*height, "You made it into the top 10!"); + glColor3f(1.0, 1.0, 0.0); /* yellow */ + text(0.2*width, 0.55*height, 0.07*height, "%02d remaining of %02d", + pegs, totalpegs); + glColor3f(0.0, 0.0, 1.0); /* blue */ + text(0.13*width, 0.4*height, 0.07*height, "Please enter your initials:"); + + /* Display what's been entered */ + glColor3f(color1, color2, color3); + for (i=0; itotpegs[i]))) + break; + for (j=9; j>i; j--) + { + if (scores[j-1]==-1 || scores[j-1]==0) + continue; +#if 0 +// printf("compare : "); +// printf(" %s %02d %02d\n", inits[j], scores[j], totpegs[j]); +#endif + scores[j] = scores[j-1]; + totpegs[j] = totpegs[j-1]; + inits[j][0] = inits[j-1][0]; + inits[j][1] = inits[j-1][1]; + inits[j][2] = inits[j-1][2]; + inits[j][3] = inits[j-1][3]; +#if 0 +// printf("with : "); +// printf(" %s %02d %02d\n", inits[j], scores[j], totpegs[j]); +#endif + } +#if 0 +// printf("Storing in index %d\n", i); +#endif + lasthigh=i; + scores[i] = pegs; + totpegs[i] = totalpegs; + inits[i][0] = newinits[0]; + inits[i][1] = newinits[1]; + inits[i][2] = newinits[2]; + inits[i][3] = 0; + + /* get the new min */ + for (j=9; j>0; j--) + if (scores[j]==-1 || scores[j]==0) + continue; + else + { + minscore = scores[j]; + minpegs = totpegs[j]; + break; + } +#if 0 +// printf("New minscore %d, minpegs %d\n", minscore, minpegs); +#endif + fp = fopen("scores.txt", "w"); + if (!fp) + { + printf("Could not open scores.txt, exiting.\n"); + exit(1); + } + for (i=0; i<10; i++) + if (scores[i]!=-1 && scores[i]!=0) + fprintf(fp, "%02d %02d %s\n", scores[i], totpegs[i], inits[i]); + else + break; + written=1; + } + +} + +void readscores(void) +{ + int i; + FILE* fp; + + newinits[0] = 0; + newinits[1] = 0; + newinits[2] = 0; + + /* Read in the current high scores */ + fp = fopen("scores.txt", "r"); + if (!fp) + { + printf("Could not open scores.txt, exiting.\n"); + exit(1); + } + for (i=0; i<10; i++) + { + /* Pegs remaining */ + if ((fscanf(fp, "%d", &(scores[i])))!=1) + { + scores[i] = -1; + break; + } + /* Total pegs */ + if ((fscanf(fp, "%d", &(totpegs[i])))!=1) + { + totpegs[i] = -1; + break; + } + fscanf(fp, "%s", inits[i]); +#if 0 +// printf("read %s\n", inits[i]); +#endif + } + if (i>0) + { + minscore = scores[i-1]; + minpegs = totpegs[i-1]; + } + + if (i<10) + { + minscore=100; + minpegs=0; + } +#if 0 +// printf("Minscore is %d, minpegs is %d\n", minscore, minpegs); +#endif +} + +void showhighscores(void) +{ + int i; + int width = glutGet(GLUT_WINDOW_WIDTH); + int height = glutGet(GLUT_WINDOW_HEIGHT); + + /* Display the current highs */ + glColor3f(1.0, 1.0, 0.0); /* yellow */ + text(0.15*width, 0.9*height, 0.07*height, "Initials Score Out of"); + for (i=0; i<10; i++) + { + if (i>=1) + glColor3f(1.0, 0.0, 0.0); /* red */ + else if (i>=5) + glColor3f(0.0, 0.0, 1.0); /* blue */ + if (scores[i]>0) + { + if (i==lasthigh) + glColor3f(color1, color2, color3); + text(0.15*width, (8.0-0.65*i)/10.0*height, 0.05*height, + " %s", inits[i]); + text(0.48*width, (8.0-0.65*i)/10.0*height, 0.05*height, + "%02d", scores[i]); + text(0.75*width, (8.0-0.65*i)/10.0*height, 0.05*height, + "%02d", totpegs[i]); + } + } + glColor3f(color1, color2, color3); + text(0.15*width, 0.1*height, 0.07*height, "Click to continue..."); + +} + +/* ARGSUSED1 */ +void keyscores(unsigned char key, int x, int y) +{ +#if 0 + if (key == '\r') /*return*/ { + + } else if (key == '\b') /*backspace*/ { + } +#endif + if (numentered>=3) + return; + newinits[numentered] = key; + numentered++; +#if 0 +// printf("Read a %c\n", key); +#endif + glutPostRedisplay(); +} + +void idlescore(void) +{ + static int hscolor=0; + + switch(hscolor) + { + case 0: + color1=1.0; + color2=0.0; + color3=0.0; + hscolor++; + break; + case 1: + color1=0.5; + color2=0.5; + color3=0.0; + hscolor++; + break; + case 2: + color1=1.0; + color2=1.0; + color3=0.0; + hscolor++; + break; + case 3: + color1=0.0; + color2=1.0; + color3=0.0; + hscolor++; + break; + case 4: + color1=0.0; + color2=0.0; + color3=1.0; + hscolor++; + break; + case 5: + color1=1.0; + color2=0.0; + color3=1.0; + hscolor=0; + break; + } + + if (curstate==HIGHSC) + highscore(); + else if (curstate==VIEWSCORES) + showhighscores(); + else + { + printf("Unknown state %d, exiting\n", curstate); + exit(1); + } + + glutPostRedisplay(); +} diff --git a/lib/glut-3.7.6/progs/demos/gliq/tb.c b/lib/glut-3.7.6/progs/demos/gliq/tb.c new file mode 100644 index 0000000000..d0b175e8c1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/tb.c @@ -0,0 +1,123 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include +#include /* SunOS 5.6 multithreaded assert() needs . Lame. */ +#include +#include +#include "trackball.h" + +/* globals */ +static GLuint tb_lasttime; + +float curquat[4]; +float lastquat[4]; +int beginx, beginy; + +static GLuint tb_width; +static GLuint tb_height; + +static GLint tb_button = -1; +static GLboolean tb_tracking = GL_FALSE; +static GLboolean tb_animate = GL_TRUE; + +static void +_tbAnimate(void) +{ + add_quats(lastquat, curquat, curquat); + glutPostRedisplay(); +} + +void +_tbStartMotion(int x, int y, int time) +{ + assert(tb_button != -1); + + glutIdleFunc(0); + tb_tracking = GL_TRUE; + tb_lasttime = time; + beginx = x; + beginy = y; +} + +void +_tbStopMotion(unsigned time) +{ + assert(tb_button != -1); + + tb_tracking = GL_FALSE; + + if (time == tb_lasttime && tb_animate) { + glutIdleFunc(_tbAnimate); + } else { + if (tb_animate) { + glutIdleFunc(0); + } + } +} + +void +tbAnimate(GLboolean animate) +{ + tb_animate = animate; +} + +void +tbInit(GLuint button) +{ + tb_button = button; + trackball(curquat, 0.0, 0.0, 0.0, 0.0); +} + +void +tbMatrix(void) +{ + GLfloat m[4][4]; + + assert(tb_button != -1); + build_rotmatrix(m, curquat); + glMultMatrixf(&m[0][0]); +} + +void +tbReshape(int width, int height) +{ + assert(tb_button != -1); + + tb_width = width; + tb_height = height; +} + +void +tbMouse(int button, int state, int x, int y) +{ + assert(tb_button != -1); + + if (state == GLUT_DOWN && button == tb_button) + _tbStartMotion(x, y, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP && button == tb_button) + _tbStopMotion(glutGet(GLUT_ELAPSED_TIME)); +} + +void +tbMotion(int x, int y) +{ + if (tb_tracking) { + trackball(lastquat, + (2.0 * beginx - tb_width) / tb_width, + (tb_height - 2.0 * beginy) / tb_height, + (2.0 * x - tb_width) / tb_width, + (tb_height - 2.0 * y) / tb_height + ); + beginx = x; + beginy = y; + tb_animate = 1; + tb_lasttime = glutGet(GLUT_ELAPSED_TIME); + _tbAnimate(); + } +} diff --git a/lib/glut-3.7.6/progs/demos/gliq/tb.h b/lib/glut-3.7.6/progs/demos/gliq/tb.h new file mode 100644 index 0000000000..e4205fb434 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/tb.h @@ -0,0 +1,95 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + * + * + * Usage: + * + * o call tbInit() in before any other tb call + * o call tbReshape() from the reshape callback + * o call tbMatrix() to get the trackball matrix rotation + * o call tbStartMotion() to begin trackball movememt + * o call tbStopMotion() to stop trackball movememt + * o call tbMotion() from the motion callback + * o call tbAnimate(GL_TRUE) if you want the trackball to continue + * spinning after the mouse button has been released + * o call tbAnimate(GL_FALSE) if you want the trackball to stop + * spinning after the mouse button has been released + * + * Typical setup: + * + * + void + init(void) + { + tbInit(GLUT_MIDDLE_BUTTON); + tbAnimate(GL_TRUE); + . . . + } + + void + reshape(int width, int height) + { + tbReshape(width, height); + . . . + } + + void + display(void) + { + glPushMatrix(); + + tbMatrix(); + . . . draw the scene . . . + + glPopMatrix(); + } + + void + mouse(int button, int state, int x, int y) + { + tbMouse(button, state, x, y); + . . . + } + + void + motion(int x, int y) + { + tbMotion(x, y); + . . . + } + + int + main(int argc, char** argv) + { + . . . + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutMotionFunc(motion); + . . . + } + * + * */ + + +/* functions */ +void +tbInit(GLuint button); + +void +tbMatrix(void); + +void +tbReshape(int width, int height); + +void +tbMouse(int button, int state, int x, int y); + +void +tbMotion(int x, int y); + +void +tbAnimate(GLboolean animate); diff --git a/lib/glut-3.7.6/progs/demos/gliq/trackball.c b/lib/glut-3.7.6/progs/demos/gliq/trackball.c new file mode 100644 index 0000000000..c2501e8f45 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/trackball.c @@ -0,0 +1,169 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + */ + + +/* includes */ +#include +#include +#include +#include "trackball.h" + + +/* globals */ +static GLuint tb_lasttime; +static GLfloat tb_lastposition[3]; + +static GLfloat tb_angle = 0.0; +static GLfloat tb_axis[3]; +static GLfloat tb_transform[4][4]; + +static GLuint tb_width; +static GLuint tb_height; + +static GLint tb_button = -1; +static GLboolean tb_tracking = GL_FALSE; +static GLboolean tb_animate = GL_TRUE; + + +/* functions */ +static void +_tbPointToVector(int x, int y, int width, int height, float v[3]) +{ + float d, a; + + /* project x, y onto a hemi-sphere centered within width, height. */ + v[0] = (2.0 * x - width) / width; + v[1] = (height - 2.0 * y) / height; + d = sqrt(v[0] * v[0] + v[1] * v[1]); + v[2] = cos((3.14159265 / 2.0) * ((d < 1.0) ? d : 1.0)); + a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] *= a; + v[1] *= a; + v[2] *= a; +} + +static void +_tbAnimate(void) +{ + glutPostRedisplay(); +} + +void +_tbStartMotion(int x, int y, int button, int time) +{ + assert(tb_button != -1); + + tb_tracking = GL_TRUE; + tb_lasttime = time; + _tbPointToVector(x, y, tb_width, tb_height, tb_lastposition); +} + +void +_tbStopMotion(int button, unsigned time) +{ + assert(tb_button != -1); + + tb_tracking = GL_FALSE; + + if (time == tb_lasttime && tb_animate) { + glutIdleFunc(_tbAnimate); + } else { + tb_angle = 0.0; + if (tb_animate) + glutIdleFunc(0); + } +} + +void +tbAnimate(GLboolean animate) +{ + tb_animate = animate; +} + +void +tbInit(GLuint button) +{ + tb_button = button; + tb_angle = 0.0; + + /* put the identity in the trackball transform */ + glPushMatrix(); + glLoadIdentity(); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform); + glPopMatrix(); +} + +void +tbMatrix() +{ + assert(tb_button != -1); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(tb_angle, tb_axis[0], tb_axis[1], tb_axis[2]); + glMultMatrixf((GLfloat *)tb_transform); + glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tb_transform); + glPopMatrix(); + + glMultMatrixf((GLfloat *)tb_transform); +} + +void +tbReshape(int width, int height) +{ + assert(tb_button != -1); + + tb_width = width; + tb_height = height; +} + +void +tbMouse(int button, int state, int x, int y) +{ + assert(tb_button != -1); + + if (state == GLUT_DOWN && button == tb_button) + _tbStartMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME)); + else if (state == GLUT_UP && button == tb_button) + _tbStopMotion(button, glutGet(GLUT_ELAPSED_TIME)); +} + +void +tbMotion(int x, int y) +{ + GLfloat current_position[3], dx, dy, dz; + + assert(tb_button != -1); + + if (tb_tracking == GL_FALSE) + return; + + _tbPointToVector(x, y, tb_width, tb_height, current_position); + + /* calculate the angle to rotate by (directly proportional to the + length of the mouse movement */ + dx = current_position[0] - tb_lastposition[0]; + dy = current_position[1] - tb_lastposition[1]; + dz = current_position[2] - tb_lastposition[2]; + tb_angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz); + + /* calculate the axis of rotation (cross product) */ + tb_axis[0] = tb_lastposition[1] * current_position[2] - + tb_lastposition[2] * current_position[1]; + tb_axis[1] = tb_lastposition[2] * current_position[0] - + tb_lastposition[0] * current_position[2]; + tb_axis[2] = tb_lastposition[0] * current_position[1] - + tb_lastposition[1] * current_position[0]; + + /* reset for next time */ + tb_lasttime = glutGet(GLUT_ELAPSED_TIME); + tb_lastposition[0] = current_position[0]; + tb_lastposition[1] = current_position[1]; + tb_lastposition[2] = current_position[2]; + + /* remember to draw new position */ + glutPostRedisplay(); +} diff --git a/lib/glut-3.7.6/progs/demos/gliq/trackball.h b/lib/glut-3.7.6/progs/demos/gliq/trackball.h new file mode 100644 index 0000000000..de0f00c6bd --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/gliq/trackball.h @@ -0,0 +1,95 @@ +/* + * Simple trackball-like motion adapted (ripped off) from projtex.c + * (written by David Yu and David Blythe). See the SIGGRAPH '96 + * Advanced OpenGL course notes. + * + * + * Usage: + * + * o call tbInit() in before any other tb call + * o call tbReshape() from the reshape callback + * o call tbMatrix() to get the trackball matrix rotation + * o call tbStartMotion() to begin trackball movememt + * o call tbStopMotion() to stop trackball movememt + * o call tbMotion() from the motion callback + * o call tbAnimate(GL_TRUE) if you want the trackball to continue + * spinning after the mouse button has been released + * o call tbAnimate(GL_FALSE) if you want the trackball to stop + * spinning after the mouse button has been released + * + * Typical setup: + * + * + void + init(void) + { + tbInit(GLUT_MIDDLE_BUTTON); + tbAnimate(GL_TRUE); + . . . + } + + void + reshape(int width, int height) + { + tbReshape(width, height); + . . . + } + + void + display(void) + { + glPushMatrix(); + + tbMatrix(); + . . . draw the scene . . . + + glPopMatrix(); + } + + void + mouse(int button, int state, int x, int y) + { + tbMouse(button, state, x, y); + . . . + } + + void + motion(int x, int y) + { + tbMotion(x, y); + . . . + } + + int + main(int argc, char** argv) + { + . . . + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutMotionFunc(motion); + . . . + } + * + * */ + + +/* functions */ +void +tbInit(GLuint button); + +void +tbMatrix(void); + +void +tbReshape(int width, int height); + +void +tbMouse(int button, int state, int x, int y); + +void +tbMotion(int x, int y); + +void +tbAnimate(GLboolean animate); diff --git a/lib/glut-3.7.6/progs/demos/glutmech/Imakefile b/lib/glut-3.7.6/progs/demos/glutmech/Imakefile new file mode 100644 index 0000000000..7b6bac3dd1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glutmech/Imakefile @@ -0,0 +1,15 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +#include "../../../Glut.cf" + +TARGETS = glutmech + +SRCS = glutmech.c +OBJS = glutmech.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(glutmech,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/glutmech/glutmech.c b/lib/glut-3.7.6/progs/demos/glutmech/glutmech.c new file mode 100644 index 0000000000..5b0193a245 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glutmech/glutmech.c @@ -0,0 +1,1764 @@ + +/** +* program : glutmech V1.1 +* author : Simon Parkinson-Bates. +* E-mail : sapb@yallara.cs.rmit.edu.au +* Copyright Simon Parkinson-Bates. +* "source if freely avaliable to anyone to copy as long as they +* acknowledge me in their work." +* +* Funtional features +* ------------------ +* * online menu system avaliable by pressing left mouse button +* * online cascading help system avaliable, providing information on +* the several key strokes and what they do. +* * animation sequence coded which makes the mech walk through an +* environment. Shadows will soon be added to make it look +* more realistic. +* * menu control to view mech in wireframe or sold mode. +* * various key strokes avaliable to control idependently the mechs +* many joints. +* * various key strokes avaliable to view mech and environment from +* different angles +* * various key strokes avaliable to alter positioning of the single +* light source. +* +* +* Program features +* ---------------- +* * uses double buffering +* * uses display lists +* * uses glut to manage windows, callbacks, and online menu. +* * uses glpolygonfill() to maintain colors in wireframe and solid +* mode. +* +**/ + +/* start of compilation conditions */ +#define SPHERE +#define COLOR +#define LIGHT +#define TORSO +#define HIP +#define SHOULDER +#define UPPER_ARM +#define LOWER_ARM +#define ROCKET_POD +#define UPPER_LEG +#define LOWER_LEG +#define NO_NORM +#define ANIMATION +#define DRAW_MECH +#define DRAW_ENVIRO +#define MOVE_LIGHT +/* end of compilation conditions */ + +/* start various header files needed */ +#include +#include +#define GLUT +#define GLUT_KEY +#define GLUT_SPEC +#include +/* end of header files */ + +/* start of display list definitions */ +#define SOLID_MECH_TORSO 1 +#define SOLID_MECH_HIP 2 +#define SOLID_MECH_SHOULDER 3 +#define SOLID_MECH_UPPER_ARM 4 +#define SOLID_MECH_FOREARM 5 +#define SOLID_MECH_UPPER_LEG 6 +#define SOLID_MECH_FOOT 7 +#define SOLID_MECH_ROCKET 8 +#define SOLID_MECH_VULCAN 9 +#define SOLID_ENVIRO 10 +/* end of display list definitions */ + +/* start of motion rate variables */ +#define ANKLE_RATE 3 +#define HEEL_RATE 3 +#define ROTATE_RATE 10 +#define TILT_RATE 10 +#define ELBOW_RATE 2 +#define SHOULDER_RATE 5 +#define LAT_RATE 5 +#define CANNON_RATE 40 +#define UPPER_LEG_RATE 3 +#define UPPER_LEG_RATE_GROIN 10 +#define LIGHT_TURN_RATE 10 +#define VIEW_TURN_RATE 10 +/* end of motion rate variables */ + +/* start of motion variables */ + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +GLUquadricObj *qobj; + +char leg = 0; + +int shoulder1 = 0, shoulder2 = 0, shoulder3 = 0, shoulder4 = 0, lat1 = 20, lat2 = 20, + elbow1 = 0, elbow2 = 0, pivot = 0, tilt = 10, ankle1 = 0, ankle2 = 0, heel1 = 0, + heel2 = 0, hip11 = 0, hip12 = 10, hip21 = 0, hip22 = 10, fire = 0, solid_part = 0, + anim = 0, turn = 0, turn1 = 0, lightturn = 0, lightturn1 = 0; + +float elevation = 0.0, distance = 0.0, frame = 3.0 + /* foot1v[] = {} foot2v[] = {} */ ; + +/* end of motion variables */ + +/* start of material definitions */ +#ifdef LIGHT +GLfloat mat_specular[] = +{0.628281, 0.555802, 0.366065, 1.0}; +GLfloat mat_ambient[] = +{0.24725, 0.1995, 0.0745, 1.0}; +GLfloat mat_diffuse[] = +{0.75164, 0.60648, 0.22648, 1.0}; +GLfloat mat_shininess[] = +{128.0 * 0.4}; + +GLfloat mat_specular2[] = +{0.508273, 0.508273, 0.508373}; +GLfloat mat_ambient2[] = +{0.19225, 0.19225, 0.19225}; +GLfloat mat_diffuse2[] = +{0.50754, 0.50754, 0.50754}; +GLfloat mat_shininess2[] = +{128.0 * 0.6}; + +GLfloat mat_specular3[] = +{0.296648, 0.296648, 0.296648}; +GLfloat mat_ambient3[] = +{0.25, 0.20725, 0.20725}; +GLfloat mat_diffuse3[] = +{1, 0.829, 0.829}; +GLfloat mat_shininess3[] = +{128.0 * 0.088}; + +GLfloat mat_specular4[] = +{0.633, 0.727811, 0.633}; +GLfloat mat_ambient4[] = +{0.0215, 0.1745, 0.0215}; +GLfloat mat_diffuse4[] = +{0.07568, 0.61424, 0.07568}; +GLfloat mat_shininess4[] = +{128 * 0.6}; + +GLfloat mat_specular5[] = +{0.60, 0.60, 0.50}; +GLfloat mat_ambient5[] = +{0.0, 0.0, 0.0}; +GLfloat mat_diffuse5[] = +{0.5, 0.5, 0.0}; +GLfloat mat_shininess5[] = +{128.0 * 0.25}; + +#endif +/* end of material definitions */ + +/* start of the body motion functions */ +void +Heel1Add(void) +{ + heel1 = (heel1 + HEEL_RATE) % 360; +} + +void +Heel1Subtract(void) +{ + heel1 = (heel1 - HEEL_RATE) % 360; +} + +void +Heel2Add(void) +{ + heel2 = (heel2 + HEEL_RATE) % 360; +} + +void +Heel2Subtract(void) +{ + heel2 = (heel2 - HEEL_RATE) % 360; +} + +void +Ankle1Add(void) +{ + ankle1 = (ankle1 + ANKLE_RATE) % 360; +} + +void +Ankle1Subtract(void) +{ + ankle1 = (ankle1 - ANKLE_RATE) % 360; +} + +void +Ankle2Add(void) +{ + ankle2 = (ankle2 + ANKLE_RATE) % 360; +} + +void +Ankle2Subtract(void) +{ + ankle2 = (ankle2 - ANKLE_RATE) % 360; +} + +void +RotateAdd(void) +{ + pivot = (pivot + ROTATE_RATE) % 360; +} + +void +RotateSubtract(void) +{ + pivot = (pivot - ROTATE_RATE) % 360; +} + +void +MechTiltSubtract(void) +{ + tilt = (tilt - TILT_RATE) % 360; +} + +void +MechTiltAdd(void) +{ + tilt = (tilt + TILT_RATE) % 360; +} + +void +elbow1Add(void) +{ + elbow1 = (elbow1 + ELBOW_RATE) % 360; +} + +void +elbow1Subtract(void) +{ + elbow1 = (elbow1 - ELBOW_RATE) % 360; +} + +void +elbow2Add(void) +{ + elbow2 = (elbow2 + ELBOW_RATE) % 360; +} + +void +elbow2Subtract(void) +{ + elbow2 = (elbow2 - ELBOW_RATE) % 360; +} + +void +shoulder1Add(void) +{ + shoulder1 = (shoulder1 + SHOULDER_RATE) % 360; +} + +void +shoulder1Subtract(void) +{ + shoulder1 = (shoulder1 - SHOULDER_RATE) % 360; +} + +void +shoulder2Add(void) +{ + shoulder2 = (shoulder2 + SHOULDER_RATE) % 360; +} + +void +shoulder2Subtract(void) +{ + shoulder2 = (shoulder2 - SHOULDER_RATE) % 360; +} + +void +shoulder3Add(void) +{ + shoulder3 = (shoulder3 + SHOULDER_RATE) % 360; +} + +void +shoulder3Subtract(void) +{ + shoulder3 = (shoulder3 - SHOULDER_RATE) % 360; +} + +void +shoulder4Add(void) +{ + shoulder4 = (shoulder4 + SHOULDER_RATE) % 360; +} + +void +shoulder4Subtract(void) +{ + shoulder4 = (shoulder4 - SHOULDER_RATE) % 360; +} + +void +lat1Raise(void) +{ + lat1 = (lat1 + LAT_RATE) % 360; +} + +void +lat1Lower(void) +{ + lat1 = (lat1 - LAT_RATE) % 360; +} + +void +lat2Raise(void) +{ + lat2 = (lat2 + LAT_RATE) % 360; +} + +void +lat2Lower(void) +{ + lat2 = (lat2 - LAT_RATE) % 360; +} + +void +FireCannon(void) +{ + fire = (fire + CANNON_RATE) % 360; +} + +void +RaiseLeg1Forward(void) +{ + hip11 = (hip11 + UPPER_LEG_RATE) % 360; +} + +void +LowerLeg1Backwards(void) +{ + hip11 = (hip11 - UPPER_LEG_RATE) % 360; +} + +void +RaiseLeg1Outwards(void) +{ + hip12 = (hip12 + UPPER_LEG_RATE_GROIN) % 360; +} + +void +LowerLeg1Inwards(void) +{ + hip12 = (hip12 - UPPER_LEG_RATE_GROIN) % 360; +} + +void +RaiseLeg2Forward(void) +{ + hip21 = (hip21 + UPPER_LEG_RATE) % 360; +} + +void +LowerLeg2Backwards(void) +{ + hip21 = (hip21 - UPPER_LEG_RATE) % 360; +} + +void +RaiseLeg2Outwards(void) +{ + hip22 = (hip22 + UPPER_LEG_RATE_GROIN) % 360; +} + +void +LowerLeg2Inwards(void) +{ + hip22 = (hip22 - UPPER_LEG_RATE_GROIN) % 360; +} + +/* end of body motion functions */ + +/* start of light source position functions */ +void +TurnRight(void) +{ + turn = (turn - VIEW_TURN_RATE) % 360; +} + +void +TurnLeft(void) +{ + turn = (turn + VIEW_TURN_RATE) % 360; +} + +void +TurnForwards(void) +{ + turn1 = (turn1 - VIEW_TURN_RATE) % 360; +} + +void +TurnBackwards(void) +{ + turn1 = (turn1 + VIEW_TURN_RATE) % 360; +} + +void +LightTurnRight(void) +{ + lightturn = (lightturn + LIGHT_TURN_RATE) % 360; +} + +void +LightTurnLeft(void) +{ + lightturn = (lightturn - LIGHT_TURN_RATE) % 360; +} + +void +LightForwards(void) +{ + lightturn1 = (lightturn1 + LIGHT_TURN_RATE) % 360; +} + +void +LightBackwards(void) +{ + lightturn1 = (lightturn1 - LIGHT_TURN_RATE) % 360; +} + +/* end of light source position functions */ + +/* start of geometric shape functions */ +void +Box(float width, float height, float depth, char solid) +{ + char i, j = 0; + float x = width / 2.0, y = height / 2.0, z = depth / 2.0; + + for (i = 0; i < 4; i++) { + glRotatef(90.0, 0.0, 0.0, 1.0); + if (j) { + if (!solid) + glBegin(GL_LINE_LOOP); + else + glBegin(GL_QUADS); + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(-x, y, z); + glVertex3f(-x, -y, z); + glVertex3f(-x, -y, -z); + glVertex3f(-x, y, -z); + glEnd(); + if (solid) { + glBegin(GL_TRIANGLES); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, z); + glVertex3f(-x, y, z); + glVertex3f(-x, -y, z); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, -z); + glVertex3f(-x, -y, -z); + glVertex3f(-x, y, -z); + glEnd(); + } + j = 0; + } else { + if (!solid) + glBegin(GL_LINE_LOOP); + else + glBegin(GL_QUADS); + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(-y, x, z); + glVertex3f(-y, -x, z); + glVertex3f(-y, -x, -z); + glVertex3f(-y, x, -z); + glEnd(); + if (solid) { + glBegin(GL_TRIANGLES); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, z); + glVertex3f(-y, x, z); + glVertex3f(-y, -x, z); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, -z); + glVertex3f(-y, -x, -z); + glVertex3f(-y, x, -z); + glEnd(); + } + j = 1; + } + } +} + +void +Octagon(float side, float height, char solid) +{ + char j; + float x = sin(0.785398163) * side, y = side / 2.0, z = height / 2.0, c; + + c = x + y; + for (j = 0; j < 8; j++) { + glTranslatef(-c, 0.0, 0.0); + if (!solid) + glBegin(GL_LINE_LOOP); + else + glBegin(GL_QUADS); + glNormal3f(-1.0, 0.0, 0.0); + glVertex3f(0.0, -y, z); + glVertex3f(0.0, y, z); + glVertex3f(0.0, y, -z); + glVertex3f(0.0, -y, -z); + glEnd(); + glTranslatef(c, 0.0, 0.0); + if (solid) { + glBegin(GL_TRIANGLES); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, z); + glVertex3f(-c, -y, z); + glVertex3f(-c, y, z); + glNormal3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, -z); + glVertex3f(-c, y, -z); + glVertex3f(-c, -y, -z); + glEnd(); + } + glRotatef(45.0, 0.0, 0.0, 1.0); + } +} + +/* end of geometric shape functions */ +#ifdef NORM +void +Normalize(float v[3]) +{ + GLfloat d = sqrt(v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + + if (d == 0.0) { + printf("zero length vector"); + return; + } + v[1] /= d; + v[2] /= d; + v[3] /= d; +} + +void +NormXprod(float v1[3], float v2[3], float v[3], float out[3]) +{ + GLint i, j; + GLfloat length; + + out[0] = v1[1] * v2[2] - v1[2] * v2[1]; + out[1] = v1[2] * v2[0] - v1[0] * v2[2]; + out[2] = v1[0] * v2[1] - v1[1] * v2[0]; + Normalize(out); +} + +#endif + +void +SetMaterial(GLfloat spec[], GLfloat amb[], GLfloat diff[], GLfloat shin[]) +{ + + glMaterialfv(GL_FRONT, GL_SPECULAR, spec); + glMaterialfv(GL_FRONT, GL_SHININESS, shin); + glMaterialfv(GL_FRONT, GL_AMBIENT, amb); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); +} + +void +MechTorso(char solid) +{ + glNewList(SOLID_MECH_TORSO, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(1.0, 1.0, 3.0, solid); + glTranslatef(0.75, 0.0, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + Box(0.5, 0.6, 2.0, solid); + glTranslatef(-1.5, 0.0, 0.0); + Box(0.5, 0.6, 2.0, solid); + glTranslatef(0.75, 0.0, 0.0); + glEndList(); +} + +void +MechHip(char solid) +{ + int i; + + glNewList(SOLID_MECH_HIP, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Octagon(0.7, 0.5, solid); +#ifdef SPHERE + for (i = 0; i < 2; i++) { + if (i) + glScalef(-1.0, 1.0, 1.0); + glTranslatef(1.0, 0.0, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + gluSphere(qobj, 0.2, 16, 16); + glTranslatef(-1.0, 0.0, 0.0); + } + glScalef(-1.0, 1.0, 1.0); +#endif + glEndList(); +} + +void +Shoulder(char solid) +{ + glNewList(SOLID_MECH_SHOULDER, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(1.0, 0.5, 0.5, solid); + glTranslatef(0.9, 0.0, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); +#ifdef SPHERE + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + gluSphere(qobj, 0.6, 16, 16); +#endif + glTranslatef(-0.9, 0.0, 0.0); + glEndList(); +} + +void +UpperArm(char solid) +{ + int i; + + glNewList(SOLID_MECH_UPPER_ARM, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(1.0, 2.0, 1.0, solid); + glTranslatef(0.0, -0.95, 0.0); + glRotatef(90.0, 1.0, 0.0, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + gluCylinder(qobj, 0.4, 0.4, 1.5, 16, 10); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glTranslatef(-0.4, -1.85, 0.0); + glRotatef(90.0, 0.0, 1.0, 0.0); + for (i = 0; i < 2; i++) { + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + if (i) + gluCylinder(qobj, 0.5, 0.5, 0.8, 16, 10); + else + gluCylinder(qobj, 0.2, 0.2, 0.8, 16, 10); + } + for (i = 0; i < 2; i++) { + if (i) + glScalef(-1.0, 1.0, 1.0); + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + if (i) + glTranslatef(0.0, 0.0, 0.8); + gluDisk(qobj, 0.2, 0.5, 16, 10); + if (i) + glTranslatef(0.0, 0.0, -0.8); + } + glScalef(-1.0, 1.0, 1.0); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glTranslatef(0.4, 2.9, 0.0); + glEndList(); +} + +void +VulcanGun(char solid) +{ + int i; + + glNewList(SOLID_MECH_VULCAN, GL_COMPILE); + +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + + if (!solid) { + gluQuadricDrawStyle(qobj, GLU_LINE); + } + gluCylinder(qobj, 0.5, 0.5, 0.5, 16, 10); + glTranslatef(0.0, 0.0, 0.5); + gluDisk(qobj, 0.0, 0.5, 16, 10); + + for (i = 0; i < 5; i++) { + glRotatef(72.0, 0.0, 0.0, 1.0); + glTranslatef(0.0, 0.3, 0.0); + if (!solid) { + gluQuadricDrawStyle(qobj, GLU_LINE); + } + gluCylinder(qobj, 0.15, 0.15, 2.0, 16, 10); + gluCylinder(qobj, 0.06, 0.06, 2.0, 16, 10); + glTranslatef(0.0, 0.0, 2.0); + gluDisk(qobj, 0.1, 0.15, 16, 10); + gluCylinder(qobj, 0.1, 0.1, 0.1, 16, 5); + glTranslatef(0.0, 0.0, 0.1); + gluDisk(qobj, 0.06, 0.1, 16, 5); + glTranslatef(0.0, -0.3, -2.1); + } + glEndList(); +} + +void +ForeArm(char solid) +{ + char i; + + glNewList(SOLID_MECH_FOREARM, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + for (i = 0; i < 5; i++) { + glTranslatef(0.0, -0.1, -0.15); + Box(0.6, 0.8, 0.2, solid); + glTranslatef(0.0, 0.1, -0.15); + Box(0.4, 0.6, 0.1, solid); + } + glTranslatef(0.0, 0.0, 2.45); + Box(1.0, 1.0, 2.0, solid); + glTranslatef(0.0, 0.0, -1.0); + glEndList(); +} + +void +UpperLeg(char solid) +{ + int i; + + glNewList(SOLID_MECH_UPPER_LEG, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + if (!solid) { + gluQuadricDrawStyle(qobj, GLU_LINE); + } + glTranslatef(0.0, -1.0, 0.0); + Box(0.4, 1.0, 0.7, solid); + glTranslatef(0.0, -0.65, 0.0); + for (i = 0; i < 5; i++) { + Box(1.2, 0.3, 1.2, solid); + glTranslatef(0.0, -0.2, 0.0); + Box(1.0, 0.1, 1.0, solid); + glTranslatef(0.0, -0.2, 0.0); + } + glTranslatef(0.0, -0.15, -0.4); + Box(2.0, 0.5, 2.0, solid); + glTranslatef(0.0, -0.3, -0.2); + glRotatef(90.0, 1.0, 0.0, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + gluCylinder(qobj, 0.6, 0.6, 3.0, 16, 10); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.5, 1.0); + Box(1.5, 3.0, 0.5, solid); + glTranslatef(0.0, -1.75, -0.8); + Box(2.0, 0.5, 2.0, solid); + glTranslatef(0.0, -0.9, -0.85); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + gluCylinder(qobj, 0.8, 0.8, 1.8, 16, 10); + for (i = 0; i < 2; i++) { + if (i) + glScalef(-1.0, 1.0, 1.0); + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + if (i) + glTranslatef(0.0, 0.0, 1.8); + gluDisk(qobj, 0.0, 0.8, 16, 10); + if (i) + glTranslatef(0.0, 0.0, -1.8); + } + glScalef(-1.0, 1.0, 1.0); + glEndList(); +} + +void +Foot(char solid) +{ + + glNewList(SOLID_MECH_FOOT, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + glRotatef(90.0, 1.0, 0.0, 0.0); + Octagon(1.5, 0.6, solid); + glRotatef(-90.0, 1.0, 0.0, 0.0); + glEndList(); +} + +void +LowerLeg(char solid) +{ + float k, l; + +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + for (k = 0.0; k < 2.0; k++) { + for (l = 0.0; l < 2.0; l++) { + glPushMatrix(); + glTranslatef(k, 0.0, l); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(1.0, 0.5, 1.0, solid); + glTranslatef(0.0, -0.45, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); +#ifdef SPHERE + if (!solid) + glutWireSphere(0.2, 16, 10); + else + glutSolidSphere(0.2, 16, 10); +#endif + if (leg) + glRotatef((GLfloat) heel1, 1.0, 0.0, 0.0); + else + glRotatef((GLfloat) heel2, 1.0, 0.0, 0.0); + /* glTranslatef(0.0, -0.2, 0.0); */ + glTranslatef(0.0, -1.7, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(0.25, 3.0, 0.25, solid); + glTranslatef(0.0, -1.7, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); +#ifdef SPHERE + if (!solid) + glutWireSphere(0.2, 16, 10); + else + glutSolidSphere(0.2, 16, 10); +#endif + if (leg) + glRotatef((GLfloat) - heel1, 1.0, 0.0, 0.0); + else + glRotatef((GLfloat) - heel2, 1.0, 0.0, 0.0); + glTranslatef(0.0, -0.45, 0.0); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(1.0, 0.5, 1.0, solid); + if (!k && !l) { + int j; + + glTranslatef(-0.4, -0.8, 0.5); + if (leg) + glRotatef((GLfloat) ankle1, 1.0, 0.0, 0.0); + else + glRotatef((GLfloat) ankle2, 1.0, 0.0, 0.0); + glRotatef(90.0, 0.0, 1.0, 0.0); + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + gluCylinder(qobj, 0.8, 0.8, 1.8, 16, 10); + for (j = 0; j < 2; j++) { + if (!solid) + gluQuadricDrawStyle(qobj, GLU_LINE); + if (j) { + glScalef(-1.0, 1.0, 1.0); + glTranslatef(0.0, 0.0, 1.8); + } + gluDisk(qobj, 0.0, 0.8, 16, 10); + if (j) + glTranslatef(0.0, 0.0, -1.8); + } + glScalef(-1.0, 1.0, 1.0); + glRotatef(-90.0, 0.0, 1.0, 0.0); + glTranslatef(0.95, -0.8, 0.0); + glCallList(SOLID_MECH_FOOT); + } + glPopMatrix(); + } + } +} + +void +RocketPod(char solid) +{ + + int i, j, k = 0; + + glNewList(SOLID_MECH_ROCKET, GL_COMPILE); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glColor3f(0.5, 0.5, 0.5); + glScalef(0.4, 0.4, 0.4); + glRotatef(45.0, 0.0, 0.0, 1.0); + glTranslatef(1.0, 0.0, 0.0); + Box(2.0, 0.5, 3.0, solid); + glTranslatef(1.0, 0.0, 0.0); + glRotatef(45.0, 0.0, 0.0, 1.0); + glTranslatef(0.5, 0.0, 0.0); + Box(1.2, 0.5, 3.0, solid); + glTranslatef(2.1, 0.0, 0.0); + glRotatef(-90.0, 0.0, 0.0, 1.0); +#ifdef LIGHT + SetMaterial(mat_specular, mat_ambient, mat_diffuse, mat_shininess); +#endif + glColor3f(1.0, 1.0, 0.0); + Box(2.0, 3.0, 4.0, solid); + glTranslatef(-0.5, -1.0, 1.3); + for (i = 0; i < 2; i++) { + for (j = 0; j < 3; j++) { + if (!solid) { + gluQuadricDrawStyle(qobj, GLU_LINE); + } + glTranslatef(i, j, 0.6); +#ifdef LIGHT + SetMaterial(mat_specular3, mat_ambient3, mat_diffuse3, mat_shininess3); +#endif + glColor3f(1.0, 1.0, 1.0); + gluCylinder(qobj, 0.4, 0.4, 0.3, 16, 10); + glTranslatef(0.0, 0.0, 0.3); +#ifdef LIGHT + SetMaterial(mat_specular4, mat_ambient4, mat_diffuse4, mat_shininess4); +#endif + glColor3f(0.0, 1.0, 0.0); + gluCylinder(qobj, 0.4, 0.0, 0.5, 16, 10); + k++; + glTranslatef(-i, -j, -0.9); + } + } + glEndList(); +} + +void +Enviro(char solid) +{ + + int i, j; + + glNewList(SOLID_ENVIRO, GL_COMPILE); + SetMaterial(mat_specular4, mat_ambient4, mat_diffuse4, mat_shininess4); + glColor3f(0.0, 1.0, 0.0); + Box(20.0, 0.5, 30.0, solid); + SetMaterial(mat_specular4, mat_ambient3, mat_diffuse2, mat_shininess); + glColor3f(0.6, 0.6, 0.6); + glTranslatef(0.0, 0.0, -10.0); + for (j = 0; j < 6; j++) { + for (i = 0; i < 2; i++) { + if (i) + glScalef(-1.0, 1.0, 1.0); + glTranslatef(10.0, 4.0, 0.0); + Box(4.0, 8.0, 2.0, solid); + glTranslatef(0.0, -1.0, -3.0); + Box(4.0, 6.0, 2.0, solid); + glTranslatef(-10.0, -3.0, 3.0); + } + glScalef(-1.0, 1.0, 1.0); + glTranslatef(0.0, 0.0, 5.0); + } + glEndList(); +} + +void +Toggle(void) +{ + if (solid_part) + solid_part = 0; + else + solid_part = 1; +} + +void +disable(void) +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_NORMALIZE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +} + +void +lighting(void) +{ + + GLfloat position[] = + {0.0, 0.0, 2.0, 1.0}; + +#ifdef MOVE_LIGHT + glRotatef((GLfloat) lightturn1, 1.0, 0.0, 0.0); + glRotatef((GLfloat) lightturn, 0.0, 1.0, 0.0); + glRotatef(0.0, 1.0, 0.0, 0.0); +#endif + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); + glDepthFunc(GL_LESS); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glLightfv(GL_LIGHT0, GL_POSITION, position); + glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 80.0); + + glTranslatef(0.0, 0.0, 2.0); + glDisable(GL_LIGHTING); + Box(0.1, 0.1, 0.1, 0); + glEnable(GL_LIGHTING); +} + +void +DrawMech(void) +{ + int i, j; + + glScalef(0.5, 0.5, 0.5); + glPushMatrix(); + glTranslatef(0.0, -0.75, 0.0); + glRotatef((GLfloat) tilt, 1.0, 0.0, 0.0); + + glRotatef(90.0, 1.0, 0.0, 0.0); +#ifdef HIP + glCallList(SOLID_MECH_HIP); +#endif + glRotatef(-90.0, 1.0, 0.0, 0.0); + + glTranslatef(0.0, 0.75, 0.0); + glPushMatrix(); + glRotatef((GLfloat) pivot, 0.0, 1.0, 0.0); + glPushMatrix(); +#ifdef TORSO + glCallList(SOLID_MECH_TORSO); +#endif + glPopMatrix(); + glPushMatrix(); + glTranslatef(0.5, 0.5, 0.0); +#ifdef ROCKET_POD + glCallList(SOLID_MECH_ROCKET); +#endif + glPopMatrix(); + for (i = 0; i < 2; i++) { + glPushMatrix(); + if (i) + glScalef(-1.0, 1.0, 1.0); + glTranslatef(1.5, 0.0, 0.0); +#ifdef SHOULDER + glCallList(SOLID_MECH_SHOULDER); +#endif + glTranslatef(0.9, 0.0, 0.0); + if (i) { + glRotatef((GLfloat) lat1, 0.0, 0.0, 1.0); + glRotatef((GLfloat) shoulder1, 1.0, 0.0, 0.0); + glRotatef((GLfloat) shoulder3, 0.0, 1.0, 0.0); + } else { + glRotatef((GLfloat) lat2, 0.0, 0.0, 1.0); + glRotatef((GLfloat) shoulder2, 1.0, 0.0, 0.0); + glRotatef((GLfloat) shoulder4, 0.0, 1.0, 0.0); + } + glTranslatef(0.0, -1.4, 0.0); +#ifdef UPPER_ARM + glCallList(SOLID_MECH_UPPER_ARM); +#endif + glTranslatef(0.0, -2.9, 0.0); + if (i) + glRotatef((GLfloat) elbow1, 1.0, 0.0, 0.0); + else + glRotatef((GLfloat) elbow2, 1.0, 0.0, 0.0); + glTranslatef(0.0, -0.9, -0.2); +#ifdef LOWER_ARM + glCallList(SOLID_MECH_FOREARM); + glPushMatrix(); + glTranslatef(0.0, 0.0, 2.0); + glRotatef((GLfloat) fire, 0.0, 0.0, 1.0); + glCallList(SOLID_MECH_VULCAN); + glPopMatrix(); +#endif + glPopMatrix(); + } + glPopMatrix(); + + glPopMatrix(); + + for (j = 0; j < 2; j++) { + glPushMatrix(); + if (j) { + glScalef(-0.5, 0.5, 0.5); + leg = 1; + } else { + glScalef(0.5, 0.5, 0.5); + leg = 0; + } + glTranslatef(2.0, -1.5, 0.0); + if (j) { + glRotatef((GLfloat) hip11, 1.0, 0.0, 0.0); + glRotatef((GLfloat) hip12, 0.0, 0.0, 1.0); + } else { + glRotatef((GLfloat) hip21, 1.0, 0.0, 0.0); + glRotatef((GLfloat) hip22, 0.0, 0.0, 1.0); + } + glTranslatef(0.0, 0.3, 0.0); +#ifdef UPPER_LEG + glPushMatrix(); + glCallList(SOLID_MECH_UPPER_LEG); + glPopMatrix(); +#endif + glTranslatef(0.0, -8.3, -0.4); + if (j) + glRotatef((GLfloat) - hip12, 0.0, 0.0, 1.0); + else + glRotatef((GLfloat) - hip22, 0.0, 0.0, 1.0); + glTranslatef(-0.5, -0.85, -0.5); +#ifdef LOWER_LEG + LowerLeg(1); +#endif + glPopMatrix(); + } +} + +void +display(void) +{ + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + glPushMatrix(); + glRotatef((GLfloat) turn, 0.0, 1.0, 0.0); + glRotatef((GLfloat) turn1, 1.0, 0.0, 0.0); +#ifdef LIGHT + if (solid_part) { + glPushMatrix(); + lighting(); + glPopMatrix(); + } else + disable(); +#endif +#ifdef DRAW_MECH + glPushMatrix(); + glTranslatef(0.0, elevation, 0.0); + DrawMech(); + glPopMatrix(); +#endif +#ifdef DRAW_ENVIRO + glPushMatrix(); + if (distance >= 20.136) + distance = 0.0; + glTranslatef(0.0, -5.0, -distance); + glCallList(SOLID_ENVIRO); + glTranslatef(0.0, 0.0, 10.0); + glCallList(SOLID_ENVIRO); + glPopMatrix(); +#endif + glPopMatrix(); + glFlush(); + glutSwapBuffers(); +} + +void +myinit(void) +{ + char i = 1; + + qobj = gluNewQuadric(); +#ifdef LIGHT + SetMaterial(mat_specular2, mat_ambient2, mat_diffuse2, mat_shininess2); +#endif + glEnable(GL_DEPTH_TEST); + MechTorso(i); + MechHip(i); + Shoulder(i); + RocketPod(i); + UpperArm(i); + ForeArm(i); + UpperLeg(i); + Foot(i); + VulcanGun(i); + Enviro(i); +} + +void +myReshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(65.0, (GLfloat) w / (GLfloat) h, 1.0, 20.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 1.2, -5.5); /* viewing transform */ +} + +#ifdef ANIMATION +void +animation_walk(void) +{ + float angle; + static int step; + + if (step == 0 || step == 2) { + /* for(frame=3.0; frame<=21.0; frame=frame+3.0){ */ + if (frame >= 0.0 && frame <= 21.0) { + if (frame == 0.0) + frame = 3.0; + angle = (180 / M_PI) * (acos(((cos((M_PI / 180) * frame) * 2.043) + 1.1625) / 3.2059)); + if (frame > 0) { + elevation = -(3.2055 - (cos((M_PI / 180) * angle) * 3.2055)); + } else + elevation = 0.0; + if (step == 0) { + hip11 = -(frame * 1.7); + if (1.7 * frame > 15) + heel1 = frame * 1.7; + heel2 = 0; + ankle1 = frame * 1.7; + if (frame > 0) + hip21 = angle; + else + hip21 = 0; + ankle2 = -hip21; + shoulder1 = frame * 1.5; + shoulder2 = -frame * 1.5; + elbow1 = frame; + elbow2 = -frame; + } else { + hip21 = -(frame * 1.7); + if (1.7 * frame > 15) + heel2 = frame * 1.7; + heel1 = 0; + ankle2 = frame * 1.7; + if (frame > 0) + hip11 = angle; + else + hip11 = 0; + ankle1 = -hip11; + shoulder1 = -frame * 1.5; + shoulder2 = frame * 1.5; + elbow1 = -frame; + elbow2 = frame; + } + if (frame == 21) + step++; + if (frame < 21) + frame = frame + 3.0; + } + } + if (step == 1 || step == 3) { + /* for(x=21.0; x>=0.0; x=x-3.0){ */ + if (frame <= 21.0 && frame >= 0.0) { + angle = (180 / M_PI) * (acos(((cos((M_PI / 180) * frame) * 2.043) + 1.1625) / 3.2029)); + if (frame > 0) + elevation = -(3.2055 - (cos((M_PI / 180) * angle) * 3.2055)); + else + elevation = 0.0; + if (step == 1) { + elbow2 = hip11 = -frame; + elbow1 = heel1 = frame; + heel2 = 15; + ankle1 = frame; + if (frame > 0) + hip21 = angle; + else + hip21 = 0; + ankle2 = -hip21; + shoulder1 = 1.5 * frame; + shoulder2 = -frame * 1.5; + } else { + elbow1 = hip21 = -frame; + elbow2 = heel2 = frame; + heel1 = 15; + ankle2 = frame; + if (frame > 0) + hip11 = angle; + else + hip11 = 0; + ankle1 = -hip11; + shoulder1 = -frame * 1.5; + shoulder2 = frame * 1.5; + } + if (frame == 0.0) + step++; + if (frame > 0) + frame = frame - 3.0; + } + } + if (step == 4) + step = 0; + distance += 0.1678; + glutPostRedisplay(); +} + +void +animation(void) +{ + animation_walk(); +} + +#endif + +#ifdef GLUT +#ifdef GLUT_KEY +/* ARGSUSED1 */ +void +keyboard(unsigned char key, int x, int y) +{ + + int i = 0; + + switch (key) { + /* start arm control functions */ + case 'q':{ + shoulder2Subtract(); + i++; + } + break; + case 'a':{ + shoulder2Add(); + i++; + } + break; + case 'w':{ + shoulder1Subtract(); + i++; + } + break; + case 's':{ + shoulder1Add(); + i++; + } + break; + case '2':{ + shoulder3Add(); + i++; + } + break; + case '1':{ + shoulder4Add(); + i++; + } + break; + case '4':{ + shoulder3Subtract(); + i++; + } + break; + case '3':{ + shoulder4Subtract(); + i++; + } + break; + + case 'z':{ + lat2Raise(); + i++; + } + break; + case 'Z':{ + lat2Lower(); + i++; + } + break; + case 'x':{ + lat1Raise(); + i++; + } + break; + case 'X':{ + lat1Lower(); + i++; + } + break; + + case 'A':{ + elbow2Add(); + i++; + } + break; + case 'Q':{ + elbow2Subtract(); + i++; + } + break; + case 'S':{ + elbow1Add(); + i++; + } + break; + case 'W':{ + elbow1Subtract(); + i++; + } + break; + /* end of arm control functions */ + + /* start of torso control functions */ + case 'd':{ + RotateAdd(); + i++; + } + break; + case 'g':{ + RotateSubtract(); + i++; + } + break; + case 'r':{ + MechTiltAdd(); + i++; + } + break; + case 'f':{ + MechTiltSubtract(); + i++; + } + break; + /* end of torso control functions */ + + /* start of leg control functions */ + case 'h':{ + RaiseLeg2Forward(); + i++; + } + break; + case 'y':{ + LowerLeg2Backwards(); + i++; + } + break; + case 'Y':{ + RaiseLeg2Outwards(); + i++; + } + break; + case 'H':{ + LowerLeg2Inwards(); + i++; + } + break; + + case 'j':{ + RaiseLeg1Forward(); + i++; + } + break; + case 'u':{ + LowerLeg1Backwards(); + i++; + } + break; + case 'U':{ + RaiseLeg1Outwards(); + i++; + } + break; + case 'J':{ + LowerLeg1Inwards(); + i++; + } + break; + + case 'N':{ + Heel2Add(); + i++; + } + break; + case 'n':{ + Heel2Subtract(); + i++; + } + break; + case 'M':{ + Heel1Add(); + i++; + } + break; + case 'm':{ + Heel1Subtract(); + i++; + } + break; + + case 'k':{ + Ankle2Add(); + i++; + } + break; + case 'K':{ + Ankle2Subtract(); + i++; + } + break; + case 'l':{ + Ankle1Add(); + i++; + } + break; + case 'L':{ + Ankle1Subtract(); + i++; + } + break; + /* end of leg control functions */ + + /* start of light source position functions */ + case 'p':{ + LightTurnRight(); + i++; + } + break; + case 'i':{ + LightTurnLeft(); + i++; + } + break; + case 'o':{ + LightForwards(); + i++; + } + break; + case '9':{ + LightBackwards(); + i++; + } + break; + /* end of light source position functions */ + } + if (i) + glutPostRedisplay(); +} + +#endif + +#ifdef GLUT_SPEC +/* ARGSUSED1 */ +void +special(int key, int x, int y) +{ + + int i = 0; + + switch (key) { + /* start of view position functions */ + case GLUT_KEY_RIGHT:{ + TurnRight(); + i++; + } + break; + case GLUT_KEY_LEFT:{ + TurnLeft(); + i++; + } + break; + case GLUT_KEY_DOWN:{ + TurnForwards(); + i++; + } + break; + case GLUT_KEY_UP:{ + TurnBackwards(); + i++; + } + break; + /* end of view postions functions */ + /* start of miseclleneous functions */ + case GLUT_KEY_PAGE_UP:{ + FireCannon(); + i++; + } + break; + /* end of miscelleneous functions */ + } + if (i) + glutPostRedisplay(); +} + +#endif +#endif +void +menu_select(int mode) +{ + switch (mode) { +#ifdef ANIMATION + case 1: + glutIdleFunc(animation); + break; +#endif + case 2: + glutIdleFunc(NULL); + break; + case 3: + Toggle(); + glutPostRedisplay(); + break; + case 4: + exit(EXIT_SUCCESS); + } +} + +/* ARGSUSED */ +void +null_select(int mode) +{ +} + +void +glutMenu(void) +{ + + int glut_menu[13]; + + glut_menu[5] = glutCreateMenu(null_select); + glutAddMenuEntry("forward : q,w", 0); + glutAddMenuEntry("backwards : a,s", 0); + glutAddMenuEntry("outwards : z,x", 0); + glutAddMenuEntry("inwards : Z,X", 0); + + glut_menu[6] = glutCreateMenu(null_select); + glutAddMenuEntry("upwards : Q,W", 0); + glutAddMenuEntry("downwards : A,S", 0); + glutAddMenuEntry("outwards : 1,2", 0); + glutAddMenuEntry("inwards : 3,4", 0); + + glut_menu[1] = glutCreateMenu(null_select); + glutAddMenuEntry(" : Page_up", 0); + + glut_menu[8] = glutCreateMenu(null_select); + glutAddMenuEntry("forward : y,u", 0); + glutAddMenuEntry("backwards : h.j", 0); + glutAddMenuEntry("outwards : Y,U", 0); + glutAddMenuEntry("inwards : H,J", 0); + + glut_menu[9] = glutCreateMenu(null_select); + glutAddMenuEntry("forward : n,m", 0); + glutAddMenuEntry("backwards : N,M", 0); + + glut_menu[9] = glutCreateMenu(null_select); + glutAddMenuEntry("forward : n,m", 0); + glutAddMenuEntry("backwards : N,M", 0); + + glut_menu[10] = glutCreateMenu(null_select); + glutAddMenuEntry("toes up : K,L", 0); + glutAddMenuEntry("toes down : k,l", 0); + + glut_menu[11] = glutCreateMenu(null_select); + glutAddMenuEntry("right : right arrow", 0); + glutAddMenuEntry("left : left arrow", 0); + glutAddMenuEntry("down : up arrow", 0); + glutAddMenuEntry("up : down arrow", 0); + + glut_menu[12] = glutCreateMenu(null_select); + glutAddMenuEntry("right : p", 0); + glutAddMenuEntry("left : i", 0); + glutAddMenuEntry("up : 9", 0); + glutAddMenuEntry("down : o", 0); + + glut_menu[4] = glutCreateMenu(NULL); + glutAddSubMenu("at the shoulders? ", glut_menu[5]); + glutAddSubMenu("at the elbows?", glut_menu[6]); + + glut_menu[7] = glutCreateMenu(NULL); + glutAddSubMenu("at the hip? ", glut_menu[8]); + glutAddSubMenu("at the knees?", glut_menu[9]); + glutAddSubMenu("at the ankles? ", glut_menu[10]); + + glut_menu[2] = glutCreateMenu(null_select); + glutAddMenuEntry("turn left : d", 0); + glutAddMenuEntry("turn right : g", 0); + + glut_menu[3] = glutCreateMenu(null_select); + glutAddMenuEntry("tilt backwards : f", 0); + glutAddMenuEntry("tilt forwards : r", 0); + + glut_menu[0] = glutCreateMenu(NULL); + glutAddSubMenu("move the arms.. ", glut_menu[4]); + glutAddSubMenu("fire the vulcan guns?", glut_menu[1]); + glutAddSubMenu("move the legs.. ", glut_menu[7]); + glutAddSubMenu("move the torso?", glut_menu[2]); + glutAddSubMenu("move the hip?", glut_menu[3]); + glutAddSubMenu("rotate the scene..", glut_menu[11]); +#ifdef MOVE_LIGHT + glutAddSubMenu("rotate the light source..", glut_menu[12]); +#endif + + glutCreateMenu(menu_select); +#ifdef ANIMATION + glutAddMenuEntry("Start Walk", 1); + glutAddMenuEntry("Stop Walk", 2); +#endif + glutAddMenuEntry("Toggle Wireframe", 3); + glutAddSubMenu("How do I ..", glut_menu[0]); + glutAddMenuEntry("Quit", 4); + glutAttachMenu(GLUT_LEFT_BUTTON); + glutAttachMenu(GLUT_RIGHT_BUTTON); +} + +int +main(int argc, char **argv) +{ +#ifdef GLUT + /* start of glut windowing and control functions */ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); + glutInitWindowSize(800, 600); + glutCreateWindow("glutmech: Vulcan Gunner"); + myinit(); + glutDisplayFunc(display); + glutReshapeFunc(myReshape); +#ifdef GLUT_KEY + glutKeyboardFunc(keyboard); +#endif +#ifdef GLUT_SPEC + glutSpecialFunc(special); +#endif + glutMenu(); + glutMainLoop(); + /* end of glut windowing and control functions */ +#endif + return 0; /* ANSI C requires main to return int. */ +} diff --git a/lib/glut-3.7.6/progs/demos/glutmech/glutmech.dsp b/lib/glut-3.7.6/progs/demos/glutmech/glutmech.dsp new file mode 100644 index 0000000000..b068151fd1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/glutmech/glutmech.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="glutmech" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=glutmech - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "glutmech.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "glutmech.mak" CFG="glutmech - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "glutmech - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "glutmech - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "glutmech - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "glutmech - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "glutmech - Win32 Release" +# Name "glutmech - Win32 Debug" +# Begin Source File + +SOURCE=.\glutmech.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/ideas/Imakefile b/lib/glut-3.7.6/progs/demos/ideas/Imakefile new file mode 100644 index 0000000000..8d203a5a41 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/Imakefile @@ -0,0 +1,20 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +#include "../../../Glut.cf" + +TARGETS = ideas + +SRCS = a.c b.c d.c draw_holder.c draw_lamp.c draw_logo.c \ + draw_logo_line.c draw_logo_shadow.c e.c f.c h.c i.c ideas.c m.c n.c \ + o.c p.c r.c s.c t.c w.c + +OBJS = a.o b.o d.o draw_holder.o draw_lamp.o draw_logo.o \ + draw_logo_line.o draw_logo_shadow.o e.o f.o h.o i.o ideas.o m.o n.o \ + o.o p.o r.o s.o t.o w.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(ideas,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/ideas/a.c b/lib/glut-3.7.6/progs/demos/ideas/a.c new file mode 100644 index 0000000000..f568c38b77 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/a.c @@ -0,0 +1,194 @@ +/* + * (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. + */ +#include + +static float a_data[][2] = { + {5.618949, 10.261048}, + {5.322348, 9.438848}, + {5.124614, 10.030832}, + {4.860968, 9.488181}, + {4.811534, 9.932169}, + {3.938208, 9.438848}, + {3.658084, 9.685509}, + {2.784758, 8.994862}, + {2.801236, 9.175745}, + {1.960865, 8.172662}, + {1.186406, 7.761562}, + {1.252317, 6.561151}, + {0.576725, 6.610483}, + {0.939238, 5.525180}, + {0.164779, 4.883864}, + {0.840371, 4.818089}, + {0.230690, 3.963001}, + {0.939238, 4.242549}, + {0.609681, 3.255909}, + {1.268795, 3.963001}, + {1.021627, 3.075026}, + {1.861998, 4.045221}, + {1.829042, 3.535457}, + {2.817714, 4.818089}, + {3.163749, 4.998972}, + {3.971164, 6.643371}, + {4.267765, 6.725591}, + {4.663234, 7.630010}, + + {5.404737, 9.734840}, + {4.646756, 9.669065}, + {5.108136, 8.731757}, + {4.679712, 8.600205}, + {4.926879, 7.564234}, + {4.366632, 6.692703}, + {4.663234, 5.344296}, + {3.888774, 4.850976}, + {4.630278, 4.094553}, + {3.954686, 3.963001}, + {4.828012, 3.798561}, + {4.168898, 3.321686}, + {5.157569, 3.864337}, + {4.514933, 3.091470}, + {5.553038, 4.045221}, + {5.305870, 3.634121}, + {5.932029, 4.176773}, + +}; + +void draw_a(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(a_data[0]); + glVertex2fv(a_data[1]); + glVertex2fv(a_data[2]); + glVertex2fv(a_data[3]); + glVertex2fv(a_data[4]); + glVertex2fv(a_data[5]); + glVertex2fv(a_data[6]); + glVertex2fv(a_data[7]); + glVertex2fv(a_data[8]); + glVertex2fv(a_data[9]); + glVertex2fv(a_data[10]); + glVertex2fv(a_data[11]); + glVertex2fv(a_data[12]); + glVertex2fv(a_data[13]); + glVertex2fv(a_data[14]); + glVertex2fv(a_data[15]); + glVertex2fv(a_data[16]); + glVertex2fv(a_data[17]); + glVertex2fv(a_data[18]); + glVertex2fv(a_data[19]); + glVertex2fv(a_data[20]); + glVertex2fv(a_data[21]); + glVertex2fv(a_data[22]); + glVertex2fv(a_data[23]); + glVertex2fv(a_data[24]); + glVertex2fv(a_data[25]); + glVertex2fv(a_data[26]); + glVertex2fv(a_data[27]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(a_data[28]); + glVertex2fv(a_data[29]); + glVertex2fv(a_data[30]); + glVertex2fv(a_data[31]); + glVertex2fv(a_data[32]); + glVertex2fv(a_data[33]); + glVertex2fv(a_data[34]); + glVertex2fv(a_data[35]); + glVertex2fv(a_data[36]); + glVertex2fv(a_data[37]); + glVertex2fv(a_data[38]); + glVertex2fv(a_data[39]); + glVertex2fv(a_data[40]); + glVertex2fv(a_data[41]); + glVertex2fv(a_data[42]); + glVertex2fv(a_data[43]); + glVertex2fv(a_data[44]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(a_data[0]); + glVertex2fv(a_data[2]); + glVertex2fv(a_data[4]); + glVertex2fv(a_data[6]); + glVertex2fv(a_data[8]); + glVertex2fv(a_data[10]); + glVertex2fv(a_data[12]); + glVertex2fv(a_data[14]); + glVertex2fv(a_data[16]); + glVertex2fv(a_data[18]); + glVertex2fv(a_data[20]); + glVertex2fv(a_data[22]); + glVertex2fv(a_data[24]); + glVertex2fv(a_data[26]); + glVertex2fv(a_data[27]); + glVertex2fv(a_data[25]); + glVertex2fv(a_data[23]); + glVertex2fv(a_data[21]); + glVertex2fv(a_data[19]); + glVertex2fv(a_data[17]); + glVertex2fv(a_data[15]); + glVertex2fv(a_data[13]); + glVertex2fv(a_data[11]); + glVertex2fv(a_data[9]); + glVertex2fv(a_data[7]); + glVertex2fv(a_data[5]); + glVertex2fv(a_data[3]); + glVertex2fv(a_data[1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(a_data[28]); + glVertex2fv(a_data[30]); + glVertex2fv(a_data[32]); + glVertex2fv(a_data[34]); + glVertex2fv(a_data[36]); + glVertex2fv(a_data[38]); + glVertex2fv(a_data[40]); + glVertex2fv(a_data[42]); + glVertex2fv(a_data[44]); + glVertex2fv(a_data[43]); + glVertex2fv(a_data[41]); + glVertex2fv(a_data[39]); + glVertex2fv(a_data[37]); + glVertex2fv(a_data[35]); + glVertex2fv(a_data[33]); + glVertex2fv(a_data[31]); + glVertex2fv(a_data[29]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/b.c b/lib/glut-3.7.6/progs/demos/ideas/b.c new file mode 100644 index 0000000000..1a26c70068 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/b.c @@ -0,0 +1,146 @@ +/* + * (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. + */ +#include + +float b_data[][2] = { + {1.437827, 15.482255}, + {3.711599, 15.716075}, + {2.658307, 15.315240}, + {3.477534, 15.081420}, + {2.741902, 14.997912}, + {2.006270, 7.983298}, + {0.234065, 3.139875}, + {1.103448, 4.192067}, + {1.538140, 3.139875}, + {1.404389, 3.958246}, + {2.374086, 3.306889}, + {2.792058, 3.807933}, + {3.243469, 3.691023}, + {3.544410, 4.158664}, + {4.497388, 4.776618}, + {3.979101, 4.759916}, + {4.815047, 5.227557}, + {4.413793, 5.979123}, + {5.400209, 6.864301}, + {4.497388, 8.133612}, + {5.667712, 8.734864}, + {4.263323, 9.002088}, + {5.416928, 9.686848}, + {4.012539, 9.219207}, + {4.898642, 10.020877}, + {3.494253, 9.118998}, + {3.745037, 9.620042}, + {2.775340, 8.684760}, + {2.708464, 8.835073}, + {1.805643, 7.382046}, + {1.688610, 7.582463}, + +}; + +void draw_b(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(b_data[0]); + glVertex2fv(b_data[1]); + glVertex2fv(b_data[2]); + glVertex2fv(b_data[3]); + glVertex2fv(b_data[4]); + glVertex2fv(b_data[5]); + glVertex2fv(b_data[6]); + glVertex2fv(b_data[7]); + glVertex2fv(b_data[8]); + glVertex2fv(b_data[9]); + glVertex2fv(b_data[10]); + glVertex2fv(b_data[11]); + glVertex2fv(b_data[12]); + glVertex2fv(b_data[13]); + glVertex2fv(b_data[14]); + glVertex2fv(b_data[15]); + glVertex2fv(b_data[16]); + glVertex2fv(b_data[17]); + glVertex2fv(b_data[18]); + glVertex2fv(b_data[19]); + glVertex2fv(b_data[20]); + glVertex2fv(b_data[21]); + glVertex2fv(b_data[22]); + glVertex2fv(b_data[23]); + glVertex2fv(b_data[24]); + glVertex2fv(b_data[25]); + glVertex2fv(b_data[26]); + glVertex2fv(b_data[27]); + glVertex2fv(b_data[28]); + glVertex2fv(b_data[29]); + glVertex2fv(b_data[30]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(b_data[0]); + glVertex2fv(b_data[2]); + glVertex2fv(b_data[4]); + glVertex2fv(b_data[6]); + glVertex2fv(b_data[8]); + glVertex2fv(b_data[10]); + glVertex2fv(b_data[12]); + glVertex2fv(b_data[14]); + glVertex2fv(b_data[16]); + glVertex2fv(b_data[18]); + glVertex2fv(b_data[20]); + glVertex2fv(b_data[22]); + glVertex2fv(b_data[24]); + glVertex2fv(b_data[26]); + glVertex2fv(b_data[28]); + glVertex2fv(b_data[30]); + glVertex2fv(b_data[29]); + glVertex2fv(b_data[27]); + glVertex2fv(b_data[25]); + glVertex2fv(b_data[23]); + glVertex2fv(b_data[21]); + glVertex2fv(b_data[19]); + glVertex2fv(b_data[17]); + glVertex2fv(b_data[15]); + glVertex2fv(b_data[13]); + glVertex2fv(b_data[11]); + glVertex2fv(b_data[9]); + glVertex2fv(b_data[7]); + glVertex2fv(b_data[5]); + glVertex2fv(b_data[3]); + glVertex2fv(b_data[1]); + glVertex2fv(b_data[0]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/d.c b/lib/glut-3.7.6/progs/demos/ideas/d.c new file mode 100644 index 0000000000..5916283593 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/d.c @@ -0,0 +1,154 @@ +/* + * (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. + */ +#include + +float d_data[][2] = { + {4.714579, 9.987679}, + {2.841889, 9.429158}, + {2.825462, 9.166325}, + {1.856263, 8.722793}, + {2.004107, 8.000000}, + {0.969199, 7.605750}, + {1.494866, 6.636550}, + {0.607803, 6.028748}, + {1.527721, 4.960986}, + {0.772074, 4.254620}, + {1.774127, 4.139630}, + {1.445585, 3.186858}, + {2.266940, 3.843942}, + {2.250513, 3.022587}, + {2.776181, 3.843942}, + {3.137577, 3.383984}, + {3.351129, 4.008214}, + {3.909651, 4.451746}, + {4.090349, 4.960986}, + {4.862423, 5.946612}, + {4.763860, 6.652977}, + {5.388090, 7.572895}, + {4.862423, 8.492813}, + {5.618070, 9.921971}, + {4.698152, 10.940452}, + {5.338809, 12.303902}, + {4.238193, 12.960985}, + {4.451746, 14.554415}, + {3.581109, 14.291581}, + {3.613963, 15.342916}, + {2.677618, 15.145790}, + {2.480493, 15.540041}, + {2.036961, 15.211499}, + {1.281314, 15.112936}, + +}; + +void draw_d(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(d_data[0]); + glVertex2fv(d_data[1]); + glVertex2fv(d_data[2]); + glVertex2fv(d_data[3]); + glVertex2fv(d_data[4]); + glVertex2fv(d_data[5]); + glVertex2fv(d_data[6]); + glVertex2fv(d_data[7]); + glVertex2fv(d_data[8]); + glVertex2fv(d_data[9]); + glVertex2fv(d_data[10]); + glVertex2fv(d_data[11]); + glVertex2fv(d_data[12]); + glVertex2fv(d_data[13]); + glVertex2fv(d_data[14]); + glVertex2fv(d_data[15]); + glVertex2fv(d_data[16]); + glVertex2fv(d_data[17]); + glVertex2fv(d_data[18]); + glVertex2fv(d_data[19]); + glVertex2fv(d_data[20]); + glVertex2fv(d_data[21]); + glVertex2fv(d_data[22]); + glVertex2fv(d_data[23]); + glVertex2fv(d_data[24]); + glVertex2fv(d_data[25]); + glVertex2fv(d_data[26]); + glVertex2fv(d_data[27]); + glVertex2fv(d_data[28]); + glVertex2fv(d_data[29]); + glVertex2fv(d_data[30]); + glVertex2fv(d_data[31]); + glVertex2fv(d_data[32]); + glVertex2fv(d_data[33]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(d_data[0]); + glVertex2fv(d_data[2]); + glVertex2fv(d_data[4]); + glVertex2fv(d_data[6]); + glVertex2fv(d_data[8]); + glVertex2fv(d_data[10]); + glVertex2fv(d_data[12]); + glVertex2fv(d_data[14]); + glVertex2fv(d_data[16]); + glVertex2fv(d_data[18]); + glVertex2fv(d_data[20]); + glVertex2fv(d_data[22]); + glVertex2fv(d_data[24]); + glVertex2fv(d_data[26]); + glVertex2fv(d_data[28]); + glVertex2fv(d_data[30]); + glVertex2fv(d_data[32]); + glVertex2fv(d_data[33]); + glVertex2fv(d_data[31]); + glVertex2fv(d_data[29]); + glVertex2fv(d_data[27]); + glVertex2fv(d_data[25]); + glVertex2fv(d_data[23]); + glVertex2fv(d_data[21]); + glVertex2fv(d_data[19]); + glVertex2fv(d_data[17]); + glVertex2fv(d_data[15]); + glVertex2fv(d_data[13]); + glVertex2fv(d_data[11]); + glVertex2fv(d_data[9]); + glVertex2fv(d_data[7]); + glVertex2fv(d_data[5]); + glVertex2fv(d_data[3]); + glVertex2fv(d_data[1]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/draw_holder.c b/lib/glut-3.7.6/progs/demos/ideas/draw_holder.c new file mode 100644 index 0000000000..2ed004328e --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/draw_holder.c @@ -0,0 +1,1358 @@ +/* + * (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. + */ +#include + +#include "objects.h" + +float bn[5][3] = { + {-1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {1.0, 0.0, 0.0}, + {0.0, -1.0, 0.0}, + {0.0, 0.0, 1.0}, +}; + +float bp[4][8][3] = { + { + {-14.000000, -14.000000, 0.000000}, + {-14.000000, -14.000000, 4.000000}, + {-14.000000, 14.000000, 0.000000}, + {-14.000000, 14.000000, 4.000000}, + {14.000000, 14.000000, 0.000000}, + {14.000000, 14.000000, 4.000000}, + {14.000000, -14.000000, 0.000000}, + {14.000000, -14.000000, 4.000000}, + }, + { + {-12.000000, -12.000000, 4.000000}, + {-12.000000, -12.000000, 8.000000}, + {-12.000000, 12.000000, 4.000000}, + {-12.000000, 12.000000, 8.000000}, + {12.000000, 12.000000, 4.000000}, + {12.000000, 12.000000, 8.000000}, + {12.000000, -12.000000, 4.000000}, + {12.000000, -12.000000, 8.000000}, + }, + { + {-10.000000, -10.000000, 8.000000}, + {-10.000000, -10.000000, 12.000000}, + {-10.000000, 10.000000, 8.000000}, + {-10.000000, 10.000000, 12.000000}, + {10.000000, 10.000000, 8.000000}, + {10.000000, 10.000000, 12.000000}, + {10.000000, -10.000000, 8.000000}, + {10.000000, -10.000000, 12.000000}, + }, + { + {-8.000000, -8.000000, 12.000000}, + {-8.000000, -8.000000, 8.000000}, + {-8.000000, 8.000000, 12.000000}, + {-8.000000, 8.000000, 8.000000}, + {8.000000, 8.000000, 12.000000}, + {8.000000, 8.000000, 8.000000}, + {8.000000, -8.000000, 12.000000}, + {8.000000, -8.000000, 8.000000}, + }, +}; + +float tp[12][21][3] = { + { + {10.000000, 0.000000, 1.000000}, + {9.510565, -3.090170, 1.000000}, + {8.090170, -5.877852, 1.000000}, + {5.877852, -8.090170, 1.000000}, + {3.090170, -9.510565, 1.000000}, + {0.000000, -10.000000, 1.000000}, + {-3.090170, -9.510565, 1.000000}, + {-5.877852, -8.090170, 1.000000}, + {-8.090170, -5.877852, 1.000000}, + {-9.510565, -3.090170, 1.000000}, + {-10.000000, 0.000000, 1.000000}, + {-9.510565, 3.090170, 1.000000}, + {-8.090170, 5.877852, 1.000000}, + {-5.877852, 8.090170, 1.000000}, + {-3.090170, 9.510565, 1.000000}, + {0.000000, 10.000000, 1.000000}, + {3.090170, 9.510565, 1.000000}, + {5.877852, 8.090170, 1.000000}, + {8.090170, 5.877852, 1.000000}, + {9.510565, 3.090170, 1.000000}, + {10.000000, 0.000000, 1.000000}, + }, + + { + {10.540641, 0.000000, 0.841254}, + {10.024745, -3.257237, 0.841254}, + {8.527557, -6.195633, 0.841254}, + {6.195633, -8.527557, 0.841254}, + {3.257237, -10.024745, 0.841254}, + {0.000000, -10.540641, 0.841254}, + {-3.257237, -10.024745, 0.841254}, + {-6.195633, -8.527557, 0.841254}, + {-8.527557, -6.195633, 0.841254}, + {-10.024745, -3.257237, 0.841254}, + {-10.540641, 0.000000, 0.841254}, + {-10.024745, 3.257237, 0.841254}, + {-8.527557, 6.195633, 0.841254}, + {-6.195633, 8.527557, 0.841254}, + {-3.257237, 10.024745, 0.841254}, + {0.000000, 10.540641, 0.841254}, + {3.257237, 10.024745, 0.841254}, + {6.195633, 8.527557, 0.841254}, + {8.527557, 6.195633, 0.841254}, + {10.024745, 3.257237, 0.841254}, + {10.540641, 0.000000, 0.841254}, + }, + + { + {10.909632, 0.000000, 0.415415}, + {10.375676, -3.371262, 0.415415}, + {8.826077, -6.412521, 0.415415}, + {6.412521, -8.826077, 0.415415}, + {3.371262, -10.375676, 0.415415}, + {0.000000, -10.909632, 0.415415}, + {-3.371262, -10.375676, 0.415415}, + {-6.412521, -8.826077, 0.415415}, + {-8.826077, -6.412521, 0.415415}, + {-10.375676, -3.371262, 0.415415}, + {-10.909632, 0.000000, 0.415415}, + {-10.375676, 3.371262, 0.415415}, + {-8.826077, 6.412521, 0.415415}, + {-6.412521, 8.826077, 0.415415}, + {-3.371262, 10.375676, 0.415415}, + {0.000000, 10.909632, 0.415415}, + {3.371262, 10.375676, 0.415415}, + {6.412521, 8.826077, 0.415415}, + {8.826077, 6.412521, 0.415415}, + {10.375676, 3.371262, 0.415415}, + {10.909632, 0.000000, 0.415415}, + }, + + { + {10.989821, 0.000000, -0.142315}, + {10.451941, -3.396042, -0.142315}, + {8.890952, -6.459655, -0.142315}, + {6.459655, -8.890952, -0.142315}, + {3.396042, -10.451941, -0.142315}, + {0.000000, -10.989821, -0.142315}, + {-3.396042, -10.451941, -0.142315}, + {-6.459655, -8.890952, -0.142315}, + {-8.890952, -6.459655, -0.142315}, + {-10.451941, -3.396042, -0.142315}, + {-10.989821, 0.000000, -0.142315}, + {-10.451941, 3.396042, -0.142315}, + {-8.890952, 6.459655, -0.142315}, + {-6.459655, 8.890952, -0.142315}, + {-3.396042, 10.451941, -0.142315}, + {0.000000, 10.989821, -0.142315}, + {3.396042, 10.451941, -0.142315}, + {6.459655, 8.890952, -0.142315}, + {8.890952, 6.459655, -0.142315}, + {10.451941, 3.396042, -0.142315}, + {10.989821, 0.000000, -0.142315}, + }, + + { + {10.755750, 0.000000, -0.654861}, + {10.229325, -3.323709, -0.654861}, + {8.701584, -6.322071, -0.654861}, + {6.322071, -8.701584, -0.654861}, + {3.323709, -10.229325, -0.654861}, + {0.000000, -10.755750, -0.654861}, + {-3.323709, -10.229325, -0.654861}, + {-6.322071, -8.701584, -0.654861}, + {-8.701584, -6.322071, -0.654861}, + {-10.229325, -3.323709, -0.654861}, + {-10.755750, 0.000000, -0.654861}, + {-10.229325, 3.323709, -0.654861}, + {-8.701584, 6.322071, -0.654861}, + {-6.322071, 8.701584, -0.654861}, + {-3.323709, 10.229325, -0.654861}, + {0.000000, 10.755750, -0.654861}, + {3.323709, 10.229325, -0.654861}, + {6.322071, 8.701584, -0.654861}, + {8.701584, 6.322071, -0.654861}, + {10.229325, 3.323709, -0.654861}, + {10.755750, 0.000000, -0.654861}, + }, + + { + {10.281733, 0.000000, -0.959493}, + {9.778509, -3.177230, -0.959493}, + {8.318096, -6.043451, -0.959493}, + {6.043451, -8.318096, -0.959493}, + {3.177230, -9.778509, -0.959493}, + {0.000000, -10.281733, -0.959493}, + {-3.177230, -9.778509, -0.959493}, + {-6.043451, -8.318096, -0.959493}, + {-8.318096, -6.043451, -0.959493}, + {-9.778509, -3.177230, -0.959493}, + {-10.281733, 0.000000, -0.959493}, + {-9.778509, 3.177230, -0.959493}, + {-8.318096, 6.043451, -0.959493}, + {-6.043451, 8.318096, -0.959493}, + {-3.177230, 9.778509, -0.959493}, + {0.000000, 10.281733, -0.959493}, + {3.177230, 9.778509, -0.959493}, + {6.043451, 8.318096, -0.959493}, + {8.318096, 6.043451, -0.959493}, + {9.778509, 3.177230, -0.959493}, + {10.281733, 0.000000, -0.959493}, + }, + + { + {9.718267, 0.000000, -0.959493}, + {9.242621, -3.003110, -0.959493}, + {7.862244, -5.712255, -0.959493}, + {5.712255, -7.862244, -0.959493}, + {3.003110, -9.242621, -0.959493}, + {0.000000, -9.718267, -0.959493}, + {-3.003110, -9.242621, -0.959493}, + {-5.712255, -7.862244, -0.959493}, + {-7.862244, -5.712255, -0.959493}, + {-9.242621, -3.003110, -0.959493}, + {-9.718267, 0.000000, -0.959493}, + {-9.242621, 3.003110, -0.959493}, + {-7.862244, 5.712255, -0.959493}, + {-5.712255, 7.862244, -0.959493}, + {-3.003110, 9.242621, -0.959493}, + {0.000000, 9.718267, -0.959493}, + {3.003110, 9.242621, -0.959493}, + {5.712255, 7.862244, -0.959493}, + {7.862244, 5.712255, -0.959493}, + {9.242621, 3.003110, -0.959493}, + {9.718267, 0.000000, -0.959493}, + }, + + { + {9.244250, 0.000000, -0.654861}, + {8.791805, -2.856631, -0.654861}, + {7.478756, -5.433634, -0.654861}, + {5.433634, -7.478756, -0.654861}, + {2.856631, -8.791805, -0.654861}, + {0.000000, -9.244250, -0.654861}, + {-2.856631, -8.791805, -0.654861}, + {-5.433634, -7.478756, -0.654861}, + {-7.478756, -5.433634, -0.654861}, + {-8.791805, -2.856631, -0.654861}, + {-9.244250, 0.000000, -0.654861}, + {-8.791805, 2.856631, -0.654861}, + {-7.478756, 5.433634, -0.654861}, + {-5.433634, 7.478756, -0.654861}, + {-2.856631, 8.791805, -0.654861}, + {0.000000, 9.244250, -0.654861}, + {2.856631, 8.791805, -0.654861}, + {5.433634, 7.478756, -0.654861}, + {7.478756, 5.433634, -0.654861}, + {8.791805, 2.856631, -0.654861}, + {9.244250, 0.000000, -0.654861}, + }, + + { + {9.010179, 0.000000, -0.142315}, + {8.569189, -2.784298, -0.142315}, + {7.289388, -5.296050, -0.142315}, + {5.296050, -7.289388, -0.142315}, + {2.784298, -8.569189, -0.142315}, + {0.000000, -9.010179, -0.142315}, + {-2.784298, -8.569189, -0.142315}, + {-5.296050, -7.289388, -0.142315}, + {-7.289388, -5.296050, -0.142315}, + {-8.569189, -2.784298, -0.142315}, + {-9.010179, 0.000000, -0.142315}, + {-8.569189, 2.784298, -0.142315}, + {-7.289388, 5.296050, -0.142315}, + {-5.296050, 7.289388, -0.142315}, + {-2.784298, 8.569189, -0.142315}, + {0.000000, 9.010179, -0.142315}, + {2.784298, 8.569189, -0.142315}, + {5.296050, 7.289388, -0.142315}, + {7.289388, 5.296050, -0.142315}, + {8.569189, 2.784298, -0.142315}, + {9.010179, 0.000000, -0.142315}, + }, + + { + {9.090367, 0.000000, 0.415414}, + {8.645453, -2.809078, 0.415414}, + {7.354262, -5.343184, 0.415414}, + {5.343184, -7.354262, 0.415414}, + {2.809078, -8.645453, 0.415414}, + {0.000000, -9.090367, 0.415414}, + {-2.809078, -8.645453, 0.415414}, + {-5.343184, -7.354262, 0.415414}, + {-7.354262, -5.343184, 0.415414}, + {-8.645453, -2.809078, 0.415414}, + {-9.090367, 0.000000, 0.415414}, + {-8.645453, 2.809078, 0.415414}, + {-7.354262, 5.343184, 0.415414}, + {-5.343184, 7.354262, 0.415414}, + {-2.809078, 8.645453, 0.415414}, + {0.000000, 9.090367, 0.415414}, + {2.809078, 8.645453, 0.415414}, + {5.343184, 7.354262, 0.415414}, + {7.354262, 5.343184, 0.415414}, + {8.645453, 2.809078, 0.415414}, + {9.090367, 0.000000, 0.415414}, + }, + + { + {9.459358, 0.000000, 0.841253}, + {8.996385, -2.923103, 0.841253}, + {7.652781, -5.560071, 0.841253}, + {5.560071, -7.652781, 0.841253}, + {2.923103, -8.996385, 0.841253}, + {0.000000, -9.459358, 0.841253}, + {-2.923103, -8.996385, 0.841253}, + {-5.560071, -7.652781, 0.841253}, + {-7.652781, -5.560071, 0.841253}, + {-8.996385, -2.923103, 0.841253}, + {-9.459358, 0.000000, 0.841253}, + {-8.996385, 2.923103, 0.841253}, + {-7.652781, 5.560071, 0.841253}, + {-5.560071, 7.652781, 0.841253}, + {-2.923103, 8.996385, 0.841253}, + {0.000000, 9.459358, 0.841253}, + {2.923103, 8.996385, 0.841253}, + {5.560071, 7.652781, 0.841253}, + {7.652781, 5.560071, 0.841253}, + {8.996385, 2.923103, 0.841253}, + {9.459358, 0.000000, 0.841253}, + }, + + { + {9.999999, 0.000000, 1.000000}, + {9.510564, -3.090170, 1.000000}, + {8.090169, -5.877852, 1.000000}, + {5.877852, -8.090169, 1.000000}, + {3.090170, -9.510564, 1.000000}, + {0.000000, -9.999999, 1.000000}, + {-3.090170, -9.510564, 1.000000}, + {-5.877852, -8.090169, 1.000000}, + {-8.090169, -5.877852, 1.000000}, + {-9.510564, -3.090170, 1.000000}, + {-9.999999, 0.000000, 1.000000}, + {-9.510564, 3.090170, 1.000000}, + {-8.090169, 5.877852, 1.000000}, + {-5.877852, 8.090169, 1.000000}, + {-3.090170, 9.510564, 1.000000}, + {0.000000, 9.999999, 1.000000}, + {3.090170, 9.510564, 1.000000}, + {5.877852, 8.090169, 1.000000}, + {8.090169, 5.877852, 1.000000}, + {9.510564, 3.090170, 1.000000}, + {9.999999, 0.000000, 1.000000}, + }, + +}; + +float tn[12][21][3] = { + { + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + }, + + { + {0.540641, 0.000000, 0.841254}, + {0.514180, -0.167067, 0.841254}, + {0.437388, -0.317781, 0.841254}, + {0.317781, -0.437388, 0.841254}, + {0.167067, -0.514180, 0.841254}, + {0.000000, -0.540641, 0.841254}, + {-0.167067, -0.514180, 0.841254}, + {-0.317781, -0.437388, 0.841254}, + {-0.437388, -0.317781, 0.841254}, + {-0.514180, -0.167067, 0.841254}, + {-0.540641, 0.000000, 0.841254}, + {-0.514180, 0.167067, 0.841254}, + {-0.437388, 0.317781, 0.841254}, + {-0.317781, 0.437388, 0.841254}, + {-0.167067, 0.514180, 0.841254}, + {0.000000, 0.540641, 0.841254}, + {0.167067, 0.514180, 0.841254}, + {0.317781, 0.437388, 0.841254}, + {0.437388, 0.317781, 0.841254}, + {0.514180, 0.167067, 0.841254}, + {0.540641, 0.000000, 0.841254}, + }, + + { + {0.909632, 0.000000, 0.415415}, + {0.865111, -0.281092, 0.415415}, + {0.735908, -0.534668, 0.415415}, + {0.534668, -0.735908, 0.415415}, + {0.281092, -0.865111, 0.415415}, + {0.000000, -0.909632, 0.415415}, + {-0.281092, -0.865111, 0.415415}, + {-0.534668, -0.735908, 0.415415}, + {-0.735908, -0.534668, 0.415415}, + {-0.865111, -0.281092, 0.415415}, + {-0.909632, 0.000000, 0.415415}, + {-0.865111, 0.281092, 0.415415}, + {-0.735908, 0.534668, 0.415415}, + {-0.534668, 0.735908, 0.415415}, + {-0.281092, 0.865111, 0.415415}, + {0.000000, 0.909632, 0.415415}, + {0.281092, 0.865111, 0.415415}, + {0.534668, 0.735908, 0.415415}, + {0.735908, 0.534668, 0.415415}, + {0.865111, 0.281092, 0.415415}, + {0.909632, 0.000000, 0.415415}, + }, + + { + {0.989821, 0.000000, -0.142315}, + {0.941376, -0.305872, -0.142315}, + {0.800782, -0.581802, -0.142315}, + {0.581802, -0.800782, -0.142315}, + {0.305872, -0.941376, -0.142315}, + {0.000000, -0.989821, -0.142315}, + {-0.305872, -0.941376, -0.142315}, + {-0.581802, -0.800782, -0.142315}, + {-0.800782, -0.581802, -0.142315}, + {-0.941376, -0.305872, -0.142315}, + {-0.989821, 0.000000, -0.142315}, + {-0.941376, 0.305872, -0.142315}, + {-0.800782, 0.581802, -0.142315}, + {-0.581802, 0.800782, -0.142315}, + {-0.305872, 0.941376, -0.142315}, + {0.000000, 0.989821, -0.142315}, + {0.305872, 0.941376, -0.142315}, + {0.581802, 0.800782, -0.142315}, + {0.800782, 0.581802, -0.142315}, + {0.941376, 0.305872, -0.142315}, + {0.989821, 0.000000, -0.142315}, + }, + + { + {0.755750, 0.000000, -0.654861}, + {0.718761, -0.233539, -0.654861}, + {0.611414, -0.444218, -0.654861}, + {0.444218, -0.611414, -0.654861}, + {0.233539, -0.718761, -0.654861}, + {0.000000, -0.755750, -0.654861}, + {-0.233539, -0.718761, -0.654861}, + {-0.444218, -0.611414, -0.654861}, + {-0.611414, -0.444218, -0.654861}, + {-0.718761, -0.233539, -0.654861}, + {-0.755750, 0.000000, -0.654861}, + {-0.718761, 0.233539, -0.654861}, + {-0.611414, 0.444218, -0.654861}, + {-0.444218, 0.611414, -0.654861}, + {-0.233539, 0.718761, -0.654861}, + {0.000000, 0.755750, -0.654861}, + {0.233539, 0.718761, -0.654861}, + {0.444218, 0.611414, -0.654861}, + {0.611414, 0.444218, -0.654861}, + {0.718761, 0.233539, -0.654861}, + {0.755750, 0.000000, -0.654861}, + }, + + { + {0.281733, 0.000000, -0.959493}, + {0.267944, -0.087060, -0.959493}, + {0.227927, -0.165598, -0.959493}, + {0.165598, -0.227927, -0.959493}, + {0.087060, -0.267944, -0.959493}, + {0.000000, -0.281733, -0.959493}, + {-0.087060, -0.267944, -0.959493}, + {-0.165598, -0.227927, -0.959493}, + {-0.227927, -0.165598, -0.959493}, + {-0.267944, -0.087060, -0.959493}, + {-0.281733, 0.000000, -0.959493}, + {-0.267944, 0.087060, -0.959493}, + {-0.227927, 0.165598, -0.959493}, + {-0.165598, 0.227927, -0.959493}, + {-0.087060, 0.267944, -0.959493}, + {0.000000, 0.281733, -0.959493}, + {0.087060, 0.267944, -0.959493}, + {0.165598, 0.227927, -0.959493}, + {0.227927, 0.165598, -0.959493}, + {0.267944, 0.087060, -0.959493}, + {0.281733, 0.000000, -0.959493}, + }, + + { + {-0.281732, 0.000000, -0.959493}, + {-0.267943, 0.087060, -0.959493}, + {-0.227926, 0.165598, -0.959493}, + {-0.165598, 0.227926, -0.959493}, + {-0.087060, 0.267943, -0.959493}, + {0.000000, 0.281732, -0.959493}, + {0.087060, 0.267943, -0.959493}, + {0.165598, 0.227926, -0.959493}, + {0.227926, 0.165598, -0.959493}, + {0.267943, 0.087060, -0.959493}, + {0.281732, 0.000000, -0.959493}, + {0.267943, -0.087060, -0.959493}, + {0.227926, -0.165598, -0.959493}, + {0.165598, -0.227926, -0.959493}, + {0.087060, -0.267943, -0.959493}, + {0.000000, -0.281732, -0.959493}, + {-0.087060, -0.267943, -0.959493}, + {-0.165598, -0.227926, -0.959493}, + {-0.227926, -0.165598, -0.959493}, + {-0.267943, -0.087060, -0.959493}, + {-0.281732, 0.000000, -0.959493}, + }, + + { + {-0.755749, 0.000000, -0.654861}, + {-0.718760, 0.233539, -0.654861}, + {-0.611414, 0.444218, -0.654861}, + {-0.444218, 0.611414, -0.654861}, + {-0.233539, 0.718760, -0.654861}, + {0.000000, 0.755749, -0.654861}, + {0.233539, 0.718760, -0.654861}, + {0.444218, 0.611414, -0.654861}, + {0.611414, 0.444218, -0.654861}, + {0.718760, 0.233539, -0.654861}, + {0.755749, 0.000000, -0.654861}, + {0.718760, -0.233539, -0.654861}, + {0.611414, -0.444218, -0.654861}, + {0.444218, -0.611414, -0.654861}, + {0.233539, -0.718760, -0.654861}, + {0.000000, -0.755749, -0.654861}, + {-0.233539, -0.718760, -0.654861}, + {-0.444218, -0.611414, -0.654861}, + {-0.611414, -0.444218, -0.654861}, + {-0.718760, -0.233539, -0.654861}, + {-0.755749, 0.000000, -0.654861}, + }, + + { + {-0.989821, 0.000000, -0.142315}, + {-0.941376, 0.305872, -0.142315}, + {-0.800782, 0.581802, -0.142315}, + {-0.581802, 0.800782, -0.142315}, + {-0.305872, 0.941376, -0.142315}, + {0.000000, 0.989821, -0.142315}, + {0.305872, 0.941376, -0.142315}, + {0.581802, 0.800782, -0.142315}, + {0.800782, 0.581802, -0.142315}, + {0.941376, 0.305872, -0.142315}, + {0.989821, 0.000000, -0.142315}, + {0.941376, -0.305872, -0.142315}, + {0.800782, -0.581802, -0.142315}, + {0.581802, -0.800782, -0.142315}, + {0.305872, -0.941376, -0.142315}, + {0.000000, -0.989821, -0.142315}, + {-0.305872, -0.941376, -0.142315}, + {-0.581802, -0.800782, -0.142315}, + {-0.800782, -0.581802, -0.142315}, + {-0.941376, -0.305872, -0.142315}, + {-0.989821, 0.000000, -0.142315}, + }, + + { + {-0.909632, 0.000000, 0.415414}, + {-0.865112, 0.281092, 0.415414}, + {-0.735908, 0.534668, 0.415414}, + {-0.534668, 0.735908, 0.415414}, + {-0.281092, 0.865112, 0.415414}, + {0.000000, 0.909632, 0.415414}, + {0.281092, 0.865112, 0.415414}, + {0.534668, 0.735908, 0.415414}, + {0.735908, 0.534668, 0.415414}, + {0.865112, 0.281092, 0.415414}, + {0.909632, 0.000000, 0.415414}, + {0.865112, -0.281092, 0.415414}, + {0.735908, -0.534668, 0.415414}, + {0.534668, -0.735908, 0.415414}, + {0.281092, -0.865112, 0.415414}, + {0.000000, -0.909632, 0.415414}, + {-0.281092, -0.865112, 0.415414}, + {-0.534668, -0.735908, 0.415414}, + {-0.735908, -0.534668, 0.415414}, + {-0.865112, -0.281092, 0.415414}, + {-0.909632, 0.000000, 0.415414}, + }, + + { + {-0.540642, 0.000000, 0.841253}, + {-0.514181, 0.167067, 0.841253}, + {-0.437388, 0.317781, 0.841253}, + {-0.317781, 0.437388, 0.841253}, + {-0.167067, 0.514181, 0.841253}, + {0.000000, 0.540642, 0.841253}, + {0.167067, 0.514181, 0.841253}, + {0.317781, 0.437388, 0.841253}, + {0.437388, 0.317781, 0.841253}, + {0.514181, 0.167067, 0.841253}, + {0.540642, 0.000000, 0.841253}, + {0.514181, -0.167067, 0.841253}, + {0.437388, -0.317781, 0.841253}, + {0.317781, -0.437388, 0.841253}, + {0.167067, -0.514181, 0.841253}, + {0.000000, -0.540642, 0.841253}, + {-0.167067, -0.514181, 0.841253}, + {-0.317781, -0.437388, 0.841253}, + {-0.437388, -0.317781, 0.841253}, + {-0.514181, -0.167067, 0.841253}, + {-0.540642, 0.000000, 0.841253}, + }, + + { + {-0.000001, 0.000000, 1.000000}, + {-0.000001, 0.000000, 1.000000}, + {-0.000001, 0.000001, 1.000000}, + {-0.000001, 0.000001, 1.000000}, + {0.000000, 0.000001, 1.000000}, + {0.000000, 0.000001, 1.000000}, + {0.000000, 0.000001, 1.000000}, + {0.000001, 0.000001, 1.000000}, + {0.000001, 0.000001, 1.000000}, + {0.000001, 0.000000, 1.000000}, + {0.000001, 0.000000, 1.000000}, + {0.000001, 0.000000, 1.000000}, + {0.000001, -0.000001, 1.000000}, + {0.000001, -0.000001, 1.000000}, + {0.000000, -0.000001, 1.000000}, + {0.000000, -0.000001, 1.000000}, + {0.000000, -0.000001, 1.000000}, + {-0.000001, -0.000001, 1.000000}, + {-0.000001, -0.000001, 1.000000}, + {-0.000001, 0.000000, 1.000000}, + {-0.000001, 0.000000, 1.000000}, + }, + +}; + +void draw_base(void) { + + glCallList( MAT_HOLDER_BASE); + + glBegin(GL_POLYGON); + glNormal3fv(bn[0]); + glVertex3fv(bp[0][0]); + glVertex3fv(bp[0][1]); + glVertex3fv(bp[0][3]); + glVertex3fv(bp[0][2]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[1]); + glVertex3fv(bp[0][2]); + glVertex3fv(bp[0][3]); + glVertex3fv(bp[0][5]); + glVertex3fv(bp[0][4]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[2]); + glVertex3fv(bp[0][4]); + glVertex3fv(bp[0][5]); + glVertex3fv(bp[0][7]); + glVertex3fv(bp[0][6]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[3]); + glVertex3fv(bp[0][6]); + glVertex3fv(bp[0][7]); + glVertex3fv(bp[0][1]); + glVertex3fv(bp[0][0]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(bn[4]); + glVertex3fv(bp[0][1]); + glVertex3fv(bp[1][0]); + glVertex3fv(bp[0][3]); + glVertex3fv(bp[1][2]); + glVertex3fv(bp[0][5]); + glVertex3fv(bp[1][4]); + glVertex3fv(bp[0][7]); + glVertex3fv(bp[1][6]); + glVertex3fv(bp[0][1]); + glVertex3fv(bp[1][0]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[0]); + glVertex3fv(bp[1][0]); + glVertex3fv(bp[1][1]); + glVertex3fv(bp[1][3]); + glVertex3fv(bp[1][2]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[1]); + glVertex3fv(bp[1][2]); + glVertex3fv(bp[1][3]); + glVertex3fv(bp[1][5]); + glVertex3fv(bp[1][4]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[2]); + glVertex3fv(bp[1][4]); + glVertex3fv(bp[1][5]); + glVertex3fv(bp[1][7]); + glVertex3fv(bp[1][6]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[3]); + glVertex3fv(bp[1][6]); + glVertex3fv(bp[1][7]); + glVertex3fv(bp[1][1]); + glVertex3fv(bp[1][0]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(bn[4]); + glVertex3fv(bp[1][1]); + glVertex3fv(bp[2][0]); + glVertex3fv(bp[1][3]); + glVertex3fv(bp[2][2]); + glVertex3fv(bp[1][5]); + glVertex3fv(bp[2][4]); + glVertex3fv(bp[1][7]); + glVertex3fv(bp[2][6]); + glVertex3fv(bp[1][1]); + glVertex3fv(bp[2][0]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[0]); + glVertex3fv(bp[2][0]); + glVertex3fv(bp[2][1]); + glVertex3fv(bp[2][3]); + glVertex3fv(bp[2][2]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[1]); + glVertex3fv(bp[2][2]); + glVertex3fv(bp[2][3]); + glVertex3fv(bp[2][5]); + glVertex3fv(bp[2][4]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[2]); + glVertex3fv(bp[2][4]); + glVertex3fv(bp[2][5]); + glVertex3fv(bp[2][7]); + glVertex3fv(bp[2][6]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[3]); + glVertex3fv(bp[2][6]); + glVertex3fv(bp[2][7]); + glVertex3fv(bp[2][1]); + glVertex3fv(bp[2][0]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(bn[4]); + glVertex3fv(bp[2][1]); + glVertex3fv(bp[3][0]); + glVertex3fv(bp[2][3]); + glVertex3fv(bp[3][2]); + glVertex3fv(bp[2][5]); + glVertex3fv(bp[3][4]); + glVertex3fv(bp[2][7]); + glVertex3fv(bp[3][6]); + glVertex3fv(bp[2][1]); + glVertex3fv(bp[3][0]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[2]); + glVertex3fv(bp[3][0]); + glVertex3fv(bp[3][1]); + glVertex3fv(bp[3][3]); + glVertex3fv(bp[3][2]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[3]); + glVertex3fv(bp[3][2]); + glVertex3fv(bp[3][3]); + glVertex3fv(bp[3][5]); + glVertex3fv(bp[3][4]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[0]); + glVertex3fv(bp[3][4]); + glVertex3fv(bp[3][5]); + glVertex3fv(bp[3][7]); + glVertex3fv(bp[3][6]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[1]); + glVertex3fv(bp[3][6]); + glVertex3fv(bp[3][7]); + glVertex3fv(bp[3][1]); + glVertex3fv(bp[3][0]); + glEnd(); + + glBegin(GL_POLYGON); + glNormal3fv(bn[4]); + glVertex3fv(bp[3][1]); + glVertex3fv(bp[3][3]); + glVertex3fv(bp[3][5]); + glVertex3fv(bp[3][7]); + glEnd(); +} + +void draw_torus(void) { + + glCallList( MAT_HOLDER_RINGS); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[0][0]); glVertex3fv(tp[0][0]); + glNormal3fv(tn[1][0]); glVertex3fv(tp[1][0]); + glNormal3fv(tn[0][1]); glVertex3fv(tp[0][1]); + glNormal3fv(tn[1][1]); glVertex3fv(tp[1][1]); + glNormal3fv(tn[0][2]); glVertex3fv(tp[0][2]); + glNormal3fv(tn[1][2]); glVertex3fv(tp[1][2]); + glNormal3fv(tn[0][3]); glVertex3fv(tp[0][3]); + glNormal3fv(tn[1][3]); glVertex3fv(tp[1][3]); + glNormal3fv(tn[0][4]); glVertex3fv(tp[0][4]); + glNormal3fv(tn[1][4]); glVertex3fv(tp[1][4]); + glNormal3fv(tn[0][5]); glVertex3fv(tp[0][5]); + glNormal3fv(tn[1][5]); glVertex3fv(tp[1][5]); + glNormal3fv(tn[0][6]); glVertex3fv(tp[0][6]); + glNormal3fv(tn[1][6]); glVertex3fv(tp[1][6]); + glNormal3fv(tn[0][7]); glVertex3fv(tp[0][7]); + glNormal3fv(tn[1][7]); glVertex3fv(tp[1][7]); + glNormal3fv(tn[0][8]); glVertex3fv(tp[0][8]); + glNormal3fv(tn[1][8]); glVertex3fv(tp[1][8]); + glNormal3fv(tn[0][9]); glVertex3fv(tp[0][9]); + glNormal3fv(tn[1][9]); glVertex3fv(tp[1][9]); + glNormal3fv(tn[0][10]); glVertex3fv(tp[0][10]); + glNormal3fv(tn[1][10]); glVertex3fv(tp[1][10]); + glNormal3fv(tn[0][11]); glVertex3fv(tp[0][11]); + glNormal3fv(tn[1][11]); glVertex3fv(tp[1][11]); + glNormal3fv(tn[0][12]); glVertex3fv(tp[0][12]); + glNormal3fv(tn[1][12]); glVertex3fv(tp[1][12]); + glNormal3fv(tn[0][13]); glVertex3fv(tp[0][13]); + glNormal3fv(tn[1][13]); glVertex3fv(tp[1][13]); + glNormal3fv(tn[0][14]); glVertex3fv(tp[0][14]); + glNormal3fv(tn[1][14]); glVertex3fv(tp[1][14]); + glNormal3fv(tn[0][15]); glVertex3fv(tp[0][15]); + glNormal3fv(tn[1][15]); glVertex3fv(tp[1][15]); + glNormal3fv(tn[0][16]); glVertex3fv(tp[0][16]); + glNormal3fv(tn[1][16]); glVertex3fv(tp[1][16]); + glNormal3fv(tn[0][17]); glVertex3fv(tp[0][17]); + glNormal3fv(tn[1][17]); glVertex3fv(tp[1][17]); + glNormal3fv(tn[0][18]); glVertex3fv(tp[0][18]); + glNormal3fv(tn[1][18]); glVertex3fv(tp[1][18]); + glNormal3fv(tn[0][19]); glVertex3fv(tp[0][19]); + glNormal3fv(tn[1][19]); glVertex3fv(tp[1][19]); + glNormal3fv(tn[0][20]); glVertex3fv(tp[0][20]); + glNormal3fv(tn[1][20]); glVertex3fv(tp[1][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[1][0]); glVertex3fv(tp[1][0]); + glNormal3fv(tn[2][0]); glVertex3fv(tp[2][0]); + glNormal3fv(tn[1][1]); glVertex3fv(tp[1][1]); + glNormal3fv(tn[2][1]); glVertex3fv(tp[2][1]); + glNormal3fv(tn[1][2]); glVertex3fv(tp[1][2]); + glNormal3fv(tn[2][2]); glVertex3fv(tp[2][2]); + glNormal3fv(tn[1][3]); glVertex3fv(tp[1][3]); + glNormal3fv(tn[2][3]); glVertex3fv(tp[2][3]); + glNormal3fv(tn[1][4]); glVertex3fv(tp[1][4]); + glNormal3fv(tn[2][4]); glVertex3fv(tp[2][4]); + glNormal3fv(tn[1][5]); glVertex3fv(tp[1][5]); + glNormal3fv(tn[2][5]); glVertex3fv(tp[2][5]); + glNormal3fv(tn[1][6]); glVertex3fv(tp[1][6]); + glNormal3fv(tn[2][6]); glVertex3fv(tp[2][6]); + glNormal3fv(tn[1][7]); glVertex3fv(tp[1][7]); + glNormal3fv(tn[2][7]); glVertex3fv(tp[2][7]); + glNormal3fv(tn[1][8]); glVertex3fv(tp[1][8]); + glNormal3fv(tn[2][8]); glVertex3fv(tp[2][8]); + glNormal3fv(tn[1][9]); glVertex3fv(tp[1][9]); + glNormal3fv(tn[2][9]); glVertex3fv(tp[2][9]); + glNormal3fv(tn[1][10]); glVertex3fv(tp[1][10]); + glNormal3fv(tn[2][10]); glVertex3fv(tp[2][10]); + glNormal3fv(tn[1][11]); glVertex3fv(tp[1][11]); + glNormal3fv(tn[2][11]); glVertex3fv(tp[2][11]); + glNormal3fv(tn[1][12]); glVertex3fv(tp[1][12]); + glNormal3fv(tn[2][12]); glVertex3fv(tp[2][12]); + glNormal3fv(tn[1][13]); glVertex3fv(tp[1][13]); + glNormal3fv(tn[2][13]); glVertex3fv(tp[2][13]); + glNormal3fv(tn[1][14]); glVertex3fv(tp[1][14]); + glNormal3fv(tn[2][14]); glVertex3fv(tp[2][14]); + glNormal3fv(tn[1][15]); glVertex3fv(tp[1][15]); + glNormal3fv(tn[2][15]); glVertex3fv(tp[2][15]); + glNormal3fv(tn[1][16]); glVertex3fv(tp[1][16]); + glNormal3fv(tn[2][16]); glVertex3fv(tp[2][16]); + glNormal3fv(tn[1][17]); glVertex3fv(tp[1][17]); + glNormal3fv(tn[2][17]); glVertex3fv(tp[2][17]); + glNormal3fv(tn[1][18]); glVertex3fv(tp[1][18]); + glNormal3fv(tn[2][18]); glVertex3fv(tp[2][18]); + glNormal3fv(tn[1][19]); glVertex3fv(tp[1][19]); + glNormal3fv(tn[2][19]); glVertex3fv(tp[2][19]); + glNormal3fv(tn[1][20]); glVertex3fv(tp[1][20]); + glNormal3fv(tn[2][20]); glVertex3fv(tp[2][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[2][0]); glVertex3fv(tp[2][0]); + glNormal3fv(tn[3][0]); glVertex3fv(tp[3][0]); + glNormal3fv(tn[2][1]); glVertex3fv(tp[2][1]); + glNormal3fv(tn[3][1]); glVertex3fv(tp[3][1]); + glNormal3fv(tn[2][2]); glVertex3fv(tp[2][2]); + glNormal3fv(tn[3][2]); glVertex3fv(tp[3][2]); + glNormal3fv(tn[2][3]); glVertex3fv(tp[2][3]); + glNormal3fv(tn[3][3]); glVertex3fv(tp[3][3]); + glNormal3fv(tn[2][4]); glVertex3fv(tp[2][4]); + glNormal3fv(tn[3][4]); glVertex3fv(tp[3][4]); + glNormal3fv(tn[2][5]); glVertex3fv(tp[2][5]); + glNormal3fv(tn[3][5]); glVertex3fv(tp[3][5]); + glNormal3fv(tn[2][6]); glVertex3fv(tp[2][6]); + glNormal3fv(tn[3][6]); glVertex3fv(tp[3][6]); + glNormal3fv(tn[2][7]); glVertex3fv(tp[2][7]); + glNormal3fv(tn[3][7]); glVertex3fv(tp[3][7]); + glNormal3fv(tn[2][8]); glVertex3fv(tp[2][8]); + glNormal3fv(tn[3][8]); glVertex3fv(tp[3][8]); + glNormal3fv(tn[2][9]); glVertex3fv(tp[2][9]); + glNormal3fv(tn[3][9]); glVertex3fv(tp[3][9]); + glNormal3fv(tn[2][10]); glVertex3fv(tp[2][10]); + glNormal3fv(tn[3][10]); glVertex3fv(tp[3][10]); + glNormal3fv(tn[2][11]); glVertex3fv(tp[2][11]); + glNormal3fv(tn[3][11]); glVertex3fv(tp[3][11]); + glNormal3fv(tn[2][12]); glVertex3fv(tp[2][12]); + glNormal3fv(tn[3][12]); glVertex3fv(tp[3][12]); + glNormal3fv(tn[2][13]); glVertex3fv(tp[2][13]); + glNormal3fv(tn[3][13]); glVertex3fv(tp[3][13]); + glNormal3fv(tn[2][14]); glVertex3fv(tp[2][14]); + glNormal3fv(tn[3][14]); glVertex3fv(tp[3][14]); + glNormal3fv(tn[2][15]); glVertex3fv(tp[2][15]); + glNormal3fv(tn[3][15]); glVertex3fv(tp[3][15]); + glNormal3fv(tn[2][16]); glVertex3fv(tp[2][16]); + glNormal3fv(tn[3][16]); glVertex3fv(tp[3][16]); + glNormal3fv(tn[2][17]); glVertex3fv(tp[2][17]); + glNormal3fv(tn[3][17]); glVertex3fv(tp[3][17]); + glNormal3fv(tn[2][18]); glVertex3fv(tp[2][18]); + glNormal3fv(tn[3][18]); glVertex3fv(tp[3][18]); + glNormal3fv(tn[2][19]); glVertex3fv(tp[2][19]); + glNormal3fv(tn[3][19]); glVertex3fv(tp[3][19]); + glNormal3fv(tn[2][20]); glVertex3fv(tp[2][20]); + glNormal3fv(tn[3][20]); glVertex3fv(tp[3][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[3][0]); glVertex3fv(tp[3][0]); + glNormal3fv(tn[4][0]); glVertex3fv(tp[4][0]); + glNormal3fv(tn[3][1]); glVertex3fv(tp[3][1]); + glNormal3fv(tn[4][1]); glVertex3fv(tp[4][1]); + glNormal3fv(tn[3][2]); glVertex3fv(tp[3][2]); + glNormal3fv(tn[4][2]); glVertex3fv(tp[4][2]); + glNormal3fv(tn[3][3]); glVertex3fv(tp[3][3]); + glNormal3fv(tn[4][3]); glVertex3fv(tp[4][3]); + glNormal3fv(tn[3][4]); glVertex3fv(tp[3][4]); + glNormal3fv(tn[4][4]); glVertex3fv(tp[4][4]); + glNormal3fv(tn[3][5]); glVertex3fv(tp[3][5]); + glNormal3fv(tn[4][5]); glVertex3fv(tp[4][5]); + glNormal3fv(tn[3][6]); glVertex3fv(tp[3][6]); + glNormal3fv(tn[4][6]); glVertex3fv(tp[4][6]); + glNormal3fv(tn[3][7]); glVertex3fv(tp[3][7]); + glNormal3fv(tn[4][7]); glVertex3fv(tp[4][7]); + glNormal3fv(tn[3][8]); glVertex3fv(tp[3][8]); + glNormal3fv(tn[4][8]); glVertex3fv(tp[4][8]); + glNormal3fv(tn[3][9]); glVertex3fv(tp[3][9]); + glNormal3fv(tn[4][9]); glVertex3fv(tp[4][9]); + glNormal3fv(tn[3][10]); glVertex3fv(tp[3][10]); + glNormal3fv(tn[4][10]); glVertex3fv(tp[4][10]); + glNormal3fv(tn[3][11]); glVertex3fv(tp[3][11]); + glNormal3fv(tn[4][11]); glVertex3fv(tp[4][11]); + glNormal3fv(tn[3][12]); glVertex3fv(tp[3][12]); + glNormal3fv(tn[4][12]); glVertex3fv(tp[4][12]); + glNormal3fv(tn[3][13]); glVertex3fv(tp[3][13]); + glNormal3fv(tn[4][13]); glVertex3fv(tp[4][13]); + glNormal3fv(tn[3][14]); glVertex3fv(tp[3][14]); + glNormal3fv(tn[4][14]); glVertex3fv(tp[4][14]); + glNormal3fv(tn[3][15]); glVertex3fv(tp[3][15]); + glNormal3fv(tn[4][15]); glVertex3fv(tp[4][15]); + glNormal3fv(tn[3][16]); glVertex3fv(tp[3][16]); + glNormal3fv(tn[4][16]); glVertex3fv(tp[4][16]); + glNormal3fv(tn[3][17]); glVertex3fv(tp[3][17]); + glNormal3fv(tn[4][17]); glVertex3fv(tp[4][17]); + glNormal3fv(tn[3][18]); glVertex3fv(tp[3][18]); + glNormal3fv(tn[4][18]); glVertex3fv(tp[4][18]); + glNormal3fv(tn[3][19]); glVertex3fv(tp[3][19]); + glNormal3fv(tn[4][19]); glVertex3fv(tp[4][19]); + glNormal3fv(tn[3][20]); glVertex3fv(tp[3][20]); + glNormal3fv(tn[4][20]); glVertex3fv(tp[4][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[4][0]); glVertex3fv(tp[4][0]); + glNormal3fv(tn[5][0]); glVertex3fv(tp[5][0]); + glNormal3fv(tn[4][1]); glVertex3fv(tp[4][1]); + glNormal3fv(tn[5][1]); glVertex3fv(tp[5][1]); + glNormal3fv(tn[4][2]); glVertex3fv(tp[4][2]); + glNormal3fv(tn[5][2]); glVertex3fv(tp[5][2]); + glNormal3fv(tn[4][3]); glVertex3fv(tp[4][3]); + glNormal3fv(tn[5][3]); glVertex3fv(tp[5][3]); + glNormal3fv(tn[4][4]); glVertex3fv(tp[4][4]); + glNormal3fv(tn[5][4]); glVertex3fv(tp[5][4]); + glNormal3fv(tn[4][5]); glVertex3fv(tp[4][5]); + glNormal3fv(tn[5][5]); glVertex3fv(tp[5][5]); + glNormal3fv(tn[4][6]); glVertex3fv(tp[4][6]); + glNormal3fv(tn[5][6]); glVertex3fv(tp[5][6]); + glNormal3fv(tn[4][7]); glVertex3fv(tp[4][7]); + glNormal3fv(tn[5][7]); glVertex3fv(tp[5][7]); + glNormal3fv(tn[4][8]); glVertex3fv(tp[4][8]); + glNormal3fv(tn[5][8]); glVertex3fv(tp[5][8]); + glNormal3fv(tn[4][9]); glVertex3fv(tp[4][9]); + glNormal3fv(tn[5][9]); glVertex3fv(tp[5][9]); + glNormal3fv(tn[4][10]); glVertex3fv(tp[4][10]); + glNormal3fv(tn[5][10]); glVertex3fv(tp[5][10]); + glNormal3fv(tn[4][11]); glVertex3fv(tp[4][11]); + glNormal3fv(tn[5][11]); glVertex3fv(tp[5][11]); + glNormal3fv(tn[4][12]); glVertex3fv(tp[4][12]); + glNormal3fv(tn[5][12]); glVertex3fv(tp[5][12]); + glNormal3fv(tn[4][13]); glVertex3fv(tp[4][13]); + glNormal3fv(tn[5][13]); glVertex3fv(tp[5][13]); + glNormal3fv(tn[4][14]); glVertex3fv(tp[4][14]); + glNormal3fv(tn[5][14]); glVertex3fv(tp[5][14]); + glNormal3fv(tn[4][15]); glVertex3fv(tp[4][15]); + glNormal3fv(tn[5][15]); glVertex3fv(tp[5][15]); + glNormal3fv(tn[4][16]); glVertex3fv(tp[4][16]); + glNormal3fv(tn[5][16]); glVertex3fv(tp[5][16]); + glNormal3fv(tn[4][17]); glVertex3fv(tp[4][17]); + glNormal3fv(tn[5][17]); glVertex3fv(tp[5][17]); + glNormal3fv(tn[4][18]); glVertex3fv(tp[4][18]); + glNormal3fv(tn[5][18]); glVertex3fv(tp[5][18]); + glNormal3fv(tn[4][19]); glVertex3fv(tp[4][19]); + glNormal3fv(tn[5][19]); glVertex3fv(tp[5][19]); + glNormal3fv(tn[4][20]); glVertex3fv(tp[4][20]); + glNormal3fv(tn[5][20]); glVertex3fv(tp[5][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[5][0]); glVertex3fv(tp[5][0]); + glNormal3fv(tn[6][0]); glVertex3fv(tp[6][0]); + glNormal3fv(tn[5][1]); glVertex3fv(tp[5][1]); + glNormal3fv(tn[6][1]); glVertex3fv(tp[6][1]); + glNormal3fv(tn[5][2]); glVertex3fv(tp[5][2]); + glNormal3fv(tn[6][2]); glVertex3fv(tp[6][2]); + glNormal3fv(tn[5][3]); glVertex3fv(tp[5][3]); + glNormal3fv(tn[6][3]); glVertex3fv(tp[6][3]); + glNormal3fv(tn[5][4]); glVertex3fv(tp[5][4]); + glNormal3fv(tn[6][4]); glVertex3fv(tp[6][4]); + glNormal3fv(tn[5][5]); glVertex3fv(tp[5][5]); + glNormal3fv(tn[6][5]); glVertex3fv(tp[6][5]); + glNormal3fv(tn[5][6]); glVertex3fv(tp[5][6]); + glNormal3fv(tn[6][6]); glVertex3fv(tp[6][6]); + glNormal3fv(tn[5][7]); glVertex3fv(tp[5][7]); + glNormal3fv(tn[6][7]); glVertex3fv(tp[6][7]); + glNormal3fv(tn[5][8]); glVertex3fv(tp[5][8]); + glNormal3fv(tn[6][8]); glVertex3fv(tp[6][8]); + glNormal3fv(tn[5][9]); glVertex3fv(tp[5][9]); + glNormal3fv(tn[6][9]); glVertex3fv(tp[6][9]); + glNormal3fv(tn[5][10]); glVertex3fv(tp[5][10]); + glNormal3fv(tn[6][10]); glVertex3fv(tp[6][10]); + glNormal3fv(tn[5][11]); glVertex3fv(tp[5][11]); + glNormal3fv(tn[6][11]); glVertex3fv(tp[6][11]); + glNormal3fv(tn[5][12]); glVertex3fv(tp[5][12]); + glNormal3fv(tn[6][12]); glVertex3fv(tp[6][12]); + glNormal3fv(tn[5][13]); glVertex3fv(tp[5][13]); + glNormal3fv(tn[6][13]); glVertex3fv(tp[6][13]); + glNormal3fv(tn[5][14]); glVertex3fv(tp[5][14]); + glNormal3fv(tn[6][14]); glVertex3fv(tp[6][14]); + glNormal3fv(tn[5][15]); glVertex3fv(tp[5][15]); + glNormal3fv(tn[6][15]); glVertex3fv(tp[6][15]); + glNormal3fv(tn[5][16]); glVertex3fv(tp[5][16]); + glNormal3fv(tn[6][16]); glVertex3fv(tp[6][16]); + glNormal3fv(tn[5][17]); glVertex3fv(tp[5][17]); + glNormal3fv(tn[6][17]); glVertex3fv(tp[6][17]); + glNormal3fv(tn[5][18]); glVertex3fv(tp[5][18]); + glNormal3fv(tn[6][18]); glVertex3fv(tp[6][18]); + glNormal3fv(tn[5][19]); glVertex3fv(tp[5][19]); + glNormal3fv(tn[6][19]); glVertex3fv(tp[6][19]); + glNormal3fv(tn[5][20]); glVertex3fv(tp[5][20]); + glNormal3fv(tn[6][20]); glVertex3fv(tp[6][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[6][0]); glVertex3fv(tp[6][0]); + glNormal3fv(tn[7][0]); glVertex3fv(tp[7][0]); + glNormal3fv(tn[6][1]); glVertex3fv(tp[6][1]); + glNormal3fv(tn[7][1]); glVertex3fv(tp[7][1]); + glNormal3fv(tn[6][2]); glVertex3fv(tp[6][2]); + glNormal3fv(tn[7][2]); glVertex3fv(tp[7][2]); + glNormal3fv(tn[6][3]); glVertex3fv(tp[6][3]); + glNormal3fv(tn[7][3]); glVertex3fv(tp[7][3]); + glNormal3fv(tn[6][4]); glVertex3fv(tp[6][4]); + glNormal3fv(tn[7][4]); glVertex3fv(tp[7][4]); + glNormal3fv(tn[6][5]); glVertex3fv(tp[6][5]); + glNormal3fv(tn[7][5]); glVertex3fv(tp[7][5]); + glNormal3fv(tn[6][6]); glVertex3fv(tp[6][6]); + glNormal3fv(tn[7][6]); glVertex3fv(tp[7][6]); + glNormal3fv(tn[6][7]); glVertex3fv(tp[6][7]); + glNormal3fv(tn[7][7]); glVertex3fv(tp[7][7]); + glNormal3fv(tn[6][8]); glVertex3fv(tp[6][8]); + glNormal3fv(tn[7][8]); glVertex3fv(tp[7][8]); + glNormal3fv(tn[6][9]); glVertex3fv(tp[6][9]); + glNormal3fv(tn[7][9]); glVertex3fv(tp[7][9]); + glNormal3fv(tn[6][10]); glVertex3fv(tp[6][10]); + glNormal3fv(tn[7][10]); glVertex3fv(tp[7][10]); + glNormal3fv(tn[6][11]); glVertex3fv(tp[6][11]); + glNormal3fv(tn[7][11]); glVertex3fv(tp[7][11]); + glNormal3fv(tn[6][12]); glVertex3fv(tp[6][12]); + glNormal3fv(tn[7][12]); glVertex3fv(tp[7][12]); + glNormal3fv(tn[6][13]); glVertex3fv(tp[6][13]); + glNormal3fv(tn[7][13]); glVertex3fv(tp[7][13]); + glNormal3fv(tn[6][14]); glVertex3fv(tp[6][14]); + glNormal3fv(tn[7][14]); glVertex3fv(tp[7][14]); + glNormal3fv(tn[6][15]); glVertex3fv(tp[6][15]); + glNormal3fv(tn[7][15]); glVertex3fv(tp[7][15]); + glNormal3fv(tn[6][16]); glVertex3fv(tp[6][16]); + glNormal3fv(tn[7][16]); glVertex3fv(tp[7][16]); + glNormal3fv(tn[6][17]); glVertex3fv(tp[6][17]); + glNormal3fv(tn[7][17]); glVertex3fv(tp[7][17]); + glNormal3fv(tn[6][18]); glVertex3fv(tp[6][18]); + glNormal3fv(tn[7][18]); glVertex3fv(tp[7][18]); + glNormal3fv(tn[6][19]); glVertex3fv(tp[6][19]); + glNormal3fv(tn[7][19]); glVertex3fv(tp[7][19]); + glNormal3fv(tn[6][20]); glVertex3fv(tp[6][20]); + glNormal3fv(tn[7][20]); glVertex3fv(tp[7][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[7][0]); glVertex3fv(tp[7][0]); + glNormal3fv(tn[8][0]); glVertex3fv(tp[8][0]); + glNormal3fv(tn[7][1]); glVertex3fv(tp[7][1]); + glNormal3fv(tn[8][1]); glVertex3fv(tp[8][1]); + glNormal3fv(tn[7][2]); glVertex3fv(tp[7][2]); + glNormal3fv(tn[8][2]); glVertex3fv(tp[8][2]); + glNormal3fv(tn[7][3]); glVertex3fv(tp[7][3]); + glNormal3fv(tn[8][3]); glVertex3fv(tp[8][3]); + glNormal3fv(tn[7][4]); glVertex3fv(tp[7][4]); + glNormal3fv(tn[8][4]); glVertex3fv(tp[8][4]); + glNormal3fv(tn[7][5]); glVertex3fv(tp[7][5]); + glNormal3fv(tn[8][5]); glVertex3fv(tp[8][5]); + glNormal3fv(tn[7][6]); glVertex3fv(tp[7][6]); + glNormal3fv(tn[8][6]); glVertex3fv(tp[8][6]); + glNormal3fv(tn[7][7]); glVertex3fv(tp[7][7]); + glNormal3fv(tn[8][7]); glVertex3fv(tp[8][7]); + glNormal3fv(tn[7][8]); glVertex3fv(tp[7][8]); + glNormal3fv(tn[8][8]); glVertex3fv(tp[8][8]); + glNormal3fv(tn[7][9]); glVertex3fv(tp[7][9]); + glNormal3fv(tn[8][9]); glVertex3fv(tp[8][9]); + glNormal3fv(tn[7][10]); glVertex3fv(tp[7][10]); + glNormal3fv(tn[8][10]); glVertex3fv(tp[8][10]); + glNormal3fv(tn[7][11]); glVertex3fv(tp[7][11]); + glNormal3fv(tn[8][11]); glVertex3fv(tp[8][11]); + glNormal3fv(tn[7][12]); glVertex3fv(tp[7][12]); + glNormal3fv(tn[8][12]); glVertex3fv(tp[8][12]); + glNormal3fv(tn[7][13]); glVertex3fv(tp[7][13]); + glNormal3fv(tn[8][13]); glVertex3fv(tp[8][13]); + glNormal3fv(tn[7][14]); glVertex3fv(tp[7][14]); + glNormal3fv(tn[8][14]); glVertex3fv(tp[8][14]); + glNormal3fv(tn[7][15]); glVertex3fv(tp[7][15]); + glNormal3fv(tn[8][15]); glVertex3fv(tp[8][15]); + glNormal3fv(tn[7][16]); glVertex3fv(tp[7][16]); + glNormal3fv(tn[8][16]); glVertex3fv(tp[8][16]); + glNormal3fv(tn[7][17]); glVertex3fv(tp[7][17]); + glNormal3fv(tn[8][17]); glVertex3fv(tp[8][17]); + glNormal3fv(tn[7][18]); glVertex3fv(tp[7][18]); + glNormal3fv(tn[8][18]); glVertex3fv(tp[8][18]); + glNormal3fv(tn[7][19]); glVertex3fv(tp[7][19]); + glNormal3fv(tn[8][19]); glVertex3fv(tp[8][19]); + glNormal3fv(tn[7][20]); glVertex3fv(tp[7][20]); + glNormal3fv(tn[8][20]); glVertex3fv(tp[8][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[8][0]); glVertex3fv(tp[8][0]); + glNormal3fv(tn[9][0]); glVertex3fv(tp[9][0]); + glNormal3fv(tn[8][1]); glVertex3fv(tp[8][1]); + glNormal3fv(tn[9][1]); glVertex3fv(tp[9][1]); + glNormal3fv(tn[8][2]); glVertex3fv(tp[8][2]); + glNormal3fv(tn[9][2]); glVertex3fv(tp[9][2]); + glNormal3fv(tn[8][3]); glVertex3fv(tp[8][3]); + glNormal3fv(tn[9][3]); glVertex3fv(tp[9][3]); + glNormal3fv(tn[8][4]); glVertex3fv(tp[8][4]); + glNormal3fv(tn[9][4]); glVertex3fv(tp[9][4]); + glNormal3fv(tn[8][5]); glVertex3fv(tp[8][5]); + glNormal3fv(tn[9][5]); glVertex3fv(tp[9][5]); + glNormal3fv(tn[8][6]); glVertex3fv(tp[8][6]); + glNormal3fv(tn[9][6]); glVertex3fv(tp[9][6]); + glNormal3fv(tn[8][7]); glVertex3fv(tp[8][7]); + glNormal3fv(tn[9][7]); glVertex3fv(tp[9][7]); + glNormal3fv(tn[8][8]); glVertex3fv(tp[8][8]); + glNormal3fv(tn[9][8]); glVertex3fv(tp[9][8]); + glNormal3fv(tn[8][9]); glVertex3fv(tp[8][9]); + glNormal3fv(tn[9][9]); glVertex3fv(tp[9][9]); + glNormal3fv(tn[8][10]); glVertex3fv(tp[8][10]); + glNormal3fv(tn[9][10]); glVertex3fv(tp[9][10]); + glNormal3fv(tn[8][11]); glVertex3fv(tp[8][11]); + glNormal3fv(tn[9][11]); glVertex3fv(tp[9][11]); + glNormal3fv(tn[8][12]); glVertex3fv(tp[8][12]); + glNormal3fv(tn[9][12]); glVertex3fv(tp[9][12]); + glNormal3fv(tn[8][13]); glVertex3fv(tp[8][13]); + glNormal3fv(tn[9][13]); glVertex3fv(tp[9][13]); + glNormal3fv(tn[8][14]); glVertex3fv(tp[8][14]); + glNormal3fv(tn[9][14]); glVertex3fv(tp[9][14]); + glNormal3fv(tn[8][15]); glVertex3fv(tp[8][15]); + glNormal3fv(tn[9][15]); glVertex3fv(tp[9][15]); + glNormal3fv(tn[8][16]); glVertex3fv(tp[8][16]); + glNormal3fv(tn[9][16]); glVertex3fv(tp[9][16]); + glNormal3fv(tn[8][17]); glVertex3fv(tp[8][17]); + glNormal3fv(tn[9][17]); glVertex3fv(tp[9][17]); + glNormal3fv(tn[8][18]); glVertex3fv(tp[8][18]); + glNormal3fv(tn[9][18]); glVertex3fv(tp[9][18]); + glNormal3fv(tn[8][19]); glVertex3fv(tp[8][19]); + glNormal3fv(tn[9][19]); glVertex3fv(tp[9][19]); + glNormal3fv(tn[8][20]); glVertex3fv(tp[8][20]); + glNormal3fv(tn[9][20]); glVertex3fv(tp[9][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[9][0]); glVertex3fv(tp[9][0]); + glNormal3fv(tn[10][0]); glVertex3fv(tp[10][0]); + glNormal3fv(tn[9][1]); glVertex3fv(tp[9][1]); + glNormal3fv(tn[10][1]); glVertex3fv(tp[10][1]); + glNormal3fv(tn[9][2]); glVertex3fv(tp[9][2]); + glNormal3fv(tn[10][2]); glVertex3fv(tp[10][2]); + glNormal3fv(tn[9][3]); glVertex3fv(tp[9][3]); + glNormal3fv(tn[10][3]); glVertex3fv(tp[10][3]); + glNormal3fv(tn[9][4]); glVertex3fv(tp[9][4]); + glNormal3fv(tn[10][4]); glVertex3fv(tp[10][4]); + glNormal3fv(tn[9][5]); glVertex3fv(tp[9][5]); + glNormal3fv(tn[10][5]); glVertex3fv(tp[10][5]); + glNormal3fv(tn[9][6]); glVertex3fv(tp[9][6]); + glNormal3fv(tn[10][6]); glVertex3fv(tp[10][6]); + glNormal3fv(tn[9][7]); glVertex3fv(tp[9][7]); + glNormal3fv(tn[10][7]); glVertex3fv(tp[10][7]); + glNormal3fv(tn[9][8]); glVertex3fv(tp[9][8]); + glNormal3fv(tn[10][8]); glVertex3fv(tp[10][8]); + glNormal3fv(tn[9][9]); glVertex3fv(tp[9][9]); + glNormal3fv(tn[10][9]); glVertex3fv(tp[10][9]); + glNormal3fv(tn[9][10]); glVertex3fv(tp[9][10]); + glNormal3fv(tn[10][10]); glVertex3fv(tp[10][10]); + glNormal3fv(tn[9][11]); glVertex3fv(tp[9][11]); + glNormal3fv(tn[10][11]); glVertex3fv(tp[10][11]); + glNormal3fv(tn[9][12]); glVertex3fv(tp[9][12]); + glNormal3fv(tn[10][12]); glVertex3fv(tp[10][12]); + glNormal3fv(tn[9][13]); glVertex3fv(tp[9][13]); + glNormal3fv(tn[10][13]); glVertex3fv(tp[10][13]); + glNormal3fv(tn[9][14]); glVertex3fv(tp[9][14]); + glNormal3fv(tn[10][14]); glVertex3fv(tp[10][14]); + glNormal3fv(tn[9][15]); glVertex3fv(tp[9][15]); + glNormal3fv(tn[10][15]); glVertex3fv(tp[10][15]); + glNormal3fv(tn[9][16]); glVertex3fv(tp[9][16]); + glNormal3fv(tn[10][16]); glVertex3fv(tp[10][16]); + glNormal3fv(tn[9][17]); glVertex3fv(tp[9][17]); + glNormal3fv(tn[10][17]); glVertex3fv(tp[10][17]); + glNormal3fv(tn[9][18]); glVertex3fv(tp[9][18]); + glNormal3fv(tn[10][18]); glVertex3fv(tp[10][18]); + glNormal3fv(tn[9][19]); glVertex3fv(tp[9][19]); + glNormal3fv(tn[10][19]); glVertex3fv(tp[10][19]); + glNormal3fv(tn[9][20]); glVertex3fv(tp[9][20]); + glNormal3fv(tn[10][20]); glVertex3fv(tp[10][20]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(tn[10][0]); glVertex3fv(tp[10][0]); + glNormal3fv(tn[11][0]); glVertex3fv(tp[11][0]); + glNormal3fv(tn[10][1]); glVertex3fv(tp[10][1]); + glNormal3fv(tn[11][1]); glVertex3fv(tp[11][1]); + glNormal3fv(tn[10][2]); glVertex3fv(tp[10][2]); + glNormal3fv(tn[11][2]); glVertex3fv(tp[11][2]); + glNormal3fv(tn[10][3]); glVertex3fv(tp[10][3]); + glNormal3fv(tn[11][3]); glVertex3fv(tp[11][3]); + glNormal3fv(tn[10][4]); glVertex3fv(tp[10][4]); + glNormal3fv(tn[11][4]); glVertex3fv(tp[11][4]); + glNormal3fv(tn[10][5]); glVertex3fv(tp[10][5]); + glNormal3fv(tn[11][5]); glVertex3fv(tp[11][5]); + glNormal3fv(tn[10][6]); glVertex3fv(tp[10][6]); + glNormal3fv(tn[11][6]); glVertex3fv(tp[11][6]); + glNormal3fv(tn[10][7]); glVertex3fv(tp[10][7]); + glNormal3fv(tn[11][7]); glVertex3fv(tp[11][7]); + glNormal3fv(tn[10][8]); glVertex3fv(tp[10][8]); + glNormal3fv(tn[11][8]); glVertex3fv(tp[11][8]); + glNormal3fv(tn[10][9]); glVertex3fv(tp[10][9]); + glNormal3fv(tn[11][9]); glVertex3fv(tp[11][9]); + glNormal3fv(tn[10][10]); glVertex3fv(tp[10][10]); + glNormal3fv(tn[11][10]); glVertex3fv(tp[11][10]); + glNormal3fv(tn[10][11]); glVertex3fv(tp[10][11]); + glNormal3fv(tn[11][11]); glVertex3fv(tp[11][11]); + glNormal3fv(tn[10][12]); glVertex3fv(tp[10][12]); + glNormal3fv(tn[11][12]); glVertex3fv(tp[11][12]); + glNormal3fv(tn[10][13]); glVertex3fv(tp[10][13]); + glNormal3fv(tn[11][13]); glVertex3fv(tp[11][13]); + glNormal3fv(tn[10][14]); glVertex3fv(tp[10][14]); + glNormal3fv(tn[11][14]); glVertex3fv(tp[11][14]); + glNormal3fv(tn[10][15]); glVertex3fv(tp[10][15]); + glNormal3fv(tn[11][15]); glVertex3fv(tp[11][15]); + glNormal3fv(tn[10][16]); glVertex3fv(tp[10][16]); + glNormal3fv(tn[11][16]); glVertex3fv(tp[11][16]); + glNormal3fv(tn[10][17]); glVertex3fv(tp[10][17]); + glNormal3fv(tn[11][17]); glVertex3fv(tp[11][17]); + glNormal3fv(tn[10][18]); glVertex3fv(tp[10][18]); + glNormal3fv(tn[11][18]); glVertex3fv(tp[11][18]); + glNormal3fv(tn[10][19]); glVertex3fv(tp[10][19]); + glNormal3fv(tn[11][19]); glVertex3fv(tp[11][19]); + glNormal3fv(tn[10][20]); glVertex3fv(tp[10][20]); + glNormal3fv(tn[11][20]); glVertex3fv(tp[11][20]); + glEnd(); +} + +void draw_holder(void) { + + glCallList( MAT_HOLDER_RINGS); + + glPushMatrix(); + draw_base(); + glTranslatef(0.0, 0.0, 20.000000); + draw_torus(); + glTranslatef(0.0, 0.0, 5.000000); + draw_torus(); + glTranslatef(0.0, 0.0, 5.000000); + draw_torus(); + glPopMatrix(); +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/draw_lamp.c b/lib/glut-3.7.6/progs/demos/ideas/draw_lamp.c new file mode 100644 index 0000000000..70e5b96a9a --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/draw_lamp.c @@ -0,0 +1,826 @@ +/* + * (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. + */ +#include + +#include "objects.h" +/* +#define glNormal3fv(v) \ +{ \ + printf("%g, %g, %g --> %.10f\n", \ + v[0], v[1], v[2], v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); \ + glNormal3fv(v); \ +} +*/ +float hp[6][13][3] = { + + { + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + }, + { + {0.438371, 0.000000, 0.898794}, + {0.379641, 0.219186, 0.898794}, + {0.219186, 0.379641, 0.898794}, + {0.000000, 0.438371, 0.898794}, + {-0.219186, 0.379641, 0.898794}, + {-0.379641, 0.219186, 0.898794}, + {-0.438371, 0.000000, 0.898794}, + {-0.379641, -0.219186, 0.898794}, + {-0.219186, -0.379641, 0.898794}, + {0.000000, -0.438371, 0.898794}, + {0.219186, -0.379641, 0.898794}, + {0.379641, -0.219186, 0.898794}, + {0.438371, 0.000000, 0.898794}, + }, + { + {0.788011, 0.000000, 0.615662}, + {0.682437, 0.394005, 0.615662}, + {0.394005, 0.682437, 0.615662}, + {0.000000, 0.788011, 0.615662}, + {-0.394005, 0.682437, 0.615662}, + {-0.682437, 0.394005, 0.615662}, + {-0.788011, 0.000000, 0.615662}, + {-0.682437, -0.394005, 0.615662}, + {-0.394005, -0.682437, 0.615662}, + {0.000000, -0.788011, 0.615662}, + {0.394005, -0.682437, 0.615662}, + {0.682437, -0.394005, 0.615662}, + {0.788011, 0.000000, 0.615662}, + }, + { + {0.978148, 0.000000, 0.207912}, + {0.847101, 0.489074, 0.207912}, + {0.489074, 0.847101, 0.207912}, + {0.000000, 0.978148, 0.207912}, + {-0.489074, 0.847101, 0.207912}, + {-0.847101, 0.489074, 0.207912}, + {-0.978148, 0.000000, 0.207912}, + {-0.847101, -0.489074, 0.207912}, + {-0.489074, -0.847101, 0.207912}, + {0.000000, -0.978148, 0.207912}, + {0.489074, -0.847101, 0.207912}, + {0.847101, -0.489074, 0.207912}, + {0.978148, 0.000000, 0.207912}, + }, + { + {0.970296, 0.000000, -0.241922}, + {0.840301, 0.485148, -0.241922}, + {0.485148, 0.840301, -0.241922}, + {0.000000, 0.970296, -0.241922}, + {-0.485148, 0.840301, -0.241922}, + {-0.840301, 0.485148, -0.241922}, + {-0.970296, 0.000000, -0.241922}, + {-0.840301, -0.485148, -0.241922}, + {-0.485148, -0.840301, -0.241922}, + {0.000000, -0.970296, -0.241922}, + {0.485148, -0.840301, -0.241922}, + {0.840301, -0.485148, -0.241922}, + {0.970296, 0.000000, -0.241922}, + }, + { + {0.766044, 0.000000, -0.642788}, + {0.663414, 0.383022, -0.642788}, + {0.383022, 0.663414, -0.642788}, + {0.000000, 0.766044, -0.642788}, + {-0.383022, 0.663414, -0.642788}, + {-0.663414, 0.383022, -0.642788}, + {-0.766044, 0.000000, -0.642788}, + {-0.663414, -0.383022, -0.642788}, + {-0.383022, -0.663414, -0.642788}, + {0.000000, -0.766044, -0.642788}, + {0.383022, -0.663414, -0.642788}, + {0.663414, -0.383022, -0.642788}, + {0.766044, 0.000000, -0.642788}, + }, +}; + +float ltp[9][25][3] = { + { + {10.000000, 0.000000, 1.000000}, + {9.659258, -2.588191, 1.000000}, + {8.660254, -5.000000, 1.000000}, + {7.071068, -7.071068, 1.000000}, + {5.000000, -8.660254, 1.000000}, + {2.588191, -9.659258, 1.000000}, + {0.000000, -10.000000, 1.000000}, + {-2.588191, -9.659258, 1.000000}, + {-5.000000, -8.660254, 1.000000}, + {-7.071068, -7.071068, 1.000000}, + {-8.660254, -5.000000, 1.000000}, + {-9.659258, -2.588191, 1.000000}, + {-10.000000, 0.000000, 1.000000}, + {-9.659258, 2.588191, 1.000000}, + {-8.660254, 5.000000, 1.000000}, + {-7.071068, 7.071068, 1.000000}, + {-5.000000, 8.660254, 1.000000}, + {-2.588191, 9.659258, 1.000000}, + {0.000000, 10.000000, 1.000000}, + {2.588191, 9.659258, 1.000000}, + {5.000000, 8.660254, 1.000000}, + {7.071068, 7.071068, 1.000000}, + {8.660254, 5.000000, 1.000000}, + {9.659258, 2.588191, 1.000000}, + {10.000000, 0.000000, 1.000000}, + }, + + { + {10.707107, 0.000000, 0.707107}, + {10.342271, -2.771203, 0.707107}, + {9.272627, -5.353553, 0.707107}, + {7.571068, -7.571068, 0.707107}, + {5.353553, -9.272627, 0.707107}, + {2.771203, -10.342271, 0.707107}, + {0.000000, -10.707107, 0.707107}, + {-2.771203, -10.342271, 0.707107}, + {-5.353553, -9.272627, 0.707107}, + {-7.571068, -7.571068, 0.707107}, + {-9.272627, -5.353553, 0.707107}, + {-10.342271, -2.771203, 0.707107}, + {-10.707107, 0.000000, 0.707107}, + {-10.342271, 2.771203, 0.707107}, + {-9.272627, 5.353553, 0.707107}, + {-7.571068, 7.571068, 0.707107}, + {-5.353553, 9.272627, 0.707107}, + {-2.771203, 10.342271, 0.707107}, + {0.000000, 10.707107, 0.707107}, + {2.771203, 10.342271, 0.707107}, + {5.353553, 9.272627, 0.707107}, + {7.571068, 7.571068, 0.707107}, + {9.272627, 5.353553, 0.707107}, + {10.342271, 2.771203, 0.707107}, + {10.707107, 0.000000, 0.707107}, + }, + + { + {11.000000, 0.000000, 0.000000}, + {10.625184, -2.847009, 0.000000}, + {9.526279, -5.500000, 0.000000}, + {7.778174, -7.778174, 0.000000}, + {5.500000, -9.526279, 0.000000}, + {2.847009, -10.625184, 0.000000}, + {0.000000, -11.000000, 0.000000}, + {-2.847009, -10.625184, 0.000000}, + {-5.500000, -9.526279, 0.000000}, + {-7.778174, -7.778174, 0.000000}, + {-9.526279, -5.500000, 0.000000}, + {-10.625184, -2.847009, 0.000000}, + {-11.000000, 0.000000, 0.000000}, + {-10.625184, 2.847009, 0.000000}, + {-9.526279, 5.500000, 0.000000}, + {-7.778174, 7.778174, 0.000000}, + {-5.500000, 9.526279, 0.000000}, + {-2.847009, 10.625184, 0.000000}, + {0.000000, 11.000000, 0.000000}, + {2.847009, 10.625184, 0.000000}, + {5.500000, 9.526279, 0.000000}, + {7.778174, 7.778174, 0.000000}, + {9.526279, 5.500000, 0.000000}, + {10.625184, 2.847009, 0.000000}, + {11.000000, 0.000000, 0.000000}, + }, + + { + {10.707107, 0.000000, -0.707107}, + {10.342271, -2.771203, -0.707107}, + {9.272627, -5.353553, -0.707107}, + {7.571068, -7.571068, -0.707107}, + {5.353553, -9.272627, -0.707107}, + {2.771203, -10.342271, -0.707107}, + {0.000000, -10.707107, -0.707107}, + {-2.771203, -10.342271, -0.707107}, + {-5.353553, -9.272627, -0.707107}, + {-7.571068, -7.571068, -0.707107}, + {-9.272627, -5.353553, -0.707107}, + {-10.342271, -2.771203, -0.707107}, + {-10.707107, 0.000000, -0.707107}, + {-10.342271, 2.771203, -0.707107}, + {-9.272627, 5.353553, -0.707107}, + {-7.571068, 7.571068, -0.707107}, + {-5.353553, 9.272627, -0.707107}, + {-2.771203, 10.342271, -0.707107}, + {0.000000, 10.707107, -0.707107}, + {2.771203, 10.342271, -0.707107}, + {5.353553, 9.272627, -0.707107}, + {7.571068, 7.571068, -0.707107}, + {9.272627, 5.353553, -0.707107}, + {10.342271, 2.771203, -0.707107}, + {10.707107, 0.000000, -0.707107}, + }, + + { + {10.000000, 0.000000, -1.000000}, + {9.659258, -2.588191, -1.000000}, + {8.660254, -5.000000, -1.000000}, + {7.071068, -7.071068, -1.000000}, + {5.000000, -8.660254, -1.000000}, + {2.588191, -9.659258, -1.000000}, + {0.000000, -10.000000, -1.000000}, + {-2.588191, -9.659258, -1.000000}, + {-5.000000, -8.660254, -1.000000}, + {-7.071068, -7.071068, -1.000000}, + {-8.660254, -5.000000, -1.000000}, + {-9.659258, -2.588191, -1.000000}, + {-10.000000, 0.000000, -1.000000}, + {-9.659258, 2.588191, -1.000000}, + {-8.660254, 5.000000, -1.000000}, + {-7.071068, 7.071068, -1.000000}, + {-5.000000, 8.660254, -1.000000}, + {-2.588191, 9.659258, -1.000000}, + {0.000000, 10.000000, -1.000000}, + {2.588191, 9.659258, -1.000000}, + {5.000000, 8.660254, -1.000000}, + {7.071068, 7.071068, -1.000000}, + {8.660254, 5.000000, -1.000000}, + {9.659258, 2.588191, -1.000000}, + {10.000000, 0.000000, -1.000000}, + }, + + { + {9.292893, 0.000000, -0.707107}, + {8.976246, -2.405178, -0.707107}, + {8.047881, -4.646447, -0.707107}, + {6.571068, -6.571068, -0.707107}, + {4.646447, -8.047881, -0.707107}, + {2.405178, -8.976246, -0.707107}, + {0.000000, -9.292893, -0.707107}, + {-2.405178, -8.976246, -0.707107}, + {-4.646447, -8.047881, -0.707107}, + {-6.571068, -6.571068, -0.707107}, + {-8.047881, -4.646447, -0.707107}, + {-8.976246, -2.405178, -0.707107}, + {-9.292893, 0.000000, -0.707107}, + {-8.976246, 2.405178, -0.707107}, + {-8.047881, 4.646447, -0.707107}, + {-6.571068, 6.571068, -0.707107}, + {-4.646447, 8.047881, -0.707107}, + {-2.405178, 8.976246, -0.707107}, + {0.000000, 9.292893, -0.707107}, + {2.405178, 8.976246, -0.707107}, + {4.646447, 8.047881, -0.707107}, + {6.571068, 6.571068, -0.707107}, + {8.047881, 4.646447, -0.707107}, + {8.976246, 2.405178, -0.707107}, + {9.292893, 0.000000, -0.707107}, + }, + + { + {9.000000, 0.000000, 0.000000}, + {8.693333, -2.329371, 0.000000}, + {7.794229, -4.500000, 0.000000}, + {6.363961, -6.363961, 0.000000}, + {4.500000, -7.794229, 0.000000}, + {2.329371, -8.693333, 0.000000}, + {0.000000, -9.000000, 0.000000}, + {-2.329371, -8.693333, 0.000000}, + {-4.500000, -7.794229, 0.000000}, + {-6.363961, -6.363961, 0.000000}, + {-7.794229, -4.500000, 0.000000}, + {-8.693333, -2.329371, 0.000000}, + {-9.000000, 0.000000, 0.000000}, + {-8.693333, 2.329371, 0.000000}, + {-7.794229, 4.500000, 0.000000}, + {-6.363961, 6.363961, 0.000000}, + {-4.500000, 7.794229, 0.000000}, + {-2.329371, 8.693333, 0.000000}, + {0.000000, 9.000000, 0.000000}, + {2.329371, 8.693333, 0.000000}, + {4.500000, 7.794229, 0.000000}, + {6.363961, 6.363961, 0.000000}, + {7.794229, 4.500000, 0.000000}, + {8.693333, 2.329371, 0.000000}, + {9.000000, 0.000000, 0.000000}, + }, + + { + {9.292893, 0.000000, 0.707107}, + {8.976246, -2.405178, 0.707107}, + {8.047881, -4.646447, 0.707107}, + {6.571068, -6.571068, 0.707107}, + {4.646447, -8.047881, 0.707107}, + {2.405178, -8.976246, 0.707107}, + {0.000000, -9.292893, 0.707107}, + {-2.405178, -8.976246, 0.707107}, + {-4.646447, -8.047881, 0.707107}, + {-6.571068, -6.571068, 0.707107}, + {-8.047881, -4.646447, 0.707107}, + {-8.976246, -2.405178, 0.707107}, + {-9.292893, 0.000000, 0.707107}, + {-8.976246, 2.405178, 0.707107}, + {-8.047881, 4.646447, 0.707107}, + {-6.571068, 6.571068, 0.707107}, + {-4.646447, 8.047881, 0.707107}, + {-2.405178, 8.976246, 0.707107}, + {0.000000, 9.292893, 0.707107}, + {2.405178, 8.976246, 0.707107}, + {4.646447, 8.047881, 0.707107}, + {6.571068, 6.571068, 0.707107}, + {8.047881, 4.646447, 0.707107}, + {8.976246, 2.405178, 0.707107}, + {9.292893, 0.000000, 0.707107}, + }, + + { + {10.000000, 0.000000, 1.000000}, + {9.659258, -2.588191, 1.000000}, + {8.660254, -5.000000, 1.000000}, + {7.071068, -7.071068, 1.000000}, + {5.000000, -8.660254, 1.000000}, + {2.588191, -9.659258, 1.000000}, + {0.000000, -10.000000, 1.000000}, + {-2.588191, -9.659258, 1.000000}, + {-5.000000, -8.660254, 1.000000}, + {-7.071068, -7.071068, 1.000000}, + {-8.660254, -5.000000, 1.000000}, + {-9.659258, -2.588191, 1.000000}, + {-10.000000, 0.000000, 1.000000}, + {-9.659258, 2.588191, 1.000000}, + {-8.660254, 5.000000, 1.000000}, + {-7.071068, 7.071068, 1.000000}, + {-5.000000, 8.660254, 1.000000}, + {-2.588191, 9.659258, 1.000000}, + {0.000000, 10.000000, 1.000000}, + {2.588191, 9.659258, 1.000000}, + {5.000000, 8.660254, 1.000000}, + {7.071068, 7.071068, 1.000000}, + {8.660254, 5.000000, 1.000000}, + {9.659258, 2.588191, 1.000000}, + {10.000000, 0.000000, 1.000000}, + }, + +}; + +float ltn[9][25][3] = { + { + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + }, + + { + {0.707107, 0.000000, 0.707107}, + {0.683013, -0.183013, 0.707107}, + {0.612372, -0.353553, 0.707107}, + {0.500000, -0.500000, 0.707107}, + {0.353553, -0.612372, 0.707107}, + {0.183013, -0.683013, 0.707107}, + {0.000000, -0.707107, 0.707107}, + {-0.183013, -0.683013, 0.707107}, + {-0.353553, -0.612372, 0.707107}, + {-0.500000, -0.500000, 0.707107}, + {-0.612372, -0.353553, 0.707107}, + {-0.683013, -0.183013, 0.707107}, + {-0.707107, 0.000000, 0.707107}, + {-0.683013, 0.183013, 0.707107}, + {-0.612372, 0.353553, 0.707107}, + {-0.500000, 0.500000, 0.707107}, + {-0.353553, 0.612372, 0.707107}, + {-0.183013, 0.683013, 0.707107}, + {0.000000, 0.707107, 0.707107}, + {0.183013, 0.683013, 0.707107}, + {0.353553, 0.612372, 0.707107}, + {0.500000, 0.500000, 0.707107}, + {0.612372, 0.353553, 0.707107}, + {0.683013, 0.183013, 0.707107}, + {0.707107, 0.000000, 0.707107}, + }, + + { + {1.000000, 0.000000, 0.000000}, + {0.965926, -0.258819, 0.000000}, + {0.866025, -0.500000, 0.000000}, + {0.707107, -0.707107, 0.000000}, + {0.500000, -0.866025, 0.000000}, + {0.258819, -0.965926, 0.000000}, + {0.000000, -1.000000, 0.000000}, + {-0.258819, -0.965926, 0.000000}, + {-0.500000, -0.866025, 0.000000}, + {-0.707107, -0.707107, 0.000000}, + {-0.866025, -0.500000, 0.000000}, + {-0.965926, -0.258819, 0.000000}, + {-1.000000, 0.000000, 0.000000}, + {-0.965926, 0.258819, 0.000000}, + {-0.866025, 0.500000, 0.000000}, + {-0.707107, 0.707107, 0.000000}, + {-0.500000, 0.866025, 0.000000}, + {-0.258819, 0.965926, 0.000000}, + {0.000000, 1.000000, 0.000000}, + {0.258819, 0.965926, 0.000000}, + {0.500000, 0.866025, 0.000000}, + {0.707107, 0.707107, 0.000000}, + {0.866025, 0.500000, 0.000000}, + {0.965926, 0.258819, 0.000000}, + {1.000000, 0.000000, 0.000000}, + }, + + { + {0.707107, 0.000000, -0.707107}, + {0.683013, -0.183013, -0.707107}, + {0.612372, -0.353553, -0.707107}, + {0.500000, -0.500000, -0.707107}, + {0.353553, -0.612372, -0.707107}, + {0.183013, -0.683013, -0.707107}, + {0.000000, -0.707107, -0.707107}, + {-0.183013, -0.683013, -0.707107}, + {-0.353553, -0.612372, -0.707107}, + {-0.500000, -0.500000, -0.707107}, + {-0.612372, -0.353553, -0.707107}, + {-0.683013, -0.183013, -0.707107}, + {-0.707107, 0.000000, -0.707107}, + {-0.683013, 0.183013, -0.707107}, + {-0.612372, 0.353553, -0.707107}, + {-0.500000, 0.500000, -0.707107}, + {-0.353553, 0.612372, -0.707107}, + {-0.183013, 0.683013, -0.707107}, + {0.000000, 0.707107, -0.707107}, + {0.183013, 0.683013, -0.707107}, + {0.353553, 0.612372, -0.707107}, + {0.500000, 0.500000, -0.707107}, + {0.612372, 0.353553, -0.707107}, + {0.683013, 0.183013, -0.707107}, + {0.707107, 0.000000, -0.707107}, + }, + + { + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + {0.000000, 0.000000, -1.000000}, + }, + + { + {-0.707107, 0.000000, -0.707107}, + {-0.683013, 0.183013, -0.707107}, + {-0.612372, 0.353553, -0.707107}, + {-0.500000, 0.500000, -0.707107}, + {-0.353553, 0.612372, -0.707107}, + {-0.183013, 0.683013, -0.707107}, + {0.000000, 0.707107, -0.707107}, + {0.183013, 0.683013, -0.707107}, + {0.353553, 0.612372, -0.707107}, + {0.500000, 0.500000, -0.707107}, + {0.612372, 0.353553, -0.707107}, + {0.683013, 0.183013, -0.707107}, + {0.707107, 0.000000, -0.707107}, + {0.683013, -0.183013, -0.707107}, + {0.612372, -0.353553, -0.707107}, + {0.500000, -0.500000, -0.707107}, + {0.353553, -0.612372, -0.707107}, + {0.183013, -0.683013, -0.707107}, + {0.000000, -0.707107, -0.707107}, + {-0.183013, -0.683013, -0.707107}, + {-0.353553, -0.612372, -0.707107}, + {-0.500000, -0.500000, -0.707107}, + {-0.612372, -0.353553, -0.707107}, + {-0.683013, -0.183013, -0.707107}, + {-0.707107, 0.000000, -0.707107}, + }, + + { + {-1.000000, 0.000000, 0.000000}, + {-0.965926, 0.258819, 0.000000}, + {-0.866025, 0.500000, 0.000000}, + {-0.707107, 0.707107, 0.000000}, + {-0.500000, 0.866025, 0.000000}, + {-0.258819, 0.965926, 0.000000}, + {0.000000, 1.000000, 0.000000}, + {0.258819, 0.965926, 0.000000}, + {0.500000, 0.866025, 0.000000}, + {0.707107, 0.707107, 0.000000}, + {0.866025, 0.500000, 0.000000}, + {0.965926, 0.258819, 0.000000}, + {1.000000, 0.000000, 0.000000}, + {0.965926, -0.258819, 0.000000}, + {0.866025, -0.500000, 0.000000}, + {0.707107, -0.707107, 0.000000}, + {0.500000, -0.866025, 0.000000}, + {0.258819, -0.965926, 0.000000}, + {0.000000, -1.000000, 0.000000}, + {-0.258819, -0.965926, 0.000000}, + {-0.500000, -0.866025, 0.000000}, + {-0.707107, -0.707107, 0.000000}, + {-0.866025, -0.500000, 0.000000}, + {-0.965926, -0.258819, 0.000000}, + {-1.000000, 0.000000, 0.000000}, + }, + + { + {-0.707107, 0.000000, 0.707107}, + {-0.683013, 0.183013, 0.707107}, + {-0.612372, 0.353553, 0.707107}, + {-0.500000, 0.500000, 0.707107}, + {-0.353553, 0.612372, 0.707107}, + {-0.183013, 0.683013, 0.707107}, + {0.000000, 0.707107, 0.707107}, + {0.183013, 0.683013, 0.707107}, + {0.353553, 0.612372, 0.707107}, + {0.500000, 0.500000, 0.707107}, + {0.612372, 0.353553, 0.707107}, + {0.683013, 0.183013, 0.707107}, + {0.707107, 0.000000, 0.707107}, + {0.683013, -0.183013, 0.707107}, + {0.612372, -0.353553, 0.707107}, + {0.500000, -0.500000, 0.707107}, + {0.353553, -0.612372, 0.707107}, + {0.183013, -0.683013, 0.707107}, + {0.000000, -0.707107, 0.707107}, + {-0.183013, -0.683013, 0.707107}, + {-0.353553, -0.612372, 0.707107}, + {-0.500000, -0.500000, 0.707107}, + {-0.612372, -0.353553, 0.707107}, + {-0.683013, -0.183013, 0.707107}, + {-0.707107, 0.000000, 0.707107}, + }, + + { + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + {0.000000, 0.000000, 1.000000}, + }, + +}; + +void draw_hemisphere(void) { + + glCallList(MAT_HEMISPHERE); + glEnable(GL_LIGHTING); + + /* CF damn! */ + /* glEnable(GL_NORMALIZE); */ + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(hp[0][0]); glVertex3fv(hp[0][0]); + glNormal3fv(hp[1][0]); glVertex3fv(hp[1][0]); + glNormal3fv(hp[0][1]); glVertex3fv(hp[0][1]); + glNormal3fv(hp[1][1]); glVertex3fv(hp[1][1]); + glNormal3fv(hp[0][2]); glVertex3fv(hp[0][2]); + glNormal3fv(hp[1][2]); glVertex3fv(hp[1][2]); + glNormal3fv(hp[0][3]); glVertex3fv(hp[0][3]); + glNormal3fv(hp[1][3]); glVertex3fv(hp[1][3]); + glNormal3fv(hp[0][4]); glVertex3fv(hp[0][4]); + glNormal3fv(hp[1][4]); glVertex3fv(hp[1][4]); + glNormal3fv(hp[0][5]); glVertex3fv(hp[0][5]); + glNormal3fv(hp[1][5]); glVertex3fv(hp[1][5]); + glNormal3fv(hp[0][6]); glVertex3fv(hp[0][6]); + glNormal3fv(hp[1][6]); glVertex3fv(hp[1][6]); + glNormal3fv(hp[0][7]); glVertex3fv(hp[0][7]); + glNormal3fv(hp[1][7]); glVertex3fv(hp[1][7]); + glNormal3fv(hp[0][8]); glVertex3fv(hp[0][8]); + glNormal3fv(hp[1][8]); glVertex3fv(hp[1][8]); + glNormal3fv(hp[0][9]); glVertex3fv(hp[0][9]); + glNormal3fv(hp[1][9]); glVertex3fv(hp[1][9]); + glNormal3fv(hp[0][10]); glVertex3fv(hp[0][10]); + glNormal3fv(hp[1][10]); glVertex3fv(hp[1][10]); + glNormal3fv(hp[0][11]); glVertex3fv(hp[0][11]); + glNormal3fv(hp[1][11]); glVertex3fv(hp[1][11]); + glNormal3fv(hp[0][12]); glVertex3fv(hp[0][12]); + glNormal3fv(hp[1][12]); glVertex3fv(hp[1][12]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(hp[1][0]); glVertex3fv(hp[1][0]); + glNormal3fv(hp[2][0]); glVertex3fv(hp[2][0]); + glNormal3fv(hp[1][1]); glVertex3fv(hp[1][1]); + glNormal3fv(hp[2][1]); glVertex3fv(hp[2][1]); + glNormal3fv(hp[1][2]); glVertex3fv(hp[1][2]); + glNormal3fv(hp[2][2]); glVertex3fv(hp[2][2]); + glNormal3fv(hp[1][3]); glVertex3fv(hp[1][3]); + glNormal3fv(hp[2][3]); glVertex3fv(hp[2][3]); + glNormal3fv(hp[1][4]); glVertex3fv(hp[1][4]); + glNormal3fv(hp[2][4]); glVertex3fv(hp[2][4]); + glNormal3fv(hp[1][5]); glVertex3fv(hp[1][5]); + glNormal3fv(hp[2][5]); glVertex3fv(hp[2][5]); + glNormal3fv(hp[1][6]); glVertex3fv(hp[1][6]); + glNormal3fv(hp[2][6]); glVertex3fv(hp[2][6]); + glNormal3fv(hp[1][7]); glVertex3fv(hp[1][7]); + glNormal3fv(hp[2][7]); glVertex3fv(hp[2][7]); + glNormal3fv(hp[1][8]); glVertex3fv(hp[1][8]); + glNormal3fv(hp[2][8]); glVertex3fv(hp[2][8]); + glNormal3fv(hp[1][9]); glVertex3fv(hp[1][9]); + glNormal3fv(hp[2][9]); glVertex3fv(hp[2][9]); + glNormal3fv(hp[1][10]); glVertex3fv(hp[1][10]); + glNormal3fv(hp[2][10]); glVertex3fv(hp[2][10]); + glNormal3fv(hp[1][11]); glVertex3fv(hp[1][11]); + glNormal3fv(hp[2][11]); glVertex3fv(hp[2][11]); + glNormal3fv(hp[1][12]); glVertex3fv(hp[1][12]); + glNormal3fv(hp[2][12]); glVertex3fv(hp[2][12]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(hp[2][0]); glVertex3fv(hp[2][0]); + glNormal3fv(hp[3][0]); glVertex3fv(hp[3][0]); + glNormal3fv(hp[2][1]); glVertex3fv(hp[2][1]); + glNormal3fv(hp[3][1]); glVertex3fv(hp[3][1]); + glNormal3fv(hp[2][2]); glVertex3fv(hp[2][2]); + glNormal3fv(hp[3][2]); glVertex3fv(hp[3][2]); + glNormal3fv(hp[2][3]); glVertex3fv(hp[2][3]); + glNormal3fv(hp[3][3]); glVertex3fv(hp[3][3]); + glNormal3fv(hp[2][4]); glVertex3fv(hp[2][4]); + glNormal3fv(hp[3][4]); glVertex3fv(hp[3][4]); + glNormal3fv(hp[2][5]); glVertex3fv(hp[2][5]); + glNormal3fv(hp[3][5]); glVertex3fv(hp[3][5]); + glNormal3fv(hp[2][6]); glVertex3fv(hp[2][6]); + glNormal3fv(hp[3][6]); glVertex3fv(hp[3][6]); + glNormal3fv(hp[2][7]); glVertex3fv(hp[2][7]); + glNormal3fv(hp[3][7]); glVertex3fv(hp[3][7]); + glNormal3fv(hp[2][8]); glVertex3fv(hp[2][8]); + glNormal3fv(hp[3][8]); glVertex3fv(hp[3][8]); + glNormal3fv(hp[2][9]); glVertex3fv(hp[2][9]); + glNormal3fv(hp[3][9]); glVertex3fv(hp[3][9]); + glNormal3fv(hp[2][10]); glVertex3fv(hp[2][10]); + glNormal3fv(hp[3][10]); glVertex3fv(hp[3][10]); + glNormal3fv(hp[2][11]); glVertex3fv(hp[2][11]); + glNormal3fv(hp[3][11]); glVertex3fv(hp[3][11]); + glNormal3fv(hp[2][12]); glVertex3fv(hp[2][12]); + glNormal3fv(hp[3][12]); glVertex3fv(hp[3][12]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(hp[3][0]); glVertex3fv(hp[3][0]); + glNormal3fv(hp[4][0]); glVertex3fv(hp[4][0]); + glNormal3fv(hp[3][1]); glVertex3fv(hp[3][1]); + glNormal3fv(hp[4][1]); glVertex3fv(hp[4][1]); + glNormal3fv(hp[3][2]); glVertex3fv(hp[3][2]); + glNormal3fv(hp[4][2]); glVertex3fv(hp[4][2]); + glNormal3fv(hp[3][3]); glVertex3fv(hp[3][3]); + glNormal3fv(hp[4][3]); glVertex3fv(hp[4][3]); + glNormal3fv(hp[3][4]); glVertex3fv(hp[3][4]); + glNormal3fv(hp[4][4]); glVertex3fv(hp[4][4]); + glNormal3fv(hp[3][5]); glVertex3fv(hp[3][5]); + glNormal3fv(hp[4][5]); glVertex3fv(hp[4][5]); + glNormal3fv(hp[3][6]); glVertex3fv(hp[3][6]); + glNormal3fv(hp[4][6]); glVertex3fv(hp[4][6]); + glNormal3fv(hp[3][7]); glVertex3fv(hp[3][7]); + glNormal3fv(hp[4][7]); glVertex3fv(hp[4][7]); + glNormal3fv(hp[3][8]); glVertex3fv(hp[3][8]); + glNormal3fv(hp[4][8]); glVertex3fv(hp[4][8]); + glNormal3fv(hp[3][9]); glVertex3fv(hp[3][9]); + glNormal3fv(hp[4][9]); glVertex3fv(hp[4][9]); + glNormal3fv(hp[3][10]); glVertex3fv(hp[3][10]); + glNormal3fv(hp[4][10]); glVertex3fv(hp[4][10]); + glNormal3fv(hp[3][11]); glVertex3fv(hp[3][11]); + glNormal3fv(hp[4][11]); glVertex3fv(hp[4][11]); + glNormal3fv(hp[3][12]); glVertex3fv(hp[3][12]); + glNormal3fv(hp[4][12]); glVertex3fv(hp[4][12]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(hp[4][0]); glVertex3fv(hp[4][0]); + glNormal3fv(hp[5][0]); glVertex3fv(hp[5][0]); + glNormal3fv(hp[4][1]); glVertex3fv(hp[4][1]); + glNormal3fv(hp[5][1]); glVertex3fv(hp[5][1]); + glNormal3fv(hp[4][2]); glVertex3fv(hp[4][2]); + glNormal3fv(hp[5][2]); glVertex3fv(hp[5][2]); + glNormal3fv(hp[4][3]); glVertex3fv(hp[4][3]); + glNormal3fv(hp[5][3]); glVertex3fv(hp[5][3]); + glNormal3fv(hp[4][4]); glVertex3fv(hp[4][4]); + glNormal3fv(hp[5][4]); glVertex3fv(hp[5][4]); + glNormal3fv(hp[4][5]); glVertex3fv(hp[4][5]); + glNormal3fv(hp[5][5]); glVertex3fv(hp[5][5]); + glNormal3fv(hp[4][6]); glVertex3fv(hp[4][6]); + glNormal3fv(hp[5][6]); glVertex3fv(hp[5][6]); + glNormal3fv(hp[4][7]); glVertex3fv(hp[4][7]); + glNormal3fv(hp[5][7]); glVertex3fv(hp[5][7]); + glNormal3fv(hp[4][8]); glVertex3fv(hp[4][8]); + glNormal3fv(hp[5][8]); glVertex3fv(hp[5][8]); + glNormal3fv(hp[4][9]); glVertex3fv(hp[4][9]); + glNormal3fv(hp[5][9]); glVertex3fv(hp[5][9]); + glNormal3fv(hp[4][10]); glVertex3fv(hp[4][10]); + glNormal3fv(hp[5][10]); glVertex3fv(hp[5][10]); + glNormal3fv(hp[4][11]); glVertex3fv(hp[4][11]); + glNormal3fv(hp[5][11]); glVertex3fv(hp[5][11]); + glNormal3fv(hp[4][12]); glVertex3fv(hp[4][12]); + glNormal3fv(hp[5][12]); glVertex3fv(hp[5][12]); + glEnd(); + + glDisable(GL_LIGHTING); + glColor3ub(255, 255, 255); + glBegin(GL_POLYGON); + glVertex3fv(hp[5][0]); + glVertex3fv(hp[5][1]); + glVertex3fv(hp[5][2]); + glVertex3fv(hp[5][3]); + glVertex3fv(hp[5][4]); + glVertex3fv(hp[5][5]); + glVertex3fv(hp[5][6]); + glVertex3fv(hp[5][7]); + glVertex3fv(hp[5][8]); + glVertex3fv(hp[5][9]); + glVertex3fv(hp[5][10]); + glVertex3fv(hp[5][11]); + glEnd(); + + /* CF damn! */ + /* glDisable(GL_NORMALIZE); */ + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/draw_logo.c b/lib/glut-3.7.6/progs/demos/ideas/draw_logo.c new file mode 100644 index 0000000000..6bf90fec25 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/draw_logo.c @@ -0,0 +1,524 @@ +/* + * (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. + */ +#include + +#include "objects.h" + +static 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 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}, +}; + +static 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}, + }, + +}; + +static 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}, + {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}, + }, + +}; + +static void draw_single_cylinder(void) { + + 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(); +} + +static void draw_double_cylinder(void) { + + glEnable(GL_NORMALIZE); + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(dcp[0]); glVertex3fv(dcp[0]); + glNormal3fv(dcp[0]); + glVertex3fv(dcp[1]); + glNormal3fv(dcp[2]); glVertex3fv(dcp[2]); + glNormal3fv(dcp[2]); + glVertex3fv(dcp[3]); + glNormal3fv(dcp[4]); glVertex3fv(dcp[4]); + glNormal3fv(dcp[4]); + glVertex3fv(dcp[5]); + glNormal3fv(dcp[6]); glVertex3fv(dcp[6]); + glNormal3fv(dcp[6]); + glVertex3fv(dcp[7]); + glNormal3fv(dcp[8]); glVertex3fv(dcp[8]); + glNormal3fv(dcp[8]); + glVertex3fv(dcp[9]); + glNormal3fv(dcp[10]); glVertex3fv(dcp[10]); + glNormal3fv(dcp[10]); + glVertex3fv(dcp[11]); + glNormal3fv(dcp[12]); glVertex3fv(dcp[12]); + glNormal3fv(dcp[12]); + glVertex3fv(dcp[13]); + glNormal3fv(dcp[14]); glVertex3fv(dcp[14]); + glNormal3fv(dcp[14]); + glVertex3fv(dcp[15]); + glNormal3fv(dcp[16]); glVertex3fv(dcp[16]); + glNormal3fv(dcp[16]); + glVertex3fv(dcp[17]); + glEnd(); +} + +static void draw_elbow(void) { + + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[0][0]); glVertex3fv(ep[0][0]); + glNormal3fv(en[1][0]); glVertex3fv(ep[1][0]); + glNormal3fv(en[0][1]); glVertex3fv(ep[0][1]); + glNormal3fv(en[1][1]); glVertex3fv(ep[1][1]); + glNormal3fv(en[0][2]); glVertex3fv(ep[0][2]); + glNormal3fv(en[1][2]); glVertex3fv(ep[1][2]); + glNormal3fv(en[0][3]); glVertex3fv(ep[0][3]); + glNormal3fv(en[1][3]); glVertex3fv(ep[1][3]); + glNormal3fv(en[0][4]); glVertex3fv(ep[0][4]); + glNormal3fv(en[1][4]); glVertex3fv(ep[1][4]); + glNormal3fv(en[0][5]); glVertex3fv(ep[0][5]); + glNormal3fv(en[1][5]); glVertex3fv(ep[1][5]); + glNormal3fv(en[0][6]); glVertex3fv(ep[0][6]); + glNormal3fv(en[1][6]); glVertex3fv(ep[1][6]); + glNormal3fv(en[0][7]); glVertex3fv(ep[0][7]); + glNormal3fv(en[1][7]); glVertex3fv(ep[1][7]); + glNormal3fv(en[0][8]); glVertex3fv(ep[0][8]); + glNormal3fv(en[1][8]); glVertex3fv(ep[1][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[1][0]); glVertex3fv(ep[1][0]); + glNormal3fv(en[2][0]); glVertex3fv(ep[2][0]); + glNormal3fv(en[1][1]); glVertex3fv(ep[1][1]); + glNormal3fv(en[2][1]); glVertex3fv(ep[2][1]); + glNormal3fv(en[1][2]); glVertex3fv(ep[1][2]); + glNormal3fv(en[2][2]); glVertex3fv(ep[2][2]); + glNormal3fv(en[1][3]); glVertex3fv(ep[1][3]); + glNormal3fv(en[2][3]); glVertex3fv(ep[2][3]); + glNormal3fv(en[1][4]); glVertex3fv(ep[1][4]); + glNormal3fv(en[2][4]); glVertex3fv(ep[2][4]); + glNormal3fv(en[1][5]); glVertex3fv(ep[1][5]); + glNormal3fv(en[2][5]); glVertex3fv(ep[2][5]); + glNormal3fv(en[1][6]); glVertex3fv(ep[1][6]); + glNormal3fv(en[2][6]); glVertex3fv(ep[2][6]); + glNormal3fv(en[1][7]); glVertex3fv(ep[1][7]); + glNormal3fv(en[2][7]); glVertex3fv(ep[2][7]); + glNormal3fv(en[1][8]); glVertex3fv(ep[1][8]); + glNormal3fv(en[2][8]); glVertex3fv(ep[2][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[2][0]); glVertex3fv(ep[2][0]); + glNormal3fv(en[3][0]); glVertex3fv(ep[3][0]); + glNormal3fv(en[2][1]); glVertex3fv(ep[2][1]); + glNormal3fv(en[3][1]); glVertex3fv(ep[3][1]); + glNormal3fv(en[2][2]); glVertex3fv(ep[2][2]); + glNormal3fv(en[3][2]); glVertex3fv(ep[3][2]); + glNormal3fv(en[2][3]); glVertex3fv(ep[2][3]); + glNormal3fv(en[3][3]); glVertex3fv(ep[3][3]); + glNormal3fv(en[2][4]); glVertex3fv(ep[2][4]); + glNormal3fv(en[3][4]); glVertex3fv(ep[3][4]); + glNormal3fv(en[2][5]); glVertex3fv(ep[2][5]); + glNormal3fv(en[3][5]); glVertex3fv(ep[3][5]); + glNormal3fv(en[2][6]); glVertex3fv(ep[2][6]); + glNormal3fv(en[3][6]); glVertex3fv(ep[3][6]); + glNormal3fv(en[2][7]); glVertex3fv(ep[2][7]); + glNormal3fv(en[3][7]); glVertex3fv(ep[3][7]); + glNormal3fv(en[2][8]); glVertex3fv(ep[2][8]); + glNormal3fv(en[3][8]); glVertex3fv(ep[3][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[3][0]); glVertex3fv(ep[3][0]); + glNormal3fv(en[4][0]); glVertex3fv(ep[4][0]); + glNormal3fv(en[3][1]); glVertex3fv(ep[3][1]); + glNormal3fv(en[4][1]); glVertex3fv(ep[4][1]); + glNormal3fv(en[3][2]); glVertex3fv(ep[3][2]); + glNormal3fv(en[4][2]); glVertex3fv(ep[4][2]); + glNormal3fv(en[3][3]); glVertex3fv(ep[3][3]); + glNormal3fv(en[4][3]); glVertex3fv(ep[4][3]); + glNormal3fv(en[3][4]); glVertex3fv(ep[3][4]); + glNormal3fv(en[4][4]); glVertex3fv(ep[4][4]); + glNormal3fv(en[3][5]); glVertex3fv(ep[3][5]); + glNormal3fv(en[4][5]); glVertex3fv(ep[4][5]); + glNormal3fv(en[3][6]); glVertex3fv(ep[3][6]); + glNormal3fv(en[4][6]); glVertex3fv(ep[4][6]); + glNormal3fv(en[3][7]); glVertex3fv(ep[3][7]); + glNormal3fv(en[4][7]); glVertex3fv(ep[4][7]); + glNormal3fv(en[3][8]); glVertex3fv(ep[3][8]); + glNormal3fv(en[4][8]); glVertex3fv(ep[4][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[4][0]); glVertex3fv(ep[4][0]); + glNormal3fv(en[5][0]); glVertex3fv(ep[5][0]); + glNormal3fv(en[4][1]); glVertex3fv(ep[4][1]); + glNormal3fv(en[5][1]); glVertex3fv(ep[5][1]); + glNormal3fv(en[4][2]); glVertex3fv(ep[4][2]); + glNormal3fv(en[5][2]); glVertex3fv(ep[5][2]); + glNormal3fv(en[4][3]); glVertex3fv(ep[4][3]); + glNormal3fv(en[5][3]); glVertex3fv(ep[5][3]); + glNormal3fv(en[4][4]); glVertex3fv(ep[4][4]); + glNormal3fv(en[5][4]); glVertex3fv(ep[5][4]); + glNormal3fv(en[4][5]); glVertex3fv(ep[4][5]); + glNormal3fv(en[5][5]); glVertex3fv(ep[5][5]); + glNormal3fv(en[4][6]); glVertex3fv(ep[4][6]); + glNormal3fv(en[5][6]); glVertex3fv(ep[5][6]); + glNormal3fv(en[4][7]); glVertex3fv(ep[4][7]); + glNormal3fv(en[5][7]); glVertex3fv(ep[5][7]); + glNormal3fv(en[4][8]); glVertex3fv(ep[4][8]); + glNormal3fv(en[5][8]); glVertex3fv(ep[5][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glNormal3fv(en[5][0]); glVertex3fv(ep[5][0]); + glNormal3fv(en[6][0]); glVertex3fv(ep[6][0]); + glNormal3fv(en[5][1]); glVertex3fv(ep[5][1]); + glNormal3fv(en[6][1]); glVertex3fv(ep[6][1]); + glNormal3fv(en[5][2]); glVertex3fv(ep[5][2]); + glNormal3fv(en[6][2]); glVertex3fv(ep[6][2]); + glNormal3fv(en[5][3]); glVertex3fv(ep[5][3]); + glNormal3fv(en[6][3]); glVertex3fv(ep[6][3]); + glNormal3fv(en[5][4]); glVertex3fv(ep[5][4]); + glNormal3fv(en[6][4]); glVertex3fv(ep[6][4]); + glNormal3fv(en[5][5]); glVertex3fv(ep[5][5]); + glNormal3fv(en[6][5]); glVertex3fv(ep[6][5]); + glNormal3fv(en[5][6]); glVertex3fv(ep[5][6]); + glNormal3fv(en[6][6]); glVertex3fv(ep[6][6]); + glNormal3fv(en[5][7]); glVertex3fv(ep[5][7]); + glNormal3fv(en[6][7]); glVertex3fv(ep[6][7]); + glNormal3fv(en[5][8]); glVertex3fv(ep[5][8]); + glNormal3fv(en[6][8]); glVertex3fv(ep[6][8]); + glEnd(); +} + +static void bend_forward(void) { + + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +static void bend_left(void) { + glRotatef (0.1 * (-900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +static void bend_right(void) { + glRotatef (0.1 * (900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +void draw_logo(void) { + + glCallList( MAT_LOGO); + + glTranslatef(5.500000, -3.500000, 4.500000); + + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + + glDisable(GL_NORMALIZE); +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/draw_logo_line.c b/lib/glut-3.7.6/progs/demos/ideas/draw_logo_line.c new file mode 100644 index 0000000000..906a21733a --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/draw_logo_line.c @@ -0,0 +1,378 @@ +/* + * (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. + */ +#include + +#include "objects.h" + +float scp[14][3] = { + {1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 5.000000}, + {0.500000, 0.866025, 0.000000}, {0.500000, 0.866025, 5.000000}, + {-0.500000, 0.866025, 0.000000}, {-0.500000, 0.866025, 5.000000}, + {-1.000000, 0.000000, 0.000000}, {-1.000000, 0.000000, 5.000000}, + {-0.500000, -0.866025, 0.000000}, {-0.500000, -0.866025, 5.000000}, + {0.500000, -0.866025, 0.000000}, {0.500000, -0.866025, 5.000000}, + {1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 5.000000}, +}; + +float dcp[14][3] = { + {1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 7.000000}, + {0.500000, 0.866025, 0.000000}, {0.500000, 0.866025, 7.000000}, + {-0.500000, 0.866025, 0.000000}, {-0.500000, 0.866025, 7.000000}, + {-1.000000, 0.000000, 0.000000}, {-1.000000, 0.000000, 7.000000}, + {-0.500000, -0.866025, 0.000000}, {-0.500000, -0.866025, 7.000000}, + {0.500000, -0.866025, 0.000000}, {0.500000, -0.866025, 7.000000}, + {1.000000, 0.000000, 0.000000}, {1.000000, 0.000000, 7.000000}, +}; + +float ep[7][7][3] = { + { + {1.000000, 0.000000, 0.000000}, + {0.500000, 0.866025, 0.000000}, + {-0.500000, 0.866025, 0.000000}, + {-1.000000, 0.000000, 0.000000}, + {-0.500000, -0.866025, 0.000000}, + {0.500000, -0.866025, 0.000000}, + {1.000000, 0.000000, 0.000000}, + }, + + { + {1.000000, 0.034074, 0.258819}, + {0.500000, 0.870590, 0.034675}, + {-0.500000, 0.870590, 0.034675}, + {-1.000000, 0.034074, 0.258819}, + {-0.500000, -0.802442, 0.482963}, + {0.500000, -0.802442, 0.482963}, + {1.000000, 0.034074, 0.258819}, + }, + + { + {1.000000, 0.133975, 0.500000}, + {0.500000, 0.883975, 0.066987}, + {-0.500000, 0.883975, 0.066987}, + {-1.000000, 0.133975, 0.500000}, + {-0.500000, -0.616025, 0.933013}, + {0.500000, -0.616025, 0.933013}, + {1.000000, 0.133975, 0.500000}, + }, + + { + {1.000000, 0.292893, 0.707107}, + {0.500000, 0.905266, 0.094734}, + {-0.500000, 0.905266, 0.094734}, + {-1.000000, 0.292893, 0.707107}, + {-0.500000, -0.319479, 1.319479}, + {0.500000, -0.319479, 1.319479}, + {1.000000, 0.292893, 0.707107}, + }, + + { + {1.000000, 0.500000, 0.866025}, + {0.500000, 0.933013, 0.116025}, + {-0.500000, 0.933013, 0.116025}, + {-1.000000, 0.500000, 0.866025}, + {-0.500000, 0.066987, 1.616025}, + {0.500000, 0.066987, 1.616025}, + {1.000000, 0.500000, 0.866025}, + }, + + { + {1.000000, 0.741181, 0.965926}, + {0.500000, 0.965325, 0.129410}, + {-0.500000, 0.965325, 0.129410}, + {-1.000000, 0.741181, 0.965926}, + {-0.500000, 0.517037, 1.802442}, + {0.500000, 0.517037, 1.802442}, + {1.000000, 0.741181, 0.965926}, + }, + + { + {1.000000, 1.000000, 1.000000}, + {0.500000, 1.000000, 0.133975}, + {-0.500000, 1.000000, 0.133975}, + {-1.000000, 1.000000, 1.000000}, + {-0.500000, 1.000000, 1.866025}, + {0.500000, 1.000000, 1.866025}, + {1.000000, 1.000000, 1.000000}, + }, + +}; + +void draw_single_cylinder(void) { + + glBegin(GL_LINE_STRIP); +glVertex3fv(scp[0]); +glVertex3fv(scp[1]); +glVertex3fv(scp[2]); +glVertex3fv(scp[3]); +glVertex3fv(scp[4]); +glVertex3fv(scp[5]); +glVertex3fv(scp[6]); +glVertex3fv(scp[7]); +glVertex3fv(scp[8]); +glVertex3fv(scp[9]); +glVertex3fv(scp[10]); +glVertex3fv(scp[11]); +glVertex3fv(scp[12]); +glVertex3fv(scp[13]); + glEnd(); +} + +void draw_double_cylinder(void) { + + glBegin(GL_LINE_STRIP); +glVertex3fv(dcp[0]); +glVertex3fv(dcp[1]); +glVertex3fv(dcp[2]); +glVertex3fv(dcp[3]); +glVertex3fv(dcp[4]); +glVertex3fv(dcp[5]); +glVertex3fv(dcp[6]); +glVertex3fv(dcp[7]); +glVertex3fv(dcp[8]); +glVertex3fv(dcp[9]); +glVertex3fv(dcp[10]); +glVertex3fv(dcp[11]); +glVertex3fv(dcp[12]); +glVertex3fv(dcp[13]); + glEnd(); +} + +void draw_elbow(void) { + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[0][0]); + glVertex3fv(ep[1][0]); + glVertex3fv(ep[0][1]); + glVertex3fv(ep[1][1]); + glVertex3fv(ep[0][2]); + glVertex3fv(ep[1][2]); + glVertex3fv(ep[0][3]); + glVertex3fv(ep[1][3]); + glVertex3fv(ep[0][4]); + glVertex3fv(ep[1][4]); + glVertex3fv(ep[0][5]); + glVertex3fv(ep[1][5]); + glVertex3fv(ep[0][6]); + glVertex3fv(ep[1][6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[1][0]); + glVertex3fv(ep[2][0]); + glVertex3fv(ep[1][1]); + glVertex3fv(ep[2][1]); + glVertex3fv(ep[1][2]); + glVertex3fv(ep[2][2]); + glVertex3fv(ep[1][3]); + glVertex3fv(ep[2][3]); + glVertex3fv(ep[1][4]); + glVertex3fv(ep[2][4]); + glVertex3fv(ep[1][5]); + glVertex3fv(ep[2][5]); + glVertex3fv(ep[1][6]); + glVertex3fv(ep[2][6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[2][0]); + glVertex3fv(ep[3][0]); + glVertex3fv(ep[2][1]); + glVertex3fv(ep[3][1]); + glVertex3fv(ep[2][2]); + glVertex3fv(ep[3][2]); + glVertex3fv(ep[2][3]); + glVertex3fv(ep[3][3]); + glVertex3fv(ep[2][4]); + glVertex3fv(ep[3][4]); + glVertex3fv(ep[2][5]); + glVertex3fv(ep[3][5]); + glVertex3fv(ep[2][6]); + glVertex3fv(ep[3][6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[3][0]); + glVertex3fv(ep[4][0]); + glVertex3fv(ep[3][1]); + glVertex3fv(ep[4][1]); + glVertex3fv(ep[3][2]); + glVertex3fv(ep[4][2]); + glVertex3fv(ep[3][3]); + glVertex3fv(ep[4][3]); + glVertex3fv(ep[3][4]); + glVertex3fv(ep[4][4]); + glVertex3fv(ep[3][5]); + glVertex3fv(ep[4][5]); + glVertex3fv(ep[3][6]); + glVertex3fv(ep[4][6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[4][0]); + glVertex3fv(ep[5][0]); + glVertex3fv(ep[4][1]); + glVertex3fv(ep[5][1]); + glVertex3fv(ep[4][2]); + glVertex3fv(ep[5][2]); + glVertex3fv(ep[4][3]); + glVertex3fv(ep[5][3]); + glVertex3fv(ep[4][4]); + glVertex3fv(ep[5][4]); + glVertex3fv(ep[4][5]); + glVertex3fv(ep[5][5]); + glVertex3fv(ep[4][6]); + glVertex3fv(ep[5][6]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex3fv(ep[5][0]); + glVertex3fv(ep[6][0]); + glVertex3fv(ep[5][1]); + glVertex3fv(ep[6][1]); + glVertex3fv(ep[5][2]); + glVertex3fv(ep[6][2]); + glVertex3fv(ep[5][3]); + glVertex3fv(ep[6][3]); + glVertex3fv(ep[5][4]); + glVertex3fv(ep[6][4]); + glVertex3fv(ep[5][5]); + glVertex3fv(ep[6][5]); + glVertex3fv(ep[5][6]); + glVertex3fv(ep[6][6]); + glEnd(); +} + +void bend_forward(void) { + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +void bend_left(void) { + glRotatef (0.1 * (-900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +void bend_right(void) { + glRotatef (0.1 * (900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +void draw_logo_line(void) { + + glCallList( MAT_LOGO); + + glTranslatef(5.500000, -3.500000, 4.500000); + + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/draw_logo_shadow.c b/lib/glut-3.7.6/progs/demos/ideas/draw_logo_shadow.c new file mode 100644 index 0000000000..976da3085f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/draw_logo_shadow.c @@ -0,0 +1,488 @@ +/* + * (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. + */ +#include + +#include "objects.h" + +static 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 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}, +}; + +static float ep[9][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.019215, 0.195090}, + {0.707107, 0.712735, 0.057141}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.712735, 0.057141}, + {-1.000000, 0.019215, 0.195090}, + {-0.707107, -0.674305, 0.333040}, + {0.000000, -0.961571, 0.390181}, + {0.707107, -0.674305, 0.333040}, + {1.000000, 0.019215, 0.195090}, + }, + + { + {1.000000, 0.076120, 0.382683}, + {0.707107, 0.729402, 0.112085}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.729402, 0.112085}, + {-1.000000, 0.076120, 0.382683}, + {-0.707107, -0.577161, 0.653282}, + {0.000000, -0.847759, 0.765367}, + {0.707107, -0.577161, 0.653282}, + {1.000000, 0.076120, 0.382683}, + }, + + { + {1.000000, 0.168530, 0.555570}, + {0.707107, 0.756468, 0.162723}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.756468, 0.162723}, + {-1.000000, 0.168530, 0.555570}, + {-0.707107, -0.419407, 0.948418}, + {0.000000, -0.662939, 1.111140}, + {0.707107, -0.419407, 0.948418}, + {1.000000, 0.168530, 0.555570}, + }, + + { + {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.444430, 0.831470}, + {0.707107, 0.837277, 0.243532}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.837277, 0.243532}, + {-1.000000, 0.444430, 0.831470}, + {-0.707107, 0.051582, 1.419407}, + {0.000000, -0.111140, 1.662939}, + {0.707107, 0.051582, 1.419407}, + {1.000000, 0.444430, 0.831470}, + }, + + { + {1.000000, 0.617317, 0.923880}, + {0.707107, 0.887915, 0.270598}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.887915, 0.270598}, + {-1.000000, 0.617317, 0.923880}, + {-0.707107, 0.346719, 1.577161}, + {0.000000, 0.234633, 1.847759}, + {0.707107, 0.346719, 1.577161}, + {1.000000, 0.617317, 0.923880}, + }, + + { + {1.000000, 0.804910, 0.980785}, + {0.707107, 0.942859, 0.287265}, + {0.000000, 1.000000, 0.000000}, + {-0.707107, 0.942859, 0.287265}, + {-1.000000, 0.804910, 0.980785}, + {-0.707107, 0.666960, 1.674305}, + {0.000000, 0.609819, 1.961571}, + {0.707107, 0.666960, 1.674305}, + {1.000000, 0.804910, 0.980785}, + }, + + { + {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}, + }, + +}; + +static void draw_single_cylinder(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(scp[0]); + glVertex3fv(scp[1]); + glVertex3fv(scp[2]); + glVertex3fv(scp[3]); + glVertex3fv(scp[4]); + glVertex3fv(scp[5]); + glVertex3fv(scp[6]); + glVertex3fv(scp[7]); + glVertex3fv(scp[8]); + glVertex3fv(scp[9]); + glVertex3fv(scp[10]); + glVertex3fv(scp[11]); + glVertex3fv(scp[12]); + glVertex3fv(scp[13]); + glVertex3fv(scp[14]); + glVertex3fv(scp[15]); + glVertex3fv(scp[16]); + glVertex3fv(scp[17]); + glEnd(); +} + +static void draw_double_cylinder(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(dcp[0]); + glVertex3fv(dcp[1]); + glVertex3fv(dcp[2]); + glVertex3fv(dcp[3]); + glVertex3fv(dcp[4]); + glVertex3fv(dcp[5]); + glVertex3fv(dcp[6]); + glVertex3fv(dcp[7]); + glVertex3fv(dcp[8]); + glVertex3fv(dcp[9]); + glVertex3fv(dcp[10]); + glVertex3fv(dcp[11]); + glVertex3fv(dcp[12]); + glVertex3fv(dcp[13]); + glVertex3fv(dcp[14]); + glVertex3fv(dcp[15]); + glVertex3fv(dcp[16]); + glVertex3fv(dcp[17]); + glEnd(); +} + +static void draw_elbow(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[0][0]); + glVertex3fv(ep[1][0]); + glVertex3fv(ep[0][1]); + glVertex3fv(ep[1][1]); + glVertex3fv(ep[0][2]); + glVertex3fv(ep[1][2]); + glVertex3fv(ep[0][3]); + glVertex3fv(ep[1][3]); + glVertex3fv(ep[0][4]); + glVertex3fv(ep[1][4]); + glVertex3fv(ep[0][5]); + glVertex3fv(ep[1][5]); + glVertex3fv(ep[0][6]); + glVertex3fv(ep[1][6]); + glVertex3fv(ep[0][7]); + glVertex3fv(ep[1][7]); + glVertex3fv(ep[0][8]); + glVertex3fv(ep[1][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[1][0]); + glVertex3fv(ep[2][0]); + glVertex3fv(ep[1][1]); + glVertex3fv(ep[2][1]); + glVertex3fv(ep[1][2]); + glVertex3fv(ep[2][2]); + glVertex3fv(ep[1][3]); + glVertex3fv(ep[2][3]); + glVertex3fv(ep[1][4]); + glVertex3fv(ep[2][4]); + glVertex3fv(ep[1][5]); + glVertex3fv(ep[2][5]); + glVertex3fv(ep[1][6]); + glVertex3fv(ep[2][6]); + glVertex3fv(ep[1][7]); + glVertex3fv(ep[2][7]); + glVertex3fv(ep[1][8]); + glVertex3fv(ep[2][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[2][0]); + glVertex3fv(ep[3][0]); + glVertex3fv(ep[2][1]); + glVertex3fv(ep[3][1]); + glVertex3fv(ep[2][2]); + glVertex3fv(ep[3][2]); + glVertex3fv(ep[2][3]); + glVertex3fv(ep[3][3]); + glVertex3fv(ep[2][4]); + glVertex3fv(ep[3][4]); + glVertex3fv(ep[2][5]); + glVertex3fv(ep[3][5]); + glVertex3fv(ep[2][6]); + glVertex3fv(ep[3][6]); + glVertex3fv(ep[2][7]); + glVertex3fv(ep[3][7]); + glVertex3fv(ep[2][8]); + glVertex3fv(ep[3][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[3][0]); + glVertex3fv(ep[4][0]); + glVertex3fv(ep[3][1]); + glVertex3fv(ep[4][1]); + glVertex3fv(ep[3][2]); + glVertex3fv(ep[4][2]); + glVertex3fv(ep[3][3]); + glVertex3fv(ep[4][3]); + glVertex3fv(ep[3][4]); + glVertex3fv(ep[4][4]); + glVertex3fv(ep[3][5]); + glVertex3fv(ep[4][5]); + glVertex3fv(ep[3][6]); + glVertex3fv(ep[4][6]); + glVertex3fv(ep[3][7]); + glVertex3fv(ep[4][7]); + glVertex3fv(ep[3][8]); + glVertex3fv(ep[4][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[4][0]); + glVertex3fv(ep[5][0]); + glVertex3fv(ep[4][1]); + glVertex3fv(ep[5][1]); + glVertex3fv(ep[4][2]); + glVertex3fv(ep[5][2]); + glVertex3fv(ep[4][3]); + glVertex3fv(ep[5][3]); + glVertex3fv(ep[4][4]); + glVertex3fv(ep[5][4]); + glVertex3fv(ep[4][5]); + glVertex3fv(ep[5][5]); + glVertex3fv(ep[4][6]); + glVertex3fv(ep[5][6]); + glVertex3fv(ep[4][7]); + glVertex3fv(ep[5][7]); + glVertex3fv(ep[4][8]); + glVertex3fv(ep[5][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[5][0]); + glVertex3fv(ep[6][0]); + glVertex3fv(ep[5][1]); + glVertex3fv(ep[6][1]); + glVertex3fv(ep[5][2]); + glVertex3fv(ep[6][2]); + glVertex3fv(ep[5][3]); + glVertex3fv(ep[6][3]); + glVertex3fv(ep[5][4]); + glVertex3fv(ep[6][4]); + glVertex3fv(ep[5][5]); + glVertex3fv(ep[6][5]); + glVertex3fv(ep[5][6]); + glVertex3fv(ep[6][6]); + glVertex3fv(ep[5][7]); + glVertex3fv(ep[6][7]); + glVertex3fv(ep[5][8]); + glVertex3fv(ep[6][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[6][0]); + glVertex3fv(ep[7][0]); + glVertex3fv(ep[6][1]); + glVertex3fv(ep[7][1]); + glVertex3fv(ep[6][2]); + glVertex3fv(ep[7][2]); + glVertex3fv(ep[6][3]); + glVertex3fv(ep[7][3]); + glVertex3fv(ep[6][4]); + glVertex3fv(ep[7][4]); + glVertex3fv(ep[6][5]); + glVertex3fv(ep[7][5]); + glVertex3fv(ep[6][6]); + glVertex3fv(ep[7][6]); + glVertex3fv(ep[6][7]); + glVertex3fv(ep[7][7]); + glVertex3fv(ep[6][8]); + glVertex3fv(ep[7][8]); + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + glVertex3fv(ep[7][0]); + glVertex3fv(ep[8][0]); + glVertex3fv(ep[7][1]); + glVertex3fv(ep[8][1]); + glVertex3fv(ep[7][2]); + glVertex3fv(ep[8][2]); + glVertex3fv(ep[7][3]); + glVertex3fv(ep[8][3]); + glVertex3fv(ep[7][4]); + glVertex3fv(ep[8][4]); + glVertex3fv(ep[7][5]); + glVertex3fv(ep[8][5]); + glVertex3fv(ep[7][6]); + glVertex3fv(ep[8][6]); + glVertex3fv(ep[7][7]); + glVertex3fv(ep[8][7]); + glVertex3fv(ep[7][8]); + glVertex3fv(ep[8][8]); + glEnd(); +} + +static void bend_forward(void) { + + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +static void bend_left(void) { + + glRotatef (0.1 * (-900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +static void bend_right(void) { + + glRotatef (0.1 * (900), 0.0, 0.0, 1.0); + glTranslatef(0.0, 1.000000, 0.0); + glRotatef (0.1 * (900), 1.0, 0.0, 0.0); + glTranslatef(0.0, -1.000000, 0.0); +} + +void draw_logo_shadow(void) { + + glTranslatef(5.500000, -3.500000, 4.500000); + + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_right(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -7.000000); + draw_double_cylinder(); + bend_forward(); + draw_elbow(); + glTranslatef(0.0, 0.0, -5.000000); + draw_single_cylinder(); + bend_left(); + draw_elbow(); +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/e.c b/lib/glut-3.7.6/progs/demos/ideas/e.c new file mode 100644 index 0000000000..9f6b667e6f --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/e.c @@ -0,0 +1,151 @@ +/* + * (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. + */ +#include + +float e_data[][2] = { + {1.095436, 6.190871}, + {2.107884, 6.970954}, + {2.556017, 7.020747}, + {3.020747, 7.867220}, + {3.518672, 8.033195}, + {3.269710, 8.531120}, + {4.165975, 8.929461}, + {3.302905, 9.062241}, + {4.331950, 9.626556}, + {3.286307, 9.344398}, + {4.116183, 9.958507}, + {3.004149, 9.510373}, + {3.518672, 9.991701}, + {2.705394, 9.493776}, + {2.091286, 9.311203}, + {2.041494, 9.062241}, + {1.178423, 8.514523}, + {1.443983, 8.165976}, + {0.481328, 7.535270}, + {1.045643, 6.904564}, + {0.149378, 6.091286}, + {1.095436, 5.410789}, + {0.464730, 4.232365}, + {1.377593, 4.497925}, + {1.261411, 3.136930}, + {1.925311, 3.950207}, + {2.240664, 3.037344}, + {2.589212, 3.834025}, + {3.087137, 3.269710}, + {3.236515, 3.867220}, + {3.684647, 3.867220}, + {3.867220, 4.448133}, + {4.398340, 5.128631}, + +}; + +void draw_e(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(e_data[0]); + glVertex2fv(e_data[1]); + glVertex2fv(e_data[2]); + glVertex2fv(e_data[3]); + glVertex2fv(e_data[4]); + glVertex2fv(e_data[5]); + glVertex2fv(e_data[6]); + glVertex2fv(e_data[7]); + glVertex2fv(e_data[8]); + glVertex2fv(e_data[9]); + glVertex2fv(e_data[10]); + glVertex2fv(e_data[11]); + glVertex2fv(e_data[12]); + glVertex2fv(e_data[13]); + glVertex2fv(e_data[14]); + glVertex2fv(e_data[15]); + glVertex2fv(e_data[16]); + glVertex2fv(e_data[17]); + glVertex2fv(e_data[18]); + glVertex2fv(e_data[19]); + glVertex2fv(e_data[20]); + glVertex2fv(e_data[21]); + glVertex2fv(e_data[22]); + glVertex2fv(e_data[23]); + glVertex2fv(e_data[24]); + glVertex2fv(e_data[25]); + glVertex2fv(e_data[26]); + glVertex2fv(e_data[27]); + glVertex2fv(e_data[28]); + glVertex2fv(e_data[29]); + glVertex2fv(e_data[30]); + glVertex2fv(e_data[31]); + glVertex2fv(e_data[32]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(e_data[0]); + glVertex2fv(e_data[2]); + glVertex2fv(e_data[4]); + glVertex2fv(e_data[6]); + glVertex2fv(e_data[8]); + glVertex2fv(e_data[10]); + glVertex2fv(e_data[12]); + glVertex2fv(e_data[14]); + glVertex2fv(e_data[16]); + glVertex2fv(e_data[18]); + glVertex2fv(e_data[20]); + glVertex2fv(e_data[22]); + glVertex2fv(e_data[24]); + glVertex2fv(e_data[26]); + glVertex2fv(e_data[28]); + glVertex2fv(e_data[30]); + glVertex2fv(e_data[32]); + glVertex2fv(e_data[31]); + glVertex2fv(e_data[29]); + glVertex2fv(e_data[27]); + glVertex2fv(e_data[25]); + glVertex2fv(e_data[23]); + glVertex2fv(e_data[21]); + glVertex2fv(e_data[19]); + glVertex2fv(e_data[17]); + glVertex2fv(e_data[15]); + glVertex2fv(e_data[13]); + glVertex2fv(e_data[11]); + glVertex2fv(e_data[9]); + glVertex2fv(e_data[7]); + glVertex2fv(e_data[5]); + glVertex2fv(e_data[3]); + glVertex2fv(e_data[1]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/f.c b/lib/glut-3.7.6/progs/demos/ideas/f.c new file mode 100644 index 0000000000..63bb886eb1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/f.c @@ -0,0 +1,175 @@ +/* + * (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. + */ +#include + +float f_data[][2] = { + {0.157570-3.0, 0.105155-2.0}, + {1.820803-3.0, 0.736082-2.0}, + {2.030896-3.0, 0.525773-2.0}, + {2.731205-3.0, 1.507216-2.0}, + {2.906282-3.0, 1.139175-2.0}, + {3.378991-3.0, 2.611340-2.0}, + {4.009269-3.0, 3.014433-2.0}, + {4.429454-3.0, 5.730928-2.0}, + {5.042224-3.0, 5.783505-2.0}, + {5.269825-3.0, 10.252578-2.0}, + {6.092688-3.0, 10.708247-2.0}, + {5.917611-3.0, 12.758763-2.0}, + {6.915551-3.0, 13.635052-2.0}, + {6.565396-3.0, 14.388659-2.0}, + {7.370752-3.0, 14.686598-2.0}, + {7.003089-3.0, 15.159794-2.0}, + {7.720906-3.0, 15.300000-2.0}, + {7.633368-3.0, 15.668041-2.0}, + {8.403708-3.0, 15.930928-2.0}, + {9.401648-3.0, 16.596907-2.0}, + {9.261586-3.0, 16.211340-2.0}, + {9.874356-3.0, 16.719587-2.0}, + {10.136972-3.0, 16.228867-2.0}, + {10.469619-3.0, 16.789690-2.0}, + {10.854789-3.0, 16.228867-2.0}, + {11.064881-3.0, 16.667011-2.0}, + {11.169928-3.0, 16.369072-2.0}, + + {3.956746-3.0, 10.988660-2.0}, + {5.147271-3.0, 11.479382-2.0}, + {5.654995-3.0, 11.006186-2.0}, + {5.812564-3.0, 11.970103-2.0}, + {6.127703-3.0, 11.023711-2.0}, + {6.495366-3.0, 11.461856-2.0}, + {7.230690-3.0, 11.006186-2.0}, + {7.318229-3.0, 11.321650-2.0}, + {7.983522-3.0, 11.198969-2.0}, + {8.106076-3.0, 11.426805-2.0}, + {8.613800-3.0, 11.584537-2.0}, + +}; + +void draw_f(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(f_data[0]); + glVertex2fv(f_data[1]); + glVertex2fv(f_data[2]); + glVertex2fv(f_data[3]); + glVertex2fv(f_data[4]); + glVertex2fv(f_data[5]); + glVertex2fv(f_data[6]); + glVertex2fv(f_data[7]); + glVertex2fv(f_data[8]); + glVertex2fv(f_data[9]); + glVertex2fv(f_data[10]); + glVertex2fv(f_data[11]); + glVertex2fv(f_data[12]); + glVertex2fv(f_data[13]); + glVertex2fv(f_data[14]); + glVertex2fv(f_data[15]); + glVertex2fv(f_data[16]); + glVertex2fv(f_data[17]); + glVertex2fv(f_data[18]); + glVertex2fv(f_data[19]); + glVertex2fv(f_data[20]); + glVertex2fv(f_data[21]); + glVertex2fv(f_data[22]); + glVertex2fv(f_data[23]); + glVertex2fv(f_data[24]); + glVertex2fv(f_data[25]); + glVertex2fv(f_data[26]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(f_data[27]); + glVertex2fv(f_data[28]); + glVertex2fv(f_data[29]); + glVertex2fv(f_data[30]); + glVertex2fv(f_data[31]); + glVertex2fv(f_data[32]); + glVertex2fv(f_data[33]); + glVertex2fv(f_data[34]); + glVertex2fv(f_data[35]); + glVertex2fv(f_data[36]); + glVertex2fv(f_data[37]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(f_data[0]); + glVertex2fv(f_data[2]); + glVertex2fv(f_data[4]); + glVertex2fv(f_data[6]); + glVertex2fv(f_data[8]); + glVertex2fv(f_data[10]); + glVertex2fv(f_data[12]); + glVertex2fv(f_data[14]); + glVertex2fv(f_data[16]); + glVertex2fv(f_data[18]); + glVertex2fv(f_data[20]); + glVertex2fv(f_data[22]); + glVertex2fv(f_data[24]); + glVertex2fv(f_data[26]); + glVertex2fv(f_data[25]); + glVertex2fv(f_data[23]); + glVertex2fv(f_data[21]); + glVertex2fv(f_data[19]); + glVertex2fv(f_data[17]); + glVertex2fv(f_data[15]); + glVertex2fv(f_data[13]); + glVertex2fv(f_data[11]); + glVertex2fv(f_data[9]); + glVertex2fv(f_data[7]); + glVertex2fv(f_data[5]); + glVertex2fv(f_data[3]); + glVertex2fv(f_data[1]); + glVertex2fv(f_data[0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(f_data[27]); + glVertex2fv(f_data[29]); + glVertex2fv(f_data[31]); + glVertex2fv(f_data[33]); + glVertex2fv(f_data[35]); + glVertex2fv(f_data[37]); + glVertex2fv(f_data[36]); + glVertex2fv(f_data[34]); + glVertex2fv(f_data[32]); + glVertex2fv(f_data[30]); + glVertex2fv(f_data[28]); + glVertex2fv(f_data[27]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/h.c b/lib/glut-3.7.6/progs/demos/ideas/h.c new file mode 100644 index 0000000000..07c20bc98b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/h.c @@ -0,0 +1,187 @@ +/* + * (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. + */ +#include + +float h_data[][2] = { + {1.462963, 17.499485-3.0}, + {3.259259, 17.851700-3.0}, + {2.074074, 17.351185-3.0}, + {3.037037, 17.073120-3.0}, + {2.277778, 17.054583-3.0}, + {2.814815, 15.775489-3.0}, + {2.018518, 14.737384-3.0}, + {2.203704, 12.142121-3.0}, + {1.296296, 10.158600-3.0}, + {1.259259, 7.674562-3.0}, + {0.666667, 6.933059-3.0}, + {0.685185, 5.728116-3.0}, + {0.314815, 5.653965-3.0}, + {0.444444, 5.227601-3.0}, + {0.074074, 5.097837-3.0}, + + {1.611111, 9.824923-3.0}, + {1.333333, 8.527291-3.0}, + {2.240741, 10.937179-3.0}, + {2.500000, 10.992791-3.0}, + {2.888889, 11.771370-3.0}, + {3.314815, 11.845520-3.0}, + {3.462963, 12.253347-3.0}, + {3.740741, 12.067971-3.0}, + {4.500000, 12.846550-3.0}, + {4.148148, 12.030896-3.0}, + {5.185185, 12.883625-3.0}, + {4.296296, 11.771370-3.0}, + {5.351852, 12.420185-3.0}, + {4.333333, 11.196705-3.0}, + {5.129630, 10.955716-3.0}, + {4.129630, 9.583934-3.0}, + {4.203704, 7.192585-3.0}, + {3.518518, 6.414006-3.0}, + {4.129630, 6.469619-3.0}, + {3.537037, 5.765191-3.0}, + {4.296296, 6.061792-3.0}, + {3.851852, 5.171988-3.0}, + {4.722222, 5.802266-3.0}, + {4.277778, 5.060762-3.0}, + {5.314815, 5.894954-3.0}, + {5.148148, 5.431514-3.0}, + {5.777778, 6.098867-3.0}, + +}; + +void draw_h(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(h_data[0]); + glVertex2fv(h_data[1]); + glVertex2fv(h_data[2]); + glVertex2fv(h_data[3]); + glVertex2fv(h_data[4]); + glVertex2fv(h_data[5]); + glVertex2fv(h_data[6]); + glVertex2fv(h_data[7]); + glVertex2fv(h_data[8]); + glVertex2fv(h_data[9]); + glVertex2fv(h_data[10]); + glVertex2fv(h_data[11]); + glVertex2fv(h_data[12]); + glVertex2fv(h_data[13]); + glVertex2fv(h_data[14]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(h_data[15]); + glVertex2fv(h_data[16]); + glVertex2fv(h_data[17]); + glVertex2fv(h_data[18]); + glVertex2fv(h_data[19]); + glVertex2fv(h_data[20]); + glVertex2fv(h_data[21]); + glVertex2fv(h_data[22]); + glVertex2fv(h_data[23]); + glVertex2fv(h_data[24]); + glVertex2fv(h_data[25]); + glVertex2fv(h_data[26]); + glVertex2fv(h_data[27]); + glVertex2fv(h_data[28]); + glVertex2fv(h_data[29]); + glVertex2fv(h_data[30]); + glVertex2fv(h_data[31]); + glVertex2fv(h_data[32]); + glVertex2fv(h_data[33]); + glVertex2fv(h_data[34]); + glVertex2fv(h_data[35]); + glVertex2fv(h_data[36]); + glVertex2fv(h_data[37]); + glVertex2fv(h_data[38]); + glVertex2fv(h_data[39]); + glVertex2fv(h_data[40]); + glVertex2fv(h_data[41]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(h_data[0]); + glVertex2fv(h_data[2]); + glVertex2fv(h_data[4]); + glVertex2fv(h_data[6]); + glVertex2fv(h_data[8]); + glVertex2fv(h_data[10]); + glVertex2fv(h_data[12]); + glVertex2fv(h_data[14]); + glVertex2fv(h_data[13]); + glVertex2fv(h_data[11]); + glVertex2fv(h_data[9]); + glVertex2fv(h_data[7]); + glVertex2fv(h_data[5]); + glVertex2fv(h_data[3]); + glVertex2fv(h_data[1]); + glVertex2fv(h_data[0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(h_data[15]); + glVertex2fv(h_data[17]); + glVertex2fv(h_data[19]); + glVertex2fv(h_data[21]); + glVertex2fv(h_data[23]); + glVertex2fv(h_data[25]); + glVertex2fv(h_data[27]); + glVertex2fv(h_data[29]); + glVertex2fv(h_data[31]); + glVertex2fv(h_data[33]); + glVertex2fv(h_data[35]); + glVertex2fv(h_data[37]); + glVertex2fv(h_data[39]); + glVertex2fv(h_data[41]); + glVertex2fv(h_data[40]); + glVertex2fv(h_data[38]); + glVertex2fv(h_data[36]); + glVertex2fv(h_data[34]); + glVertex2fv(h_data[32]); + glVertex2fv(h_data[30]); + glVertex2fv(h_data[28]); + glVertex2fv(h_data[26]); + glVertex2fv(h_data[24]); + glVertex2fv(h_data[22]); + glVertex2fv(h_data[20]); + glVertex2fv(h_data[18]); + glVertex2fv(h_data[16]); + glVertex2fv(h_data[15]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/i.c b/lib/glut-3.7.6/progs/demos/ideas/i.c new file mode 100644 index 0000000000..209c2614c7 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/i.c @@ -0,0 +1,132 @@ +/* + * (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. + */ +#include + +float i_data[][2] = { + {0.548767, 9.414791}, + {2.795284, 9.757771}, + {1.457663, 9.311897}, + {2.503751, 9.157557}, + {1.714898, 8.986067}, + {2.109325, 7.785638}, + {1.286174, 7.013934}, + {1.800643, 6.070740}, + {0.994641, 5.161843}, + {1.783494, 4.767417}, + {0.943194, 4.167202}, + {1.852090, 4.304394}, + {1.063237, 3.549839}, + {2.023580, 3.978564}, + {1.406217, 3.172562}, + {2.315113, 3.875670}, + {2.006431, 3.018221}, + {2.812433, 3.944266}, + {2.726688, 3.429796}, + {3.258307, 4.132905}, + + {1.989282, 10.923902}, + {2.778135, 12.295820}, + {2.966774, 11.678456}, + {3.687031, 12.947481}, + +}; + + +void draw_i(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(i_data[0]); + glVertex2fv(i_data[1]); + glVertex2fv(i_data[2]); + glVertex2fv(i_data[3]); + glVertex2fv(i_data[4]); + glVertex2fv(i_data[5]); + glVertex2fv(i_data[6]); + glVertex2fv(i_data[7]); + glVertex2fv(i_data[8]); + glVertex2fv(i_data[9]); + glVertex2fv(i_data[10]); + glVertex2fv(i_data[11]); + glVertex2fv(i_data[12]); + glVertex2fv(i_data[13]); + glVertex2fv(i_data[14]); + glVertex2fv(i_data[15]); + glVertex2fv(i_data[16]); + glVertex2fv(i_data[17]); + glVertex2fv(i_data[18]); + glVertex2fv(i_data[19]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(i_data[20]); + glVertex2fv(i_data[21]); + glVertex2fv(i_data[22]); + glVertex2fv(i_data[23]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(i_data[0]); + glVertex2fv(i_data[2]); + glVertex2fv(i_data[4]); + glVertex2fv(i_data[6]); + glVertex2fv(i_data[8]); + glVertex2fv(i_data[10]); + glVertex2fv(i_data[12]); + glVertex2fv(i_data[14]); + glVertex2fv(i_data[16]); + glVertex2fv(i_data[18]); + glVertex2fv(i_data[19]); + glVertex2fv(i_data[17]); + glVertex2fv(i_data[15]); + glVertex2fv(i_data[13]); + glVertex2fv(i_data[11]); + glVertex2fv(i_data[9]); + glVertex2fv(i_data[7]); + glVertex2fv(i_data[5]); + glVertex2fv(i_data[3]); + glVertex2fv(i_data[1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(i_data[20]); + glVertex2fv(i_data[22]); + glVertex2fv(i_data[23]); + glVertex2fv(i_data[21]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/ideas.c b/lib/glut-3.7.6/progs/demos/ideas/ideas.c new file mode 100644 index 0000000000..ae54438f2c --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/ideas.c @@ -0,0 +1,1056 @@ + +/* Copyright (c) Mark J. Kilgard, 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. + */ +#include +#ifdef _WIN32 +#include +#include +#include +#define gettimeofday(_x, _y) \ +{ \ + struct timeb _t; \ + ftime(&_t); \ + (_x)->tv_sec = _t.time; \ + (_x)->tv_usec = _t.millitm * 1000; \ +} +#else +#include +#endif +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#include +#include +#include "objects.h" +#include + +#define X 0 +#define Y 1 +#define Z 2 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEG *M_PI/180.0 +#define RAD *180.0/M_PI + +float move_speed; /* Spline distance per second */ + +int multisample = 0; /* Antialias polygons? */ +int doublebuffer = 1; /* Doublebuffer? */ + + +#define SPEED_SLOW 0.2 /* Spline distances per second */ +#define SPEED_MEDIUM 0.4 +#define SPEED_FAST 0.7 +#define SPEED_SUPER_FAST 1.0 + +#define O_NOMS 7 +#define O_4MS 8 +#define O_8MS 9 +#define O_16MS 10 + +static int RGBA_SB_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE; + +static int RGBA_DB_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE; + +float light1_ambient[] = { 0.0,0.0,0.0,1.0 }; +float light1_lcolor[] = { 1.0,1.0,1.0,1.0 }; +float light1_position[] = { 0.0,1.0,0.0,0.0 }; + +float light2_ambient[] = { 0.0,0.0,0.0,1.0 }; +float light2_lcolor[] = { 0.3,0.3,0.5,1.0 }; +float light2_position[] = { -1.0,0.0,0.0,0.0 }; + +float light3_ambient[] = { 0.2,0.2,0.2,1.0 }; +float light3_lcolor[] = { 0.2,0.2,0.2,1.0 }; +float light3_position[] = { 0.0,-1.0,0.0,0.0 }; + +float lmodel_LVW[] = { 0.0 }; +float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 }; +float lmodel_TWO[] = { GL_TRUE }; + +float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0}; +float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0}; +float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0}; +float mat_logo_shininess[] = {30.0}; + +float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0}; +float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0}; +float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0}; +float mat_holder_base_shininess[] = {30.0}; + +float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 }; +float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 }; +float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 }; +float mat_holder_rings_shininess[] = { 30.0 }; + +float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 }; +float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 }; +float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 }; +float mat_hemisphere_shininess[] = {20.0}; + +GLubyte stipple[32*32]; + +typedef float vector[3]; +typedef float vector4[4]; +typedef vector parameter[4]; + +/* + * Function definitions + */ +static void initialize(void); +static void resize_window(int w, int h); +static void build_table(void); +static parameter *calc_spline_params(vector *ctl_pts, int n); +static void calc_spline(vector v, parameter *params, float current_time); +static void normalize(vector v); +static float dot(vector v1, vector v2); +void draw_table(void); +void draw_logo_shadow(void); +void draw_hemisphere(void); +void draw_logo(void); +void draw_under_table(void); +void draw_i(void); +void draw_d(void); +void draw_e(void); +void draw_a(void); +void draw_s(void); +void draw_n(void); +void draw_m(void); +void draw_o(void); +void draw_t(void); + +int post_idle = 0; +static void idle(void); +static void do_post_idle(void); +static void display(void); +static void mouse(int b, int s, int x, int y); +static void keyboard(unsigned char c, int x, int y); +static void vis(int); + +static void init_materials(void) { + int x, y; + + /* Stipple pattern */ + for (y = 0; y < 32; y++) + for (x = 0; x < 4; x++) + stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55; + + glNewList(MAT_LOGO, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess); + glEndList(); + + glNewList( MAT_HOLDER_BASE, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess); + glEndList(); + + glNewList(MAT_HOLDER_RINGS, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess); + glEndList(); + + glNewList(MAT_HEMISPHERE, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess); + glEndList(); + +} + +void init_lights(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 }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, position); + + glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient); + glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor); + glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor); + glLightfv (GL_LIGHT1, GL_POSITION, light1_position); + + glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient); + glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor); + glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor); + glLightfv (GL_LIGHT2, GL_POSITION, light2_position); + + glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient); + glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor); + glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor); + glLightfv (GL_LIGHT3, GL_POSITION, light3_position); + + glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW); + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); +} + +short dev, val; + +float current_time=0.0; +float hold_time=0.0; /* Used when auto-running */ + +float tmplight[] = { + GL_POSITION, 0.0, 0.0, 0.0, 0.0, +}; + +GLfloat tv[4][4] = { + {1.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, -1.0}, + {0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, +}; + +#define TABLERES 12 + +float pcr, pcg, pcb, pca; + +vector table_points[TABLERES+1][TABLERES+1]; +GLubyte tablecolors[TABLERES+1][TABLERES+1]; + +vector paper_points[4] = { + {-0.8, 0.0, 0.4}, + {-0.2, 0.0, -1.4}, + {1.0, 0.0, -1.0}, + {0.4, 0.0, 0.8}, +}; + +float dot(vector, vector); + +#define TIME 15 +#define START_TIME 0.6 + +vector light_pos_ctl[] = { + + {0.0, 1.8, 0.0}, + {0.0, 1.8, 0.0}, + {0.0, 1.6, 0.0}, + + {0.0, 1.6, 0.0}, + {0.0, 1.6, 0.0}, + {0.0, 1.6, 0.0}, + {0.0, 1.4, 0.0}, + + {0.0, 1.3, 0.0}, + {-0.2, 1.5, 2.0}, + {0.8, 1.5, -0.4}, + {-0.8, 1.5, -0.4}, + + {0.8, 2.0, 1.0}, + {1.8, 5.0, -1.8}, + {8.0, 10.0, -4.0}, + {8.0, 10.0, -4.0}, + {8.0, 10.0, -4.0}, +}; + +vector logo_pos_ctl[] = { + + {0.0, -0.5, 0.0}, + + {0.0, -0.5, 0.0}, + {0.0, -0.5, 0.0}, + + {0.0, -0.5, 0.0}, + {0.0, -0.5, 0.0}, + {0.0, -0.5, 0.0}, + {0.0, 0.0, 0.0}, + + {0.0, 0.6, 0.0}, + {0.0, 0.75, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + + {0.0, 0.5, 0.0}, + {0.0, 0.5, 0.0}, + {0.0, 0.5, 0.0}, + {0.0, 0.5, 0.0}, + {0.0, 0.5, 0.0}, +}; + + +vector logo_rot_ctl[] = { + + {0.0, 0.0, -18.4}, + + {0.0, 0.0, -18.4}, + {0.0, 0.0, -18.4}, + + {0.0, 0.0, -18.4}, + {0.0, 0.0, -18.4}, + {0.0, 0.0, -18.4}, + {0.0, 0.0, -18.4}, + {0.0, 0.0, -18.4}, + +/* {90.0, 0.0, -90.0}, + {180.0, 180.0, 90.0}, */ + {240.0, 360.0, 180.0}, + {90.0, 180.0, 90.0}, + + {11.9, 0.0, -18.4}, + {11.9, 0.0, -18.4}, + {11.9, 0.0, -18.4}, + {11.9, 0.0, -18.4}, + {11.9, 0.0, -18.4}, +}; + + +vector view_from_ctl[] = { + + {-1.0, 1.0, -4.0}, + + {-1.0, -3.0, -4.0}, /* 0 */ + {-3.0, 1.0, -3.0}, /* 1 */ + + {-1.8, 2.0, 5.4}, /* 2 */ + {-0.4, 2.0, 1.2}, /* 3 */ + {-0.2, 1.5, 0.6}, /* 4 */ + {-0.2, 1.2, 0.6}, /* 5 */ + + {-0.8, 1.0, 2.4}, /* 6 */ + {-1.0, 2.0, 3.0}, /* 7 */ + {0.0, 4.0, 3.6}, /* 8 */ + {-0.8, 4.0, 1.2}, /* 9 */ + + {-0.2, 3.0, 0.6}, /* 10 */ + {-0.1, 2.0, 0.3}, /* 11 */ + {-0.1, 2.0, 0.3}, /* 12 */ + {-0.1, 2.0, 0.3}, /* 13 */ + {-0.1, 2.0, 0.3}, /* 13 */ + + +}; + +vector view_to_ctl[] = { + + {-1.0, 1.0, 0.0}, + + {-1.0, -3.0, 0.0}, + {-1.0, 1.0, 0.0}, + + {0.1, 0.0, -0.3}, + {0.1, 0.0, -0.3}, + {0.1, 0.0, -0.3}, + {0.0, 0.2, 0.0}, + + {0.0, 0.6, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + {0.0, 0.8, 0.0}, + +}; + + +vector view_from, view_to, logo_pos, logo_rot; +vector4 light_pos; + +parameter *view_from_spline, *view_to_spline, + *light_pos_spline, *logo_pos_spline, + *logo_rot_spline; + +double a3, a4; + +void ideas_usage(void) +{ + fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n"); + fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n"); + fprintf(stderr, "to pause.\n"); +} + + int auto_run; /* If set, then automatically run forever */ + float new_speed; /* Set new animation speed? */ + int timejerk; /* Set to indicate time jerked! (menu pulled down) */ + int paused = 0; /* Paused? */ + int right = 0; /* Draw right eye? */ + int resetclock; /* Reset the clock? */ + float timeoffset; /* Used to compute timing */ + struct timeval start; + +int main(int argc, char **argv) +{ + int i; + + glutInit(&argc, argv); + + auto_run = 0; /* Don't automatically run forever */ + /* .4 spline distance per second by default */ + move_speed = SPEED_MEDIUM; + new_speed = SPEED_MEDIUM; + timeoffset = START_TIME; + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + break; + } + + switch(argv[i][1]) { + case 'a': /* Keep running forever */ + auto_run = 1; + break; + case 'm': /* Multisample */ + multisample = 1; + break; + case 'd': /* Single buffer */ + doublebuffer = 0; + break; + case 's': + switch(argv[i][2]) { + case '1': + move_speed = new_speed = SPEED_SLOW; + break; + case '2': + move_speed = new_speed = SPEED_MEDIUM; + break; + case '3': + move_speed = new_speed = SPEED_FAST; + break; + case '4': + move_speed = new_speed = SPEED_SUPER_FAST; + break; + } + break; + default: + ideas_usage(); + break; + } + } + + initialize(); + + current_time = timeoffset; + resetclock = 1; + timejerk = 0; + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +static void idle(void) +{ + if ((current_time) > (TIME*1.0)-3.0) { + if (auto_run) { + hold_time += current_time - (TIME - 3.001); + if (hold_time > 3.0) { /* 3 second hold */ + hold_time = 0.0; + resetclock = 1; + } + } else { + if(!resetclock) glutIdleFunc(NULL); + } + current_time = (TIME*1.0)-3.001; + } else { + post_idle = 1; + } + glutPostRedisplay(); +} + +/* ARGSUSED2 */ +static void +mouse(int b, int s, int x, int y) +{ + if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN) { + resetclock = 1; + paused = 0; + glutIdleFunc(idle); + } +} + +/* ARGSUSED1 */ +static void +keyboard(unsigned char c, int x, int y) +{ + switch(c) { + case 27: + exit(0); + break; + case '1': + new_speed = SPEED_SLOW; + break; + case '2': + new_speed = SPEED_MEDIUM; + break; + case '3': + new_speed = SPEED_FAST; + break; + case '4': + new_speed = SPEED_SUPER_FAST; + break; + default: + if (paused) timejerk = 1; + paused = ~paused; + if(paused) { + glutIdleFunc(NULL); + } else { + glutIdleFunc(idle); + } + } +} + +static void +vis(int visible) +{ + if (visible == GLUT_VISIBLE) { + if(!paused) glutIdleFunc(idle); + do_post_idle(); + } else { + if(!paused) glutIdleFunc(NULL); + } +} + +static void display(void) +{ + float x, y, z, c; + + calc_spline(view_from, view_from_spline, current_time); + calc_spline(view_to, view_to_spline, current_time); + calc_spline(light_pos, light_pos_spline, current_time); + light_pos[3] = 0.0; + calc_spline(logo_pos, logo_pos_spline, current_time); + calc_spline(logo_rot, logo_rot_spline, current_time); + + tmplight[1] = light_pos[X] - logo_pos[X]; + tmplight[2] = light_pos[Y] - logo_pos[Y]; + tmplight[3] = light_pos[Z] - logo_pos[Z]; + + glNewList(LIGHT_TMP, GL_COMPILE); + glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); + glEndList(); + + tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y]; + + glColor3ub(0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* + * SHADOW + */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(view_from[X], view_from[Y], view_from[Z], + view_to[X], view_to[Y], view_to[Z], + 0.0, 1.0, 0.0); + + if (view_from[Y] > 0.0) draw_table(); + + glEnable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + if (logo_pos[Y] < 0.0) { + + if (logo_pos[Y]>-0.33) { + /* We're emerging from the table */ + c = 1.0 - (logo_pos[Y]) / -0.33; + pca /= 4.0; + glColor3ub((GLubyte)(128.0*(1.0-c)*0.5 + 255.0*pca*c), + (GLubyte)(102.0*(1.0-c)*0.5 + 255.0*pca*c), + (GLubyte)(179.0*(1.0-c)*0.5 + 200.0*pca*c)); + } else { + /* Still under table */ + glColor3ub(128/2, 102/2, 179/2); + } + + glPushMatrix(); + glScalef(0.04, 0.0, 0.04); + glRotatef(0.1 * (-900), 1.0, 0.0, 0.0); + glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0); + glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0); + glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0); + glRotatef(0.1 * (353), 1.0, 0.0, 0.0); + glRotatef(0.1 * (450), 0.0, 1.0, 0.0); + draw_logo_shadow(); + glPopMatrix(); + } + + if (logo_pos[Y] > 0.0) { + glPushMatrix(); + if (logo_pos[Y]<0.33) { + pca /= 4.0; + c = 1.0 - (logo_pos[Y])/0.33; + glColor3ub((GLubyte)(255.0*pca*c), + (GLubyte)(255.0*pca*c), + (GLubyte)(200.0*pca*c)); + } else { + glColor3ub(0, 0, 0); + } + + glTranslatef(light_pos[X], light_pos[Y], light_pos[Z]); + glMultMatrixf(&tv[0][0]); + glTranslatef(-light_pos[X]+logo_pos[X], + -light_pos[Y]+logo_pos[Y], + -light_pos[Z]+logo_pos[Z]); + glScalef(0.04, 0.04, 0.04); + glRotatef (0.1 * (-900), 1.0, 0.0, 0.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0); + glRotatef (0.1 * (353), 1.0, 0.0, 0.0); + glRotatef (0.1 * (450), 0.0, 1.0, 0.0); + + + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple); + draw_logo_shadow(); + glDisable(GL_POLYGON_STIPPLE); + glPopMatrix(); + } + /* + * DONE SHADOW + */ + + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(.1*(450), 5.0/4.0, 0.5, 20.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(view_from[X], view_from[Y], view_from[Z], + view_to[X], view_to[Y], view_to[Z], + 0.0, 1.0, 0.0); + + glCallList( MAT_HOLDER_RINGS); + + glPushMatrix(); + glTranslatef(light_pos[X], light_pos[Y], light_pos[Z]); + glScalef(0.1, 0.1, 0.1); + + x = light_pos[X] - logo_pos[X]; + y = light_pos[Y] - logo_pos[Y]; + z = light_pos[Z] - logo_pos[Z]; + + if (x!=0.0) { + a3 = -atan2(z, x)*10.0 RAD; + } else a3 = 0.0; + + a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD; + + glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0); + glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0); + glRotatef (0.1 * (-900), 1.0, 0.0, 0.0); + + glEnable(GL_LIGHT2); + glEnable(GL_LIGHT3); + glCallList(MAT_HEMISPHERE); + glEnable(GL_NORMALIZE); + draw_hemisphere(); + glDisable(GL_NORMALIZE); + glPopMatrix(); + + glDisable(GL_LIGHT2); + glDisable(GL_LIGHT3); + glEnable(GL_LIGHT1); + glLightfv(GL_LIGHT1, GL_POSITION, light_pos); + + if (logo_pos[Y] > -0.33) { + + glCallList(MAT_LOGO); + + glPushMatrix(); + glTranslatef(logo_pos[X], logo_pos[Y], logo_pos[Z]); + glScalef(0.04, 0.04, 0.04); + glRotatef (0.1 * (-900), 1.0, 0.0, 0.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0); + glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0); + glRotatef (0.1 * (353), 1.0, 0.0, 0.0); + glRotatef (0.1 * (450), 0.0, 1.0, 0.0); + glEnable(GL_LIGHTING); + draw_logo(); + glPopMatrix(); + } + + if (view_from[Y] < 0.0) draw_under_table(); + + glutSwapBuffers(); + + if(post_idle) do_post_idle(); +} + +static void do_post_idle(void) +{ + struct timeval current; + float timediff; + + /* Time jerked -- adjust clock appropriately */ + if (timejerk) { + timejerk = 0; + timeoffset = current_time; + gettimeofday(&start, NULL); + } + + /* Reset our timer */ + if (resetclock) { + resetclock = 0; + paused = 0; + timeoffset = START_TIME; + gettimeofday(&start, NULL); + } + + /* Compute new time */ + gettimeofday(¤t, NULL); + timediff = (current.tv_sec - start.tv_sec) + + ((double) (current.tv_usec - start.tv_usec)) / 1000000.0; + if (!paused) { + current_time = timediff * move_speed + timeoffset; + } + + /* Adjust to new speed */ + if (new_speed != move_speed) { + move_speed = new_speed; + timeoffset = current_time; + gettimeofday(&start, NULL); + } + post_idle = 0; +} + +static void resize_window(int w, int h) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, w, h); +} + +static void initialize(void) +{ + int attr; + + attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes; + glutInitDisplayMode(attr); + glutInitWindowSize(640, 480); + glutCreateWindow("Ideas"); + + if (multisample) glEnable(GL_POLYGON_SMOOTH); + + init_lights(); + init_materials(); + + build_table(); + + view_from_spline = calc_spline_params(view_from_ctl, TIME); + view_to_spline = calc_spline_params(view_to_ctl, TIME); + light_pos_spline = calc_spline_params(light_pos_ctl, TIME); + logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME); + logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME); + + glutReshapeFunc(resize_window); + glutDisplayFunc(display); + glutMouseFunc(mouse); + glutKeyboardFunc(keyboard); + glutVisibilityFunc(vis); + + glMatrixMode(GL_MODELVIEW); +} + + +static void build_table(void) +{ + float i, j; + + for (j=0.0; j<=TABLERES*1.0; j+=1.0) { + for (i=0.0; i<=TABLERES*1.0; i+=1.0) { + table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0; + table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0; + table_points[(int)j][(int)i][Y] = 0.0; + } + } +} + + +void draw_table(void) +{ + float c; + int i, j; + int k, l; + float ov[3], lv[3]; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + ov[X] = light_pos[X]-logo_pos[X]; + ov[Y] = light_pos[Y]-logo_pos[Y]; + ov[Z] = light_pos[Z]-logo_pos[Z]; + + normalize(ov); + + for (j=0; j<=TABLERES; j++) { + for (i=0; i<=TABLERES; i++) { + lv[X] = light_pos[X] - table_points[j][i][X]; + lv[Y] = light_pos[Y] - table_points[j][i][Y]; + lv[Z] = light_pos[Z] - table_points[j][i][Z]; + normalize(lv); + if ((c = dot(lv, ov))<0.0) c = 0.0; + c = c * c * c * lv[Y] * 255.0; + /* fade */ + if ((current_time>TIME-5.0) && (current_time-0.33 && logo_pos[Y]<0.33) { + glEnable(GL_DEPTH_TEST); + } + + pca = 0.0; + glBegin(GL_POLYGON); + for (i=0; i<4; i++) { + lv[X] = light_pos[X] - paper_points[i][X]; + lv[Y] = light_pos[Y] - paper_points[i][Y]; + lv[Z] = light_pos[Z] - paper_points[i][Z]; + normalize(lv); + if ((c = dot(lv, ov))<0.0) c = 0.0; + c = c * c * c * lv[Y]; + /* fade */ + if ((current_time>TIME-5.0) && (current_timeTIME*1.0-5.0) { + c = (current_time-(TIME*1.0-5.0))/2.0; + glColor3ub((GLubyte)(c*255.0), (GLubyte)(c*255.0), (GLubyte)(c*255.0)); + } else glColor3ub(0, 0, 0); + + glDisable(GL_DEPTH_TEST); + + draw_i(); + glTranslatef(3.0, 0.0, 0.0); + + draw_d(); + glTranslatef(6.0, 0.0, 0.0); + + draw_e(); + glTranslatef(5.0, 0.0, 0.0); + + draw_a(); + glTranslatef(6.0, 0.0, 0.0); + + draw_s(); + glTranslatef(10.0, 0.0, 0.0); + + draw_i(); + glTranslatef(3.0, 0.0, 0.0); + + draw_n(); + glTranslatef(-31.0, -13.0, 0.0); + + draw_m(); + glTranslatef(10.0, 0.0, 0.0); + + draw_o(); + glTranslatef(5.0, 0.0, 0.0); + + draw_t(); + glTranslatef(4.0, 0.0, 0.0); + + draw_i(); + glTranslatef(3.5, 0.0, 0.0); + + draw_o(); + glTranslatef(5.0, 0.0, 0.0); + + draw_n(); + + glPopMatrix(); + +} + + + +void draw_under_table(void) +{ + int k, l; + + glDisable(GL_DEPTH_TEST); + + + glColor3ub(0, 0, 0); + + for (l=0; l= (TIME - 3)) { + ti = TIME - 4; + } + + for (i=0; i<3; i++) { + v[i] = params[ti][3][i] + + params[ti][2][i] * t + + params[ti][1][i] * t * t + + params[ti][0][i] * t * t * t; + } + +} + +static parameter *calc_spline_params(vector *ctl_pts, int n) +{ + + int i, j; + parameter *params; + + if (n<4) { + fprintf(stderr, + "calc_spline_params: not enough control points\n"); + return (NULL); + } + + params = (parameter *)malloc(sizeof(parameter) * (n-3)); + + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ideas - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ideas.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ideas.mak" CFG="ideas - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ideas - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ideas - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ideas - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ideas - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "ideas - Win32 Release" +# Name "ideas - Win32 Debug" +# Begin Source File + +SOURCE=.\a.c +# End Source File +# Begin Source File + +SOURCE=.\b.c +# End Source File +# Begin Source File + +SOURCE=.\d.c +# End Source File +# Begin Source File + +SOURCE=.\draw_holder.c +# End Source File +# Begin Source File + +SOURCE=.\draw_lamp.c +# End Source File +# Begin Source File + +SOURCE=.\draw_logo.c +# End Source File +# Begin Source File + +SOURCE=.\draw_logo_line.c +# End Source File +# Begin Source File + +SOURCE=.\draw_logo_shadow.c +# End Source File +# Begin Source File + +SOURCE=.\e.c +# End Source File +# Begin Source File + +SOURCE=.\f.c +# End Source File +# Begin Source File + +SOURCE=.\h.c +# End Source File +# Begin Source File + +SOURCE=.\i.c +# End Source File +# Begin Source File + +SOURCE=.\ideas.c +# End Source File +# Begin Source File + +SOURCE=.\m.c +# End Source File +# Begin Source File + +SOURCE=.\n.c +# End Source File +# Begin Source File + +SOURCE=.\o.c +# End Source File +# Begin Source File + +SOURCE=.\objects.h +# End Source File +# Begin Source File + +SOURCE=.\p.c +# End Source File +# Begin Source File + +SOURCE=.\r.c +# End Source File +# Begin Source File + +SOURCE=.\s.c +# End Source File +# Begin Source File + +SOURCE=.\t.c +# End Source File +# Begin Source File + +SOURCE=.\w.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/ideas/m.c b/lib/glut-3.7.6/progs/demos/ideas/m.c new file mode 100644 index 0000000000..1ce138fa1b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/m.c @@ -0,0 +1,228 @@ +/* + * (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. + */ +#include + +float m_data[][2] = { + {0.590769, 9.449335}, + {2.116923, 9.842375}, + {1.362051, 9.383828}, + {2.527179, 9.825998}, + {1.591795, 9.072672}, + {2.789744, 9.514841}, + {1.690256, 8.663255}, + {2.658462, 8.335722}, + {1.575385, 7.222108}, + {2.067692, 6.255886}, + {0.918974, 4.028659}, + {1.050256, 3.013306}, + {0.705641, 3.013306}, + + {2.018461, 6.386899}, + {1.788718, 5.617196}, + {2.921026, 7.991812}, + {3.167180, 8.008188}, + {3.544615, 8.827022}, + {3.872821, 8.843398}, + {4.414359, 9.547595}, + {4.447179, 9.056294}, + {5.120000, 9.891504}, + {4.841026, 8.843398}, + {5.825641, 9.809621}, + {5.005128, 8.040941}, + {5.989744, 8.761515}, + {4.906667, 6.714432}, + {5.595897, 7.123848}, + {3.987692, 2.996929}, + {4.348718, 2.996929}, + + {5.218462, 5.977482}, + {5.251282, 6.354146}, + {6.449231, 7.893552}, + {6.400000, 8.221085}, + {7.302564, 8.843398}, + {7.351795, 9.334698}, + {7.827693, 9.154554}, + {8.008205, 9.842375}, + {8.139487, 9.121801}, + {8.795897, 9.973388}, + {8.402051, 8.728762}, + {9.337436, 9.531218}, + {8.402051, 8.040941}, + {9.288205, 8.433982}, + {7.745641, 5.813715}, + {8.320000, 5.928352}, + {7.286154, 4.012282}, + {7.991795, 4.126919}, + {7.499487, 3.357216}, + {8.533334, 3.766633}, + {8.123077, 3.062436}, + {8.927179, 3.832139}, + {8.910769, 3.340839}, + {9.550769, 4.126919}, + +}; + +void draw_m(void) { + + glBegin(GL_LINE_STRIP); + glVertex2fv(m_data[0]); + glVertex2fv(m_data[2]); + glVertex2fv(m_data[4]); + glVertex2fv(m_data[6]); + glVertex2fv(m_data[8]); + glVertex2fv(m_data[10]); + glVertex2fv(m_data[12]); + glVertex2fv(m_data[11]); + glVertex2fv(m_data[9]); + glVertex2fv(m_data[7]); + glVertex2fv(m_data[5]); + glVertex2fv(m_data[3]); + glVertex2fv(m_data[1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(m_data[14]); + glVertex2fv(m_data[16]); + glVertex2fv(m_data[18]); + glVertex2fv(m_data[20]); + glVertex2fv(m_data[22]); + glVertex2fv(m_data[24]); + glVertex2fv(m_data[26]); + glVertex2fv(m_data[28]); + glVertex2fv(m_data[29]); + glVertex2fv(m_data[27]); + glVertex2fv(m_data[25]); + glVertex2fv(m_data[23]); + glVertex2fv(m_data[21]); + glVertex2fv(m_data[19]); + glVertex2fv(m_data[17]); + glVertex2fv(m_data[15]); + glVertex2fv(m_data[13]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(m_data[30]); + glVertex2fv(m_data[32]); + glVertex2fv(m_data[34]); + glVertex2fv(m_data[36]); + glVertex2fv(m_data[38]); + glVertex2fv(m_data[40]); + glVertex2fv(m_data[42]); + glVertex2fv(m_data[44]); + glVertex2fv(m_data[46]); + glVertex2fv(m_data[48]); + glVertex2fv(m_data[50]); + glVertex2fv(m_data[52]); + glVertex2fv(m_data[53]); + glVertex2fv(m_data[51]); + glVertex2fv(m_data[49]); + glVertex2fv(m_data[47]); + glVertex2fv(m_data[45]); + glVertex2fv(m_data[43]); + glVertex2fv(m_data[41]); + glVertex2fv(m_data[39]); + glVertex2fv(m_data[37]); + glVertex2fv(m_data[35]); + glVertex2fv(m_data[33]); + glVertex2fv(m_data[31]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(m_data[0]); + glVertex2fv(m_data[1]); + glVertex2fv(m_data[2]); + glVertex2fv(m_data[3]); + glVertex2fv(m_data[4]); + glVertex2fv(m_data[5]); + glVertex2fv(m_data[6]); + glVertex2fv(m_data[7]); + glVertex2fv(m_data[8]); + glVertex2fv(m_data[9]); + glVertex2fv(m_data[10]); + glVertex2fv(m_data[11]); + glVertex2fv(m_data[12]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(m_data[13]); + glVertex2fv(m_data[14]); + glVertex2fv(m_data[15]); + glVertex2fv(m_data[16]); + glVertex2fv(m_data[17]); + glVertex2fv(m_data[18]); + glVertex2fv(m_data[19]); + glVertex2fv(m_data[20]); + glVertex2fv(m_data[21]); + glVertex2fv(m_data[22]); + glVertex2fv(m_data[23]); + glVertex2fv(m_data[24]); + glVertex2fv(m_data[25]); + glVertex2fv(m_data[26]); + glVertex2fv(m_data[27]); + glVertex2fv(m_data[28]); + glVertex2fv(m_data[29]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(m_data[30]); + glVertex2fv(m_data[31]); + glVertex2fv(m_data[32]); + glVertex2fv(m_data[33]); + glVertex2fv(m_data[34]); + glVertex2fv(m_data[35]); + glVertex2fv(m_data[36]); + glVertex2fv(m_data[37]); + glVertex2fv(m_data[38]); + glVertex2fv(m_data[39]); + glVertex2fv(m_data[40]); + glVertex2fv(m_data[41]); + glVertex2fv(m_data[42]); + glVertex2fv(m_data[43]); + glVertex2fv(m_data[44]); + glVertex2fv(m_data[45]); + glVertex2fv(m_data[46]); + glVertex2fv(m_data[47]); + glVertex2fv(m_data[48]); + glVertex2fv(m_data[49]); + glVertex2fv(m_data[50]); + glVertex2fv(m_data[51]); + glVertex2fv(m_data[52]); + glVertex2fv(m_data[53]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/n.c b/lib/glut-3.7.6/progs/demos/ideas/n.c new file mode 100644 index 0000000000..65ef1104f1 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/n.c @@ -0,0 +1,161 @@ +/* + * (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. + */ +#include + +float n_data[][2] = { + {1.009307, 9.444788}, + {2.548087, 9.742002}, + {1.737332, 9.213622}, + {2.994829, 9.659443}, + {1.985522, 8.751290}, + {3.127198, 9.180598}, + {1.935884, 7.975232}, + {2.481903, 6.571723}, + {1.472596, 5.019608}, + {1.439504, 2.988648}, + {1.025853, 2.988648}, + + {2.283350, 6.059855}, + {2.035160, 5.366357}, + {3.292658, 7.711042}, + {3.540848, 7.744066}, + {4.384695, 9.031992}, + {4.699069, 8.916409}, + {5.609100, 9.808049}, + {5.145812, 8.982456}, + {6.155119, 9.791537}, + {5.410548, 8.635707}, + {6.337125, 9.312694}, + {5.360910, 7.991744}, + {6.088935, 8.090816}, + {4.947259, 5.977296}, + {5.261634, 4.804954}, + {4.616339, 4.028896}, + {5.211996, 3.962848}, + {4.732162, 3.318886}, + {5.559462, 3.814241}, + {5.228542, 3.038184}, + {5.940021, 3.814241}, + {5.906929, 3.335397}, + {6.684591, 4.094943}, + +}; + +void draw_n(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(n_data[0]); + glVertex2fv(n_data[1]); + glVertex2fv(n_data[2]); + glVertex2fv(n_data[3]); + glVertex2fv(n_data[4]); + glVertex2fv(n_data[5]); + glVertex2fv(n_data[6]); + glVertex2fv(n_data[7]); + glVertex2fv(n_data[8]); + glVertex2fv(n_data[9]); + glVertex2fv(n_data[10]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(n_data[11]); + glVertex2fv(n_data[12]); + glVertex2fv(n_data[13]); + glVertex2fv(n_data[14]); + glVertex2fv(n_data[15]); + glVertex2fv(n_data[16]); + glVertex2fv(n_data[17]); + glVertex2fv(n_data[18]); + glVertex2fv(n_data[19]); + glVertex2fv(n_data[20]); + glVertex2fv(n_data[21]); + glVertex2fv(n_data[22]); + glVertex2fv(n_data[23]); + glVertex2fv(n_data[24]); + glVertex2fv(n_data[25]); + glVertex2fv(n_data[26]); + glVertex2fv(n_data[27]); + glVertex2fv(n_data[28]); + glVertex2fv(n_data[29]); + glVertex2fv(n_data[30]); + glVertex2fv(n_data[31]); + glVertex2fv(n_data[32]); + glVertex2fv(n_data[33]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(n_data[0]); + glVertex2fv(n_data[2]); + glVertex2fv(n_data[4]); + glVertex2fv(n_data[6]); + glVertex2fv(n_data[8]); + glVertex2fv(n_data[10]); + glVertex2fv(n_data[9]); + glVertex2fv(n_data[7]); + glVertex2fv(n_data[5]); + glVertex2fv(n_data[3]); + glVertex2fv(n_data[1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(n_data[12]); + glVertex2fv(n_data[14]); + glVertex2fv(n_data[16]); + glVertex2fv(n_data[18]); + glVertex2fv(n_data[20]); + glVertex2fv(n_data[22]); + glVertex2fv(n_data[24]); + glVertex2fv(n_data[26]); + glVertex2fv(n_data[28]); + glVertex2fv(n_data[30]); + glVertex2fv(n_data[32]); + glVertex2fv(n_data[33]); + glVertex2fv(n_data[31]); + glVertex2fv(n_data[29]); + glVertex2fv(n_data[27]); + glVertex2fv(n_data[25]); + glVertex2fv(n_data[23]); + glVertex2fv(n_data[21]); + glVertex2fv(n_data[19]); + glVertex2fv(n_data[17]); + glVertex2fv(n_data[15]); + glVertex2fv(n_data[13]); + glVertex2fv(n_data[11]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/o.c b/lib/glut-3.7.6/progs/demos/ideas/o.c new file mode 100644 index 0000000000..b442355adf --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/o.c @@ -0,0 +1,151 @@ +/* + * (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. + */ +#include + +float o_data[][2] = { + {2.975610, 9.603255}, + {2.878049, 9.342828}, + {2.292683, 9.131231}, + {2.048780, 8.691760}, + {1.707317, 8.528993}, + {1.658537, 7.731434}, + {0.878049, 7.047813}, + {1.349594, 5.550356}, + {0.569106, 5.029501}, + {1.528455, 4.443540}, + {0.991870, 3.434385}, + {1.967480, 3.955239}, + {1.772358, 2.994914}, + {2.422764, 3.825025}, + {2.829268, 3.092574}, + {3.154472, 3.971516}, + {3.512195, 3.727365}, + {3.772358, 4.264496}, + {4.130081, 4.524924}, + {4.162601, 4.996948}, + {4.699187, 5.403866}, + {4.471545, 6.461852}, + {5.219512, 7.243133}, + {4.439024, 8.105799}, + {5.235772, 8.756866}, + {4.065041, 8.870804}, + {4.991870, 9.391658}, + {3.853658, 9.228891}, + {4.390244, 9.912513}, + {3.463415, 9.407935}, + {3.674797, 9.912513}, + {2.829268, 9.342828}, + {2.959350, 9.603255}, + +}; + +void draw_o(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(o_data[0]); + glVertex2fv(o_data[1]); + glVertex2fv(o_data[2]); + glVertex2fv(o_data[3]); + glVertex2fv(o_data[4]); + glVertex2fv(o_data[5]); + glVertex2fv(o_data[6]); + glVertex2fv(o_data[7]); + glVertex2fv(o_data[8]); + glVertex2fv(o_data[9]); + glVertex2fv(o_data[10]); + glVertex2fv(o_data[11]); + glVertex2fv(o_data[12]); + glVertex2fv(o_data[13]); + glVertex2fv(o_data[14]); + glVertex2fv(o_data[15]); + glVertex2fv(o_data[16]); + glVertex2fv(o_data[17]); + glVertex2fv(o_data[18]); + glVertex2fv(o_data[19]); + glVertex2fv(o_data[20]); + glVertex2fv(o_data[21]); + glVertex2fv(o_data[22]); + glVertex2fv(o_data[23]); + glVertex2fv(o_data[24]); + glVertex2fv(o_data[25]); + glVertex2fv(o_data[26]); + glVertex2fv(o_data[27]); + glVertex2fv(o_data[28]); + glVertex2fv(o_data[29]); + glVertex2fv(o_data[30]); + glVertex2fv(o_data[31]); + glVertex2fv(o_data[32]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(o_data[0]); + glVertex2fv(o_data[2]); + glVertex2fv(o_data[4]); + glVertex2fv(o_data[6]); + glVertex2fv(o_data[8]); + glVertex2fv(o_data[10]); + glVertex2fv(o_data[12]); + glVertex2fv(o_data[14]); + glVertex2fv(o_data[16]); + glVertex2fv(o_data[18]); + glVertex2fv(o_data[20]); + glVertex2fv(o_data[22]); + glVertex2fv(o_data[24]); + glVertex2fv(o_data[26]); + glVertex2fv(o_data[28]); + glVertex2fv(o_data[30]); + glVertex2fv(o_data[32]); + glVertex2fv(o_data[31]); + glVertex2fv(o_data[29]); + glVertex2fv(o_data[27]); + glVertex2fv(o_data[25]); + glVertex2fv(o_data[23]); + glVertex2fv(o_data[21]); + glVertex2fv(o_data[19]); + glVertex2fv(o_data[17]); + glVertex2fv(o_data[15]); + glVertex2fv(o_data[13]); + glVertex2fv(o_data[11]); + glVertex2fv(o_data[9]); + glVertex2fv(o_data[7]); + glVertex2fv(o_data[5]); + glVertex2fv(o_data[3]); + glVertex2fv(o_data[1]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/objects.h b/lib/glut-3.7.6/progs/demos/ideas/objects.h new file mode 100644 index 0000000000..85e6bdc472 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/objects.h @@ -0,0 +1,61 @@ +/* + * (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. + */ + +#define MAT_LOGO 1 + +#define MAT_PENCIL_ERASER 2 +#define MAT_PENCIL_END 3 +#define MAT_PENCIL_PAINT 4 +#define MAT_PENCIL_WOOD 5 +#define MAT_PENCIL_TIP 6 + +#define MAT_HOLDER_BASE 7 +#define MAT_HOLDER_RINGS 8 + +#define MAT_HEMISPHERE 9 + +#define LIGHT_TMP 10 + +extern float idmat[4][4]; +extern float light1[]; +extern float light2[]; +extern float light3[]; +extern float lmodel[]; +extern float mat_logo[]; +extern float mat_holder_base[]; +extern float mat_holder_rings[]; +extern float mat_hemisphere[]; diff --git a/lib/glut-3.7.6/progs/demos/ideas/p.c b/lib/glut-3.7.6/progs/demos/ideas/p.c new file mode 100644 index 0000000000..035d760ed0 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/p.c @@ -0,0 +1,184 @@ +/* + * (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. + */ +#include + +float p_data[][2] = { + {1.987500, 11.437500-3.0}, + {2.606250, 11.662500-3.0}, + {2.887500, 12.150000-3.0}, + {3.037500, 11.943750-3.0}, + {3.618750, 12.956250-3.0}, + {2.793750, 10.256250-3.0}, + {3.037500, 8.775000-3.0}, + {2.418750, 8.006250-3.0}, + {2.381250, 3.656250-3.0}, + {1.518750, 2.756250-3.0}, + {1.856250, 1.687500-3.0}, + {0.975000, 1.087500-3.0}, + {1.087500, 0.393750-3.0}, + {0.600000, 0.431250-3.0}, + {0.018750, 0.037500-3.0}, + + {3.093750, 9.787500-3.0}, + {3.037500, 9.412500-3.0}, + {4.050000, 11.231250-3.0}, + {4.331250, 11.175000-3.0}, + {5.100000, 12.187500-3.0}, + {5.137500, 11.906250-3.0}, + {5.831250, 12.712500-3.0}, + {5.643750, 12.000000-3.0}, + {6.656250, 12.731250-3.0}, + {5.962500, 11.831250-3.0}, + {6.956250, 12.393750-3.0}, + {6.112500, 11.512500-3.0}, + {7.012500, 11.512500-3.0}, + {6.093750, 10.575000-3.0}, + {6.787500, 9.993750-3.0}, + {5.868750, 9.412500-3.0}, + {6.018750, 7.950000-3.0}, + {5.193750, 7.256250-3.0}, + {5.043750, 6.318750-3.0}, + {4.068750, 5.775000-3.0}, + {3.881250, 5.418750-3.0}, + {3.337500, 5.606250-3.0}, + {3.093750, 5.193750-3.0}, + {2.868750, 5.793750-3.0}, + {2.493750, 5.512500-3.0}, + {2.643750, 6.675000-3.0}, + +}; + +void draw_p(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(p_data[0]); + glVertex2fv(p_data[1]); + glVertex2fv(p_data[2]); + glVertex2fv(p_data[3]); + glVertex2fv(p_data[4]); + glVertex2fv(p_data[5]); + glVertex2fv(p_data[6]); + glVertex2fv(p_data[7]); + glVertex2fv(p_data[8]); + glVertex2fv(p_data[9]); + glVertex2fv(p_data[10]); + glVertex2fv(p_data[11]); + glVertex2fv(p_data[12]); + glVertex2fv(p_data[13]); + glVertex2fv(p_data[14]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(p_data[15]); + glVertex2fv(p_data[16]); + glVertex2fv(p_data[17]); + glVertex2fv(p_data[18]); + glVertex2fv(p_data[19]); + glVertex2fv(p_data[20]); + glVertex2fv(p_data[21]); + glVertex2fv(p_data[22]); + glVertex2fv(p_data[23]); + glVertex2fv(p_data[24]); + glVertex2fv(p_data[25]); + glVertex2fv(p_data[26]); + glVertex2fv(p_data[27]); + glVertex2fv(p_data[28]); + glVertex2fv(p_data[29]); + glVertex2fv(p_data[30]); + glVertex2fv(p_data[31]); + glVertex2fv(p_data[32]); + glVertex2fv(p_data[33]); + glVertex2fv(p_data[34]); + glVertex2fv(p_data[35]); + glVertex2fv(p_data[36]); + glVertex2fv(p_data[37]); + glVertex2fv(p_data[38]); + glVertex2fv(p_data[39]); + glVertex2fv(p_data[40]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(p_data[0]); + glVertex2fv(p_data[2]); + glVertex2fv(p_data[4]); + glVertex2fv(p_data[6]); + glVertex2fv(p_data[8]); + glVertex2fv(p_data[10]); + glVertex2fv(p_data[12]); + glVertex2fv(p_data[14]); + glVertex2fv(p_data[13]); + glVertex2fv(p_data[11]); + glVertex2fv(p_data[9]); + glVertex2fv(p_data[7]); + glVertex2fv(p_data[5]); + glVertex2fv(p_data[3]); + glVertex2fv(p_data[1]); + glVertex2fv(p_data[0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(p_data[15]); + glVertex2fv(p_data[17]); + glVertex2fv(p_data[19]); + glVertex2fv(p_data[21]); + glVertex2fv(p_data[23]); + glVertex2fv(p_data[25]); + glVertex2fv(p_data[27]); + glVertex2fv(p_data[29]); + glVertex2fv(p_data[31]); + glVertex2fv(p_data[33]); + glVertex2fv(p_data[35]); + glVertex2fv(p_data[37]); + glVertex2fv(p_data[39]); + glVertex2fv(p_data[40]); + glVertex2fv(p_data[38]); + glVertex2fv(p_data[36]); + glVertex2fv(p_data[34]); + glVertex2fv(p_data[32]); + glVertex2fv(p_data[30]); + glVertex2fv(p_data[28]); + glVertex2fv(p_data[26]); + glVertex2fv(p_data[24]); + glVertex2fv(p_data[22]); + glVertex2fv(p_data[20]); + glVertex2fv(p_data[18]); + glVertex2fv(p_data[16]); + glVertex2fv(p_data[15]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/r.c b/lib/glut-3.7.6/progs/demos/ideas/r.c new file mode 100644 index 0000000000..4e8f57fc6b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/r.c @@ -0,0 +1,139 @@ +/* + * (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. + */ +#include + +float r_data[][2] = { + {0.018462, 12.344969-3.0}, + {0.775385, 12.677618-3.0}, + {0.812308, 12.344969-3.0}, + {1.421538, 12.899384-3.0}, + {1.126154, 12.123203-3.0}, + {1.864615, 12.825462-3.0}, + {1.181538, 11.716633-3.0}, + {2.030769, 12.603696-3.0}, + {1.089231, 10.700206-3.0}, + {1.495385, 9.351130-3.0}, + {0.516923, 7.355236-3.0}, + {0.756923, 6.375770-3.0}, + {0.129231, 5.119096-3.0}, + {0.461538, 5.322382-3.0}, + + {1.680000, 10.663244-3.0}, + {1.550769, 9.942505-3.0}, + {2.160000, 11.383984-3.0}, + {2.400000, 11.531828-3.0}, + {2.640000, 12.086243-3.0}, + {2.916923, 12.086243-3.0}, + {3.341538, 12.806981-3.0}, + {3.526154, 12.160164-3.0}, + {4.043077, 12.954825-3.0}, + {4.209231, 12.308008-3.0}, + {4.504615, 12.880903-3.0}, + {4.541538, 12.622176-3.0}, + +}; + +void draw_r(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(r_data[0]); + glVertex2fv(r_data[1]); + glVertex2fv(r_data[2]); + glVertex2fv(r_data[3]); + glVertex2fv(r_data[4]); + glVertex2fv(r_data[5]); + glVertex2fv(r_data[6]); + glVertex2fv(r_data[7]); + glVertex2fv(r_data[8]); + glVertex2fv(r_data[9]); + glVertex2fv(r_data[10]); + glVertex2fv(r_data[11]); + glVertex2fv(r_data[12]); + glVertex2fv(r_data[13]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(r_data[14]); + glVertex2fv(r_data[15]); + glVertex2fv(r_data[16]); + glVertex2fv(r_data[17]); + glVertex2fv(r_data[18]); + glVertex2fv(r_data[19]); + glVertex2fv(r_data[20]); + glVertex2fv(r_data[21]); + glVertex2fv(r_data[22]); + glVertex2fv(r_data[23]); + glVertex2fv(r_data[24]); + glVertex2fv(r_data[25]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(r_data[0]); + glVertex2fv(r_data[2]); + glVertex2fv(r_data[4]); + glVertex2fv(r_data[6]); + glVertex2fv(r_data[8]); + glVertex2fv(r_data[10]); + glVertex2fv(r_data[12]); + glVertex2fv(r_data[13]); + glVertex2fv(r_data[11]); + glVertex2fv(r_data[9]); + glVertex2fv(r_data[7]); + glVertex2fv(r_data[5]); + glVertex2fv(r_data[3]); + glVertex2fv(r_data[1]); + glVertex2fv(r_data[0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(r_data[14]); + glVertex2fv(r_data[16]); + glVertex2fv(r_data[18]); + glVertex2fv(r_data[20]); + glVertex2fv(r_data[22]); + glVertex2fv(r_data[24]); + glVertex2fv(r_data[25]); + glVertex2fv(r_data[23]); + glVertex2fv(r_data[21]); + glVertex2fv(r_data[19]); + glVertex2fv(r_data[17]); + glVertex2fv(r_data[15]); + glVertex2fv(r_data[14]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/s.c b/lib/glut-3.7.6/progs/demos/ideas/s.c new file mode 100644 index 0000000000..988ead6a2e --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/s.c @@ -0,0 +1,142 @@ +/* + * (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. + */ +#include + +float s_data[][2] = { + {0.860393, 5.283798}, + {0.529473, 3.550052}, + {0.992761, 4.491228}, + {0.910031, 3.368421}, + {1.240951, 3.830753}, + {1.456050, 3.104231}, + {1.935884, 3.517028}, + {2.002068, 2.988648}, + {2.763185, 3.533540}, + {3.061013, 3.120743}, + {3.391934, 3.748194}, + {4.053774, 3.632611}, + {3.822130, 4.540764}, + {4.550155, 4.590299}, + {3.656670, 5.465428}, + {4.517063, 5.713106}, + {3.276112, 5.894737}, + {3.921407, 6.538700}, + {2.299896, 6.736842}, + {3.044467, 7.430341}, + {1.886246, 7.496388}, + {2.581179, 8.222910}, + {1.902792, 8.751290}, + {2.680455, 8.883385}, + {2.283350, 9.312694}, + {3.358842, 9.609907}, + {3.507756, 9.907121}, + {4.285419, 9.758514}, + {5.112720, 9.973168}, + {4.748707, 9.593395}, + +}; + +void draw_s(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(s_data[0]); + glVertex2fv(s_data[1]); + glVertex2fv(s_data[2]); + glVertex2fv(s_data[3]); + glVertex2fv(s_data[4]); + glVertex2fv(s_data[5]); + glVertex2fv(s_data[6]); + glVertex2fv(s_data[7]); + glVertex2fv(s_data[8]); + glVertex2fv(s_data[9]); + glVertex2fv(s_data[10]); + glVertex2fv(s_data[11]); + glVertex2fv(s_data[12]); + glVertex2fv(s_data[13]); + glVertex2fv(s_data[14]); + glVertex2fv(s_data[15]); + glVertex2fv(s_data[16]); + glVertex2fv(s_data[17]); + glVertex2fv(s_data[18]); + glVertex2fv(s_data[19]); + glVertex2fv(s_data[20]); + glVertex2fv(s_data[21]); + glVertex2fv(s_data[22]); + glVertex2fv(s_data[23]); + glVertex2fv(s_data[24]); + glVertex2fv(s_data[25]); + glVertex2fv(s_data[26]); + glVertex2fv(s_data[27]); + glVertex2fv(s_data[28]); + glVertex2fv(s_data[29]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(s_data[0]); + glVertex2fv(s_data[2]); + glVertex2fv(s_data[4]); + glVertex2fv(s_data[6]); + glVertex2fv(s_data[8]); + glVertex2fv(s_data[10]); + glVertex2fv(s_data[12]); + glVertex2fv(s_data[14]); + glVertex2fv(s_data[16]); + glVertex2fv(s_data[18]); + glVertex2fv(s_data[20]); + glVertex2fv(s_data[22]); + glVertex2fv(s_data[24]); + glVertex2fv(s_data[26]); + glVertex2fv(s_data[28]); + glVertex2fv(s_data[29]); + glVertex2fv(s_data[27]); + glVertex2fv(s_data[25]); + glVertex2fv(s_data[23]); + glVertex2fv(s_data[21]); + glVertex2fv(s_data[19]); + glVertex2fv(s_data[17]); + glVertex2fv(s_data[15]); + glVertex2fv(s_data[13]); + glVertex2fv(s_data[11]); + glVertex2fv(s_data[9]); + glVertex2fv(s_data[7]); + glVertex2fv(s_data[5]); + glVertex2fv(s_data[3]); + glVertex2fv(s_data[1]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/t.c b/lib/glut-3.7.6/progs/demos/ideas/t.c new file mode 100644 index 0000000000..31140d146b --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/t.c @@ -0,0 +1,165 @@ +/* + * (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. + */ +#include + +float t_data[][2] = { + {2.986667, 14.034801}, + {2.445128, 10.088024}, + {1.788718, 9.236438}, + {2.264615, 7.664279}, + {1.165128, 5.666326}, + {2.034872, 4.945752}, + {1.132308, 3.766633}, + {2.182564, 3.570113}, + {1.411282, 2.309109}, + {2.510769, 2.341863}, + {2.149744, 1.048106}, + {3.364103, 1.375640}, + {3.167180, 0.327533}, + {4.381538, 0.736950}, + {5.005128, 0.032753}, + {5.612308, 0.638690}, + {6.235898, 0.540430}, + {7.187692, 1.162743}, + + {1.985641, 9.039918}, + {2.133333, 10.186285}, + {1.509744, 9.023541}, + {1.608205, 9.662231}, + {1.050256, 9.023541}, + {1.050256, 9.334698}, + {0.196923, 9.007165}, + + {2.363077, 9.711361}, + {2.264615, 9.023541}, + {3.282051, 9.563972}, + {3.446154, 9.023541}, + {4.069744, 9.531218}, + {4.299487, 9.236438}, + {4.644103, 9.613101}, + {5.251282, 9.875128}, + +}; + +void draw_t(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(t_data[0]); + glVertex2fv(t_data[1]); + glVertex2fv(t_data[2]); + glVertex2fv(t_data[3]); + glVertex2fv(t_data[4]); + glVertex2fv(t_data[5]); + glVertex2fv(t_data[6]); + glVertex2fv(t_data[7]); + glVertex2fv(t_data[8]); + glVertex2fv(t_data[9]); + glVertex2fv(t_data[10]); + glVertex2fv(t_data[11]); + glVertex2fv(t_data[12]); + glVertex2fv(t_data[13]); + glVertex2fv(t_data[14]); + glVertex2fv(t_data[15]); + glVertex2fv(t_data[16]); + glVertex2fv(t_data[17]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(t_data[18]); + glVertex2fv(t_data[19]); + glVertex2fv(t_data[20]); + glVertex2fv(t_data[21]); + glVertex2fv(t_data[22]); + glVertex2fv(t_data[23]); + glVertex2fv(t_data[24]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(t_data[25]); + glVertex2fv(t_data[26]); + glVertex2fv(t_data[27]); + glVertex2fv(t_data[28]); + glVertex2fv(t_data[29]); + glVertex2fv(t_data[30]); + glVertex2fv(t_data[31]); + glVertex2fv(t_data[32]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(t_data[0]); + glVertex2fv(t_data[2]); + glVertex2fv(t_data[4]); + glVertex2fv(t_data[6]); + glVertex2fv(t_data[8]); + glVertex2fv(t_data[10]); + glVertex2fv(t_data[12]); + glVertex2fv(t_data[14]); + glVertex2fv(t_data[16]); + glVertex2fv(t_data[17]); + glVertex2fv(t_data[15]); + glVertex2fv(t_data[13]); + glVertex2fv(t_data[11]); + glVertex2fv(t_data[9]); + glVertex2fv(t_data[7]); + glVertex2fv(t_data[5]); + glVertex2fv(t_data[3]); + glVertex2fv(t_data[1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(t_data[18]); + glVertex2fv(t_data[20]); + glVertex2fv(t_data[22]); + glVertex2fv(t_data[24]); + glVertex2fv(t_data[23]); + glVertex2fv(t_data[21]); + glVertex2fv(t_data[19]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(t_data[26]); + glVertex2fv(t_data[28]); + glVertex2fv(t_data[30]); + glVertex2fv(t_data[32]); + glVertex2fv(t_data[31]); + glVertex2fv(t_data[29]); + glVertex2fv(t_data[27]); + glVertex2fv(t_data[25]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/ideas/w.c b/lib/glut-3.7.6/progs/demos/ideas/w.c new file mode 100644 index 0000000000..f0637cc409 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/ideas/w.c @@ -0,0 +1,245 @@ +/* + * (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. + */ +#include + +float w_data[][2] = { + {2.400000, 12.899384-3.0}, + {1.624615, 12.344969-3.0}, + {1.513846, 11.790554-3.0}, + {0.812308, 11.310061-3.0}, + {1.292308, 10.570842-3.0}, + {0.387692, 9.554415-3.0}, + {1.163077, 8.907598-3.0}, + {0.443077, 8.427105-3.0}, + {1.236923, 7.983573-3.0}, + {0.627692, 6.911705-3.0}, + {1.218462, 6.874743-3.0}, + {0.701538, 5.765914-3.0}, + {1.089231, 5.858316-3.0}, + {0.590769, 5.082136-3.0}, + + {0.904615, 5.636550-3.0}, + {1.070769, 6.227926-3.0}, + {1.716923, 6.708419-3.0}, + {1.993846, 7.577002-3.0}, + {2.603077, 7.780287-3.0}, + {2.621538, 8.408625-3.0}, + {3.138462, 8.630390-3.0}, + {3.193846, 9.314168-3.0}, + {4.080000, 10.995893-3.0}, + {4.209231, 11.550308-3.0}, + + {4.689231, 12.954825-3.0}, + {4.209231, 11.809035-3.0}, + {4.615385, 12.030801-3.0}, + {4.006154, 10.552361-3.0}, + {4.633846, 10.995893-3.0}, + {4.080000, 9.887064-3.0}, + {4.966154, 9.850102-3.0}, + {4.375385, 8.981520-3.0}, + {5.409231, 8.889117-3.0}, + {4.744616, 7.946612-3.0}, + {5.704616, 7.687885-3.0}, + {5.058462, 7.041068-3.0}, + {5.889231, 6.135524-3.0}, + {5.427692, 5.599589-3.0}, + {5.501538, 5.026694-3.0}, + + {5.630769, 5.414784-3.0}, + {5.741539, 5.987679-3.0}, + {6.203077, 6.264887-3.0}, + {6.572308, 7.281314-3.0}, + {7.347692, 7.817248-3.0}, + {7.255384, 9.221766-3.0}, + {7.993846, 9.166325-3.0}, + {7.458462, 11.032854-3.0}, + {8.603077, 11.550308-3.0}, + {7.403077, 11.975359-3.0}, + {8.510769, 12.511293-3.0}, + {7.070769, 12.326488-3.0}, + {7.956923, 12.936345-3.0}, + {6.590769, 12.308008-3.0}, + {7.236923, 12.954825-3.0}, + {6.000000, 12.012321-3.0}, + {6.461538, 12.511293-3.0}, + +}; + +void draw_w(void) { + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(w_data[0]); + glVertex2fv(w_data[1]); + glVertex2fv(w_data[2]); + glVertex2fv(w_data[3]); + glVertex2fv(w_data[4]); + glVertex2fv(w_data[5]); + glVertex2fv(w_data[6]); + glVertex2fv(w_data[7]); + glVertex2fv(w_data[8]); + glVertex2fv(w_data[9]); + glVertex2fv(w_data[10]); + glVertex2fv(w_data[11]); + glVertex2fv(w_data[12]); + glVertex2fv(w_data[13]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(w_data[14]); + glVertex2fv(w_data[15]); + glVertex2fv(w_data[16]); + glVertex2fv(w_data[17]); + glVertex2fv(w_data[18]); + glVertex2fv(w_data[19]); + glVertex2fv(w_data[20]); + glVertex2fv(w_data[21]); + glVertex2fv(w_data[22]); + glVertex2fv(w_data[23]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(w_data[24]); + glVertex2fv(w_data[25]); + glVertex2fv(w_data[26]); + glVertex2fv(w_data[27]); + glVertex2fv(w_data[28]); + glVertex2fv(w_data[29]); + glVertex2fv(w_data[30]); + glVertex2fv(w_data[31]); + glVertex2fv(w_data[32]); + glVertex2fv(w_data[33]); + glVertex2fv(w_data[34]); + glVertex2fv(w_data[35]); + glVertex2fv(w_data[36]); + glVertex2fv(w_data[37]); + glVertex2fv(w_data[38]); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2fv(w_data[39]); + glVertex2fv(w_data[40]); + glVertex2fv(w_data[41]); + glVertex2fv(w_data[42]); + glVertex2fv(w_data[43]); + glVertex2fv(w_data[44]); + glVertex2fv(w_data[45]); + glVertex2fv(w_data[46]); + glVertex2fv(w_data[47]); + glVertex2fv(w_data[48]); + glVertex2fv(w_data[49]); + glVertex2fv(w_data[50]); + glVertex2fv(w_data[51]); + glVertex2fv(w_data[52]); + glVertex2fv(w_data[53]); + glVertex2fv(w_data[54]); + glVertex2fv(w_data[55]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(w_data[0]); + glVertex2fv(w_data[2]); + glVertex2fv(w_data[4]); + glVertex2fv(w_data[6]); + glVertex2fv(w_data[8]); + glVertex2fv(w_data[10]); + glVertex2fv(w_data[12]); + glVertex2fv(w_data[13]); + glVertex2fv(w_data[11]); + glVertex2fv(w_data[9]); + glVertex2fv(w_data[7]); + glVertex2fv(w_data[5]); + glVertex2fv(w_data[3]); + glVertex2fv(w_data[1]); + glVertex2fv(w_data[0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(w_data[14]); + glVertex2fv(w_data[16]); + glVertex2fv(w_data[18]); + glVertex2fv(w_data[20]); + glVertex2fv(w_data[22]); + glVertex2fv(w_data[23]); + glVertex2fv(w_data[21]); + glVertex2fv(w_data[19]); + glVertex2fv(w_data[17]); + glVertex2fv(w_data[15]); + glVertex2fv(w_data[14]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(w_data[24]); + glVertex2fv(w_data[26]); + glVertex2fv(w_data[28]); + glVertex2fv(w_data[30]); + glVertex2fv(w_data[32]); + glVertex2fv(w_data[34]); + glVertex2fv(w_data[36]); + glVertex2fv(w_data[38]); + glVertex2fv(w_data[37]); + glVertex2fv(w_data[35]); + glVertex2fv(w_data[33]); + glVertex2fv(w_data[31]); + glVertex2fv(w_data[29]); + glVertex2fv(w_data[27]); + glVertex2fv(w_data[25]); + glVertex2fv(w_data[24]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2fv(w_data[39]); + glVertex2fv(w_data[41]); + glVertex2fv(w_data[43]); + glVertex2fv(w_data[45]); + glVertex2fv(w_data[47]); + glVertex2fv(w_data[49]); + glVertex2fv(w_data[51]); + glVertex2fv(w_data[53]); + glVertex2fv(w_data[55]); + glVertex2fv(w_data[54]); + glVertex2fv(w_data[52]); + glVertex2fv(w_data[50]); + glVertex2fv(w_data[48]); + glVertex2fv(w_data[46]); + glVertex2fv(w_data[44]); + glVertex2fv(w_data[42]); + glVertex2fv(w_data[40]); + glVertex2fv(w_data[39]); + glEnd(); + +} + diff --git a/lib/glut-3.7.6/progs/demos/lorenz/Imakefile b/lib/glut-3.7.6/progs/demos/lorenz/Imakefile new file mode 100644 index 0000000000..4c9c2d779d --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/lorenz/Imakefile @@ -0,0 +1,15 @@ + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +#include "../../../Glut.cf" + +TARGETS = lorenz + +SRCS = lorenz.c +OBJS = lorenz.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(lorenz,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/lorenz/lorenz.c b/lib/glut-3.7.6/progs/demos/lorenz/lorenz.c new file mode 100644 index 0000000000..0bbd5567f5 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/lorenz/lorenz.c @@ -0,0 +1,644 @@ +/* + * Lorenz Attractor Demo + * + * Adapted from code originally written for the 4D60GT by + * Aaron T. Ferrucci (aaronf@cse.ucsc.edu), 7/3/92. + * + * Description: + * + * This program shows some particles stuck in a Lorenz attractor (the parameters + * used are r=28, b=8/3, sigma=10). The eye is attracted to the red particle, + * with a force directly proportionate to distance. A command line + * puts the whole mess inside a box made of hexagons. I think this helps to + * maintain the illusion of 3 dimensions, but it can slow things down. + * Other options allow you to play with the redraw rate and the number of new + * lines per redraw. So you can customize it to the speed of your machine. + * + * For general info on Lorenz attractors I recommend "An Introduction to + * the Lorenz Equations", IEEE Transactions on Circuits and Systems, August '83. + * + * Bugs: hidden surface removal doesn't apply to hexagons, and + * works poorly on lines when they are too close together. + * + * Notes on OpenGL port: + * + * The timer functions do not exist in OpenGL, so the drawing occurs in a + * continuous loop, controlled by step, stop and go input from the keyboard. + * Perhaps system function could be called to control timing. + * + */ + +#include +#include +#include +#include +#include +#include + +float +random_float(void) +{ + return (float)rand()/RAND_MAX; +} + +void +seed_random_float(long seed) +{ + srand(seed); +} + +static GLuint asphere; + +#define POINTMASK 511 +#define G (0.002) /* eyept to red sphere gravity */ +#define LG (0.3) +#define CUBESIDE (120.) +#define CUBESCALE (23.) +#define CUBEOFFX (-4.) +#define CUBEOFFY (0.) +#define CUBEOFFZ (57.) +#define FALSE 0 +#define TRUE 1 + +/* globals */ +float sigma = 10., r = 28., b = 8./3., dt = 0.003; +int rp = 0, bp = 0, gp = 0, yp = 0, mp = 0; +long xmax, ymax, zmax, zmin; +float rv[POINTMASK+1][3], /* red points */ + bv[POINTMASK+1][3], /* blue points */ + gv[POINTMASK+1][3], /* green points */ + yv[POINTMASK+1][3], /* yellow points */ + mv[POINTMASK+1][3]; /* magenta points */ + +int lpf; /* number of new lines per frame */ + +float eyex[3], /* eye location */ + eyev[3], /* eye velocity */ + eyel[3]; /* lookat point location */ +GLint fovy = 600; +float dx, dy, dz; +GLUquadricObj *quadObj; + +float cubeoffx = CUBEOFFX; +float cubeoffy = CUBEOFFY; +float cubeoffz = CUBEOFFZ; +float farplane = 80.; + +int animate = 1; + +/* option flags */ +GLboolean hexflag, /* hexagons? */ + sflag, + fflag, + wflag, + gflag, + debug; + +/* option values */ +short hexbright; /* brightness for hexagon color */ +int speed, /* speed (number of new line segs per redraw) */ + frame; /* frame rate (actually noise value for TIMER0) */ +float a = 0, + da; /* hexagon rotational velocity (.1 degree/redraw) */ +float gravity; + +/* function declarations */ +void init_3d(void); +void init_graphics(void); +void draw_hexcube(void); +void draw_hexplane(void); +void draw_hexagon(void); +void move_eye(void); +void redraw(void); +void next_line(float v[][3], int *p); +void parse_args(int argc, char **argv); +void print_usage(char*); +void print_info(void); +void sphdraw(float args[4]); +void setPerspective(int angle, float aspect, float zNear, float zFar); + + +static void Reshape(int width, int height) +{ + + glViewport(0,0,width,height); + glClear(GL_COLOR_BUFFER_BIT); + xmax = width; + ymax = height; +} + +/* ARGSUSED1 */ +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 'g': + animate = 1; + glutPostRedisplay(); + break; + case 's': + animate = 0; + glutPostRedisplay(); + break; + case 27: + gluDeleteQuadric(quadObj); + exit(0); + } +} + +static void Draw(void) +{ + int i; + + if (animate) { + i = speed; + while (i--) { + next_line(rv, &rp); + next_line(bv, &bp); + next_line(gv, &gp); + next_line(yv, &yp); + next_line(mv, &mp); + } + glPushMatrix(); + move_eye(); + redraw(); + glPopMatrix(); + } +} + +int main(int argc, char **argv) +{ + glutInitWindowSize(600, 600); + + glutInit(&argc, argv); + + parse_args(argc, argv); + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + + glutCreateWindow("Lorenz Attractors"); + + init_3d(); + init_graphics(); + + /* draw the first POINTMASK points in each color */ + while(rp < POINTMASK) { + next_line(rv, &rp); + next_line(bv, &bp); + next_line(gv, &gp); + next_line(yv, &yp); + next_line(mv, &mp); + } + + eyex[0] = eyex[1] = eyex[2] = 0.; + eyel[0] = rv[rp][0]; + eyel[1] = rv[rp][1]; + eyel[2] = rv[rp][2]; + + glPushMatrix(); + move_eye(); + redraw(); + glPopMatrix(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutIdleFunc(Draw); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + +/* compute the next point on the path according to Lorenz' equations. */ +void next_line(float v[][3], int *p) +{ + + dx = sigma * (v[*p][1] - v[*p][0]) * dt; + dy = (r*v[*p][0] - v[*p][1] + v[*p][0]*v[*p][2]) * dt; + dz = (v[*p][0] *v[*p][1] + b*v[*p][2]) * dt; + + v[(*p + 1) & POINTMASK][0] = v[*p][0] + dx; + v[(*p + 1) & POINTMASK][1] = v[*p][1] + dy; + v[(*p + 1) & POINTMASK][2] = v[*p][2] - dz; + *p = (*p + 1) & POINTMASK; +} + +void drawLines(int index, float array[POINTMASK][3]) +{ + int p; + int i; + +#define LINE_STEP 4 + + p = (index+1)&POINTMASK; + i = LINE_STEP-(p % LINE_STEP); + if (i == LINE_STEP) i=0; + glBegin(GL_LINE_STRIP); + /* draw points in order from oldest to newest */ + while(p != index) { + if (i == 0) { + glVertex3fv(array[p]); + i = LINE_STEP; + } + i--; + p = (p+1) & POINTMASK; + } + glVertex3fv(array[index]); + glEnd(); +} + +void redraw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(hexflag) + draw_hexcube(); + + glColor3f(1.0, 0.0, 0.0); + drawLines(rp, rv); + sphdraw(rv[rp]); + + glColor3f(0.0, 0.0, 1.0); + drawLines(bp, bv); + sphdraw(bv[bp]); + + glColor3f(0.0, 1.0, 0.0); + drawLines(gp, gv); + sphdraw(gv[gp]); + + glColor3f(1.0, 0.0, 1.0); + drawLines(yp, yv); + sphdraw(yv[yp]); + + glColor3f(0.0, 1.0, 1.0); + drawLines(mp, mv); + sphdraw(mv[mp]); + + glutSwapBuffers(); +} + +void move_eye(void) +{ + /* first move the eye */ + eyev[0] += gravity * (rv[rp][0] - eyex[0]); + eyev[1] += gravity * (rv[rp][1] - eyex[1]); + eyev[2] += gravity * (rv[rp][2] - eyex[2]); + + /* adjust position using new velocity */ + eyex[0] += eyev[0] * dt; + eyex[1] += eyev[1] * dt; + eyex[2] += eyev[2] * dt; + + /* move the lookat point */ + /* it catches up to the red point if it's moving slowly enough */ + eyel[0] += LG * (rv[rp][0] - eyel[0]); + eyel[1] += LG * (rv[rp][1] - eyel[1]); + eyel[2] += LG * (rv[rp][2] - eyel[2]); + + /* change view */ + gluLookAt(eyex[0], eyex[1], eyex[2], eyel[0], eyel[1], eyel[2], + 0, 1, 0); +} + +void draw_hexcube(void) +{ + + a += da; + if(a >= 720.) /* depends on slowest rotation factor */ + a = 0.; + + /* draw hexplanes, without changing z-values */ + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + + /* x-y plane */ + glColor3f(0.2, 0.2, 0.6); + glPushMatrix(); + glTranslatef(cubeoffx, cubeoffy, cubeoffz); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + /* x-y plane, translated */ + glPushMatrix(); + glTranslatef(cubeoffx, cubeoffy, cubeoffz - 2*CUBESIDE); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + glColor3f(0.6, 0.2, 0.2); + /* x-z plane, translate low */ + glPushMatrix(); + glRotatef(90, 1.0, 0.0, 0.0); + glTranslatef(cubeoffx, cubeoffz - CUBESIDE, -cubeoffy + CUBESIDE); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + /* x-z plane, translate high */ + glPushMatrix(); + glRotatef(90, 1.0, 0.0, 0.0); + glTranslatef(cubeoffx, cubeoffz - CUBESIDE, -cubeoffy - CUBESIDE); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + glColor3f(0.2, 0.6, 0.2); + /* y-z plane, translate low */ + glPushMatrix(); + glRotatef(90, 0.0, 1.0, 0.0); + glTranslatef(-cubeoffz + CUBESIDE, cubeoffy, cubeoffx + CUBESIDE); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + /* y-z plane, translate high */ + glPushMatrix(); + glRotatef (90, 0.0, 1.0, 0.0); + glTranslatef(-cubeoffz + CUBESIDE, cubeoffy, cubeoffx - CUBESIDE); + glScalef(CUBESCALE, CUBESCALE, CUBESCALE); + draw_hexplane(); + glPopMatrix(); + + glFlush(); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); +} + +float hex_data[8][3] = { + {0., 0., 0.}, + {1.155, 0., 0.}, + {0.577, 1., 0.}, + {-0.577, 1., 0.}, + {-1.155, 0., 0.}, + {-0.577, -1., 0.}, + {0.577, -1., 0.}, + {1.155, 0., 0.}, +}; + +/* draws a hexagon 2 units across, in the x-y plane, */ +/* centered at <0, 0, 0> */ + +void draw_hexagon(void) +{ + if(wflag) { + glPushMatrix(); + glRotatef(a, 0.0, 0.0, 1.0); + } + + glBegin(GL_TRIANGLE_FAN); + glVertex3fv(hex_data[0]); + glVertex3fv(hex_data[1]); + glVertex3fv(hex_data[2]); + glVertex3fv(hex_data[3]); + glVertex3fv(hex_data[4]); + glVertex3fv(hex_data[5]); + glVertex3fv(hex_data[6]); + glVertex3fv(hex_data[7]); + glEnd(); + + if(wflag) + glPopMatrix(); +} + +void tmp_draw_hexplane(void) +{ + glRectf(-2.0, -2.0, 2.0, 2.0); +} + +/* draw 7 hexagons */ +void draw_hexplane(void) +{ + if(wflag) { + glPushMatrix(); + glRotatef(-0.5*a, 0.0, 0.0, 1.0); + } + + /* center , <0, 0, 0> */ + draw_hexagon(); + + /* 12 o'clock, <0, 4, 0> */ + glTranslatef(0., 4., 0.); + draw_hexagon(); + + /* 10 o'clock, <-3.464, 2, 0> */ + glTranslatef(-3.464, -2., 0.); + draw_hexagon(); + + /* 8 o'clock, <-3.464, -2, 0> */ + glTranslatef(0., -4., 0.); + draw_hexagon(); + + /* 6 o'clock, <0, -4, 0> */ + glTranslatef(3.464, -2., 0.); + draw_hexagon(); + + /* 4 o'clock, <3.464, -2, 0> */ + glTranslatef(3.464, 2., 0.); + draw_hexagon(); + + /* 2 o'clock, <3.464, 2, 0> */ + glTranslatef(0., 4., 0.); + draw_hexagon(); + + if(wflag) + glPopMatrix(); +} + +void sphdraw(float args[3]) +{ + glPushMatrix(); + glTranslatef(args[0], args[1], args[2]); + glCallList(asphere); + glPopMatrix(); +} + +void setPerspective(int angle, float aspect, float zNear, float zFar) +{ + glPushAttrib(GL_TRANSFORM_BIT); + glMatrixMode(GL_PROJECTION); + gluPerspective(angle * 0.1, aspect, zNear, zFar); + glPopAttrib(); +} + +/* initialize global 3-vectors */ +void init_3d(void) +{ + (void)seed_random_float((long)time((time_t*)NULL)); + + /* initialize colored points */ + rv[0][0] = (float)random_float() * 10.; + rv[0][1] = (float)random_float() * 10.; + rv[0][2] = (float)random_float() * 10. - 10.; + + bv[0][0] = rv[0][0] + (float)random_float()*5.; + bv[0][1] = rv[0][1] + (float)random_float()*5.; + bv[0][0] = rv[0][2] + (float)random_float()*5.; + + gv[0][0] = rv[0][0] + (float)random_float()*5.; + gv[0][1] = rv[0][1] + (float)random_float()*5.; + gv[0][0] = rv[0][2] + (float)random_float()*5.; + + yv[0][0] = rv[0][0] + (float)random_float()*5.; + yv[0][1] = rv[0][1] + (float)random_float()*5.; + yv[0][0] = rv[0][2] + (float)random_float()*5.; + + mv[0][0] = rv[0][0] + (float)random_float()*5.; + mv[0][1] = rv[0][1] + (float)random_float()*5.; + mv[0][0] = rv[0][2] + (float)random_float()*5.; + + /* initialize eye velocity */ + eyev[0] = eyev[1] = eyev[2] = 0.; +} + + +void init_graphics(void) +{ + int width = 600; + int height = 600; + + xmax = width; + ymax = height; + glDrawBuffer(GL_BACK); + glEnable(GL_DEPTH_TEST); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClearDepth(1.0); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glViewport(0, 0, xmax, ymax); + setPerspective(fovy, (float)xmax/(float)ymax, 0.01, farplane); + quadObj = gluNewQuadric(); + gluQuadricNormals(quadObj, GLU_NONE); + asphere = glGenLists(1); + glNewList(asphere, GL_COMPILE); + gluSphere(quadObj, 0.3, 12, 8); + glEndList(); +} + +#define USAGE "usage message: this space for rent\n" +void parse_args(int argc, char **argv) +{ + hexflag = sflag = fflag = wflag = gflag = debug = FALSE; + + while (--argc) { + if (strcmp("-X", argv[argc]) == 0) { + debug = TRUE; + } else if (strcmp("-h", argv[argc]) == 0) { + print_usage(argv[0]); + exit(1); + } else if (strcmp("-i", argv[argc]) == 0) { + print_info(); + exit(1); + } else if (strcmp("-x", argv[argc]) == 0) { + hexflag = TRUE; + farplane = 300.; + } else if (strcmp("-s", argv[argc]) == 0) { + sflag = TRUE; + if (argv[argc+1]) + speed = atoi(argv[argc+1]); + else { + printf("%s: -s option requires an argument.\n", argv[0]); + exit(1); + } + } else if (strcmp("-f", argv[argc]) == 0) { + fflag = TRUE; + if (argv[argc+1]) + frame = atoi(argv[argc+1]); + else { + printf("%s: -f option requires an argument.\n", argv[0]); + exit(1); + } + if(frame < 0) { + fprintf(stderr, "Try a small positive value for \n"); + fprintf(stderr, "'f'; this is the number of vertical "); + fprintf(stderr, "retraces per redraw\n"); + fprintf(stderr, "Try %s -h for help\n", argv[0]); + exit(1); + } + } else if (strcmp("-w", argv[argc]) == 0) { + wflag = TRUE; + if (argv[argc+1]) + da = atof(argv[argc+1]); + else { + printf("%s: -w option requires an argument.\n", argv[0]); + exit(1); + } + if(da > 10.) { + fprintf(stderr, "That's a large rotational velocity ('w')"); + fprintf(stderr, " but you asked for it\n"); + } + break; + } else if (strcmp("-g", argv[argc]) == 0) { + gflag = TRUE; + if (argv[argc+1]) + gravity = atof(argv[argc+1]); + else { + printf("%s: -g option requires an argument.\n", argv[0]); + exit(1); + } + if(gravity <= 0) { + fprintf(stderr, "Gravity ('g') should be positive\n"); + fprintf(stderr, "Try %s -h for help\n", argv[0]); + } + } else if (strcmp("-?", argv[argc]) == 0) { + fprintf(stderr, USAGE); + } + } + + /* set up default values */ + if(!sflag) + speed = 3; + if(!fflag) + frame = 2; + if(!wflag) + da = 0.; + if(!gflag) + gravity = G; +} + +void print_usage(char *program) +{ +printf("\nUsage: %s [-h] [-i] [-x] [-s speed]", program); +printf(" [-w rot_v] [-g gravity]\n\n"); +printf("-h Print this message.\n"); +printf("-i Print information about the demo.\n"); +printf("-x Enclose the particles in a box made of hexagons.\n"); +printf("-s speed Sets the number of new line segments per redraw \n"); +printf(" interval per line. Default value: 3.\n"); + +/*** The X port does not currently include a timer, so this feature is disabled. +printf("-f framenoise Sets the number of vertical retraces per redraw\n"); +printf(" interval. Example: -f 2 specifies one redraw per\n"); +printf(" 2 vertical retraces, or 30 frames per second.\n"); +printf(" Default value: 2.\n"); +************/ + +printf("-w rot_v Spins the hexagons on their centers, and the sides\n"); +printf(" of the box on their centers. Hexagons spin at the\n"); +printf(" rate rot_v degrees per redraw, and box sides spin\n"); +printf(" at -rot_v/2 degrees per redraw.\n"); +printf("-g gravity Sets the strength of the attraction of the eye to\n"); +printf(" the red particle. Actually, it's not gravity since\n"); +printf(" the attraction is proportionate to distance.\n"); +printf(" Default value: 0.002. Try large values!\n"); +/* input added for GLX port */ +printf(" Executions control: \n"); +printf(" step through single frames\n"); +printf(" g begin continuous frames\n"); +printf(" s stop continuous frames\n"); + +} + +void print_info(void) +{ +printf("\nLORENZ ATTRACTOR DEMO\n\n"); +printf("This program shows some particles stuck in a Lorenz attractor (the \n"); +printf("parameters used are r=28, b=8/3, sigma=10). The eye is attracted to \n"); +printf("the red particle, with a force directly proportional to distance. \n"); +printf("A command line argument puts the particles inside a box made of hexagons, \n"); +printf("helping to maintain the sense of 3 dimensions, but it can slow things down.\n"); +printf("Other options allow you to play with the redraw rate and gravity.\n\n"); + +printf("Try lorenz -h for the usage message.\n"); +} diff --git a/lib/glut-3.7.6/progs/demos/lorenz/lorenz.dsp b/lib/glut-3.7.6/progs/demos/lorenz/lorenz.dsp new file mode 100644 index 0000000000..e5eb290c41 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/lorenz/lorenz.dsp @@ -0,0 +1,88 @@ +# Microsoft Developer Studio Project File - Name="lorenz" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=lorenz - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lorenz.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lorenz.mak" CFG="lorenz - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lorenz - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "lorenz - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lorenz - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "lorenz - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lorenz - Win32 Release" +# Name "lorenz - Win32 Debug" +# Begin Source File + +SOURCE=.\lorenz.c +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/newave/Imakefile b/lib/glut-3.7.6/progs/demos/newave/Imakefile new file mode 100644 index 0000000000..12d04471d8 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/newave/Imakefile @@ -0,0 +1,16 @@ + +/* Copyright (c) Mark J. Kilgard, 1998. */ + +#include "../../../Glut.cf" + +TARGETS = newave + +SRCS = newave.c texture.c + +OBJS = newave.o texture.o + +AllTarget($(TARGETS)) + +NormalGlutProgramTarget(newave,$(OBJS)) + +DependTarget() diff --git a/lib/glut-3.7.6/progs/demos/newave/newave.c b/lib/glut-3.7.6/progs/demos/newave/newave.c new file mode 100644 index 0000000000..802b6ebe67 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/newave/newave.c @@ -0,0 +1,890 @@ +/* + + Newave - Ported from the original IrisGL SGI demo + (see https://www.sgi.com/toolbox/src/) + + I've ported an old IrisGL demo, newave, to OpenGL and GLUT. + This port has a couple of new features compared to the + "ancient" GL demo: + + * environment mapping (very cool!) + * texture mapping + * line antialiasing (needs some work) + * better wave propagation + + I haven't implemented the mesh editing found in the old demo. + + By default the program loads "texmap.rgb" and "spheremap.rgb" + if no filenames are given as command line arguments. + Specify the texture map as the first argument and the sphere + map as the second argument. + + Left mouse rotates the scene, middle mouse or +/- keys zoom, + right mouse for menu. + + Erik Larsen + cayman@sprintmail.com + +*/ + +#include +#include +#include +#include "texture.h" + +#if defined(GL_EXT_texture_object) && !defined(GL_VERSION_1_1) +#define glBindTexture(A,B) glBindTextureEXT(A,B) +#define glGenTextures(A,B) glGenTexturesEXT(A,B) +#endif +#if defined(GL_EXT_polygon_offset) && !defined(GL_VERSION_1_1) +#define glPolygonOffset(A,B) glPolygonOffsetEXT(A,B) +/* OpenGL 1.1's polygon offset can be different for each + polygon mode primitive type. The EXT extension has + only one offset. */ +#define GL_POLYGON_OFFSET_FILL GL_POLYGON_OFFSET_EXT +#endif + +typedef int bool; +#define true 1 +#define false 0 + +/* Grid */ +#define MAXGRID 63 +enum {WIREFRAME, HIDDENLINE, FLATSHADED, SMOOTHSHADED, TEXTURED}; +enum {FULLSCREEN, FACENORMALS, ANTIALIAS, ENVMAP}; +enum {WEAK, NORMAL, STRONG}; +enum {SMALL, MEDIUM, LARGE, XLARGE}; +enum {CURRENT, FLAT, SPIKE, DIAGONALWALL, SIDEWALL, HOLE, + MIDDLEBLOCK, DIAGONALBLOCK, CORNERBLOCK, HILL, HILLFOUR}; +int displayMode = WIREFRAME; +int resetMode = DIAGONALBLOCK; +int grid = 17; +float dt = 0.004; +float force[MAXGRID][MAXGRID], + veloc[MAXGRID][MAXGRID], + posit[MAXGRID][MAXGRID], + vertNorms[MAXGRID][MAXGRID][3], + faceNorms[2][MAXGRID][MAXGRID][3], + faceNormSegs[2][2][MAXGRID][MAXGRID][3]; +bool waving = false, editing = false, + drawFaceNorms = false, antialias = false, + envMap = false; +#define SQRTOFTWOINV 1.0 / 1.414213562 + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +int texWidth, texHeight; +GLubyte *texData; +char *texFilename1 = "texmap.rgb", *texFilename2 = "spheremap.rgb"; +GLuint texId1, texId2; +float texCoords[MAXGRID][MAXGRID][2]; + +/* Viewing */ +float sphi=90.0, stheta=45.0; +float sdepth = 5.0/4.0 * MAXGRID; +float zNear=15.0, zFar=100.0; +float aspect = 5.0/4.0; +long xsize, ysize; +int downX, downY; +bool leftButton = false, middleButton = false; +int i,j; +GLfloat lightPosition[] = { 0.0, 0.0, 1.0, 1.0}; +int displayMenu, otherMenu, speedMenu, sizeMenu, + resetMenu, mainMenu; + +void getforce(void) +{ + float d; + + for(i=0;i 0) + { + add( avg, avg, faceNorms[0][i-1][j] ); + add( avg, avg, faceNorms[1][i-1][j] ); + } + /* Left & above */ + if (j > 0 && i < grid-1) + { + add( avg, avg, faceNorms[0][i][j-1] ); + add( avg, avg, faceNorms[1][i][j-1] ); + } + /* Left & below */ + if (j > 0 && i > 0) + { + add( avg, avg, faceNorms[1][i-1][j-1] ); + } + + /* Normalize */ + norm( avg ); + copy( vertNorms[i][j], avg ); + } + } +} + + +void getFaceNormSegs(void) +{ + float center0[3], center1[3], normSeg0[3], normSeg1[3]; + float geom0[3], geom1[3], geom2[3], geom3[3]; + for (i = 0; i < grid - 1; ++i) + { + for (j = 0; j < grid - 1; ++j) + { + geom0[0] = i; geom0[1] = j; geom0[2] = posit[i][j]; + geom1[0] = i; geom1[1] = j+1; geom1[2] = posit[i][j+1]; + geom2[0] = i+1; geom2[1] = j; geom2[2] = posit[i+1][j]; + geom3[0] = i+1; geom3[1] = j+1; geom3[2] = posit[i+1][j+1]; + + /* find center of triangle face by averaging three vertices */ + add( center0, geom2, geom0 ); + add( center0, center0, geom1 ); + scalDiv( center0, 3.0 ); + + add( center1, geom2, geom1 ); + add( center1, center1, geom3 ); + scalDiv( center1, 3.0 ); + + /* translate normal to center of triangle face to get normal segment */ + add( normSeg0, center0, faceNorms[0][i][j] ); + add( normSeg1, center1, faceNorms[1][i][j] ); + + copy( faceNormSegs[0][0][i][j], center0 ); + copy( faceNormSegs[1][0][i][j], center1 ); + + copy( faceNormSegs[0][1][i][j], normSeg0 ); + copy( faceNormSegs[1][1][i][j], normSeg1 ); + } + } +} + +void getTexCoords(void) +{ + for (i = 0; i < grid; ++i) + { + for (j = 0; j < grid; ++j) + { + texCoords[i][j][0] = (float)j/(float)(grid-1); + texCoords[i][j][1] = (float)i/(float)(grid-1); + } + } +} + + +void wave(void) +{ + if (waving) + { + getforce(); + getvelocity(); + getposition(); + glutPostRedisplay(); + } +} + +void go(void) +{ + waving = true; + editing = false; + glutIdleFunc(wave); +} + +void stop(void) +{ + waving = false; + glutIdleFunc(NULL); +} + +void edit(void) +{ + stop(); + editing = true; +} + +void reverse(void) +{ + for(i=1;i<(grid-1);i++) + for(j=1;j<(grid-1);j++) + veloc[i][j]= -veloc[i][j]; + + if (!waving) + go(); +} + +void reset(int value) +{ + if (waving) + stop(); + + if (value != CURRENT) + resetMode = value; + for(i=0;i grid/3 && j > grid/3)&&(i < grid*2/3 && j < grid*2/3))) ? grid/4 : 0.0; + break; + case DIAGONALWALL: + posit[i][j]= (((grid-i)-j<3) && ((grid-i)-j>0)) ? grid/6 : 0.0; + break; + case SIDEWALL: + posit[i][j]= (i==1) ? grid/4 : 0.0; + break; + case DIAGONALBLOCK: + posit[i][j]= ((grid-i)-j<3) ? grid/6 : 0.0; + break; + case MIDDLEBLOCK: + posit[i][j]= ((i > grid/3 && j > grid/3)&&(i < grid*2/3 && j < grid*2/3)) ? grid/4 : 0.0; + break; + case CORNERBLOCK: + posit[i][j]= ((i > grid*3/4 && j > grid*3/4)) ? grid/4 : 0.0; + break; + case HILL: + posit[i][j]= + (sin(M_PI * ((float)i/(float)grid)) + + sin(M_PI * ((float)j/(float)grid)))* grid/6.0; + break; + case HILLFOUR: + posit[i][j]= + (sin(M_PI*2 * ((float)i/(float)grid)) + + sin(M_PI*2 * ((float)j/(float)grid)))* grid/6.0; + break; + } + if (i==0||j==0||i==grid-1||j==grid-1) posit[i][j]=0.0; + } + glutPostRedisplay(); +} + +void setSize(int value) +{ + int prevGrid = grid; + switch(value) + { + case SMALL : grid = MAXGRID/4; break; + case MEDIUM: grid = MAXGRID/2; break; + case LARGE : grid = MAXGRID/1.5; break; + case XLARGE : grid = MAXGRID; break; + } + if (prevGrid > grid) + { + reset(resetMode); + } + zNear= grid/10.0; + zFar= grid*3.0; + sdepth = 5.0/4.0 * grid; + getTexCoords(); + glutPostRedisplay(); +} + +void setSpeed(int value) +{ + switch(value) + { + case WEAK : dt = 0.001; break; + case NORMAL: dt = 0.004; break; + case STRONG: dt = 0.008; break; + } +} + +void setDisplay(int value) +{ + displayMode = value; + switch(value) + { + case WIREFRAME : + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + break; + case HIDDENLINE: + glShadeModel(GL_FLAT); + glDisable(GL_LIGHTING); + break; + case FLATSHADED : + glShadeModel(GL_FLAT); + glEnable(GL_LIGHTING); + break; + case SMOOTHSHADED: + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + break; + case TEXTURED: + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + break; + } + glutPostRedisplay(); +} + +void setOther(int value) +{ + switch (value) + { + case FULLSCREEN: + glutFullScreen(); + break; + case FACENORMALS: + drawFaceNorms = !drawFaceNorms; + break; + case ANTIALIAS: + antialias = !antialias; + if (antialias) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_LINE_SMOOTH); + glLineWidth(1.5); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + glLineWidth(1.0); + } + break; + case ENVMAP: + envMap = !envMap; + if (envMap) + { + glBindTexture(GL_TEXTURE_2D, texId2); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + else + { + glBindTexture(GL_TEXTURE_2D, texId1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } + break; + } + glutPostRedisplay(); +} + +void setMain(int value) +{ + switch(value) + { + case 1: edit(); break; + case 2: go(); break; /* set idle func to something */ + case 3: stop(); break; /* set idle func to null */ + case 4: reverse(); break; + case 5: exit(0); break; + } +} + + +void drawFaceNormals(void) +{ + glColor3f(1.0,1.0,1.0); + for (i = 0; i < grid - 1; ++i) + { + for (j = 0; j < grid - 1; ++j) + { + glBegin(GL_LINES); + glVertex3fv(faceNormSegs[0][0][i][j]); + glVertex3fv(faceNormSegs[0][1][i][j]); + glEnd(); + + glBegin(GL_LINES); + glVertex3fv(faceNormSegs[1][0][i][j]); + glVertex3fv(faceNormSegs[1][1][i][j]); + glEnd(); + } + } +} + +void drawSmoothShaded(void) +{ + glColor3f(0.8f, 0.2f, 0.8f); + for (i = 0; i < grid - 1; ++i) + { + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < grid; ++j) + { + glNormal3fv( vertNorms[i][j] ); + glVertex3f( i, j, posit[i][j] ); + glNormal3fv( vertNorms[i+1][j] ); + glVertex3f( i+1, j, posit[i+1][j] ); + } + glEnd(); + } +} + +void drawWireframe(void) +{ + glColor3f(1.0, 1.0, 1.0); + + for(i=0;i 1 && argv[1] != 0) + texFilename1 = argv[1]; + if (argc > 2 && argv[2] != 0) + texFilename2 = argv[2]; + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glClearColor(0.0, 0.0, 0.0, 0.0); + glPolygonOffset(1.0, 1.0); + glEnable(GL_CULL_FACE); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT, GL_DIFFUSE); + glLightfv (GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHT0); + loadImageTexture(); + + setSize(MEDIUM); + setSpeed(NORMAL); + setDisplay(TEXTURED); + setOther(ENVMAP); + reset(HILLFOUR); + + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutVisibilityFunc(visibility); + + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + displayMenu = glutCreateMenu(setDisplay); + glutAddMenuEntry("Wireframe", WIREFRAME); + glutAddMenuEntry("Hidden Line", HIDDENLINE); + glutAddMenuEntry("Flat Shaded", FLATSHADED); + glutAddMenuEntry("Smooth Shaded", SMOOTHSHADED); + glutAddMenuEntry("Textured", TEXTURED); + + otherMenu = glutCreateMenu(setOther); + glutAddMenuEntry("Full Screen", FULLSCREEN); + glutAddMenuEntry("Face Normals", FACENORMALS); + glutAddMenuEntry("Antialias", ANTIALIAS); + glutAddMenuEntry("Environment Map", ENVMAP); + + speedMenu = glutCreateMenu(setSpeed); + glutAddMenuEntry("Weak", WEAK); + glutAddMenuEntry("Normal", NORMAL); + glutAddMenuEntry("Strong", STRONG); + + sizeMenu = glutCreateMenu(setSize); + glutAddMenuEntry("Small", SMALL); + glutAddMenuEntry("Medium", MEDIUM); + glutAddMenuEntry("Large", LARGE); + glutAddMenuEntry("Extra Large", XLARGE); + + resetMenu = glutCreateMenu(reset); + glutAddMenuEntry("Current", CURRENT); + glutAddMenuEntry("Spike", SPIKE); + glutAddMenuEntry("Hole", HOLE); + glutAddMenuEntry("Diagonal Wall", DIAGONALWALL); + glutAddMenuEntry("Side Wall", SIDEWALL); + glutAddMenuEntry("Middle Block", MIDDLEBLOCK); + glutAddMenuEntry("Diagonal Block", DIAGONALBLOCK); + glutAddMenuEntry("Corner Block", CORNERBLOCK); + glutAddMenuEntry("Hill", HILL); + glutAddMenuEntry("Hill Four", HILLFOUR); + + mainMenu = glutCreateMenu(setMain); + glutAddMenuEntry("Go", 2); + glutAddMenuEntry("Stop", 3); + glutAddMenuEntry("Reverse", 4); + glutAddSubMenu("Display", displayMenu); + glutAddSubMenu("Reset", resetMenu); + glutAddSubMenu("Size", sizeMenu); + glutAddSubMenu("Speed", speedMenu); + glutAddSubMenu("Other", otherMenu); + glutAddMenuEntry("Exit", 5); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; /* ANSI C requires main to return int. */ +} + + diff --git a/lib/glut-3.7.6/progs/demos/newave/newave.dsp b/lib/glut-3.7.6/progs/demos/newave/newave.dsp new file mode 100644 index 0000000000..6aaf004716 --- /dev/null +++ b/lib/glut-3.7.6/progs/demos/newave/newave.dsp @@ -0,0 +1,96 @@ +# Microsoft Developer Studio Project File - Name="newave" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=newave - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "newave.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "newave.mak" CFG="newave - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "newave - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "newave - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "newave - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "newave - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "newave - Win32 Release" +# Name "newave - Win32 Debug" +# Begin Source File + +SOURCE=.\newave.c +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\texture.h +# End Source File +# End Target +# End Project diff --git a/lib/glut-3.7.6/progs/demos/newave/spheremap.rgb b/lib/glut-3.7.6/progs/demos/newave/spheremap.rgb new file mode 100644 index 0000000000000000000000000000000000000000..87665fb5dbe374cd8fc6d83dc0372ac9cc0d4444 GIT binary patch literal 143414 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