pax_global_header00006660000000000000000000000064143751453410014521gustar00rootroot0000000000000052 comment=248ee43ea3ae10abb775f7b05e52866aa526db8e lablgl-1.07/000077500000000000000000000000001437514534100127055ustar00rootroot00000000000000lablgl-1.07/.cvsignore000066400000000000000000000000201437514534100146750ustar00rootroot00000000000000Makefile.config lablgl-1.07/CHANGES000066400000000000000000000070711437514534100137050ustar00rootroot00000000000000LablGL 1.07: ------------ 2023-02-21: * Update Makefile.config.osx [Jacques] * Add support for OCaml 5.0.0 (#3) [Kate Deplaix] 2022-04-21: * Activate CAML_NAME_SPACE (#2) [Kate Deplaix] LablGL 1.06: ------------ 2019-08-07: * remove dependency on camlp4/camlp5 for installation (only use camlp5 during development to generate stream parsers) * fix stdlib deprecations LablGL 1.05: ------------ 2013-09-20: * make it work with the OCaml 4.01 windows installer (both lablglut and togl) 2013-09-11: * add configuration file for Ubuntu 2012-10-18: * allow building with make -j 2012-06-05: * switch to Togl 1.7, doesn't need Tk internals anymore 2012-03-06: * add `bgr and `bgra to Gl.format and GlTex.format (reported by Vu Ngoc San) 2010-06-16: * fix Glut.special_of_int to raise no exception (reported by malc) 2010-03-11: * merge glShader support by Florent Monnier LablGL 1.04: ------------ 2008-12-21: * support windows compilation for ocaml 3.11 2008-10-25: * support Tcl/Tk 8.5 * require Raw.static in GlArray (reported by malc) * check for GL_ARB_texture_non_power_of_two in GlTex (reported by malc) 2008-01-10: * fix GlMap.eval_coord2 (reported by Florent Monnier) LablGL 1.03: --------------------- 2007-04-13: [Jacques] * add glPolygonOffset * fix Glut.createMenu * fix GlTex.gen_textures 2006-07-29: [Jacques] * make LablGlut's callback window dependent * simplify glutInit 2006-03-23: [Jacques] * avoid all uses of stderr in stubs (caused incompatibilities) * use mingw import libraries * mingw build works again (but togl only works in dll mode) LablGL 1.02: ------------ 2005-10-28: [Jacques] * fix GlMat.mult_transpose (Gregory Guyomarc'h) 2005-10-20: [Jacques] * correct GlTex.image2d border bug (Eric Cooper) 2005-10-14: [Jacques] * add glGetError 2004-07-20: [Jacques] * add index_logic_op and color_logic_op LablGL 1.01: ------------ 2004-07-13: [Jacques] * merge Jon Harrop's tesselator support LablGL 1.00: ------------ 2003-10-01: [Jacques] * split togl, move examples to Togl/examples * add mingw support 2003-09-29: [Jacques] * reorganized directories and Makefiles 2003-09-25: [Christophe] * merge ijtrotts' LablGlut 2003-09-24: [Christophe] * add glArray support LablGL 0.99: ------------ * add texture binding functions, contributed by Chris Hecker * add support for Tcl/Tk8.4 * allow compiling and installing without Tk LablGL 0.98: ------------ * add windows port * add lablGL.spec (Ben Martin) * add GLU_VERSION and GLU_EXTENSIONS tags * check returned strings LablGL 0.97: ------------ * support ocaml 3.04 LablGL 0.96: ------------ * adapt to new label mode / new variant syntax * split library into lablgl.cma and togl.cma to support ocaml dynamic linking LablGL 0.95: ------------ * corrected variant matching for Objective Caml 3.01 * add variance annotations * some bug fixes LablGL 0.94: ------------ * corrected syntax for Objective Caml 3.00 LablGL 0.93: ------------ * use Objective Caml 2.99 instead of Objective Label. * a few functions changed, to comply with the new semantics for optional arguments. * togl.cmo is not included in lablgl.cma, to allow easy linking with lablgtk. LablGL 0.92: ------------ * allow use of newer patch levels for Tk. * corrected bugs in the Raw module. Now, it handles correctly alignment constraints on doubles. * added the Raw.sub function, which extracts a slice from an existing raw array. Values are still physically shared with the original array. LablGL 0.91: ------------ * switched to Togl-1.5. The previous versions had problems on Linux. LablGL 0.9: ----------- * first public release lablgl-1.07/COPYRIGHT000066400000000000000000000027351437514534100142070ustar00rootroot00000000000000Copyright (c) 1997-2001 Jacques Garrigue and Kyoto University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lablgl-1.07/LablGlut/000077500000000000000000000000001437514534100144135ustar00rootroot00000000000000lablgl-1.07/LablGlut/COPYRIGHT000066400000000000000000000033251437514534100157110ustar00rootroot00000000000000LablGLUT, copyright (c) 2003 Issac Trotts. All rights reserved. This copyright does not apply to any of the bundled demos by Mike Kilgard or others, nor to the (modified) code by Hugues Casse contained in the c2ml directory, nor to the (modified) code by Xavier Leroy contained in the camlidl directory. Many of the demos are derived from original C sources in Mark Kilgard's GLUT distribution. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lablgl-1.07/LablGlut/ChangeLog000066400000000000000000000142011437514534100161630ustar00rootroot000000000000002002-09-11 Issac Trotts * examples/glut3.7/test/joy_test.ml, examples/glut3.7/test/test10.ml, examples/glut3.7/test/test2.ml, examples/glut3.7/test/test26.ml, examples/glut3.7/test/test4.ml, examples/glut3.7/test/test8.ml: updated calls to Glut.idleFunc * lablGL-0.98/gl_tags.var, lablGL-0.98/gluMat.ml, lablGL-0.98/gluMat.mli, lablGL-0.98/gluMisc.ml, lablGL-0.98/gluMisc.mli, lablGL-0.98/gluNurbs.ml, lablGL-0.98/gluNurbs.mli, lablGL-0.98/gluQuadric.ml, lablGL-0.98/gluQuadric.mli, lablGL-0.98/gluTess.ml, lablGL-0.98/gluTess.mli, lablGL-0.98/glu_tags.var, lablGL-0.98/lablGL.spec, lablGL-0.98/lablgl.bat, lablGL-0.98/lablgl.in, lablGL-0.98/ml_gl.c, lablGL-0.98/ml_gl.h, lablGL-0.98/ml_glu.c, lablGL-0.98/ml_raw.c, lablGL-0.98/ml_raw.h, lablGL-0.98/raw.ml, lablGL-0.98/raw.mli, lablGL-0.98/raw_tags.var, lablGL-0.98/var2def.ml, lablGL-0.98/var2switch.ml, lablGL-0.98/.cvsignore, lablGL-0.98/.depend, lablGL-0.98/CHANGES, lablGL-0.98/COPYRIGHT, lablGL-0.98/Makefile, lablGL-0.98/Makefile.config, lablGL-0.98/Makefile.config.ex, lablGL-0.98/README, lablGL-0.98/gl.ml, lablGL-0.98/gl.mli, lablGL-0.98/glClear.ml, lablGL-0.98/glClear.mli, lablGL-0.98/glDraw.ml, lablGL-0.98/glDraw.mli, lablGL-0.98/glFunc.ml, lablGL-0.98/glFunc.mli, lablGL-0.98/glLight.ml, lablGL-0.98/glLight.mli, lablGL-0.98/glList.ml, lablGL-0.98/glList.mli, lablGL-0.98/glMap.ml, lablGL-0.98/glMap.mli, lablGL-0.98/glMat.ml, lablGL-0.98/glMat.mli, lablGL-0.98/glMisc.ml, lablGL-0.98/glMisc.mli, lablGL-0.98/glPix.ml, lablGL-0.98/glPix.mli, lablGL-0.98/glTex.ml, lablGL-0.98/glTex.mli, examples/glut3.7/trackball/Makefile, examples/glut3.7/trackball/teaspin.ml, examples/glut3.7/test/joy_test.ml, examples/glut3.7/test/keyup_test.ml, examples/glut3.7/test/menu_test.ml, examples/glut3.7/test/shape_test.ml, examples/glut3.7/test/test1.ml, examples/glut3.7/test/test10.ml, examples/glut3.7/test/test11.ml, examples/glut3.7/test/test12.ml, examples/glut3.7/test/test13.ml, examples/glut3.7/test/test14.ml, examples/glut3.7/test/test15.ml, examples/glut3.7/test/test16.ml, examples/glut3.7/test/test17.ml, examples/glut3.7/test/test18.ml, examples/glut3.7/test/test19.ml, examples/glut3.7/test/test2.ml, examples/glut3.7/test/test20.ml, examples/glut3.7/test/test21.ml, examples/glut3.7/test/test22.ml, examples/glut3.7/test/test23.ml, examples/glut3.7/test/test24.ml, examples/glut3.7/test/test25.ml, examples/glut3.7/test/test26.ml, examples/glut3.7/test/test27.ml, examples/glut3.7/test/test28.ml, examples/glut3.7/test/test3.ml, examples/glut3.7/test/test4.ml, examples/glut3.7/test/test7.ml, examples/glut3.7/test/test8.ml, examples/glut3.7/test/test9.ml, examples/glut3.7/test/timer_test.ml, examples/glut3.7/test/cursor_test.ml, examples/nehe/lesson2.ml, examples/nehe/lesson3.ml, examples/nehe/lesson4.ml, examples/nehe/lesson5.ml, examples/etc/draw2d.ml, examples/lablGL/README, examples/lablGL/checker.ml, examples/lablGL/gears, examples/lablGL/gears.ml, examples/lablGL/morph3d.ml, examples/lablGL/planet.ml, examples/lablGL/scene.ml, examples/lablGL/simple.ml, examples/lablGL/texturesurf.ml, examples/checker.ml, examples/gears.ml, examples/morph3d.ml, examples/planet.ml, examples/scene.ml, examples/simple.ml, examples/texturesurf.ml: . * src_lablglut/ml_glut.h, src_lablglut/ml_raw.h: changed glutIdleFunc to take a function option so we can have a null idle function and not burn up the cpu * src_lablglut/ezgl.mli, src_lablglut/ezglut, src_lablglut/ezgl.ml: . 2002-09-02 Issac Trotts * examples/glut3.7/trackball/Makefile, examples/glut3.7/trackball/teaspin.ml, examples/glut3.7/trackball/trackball.ml, examples/glut3.7/trackball/trackball.mli: . * examples/glut3.7/not_yet_ported/Makefile, examples/glut3.7/not_yet_ported/teaspin.ml, examples/glut3.7/not_yet_ported/trackball.c, examples/glut3.7/not_yet_ported/trackball.h, examples/glut3.7/not_yet_ported/trackball.ml, examples/glut3.7/not_yet_ported/trackball.mli: removed some files * examples/glut3.7/not_yet_ported/teaspin.ml: - colored lights - "Spin me" * examples/glut3.7/not_yet_ported/teaspin.ml: - disabled back-face culling, so now the teapot renders correctly * examples/glut3.7/not_yet_ported/Makefile, examples/glut3.7/not_yet_ported/teaspin.ml: Got teaspin to work, though it's still rough around the edges. * examples/glut3.7/not_yet_ported/Makefile, examples/glut3.7/not_yet_ported/dinospin.c, examples/glut3.7/not_yet_ported/dinospin.ml, examples/glut3.7/not_yet_ported/scube.c, examples/glut3.7/not_yet_ported/scube.ml, examples/glut3.7/not_yet_ported/splatlogo.c, examples/glut3.7/not_yet_ported/splatlogo.ml, examples/glut3.7/not_yet_ported/spots.c, examples/glut3.7/not_yet_ported/spots.ml, examples/glut3.7/not_yet_ported/stars.c, examples/glut3.7/not_yet_ported/stars.ml, examples/glut3.7/not_yet_ported/teaspin.ml, examples/glut3.7/not_yet_ported/trackball.c, examples/glut3.7/not_yet_ported/trackball.h, examples/glut3.7/not_yet_ported/trackball.ml, examples/glut3.7/not_yet_ported/trackball.mli: . 2002-09-01 Issac Trotts * THANKS, lgcompile, lgport.py: . 2002-07-26 Issac Trotts * examples/README, examples/checker.ml, examples/gears.ml, examples/morph3d.ml, examples/planet.ml, examples/scene.ml, examples/simple.ml, examples/texturesurf.ml: New file. * examples/README, examples/checker.ml, examples/gears.ml, examples/morph3d.ml, examples/planet.ml, examples/scene.ml, examples/simple.ml, examples/texturesurf.ml: just getting started. * CHANGES, COPYRIGHT, README, TODO, build, src_lablglut/Makefile, src_lablglut/OCamlMakefile, src_lablglut/ezgl.ml, src_lablglut/ezgl.mli, src_lablglut/ezglut, src_lablglut/glut.ml, src_lablglut/glut.mli, src_lablglut/wrap_gl.c, src_lablglut/wrap_glut.c, toplevel_lablglut/Makefile, toplevel_lablglut/OCamlMakefile, toplevel_lablglut/lablglut: New file. * CHANGES, COPYRIGHT, README, TODO, build, src_lablglut/Makefile, src_lablglut/OCamlMakefile, src_lablglut/ezgl.ml, src_lablglut/ezgl.mli, src_lablglut/ezglut, src_lablglut/glut.ml, src_lablglut/glut.mli, src_lablglut/wrap_gl.c, src_lablglut/wrap_glut.c, toplevel_lablglut/Makefile, toplevel_lablglut/OCamlMakefile, toplevel_lablglut/lablglut: just getting started. lablgl-1.07/LablGlut/README000066400000000000000000000016421437514534100152760ustar00rootroot00000000000000*LablGLUT* A GLUT Binding for OCaml Last change: 2003 Oct 22 LablGLUT Issac Trotts ijtrotts@ucdavis.edu with nehe demo ports by Jeffrey Palmer Introduction ============ The LablGLUT library is an OCaml binding for GLUT version 3.7. GLUT (GL Utility Toolkit) is a portable windowing library for OpenGL, written by Mark Kilgard. GLUT tends to be easier to install and use than other OpenGL windowing alternatives. It is very portable, depending only on libraries for OpenGL and the underlying window system. Installation ============ The easy way is to become root and say ./build all opt install clean test Otherwise it's necessary to modify installation targets in the Makefiles. License ======= LablGLUT is under a BSD-style license. lablgl-1.07/LablGlut/THANKS000066400000000000000000000012661437514534100153330ustar00rootroot00000000000000 THANKS TO - Jeffrey Palmer for contributing the nehe demo ports - Mark Kilgard for creating GLUT - Jacques Garrigue for writing LablGL - Markus Mottl for writing OCamlMakefile - Hugues Casse for writing FrontC, the basis for the program c2ml included with LablGLUT. This program was very helpful in porting the original GLUT demos written in C. - Xavier Leroy for writing Camlidl, a wrapper generator for OCaml. LablGLUT comes with a modified version of Camlidl that can handle [bigarray,in] void* arguments, as well as arrays of GLdoubles and GLfloats. Camlidl was used to write LablGLUT's simplified bindings for GL and GLU. - The OCaml team lablgl-1.07/LablGlut/TODO000066400000000000000000000000621437514534100151010ustar00rootroot00000000000000- port lots of demos - add reading of .pnm files lablgl-1.07/LablGlut/examples/000077500000000000000000000000001437514534100162315ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/README000066400000000000000000000001321437514534100171050ustar00rootroot00000000000000$Id: README,v 1.2 2003-09-26 08:25:07 garrigue Exp $ Here are a few examples for LablGL. lablgl-1.07/LablGlut/examples/caml-images/000077500000000000000000000000001437514534100204105ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/caml-images/ChangeLog000066400000000000000000000013371437514534100221660ustar00rootroot000000000000002002-09-20 Issac Trotts * main.ml: Added a check so we don't do the expensive rescale unless we have to. * main.ml: Fixed up the aspect ratio. * main.ml: Added rescaling to next highest power of two along each axis. Changed texture coordinates so the image no longer appears rotated by 90 deg. * main.ml: Added conversion from camlimages to lablGL's preferred raw format. In order to make the image a power of two, I truncate the image. This needs to be replaced with scaling up to the next largest power of two and rescaling the square to have the proper aspect ratio. * .Makefile.swp: . * .Makefile.swp, Makefile, OCamlMakefile, main.ml: Just displays a checkerboard at the moment. lablgl-1.07/LablGlut/examples/caml-images/Makefile000066400000000000000000000005071437514534100220520ustar00rootroot00000000000000include $(OCAML)/camlimages/Makefile.config all: dc RESULT=ciglut SOURCES=main.ml LIBS=lablgl lablglut INCDIRS=+camlimages +lablGL +lablglut OCAMLFLAGS=$(COMPFLAGS_CAMLIMAGES) #OCAMLLDFLAGS=$(COMPFLAGS_CAMLIMAGES) $(LINKFLAGS_CAMLIMAGES) OCAMLLDFLAGS=$(COMPFLAGS_CAMLIMAGES) $(LINKFLAGS_CAMLIMAGES) include ./OCamlMakefile lablgl-1.07/LablGlut/examples/caml-images/OCamlMakefile000066400000000000000000000452721437514534100227760ustar00rootroot00000000000000########################################################################### # OCamlMakefile # Copyright (C) 1999-2002 Markus Mottl # # For updates see: # http://www.oefai.at/~markus/ocaml_sources # # $Id: OCamlMakefile,v 1.1 2003-09-25 13:54:01 raffalli Exp $ # ########################################################################### # Set these variables to the names of the sources to be processed and # the result variable. Order matters during linkage! ifndef SOURCES SOURCES := foo.ml endif export SOURCES ifndef RES_CLIB_SUF RES_CLIB_SUF := _stubs endif export RES_CLIB_SUF ifndef RESULT RESULT := foo endif export RESULT ifndef DOC_FILES DOC_FILES := $(filter %.mli, $(SOURCES)) endif export DOC_FILES export BCSUFFIX export NCSUFFIX ifndef TOPSUFFIX TOPSUFFIX := .top endif export TOPSUFFIX # Eventually set include- and library-paths, libraries to link, # additional compilation-, link- and ocamlyacc-flags # Path- and library information needs not be written with "-I" and such... # Define THREADS if you need it, otherwise leave it unset (same for # USE_CAMLP4)! export THREADS export USE_CAMLP4 export INCDIRS export LIBDIRS export OCAML_DEFAULT_DIRS export OCAML_LIB_INSTALL export LIBS export CLIBS export OCAMLFLAGS export OCAMLNCFLAGS export OCAMLBCFLAGS export OCAMLLDFLAGS export OCAMLNLDFLAGS export OCAMLBLDFLAGS ifndef OCAMLCPFLAGS OCAMLCPFLAGS := a endif export OCAMLCPFLAGS export YFLAGS export IDLFLAGS export OCAMLDOCFLAGS export DVIPSFLAGS export STATIC # Add a list of optional trash files that should be deleted by "make clean" export TRASH #################### variables depending on your OCaml-installation ifdef MINGW export MINGW WIN32 := 1 endif ifdef MSVC export MSVC WIN32 := 1 EXT_OBJ := obj EXT_LIB := lib ifeq ($(CC),gcc) # work around GNU Make default value CC := cl endif ifeq ($(CXX),g++) # work around GNU Make default value CXX := cl endif CFLAG_O := -Fo endif ifdef WIN32 EXT_CXX := cpp EXE := .exe endif ifndef EXT_OBJ EXT_OBJ := o endif ifndef EXT_LIB EXT_LIB := a endif ifndef EXT_CXX EXT_CXX := cc endif ifndef EXE EXE := # empty endif ifndef CFLAG_O CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)! endif export CC export CXX export CFLAGS export CXXFLAGS export LDFLAGS BCRESULT := $(addsuffix $(BCSUFFIX), $(RESULT)) NCRESULT := $(addsuffix $(NCSUFFIX), $(RESULT)) TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT)) ifndef OCAMLC OCAMLC := ocamlc endif export OCAMLC ifndef OCAMLOPT OCAMLOPT := ocamlopt endif export OCAMLOPT ifndef OCAMLMKTOP OCAMLMKTOP := ocamlmktop endif export OCAMLMKTOP ifndef OCAMLCP OCAMLCP := ocamlcp endif export OCAMLCP ifndef OCAMLDEP OCAMLDEP := ocamldep endif export OCAMLDEP ifndef OCAMLLEX OCAMLLEX := ocamllex endif export OCAMLLEX ifndef OCAMLYACC OCAMLYACC := ocamlyacc endif export OCAMLYACC ifndef CAMLIDL CAMLIDL := camlidl endif export CAMLIDL ifndef CAMLIDLDLL CAMLIDLDLL := camlidldll endif export CAMLIDLDLL ifndef NOIDLHEADER MAYBE_IDL_HEADER := -header endif export NOIDLHEADER ifndef CAMLP4 CAMLP4 := camlp4 endif export CAMLP4 ifndef OCAMLDOC OCAMLDOC := ocamldoc endif export OCAMLDOC ifndef LATEX LATEX := latex endif export LATEX ifndef DVIPS DVIPS := dvips endif export DVIPS ifndef PS2PDF PS2PDF := ps2pdf endif export PS2PDF ifndef OCAMLMAKEFILE OCAMLMAKEFILE := OCamlMakefile endif export OCAMLMAKEFILE ifndef OCAMLLIBPATH OCAMLLIBPATH := \ $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/local/lib/ocaml) endif export OCAMLLIBPATH ifndef OCAML_LIB_INSTALL OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib endif export OCAML_LIB_INSTALL ########################################################################### #################### change following sections only if #################### you know what you are doing! # for pedants using "--warn-undefined-variables" export MAYBE_IDL export REAL_RESULT export CAMLIDLFLAGS export THREAD_FLAG export RES_CLIB export MAKEDLL SHELL := /bin/sh MLDEPDIR := ._d BCDIDIR := ._bcdi NCDIDIR := ._ncdi FILTERED := $(filter %.mli %.ml %.mll %.mly %.idl %.c %.$(EXT_CXX), \ $(SOURCES)) SOURCE_DIRS := $(filter-out ./, $(sort $(dir $(FILTERED)))) FILTERED_ML := $(filter %.ml, $(FILTERED)) DEP_ML := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d) FILTERED_MLI := $(filter %.mli, $(FILTERED)) DEP_MLI := $(FILTERED_MLI:.mli=.di) FILTERED_MLL := $(filter %.mll, $(FILTERED)) DEP_MLL := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d) AUTO_MLL := $(FILTERED_MLL:.mll=.ml) FILTERED_MLY := $(filter %.mly, $(FILTERED)) DEP_MLY := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di) AUTO_MLY := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml) FILTERED_IDL := $(filter %.idl, $(FILTERED)) DEP_IDL := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di) C_IDL := $(FILTERED_IDL:%.idl=%_stubs.c) $(FILTERED_IDL:.idl=.h) OBJ_C_IDL := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ)) AUTO_IDL := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL) FILTERED_C_CXX := $(filter %.c %.$(EXT_CXX), $(FILTERED)) OBJ_C_CXX := $(FILTERED_C_CXX:.c=.$(EXT_OBJ)) OBJ_C_CXX := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ)) PRE_TARGETS += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) ALL_DEPS := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) MLDEPS := $(filter %.d, $(ALL_DEPS)) MLIDEPS := $(filter %.di, $(ALL_DEPS)) BCDEPIS := $(MLIDEPS:%.di=$(BCDIDIR)/%.di) NCDEPIS := $(MLIDEPS:%.di=$(NCDIDIR)/%.di) ALLML := $(filter %.mli %.ml %.mll %.mly %.idl, $(FILTERED)) IMPLO_INTF := $(ALLML:%.mli=%.mli.__) IMPLO_INTF := $(foreach file, $(IMPLO_INTF), \ $(basename $(file)).cmi $(basename $(file)).cmo) IMPLO_INTF := $(filter-out %.mli.cmo, $(IMPLO_INTF)) IMPLO_INTF := $(IMPLO_INTF:%.mli.cmi=%.cmi) IMPLX_INTF := $(IMPLO_INTF:.cmo=.cmx) INTF := $(filter %.cmi, $(IMPLO_INTF)) IMPL_CMO := $(filter %.cmo, $(IMPLO_INTF)) IMPL_CMX := $(IMPL_CMO:.cmo=.cmx) OBJ_LINK := $(OBJ_C_IDL) $(OBJ_C_CXX) OBJ_FILES := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK) EXECS := $(addsuffix $(EXE), \ $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT))) ifdef WIN32 EXECS += $(BCRESULT).dll $(NCRESULT).dll endif CLIB_BASE := $(RESULT)$(RES_CLIB_SUF) ifneq ($(strip $(OBJ_LINK)),) RES_CLIB := lib$(CLIB_BASE).$(EXT_LIB) endif DLLSONAME := dll$(CLIB_BASE).so NONEXECS := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(OBJ_FILES) $(PRE_TARGETS) \ $(BCRESULT).cma $(NCRESULT).cmxa $(NCRESULT).$(EXT_LIB) \ $(RES_CLIB) $(DLLSONAME) ifndef LIBINSTALL_FILES LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \ $(RESULT).cmxa $(RESULT).a $(RES_CLIB) $(DLLSONAME) endif export LIBINSTALL_FILES ifdef WIN32 # some extra stuff is created while linking DLLs NONEXECS += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp endif TARGETS := $(EXECS) $(NONEXECS) # If there are IDL-files ifneq ($(strip $(FILTERED_IDL)),) MAYBE_IDL := -cclib -lcamlidl endif ifdef USE_CAMLP4 CAMLP4PATH := \ $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/local/lib/camlp4) INCFLAGS := -I $(CAMLP4PATH) CINCFLAGS := -I$(CAMLP4PATH) endif INCFLAGS += $(SOURCE_DIRS:%=-I %) $(INCDIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %) CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%) CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) $(OCAML_DEFAULT_DIRS:%=-L%) ifndef PROFILING INTF_OCAMLC := $(OCAMLC) else ifndef THREADS INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS) else # OCaml does not support profiling byte code # with threads (yet), therefore we force an error. ifndef REAL_OCAMLC $(error Profiling of multithreaded byte code not yet supported by OCaml) endif endif endif ifndef MSVC COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \ $(LIBDIRS:%=-ccopt -L%) $(OCAML_DEFAULT_DIRS:%=-ccopt -L%) else # currenly MSVC-build ocamlc/ocamlopt cannot pass any option to C linker :-( COMMON_LDFLAGS := endif ifndef MSVC CLIBS_OPTS := $(CLIBS:%=-cclib -l%) else # MSVC libraries do not have 'lib' prefix CLIBS_OPTS := $(CLIBS:%=-ccopt %) endif ifneq ($(strip $(OBJ_LINK)),) ifdef CREATE_LIB OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL) else OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL) endif else OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL) endif # If we have to make byte-code ifndef REAL_OCAMLC SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS) REAL_OCAMLC := $(INTF_OCAMLC) REAL_IMPL := $(IMPL_CMO) REAL_IMPL_INTF := $(IMPLO_INTF) IMPL_SUF := .cmo DEPFLAGS := MAKE_DEPS := $(MLDEPS) $(BCDEPIS) ifdef CREATE_LIB ifndef STATIC ifneq ($(strip $(OBJ_LINK)),) MAKEDLL := $(DLLSONAME) ALL_LDFLAGS := -dllib $(DLLSONAME) endif endif endif ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS))" "" ALL_LDFLAGS += -custom endif ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \ $(COMMON_LDFLAGS) $(LIBS:%=%.cma) CAMLIDLDLLFLAGS := ifdef THREADS ALL_LDFLAGS += -thread unix.cma threads.cma THREAD_FLAG := -thread endif # we have to make native-code else ifndef PROFILING SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS) PLDFLAGS := else SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS) PLDFLAGS := -p endif REAL_IMPL := $(IMPL_CMX) REAL_IMPL_INTF := $(IMPLX_INTF) IMPL_SUF := .cmx CFLAGS := -DNATIVE_CODE $(CFLAGS) DEPFLAGS := -native MAKE_DEPS := $(MLDEPS) $(NCDEPIS) ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \ $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS) CAMLIDLDLLFLAGS := -opt ifndef CREATE_LIB ALL_LDFLAGS += $(LIBS:%=%.cmxa) endif ifdef THREADS ALL_LDFLAGS := -thread $(ALL_LDFLAGS) ifndef CREATE_LIB ALL_LDFLAGS += unix.cmxa threads.cmxa endif THREAD_FLAG := -thread endif endif ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(OCAMLFLAGS) \ $(INCFLAGS) $(SPECIAL_OCAMLFLAGS) ifdef make_deps -include $(MAKE_DEPS) PRE_TARGETS := endif ########################################################################### # USER RULES # generates byte-code (default) byte-code: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ REAL_RESULT="$(BCRESULT)" make_deps=yes bc: byte-code byte-code-nolink: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ REAL_RESULT="$(BCRESULT)" make_deps=yes bcnl: byte-code-nolink top: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \ REAL_RESULT="$(BCRESULT)" make_deps=yes # generates native-code native-code: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ REAL_RESULT="$(NCRESULT)" \ REAL_OCAMLC="$(OCAMLOPT)" \ make_deps=yes nc: native-code native-code-nolink: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ REAL_RESULT="$(NCRESULT)" \ REAL_OCAMLC="$(OCAMLOPT)" \ make_deps=yes ncnl: native-code-nolink # generates byte-code libraries byte-code-library: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(BCRESULT).cma \ REAL_RESULT="$(BCRESULT)" \ CREATE_LIB=yes \ make_deps=yes bcl: byte-code-library # generates native-code libraries native-code-library: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(NCRESULT).cmxa \ REAL_RESULT="$(NCRESULT)" \ REAL_OCAMLC="$(OCAMLOPT)" \ CREATE_LIB=yes \ make_deps=yes ncl: native-code-library ifdef WIN32 # generates byte-code dll byte-code-dll: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(BCRESULT).dll \ REAL_RESULT="$(BCRESULT)" \ make_deps=yes bcd: byte-code-dll # generates native-code dll native-code-dll: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(NCRESULT).dll \ REAL_RESULT="$(NCRESULT)" \ REAL_OCAMLC="$(OCAMLOPT)" \ make_deps=yes ncd: native-code-dll endif # generates byte-code with debugging information debug-code: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ REAL_RESULT="$(BCRESULT)" make_deps=yes \ OCAMLFLAGS="-g $(OCAMLFLAGS)" \ OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" dc: debug-code # generates byte-code libraries with debugging information debug-code-library: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(BCRESULT).cma \ REAL_RESULT="$(BCRESULT)" make_deps=yes \ CREATE_LIB=yes \ OCAMLFLAGS="-g $(OCAMLFLAGS)" \ OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" dcl: debug-code-library # generates byte-code for profiling profiling-byte-code: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ REAL_RESULT="$(BCRESULT)" PROFILING="y" \ make_deps=yes pbc: profiling-byte-code # generates native-code profiling-native-code: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ REAL_RESULT="$(NCRESULT)" \ REAL_OCAMLC="$(OCAMLOPT)" \ PROFILING="y" \ make_deps=yes pnc: profiling-native-code # generates byte-code libraries profiling-byte-code-library: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(BCRESULT).cma \ REAL_RESULT="$(BCRESULT)" PROFILING="y" \ CREATE_LIB=yes \ make_deps=yes pbcl: profiling-byte-code-library # generates native-code libraries profiling-native-code-library: $(PRE_TARGETS) @$(MAKE) -r -f $(OCAMLMAKEFILE) \ $(RES_CLIB) $(NCRESULT).cmxa \ REAL_RESULT="$(NCRESULT)" PROFILING="y" \ REAL_OCAMLC="$(OCAMLOPT)" \ CREATE_LIB=yes \ make_deps=yes pncl: profiling-native-code-library # generates HTML-documentation htdoc: doc/html # generates Latex-documentation ladoc: doc/latex # generates PostScript-documentation psdoc: doc/latex/doc.ps # generates PDF-documentation pdfdoc: doc/latex/doc.pdf # generates all supported forms of documentation doc: htdoc ladoc psdoc pdfdoc ########################################################################### # LOW LEVEL RULES $(REAL_RESULT): $(REAL_IMPL_INTF) $(OBJ_LINK) $(REAL_OCAMLC) $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ $(REAL_IMPL) ifdef MSVC # work around the bug in ocamlc -- it should delete this file itself rm -f camlprim?.$(EXT_OBJ) endif nolink: $(REAL_IMPL_INTF) $(OBJ_LINK) ifdef WIN32 $(REAL_RESULT).dll: $(REAL_IMPL_INTF) $(OBJ_LINK) $(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \ -o $@ $(REAL_IMPL) endif %$(TOPSUFFIX): $(REAL_IMPL_INTF) $(OBJ_LINK) $(OCAMLMKTOP) $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ $(REAL_IMPL) ifdef MSVC # work around the bug in ocamltop -- it should delete this file itself rm -f camlprim?.$(EXT_OBJ) endif .SUFFIXES: .mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \ .mly .di .d .$(EXT_LIB) .idl .c .$(EXT_CXX) .h .so $(DLLSONAME): $(OBJ_LINK) $(CC) -shared $(CINCFLAGS) $(CLIBFLAGS) \ -o $@ $(OBJ_LINK) $(CLIBS:%=-l%) $(RESULT).cma: $(REAL_IMPL_INTF) $(MAKEDLL) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \ $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(REAL_IMPL) $(RESULT).cmxa $(RESULT).$(EXT_LIB): $(REAL_IMPL_INTF) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \ $(OCAMLNLDFLAGS) -o $@ $(REAL_IMPL) $(RES_CLIB): $(OBJ_LINK) ifndef MSVC ifneq ($(strip $(OBJ_LINK)),) ar rc $@ $(OBJ_LINK) ranlib $@ endif else ifneq ($(strip $(OBJ_LINK)),) lib /nologo /debugtype:cv /out:$(RES_CLIB) $(OBJ_LINK) endif endif .mli.cmi: @pp=`sed -n -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ if [ -z "$$pp" ]; then \ echo $(INTF_OCAMLC) -c $(THREAD_FLAG) \ $(OCAMLFLAGS) $(INCFLAGS) $<; \ $(INTF_OCAMLC) -c $(THREAD_FLAG) $(OCAMLFLAGS) \ $(INCFLAGS) $<; \ else \ echo $(INTF_OCAMLC) -c -pp \"$$pp\" $(THREAD_FLAG) \ $(OCAMLFLAGS) $(INCFLAGS) $<; \ $(INTF_OCAMLC) -c -pp "$$pp" $(THREAD_FLAG) \ $(OCAMLFLAGS) $(INCFLAGS) $<; \ fi .ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: @pp=`sed -n -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ if [ -z "$$pp" ]; then \ echo $(REAL_OCAMLC) -c $(ALL_OCAMLCFLAGS) $<; \ $(REAL_OCAMLC) -c $(ALL_OCAMLCFLAGS) $<; \ else \ echo $(REAL_OCAMLC) -c -pp \"$$pp\" \ $(ALL_OCAMLCFLAGS) $<; \ $(REAL_OCAMLC) -c -pp "$$pp" $(ALL_OCAMLCFLAGS) $<; \ fi .PRECIOUS: %.ml %.ml: %.mll $(OCAMLLEX) $< .PRECIOUS: %.ml %.mli %.ml %.mli: %.mly $(OCAMLYACC) $(YFLAGS) $< .PRECIOUS: %.ml %.mli %_stubs.c %.h %.ml %.mli %_stubs.c %.h: %.idl $(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \ $(CAMLIDLFLAGS) $< @if [ $(NOIDLHEADER) ]; then touch $*.h; fi .c.$(EXT_OBJ): $(CC) -c $(CFLAGS) $(CINCFLAGS) -I$(OCAMLLIBPATH) \ $< $(CFLAG_O)$@ .$(EXT_CXX).$(EXT_OBJ): $(CXX) -c $(CXXFLAGS) $(CINCFLAGS) -I$(OCAMLLIBPATH) \ $< $(CFLAG_O)$@ $(MLDEPDIR)/%.d: %.ml @echo making $@ from $< @if [ ! -d $(@D) ]; then mkdir -p $(@D); fi @pp=`sed -n -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ if [ -z "$$pp" ]; then \ $(OCAMLDEP) $(INCFLAGS) $< > $@; \ else \ $(OCAMLDEP) -pp "$$pp" $(INCFLAGS) $< > $@; \ fi $(BCDIDIR)/%.di $(NCDIDIR)/%.di: %.mli @echo making $@ from $< @if [ ! -d $(@D) ]; then mkdir -p $(@D); fi @pp=`sed -n -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ if [ -z "$$pp" ]; then \ $(OCAMLDEP) $(DEPFLAGS) $(INCFLAGS) $< > $@; \ else \ $(OCAMLDEP) $(DEPFLAGS) \ -pp "$$pp" $(INCFLAGS) $< > $@; \ fi doc/html: $(DOC_FILES) rm -rf $@ mkdir -p $@ $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(DOC_FILES) doc/latex: $(DOC_FILES) rm -rf $@ mkdir -p $@ $(OCAMLDOC) -latex -d $@ $(OCAMLDOCFLAGS) $(DOC_FILES) -o doc.tex doc/latex/doc.ps: doc/latex cd doc/latex && \ $(LATEX) doc.tex && \ $(LATEX) doc.tex && \ $(DVIPS) $(DVIPSFLAGS) doc.dvi -o $(@F) doc/latex/doc.pdf: doc/latex/doc.ps cd doc/latex && $(PS2PDF) $(= 0 && (!y land (1 lsl !i)) == 0 do i := !i - 1; done; 1 lsl !i; ;; let pow2ceil x = let p2f = pow2floor x in if p2f = x then x else (pow2floor x) lsl 1;; let i2f i = float_of_int i;; let f2i f = int_of_float f;; let raw_of_camlimg cimg = let w = cimg#width and h = cimg#height in let image = GlPix.create `ubyte ~format:`rgb ~width:w ~height:h in for i = 0 to w - 1 do for j = 0 to h - 1 do let pixel = cimg#get i j in (* pixel is a Color.rgb *) Raw.sets (GlPix.to_raw image) ~pos:(3*(i*h+j)) [| pixel.r; pixel.g; pixel.b |]; done done; image ;; (* scale the image up so it's a power of two along each axis. (IMPROVEME: this takes too long) *) let rescale img = let newimg = img#resize None (pow2ceil img#width) (pow2ceil img#height) in img#destroy; newimg;; let initialize ci_img = printf "initializing..."; endl(); GlClear.color (0.0, 0.0, 0.0); (* save the original width and height *) let w = ci_img#width and h = ci_img#height in width := w; height := h; let ci_img = if pow2floor w <> w || pow2floor h <> h then rescale ci_img else ci_img in let gl_image = raw_of_camlimg ci_img in GlPix.store (`unpack_alignment 1); GlTex.image2d gl_image; List.iter (GlTex.parameter ~target:`texture_2d) [ `wrap_s `clamp; `wrap_t `clamp; `mag_filter `linear; `min_filter `linear ]; GlTex.env (`mode `decal); Gl.enable `texture_2d; GlDraw.shade_model `flat; printf "done"; endl(); ;; (* -- ui callbacks -- *) let disp_called = ref false let display () = if not(!disp_called) then begin Glut.reshapeWindow !width !height; GluMat.ortho2d ~x:(0.0, i2f !width) ~y:(0.0, i2f !height); disp_called := true end; GlClear.clear [`color]; GlDraw.begins `quads; let w = i2f !width and h = i2f !height in GlTex.coord2(1.0, 0.0); GlDraw.vertex3(0.0, 0.0, 0.0); GlTex.coord2(1.0, 1.0); GlDraw.vertex3(w, 0.0, 0.0); GlTex.coord2(0.0, 1.0); GlDraw.vertex3(w, h, 0.0); GlTex.coord2(0.0, 0.0); GlDraw.vertex3(0.0, h, 0.0); GlDraw.ends(); GlDraw.begins `lines; GlDraw.color(1.0, 0.0, 0.0); GlDraw.vertex2(0.0, 0.0); GlDraw.vertex2(1.0, 0.0); GlDraw.color(0.0, 1.0, 0.0); GlDraw.vertex2(0.0, 0.0); GlDraw.vertex2(0.0, 1.0); GlDraw.ends(); Gl.flush (); ;; let on_keyboard ~key ~x ~y = match key with | 27 -> exit 0; | _ -> (); ;; let view_with_glut img = (* open a couple of Glut windows and display the file directly and via texture on a square *) ignore(Glut.init Sys.argv); Glut.initDisplayMode ~double_buffer:false ~depth:false (); Glut.initWindowSize 256 256; ignore(Glut.createWindow "ocimgview"); GlDraw.shade_model `flat; GlClear.color(0.0,0.0,0.0); (* GluMat.ortho2d ~x:(0.0,1.0) ~y:(0.0,1.0); *) initialize img; Glut.displayFunc (fun () -> display()); Glut.keyboardFunc (fun ~key ~x ~y -> on_keyboard ~key ~x ~y); Glut.postRedisplay(); Glut.mainLoop(); ;; let _ = Bitmap.maximum_live := 15000000; (* 60MB *) Bitmap.maximum_block_size := !Bitmap.maximum_live / 16; let r = Gc.get () in r.Gc.max_overhead <- 30; Gc.set r ;; let _ = let filename = ref None in let argfmt = [ (* "-scale", Arg.Float (fun sc -> scale := sc), "scale"; *) ] in Arg.parse argfmt (fun s -> filename := Some s) "ocimgview file"; let filename = match !filename with | None -> Arg.usage argfmt "ocimgview file"; exit(-1); | Some s -> s in printf "Reading in %s" filename; endl(); let img = OImage.load filename [] in let img = OImage.rgb24 img in view_with_glut img; ;; lablgl-1.07/LablGlut/examples/caml-images/ppm.ppm000066400000000000000000003647551437514534100217460ustar00rootroot00000000000000P6 # CREATOR: XV Version 3.10a+FLmask+jp5.3.3+PNG patch 1.2d+misc Rev: 12/29/94 # CREATOR: XV Version 3.10a+FLmask+jp5.3.3+PNG patch 1.2d+misc Rev: 12/29/94 250 167 255 蛣艂撖銕葖銕鈰銕搟琩撖琩艂琩艂琩琱葖銕甯銢閫銕銕撖銕銕葖銕銕銕銕撖撖敿撖擃撖撖銕銕銕銕銕銕銕閫撖銕銕撖銕銕隢銕撖擃艂銕銕撖銕銕艂銕撖銕銕銕銕銕撖銕艂蒗銕葖銕銕艂琩艂嶆艂鈰撖銕銕銕葖銕鈰銕銕酮銕葖葖蝳銕葖銕葖琩艂艂琱琩銕琱菾屣銢銕艂獢蛣葖葖銕銕葖葖銕銕銕艂琩艂琩琩銕銕銕菗銕銕銕銕葖艂銕銕銕銕銕琱銕銕銕銕葖艂艂琩琱琱艂葖琩葖葖艂銕琱琱琱獢葖葖銕琱銕艂銕銕銕琱琩艂琱琱琱琱銕艂銕艂銕銕琱銕琱艂銕銕艂銕艂琱琩琱艂琱艂銕銕艂銕銕艂艂琱艂琱琩琩銕艂銕銕艂琱琩銕艂菗葖琩葖琱艂銕菗琱琩葖琱艂琩琩琩艂琱琱菗銕葖葖琩銕葖鉽銕銕嶉嵷嵷葖艂搣嵷琲嵷嵷銕銕琱艂艂艂鉈銕銕銕鉽鉽瑹撖鉽銕鉽銕撖潃憡漇嵷嵷鉽鉽銕嵷銕銕銕潃銕鉽撖漵瑹銕蝭銕銕鉽潃銕撖憡銕鉽銕鉽鉽銕鉽銕鉽鉽嵷銕銕嶉嵷銕銕嵷銕銕蓱葖葖嵷銕銕嶉銕葖嶉銕嶉鉽銕銕嵷嵷嵷蓱銕艂嶉嶉雈搣雈雈搣嶉菇摁鄐晻雱滽璈蓱嵷鉽銕雱潃銕嶉銕滽葖嶉艂雱蓱銕嶉銕銕銕銕葖銕銕銕銕銕嵷艂琱銕銕嶉銕嶉雱琣雈雱琱搦琱雈葖銕雱銕雈雈琱葖琱嵷艂琣艂銕銕銕銕艂琱琣艂葖琱琣雈雈銕嶉銕嵷艂嶉嵷銕璈銕銕銕嵷雈琱雈雈嵷艂琣蓱雈雱琱琱銕艂琱琱雈銕銕銕艂雈琱雈艂艂嶉琩琱蓱艂銕琱搣艂琱雱琱雱雈搣琱琲雈琱蓱搦葖搣銕葖蓱銕搦銕艂艂嶉銕嵷艂蓱銕嵷銕搣嵷銕嵷鉽銕銕鉽甇銕銕鉽瑹銕銕銕鉽撖鉽嶉鉽銕鉽銕銕銕銕銕銕銕銕鉽銕銕銕銕銕銕銕銕銕嶉鉽銕鉽銕銕銕銕銕嵷銕瑹銕撖舕隢鉽銕銕銕銕鉽甇銕嶉銕鉽銕銕銕銕銕銕鉽鉽銕銕銕銕銕憡瑹銕銕銕銕嶉嶉潀嵷銕嵷搣撖嶉鉽鉽銕嵷嶉璈銕嶉嵷撖嶉葖艂鉽搦嶉蓱雱銕銕嶉銕銕銕嵷蓱菇銕銕銕嶉嵷雈銕銕銕銕銕銕銕銕嵷銕銕銕嵷銕艂葖搣蓱嶉葖蓱嵷艂雈嶉雈琣嵷艂艂銕銕銕銕銕銕銕銕銕銕艂琱艂銕嶉銕銕銕銕滮搣銕銕銕銕晼琱雈艂雈琱嵷琱嵷嵷嵷琱琱嵷銕蓱雱葖銕銕銕銕銕銕銕銕銕銕銕銕銕雈琣雱雈琣艂雈銕嶉艂琱琲蓱嵷嵷嵷雱雈琲撖撖銕葖銕嶉嵷銕銕嵷蓱嵷嶉銕嶉鉽嵷嵷銕瑹瑹銕鉽甇鉽鉽撖銊葖銕鉽撖銕撖蝭鉽鉽鉽銕銕銕銕鉽銕銕銕銕瑹銕嶉銕銕銕鉽銕銕瑹撖銕銕鉽鉽銕鉽瑹鉽銕銕瑹甇鉽舕銕銕銕銕銕銕銕銕銕鉽膌銕甇鉽銕銕銕銕銕鉽撖銕銕銕鉽憡撠銕嵷銕嵷鉽銎鄔搣搣蓱琱銕銕銕銕潃銕銕蓱蓱漼鉽嵷銕銕鉽葖蓱琲嵷葖嶉銕銕銕銕銕銕嵷銕銕銕葖銕艂嵷銕銕銕銕銕銕銕銕鉽銕銕銕嵷嶉銕蓱艂雱蓱銕嶉銕憒雱蓱嶉葖嵷蓱銕嶉銕琱嵷銕銕銕銕銕銕銕銕銕銕銕銕銕銕艂銕嵷銕銕銕銕嵷銕蓱嵷艂嵷嵷琱雈銕艂琱嵷艂銕銕蓱銕嵷嶉嵷銕銕銕銕銕銕銕銕銕銕艂艂艂艂嵷嵷艂搣雱銕嶉銕銕銕嵷瑹銕銕鉽撖嵷搣雱銕銕鉽銕嵷艂嶉嶉蓱鉽銕艂撖鉽銕銕銕銕敿銕銕鉽鉽蝳蓱鉽銕嶉鉽甇滽鉽瑹銕鉽銕銕銕銕銕銕銕鉽銕鉽銕甇銕銕銕鉽鉽銕甇銕銕銕銕銕銕銕銕鉽瑹鉽撖鉽瑹鉽鉽銕銕銕嵷銕鉽鉽銕甇嶉銕銕銕銕銕鉽銕銕銕鉽銕銕甇漇瑹銕銕銕艂銕蓱鄔嵷銕蓱艂銕銕銕嶉銕銕銕嶉銕撖漇銕嶉鉽銕嶉酯蓱葖艂嶉嶉嵷銕銕銕銕銕銕銕嶉銕嶉嵷嵷銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕嶉嶉銕銕銕銕鉽嵷雱銕銕銕銕銕銕銕嵷嵷銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕嶉嶉銕銕銕銕銕銕銕銕琱琱雈雈雈琱艂琱銕嵷嵷嵷銕銕銕嶉銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕鉽鉽鉽瑹銕銕撖瑹隢甇瑹鉽蝭撅葖銕鉽嶉搦晱雱嵷蓱雱嶉嶉嵷銕銕嶉鉽鉽瑹鉽鉽鉽鉽撖甇撅鉽嵾蝑銕銕漇鉽鉽撖鉽鉽鉽撖銕撖撖鉽鉽撖瘣鉽鉽撖瑹銕銕銕銕銕撖銕銕銕銕銕瑹嵷鉽銕撖撖撖撖鉽撖鉽鉽銕蝭瑹瑹甇鉽銕銕嵷嶉漇鉽蓱銕嶉銕銕銕嶉銕銕銕葖銕嵾滽銕銕嵷蓱膌鉽膌蓱銕銕銕嶉葖嶉蓱嶉嵷嵷銕嶉嶉嶉撅鉽鉽鉽銕蓱搣琣琣銕銕銕銕鉽鉽鉽銕銕嶉銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕鉽銕銕銕銕銕銕璈嵷銕銕銕嵷銕銕銕銕銕銕雈艂銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕嵷銕銕銕嵷銕銕雈銕艂艂艂雈艂銕銕嵷嶉嵷嶉嵷銕嶉銕銕銕鉽銕銕銕銕銕鉽瑹銕鉽銕銕銕鉽撖鉽瑹隢銕銕銕銕鉽銕銕銕撖銕葖琱晲搣搢萿摃犑艂潃嵺鄐嶀犍漇潃銕銕擳鉽鉽鉽銕瑼撖蝑鈺甇撖漇嶉蓱鉽銎嶉犑漇甇銕鉽瑹甇憡滽撖鉽嵷嶉甇瑹銕鉽鉽銕銕銕蝭鉽鉽憡嵷嶉艂嶉鄎鉽潃潃撅閫嶉銕銕銕銕銕銕鉽嵷鉽鉽潃嶊蓱蓱鉽嵷葖銕鉽葖嶉銕璈嶉銎蒡嶉嶉銕銕潃銕艂漇漇艂嶉潃漇摁銕犑蓱犑艂潀銕銕銕銕撖摮葹銕銊嶉琩嶉銕銕銕銕銕鉽撖銕潃銕銕銕銕嶉銕銕嵷銕銕銕銕銕銕鉽銕銕銕銕嵷銕銕銕銕銕銕銕銕璈蓱艂鉽銕鉽璈銕銕銕嵷憒嶉銕銕銕銕銕銕銕銕銕銕鉽銕銕嵷憒嶉銕艂嵷嵷嵷嵷銕銕雈銕艂嵷雱蓱艂雈嶉銕銕嵷艂銕銕銕銕銕銕銕鉽嶉漇銕銕瑹瑹銕銕銕銕銕銕銕鉽鉽銕鉽銕銕鉽銕銕嵷銕銕酮蓱菪嵷蓱葖銎滽靰葹蓱鉽滽鉽鉽銕撖漇鉽葖憡嶉漇銕漇鉽鉽嵷滽銕銕滽鉽嶉嵾潃撖嵷嶉鉽銕潃銕潃蝭鉽鉽撖甇鉽鉽銕撖銕銕葖銕漼銎鉽銕銕蓱漇銕銕鉽甇鉽甇鉽蝑鉽鉽銕鉽鉽銕嶉嶉銕鉽嶉潃滽隢嶉鉽鉽潃撖瑹葥嶉嶉鉽鉽鄑銎嶉鉽銕嶉葖酮犑搰嵷葖嶉蓱蓱搰搣葖琲葖潃鉽鉽嶉撖銕甇瘞撅蓱搦葖雱嶉銕嶉銕銕銕撖鉽銕銕銕嶉銕銕嵷銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕嵷嵷銕銕銕銕鉽銕銕銕銕嶉銕銕銕銕銕銕嶉銕銕銕鉽銕銕銕嵷銕銕銕銕銕銕銕銕雈艂琣艂琱艂嵷銕銕銕銕琩銕銕銕銕嶉銕銕銕銕銕銕銕銕銕銕銕銕嵷銕銕銕銕銕銕銕銕銕艂銕鉽銕銕銕銕銕銕銕搣銕銕銕嶉琱搢漇琲搣嵷葖葹搣嶉艂潃鉽嵾銕銕銕銕銕銕蓱銕銕銕鉽銕鉽潃鉽撖嶉瑹嶉鉽擳葖嶉銕蓱鉽銕銎蓱鉽銕撖銕銕銕鉽潃鉽銕鉽銕銕銕鉽銕銕葖蓱銕嵷嶉鉽銕鉽鉽銕鉽鉽撖銕銕鉽嵷嵷葖銕銕撖嶉鉽嶉搣鉽銕嶉蓱潃鉽憒鉽葖搣雱嶉蓱鉽銕嶉漇艂葖搌艂嶉葖嶉搣葥憭葖葖蓱蓱嵷銕酯嶉銕銕潃鉽滽葖菗雱搦嵷蓱琩葖葖銕銕銕嶉銕銕嶉嶉銕銕銕銕銕銕銕嶉銕銕銕銕銕嶉銕銕銕銕銕銕銕銕嶉嵷銕銕蓱銕銕銕銕銕銕嶉銕銕銕銕銕銕銕銕銕銕銕銕雱嵷銕銕銕鉽銕蓱琣琣琱雈雱艂嵷艂銕銕銕璈銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕銕嶉銕銕銕銕銕銕嵷銕嵷蓱銕銕搣艂菗嶉搣嶉蓱葖銕銕酯雈雱嶉葖銕嵷銕銕瘥豱嶊鉽銊憍霈貒豱霈黕貕豱豱豱赯赯篝嚜貒豱嚝薾貒穘諨豱豱豱豱豱敼豱銕甇賵蝎甇霈銊靚貒蝪謓豱貒貒憳膍瑹瑹賵甇潃蝎嶈隢銕潃撖鉽搦撗撖嶈甇鉈葖銕諯滽潃滽撖潃潃嵿潃酮蝎銕銕膍膋嶊嶈甇蝪銕甇鈰潃鉽憳撠鉽撖鉈鉽諯撗滽霈撖潃鉽鉈蒗鉈漇蓱艂艂葖銕膍憍甇鉽瘣撖隢甇銕嵷漇隢鉽甇鉽潃膌銕瑹鉽撖甇銕銕銕銕銕銕銕嵷銕銕艂銕銕銕銕嶉銕銕銕銕嵷嵷鉽銕銕銕銕銕銕銕銕銕嵷銕銕銕銕銕銕銕銕銕銕嶉艂琱琱嵷艂蓱銕銕銕銕鉽銕銕銕銕銕銕銕銕嵷嵷蓱銕銕銕銕銕嵷銕銕銕銕銕銕嶉銕銕銕嶉嶉銕銕銕銕銕雈雱銕銕蓱琣銕葖潃銕鉽銕銕撖鉽鉽鉽潃鉽銕銕撅潃篞噹m棷yox}wwn司]肚erf`PfT~ZFzb}YCfUxZE~ZFmYGt^iYurppp囮v囮玊s囮癡uphzgwbㄏjkzzv洬膠艇閒}儐膝妗妠妠ご繚噤Ш膳趕戚迭釣砠z~z~yvz{vp囮q迢f囮szys儔膜~舅|楚汃汃~zv{洠{洠棷埻{堔怗rttvrg]_uwwk﹄y癟u縣~yy{||wp膘縞楷z膘漸楨蕊賒楨隍z鼓蔗膘蔗蔑Е刓佴彖彖刓繪羶捚恉刐鬚佹匢匢匢岋捚媜媜痭S苤錧恃葶癪卸犐嵺鸇卷鄖鉽鄎銕鉽漅瘞醲唔膋獾村鄏鄔鷾阿漅潃銕銕銕蝎蝭鉽銕嶉蓱嶉舕膍膌膌鉽甇甇甇敼敼豱搦琲雱琱雈搣嶉蓱銕銕雈雱銕銕銕銕銕銕葖菗漇艂艂酯銕銕嶉蓱潃銕銕撖鉽銕潃儦mXE櫋<踒.璻3璾0璻3轈5饎?鄺7旝5饌A饎?櫧7曣:鐻H饋@饎?櫳<鐶H櫳<饎?饌A饎?櫧7櫧7鄺7璻3轈5璻3璾0璾0璾0璻3璾0璾0璾0璾0踓0轈5璾0璾0轈5璾0璾0璾0璻3轈5璾0璻3踒.匰2榎4劁0觡.觡.觡.踒.觡.9)9)劁02$>+>+>-匰2觡.劁0觡.觡.劁0劁0劁0觡.匰2劁0蕱8劁0踓0踓0熿5璾0璻3旝5璾0璾0踒.>+觡.觡.>+>+觡.愅/噞3觡.觡.璾0璻3踒.踒.轈5踒.璾0噞3踒.踓0劁0璾0燅3誫6誫6誫6誫6燅3燅3閵8閵8誫6誫6誫6誫6誫6榬0>+誫6墱8>+惲-聐2聐2誫6毧.浺1毧.毧.毧.毧.毧.毧.毧.毧.毧.毧.惲-毧.毧.毧.毧.毧.惲-惲-毧.惲-9(毧.毧.9(9(9(毧.>+>+9(9(乇39(9(劇-劇-9(9(澶2蚊.湟3膂8膂8膂8膂8膂8靦=膂8蚊.蚊.蚊.膂8湟3蚊.膂8膂8湟3膂8膂8靦=膂8枇8㎜9㎜9O8昤=㎜9枇8G4枇8C1G4袈:訪C吐箠J\B赯雈琱嶉搦銕銕嶉銕銕蓱艂嶉嶉葖銕銕葖蓱銕葖嶉嶉嵷嶉銕銕龢潃嵷鉽嶉潃鉽潃蠁ドF酄B饌A曣:櫳<饎?饎?櫳<櫳<曣:櫳<櫳<曣:曣:櫳<櫳<曣:曣:曣:曣:曣:曣:饎?曣:櫳<曣:璻3曣:曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:曣:櫳<曣:曣:曣:櫳<曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:曣:曣:曣:曣:櫳<櫳<曣:曣:曣:曣:閵8曣:櫳<曣:旝5閵8誫6燅3拯,窨4箊:涎0毧.誫6曣:曣:櫳<曣:曣:曣:饌A櫳<曣:饎?曣:櫳<櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:閵8曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:饎?曣:曣:曣:曣:曣:櫳<曣:曣:櫳<曣:饎?饎?曣:曣:櫳<曣:曣:曣:櫳<酆D酆D饌A饌A曣:饎?饎?饌A饎?櫳<曣:櫳<饌A饌A饌A饎?饎?饌A醹E酆D醹E瘟2曀搣艂搣琩嶉嵷蓱銕銕嵷嵷銕銕嵷嶉銕嶉嵷葖蓱琲琲嶉憒舕舕鉦鉽舕嶉蓱蓱撗搰鐙)饎?櫳<饎?騴C櫳<饙>櫳<饙>饎?櫳<櫳<饌A櫳<饋@酆D櫳<饌A曣:櫳<曣:曣:曣:饎?櫳<曣:櫳<曣:櫳<饎?曣:櫳<曣:曣:曣:櫳<醹E饌A饎?騴C曣:曣:曣:曣:櫳<曣:櫳<櫳<蕦<饎?櫳<櫳<饎?饎?饎?櫳<櫳<櫳<櫳<蕦<曣:饌A櫳<閵8曣:饎?曣:櫳<饎?櫳<饎?饎?饎?櫳<櫳<饎?饎?饎?曣:櫳<閵8誫6曣:曣:曣:曣:曣:櫳<蹭:P;佈2雔:瞋;櫳<櫧7櫳<櫳<櫳<曣:櫳<曣:曣:濣=饌A饌A酆D酆D饎?酆D櫳<曣:曣:曣:曣:櫳<櫳<曣:曣:曣:曣:櫳<饎?櫳<櫳<櫳<曣:饎?饎?曣:櫳<曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<饎?櫳<曣:曣:櫳<曣:櫳<饎?曣:曣:曣:曣:櫳<曣:櫳<曣:櫳<饎?櫳<曣:曣:曣:饎?饎?櫳<櫳<饌A饌A饎?饎?饎?酆D饌A饎?饎?饌A櫳<饎?櫳<酆D醹E酆D饌A醹E醹E酆D埕7紫菇蓱銕銕嶉嶉銕銕銕搣嵷蓱銕銕銕嶉葖銕琩靰犍雈搣雱嵷鉽瑹葖琩蓱搣琩摁銊z菀H饎?酆C饋@酆C饎?醹E酆D饌A櫳<饎?饌A饎?饎?饌A饌A醹E饌A酆D饎?饌A酆D饎?饎?饎?饎?櫳<饎?櫳<饎?饎?饎?饎?櫳<櫳<櫳<饙>饋@饌A櫳<酄B饌A饎?櫳<櫳<饎?饌A醹E醹E櫳<酆D饎?饌A櫳<饎?饎?饎?櫳<饎?酆C醹E酆D饎?饌A醹E醹E酆D酆D酆D酆D饎?櫳<曣:饌A饎?饌A櫳<櫳<曣:櫳<曣:櫳<饎?饌A曣:曣:饎?櫳<櫳<燡F涼/饎?象0窨4曣:曣:櫳<饙>饎?曣:櫳<饌A饎?饌A饎?饌A饌A饎?饎?酆C饌A饌A饎?饎?枳6|E)酆C饌A饎?饎?酆D酆D酆D饌A櫳<櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<櫳<曣:曣:曣:曣:櫳<曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:曣:櫳<曣:曣:櫳<饎?酆D饎?饎?饎?饌A饎?櫳<曣:饎?饎?饎?饌A酆D饎?饎?曣:櫳<饎?櫳<饎?櫳<酆D酆D酆D躒G酆D酆D醹E酆D饌A饎?饎?酆D饎?饌A酆D酆D饌A酆D酆D酆D酆D饌A酆D醹E躒G鷸K奸P瘜雈蓱搣銕嵷嶉銕銕銕銕銕銕銕鉽嶉銕銕艂艂蓱雱蓱嵷鉽葖雈嵷搣雱潀艂琭槧=.鑇O躒G躒G躒G酆C酄B饎?酆D酆C躒G醹E酆C醹E躒G躒G躒G躒G饋@醹F饋@酆C酆C醹E酆D鐻H醹E酆C醹E饌A酆D酆D酆C醹E饌A饌A饌A酆C饌A酆C酆D酆D醹E饌A饎?酆D酆D酆D躒G醹E酆D醹E饌A饌A酆D饌A饎?酆D饌A酆D饌A酆D醹E躒G躒G酆C醹E躗I鷸K躒G醹E躒G酆C醹E醹E酆D酆D酆D酆D饎?饎?饌A櫳<饎?饌A饌A酆D饎?饌A騴Cn(既3酇L9(醹E饎?饎?醹E饎?饌A饌A饓A躒G躒G躒G躒G醹E醹E躒G躗I酆D酆D躒G醹E酆C鄅DH3躒G躒G醹E躒G醹E醹E躗I酆D饋@饎?饌A饎?酆D饎?饌A饌A饌A櫳<櫳<櫳<曣:櫳<饌A饌A饎?曣:曣:櫳<饎?饎?曣:饎?饎?曣:櫳<櫳<櫳<饎?饌A櫳<饎?櫳<櫳<櫳<饎?櫳<饌A曣:櫳<櫳<饎?酆D饌A饎?饎?酆D饌A酆D酆D酆D饎?酆D酆D酆D酆D櫳<饌A饌A醹E酆D饌A酆D酆D醹E醹E躒G酆D醹E酆D躒G醹E酆D酆D酆D醹E躒G躒G躗I躗I鷸K躗I躗I躒G鷸K躒G鷸K鷶N蠼S罡D虡受雱搣銕銕嶉銕銕銕銕銕銕嵷銕銕銕銕嵷艂搣艂嶉艂艂嶉艂蓱搦銕嵷蓱豱轡PG4鱴Y鷸K鷶N轢L躗I躗I躒G躗I躒G鷸K鷶N鷸K鷶N鷸K鷸K鷶N鷸K鷦Q鷦Q鷸K躒G鷸K鷦Q鷦Q鷦Q鷢T躗I鷶N躗I鷸K鷸K躒G躗I躗I酆D酆D醹E酆D酆D酆D饌A酆D醹E躒G醹E酆D醹E醹E酆C酆D醹E躒G酆C醹E酆D醹E醹E躒G躒G醹E躗I躒G躗I鷸K醹E躗I躒G鷸K躗I鷸K躗I醹E鷸K躒G躒G躗I躒G躒G躒G躒G醹E躒G鐻H躒G醹E酆D躖J躒G醹E轢Lf泳Hz`<+鷶N躒G醹E躗I躒G醹E躒G轢L鷸K躗I鷶N躗I躗I鷶N轢L轢M躗I鷸K鷸K鷸K鷶N鷦Q,+鷶N鷸K鷸K鷸K鷸K躗I躗I鷸K鷸K躗I鷸K躗I鷸K鷸K鷸K躗I躒G躒G躒G躒G醹E躒G躒G躒G醹E醹E醹E酆D酆C酆D饌A饎?酆D酆D酆D饎?酆D饌A酆D酆D饌A酆D醹E躒G躒G酆D酆D躒G躒G酆D醹E酆D饌A饌A酆D饌A醹E醹E酆D饌A酆D酆D酆D躒G酆D酆D酆D酆D酆D躒G躒G醹E鷸K鷸K鷸K鷶N鷸K鷸K鷸K鷸K鷸K躗I躒G躗I鷸K躗I鷸K鷸K鷸K鷸K鷦Q鷶N鷸K鷸K鷶N鷸K鷢T釃W鷢TF5箹渝搯蓱銕銕嶉銕銕銕銕銕銕銕嶉銕銕嵷銕嶉艂雱銕銕嵷嶉蓱葖斢暺窙tP;i鷢T鷢T鑸Y鷦Q鷦Q鷢T鷸K鷦Q鷸K鷶N鷦Q鷦Q鷦Q鷢T蠼S鷶N鷦Q鷦Q鷶N鷦Q鷸K鷢T鷸K鷢T鷶N鷶N鷦Q鷸K鷸K鷢T鷸K鷦Q鷸K鷶N鷸K鷦Q轢L鷶N躗I鷶N轢L躗I鷸K鷦Q鷦Q鷦Q鷶N鷸K鷶N鷸K鷸K鷸K鷶N鷢T鷦Q鷢T鷶N鷶N鷸K鷶N鷸K鷶N鷦Q鷸K躗I鷶N鷦Q鷸K鷸K鷸K鷦Q鷸K鷸K鷶N鷶N鷦Q鷶N鷸K鷢T鷸K鷦Q鷶N鷶N躗I躗I鷸K躗I鷶N鷸K躗I鷶N㏄?滜E窮J鷸K躗I釃W]E鷶N鷦Q鷶O釃V鷶N鷶N鷦Q鷦Q鷦Q蠼S鷦Q鷦Q蠼S鷦Q鷦Q鷶N鷢T鱴]擾C鷢T鷢T釃W鷦Q鷢T鷦Q釃W釃W鷦Q鷢T鷶N鷸K鷦Q鷶N鷶N鷦Q鷶N鷦Q鷦Q鷦Q鷸K鷸K鷸K鷸K鷶N鷸K鷸K躒G鷸K躒G躒G躗I躗I鷸K鷸K鷸K躒G躗I鷸K鷸K鷸K鷸K鷸K鷸K鷸K鷸K鷶N鷶N鷸K鷸K鷸K鷸K鷸K躗I躒G躗I躗I躒G躒G躒G躒G躒G躒G躗I醹E躒G躒G鷸K躗I躗I鷸K躗I躗I鷸K鷸K鷶N鷦Q鷸K鷸K鷸K鷶N鷶N鷶N鷸K鷸K鷸K鷶N鷸K鷦Q鷶N鷶N鷦Q鷶N釃Vy]鑸Y鑸Y釃W鑸Y鑸XJ8暋篣雈蓱嵷銕銕銕銕銕銕銕銕艂蓱嵷葖嵷雱葖嶉葖銕嵾甇fe爹=煲Uc鸓^|`黲Zy]鑸Yy]釃V鷢T鷦Q鑸Y釃W鑸Y鑸Y鑸Yv[釃W鑸Yv[y]v[v[釃Vv[v[v[v[vZ鑸Y鑸Yv[釃V鷢T釃W釃Wv[釃W釃W鷢T鑸Y釃W釃V鷦Q鷢T釃W鑸Y鷢T鷢Tv[鼜\釃Vv[v[釃W鑸Y黲Zv[釃V蠼S釃W鷦Q釃V釃W釃W顩W黲Z饖Y顩X黲Z饖Y顩X黲Z霿U鑸Y釃V鑸Y顩W鷢T釃W鷦Q鷢T釃W鷦Q鷦Q鷢T釃W鷢T鷦Q釃V鷦Q釃V顩W鷦QS<洚^喏U鷦Q顩X蠼SvA*a鑈R鱴]~C0后D黲Z黲Z鑸Y鑸Y釃W黲Z釃W鶘\饖Y霨[饖Y鶘\瞢_YF釃W鼜\釃W釃W釃W釃W鷢T釃W釃W鑸X釃V釃V鷢T鷦Q鷢T釃W釃W釃W釃W釃W鷶N鷢T鷦Q鷢T鷦Q鷸K鷸K鷸K鷸K鷸K鷸K鷶N鷸K鷶N鷦Q鷸K鷶N鷶N鷶N鷸K鷸K鷸K鷶N鷸K鷦Q鷢T釃W釃W釃W鷢T鷦Q鷦Q釃W釃W釃W鷢T鷢T鷦Q鷶N鷦Q鷶N鷦Q鷶N鷦Q鷦Q鷸K釃W鷦Q鷢T鷢T鷢T鷶N釃W鷦Q鷢T釃V鑸Y釃W鷢T鷢T鷢T釃W鑸Y釃W鷦Q鷢T釃W鷦Q釃W釃V鑸Y鑸Yv[y]鑸Yv[v[y]|`|`d腛]洪X賑鍪昏嚜貕嶉嵷嵷嵷銕銕銕銕嵷銕銕撖嵷銕葖鉽撅銕黺kUw|`驏]鼶^baaaav[y]by]驏]鼜\y]|`|`v[y]y]|`d|`|`g|`|`dbb鼶^|`y]黲Zy]y]y]y]y]v[釃W黲Z顩W鱱]v[黲Y黲Z饖Y驏]驏]鼜\驏]_g鸓^|`a鸓^c|`驏]鸓^驏]|`|`|`鸓^c|`b|`ad驏]騽[驏]驏]鸓^礣Zav[饖Y饖Y黲Z鼜\y]饖Y騽[騽[饖Y驏]黲Z鼜\鑸Y騽[顩WT?z<,聵_齃a騽[|`柔Ae驏]eyOA緩_d|`bca驂]bcb^a驏]緬TS@b鸓^b|`bv[鼜\bad|`|`驏]y]|`鸓^v[v[v[黲Z|`v[v[v[鑸Y釃W釃W釃W鷢T釃W鷦Q釃W釃W釃W釃W釃W鷢T釃W鷦Q鷦Q鑸Yv[y]v[v[v[v[|`y]|`v[y]v[v[v[v[鑸Y鑸Y鑸Y鷢Tv[顩W釃W釃W鑸Y釃W鑸Yv[鑸Yy]y]v[y]v[|`|`y]鑸Y鑸Yv[鑸Y顩X黲Z鼜\|`y]y]y]v[y]|`|`|`bbfiloimrl忥a沱IㄆVxS攳嶉嵷艂銕銕銕鉽銕嶉銕嶉潃葖撅甇鉽鉽賵nVhijlljdhicfhfihdofdgfdjiigdddbjajbdadhiee鸓^baeaeba鼶^bbciiiffifh鶘\aee_cci__bcbfb^f_驂]鶘\驏]鸓^__霨[f鶘\a鶘\^鸓^^bdb瀋S掤Vfbb鼜\雹VsoslG6ㄏieeeefpfbif霦`愜M癥Tiiffdifdiccafii鸓^鸓^|`biadb|`|`y]b|`|`v[驏]y]|`鸓^|`鸓^鼜\y]|`鸓^by]|`bb|`b|`ay]y]bb|`bbbbdd驏]a驏]v[v[v[diddbbbbfb驏]a鸓^|`bb|`f鸓^dfbfddflojlrrvpvvqytu泡]窷琩葖嶉銕嵷銕鉽鉽嶉琩嶉鉽潃滽銕嶉蓱赯z`Q才pmoxvvwvussmpoquppvlswlmmpoliilooiolicimimooihllkiholoilrllskislolplolhkilloohkollblbbefliiekifhm`Oshgi_bkxWB沾Vgqfpooiiiieoy^uiiuilloloilroiifiiliifffbibdcffiilifbdddiiililidiidfiliiiiloiiiiliiiiiiiiioofddliififiiorpotqsssvmtwyxㄍ叻xy要S滽葖雱銕銕鉽鉽銕銕銕琩滽鄏搣搰葖蓱嶉豱|qQvwx{u』wuxqvx|x{wtwzywwstxyuqtxtutxvwx|tttxvvpmspqwpqsspwqxwㄍzxwtxptwuwxwtvwuprisxsmlhlorwpmsorsmsoE4nlprkcsvi{swqtpsqwvvst咳Wsjtjnwsmsvtspsvssvsrllomillileilllkooioiliilorllllloilvllooroporlmuilrrrlolrpuspxmxtorvrvsvvx并yx』x{y并▇N撅蓱艂銕銕銕銕鉽銕銕葖雱搦琲搣嶉搦嵷赯n^Hx﹚{|并并x』yㄍx并』ㄍ并yyㄍ|yㄍ』』』』』{y叻yy{vyx{xx』』ㄍyztvwㄍyxw﹚并』w{wxyㄍy并xxwuxyuwqvpnvxpsxtwsnvwztwtfI4}ptsjM;)j嵽vwsyxyxx`含Rwk{vxxwwxxxxx叻wywxxyxy』xyxwwxwxutppswssvwtswwsswwtvwtvwwxxvststvsqtwwxwxwwvqqwxxtqvsxtvpwxxy{﹚{叻』并并并并Y@撗嵷嶉嶉鉽鉽撖撅鉽銕葖雱琩琲琣雈雱雱篕{_I并ㄍㄍ良叻并并并并并并ㄍ并ㄍ并叻并并』▕y并』y』叻良z并』良ㄍ』叻并x﹚ㄍㄍ并并叻ㄍ』s{ㄍ{并yyzw\F年膃cW~qwfXy』ㄍw{slhz』』yyyy叻叻并叻并叻叻』ㄍ叻{q』』』xwyㄍyyywuwyyxxwxxwxx并』y{xxxwxxwxwyy』yywx』并叻叻ywqyx』并并叻叻叻并』并]F蒺銕搣蓱嵷銕撖撅撅鉽琩痐晼晼琱琲琩曊vcI并并良并四叻并并并并外并并讞鬤g顜齒痐~uwp{wXx擳h并并并并﹚并y』叻叻yv并叻叻叻并』y叻』叻并并并并叻叻x叻并并并叻叻』叻并并叻并毒^滽嶉艂琣銕鉽銕銕鉽銕藭堧琣琣琱雈晻篣gM8纂顳良馫C:5d鄎_Lyq鰣飌驦痋騋c貜蠿|ㄍ鞥|貜并叻并叻叻并xV鉈嶉雱嵷銕銕銕銕銕鉽琩琱琩雈雱賵oX鸝r]Cx^_@馫驦鬤馫顳ゝ鷅u躨t峆驦搷蒆l鉬菪z鸕鸕鸕鬤j諰yc驧顳顳q|e鱁籇}躩~lM撅銕嶉銕銕嶉銕銕嶉銕琩琩琱琱雈雱艂搣蝪~c欞鸕氻zYx讟fM恁鰡繻鰨鶶鸕驤驤驧驧鬤猀=4)萴nhcbN鰽秅|懘kqS钂鷞驦nY6悈}銢驦鬤鬤眱蚳~驤鬤飌顳飌驤|V瘣銕銕銕銕銕銕銕銕銕琩琱搣蓱艂嶉漇葥薶{[虌虌沬_yZ{_悁tZH~p[瓾爧馫虌齈鬤欞躨鬤鸕搧hwj鶡z鰣異~鰷鰶芊y鰤吽xnwp`驨齈钁欞欞荎|t鶼堜驦鷛m驧驦鰴鬤鸕{W瘣搣嵷銕銕銕銕搣銕銕葖銕滽撖鉽銕嶉撖貕z邿y`ZUK贗戇嵾瑍hXAy欞鬤鸗爧戇晜}撟鸕戇鬤q~f顴钀鼣_驩p颩ju嵹欞荇鷋鰶蒏t蝎驤鰲鸗}`]F狴怚鬤s撖琱琣琱嶉嶉銕銕嶉嶉葖蓱葹艂銕潃琣葖豱|^虌鰲虌晥e6)熒挬蛝嶉KH;Х虌欞鬤ui]r欞鸗鸗欞y欞虌艦|`XC躨{Z埱傍uz欞|s鷒鷒銝tP眽鸕虌r諯灪仍g鬤t瘣艂嶉銕葖銕嶉銕嶉搣琱雱潃嵾潃艂鉽搦豱|]欞鄔o齾耀o輕6)鸕躨鸗HH<懫鷜戇p珒r畦~搧鸕薑h瓴vS猺騇sq鷜鰽黧t曊齈漟菬黧驦鰷鸗r瘛銕蓱琱晱琩銕銕嶉葖琩漇漼嵷銕鉽葖潃貕xeO蚽虌晹壎|躨vr啈|{欞鷞鰶鸗帢`G4鶳棶_W@钀{霽鯇{g睎驨鄐虌鸗餺k龠w撋鰶搦驩鸗m瘣銕雱琱晼蓱銕鉽銕艂搣琲艂撖葖鉽蓱貒wgR蓐戇b堛僄~u^mLe\H虌鱹熂x爧欞u齞畯鷖sq拑u蚢鸗鶹陪鬩jx痑{戇鰶眹蝺欞洉c嵼鸗鸗n撖葖嵷艂嶉葖嶉銕嶉銕琱晱搰搣葖鉽嵾蒏敿nT廗鷜驩醲閎audU煚鞃o鵋钀驩pSr屪陝}躨芄n觓钁鸗欞vdD~蘛鷝ΠVM謰污囚ヾ}{v躨虌亄ils篚鷛騑謓漇鷒nO畯鸗l鈰銕蓱蓱銕鉽鉽銕銕銕堥晻犍搰腡甯犍痐隢tq\眭虌鬤钀褑jsov钀洁糽v虌抩}|k钀譨朴居{郺齈虌欞鷋虌蔆仵驨鷊儒瑱~Z爚隆mg荎虌钀牶rhP鶻漜臙啎ry爧臙艩鈺搨鰲戇i潃銕銕銕銕銕鉽銕蓱鉽艂晻琱琱搟琩艂蓱敿{n\靰鸗虌虌鷋欞钀驩堜|zj搛fWD埽cU=荂洘椌虌虌m芼j钂欞袗钁躨瑀欞欞虌yx驞lg堸顑}牉d飾鬮欞銴{譨﹁^藶戇l鷜餼x蘀k虌齈p潃嵷嶉銕銕銕銕銕嵷蓱醽晼琱琲搣琣琱蓱j眲鉠JD6塈劗悈夆鷖r襆lH}靰|^tae嶺u戇鸗鸗齈頧u齈齉茂J1芴橧zeN侚qiV钂蒧怳~钁諯si揭~眳窸戇葧茞钀a蝺銕銕銕銕銕銕嶉嶉銕魙堙琱晻雱蓱雱摰~a獉暀驩唌cuY岩興}eI甯u~byS鮶鸕か炟爧孺{k棶VRBooV怉ヲvwY=鷋钀椰}鈭堈vj晲vlS钁暀ve儽祂妢t蛅羲埣媔ぅ劙扑w榃菢搌}c豱嵷銕鉽銕銕銕鉽嵾鉽痐琣琣琩蓱琩滽^眹虌虌悢v揧憫幮傮ub簉B0#]I7~qa洃堭dXO眴洁s_Ioza驨戇禱縝虌鷐鶬鸝兡T=繩熆pヮ蓬╮h|鶱釩摀噢貼;1銧w鬅q鷐s戇睇{5+ loW?蔔~pVxXvTSF4KE.C@2DC/=;)<9+F>/D=*JE1z^{c壕y蚸}_儭銕鉽銕鉽銕銕銕嶉嶉晻晼晼琱琱雱琩潃n猻虋菢{nr[D--&鵗荷珥BB?朁瘝橭vmQw]FpmX穩蘄駘悼童w_Шu洌捄墨~戙n`EnQsrfr欞挬銡m搋q峇~b驩搵艨鷋v聹鷋抶laF0.PN?*+" #BB6`ZFc_HJG2HJ8ocOgbJf`IgbJb\GCB*B?2b[E:9'=<,TT=-[P>}\膜f赯銕鉽銕葖嶉銕銕銕嶉菗葖葖嶉銕鉽嶉銕貒h悒誘f矇}jTtjUa唹黎q芛蒧pcU蓒mr篹`晥mcK晱瑄蛁|_颩蝏皉晱yrbwf橞qft楢mV櫸洫va葳怊AJ<撗踳雿峇{戇欞朁jybxaowxv}}]woUvsV{u]|^hfeigggegg}bx^{w\zt[}s\y`{w\{w\tkWqlQgbJidIf`I]U@VQ<<=.D@.媥z豱銕銕銕銕銕銕銕嶉搣琩撖撖撖銕潃鉽嶉憳t孍又J;犎怜蟟撟蒍劑稊涿G2邧~獂瓣~眹pT餑~n蛓咯c{j捁ㄤh芞JH;鼒膳芼嬼lwd趥w悛蝮睎x茖s棓e~Z]牶u鰶欞欞鷋驩~|nT ~dhh72!w_pzxuh{_kwwqmqqoojkjmjkj{`{`~u]x^vq[tkWtnTmhMmiPf`Ie]I('w蛁讔p豱銕葖葖嶉嶉嶉搣銕葖酮嵾嶉嶉銕鉽撖銕撖t驩啎鷩戔耨z\eeKl齉枉C3{ehf鬮萛~kS童m耨簾瑳v蠵椪vbk篨揖僉鵏拔m颭▏hWx硐}慱v^楊钂棸早w怮钂qi篔爧欞欞欞虌驩攁κX?  q}q><2yZkpД穢}郭zt{zyvvvvtslsrmij}az_w_vpXvpXojMfcIb]JXT.s]萓q賵嶉銕銕銕銕嶉銕銕嵷晻雱琩琩搣犑琱憍翰欞虌钀嚙歔tJ{钂僄钁唲p`M堮鶼麂tYk炩瓞蛈堙RD;aM;鯆葹閒鼛iV塈疆疏暆bP袺o鈺擢穩be鴢o蚰嗃尤艩躨欞欞篿u  >:'xbK甝怓虌钀讟舅|RM:嚃tZ7:.`VD褑jdK7-'FB4懰熗ukU'!}pXt鈶埸z婼VO>zyД簾礙礙ДДД嶼鳩嶼嶼憬鳩艇|yytqmlg}e~u]umWumWqiTjdMgbJgbJf`I`\Af`Ih_KFA2;5(鉬苠a斢琣琩嶉銕葖銕銕銕撖琩琲琩琩搣琩琣艂鉈派r茤gGEA砥壖欞~驫虌}犗∥棓mF磎e牳銗興塈tO<棼昏漍iS蕩驨觖■m棪鬤陲觸i慡蓁y`s廾[h醐u峞{jQ7噱╞n戇戇欞鱺龢僋 HC984%-,$5-#頇捸痌篸m楚~酃|znfJQN@ytZ欒銨C?5揚篱牄釔蚨壏伉穢儒珗梣{埏拑拑讀|^ri閎Д伈ДДД鳩誧楠|zwyqomlg{`}s\soUtkWnhPleKkgPe[Ge]H^YFfXCVP=:7+vX猻`儦嶉艂艂銕鉽鉽鉽鉽鉽琱琩蓱雈雱琩搣搣蒗j椌躨撜wrg鬮Y?)Ё钀堌qT啎z鍑角ilx僄鸙之l鳦{lT郱钃o咧牉蟘hJ縌﹛n麂dD}醢u~茪{n漡j{e恁鬮欞钃rTQE8OG9YK;m_J\Q=l?7,95'PF3_XBZN7ZK7UL7A8(ZR@F@.QK>SL>'k皉z豱銕銕鉽撖甇鉽撅撖撖琱琩晱晻琲甈rv`塈z磎懦s蟼酒eK痐ZXP簷痡mu椑d鷘雈iaN縑痋蟈g]Qr搧鸙nzby`甡p`Y飾of藶k曊?*no}棫{扆鷒n[D           -) 44)77,47(11#') +0 76'<<214$%((()-"  -)藦血輶埭x斒傺煻斒z媥睄珚舅~埏珗牁禱hs憧誘艇楠滯xwythee}vZ{w\uqUrlPpjPqiTjgJjhMe`Ee[G`[CFH7[O:橪犬r貒銕銕銕銕銕撅瘣蝭銕琱晼晼琱晻晼琩琱慦ur[靰劓TTM荅暙じ驨睊夾洃h挹憬z}y鄋ve靇爧鰼妖褗蠯秀iUo钂ヮ{{]甗津{a嶸r茠~hc珓惇癟噙u誘r繹}g鬮RM;         !!+-;B0KK;KKAKSBHK= #     r攩tX篰駍煻祤煻駜鳩虒駜暵旓慾}仵珝睇珗贗儐伈簾ン簾憧漲z{zwrkhge{w\vpXliJleKjgJheKf`Ie]H_Z@^XC43%釦茪w豱銕銕銕銕鉽鉽撅甇潃琣琩琱琱琣琣雱銊u{f甯爧洘奲髂囃椪h]H@竣r钀瑀aTE晼|b瑑抭^w槤捲帆n蚰y葴ХweQ熐p壓|u巑董菢k鼓倇筍c恌陣bQ鵱眶cvusS觷爧cR>                   i憀駜鵊﹉ya輮駜駜駜駜煻駜駜萷萷袘珗牁拑Д牁牁拑Д簾憬艇楠|間~|wqe}dxbzqYqiRpfQjdMf`Ic_H^XCVU=ZWC8:(}c覹r豱銕銕銕鉽鉽嶉銕艂嶉琩晻琱晻琣琣琲琲擃t|b摁d3'醺8"羃琣sOWRC敊紜狟o帣琠^\O漜楅^飺撟fJ鈶~k蓎w鉈熀|c剸m麤hN儠g|q_虷笢 豱s釓zaL頨礿p                          q蝥;;.赫鵛亥駎駜簁駜駜駜駜暵暵暵萷斒敯袘埏袘珗牁伈Д礙鳩艇|yyvofedu\xpXumWkfNgbJe[GZWCWWCZWCSS?I=3媥j豱嶉銕銕銕銕嶉搦搦琱琱琣堧琩琣搢琲雱蝪u{f漜酮/"趥柦@焠F寘6綦`暀媯wpY漎mbI亹{npX婻犬鉒sR欞銝|is活u蝏wb|獉嶼ぃz蚨埴埸噾|IB葬轕貶TOV`UwaM苀{`橭w晥欞悝p                              snXu\u暆j?7%略phT灉仰荎傺駜駜暵煻煻暵暵熆萷敯袘珗拑ДД艇|間~{zyvrjfg}bsoUmhMe[Ge[GheK^YFaZFYS=`[CGC1t盓s豱銕銕嶉銕銕嶉菗搦琲琱琣琣琱琩琲琣琩斢wye靰躨狺@-狑Lw粁5萉[=+蒟ぁ|~g倢份蓇A/捸钀峎|{g凗{苠u皒alS秺嬤恲fv漞x茈阰驫犬酯bK:蛬挬n漱薊埢犕dm_霾F?4^[L敶鷑齠欞齠穸yc                                  QO<馽棄鄳dj:0#擿匣M=妏蟴鯙卓唌糒駜駜駜暵駜暵煻袟珚ДД嶼嶼簾嶼部{ytmljey`tnSpfQkfNheKheKecFc[CZV@d^DJ@0wtV菢y豱銕嶉銕銕嶉雱銕葖葖堧堧雱靰搌葖葖蓱韏e嵼雱湨/飥;鰝瘼Z@-=+唌虌啈hfYPSBC;.洁麷z蝡v趧q慁旍st惘~{pf挩oX斲|Y陝z誑婸:5)棐衪离襲袓鈭knxo`憎qgZ鉊今p鬮躨欞鷋鷋鷋鷋戇鷖v                                  (( 豝峰dL階駓巘佐蛌oT衖蠁∮蠁嚁駜駜駜駜煻鉧萷萷睄牁拑ДД簾礙ン鳩楠{tqiiecvpWmiPmhMheKjgJgbJ[XFb\G_\JQO;b\B萓w豱嶉銕銕銕嵷銕銕銕銕琱蓱琩搣搰酯葖蓱敿}b銩躨钀堜4&舋>)jt8(蚺怍洏蝜虌鶹v}蛁g貒楛趙瑋礙l{e{g懰{Y眭戔麚懪d{dyv黭←轡u縉黰|畽.(!:5-櫅齟mP晹钀欞戇欞鷋鷋蘌r                                        蟒攃旺唌葋灄n捸菢J>(漹藸蟣蠁鯄篰駜駜暵暵斒袘睇埏珗珗Д嶼嶼憧艇|ywtmfez`~u]wt\rmWf`IhfMf`I^XC]ZCXXFTS>gYC縪妤y賵銕銕銕艂菗雱菗琩菗甯搰葖嶉葖嶉潃漇敼^漜猼0"f焟He趏J=,驩讟飫t鬅xfjW<撗滲e蒯kW僕爩郈祫叔k慒p憍~jeO睆v]埴耨uX嶸鷞nN攦縪砥z橧钀虌爧欞麶t                                             嵹eXBt鱧c恁壧l唌譧↑唌譧↑唌鎡篰嚁駜駜熏煻煻睄桯珔拑拑嶼簾憧~yyqqc}de{cvpXnhQkfNkgPhgPe]HaZF^XCd^DUQf`Ir鉈銕銕銕嶉銕雱葖搦搦琱雱雈嶉嶉潃嶉葖鉈q葖搌咮0=,瞨{~偁B:)藽钀钀遶鶹钃g晜狳}dH晜z聾yn堿竄褗良b塈鄋僊楅  褎虒n篽s漞x磌央sZq銧躨鷋欞钀钃q                                           :=,醏梅捸琣晼犍譧↓蛂鯜藸懭鯜懭暵暵暵駜煻煻暵搡睆埏拑ДД縝誧}zwsskj{`|qZskSmhMe[Gb\G^ZBaZFt敼銕銕銕銕葖銕嶉嵷琩琩靰雈蓱銕酯葖搣撖s堨鬮搌<+諨妵7炂D猘K=+齝蚺b掅漈n黦X鯞埡vX钀唌}_暰菇zl捃ΤQ@}xb臗}v_w`rn晲wx\J傺钁虌~                              &#痽茗鄔蛂琱晼蛂鱧l唌藸藸藸嚁篰輶駜暵暵暵暵駜斒斒袘珗伈伈Д憬間~{vqllc{bxvZpjPkfIkgPe]Hf`It鉈搦葖銕撖銕鉽搦銕葖琩蓱琣蓱琣搦雈蓱鈰y黰驩摁鹽16(r顝<,=+醢cuubHu壓|蘆hK戫wTm蠙洈~笴拒屹t蚸~[氿%蚽d骳A:0熉F;.ft迉黰說                            さ滽琱琱鱣鱣譧↑唌龒↙堧齎譧♂駜駜駜駜輮煻煻煻萷珗珗珚伈羲艇楠{yrofcy`unZskSkhSkgPf`Io酮艂銕銕銕銕葖雈葖雱琩晻晱堧搣琲搣琩葖舅|幮鬮菪阢9姤Qu滐N汫=7&蟫钀驨M:$隆都芠洠穸敯|蚚^l鶬艩曀蟢葙t觷蒺搵--&虭1rpU<1馴鼫蟤o都}瘞v^J漹爩馱                       揭鷾似堙蛂堧蛂晼堨驞譧♁譧㏑駜駜暵駜駜暵駜萷斒睄珗拑伈鳩艇|}rqmcy`}tZvpXojMlfLv鉈鉽撖嶉銕銕銕鉽銕搣琱晱搣琩琩琱琩蓱韁蒧爩钀欞讟h洖Ik趒Q荁])蠸~f鍤埃C,穖n[餈贏nge\葙rZ豱鰽豱砷U灪qqV嚽鱺lSzaヮkbUmv#&!ン~鬋廙鸝c猀钀鷑鷵嬪$# !             }鄎琣蛂琱鱧t琱鱣韥譧↑唌鯜鎡鎡譧㏒駜駜暵暵暵萷暆袘炩伈簾憬楠|zysm}dx^vpXwsYrlTm鈰嶉鉽撖銕鉽鉽鉽銕銕晻晻晻琣搰搣琩潃憀餑躨躨悀偑I=.--}朁vW艙m魌va靮x\砦嬪{v轕收loa藢rU痑u灩袹-#槾:0!q抩"均9鍜造rafra囮}薯鸕鷐钂屨 #%   !#     ]]I罃唉琣琣雈雱琣琣堧堧龒↑唌譧☉懰篰蹁糒駜駜駜駜暵煻斒珚袘拑簧誧滯zxqmg{a~u]xrWx鉈銕銕鉽銕鉽鉽銕鉽銕晼晹琲菪搌蓱搣矬祤钀驩蚽嶍幓爩伝yvp棷蠗覺nP翮孇hUB挶鶭鯠{驨穸}掑伒煚蔑峇縤痀兇芚! fZDr戙鶳Ls鷘虌齞劗簫! $"'%))""!#! # &"$"$"!   ""$#$#$"$"#"   # &#$#=8-鵩瑩琣搦琲雈靇譧↑唌譧↑唌譪譧↑懭輶駜駜駜駜煻煻斒睄斒袘伈Д嶼}{wqmg{b~u]w滽銕銕銕銕鉽銕鉽撅嵷晻琩琩嵾琩琣雱捔媢虌钁掑?4靾葷y鶺灩袸}_廕y|瘐痐篹驨齈n縢臣嶉qUTO>RP<{瑄kpbO{qRs儤龠蚋汕泖虌鷐齫癡 &#$&#%(')))* ,*!)),*))))))'%'%%&('$"))('&#'%!('%$&"&#  '%(')))0")*"))('..&'%('&#$## ('$#$#$&$#('))$#""%%! #!94*玁緒琣搦琣琱琱琱漅蒤蓱鸁份煚攩仲掑藟j藸藑j掅藑j苠懭篟旓埏伈伈憬鳩楠wxtlhjx鉈嶉葖鉽銕銕鉽瘣撖撖晼琲琱琱琣琩琩艂繒瓴躨搹XE7坁|}撅s轀kT藪p鞀q郭t漞钁騞龒uY暷k楷|t m礙堈j89+ukW嵼爩t鷜騞劗t '%'%,)++,*!/*)),+/*,+63"))&#(''%))%(('(''%,,))(''%'%$#'%$#(' &('('%&/*('('+',))))))))))))),)))'%$#))))'%)))) #!))))'%,)'%('('%% " ! !(),?:-箹荷犌琱菗琣搌fJJ854&URHUSAWPA[T?ebKtjTpfPYS@f^M_ZEojRtpUkfO旓睄拑ДД嶼間~yyqni童z撖銕銕撖銕撖鉽撅撖撖堧琩雈琲琩雈菪琩嵷漁蒢ssc埬hG顫~^k儱踳l妐おok抾齫尖V:輵舨珧E=3睟漍嚜嬤鄶98.u]Iv繩冀硐鷘钀钂怜,*,*)*",),*00!-3$3.!0/,,,)/*,)('0- ))('/+))--",*00!),('$#))))('('('(')))))-"))00!30",,35#0- ),,*!0/0-!))))0-#,*,*,))))),)()%% 0- 36#,- 40")-"))(',,)*")* ,,)*",+,,)/ %%,.(+*'梤兆嶊琣琱撗JC9(% 12#98)?>0JGOM5?I5,+"韍睄埏伈Д簾誧間~ytno滽銕銕鉽銕蝭撅撅蝭鉽琩搰搣雈葖撅潃舕漇贗朣驨讟钀钀菢t﹛琅al瓞陔6- 褗呏hT亹莠奱邪ly屩陸q搚 駋倍鷎46*4(蒠z怌暾鷑钁颭23$3.!00!-0!,/02!33"74$63"63"87'3-!33"3+ 0-#0/0- ))0- 33#71#3-!87'30"--"00"))+(0+",*/*00 ,*,+)* -.$58*87'63"74$27(98)02!87'74$/-33#57'27(40"44%54(6- 0/33#87' 43#98)98)68*98,10#30"22(52'74$57'22(98)16%:=174&87':9,33#%"熊滽堧蝟VN;43+68,10(83(52)76*64';;,88)FF6ZSCVR@RR=SO=_\GPI3螫篘斒埏牁Д簾憬}zyt竣甇葖璈潃撖撖瘣鉽蝭撖琱晻漇撖撖蓱銕嶉潃憐|藱钀驨醐7,茈蚥_^U~b袚荌嵿P\Q鹺鷎筆~搦摀眥~hM鯬翅墨L4#佌捖b^I熉p芶奰僭踰v葧霅uo\*)68,76%74$74$%$00!44%3.!98)98)87'98)76%76#76#3-:6&84&40"74$54&6+63"60!0+"/*0-!),3+ 30"3-60!6- 71#3-!30 63":9,:9,54(84&?<+98)98)57'76%:9,98)87'87'98)87'D@->;)98)<:+>=-,.:9.98)98):9.<;.?=-?=-;:)?8+;9'<:+;9'><+;:+?>2<:+57'98):9,98) 劓鸀j770CC6HG8JI:FE6EG8KK>JI:LL9LLb[Eb]JIE5煻睄埏牁ДДワ艇{z竅甇銕鉽銕瘣瘣鉽撖銕甇撖蓱嵷鉽鉽鉽銕鉽撖躑讟蚺lrcR銌欑婦晲g祤ルMJ>嬼鸙坅v恣钀晛搥dX?鉥zi[>蛣蝶{jP隞虡牒MI2縼蟟|n晙洃欉鴨gN&'&(79'87';:+?=-;:+:9,54%<>/<:+DB1<:+;9'?<+?=-A?-?>0A?-FD1AC1>;)87':9,63"98);:)87'76%76#87'98)87'98)98)?=-A@2<;.?>0>;)A>+?>0<:+DC4A?/DB1HG8<;.CB176*DB1A@2FC/A?-A@2HG5DC4FE6JG:JG:87(?A/CB1CB4DC4FD3FE6FE6HG8JG7OOD1EE8JI:HG8JG:LIXUCUUC]^J_\GhfMgdO670袓暵斒埏埏埏伈嶼誧}憫甇鉽鉽銕瘣瘣瘣銕鉽撖菗嵷鉽撖銕撖撖嶉鉽{麜縔唇6#靚摁E;+蝐sU嶼鷝虒{x[m傱蓮k敯譝∥餔GKD疻梡晥z\痽昌蒗篕CE6餑QMC畟voZ灪{賵u灪考qdN+.%d`L2/!VR:A>+FH3JG7HE8D@-AB.CB1=:+@<.=;'==-?>+LG6FE3HE8FC3JG7JI7HE3FB1CB/A>+A?-?<+?=-?=-?=0AB.D@-FC3FB1A?-A?-AC3HE5FB1HE3JI5FC3FD1JG7HG8JI7OO>NN;LK9LI7:8'EA/NN;QP9LK7MI7JG:NN9NL;QQ>QP;OM?72'LIUUCVQE[XFWWCWWC`^HaZFYX@\XGWV@[XFTQCQN@SXJ-2&8;+GJ9JG;GJ8CE4FE6EG8NRAPM=TQCUUCZWCXXF[YDYXDUUCXXF_]J_\GQQ>21(埼暵萷埏袘拑拑簾嬤丳諯銕撖撅撅撖鉽銕鉽鉽銕鉽葖鉽銕撖鉽鉽撖y钀qn牶`M:蹁眲r\K撌噙aTHv鶬窱縉癡wPZQA恣踾埴FE4鉦褋搧#"鷿榭g\惇|m`痧}煻挩wa1/"NF5wo\fbN8+!UPBWV@C@+LK9JI:LI7JI:HF1JG5QI6JI7JH5OL6OK7SP:JG:JI7LK9QQLLUUCNN9QQQN8NK;WWCUUCVU=UQ=WTE92+瓴熆睄袘埏伈拑ン芚甇撖撅銕銕銕銕銕蓱嶉葖蓱銕嶉鉽潃銕葖潃y鶬玃>9(摀^e萛間幙 縻窖i睇峇蟘吋K?yOL@鵏&(棼△踶鮽魊scOeWG飧_PAi馳I?,TE1DG8dX:a^Gb_G/, b\I=;)WWCOO>SR=]WAY[ITT@HC5UUCKE6JH3SR;ON:RPAWV@FD2JJ;TS>TS>WWCUUCQP;NN9QP;QP;VU=SR;QP;VR@VR@VU=WWCSR;TT@VT;TT@^XCWWC^XCWV@TT@VU=WV@XXFWWC]^JHD3\[I\XGCB2HE8\YJaZF[XF[XF\[IXXFWWC[ZDb\GgbJUP:gdO_^H_\Jc`Kf`IkiVkhSkhSniSqjVqjVqjVhiVnjVc`NNJ8]V>olWhgPjeOfaKjfRgeRTVD21!EE6IILLTQ=[ZDWV@TT@XXFWWCTT@WTEZWCGF3祫煻旓袟斒伈坒迮撖鉽撖撖銕鉽銕銕嶉嶉銕銕蓱嶉鉽鉽鉽銕滽v讟驩爩驨~f囿{QK8馦伅 徽g縼銌鸙齝堋v 痑鼖s媟繪v晛ua?瑵寫dTrr`+%zpVBD&嬤ZZCroRnfQH@)hdIf`IiaKe]Hb[ESO8f`I_WBgbJaZFRM=ZWBJE2jdOON:SQ?ddQLK:_\GVU=JF2gbJ`_K_Z@XXF^XCWV@]WA^XC[XFXXFWWCWV@[XF^XC[XFZWC^XC^YFf`Ie[Ge]HjdOb]Je]HhfMf`IkgPNN;c_HieL/.!WS@lfLidIkfNhgPhgPhfMgbJSP;njVhiV]ZDa[FniSniSkhSnjVqjVtkWniStkWvpXwt\xvZsoUxw\HM>GD5cfPtkWvq[xw\wt\vpXrmWqjVmiS;;.VXGJI7GE:HF5DC4KN;RRALLXXFXXFXXF``NnjU椊輶駜睄珗袘抾撖銕嶉銕嶉銕葖搦銕琲琱晻雈艂搣搦葖漇鉈ぎ讟钀钁遶#橁昏攽BB?芞}sbK蹓銩え鱹掑{\銝暙滲xgR褅蟜y`Ёes2=1sdW&)mfLrfUIC/f`U;5-_VCt`HE;~w__[FrlTFB0ijSjdMg_JspXrmWniS^[FjlTmgSQQ>miPgeR\ZHjeOabNYUCdbLedMgcLgdOedSb^FheKf`Id_Lc_HgcLgbRNJ:ON<_]EfbNkiVhhShfMkgPhgPhfMgbJniSpgTkfNniSjiPtoW''cZGojQYWE1)qpYrmWqmTtnTskSqnWZXJgbNrpUqjVc`Jg`GvpXvq[zt[umWspXumWzr`~zay`zcx^}z^|yab`JOP=khR}dzby`}c|e~{cxybwsY|fHF4NN;OO@=/QUCKN;LL9TT@XXFQS>PM?VS=b\GlkTZO<葒紛葺斒睄阭甇蓱葖菗蓱搣蓱琲嶉艂晻雱蓱嶉嶉蓱琣蝝t鬮悢vgo堿7:8鈲kzwdue擿轡蒆爩蠗|敯cVHgB}瓴矩o^懰nj[zxdOO4?C4)ba\D<-HG8JJ@?-?<,GJ8NK;PM=QP9WTEQS>UUC\[Ib\GiaM_\GFH8螳萷斒睍滽葖嶉嶉雱琲搣搣葖嶉鼱晻琣雈琣搦雱雱嶊v葹虌蝜%)(鸅儉痦XXCf鶻{tJ8穔摮媢洷茩駎_XI{{n[言adLG>:$$dYI^\HOI7DG8BB?wmXmcMt\_[KiaFvu^G=-~kxs[~}fe|by>=/jslXjfMqnTzb~fxybwt\xvZvpXxybwt\rnZvpXxw\wt\wsYxw\{x^unZvpXxvZ{zaxx_mfRxybumWunZ_]Eyt`y`xvZxvZ{za}s\~u]{cxx_}by`y`gy`|ewp]a`MjybPM;li{bii\YKGE1jYVE[Q>zaxbnlljlpjgjnkSfdKllldOdaR~crpplrqlmmjrVUBML:XXFGD8JI7HG898,ED4OL>QO@JH5b]JWWCXXFXXF\[GddQ_^HWT@RPURAON:LK9KJ:Z\K_XC蠁煻矇撖嶉嶉葖鉽漇龘琩琩琩雱琩艂艂銕蓱貒}\廗钀漡$縪杉zLH=s 遻祉峊lm釂揤晸秀VAbV7~y`#JH7RI3C@(:@2_SHUM6[bQ g_HMH4kmgU_R,xoyrrtsyopxtmkUnfR}|eB<.^XEneQxruxvqsppwyxmcQ33&?;*LI>A>1HG8EE8LJ<20!87(PRCRRAWWCSR;MN===-=;+?>-[XFBE4cZG縓希隢銕銕銕銕銕琣搣琩琩雱搣琲琣艂雱琩諯yb衚芋bbW虌痧*&" 慴仇iC暯u[L?[VBecXh^Gj<9*#BD;A;3襯#!IC1pZSCo.&y^rpeTkcIr}eq~k}e}lYN1u|u`ZEuoml|eoojRh{donUljniSoolp|fhpv|s]oyerottzrruwqwulvxwtwkx;7(}|\[A]YJqlUgqRQ>njUoyw]GE4zlVQ;s|wmrrZND3nurON;vYw{cRQEur`{uutuzsqvw{agnuxc,)KJ8CB154%CC6ED6HE8HG8JI:WWCSR;LK9UUCB>.CB4NM=OOAQP;B:*k蠔瑹潃銕銕銕銕搣菗琲雱艂菇搣蓱菇雱葖嵷豱|^篹嵿$鵗蛣苺堭鸗繳wd握wn]-'|n^xoV:5#{WQA[ZCs# 87,heJw[,-! ZTCriTmb]G}sa^\FWUAc[EqpgRmpmmgQpkQi|xdjeOkppnm~{cmt{xclgjmoktpprrqWw}itr]vytbkun\vnnntoqptpqrnyb`Pzg_^HXXJ~uaRN:dbJnhRwkfOqnQskVswHH8d|ldR|az`yySQ?{ugmuxNP=~fxvq\7;0VSAwwXR>zu_vzq{vZvoZ{D?+wq[xt`r|jOP@JI:@?/QUCGG:II888'NKB?<-ML:QN;RRAMN=>;-A?/JG:JI7XUCOL8z艂琲嵷嶉嶉琩琲琲琲菗琩潃撖蓱鉽嵷漇鉽穘l銋躨蚼qphP麷珓椊俞OA87,UPD秸約祂荎蚺痼豕73)roY^T-}y]rmeMru_jihi}d}eo}y]oljipnvplnnislsoWkpieIenxfdQrpniqgeR~hhyu_|wclllrnnlijprk|i\YFxub41$46%my|ybxv_qmQnjNZUAu^xq{[\F}zf_\ILJ5nx`ZG@C6ifQjoURB=<)洽96)^\GptjhQrkRzrS|cwtahdPUQ?~u_H@,xvuxvuh<<1,- HG8DG8EE7EE88;+1/CB6BB4LL<=<+54(=<0HE:98)TOCXUAu蓱琱雱雱雈搣搣蓱琩琣堧搦潃嵷銕葖嶉潃蝎m銈钀鬮钂猺囋^H6息猻麶戇鷟晸+鍭梡瑂籀f`M=>0VWCYWC\YE?>/xoXo|bKG5wiPynT qiOolSYU>NL7谷g\B悍:7'xrYh^JZTQecWMK=SN> KK:艘FK@lfRq~}dh_E~eqn{e{pxlXoox{enne^Jtb}holWk{derljkijtqvkv\sulaIwjpsss}e~xdprqsnllpr~~jCC-tpZrmV;8.D?/"$xydCB2sm]}f|BA4|fypY|oXikkV|v]je~akkkVt|eprYwkU_cR\[IstrZ`aKKN7edQk{hTTDqiXh_R3/$b[EwoZYQ<揮xrtuwtuuu|99.KJ:?>.<<.,//.!GG:?>/BD4GG;9,z蓱雱琩琲嵷菪搹銕葖雈琩雱銕鉽銕葖蓱艂憳r搷葥搊si^**$JE5\WE7A0/0$~f暊啥荎皉^("靚斲hB:89=3a[ETZDOH8AB4YS@WO0xg??,yd`PitTWCKM0CC6PNE:7(@?/SQ?v酮琣琱琱菗葖蓱銕蓱蓱銕嵷嶉鉽銕銕鉽葖敼ㄑw畯虌虌棓鵱坏{-,$FG9OF:XUDII=-77.<;.:9.,+ -.&87';:+>=066'RRA_\Jv蓱蓱蓱雈琩蓱嵷銕嵷銕琩蓱鉽銕銕嶉銕搦漅f銇鬮葥嵿蚘ㄆhPx_遘岏橪鉈嵿銈葖譧孍∥苠蒴轕效YK?*+67'LI9HD1LI;-LIML:KJ8LG6JG9ND8JI;wbO& NL=[YD74$GD3kiUebPxq[xu`qnQxu]MF0nWh~\郊ifxoa()$s狊-+!洮pD=/~dzMF4芡KL=vukPtokOtsp[rwjz]ttjhbJzdvnW}e~hlnyw`qlyqhpttzbkpruoYvt_mjUcu{cqdynpmisrpux\lnroWkeMpkxxr}eIG1b_KXZInhUb`Qy87(B@/GF3=9,}i{b{awv`spX~hfeRa`K<9*|ydTU?vpUoNM>ZUDE=*RL;`[FSP=tq\erKI8toZneHcbKqjSvunryxxiuxv`n{wup}{_zp]rf>:/;;.00!NM=@?/BD199)::.76)22(10#63$SNBUQ<滽嶉銕嵷嵷葖銕銕撖撖琩嵷撖銕撖嶉銕銕甇fh^刓輲搢銡搣蒱鉣SJ;92$##==2@@2//'(( #/+96,9:*+"&3,"kWI蜳渝犗雰捸茛艅皛袽vYHD4&%/6+MPBJI:MK@KI;EE3?B3MG7CB6A@2LK9LI7PP?DD4oaC蛚~auhzfJ9:+;5'A@4LE0EF5f\GZO;qqUybybkkmrgU>ry[WA |[R9hdQ馳ZXP韁zc劓飪zzdoxiXVE}egozfIK<}n~sy{rj|wu^wgzrytlptrm}dlrpsrpt}hn|v_{bnmkpjus}yapuurreppj[U>WO0zx`*0[YGWVFnp]e`NfdMjwxcc`KD@,21$sp_^XCTR>~eVVI~xguoYuleQlkT{wa~|d41$PP>g\Hi##skWokToqyy`mcJqqlyuY|c~|iiieQrlX|rpxqorKK563";:+;:.55'@>4>>465%MM=87*GF7NN;KJ:{撖鉽銕銕嶉銕鉽瘣鉽鉽琩搣葖蓱蓱艂雈蓱mzthlpa|nS|mSv瑲幙瑑瑀嬲wzcOH9 /.&690HM8JI7JG:NI>JG:ED8C@1GE8A>4BA/EE8<:+@=-?>0<<4$$/-wjSx]xwXp{lW2-!,+EC:RRAPPGJH7HG8PI@LK9MJ:II>HH4PH8-<6eaL50!FE;ROA=?2颩}峏j峎q|`QgXN=oua}w_x\n}^]U?~tYwiTj}b~eq悵~l{_vkS褸rmXUG屆fv~d}d`NKK?DJ:じ}`zx^zdx~twxxsmJK9tlwu`}zatieO{yoXljQlxfzw^nopom]~yb}f|jp{elosmtk{{waspjtxz_p|cn{v`jyVPAh{ritpw~ya@C1?>0UVB%$!v.-pTQ@^ZG``LgfSOG8tp[tr]e_HPO?AA2yw`VT@{xcDE6OS@lkW{|g><)KI6miVo1/!jfTwslU~euqurWkyu]m}crv}zb{qc`K~cfxrY~a}zc~u_vr^zwdEC4==2:9.1/$87'AB.HG8@?/<:+;;.UMAOOAu甇鉽銕銕銕鉽撖瘣瘣撖魙琩艂雱蓱搣搌艂鉈i{qp{xq{efNYXIRM;5E5EG6HQ>NL>HD3GH:A>0EF4HE8EE6FE6NTBIG9IH9EE8GH:FE6DC4E?1EB6CD4JK:E=3AC3>=-=<0@C7;:+OG9TQ>RP?PO@LOFB3HE8GH;FG;IL9NJ;&+蒗g諴}SF<.0&OP>fD釂{韇G83xak^M:rikktyvxxttg賑JF8見陎`me[M僚hv閎|41"~a`VEy}x{aign|waysYyqYxbipiwf`I~jslV|g}rmybrqWwx`t`]Fxu^yfpkU|s]tmRtoXecP|fvrtvtp~u\vsroS]ZA~zaLG2}zaovrVpkWzfeyze}y^j{ekeOhcMewymroW86*X\HBC/LI;aeR{ybKF9VO;fcLcdP[YHKJ8gcLUTA]XD{yd<<.cbNus\OM9hfRhhPb^DqMG5UR]ZD^[Lha^Lxu`XT@LD4xkojTmdRov_zu^eaKf`KnjUllWZTByt_xgw`^FyjzwaqkZheW('.-":9.$ LP?;=+=9*JI:96%QN>;;,r嶊銕銕銕銕撅撅瘣撅撖琩雱嵷鄐蓱艄靰鄑f}kspuulu|v除ifjW)#,-%@>65B5DF4FD5@C4NH>QSCHE8NM>HM>IIIC9EE6DC3IG>NK;CF8JG:BF8JM=0IJ=ILC@6TT@IG9LIB=+(,!:8+zgdz〈Vy]]?tA1*~V閉|_nYkQcMJ-}bi]E糧e惆縝翰間~楊麩部u匢釭 pd=8-zc~_fbU牁}eX_N[SH撚uhxvd}lzyuixvrYpxis}|d^VprkqsoWumr}h|s{ytullvry|is|dyu~gxpdppxrZ{ewoW}z`nh}zfyw]ZVDGD2\YEKE4tur^:9*IH5TQBvq\vtcnkX'"YZEURBIH:JM9F@/g97%niSpiSOM:PO>]XClm^daLvo]ktq\nd]Jrya^_RXZEYXF<70kiR|ucgdUEG/|TP=c`O77&65%(+88,A>/DH6MRC55%E@3EF554%JK<|撖銕蝭蝭蝭蝭蝎瘣撅蝭犍雱蓱葖蓱蓱琩鉈j~smmyumsryury敞失xs]GJ=42%IC7JH8GH:GG:LIRQ>KJ1"reUIXR6MU8>="#"oV>{^tV外jnnfL|peJ}}pUeo|]^urZ飽~f~|瓟(+! 94*鉎佰JQF窏郎^\Qgz]?<2稂腫qVdxp[PG3}rW~dzuZf|hyr[rtZDF>}usYxo\~{dzedl|y_qkvq[okTf~uaozw^{d}w`j`[Gxt\wt\hcMWQ;xt]vnY~z_~ewV}xag|_igP`Z/,/ [[IkjU\YGLJ5JH6olTtw]00 xb`Lsr_XVB87,}kzr^QP2A<,65%/)C=,MJ<89'00%?>/CC456'?>-<:,@=246'=?042&??4//$<;.99.JM<咯~撖撖撖鉽撅撅蝭撖瘣撅琱琲搣琣琣琱鉈huustuwo|vqursrss]XJ?>+B?4EE8FC6ED6EC6EC8JI:LLCE1MOCF5kkqt~va榭QpQ 0 8BA6Zc=4 :CB08,$*0n\Dr_uUtW漲}郭{|襤Ё窖艇w簾佼竣漲侄98/A<-饕惜|妢fQK;媃句ufu哈_`P揪j}ixv_ozfn}ejk}bpyvcyclu{xb~gpnWho}hlo}ezu]upj|a{{ah~ciybil~yb|\~y_i|f~ay`jgfrtyl{{dlh}zfvrZhigjSJ5VUDpr]\WE{zg}kII=DC2AC3ejZ79(MJA@2VUBomWLL62&LO=HF5egO央}eocSxo}eqwq[y~h{d{foo[YR?>=0:=/;;.88,87)--!68,44(>@087)==.v潃銕銕鉽撖銕銕銕銕撖晼琱琱蓱搣琣琣酮ezuwxoqxw}sxq{tqttz悵npW46'70)ED6II;IJ9FDFNU798(;6J;01D9:83n^CmTlRs膘竅翱t仴漲嶺え伈嶼簾羲牁价熗>>-ffWxcsc|! wwa岡l~hz梴野meQb]Lyt_d_Jqsazt`OP>d`JY]EbZJGA;|lddQicSwtbVVGkhUMO<{dzytZkhgRvs\{y_~{gldO\ZIrlTWWCkq_^`Oxuawt[pmWa^K{v_pmj~}frmW}Ywu^LL:tlXts[vt_umVkgOzbx_}i}fspXvqZrmT~ycgkiVhaPFE4@?/?C4@A-]cNON:b`RPO?GEGC3@<,EB1gcQ;9*]_MhhURP>KJ8|?>.TUCVX@QJ8EG5ML@4yk~vuvyx~|葬zxtneih$07K3,CUYO-/HJC<-SF=?>;xWgMtccUlv_捶陞k宒y憚牬膠~芛棽挹炡篱FC7><3哈cr躉揚vtb咱{}`伒拑}|u\*'$CC3@=(E@1GA5:<+76'FE6;:)1.';7(A;+HB0G?4JH5EE4SN;[SA\ZEED1CB2CB2>=295(;:)<:'<>+?>/44(DB1A?-CB4FC6FA1CB2m]E滽彏門圊橁xYIE7CB4HF3QM>JL7GE5HE5@=/MK5DD3ON=+DB1JH8>9*FC1GD4DB1CB48:+63$56)IH5?<,JM9ML7JG:CE5OO?|{g?>+CB/HE8@@4PO異嵷嶉琩雱嶉嶉撖銕鉽葹艂雱琣琣雱琲搦琩嶉zc{{rvopqsvwsqvwtssx|qqwzy神kjUQ[H]hSsrpiz^~HSE{k:E:jmZbeJ{pr|wzyyumq隍+89_g+/-%=E=?5D=:LJH55$htbO埮妠揮x恲nン`wtwZ劓|bGK= 侜懂pf帚瑲宵`N馬NH-庛薊У|xe炫}caPKG-/+44 A510,(8-"+$#>=1++%KD:AG<99.-0!36$D=/!'";8.@>5#(#(#(#.'79'76'7>,11&+/'蕉篣酮葖o_Y?>=0>:,880;:.EB6?@279,;>/CB4HH:8;0<<-7:,;=*DF5BB1EG3C@1?>2;:+88,00!66%/+ BA/ED3?>032!>2KH@/A@6;8*58*-,OL<74(ON@;:+71#JF7DC1<;.<<-@?/DB3HE6_\M^_La`LPOIK<:<-12%/*0.43(00&55*$#??3LJ7igO{dqlXusZ_^L~xcfrqy{wiiheR FA.@;,X[G--"47+#"0/!CC6AA1?=-?>2x艂嵷鉽銕銕蓱搣琱琣雱琩雱雱蓱雱琣搣琱犑t^}orougispppputmsyrm}pqnwptszu~k}{hllm[YjUwsxrxtm}rv^|rz`RY=s|blt^xEE;mi_kmWjV@iXGEG6EE7($7T]+GJTE@/6:r踰SS?Й}竣妠Дが蚍芘議芘妠郕窲杼QDED2v挐穠覂$ m董_ZKncNkl咱哈w}u\w咻q岈~el鉓ˊ蝠[NA伾JN3nmiU[ZH蘁z齙wpP臟qU\T1^ha_WaFA&CC6{jFqMi桴楣vn\韎`/#uvpusf^HygeI}eic恣qkVc<*JK9JG0?@/DB1EG756'@>2CB6@C4AC4;:+57'HG8A=/JD5FE696+;:+;;.87)55')- ><,rr^sn[|gx`xw_|`{r[k}w_zkq}wwqX32#:=-A?-+(?D/14%,/!-.$HJ:,,EB3>C0BC6}艂琩琩蓱嵷雱琣琣雱晻撖嵷嵾嶉酯搦琲琩葖n|uwxtotlpstjopmni~ertxormpmrxoqupwppxzzcimVjwbdt\o}ay|x}~w{mvfhQzyo`S1<.EC:>A/HL:+;B3QPM=2@;4dbL齉褋gitxMM<楊じwvcじ憮饕除祝痶 平TRF覂箹換kqgU|;4*PL=褶~`cW駃受衚麇鑑|`剸≒怗佶捶 tx\?+B.{/rFvN摒筋kbK醟畹qVI;&tsuvroecDz`~PXfXV7miSFC5NK;HG8HE879&>=0CB4FD3BE6==0CE1HE:RPA>@/GG8CC6DH8$%21#0-<<0?>298,:9.A@4;:+EF:RN>C@3MN>?>0BA/JC4)/::0?>-DC4<9*VJ7HF38:-/+/-@>+60%_^JwqZd\Ixyf`_MJG6w~hfcOujmVvw^RN=xq98)FE6+(CB1><-:9,A>4#"10#'&HH8,+BA4>=-76'{酮琱搣雱搦琩琣琱琱晼屣嶉嶉嵷嶉嵷嶉嵷鉈|uxrsutrtqoourpsizrwv|ppprqrrpsxnrpsxqr{tsbHT?PdQIXD]cPZdWkz_zs~rv|uzuyymUO@DD6FC8BB8\XG#);GH=C;399)GF4>:+03&87,=;+HD3DD1H@-E;,51#44'JI7JI7pjUyGD3UVIXUBWQ@kVSAvt][YCmyJM<_ZCxnlT;:+HE8FD3FE6CB146%<;.%((-?>-@?475'EA3AA1A@2u酮琩搣搣琩琱琣琱琱琱琩雈琣嶉銕嶉銕搣酮zqvsutytrsysv}mpnv]HF4K>+vg^Jnttupstsswswuxoruoorqyb\gR\o\LVCZlUY[SU^IUbK;E4zt`nWhvYukvuJG<||FJ;LH;DD:IL>+.0PSFE6DDDiuhfWySㄕ╡牧牧假酊尼m螃換葫葫輔譬帑 &$riV嶷千l[lmZ鉓﹞|qo\r\caP窳颳ZN玃懊式揹蓮觭己q\褽bYHぞu 瘐oEgZH藻r蛣z鷩tpDlYsfDhnczqOUbTO<l@.JI3;8*ED6AA/88,:9.9<052'11&22(84&>3&40">A1@:,85(A?1+%:=.65*76'16%0-43&98)%$1.%88,?;(QQ=FC4:=-?6)CA/CB1FH7LL9cZDLF1>@0:7(EE6FE3ZWEmqZ.3"b]J>=+op[;6'skgPONN]I?T>et]LTF{VT?mst20$JKB6<8\g0IPB?8\6*VX@rjb章╯貝牧酊牧炒ㄒ牧﹝尼蝨ryd.-&橆GD3蚘砲臘﹗Q@}v\E>4\YKxzh{d韍鼪sМw擎咱ず~戴vpYx鼚~kF鱠r\;洐鉥q籌T$f`xVji_zTRc[UD,-lB葵躄拔戙窲o~fAKOA((vtxrws\orXuqUeqG`^kMoqSmkJ0 QS;:/!mOzZ_b_kkgasP5撞z^sgbVd`EXE4UO<6<*<>/<9+/+99.;;.8:,3.!@<.KJ:ZH2MD2PM=14%CD/IG6A@18<1nWEZM6+*.-ED4TXID>/99'QN>LN?>=-58*@E/v{iYYG]]KUQDhgR_[Hup\GF4EE6FE6JI:@>-LI:33%^P>39(BB1C@4RJ8FA14/":7'JI5E?0}滽銕銕銕銕銕銕銕銕嶉琩蓱漇嵷漇嵷雈搣鉈jtxvqurkvpjjlms|rnZ!d^QA8(z|uwzvyr|oqup{vqvrtqlt|rquOYBR]Ihjdwbqh|cn^m~fqkKRAhvj`lYqi{ +,+0OW&;C1]i:fsUb[jt]MMEBI9r{g|疝x夾壯ㄕ﹝ㄕ衯 鏽ML9RU<挾yIG<悚DA2HQDlIKB籦邡w醡陲└鰾hx晰徽RTF挳}Qj禮njuiL籌^b`_矣mUvQURkaL+*wL筋徽JG3_XB眵n44)sxyuinhPtqVrrOb3搋TjRhmL|cD0TO=7,頛嶈舕隢藜杉葖橏太庰j鬩隅~蠆烊E0膨mR?3)QT<+\]MNPBNK9;8-;9'>:,GG8>=-II8HD3RQ:(gfSHI8VQ><;.=?0JI:CB4,,@?-44%B>,43#1.F<-ZRA74$65'HB3CA/?>-r敼銕銕銕銕鉽銕銕鉽銕琩琲鉽銕銕嵷搣搰鉽丐qrqqvrmwvrsvroofyZU@mr\** 迭ppqvmp{wnxruyssv|xwspv|t}FS>NeN/7+5G?UeRPRBomomvpponk}tWaTAB2:2$mC!'*W`Kytah[bl[SV@goX?G:;E4igYafU~pt~w眸岳|{l 50"_dMRW>崿丑_YBkkTmjWyilfN}sc|l噸魱祠噶x繡47/ぜWQEk慰wf縛hGq矺鞊mcdaz_衧p礿xNc\xOhbN,,F>.z擎olW眓妍SuDD5rwvtkgR\]IvoWs`LwrMnQ^FoMr}`O:WVCI>&蒫嶉嶉撗活~躈身c捘k豱銕撖鍉兆諨mf[F1(50 D2(/+85(54%76*-/"KF902!=9)bM:.."32#MM=DD2[R=cZF88,84&::+11%?>0SS?AA1<:+FE6:7,?>043%B?0FD4hf[30'@@0DC3@?/76'=<-02#13#SN?<;+DH8^VCSE2YK-DH8<:+x撖鉽撖撅鉽鉽撖鉽鉽撖葖嶈滽嶉嵷嵷嵾銕嵷器nxom{ttwxutrqotlvavUWK郊rknoosisxwqrtyyyopy~pspoimt{|{d[cSf{`nwcFUA^kX00"c{bow`Ysb??2ieK靮dX>79-mjsqxw|w狐UdQvvneo_ogGUE9@4|nrnrVu迂o暫b[Ma[K\YH晰帛zxc|yri}fvp\"&鼥躂爢避捖砲}雪ztehO妠牶qapL芋y蠐zde閎na縈gd豸jあvmCZjJ>:%32(0/!teK籧撬鼥羞jv>>.oqvtoVG1wuYTWDvKepoRlIdpYqE6IL9F8$蝺嶉嶉貕VM:檺誣rW哈瓴r貕銕銕瑹嚁縥肩陊cQCE?,D<-:9,@=/@<+EA354%33(?>0NI:((((51$QG9MC0??0#%II<87''%@087'ydLyiQ]SBNA/CB4>:,?D220:9,@>203&u敼銕鉽撅銕鉽撅鉽銕鉽撖鉽蝑撖鉽鉽嶉銕瑹蚙ox}totuxsvthsllt~QPDwA?5xprjqpk|uptsrout|wyuw}uiqlplqEUBaxdjsfmwwT]FGX@_dNsrxdQ>G?t\J[UA44+fmjnnlsxpjjiporqlistwvxu}x~x}zugn^zd||hn中wpvo`vzmiOekZ痵役洢郺rgSqi{|~a{期_]L霽mD靽kcV@]}oJf[*$gルil耵qwS67)>B4fWCveaR# 尪?>/umR陘~暋ix52!~xdrwwqsjSxwbIS:[|R`qRc{eql[PK?E5"滶蓱葖嵷刐wPB3髡炰m豱銕銕鉽膳w{澈`IE?,HG5B<,:3%B<,LL<.,87);:+11&JC574&GD2N@/xgK=@/55'21!98,JPAQQ@AA2?>/A@2?:/96+43%/.>400#@?/67,;;0ED4<>,87*LJ>IB2')dYDE=133%8:(77)?>-FE6EC8A@/|a敼銕鉽撖瘣甇撖鉽銕鉽銕撖甇銕鉽甇銕銕瑹瑧p|wtsnsmsipnvlpstww|tmsqugvsrntwowqlqvtypospqsuqturhQE6K6%蒫嶉葖瘛縎欠靮樝健州刐f豱鉽鉽漇鵘→艂}]鮿~^FJI7CC4?>0LG9OL9OC,oUBH?.EA/<=4>6(+*97'dP;<;)UUC3/ TSFSQCDI6,,::+00 G@1J@0,+:4'GE/C@182%'#8:,*-"EC/ED1GI7OL>FE6OM>A>+OF67<(A?/hXD8;-UO>>=-CD/URIA=-LL9<:+o滽銕撖銕撅撅鉽銕銕銕艂銕甇隢撅蝭瑹銕鉽畽j{nvrtmnuuovrrnqrhbVd`K}ybwstwupryolprpsxopqnulprlvqztsusrpmUsp[=@0AOJ騿{聜:*/4/:=,LZF{xmoe}ghi\nYK]M-:,EV?xrOcOc}b\mUZpZ3@,O]H6D3UfRc}em|`~sdz[voR[Lwlyj{}q_Hxu~c|芮{弁ps幼hmXqj盛!'AFB磃Z悛pq搵nf嵿ufd22*26'_^Knvsuuusc`PYYF儦琣棎握epy~KE3ljXxxvseZEuu]IyUx`7|UhYtce{hBF4;6&漜漇堙shaM赯銕撖芞|^豱銕敼蚇滿w霅巘∥騤eOGG:FE3JI5JG7?B5MG7v_CZG3*@<+@?/41$42%;6(]J8:9,HG5AA1FB0C?/HD340"74)EF4OI9]Q@87)LL.@?/C=,%+:8'JL:KG8DB1LI7JJ7=;)IH8PK66<,98%n[N88'JM;GI5OL>CB4EE6LLH4puliljikmocyghjljhi`w`xrPbLw{[oXro}t}q~{oiupl~dl}bnz\mvn~yb蚚w覤者岩z{|q^eP]dT "oeQS帢yY伔veqQzPYi>?1fururouwzsn\i蝪椌熁侉gvvKH5leUtuvvL<-_P@1FE6A@4@?/JD5JM:LA-V?.]F3/*9;+NQ@IH8A@-^I7:9)FC/EE6>9*>:+DD2BA176')(M>.hU@FI7A;,CB4;:078%B>043#47*>=-B@-IA6?>+=9*A?/?=-aWDA>/PH5PG4==,EE6JH3EB3FD3DC1QP9YRE~潃銕銕銕銕銕鉽鉽銕銕琱琣鉽蓱鉽潃嶉銕銕徾rzvs\qx^xgxy^w|^tz_hpWbjUdlWglWkt^goZdnQ19.[`J86/ fbUcdOcjSku^hiUagPbaKdbOdgSmv]]gTlvXuo~izrqyqzrowlqmoysrrprsrnpjpfv[Dg^cQEH; [u_K_L5E7LYDRgRGSIhxdFVHhjejbhoqfjimbz`XfSXdNObO`mWjxgojSfx`ytf~bp}j}yzw^sh鰻《^>豽惘_mQ\m[UdV'0/'\R@蝏|Qn|Ym悁pmgm<<0zy_rvwppvuxicQ觖衣唭p鵓肊yz[bfcNrnVMM@d^KqsvuveO|L@$rf\UpZy~NN>?+瘣q佴臻繌兆銕銕瑹剼}_儦鉽蘉~ay蝪銕謓tY?>2?=0>=-?>0FE6EE6fO,+C>.20A;)OC114'>=-ED3LK9IH9@?/;7(JH5OK0lYEYL9KJ6HB0kYCaK94"WF:LG4JJ:AA1=<+HG8<9+\\JB@-DB1;9)?>0$"F@,WV@A9-D<,:4'ZH67=.DD3HH8KJ:A;+LI7QO==9(WM:JF5OJ9lWKP9JI7DA/?>0HG8A?/A@-EG3BA/rY貒嵷嶉葖嶉銕銕葖嵷葖葖搌舕酯嵷蓱雱晻雈橠p}qxvwoxomimnprj};60XWHjigtrorlptwwurvrnpptswmrulr|utnuqnrsrpqnvgz真[g}pujq~酋ixu_v|gZmZ_gU()E\H=K:P`Ptyj{fYn],3"/>0Ys^b|govJ[Huw[YK馬293awdUiZVnYBJ5zekjV揚疏|QeTMTB]g[]fUXbSq}h.)NO;痡umAvg`P_XDZd蚸m眹uD?7^_Fcf誓]ctuknw鍪帷cG敞苃oKdI=$すdJNA品cevUzdP9irnTu[F滴ZrcS_p^jzfS[J6+鈭}屨敼鉽銕銕撖暔{\嚜捶鉐{萯兆蝪銕豱qV?=-=<+87'>=-HE5FD1`K8^T?LP:JH7BD/]SBkSxZGD<.>;-?:,DA/;8*?;(94&G?0BD1@B.EG6CD1CE1SSBPO<--$KD2^R?LI9GF1CB2DC296+ML:44#_^KjYHC@/<7&r\@69(>@0:+oVeO?@2MH8ROAED2DD3*&B<,>>/EB3OO>A@/FE6EB6NM==@/=<+ID0nT@)%PQ>DA266%GH1OL9m^HmWpUXL<:9+EB1@?/ML<;:.54(2+45,44%44%pfP敿雱嶉銕銕銕嶉嶉搣蓱屣堙屣琣堙搣琱琩琣戃x{rzwqzvsskuspnlvOI<zdbZDxvzptpnnskoqnrqrrtptilpnogovtrvlvpqpjx}crv^肛[_@}txwquszropphksvxw}|e{fW[Iu{jXaObv`Xp[[mVRdQJR@zML>E<5DQ@zy9H2yGD3迭xb\JJG:QfTavj4<035,62+h\Aui?鉭酯jlig箠QWp_vLB2paa鑿Z<`Q_t_tvr`貕椰sV轘倣jlSkg縊]吙]浂adj^K%3DRDR3Q[p^Lbi`fggJ`VIjS@QO@) 鍉hげ觓鉽鉽銕鉽桼rS珘儒酗銕銕銕銕諯nV;:);:+?>0CB/CA1NK9dP=bN;ZT@TQ=TT@OM7JM9jP# JL@WRCHG:<:)73$@?/;;0>=-;:)@<.TQC31!43#A>200!:5(gR@N;*;5*C?/HB26,0$w^fYBB>,96'DE6><+A;.AA241$40",-12(::0*, ][A斢嵷嵷嶉蓱琲菗搣琩艂晻暺鯕擿銆搌琣巘nspvsuypsqmnonipm|c>7-x}hx|ckx}ef}fs~e{gt|epu^qybqzatt^noZfpZ]nU`pWXfMWbIZaG\aI|e}h~~hjtu`vw]iz{erqt[izfwxvstonyhYK;z`OpmnQwctzlsywulvtusxptopts}muqt`nRTiOIZDut`咯sp\QWLfkwlUYLmyWVCMK==F2Xpc`pXQbU!=9-XSEX}`gVem_mJ:鋮dJcK9kfSmy{gbix[電Tdmiuvl鵔j楎謪ㄢ\~}h掌_`dgk8;;U]Xa\DR'IP?XZvVilrMh/ ^=-kS>EH7F'窴吹_A{sV慦銕嵷嵷潃蚚jJvvm隢銕銕銕謓dJ>C/98,;:)HF3MI5OK7dR<]J:WR?\[GWWC^YIQM;WN9eO;*'@<-NM@@?/:7(@>+,,EF697+?<+??0GF1?>+GJ9KH<.-"GD886'jPeMTG6e_CsXI?0CF7:9'65%=9*>=-CB1C@4>A1;:+DB151"21#76',, [RA敿嵷葖琣搦雈琲琩琣琣琱琲篲zT{雅YRB隒婦晻鍜rvmo{jssuootqkvput`xkUYcMXcLjqVhiVeiUrvbip\klYhoVfkVpr]w|cry`tv}etw}h||ml}~g~zev}ep}ee|epl}h|wbilysrpjtvxuo_Ft`LpdTvurvwpsv}xvpptpkvysyptvpyqltv{dpo\hQU8\cDQB"#wU5~eP~jbP廝VoWhM~u`tt|q撰mdL暻捋kvklu[xtY]lZL#PLD/zoyL@`oP?@/A?/=;)?@-QK:RK4lQ;\H5SUBTQ>OM9XZF[XFTL2r^J60)<7)93#GC2?<,<8&),;<,>=-5:)88'DC6A@2?<+?<-=<.83&47*D:)iQx[UK=4,65#>=0;<+>=-@=-;=*MI7JJ::=-65#43#64#42%A>2-0$VT<貒搦嶉搦琲琲琱琲琲蓱艂甇lqsQov丳頦儽qwovtuoswppyrowrnFH220#edSuwnromvrspujsrtsrju~okqrvyzuvrvrrpvptqksf~pq|ryg{upnrsv~wttstrq~unpqmrrwz{mzdbjVMF:MK9IF6^XJVSFlPS@vust-0$72$AF>@\\-?F}.NVvq]T逝Y︾VlTjWB大QlQj{}}N_KtX哈禛﹙ra只gc癟r瘜pz屩y195@=-gD2A?1M=$t[Aw`DtRlPiOlQwXbcFdQ?yhK|gJjPlR~hLkO`IfQ|YB9;+@@.G:+z\GhNiPcHYJ6QP;LL9HG8WQ=UWBWO;TO4fMA7'E;*;7'79'63"41$11%?=-IH9>;-98)=9(54%;:)?<,,)<8*yhTrZC?/:6(:9,,,>=-<>/A?/JF7AF2DA/<:+>>243#?=-TTCCE5:6&)0"^YC豱嶉搣雱琣琣琩葖搣琣琩諯ずmbU繒筋r輵駗owrvunsspvnuxlkq;=1?6,ompmuprsqvtsritmqilonmpsvpt{|svotnvrtswru|rwotuv{qsquvoolkomguyojkwgmv}釧kkltakiUkgYUXDBD4jfK#/!JcS`q]#&?D4GXU`rt帚(=B(BIctj2SWIXV~q^ozeteIP@]G}wcbly|x}r閰葖橍s蚺n零QUT蚾nf1?&CN]tkCL9VZGYY>LDVW~cCjU>u\DmI6[F3v^?gK2CA1*-$:;5<=4?A3?D2EE8BF9?A2EH7NK>FE6CC6@B1A@4A@2@?/;=.?=-?>287'3/ HK5KJ863"63"qgV敿琩葖蓱嶉琩葖銕銕搣膍w{伝矇^犐髫ispstslsxrmpoptq痔sp`36+ssavsupssuqnvqrstyslwptuxrtptnovursupmpppqlwtwu|ttuswspyomz^~ckm~i{^UB[U@q~bmxza{{duqYov`t`rpTlkRvsZ~v^{_}wacmuqZuo[XSA85(jmY}^zc摹pgQZVA<5)GM@Ld_!:G9VZ7Y^t~qBcgv|jzjrLQ?CC3/8'5-!friur|收葖馺丹y鵘咿xO蚯6惑DdHbML躞鷵xhgOg<)mub;=.*-$==-76'41$31#42#BG78=+>=-=:/A>1A?/?A1@<.::+?>-;:+11&CB4=9*63$;8(;8)76%AA/;7(dU?RD2HE3LL7WV@[ZGWUBRL8ZUEi[Ky^GuW@E8*0,"++FE6BB1?>2;:.A>.98),*!;:+54%H=,_I7ZF57&;>.54%::054%=;+FF4<<-FD1HG8<<-ZZF22(TQCCB4@>/MO;WWC85(STBH@.豱葖銕搦銕嶉銕銕銕搦蛂鵴揍r]郭髒袺}鄖藦lvowtmovsvnjxnsxsiUC?;,qqvslrlko|oqsssmxovjlutsppvunrmlqzoomtxqotsyx|lxu|}釭VM;so[v~dypqVzw|v]gwvqk|emur]ccK]Q6mxs_cgsxwt_w]\G=:)fswqmR|3(VVB;E)JV-EDJXPbY郁?Gk{~wb|bwM]NeO`ziUjQY{蓖甈m懘衩洪RrL]品Z嚎Y2JSKc_)JV'KURkjcpnAP9QPH_\jjV廎zr}jSm_]}kt?.?,<)?A-98)98,=<+<<000!31!IL>QRDDC4ED6UTDGG;DC4?>0PO+A@2JK5GI7MJ:EB/eS@\P;SV>WQ@[XF\[IVUDXSA_\GiXF\C1kSdO;P9'@<+FE699)43%.,35#,+IH9=<0(*_R?cNC@4DC144%76%;>/>?+03"LL<<:*MO>QQ>76)llV25&NN;JL:NM=HG6HG844%WUFOK<赯蓱嶉嶉鉽銕嶉銕嶉搣魙晼醑tv衖漞琱囋}iwolv{mu{ulsuvw`pVw`scaIr^hRxmnrprrnpllrtpslkmntprsmkolpjnlqskixutoypfgnV|ewx`ry]dlq\wwalmYwt^uv^p}ixxejrYgkQMN;)i~}f~hyrnF$DL<,5邯%BH(P\?GWhb{hPybx\nzovyfh~eoV\ra惟鑄派趮6dkY:t\@lX>r[AgZ9?:5<[a)JV)JV@QT5Y`0FKxSDz6+:'p+t4 jC-xSAm>,o?-Q:BDB2nZE^I7UQ-_[G32"JJ878*NPBNN;51!uxf54'NM>LO<\XEQO;KP70/??.ZYD赯銕嶉銕鉽鉽鉽嶉銕蓱晼琣銡甈雈琩藯r|uwusmuslilwB/]Hnmrt^xv@1xnvlrpnsnqtqrtwsltrnqsngomtmpnqstrwpwrozt~y|}{zvx}gnn{~h{{dvt`px^krYxeqq]svZjkWjzv^}}drinrrgkz{_ww_yhhs\foXSXEbhUbjS`gS8@.ugQ{v]utYzt擿WUHxp,Ta8=9-S^:\\-0{zzjdvgqU\nU{ameoem}f|洫嗒弱q^醵傭lfOdLpS=fR6{R堜paR`_]`VJc^W) ゲ7<'9&B.lE4a9*]9*T;*R?*SB-tS54(,-BF9<<0?>098);;.HG6NNFD3;:.kgPJH5ON7OQ?c`LHE8?<*43#HF3FC/IH9;9'hT?\H3QP;LL_nd>US#GT4BTcQju\xdJ誓]oyg}lcwrUL;{vV縭rT7RB2?5"\芃jヰm圇p埜s菻q虳|qt_bP9VMVVHc[Dh]nnbFwKmK25*(+CB1?>2>>240"77*JM=LL>?>0FD1jlWSUBHD3CB1LK7JH1JI7MK:cbLLL9A@2=9(;>0FD3BA179'eS@WH4NN9HG8LG9GJ\]P`]H赯銕葖嵷銕銕嶉葖葖嶉琣搣艂葖晻琚堙捸搰ryit{pkoxop~eY>hRvD/g~ex`pYgQZGdF0 knuprzvsjtnojjp}cmsigmhh|}dtwbvepw^rv[y{e}dd{|aijqumv}ft{dmrZfkVflWko\emVitasu\yzfu|d}{d|yc}~j}~h~hzw`uuZuzaps]v{ayydsv[bsw]c~iwx]~h}}cwjroqsswWS6lnRf]HIA5x_qxk{LyN' KOAA:%ni_06}tㄣ#&%*/,<-1!>7ZM8lr]vtc}m諆酌qW芶b棓珧mP^EbEt\BrWBwY@wY@wY@s]IHMFtZvid|jTj_6NMYM=t_Gp[DhS=uZCp\DoV>hN>?/('BC6<>/EG531#02"HI9RP.@A/=?087'dV@\I8LJ7HD3OK4~rN[T9QP7IM5]T@C?+:<-[K9zP=yc;-+."-3$66)\SA{a{gSG?/<9)44%EG7NN=88)HE5JN;=<.BF/%(CC2@?/KK8NWD98(X[F46'HF3NM=yuZieRiiO[\GgfTvqZ赯銕嶉嶉銕銕銕銕潃葖琱艂琣琱晻琩琣琝hiXulos|\lnknhStpZ~^Et\eiqUvZ{V|mRyaMp~gkhggk~bjghpjhonokkmolhcs}~h~|donlhinrmrtnrvonhwsqulqu{~ovqsn~e|iw{d}iikfxufw~gut_ewv\z~ajx\prt畢ZXDJB8kloscz\o鯫}鸇^kd"@?;#BN8BH膾]權Z島[EA0ntXDw_m}鍭炎j艤wOvZEz[Cv[@|eOmL9u\GlR>s_JqS>xttd~k:NJ)GIu]>qZElW?lW;eP8jQ8[N3aH:<.-/#;>->=-RRA'$88)LM=-76#CB1A@4DG498)iWAeR=NK9EE3ehsLVT=EJ2]O:C?+CD4SM:v[inY1.'-4&&#ibMsXaK48:)03$$'+-98(,* 8;)KJ80CB4LL9|x^a^JnehOnlYtp]豱銕銕銕銕銕銕銕銕鉽琱琣晼搰雈琱琣菇捸xmrnprswmghi{^rJ6dKcK|M;up}}bku~f~sE2zqokjkkj{{d}jgictyw^oiyxalomhnj~~if|e~~iijulmqngotoplg|pnwlzlbnVScRdrYmu`kqZwlpwehpXhx]yw_svavt`zdswdls\lx]dqZct`goZZoUR`N\qU^gTSgP8K:8O>LeQGZDEG7AE6~frqU鬮釂{蘛r鷩t籌韇鬎yq(--6(9@hZ綞Ua矹^cgbWI2譬窷嚜捁蒗sDt[JgN{bBlTwY@dKiJ5lTumTtr|Ywgm3LIXE=qYEeKy]AkTnVCkSmS9hN11#,+CC4>D3]^M--$?>+PR?^_IOO:ON<]XIHG8HG5ML:OOHF3|hE儠篜FH6TV@ZR@A<,A@2@=-UG.icM@- EA3w]dWC! /,@D2((86%RUD<;+HG6SRDFD3][KCB1KO><>/DE7YaN17'os\DO5U\K\bLw{dho~~ile豱銕撖銕銕銕銕銕銕銕琱蓱葖嶉琩琣菇晼堙灈`iTcjnmfozion~}]iOnVXCM8jqfsioxhN:e}}deihgl}~ell|f~kkfjkq~}fo~~iljqqtqljkjlfmlilo}h~kh}k{{dvz^y{bmxbugwyazv`||iszc|~asy_{xdryby}i~mliskmqouvwaos[ow\ps\ljQouZgjRakW[aMhnY\fT\jS_iWBG8:=0`钀|zeSH?(();<!8焨JG:/^kc獵^旍s甯nb骱似撖滽鍉甩@>(jI}cLuYrWBdKwY@dKxWFdKnW?eH4:),+BD3A@4_eT00!AE3\bLZZI[[GTS;YTEQQ>QP;XUAYV@RR>NQ>SN?b`KLK7@?-A>+HF3CB1NL8<;._Q=YO6LH7IL7/EJ8MA(ioxmS{{dymVgQ52',);:)LP@#11$QRB65%65(Y^J:<+__KLO8#9A'KN#IF"DF(?ArYd1驤磩y告OkojO:URFYClnQmCNI蟥撖瘣瘥蚽},6"m[BqYEnW?u\DoW@vZCdQ<~cItt[x}}$*ED1DB1ED3;:+eZEMC2HE5NL=FE6JJ3_g|qVaS=DG2?A3AC3@9(QK8llmyiNK=,,,/.A@4KO@>B6IM>54%<>+fiU;=-\`IemXW]HVYHX_LipZW^Eow`uxcqyaoybiuYov^rv^mss貒雱橑縟晻撖銕銕銕嵷艂鉽甇銕銕銕銕銕蓱襑丈iX}k|flgsjfi~iz{cuvcy^zeM|/ p\CzcrvZkbJzpTWCJ6_@4qxfnrdzk{j~l}joj{kxi}mxixhx|fxfziyzer|akx^s~fx|f}gqos}c{~h~kxh}npxgyzi{~hzkx{ctxbr|azi{~hxh~~i}kzizizizk{jx|fn{j~lxh~mjjnnlpn{kzflq}~f{yeow`ps\v~dlo[w|ecjXkv]tv^EJ9GJ9G:$<5"~gJrThbgqSWㄆP\dT6ZWE6IN:5/lvfy|esYwwc_eU鵖嬥秶邍uG ZV@^VA\S?]S@YQ=dYBnVChU@noXttt}9UGgW;_R=dQ@-17&KJ:UWFijSIF4FE6dbL``Na`ONO@STDTV@TV@`aQNP;HG6ON,HK7>=-;;)TI8EB1HG8JI:CB/KG2o[BfbthRKL7JI77<,:5$88*mhyvdxdQ77(03"2:)AK7HP@*0"9B/>H5:?-RXF\hS[gOhw[u}deuYk{_x|fsgxhs~fq|cyzerb|kvjom|ntuZ敿雱芮膘掁琲琱琣葖搣琱琚搢銕銕銕漇犍搣擽McPu}dtbu|axhm}`~hlimunnVDpfTzkT|;*ytYk\HsmUrcPnmVx\BWDz{ejcOlv_ly_s{dm}`o`r{^vgt`uex|f{g}k{jwgq{fly`lx]rzcu{_s}ev|hr|axfqy`vy_ufly`p|bx{cp|bm~bv}czgqxhu|axfzlu~cqzbufu|au~crbs}eq{_jxdsgq~hm{^{grbzixh{jv}fjv}fxh|nu{cufzi{|gy|il{|dz~cjyzemin}gmjpt_JM:CG5iQY`O]_@pva]bJ`aP(/+99,fjXT[EGL?NJ=imYxh(JRDRIYD{|g}hxht笥G棨袸V%%wll{fr}ls{es{exiuf{{dwlttt}*?B5L@v~dlzaq|blx^vy_|gjy8>-23%EM;cfPchSZZHGNZ\HikYXXFON<`aQSO;__KkgPPR=HG6KJ8OP;KN;EH7[T?UF4QXBOO>JMD1KA3*'ns?D2fU<)/:?.;E4KU?MYENV@[eR`kXZhThubcu_cs[]pWasZfubjxa^nW]oUhwbjvclw_jx_nz`nzlugwiwi}`豱琲懩鞄琭葖蓱琲琲葖黮痑晹搣雱雈雱琣琣襑=UBp|bqfqz^lu\shp|crtaufbqSiqp^kTk`Ho_@rt]uz`v{fsK8m`Iv_HvN:kP;k{g{~fjw_p|cow`s}ev|gs~fpcjxdo}eryfmv`fv_gy`hu]fr\jt]gw\|hkt^kwbx{co`oydhwas{eeu]fwapz`xilzdhu`gy`kyhk}co}eozclyal|`n{flt`jybmv_ozcq~ht|ffy\shmwahwanzbq~gt}jm{^o{ds}csgmxdt~]v}exkt}jv~es{exgu{cv{ezf{{duet}dv|dxht|ft~g{~htJK7@L<︺NYiSg|nzcu,)"PR;ty~csczg}svo>L-DFpxft}jsh{|duy`mP醲隅qz懫lXZA0,'x}bo{dq{fr|hv|htlxixhnzbgyeqn}3LK*@HS=CD0]]H`kVKR>BG3[_NEM6T\H`_KJL:@@.BD4HL:GJ::<-XP▎PRaMs}cv|gu|hy2@->D1T\F]mU>F1HL7V^J@L3EN8PWCFH6?A2AH5LM;@I5EQ-CE28;(篹}鷩t籌tg]PK7=D5ug58)#[aFXeRQWDBJ8.0EP>[aSS^HRZGfv_fr\YhOtll{fpzhs~fo{dpdlzbpdm{em{hn|`gxdfwao`q~im{hgx]}f豱雱荎藗蓱鉽銕葖嶉嵷雱晼晼躈8NU>Q[DLO18:,4:&FRB[bLCE5CH5IW@C3MWCMR>:E0;D0ESJJ3蝵wョlc~OsRKiMNdPbt[at[^qXewb`nYgrbhxdcp^4Q=|gZsY`u^Y\HVdL`qXcu_gy`au[ooSY_Naw`^nW\oVt[K_G-3&;B6cu]\oXar[fv_eu]cu]cu]`rY]jT{Y^X[FiO3千JrZiz^n}fDM737%OXE憧s棱x恁q魋y籌籌籌籌z籌聾itRRF/13#A>-MQ>XbLXcLDO6XbLTXF>G4IW@CQ>6?,9B-GX>WePZjQUfOWYDEH5AD53>+K@.YFqmVar[\qY^s^au`_r[bt[cvbcvbznNNkR^pWfv_NgQ育PUp[15%>F3fvb\oX\rZZqXZpUSkSSjORbMVmSGaJC_FfbKeI\By^HZoYd4B0NcILW@LZA~Uゝi儱n籌癵虋}ヨcRYL;14'AD3?I8@I5JF0OTG4Q[GDM8?J86>,TcLaqYbrYUeRds]XkU[[ERE3|UC聘]灘[qM;;TA0@I5as^ZoXXmVSlVOdLLaLJ_HC_FF]GI\GJbIFZEklKp\7T鉒p鸞aSUY\z晢tk=`\=CF3AL:ESAAI9HF/GN@YiOUeQN_HZkVN`KM[DXkX^mZHP=IR?,AN5DS9NbJLaGHV?OYHIS>Q^JIT?OG7GK5]lUYjR^nUMZD^oYbo\Q\FchVS^HGR>P[GGUAV`LXiQUjTXkSNeJX_C,7&2>-BL7APN;EVBH\FM`ILYFVdLXjQLdO?T@FT?J]GIXG->*1=-;K6DWC;I5FVBK]Ffv_`s]SfNM`KXgQ".KYAJZGRdOSfOUhRYiVQbLQdLfwa\rZfwaplev\^sY^s^\r\ZpZ\r\^r[Zr\^r[ZpZat]`s[at]^qY]s`^t^^s^[p\\pZ^s^XoX\r\UjQQfTvoU豱嵷鎯J犍銕銕銕葖雱艂銕銕銕嶉鉽葖嵷雈巕'7-UnX]oW[qZZoUXlS[nUSjQ[mUZpWXlSWoXZmUSlS\qWSkSUkU[kTThSVmV\pWXmV\oXWoZYkUWqWXoX]u`XoV\nZ^pW]q[\r\ZoY\rZZmXUmXZmVXmXXlT_s^ZmUZpZ]oZXoXRgMVoXVlXUkXQjXOhQQjVTlTQhSSjXPgQSlXOfQOhSMgQYq\Zt^OfQWoZWl\WlZVjQZoVYp\Wq\ZpZ`r`^q\WkTZnSZmYXmU\pZUmXZpZZmWTjQ]t^\oWZpZZoW^q\_qZ\qX\nU\pZ\qY\oW\mXYmX^pW_oU_qY^r^\oV\r^cv]WnXeyb^nUes`ZpZ`tWawa\nZ_r\`s[_v^\qYiyd[r\ZoXZpZ\pZTlTZpZUjQukNUoU\qX`s[NhPnmLUkSXpVZqXZpZ^tZ\pU\r\^s^\sXQfN\r^?WCXoXSiTUlUWnWRZHNK>J[HM\J<&UQ:RT@NN6PJ8FD)MI1WUA`YG@3#F:a]Me\H]]E=?(JD,D?(PT;JG0YUBcaO`YGTZGHP;LR=HK:LG/?+B:#8)?0,)&#/+*+%,2!01 41 /-57"7:&>B-6?/'2$.;+1C3+80-80)5**;3/@33@43C52>19I?8D:0<2->2/<./@34@09>2FI8?D92C:0A20A267'=?.;?*AJ-GC(7@*37)*91FM9IR;KS=LP7UXHQ=IR=PYCGR;GR;OV>ISQ=8J8@N@@Q@EWBK\F>UCAT@DXC@W??P GlDraw.vertex2 (v.x, v.y) ) pts; GlDraw.ends (); method add_point p = pts <- p :: pts method print = printf "curve with %i points" (List.length pts); endl() end class app = object(self) val xlo = 0.0 val xhi = 1.0 val ylo = 0.0 val yhi = 1.0 val mutable npixx = 300 val mutable npixy = 300 val mutable ldown = false val mutable curves = ([] : pwlcurve list) val mutable cur_curve = (None : pwlcurve option) method reshape ~w ~h= GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity(); GlMat.ortho (xlo,xhi) (ylo,yhi) (-1.0,1.0); GlMat.mode `modelview; GlMat.load_identity(); npixx <- w; npixy <- h; method display = GlClear.clear [`color]; GlDraw.color (0.8, 0.8, 0.8); List.iter (fun c -> c#draw) curves; GlDraw.color (0.9, 0.0, 0.0); begin match cur_curve with None -> () | Some c -> c#draw; end; Gl.flush(); Glut.swapBuffers() method keyboard ~key ~x ~y = match (char_of_int key) with 'q' -> exit 0 | _ -> () method motion ~x ~y = if ldown then begin self#add_point x y; Glut.postRedisplay() end method add_point x y = let p = { x = xlo +. ((float)x)/. float_of_int(npixx) *. (xhi -. xlo); y = yhi -. ((float)y)/. float_of_int(npixy) *. (yhi -. ylo) } in let c = match cur_curve with | None -> failwith "curve is none" | Some c -> c in c#add_point p; method mouse ~button ~state ~x ~y = match button with | Glut.LEFT_BUTTON -> (* left button *) begin ldown <- (state = Glut.DOWN ); match state with | Glut.DOWN -> begin cur_curve <- Some(new pwlcurve []); self#add_point x y end | Glut.UP -> match cur_curve with | None -> failwith "cur_curve is None" | Some c -> begin curves <- c :: curves; Glut.postRedisplay(); end end | _ -> (); (* other buttons have no effect *) initializer Glut.initWindowSize npixx npixy ; Glut.initWindowPosition 100 100 ; ignore(Glut.createWindow "draw2d"); GlDraw.shade_model `flat; GlClear.color (0.0, 0.0, 0.0); Glut.displayFunc (fun () -> self#display); Glut.reshapeFunc (fun ~w ~h -> self#reshape ~w ~h); Glut.keyboardFunc (fun ~key ~x ~y -> self#keyboard ~key ~x ~y); Glut.mouseFunc (fun ~button ~state ~x ~y -> self#mouse ~button ~state ~x ~y); Glut.motionFunc (fun ~x ~y -> self#motion ~x ~y); Glut.postRedisplay(); Glut.mainLoop () ; end let main() = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~double_buffer:true ~depth:false (); ignore(new app);; main();; lablgl-1.07/LablGlut/examples/etc/in-progress/000077500000000000000000000000001437514534100212545ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/etc/in-progress/scene_graph.ml000077500000000000000000000067571437514534100241060ustar00rootroot00000000000000#!/usr/bin/env lablglut (* scene_graph.ml : a functional scene graph demo Copyright (c) 2002 Issac Trotts. This program can be distributed and modified as long as this message comes with it. 08aug02 : wrote TODO: - draw bounding boxes - add trackball *) open Printf;; (* ==== types ==== *) type point_t = { px:float; py:float; pz:float } type vec_t = { vx:float; vy:float; vz:float } type frame_t = { e1:vec_t; e2:vec_t; e3:vec_t } (* affine frame *) type aframe_t = { orig:point_t; frame:frame_t } type camera_t = { (* frame:aframe_t; *) pos:point_t up:vec_t center:point_t (* focus point: where we're looking *) fovy:float; znear:float; zfar:float; } (* functional node. lets you put in any code for a node *) type fnode_t = { render:(camera_t->unit); (* bounds:(unit->box_t) *) } type node_t = | Empty | FNode of fnode_t ;; let separator nodes = let render camera = GlMat.push(); Array.iter (fun n->match n with | Empty -> () | FNode fn -> fn.render cam); GlMat.pop() in FNode { render=render; } let translation ?(x=0.0) ?(y=0.0) ?(z=0.0) () = FNode { render = (fun cam->GlMat.translate ~x ~y ~z ()) } ;; (* ==== file-global data *) let the_cam = { pos = { px=0.0; py=0.0; pz=0.0 }; up = { vx=0.0; vy=1.0; vz=0.0 }; center = { px= 0.0; py= 0.0; pz = -1.0; } fovy = 45; znear = 1.0; zfar = 1000.0; };; let the_scene = separator [| |];; (* type box_t = { lo:point_t ; hi:point_t } *) (* let expand_b_p b p = { lo=pmin b.lo p; hi=pmax b.hi p; };; *) (* let expand_b_b b1 b2 = { lo= *) let tea_node () = let lo = { px = -1.0; py = -1.0; pz = -1.0 } and hi = { px=1.0; py=1.0; pz=1.0 } in FNode { render=(fun cam -> Glut.solidTeapot 1.0); (* bounds=(fun () -> { lo=lo; hi=hi; } ) *) } ;; let display () = GlClear.clear [`color;`depth]; Glut.solidTeapot 1.0; Glut.swapBuffers(); ;; let idle() = () ;; (* ... *) let reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w:w ~h:h; GlMat.mode `projection; GlMat.load_identity (); let r = float w /. float h in let r' = 1. /. r in GluMat.perspective ~fovy:45.0 ~aspect:1.0 ~z:(1.0, 10.0) ; GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate ~z:(-6.0) (); GlMat.rotate ~angle:25.0 ~x:1.0 ~y:0.0 ~z:0.0 (); GlMat.rotate ~angle:25.0 ~x:0.0 ~y:1.0 ~z:0.0 (); GlClear.clear[`color;`depth] ;; let special ~key ~x ~y = let delta = 5.0 in let redisp = ref true in match key with (* | Glut.KEY_LEFT -> view#roty (-. delta) ; | Glut.KEY_RIGHT -> view#roty delta ; | Glut.KEY_DOWN -> view#rotx (-. delta) ; | Glut.KEY_UP -> view#rotx delta ; *) | _ -> begin redisp := false; end; if !redisp then Glut.postRedisplay (); ;; let keyboard ~key ~x ~y = match (char_of_int key) with | 'q' -> exit 0; | _ -> () ;; let init () = let pos = 5.0, 5.0, -10.0, 1.0 and green = 0.0, 0.8, 0.2, 1.0 in GlLight.light ~num:0 (`position pos); GlLight.light ~num:0 (`diffuse green); List.iter Gl.enable [`lighting;`light0;`depth_test]; ;; let main () = ignore (Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~double_buffer:true ~depth:true () ; Glut.initWindowSize ~w:300 ~h:300; ignore (Glut.createWindow ~title:"scene graph demo"); init (); Glut.keyboardFunc ~cb:keyboard ; Glut.reshapeFunc ~cb:reshape ; Glut.displayFunc ~cb:display ; Glut.idleFunc ~cb:idle ; Glut.specialFunc ~cb:special ; Glut.mainLoop(); ;; let _ = main () lablgl-1.07/LablGlut/examples/glut3.7/000077500000000000000000000000001437514534100174345ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/demos/000077500000000000000000000000001437514534100205435ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/000077500000000000000000000000001437514534100227235ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/README000066400000000000000000000001461437514534100236040ustar00rootroot00000000000000The original underwater demo was written by Mark Kilgard. It was ported to lablglut by Issac Trotts. lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust00.bw000066400000000000000000000123311437514534100245340ustar00rootroot00000000000000@@Jno name?緘鬧CR^&j2v @ K  [ & j 6 v BR`+o;KRCCDDDCDBC@DDDBBDDDCCDDABDDDDDCDDDDD@DDDDDDDBDDDDCDDDDDDDDDBCC?DC口dehnz▼殙捘釩失灰蹗巀~~~ri女ikmt啻擤袬迨}yvvwz~黴懽wokkov~xo駕opt}甘嬽攢ヶzvqonmmqv{倘籗暀qga__aelux魷xz~營藜ztpjggefjns|永踑儦th^YXWX[^gq嗇葝}vplfda勺ioxㄘ爬ㄞъ穰堧mbYTRPPSW]eq|紱襴橨}vpjda_亡flu掃鼴擬厔檛鮿zh]VQPMMOQU\gp|仄徦壹橝|slgb`__`fmu姦紽澭檖蟪wg\UPOLLMORW`iu尬歆欑蠕}slfbaacipy塽燿蟟{j_VPNKJJMPT\dp~穹噌甗鑒岡voigghnu晌蕻鯓nbXQMKLNSZan~②鵔髡孕xsrrx弄錵蘟襙槸wf[TOMKKLNSYdr檞玁挬妍惘庇錹纍甀侂齬たpbXSOMMOQV]gy蟼觙ywy~仆雯仇砏鵟Й身|l`YTRRSVZdp歷麌苂雅xqnnpv平盒偉輿巃藢簾~{{zlb[YWX\cn灛妗咧}slhgglqx妖憾叡磉xqmlou~{ofcabhr桀橘訄}sjgdefilryㄤ秮瓾woieccgozupps{骯噥vmgdccdgjot}屍嬽瓽tjd`][^dmy糸巃}slgfccdfjnw帥觾磃sjc^[ZZ^do它迂潁yvy}}uoliggilox嗯輹ujc^[YY[aiw傅赸鐉趮vrquy}wrrporw皇糑wnf`][[]`gt ̄蜰橶pmnrzㄘ岳式朕譔暩|sjeb^^`cjv拄籛鵷}x歪mou|奕飪兢葭祐’務噂襐誨wpkheip}趣鮶|xu駑qry有遛藥в虮ちл僗籦鳲蜮蘆|xtqmmpu|侈鮸{wuswx{姘が龔Юв疪檟攃臘豁繞~}|{{廷匷靮~xwvwㄢ購岉蓿陵戎扣首忤瀁熁哈╡假~屏藙~xx{~往欐攽筆棟Л妒~孚俇醚儐忙ㄜ褊婕冀zwvvz扛ㄖ~弧忺鏸藬嬴僧丐旨談祰縉wrlmmov尹~{~姨冔薏穰駋雁偶懍貍尬桏袺~tmgffjpx狀zwz~那尕竤碔齘鵩馯錥獄森嗍tmhffhnu奕}wuvz朱蠍釋檀祽氖倗yqliikqx仁毓wropt|朱撩祠迂聧{z|捐鼴馴ztooqwㄚ滇蔑zsnmosy彼摯勛鏸擿鴆wttv|妖順惜|{}旬翔囌籀zsmkklpx棕蔽正聤灚伎髮sppsyㄙ眼除姨匊稌堐{rmjhhjp{污抻厥謽蛗}駒qooqvz邦б藩斂倎膷欚頖yrnigghms煦媦旅桾}xsrpstvx{zz}萃膷覷蠮先藟xrljihhkpx呴蛫盂赫~yuuutvwyxvtx使齘但鱠xtnljjkknu筵繇旨~xwxz}}~{ytqnnqy⑴佃漞{usmmlmprw俳襘珥巨|xwzztnkknv灞阿隞{vutsstvy~書燿褔‘}|yz}~tnklou泂阿蝵|xvvx|}詼譔鱠腹ㄓ|~布wqnos{盾阿鯞wusty}3贊鋿鮽噱刲か|wtuz踫獾ztqqtz煤趛篫扼譐糔~疢蹗鐔橆ぅwqnnsz紲鐉蹁濂餗末涴雸侐聶wqnnr|潛譨綵彃迨〝曾譫祠丹角ztrqu奪闇膱濄褆}yvwz藑襄陰粥馬~xww{掃噸隻姣迿褘ytqqtz維縪撥敦炒~~~輸縗}uollot}歷欘槿躉釩弛tnllq}牆蟴~tolkkpy暸窴じ釭~sjdaafm}淕蟔yplkkmw佹砠ukc]ZZ^ep桶瘙vnklpw窄ㄕ炒si`[XX[`iz龒}tqqty冀平絡ui`ZWXZ_ft汒鯆~zz}}}朱蠍孺{lc\YXZ_fs瘁痝Ⅲ噫~{~丰元忒珗sh`[Z]`hu喬蒢〃ч奮~‵景漁椅詈炱|pga`adkx喟藦蓮它捐崶懊〝偵衯瓟俯婛朠~rliikq}菔鸃嶸戌倍跏懍扔籣碭癭駉ㄢば雺瞼~wrqt{赭簐迤╲я閒森蜤紉袉仇蹈赽竄佯幰鞃屆&ь穰冗歆蒚ㄝ瘓婞け玻朅葞炎‘授婝觕~zyx{|刈潾紆篟╲裙軝媝せ衝拺譖磉僮垣智戴oonpsw|氐聤唉鵜邑幵僶鍆擨鏺酁狨撓毓ws柞gfint}孩氂鯙楔牯忮臲欋堄羶略wnjbacfkr|務鳪闃禴瓗獍楊迅誼淼譖纊喿苂rjd苔abejs|☆阼寑晇尰痀滬弦п燹齶褁だ藝閒ridaacflv秈娸尪匱蝦雁疝羝癪翱奴旨斑vlglablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust01.bw000066400000000000000000000123701437514534100245400ustar00rootroot00000000000000@@Kno name?緘鬧DT d0t@ O  _ + o ;   K Z%h2vBRb-pDDDDDDDDDDDDDDDDDDDCDDDDDDDDDDDDDDDDCDDDCDCBDDDDDDDDDDDDDDDDCCDD頫dehnz异朠萱~{{|胱籜鮶}}ul餒ikmt菰檴佽~zusrqrw{}~校麔狳}umlqy|r駕pqt~使譀鵖馳zuqlkjikosy嫖轗zohaadhow{魯yz鏡襶鸀疆{tolgdcbchlt}們鍆}of^ZZ[^bir~詬穱鎃wrlgca`勺iqy市岱粕澞晡tg^YVUUVX^eo{楮籙報僊yslea_^^_`fnx朴斃ぜ鄙幵燿鯞pc\VRPNPSW^en{扔屙堠褘ypid`^^_`fpx傖貁澭膴蘮巋}nbZUPNLMQTZ`hs盲酖攡Жyohda勺is}岌僨襣oc[UOMKMORW\dn{ㄘ邇籜酃妧痍均unhffioy殤鏸齤se[SNLKKOQU[cn|▽暟攁漕◥陌~vrqsy奪蘾鐙縟zj^VQNLLOQV[er碤攦ヴ孝撈煖斸鳼棞昈霰蔭qbYUQPPRSX]jz歙鵘薯{y|紡撈局裚籔畟葉}k`]WUTUX\du氅癰袲憬{uqoqy頁葡硃ま籫駎筒{zxld^\Z[_fr嬮繳痔vpkjkoqw帛棺罣孋蔗yqljlqxwngedfku喃轕劑忖~uojihkqy旦崋躈豪zqidaaejs~zrpru}寢學ysmjifegjpu|晌鐉獾簫vkc_\Z\`foz玉鞚}yrnkiknqv}脂襶齶訄wkb\ZXYZ_eq~ㄟ氂{vsqooprux~賜鯚wlc\YXWX\alz▲俋齘欋鬧xy}~{{z{缽襴躈zof_ZXXY\blz耙霘襓rruz豆嗦蘩攄}sjd`[_epよ欋蕾|駒st{店盔為掖絕疵帕側杽籫酃ンwnjgdccflx啜譭yv髮vxㄠ蜇蝶蝗藍闡撩褐淩籙鵻睼篊伈|wsqnlmqx泧鯜|xut咦z~弧曖Э鐘謊熒戚頂忣壛囔埧蝗ぞ階}}{|鍛鸇xvwwy※褥怤ぞ葫直殍觙砲ㄕ秧岐裲醡~xwz}ㄢ麵梤應~{{炮陞巨孝ま襶壒儒失必齣喿薊}vqopry═~~╱滑郰蠰鍇墾釣╲避蜡襲voighkqy孕~~‵嘎氪緡艜謾捃降瘧嬴產宋栖獃~slfddfls|豆~}~孝褒佮邲碖鏵歖蜱噙珍殔怓umiffgjpx‵恩|z|迆虞盔拿蕓掀蚝|smj姓s|迂集{wvx}迂痍▲徫}vvx|§奮嶺~wrpot{◣偕噤ytqqsx玨郊並趮魅sonqv|必遠||ㄞ酵刉}vqmlmqv章誅襏駕mkknrv|迂項ㄥ忮樍埥{smkjjmpw威譬個穱輷駑mkjloswxz此尕苃蕞屺羭褋zrkfeegknx閣珝者樈ヲ{駕ommoposrsw}勞贀鏵齀欀wrlgcabekq{肥箯汐尪|wvsqrqropnnos~缶籙但亄wqmiecbcfmt潼鍹姣筒~zxzxwvvsolnu遼味廗~wqmjhfehlr{承鵹挐ㄟ隅|{|}~wqkjkq|鳳熇{wtqnmqv化澥暵互恣~unliijo}闐頠|ywvvuxy|畎儑灆艇尹齒忖zrmjjkt±醢xvvwz|效裍蟴襖伢vqnos{望門壏wsqqv}忝栫鐉嚂樽鵯椑{xy⑨籔迣ztomot}勛蹠醟但鷽瞻勝鋺櫇埼階wpllms|犧蠯}|綢蒛╱誼眛尪釩voklnt~體鐐擨艜嬥{wtsvz氅鷿伓高垢眾鬥}upnorx朮Э楹妖槳燹駗窖~uomlns{鍶僕咧~ws﹁}◤z~橙鏾桮|rkhhjmu橇矘瓗縶芶筒~yxyz|}qjhiny蘗鯜}plighkr|擋稊婠芶輕~pe`^^aix渻蟥umhffjpy噸揚咩赤坐uj`ZXX[bn跟獂sljils}ㄚsh^XVVY^hx媰觷{qoory有煽sg^XUVX]eq篹|xx|ㄢと讀wj`ZWVX]ep跟灈的儘ㄝ閉彿冔椓rf^YX[_gr舷攦穡朱挓噤扒飄舅倍婌觭|nc^]`biw脣縪蔚井債椲壇╪狐謁瘌蘋酉凄懤邞znhfgip|氮轙嶸戎傑碤壅弧導紶蘧鍖○證摞硠|uporz詢矘暷恕§呠冪ㄤ忣霟鱠妥賸竤捘民裮攥膘&裷虀未湝漈仁嘎婟梛概姥郫戃賑亢憾皵魷yxxyy~池僬篹尹窒阼葄堄だ拸霘韍赫牧捕蝠onnpsuy池朄恆薜曲憊楴貘闀濿蠳鶋徆歲偺{t虐gfjnt}怏僝鸇墨弁憊麀鐖邍恔像哈yoj苑acfks}剪塝瀀蘾鵵抾ㄛ黍挋鳭籙欈訧懋rjd靠abeks~Ⅰ匊梑袀敊警‵首呫襳斸葂聶撥sid靠acfmv俸倢褶普痍姪翦攢ぎ角帕祚wlglablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust02.bw000066400000000000000000000123621437514534100245420ustar00rootroot00000000000000@@Ono name?緘鬧DT d0s? N  ] ) m 9 }  I U!b.r> M\'jDDDDDDDDDDDDCDDDDDCDDDDCDDDDDDDDDDDDCBCDDDADDDDDDDCDDDDDDCDCDCDD養fhkq}岌笤蔗}wtssw{〣霙欒﹝um駝lmpw夤諑誘|xsnmlkotx}~||鱔矐zvvw{|t骷sux}巷贂瑔{uqmgeddhlpw{yy廷緪umjhgku}鴉|~爛籩壔|vplhdb``bgls{予塽瑢vkc`_\_gnw嫗甗壎{uojca^^_`bgoz妊萵創錟nd\ZXWX\ait華蘡懩xpib_\\]^_eny素岕罈探瘉塣彏yj`ZVTRSUZ`jt邦羜鱠漱wofa_^^_agqz兮貤錎譊魙ug]XTRQPRV[ckw玷跇慱酗xmfcaabdju救濊襶朁vh^XSQPPQTY^ep}岳邃蠳酃挭僑陘|rlgfgjq者蕫鉦yj`YSPOOPRX\en{箕籩荀繂趙岳捆煽}vrrt}廷蕅蠮瓕痤}mbZTQPSX]hs嗜籜鸁え迅臏都羋檡鼪緛皸祰玶簿rf]XUSV[amz歙鵱黎}|朝岍楹0昵繀ず歇飢zlb^ZWVWZ_hw儂蟿堇yuqru}ㄣ撚蓬蜂剟鵷噸迫~}uld_]\\_gr醲挭蒂{soklmsw}◢閂腑嫋簊筑zrmklou}{tnhefeju看歙遶噹郎xqliijmpt}尬徦輹楓}qidaacgny|{trut|寞擋憎ㄐ{tnkjjknpv}椎鏸襆簡ykc_\ZZ]clt~﹎蹞儔xsollmpruux~嗨蘞籦媦wkb\ZWVY\bjw穹僪|wttuwxzw{鍥鸁ykb\YVUXY_fs冗絪★嫋暰}ne^YTVXZ`gs整籛欋xy}井圾§據齘鸆縞sid^XY[\ajx菲籫蟨骷v{甽楣岫拿溯陶悟垢樣壼灕迮ynid^^`cfq聿糶鸅}x骷w}偏鰾葭撬藕蝶集措р檛鐐膹歖佶xrmgginr~爵鸂xwv魅}扑ぬ陎噬撕雄有屬艛鄳岒卍陽}xvuw{詹暻~xwy直构硞繳惕本珫ぎ囿挈砲Ⅱ嫋鯙}}′樁睩捁情~xvwy~仇釣坏弩變嬽褙麾邪挓樝翰{tnmoqt{旬盡砨膴麑槤噥祕3庄諘蘑vlffgils{玟寰朊欳塓魟芞捲酸墾砭尬娹樗~tjecdehnu式~旨溶撮犖親貀毇葐旚玻崿帣xoif姑mt巧}市乾炒朱斿珍旆誘uojjikpxㄜ陰zx|~左爸汐噁|vuvz往鐃yrpoqw互飭僥yutwy}平炊菴囋鬧qnmmqw捆僭}{~3檔恉zupnmqsy巡釵耽襳灆尸khhimsx{ㄡ壁握時豟槢慼vnkjmqz傢蔚耽鐉甗y駐hgghinrtx~Ⅱ倧堍褸橾僨衚~smgeddfkoz汛蚡耘錎傱vτjfejljmopsx肺薧蘦嚧蠳欀tmgcbekp}啻蓔粒寪膚}uqmjikkijkjlqy鎬但鸂woidcabcflt欄縓6藤落~xyvqolkhggegks}蛟杆瑗{toifdcdfio|族鐐扆〞甄異~zvrnifcbdhoy舫受漈yuqkjhhilpx卅霟褗妍遝哄|umgcacgmy蛔昏廕zwwtqrrsvy犯踛孌漣旭結祖|rkgdejq~ん阿蒪zvwxy{商薋蟝◢芍笱ヵwokhimw技阿颲wtrrw}旬毚蕅懰樵攮埢wrprx踐樾~vponpv詳儜譭孋耕夒醲いwqlnt~侍鞃|yvx|濂鸅馱忽砮頏畟}tnkjlnu巷壛癭麔襴轕齒xsqnpt{廖葅僖帘硃蕪播揭~rmllmov甚笰褶捷ま襶獾漸}smjhkov跳瑳撈酊岱丑╮zsnmmoq{迆}~及蹖戄zogechkq{暹齁醷庥迨zvtpooswslihn{朿灊xnhdbdhox壇忒睖魠挩砠zvvssux}qfa^[_i|≒蹐}phdbcfnu凝岱垢滅撈{wtstxvh]YXWZan嶄靬wmhiilrw身~{xxz狎rdZVUUX\fy禖鯪torx食馳obZTTSV\cs摮yxx|左掬倅qd\VUSV\cs闐艡旬仃楣矽砪瑆zlaZVVY^fs渣趮椰酉扃冀次в蔗仄侲豵啈vg_[[^ajv喟駖雁狗監蜚噤丹丹素氰慬元挔隬駜qgccdgp|氯擿鼠巨溴澺噤仃厭籤勯鵌備逑瀌衈wqmmpz牒蘟瓾炕今秭黎仄枆儜鸆ㄠ覦嵎甀ˉ楒鍉憐仃扜譐~~末絖紆撣弁瘧拹盝鑑盲迵蘼蛑洽╪偏挋訬|zxxwy}池裌浸暺◣晷婄瘊笴だ奾蛶籫橐戮帘窄葭oprv{岐朅思◣窈謫儌鐨闀瀀礹欉侉盔祚}vjjgiou}玳裷鵊ㄖ掄砳闉蘡謪刓楛|qk苯fcels}笞蝍艚礵藢髡╳蜊曶塉譖酃蚡蔥vlf鞏degkt~內枒倰恘玹誑ㄕ妓譏蹞礯狣蕃隄wle頡efhmw效倢趕閂咧~|~ㄣ湳斸椈悍垣悔znhlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust03.bw000066400000000000000000000123561437514534100245460ustar00rootroot00000000000000@@Sno name?緘鬧DT b.r>  J  X ! e 1 u A  Q_*n:~JY#fDDDDDDDDBDDDDDDDDDBBDBDDDADDDDDDDDDDDDDDDCCCDDDDDDDDDDDCDDDDBCDD駐klov棧窏悻{trqpptz收洛}|}旌礹輵ㄒ{u駙qrv}升摦伬~wrlkkiimrx帛zvvw承檭邠~|~|鴉zx~嫦爞巹~wpkgdcbcglq|平咯zvvz朔慔wsnnpw朕譖孋yslhcb`半hnv仆釩{{樊挶vngcceioz些霝鷽肊wrleba_匝djs仄蕩砥舜离zng_]\\`fmx╱邃斖}tlfb_\\^^bir忠岕繳恭╡笨貁蛩wib\YXXY^dmw妥顯籩嬥閒}slfb__``dku最詒嗢寋嵁蝂蠲揧sga[WWUV[^fmy粕翬獾提tlgcbbchnz永摿贄蠲瑊}pe_YTTSTX[agrㄖ鎔齆椊戴{rlhhjox毅譊滼~pe_ZVSSTXZ^go}迅釬蠃Ф飧瑪摯}vtu{奪蘞鵿壛奱sh`ZUTTUY[_hq憊燹氍奀巡飄譬端蘩氍祳筀膼錒戩蘇ukc\XXWVZ^dmx橢蠃黎乘侚陲╯珊禂嬥繒蝓藝葛豆xpg`\\YZ^bis嫌襑慼zyuv{祭擦虞褒渿攥蔔洩角|ulgb`eju濂蠌瓟ztqnprv◢悖魚呫籜鯕雁圾|tonou{}|xtnifhkpy忍澱礱捙僧vrmklnqx}旭濱蘠鵙螂活yngcbdgmtxzzvrptx嗯樽蚢陵屆xsnmmpquyㄥ栨甗恇極sga^Z[]biqw}ょ翰╯|wsqrtvy|~ㄦ淜攮蜡襲{nc\ZXVY\ajt~ㄩ媺~{z|}}尿裎攮悛ymc\YWVXZ_fr煉錩死紿趮pf]WTUXZ`fr爺蘩攮ㄛ咻﹜#戰蕻鯕tjb[WY[\`hw桓籙欒壓魯|什僱泵ㄔ革絮揹坏庚懊翦鷽丳znib^^_bgp囹擿}魅{朵鏽蔥雀遢噪骨中府氈儜蘟貗覶鼖庛zrkgfgkr}琿駜y魄~矽曶苂遜葩陘ㄞ遽睠蚝晇詍け}wuttw胭纕z{倥豇媜艙恣彼擊散章撒惕教燹鵌狩婛慡螻}xssuy〝狙迤╱銓摙瓗禡孜俋誻穩{snjkmov~忖ㄗ偌褓婤蜲雽妏咫噫╳蹣鳺坅wnhdefjpw妖飧蝌齪妀昐倞醴融器●凎髬vniddehmt|之市眾皎洸辛蜊殌樘濄冀末涴袡{pjggfhmt{◤祖云悌內婂}{{~局晟蘊xqkjikpw底毀}~ㄙ咧倨蹞yqpqu{孛て膚}uspqx孝螢賑~zwx|#祠囹魅qkkjmsz狡髒}第衲伔|vrqorv{打滲}{~﹉巃噿rkh隔ouy娃佫螳傖碆駌{pjihijov社腦~}〥巃鮽}駟hggfhjorx~穹骭葌醴ひ翭廕vngbb`belt植硤形嬾鵖v駐jfeffijmnrz欽穱爦黀鮸wmfa__]^cjs邃骳椒鍆婼uqmihhghijijpy卅襴但壧}rhb`\]^_bju用鋺蛝忠軗蚆x│ronkjihgegks橙搥wnhd_^bgo{殘癭硌ㄤ竊芡產||wtpmigdbdhoy渠杖漡xqkhdaabflv扥簊揮曲檀蔡~xrkfdbcglv塗鉆|zvpokjknpx賞犪鞂悵井馮覬悼噫ypjgdeinz闌廜|{{yx|{{}汐碬躄鼎云斐悸硢憐wnkhgjr釳阿撱~yuvx|仇ф譖襓插﹝坐礵縌vomns|瑛樴~vrpqt|六盄薧躈楷灈|z{友鏸篘vpm〉y爺蘠斲哈|wtvy孋剽罶檶いyrlk︽w曉籗欚嚧轗嶺wrolmqw緇瑔洛仁蜃奾挭}uokjjmqx詣蜮伒絡戺攥儐|rliehlq{樹攠佴馬夾帕秘yqligjlpy掃楠}佰籗孌yngebdilv擋霠鵒冪中xpmkikns~爬rkghp}淭灃vnhdabdkt器欐塯襝槱楠xsomlnsx﹜pd_][ak券韐}phdccdks弛尼側杻捙ztqpprwwg\X[bo泐籫灄wmhjpv直蓿‘yuuwy}ㄛsdZVUVX]h|拗蹌tnrx必恐扛||}打腦ob[UTTW\eu鱧xww|走挾直恌qe]WUTW]dr窌蒧府’宏繡防砩棳zk`ZWWZ`hv癱鸀躑亢覆鴃丰氖眒翰姥砪鵻悈tf_[]_clz爵縓賓巨窒祒黀冪“岩中玷渟犗仍у薣玁ogcefis曉籦祧郊井閨蹞跼韋絰蟯斠輹2ぶ鼐犩睇wqoos}擂錆野那酚儐乘娾嬽灊直陃樏懥荈值楄剸陝ㄥ剞犪姪渀籫壧2褓邯筈雽簣式戊с膫慒捶仁毚頎~|z~倖僝海壨迂蛹薰栲瞁皵玶昅湴嬽縸糧坐妞善艙髮utuux~旁裺鯤ㄞ陷蜈購粢嚬蘪襝蘙癰袎雅咿岱z衫mnotz勒噂廒垓陷眸暱塉贄蠮縜懦惟xqj法qz允庄鳻嚬蟿ぅ′斑痍洫曾刵豟蹢謳刓釭zrljiijqz挫迍虭佫劦|咱ㄒ╮亳敁攠陔熔洛zrl餒ihjt~★侕蕊洩岱zyvx{′盔坎糾燿鵸織酊夾芍}unlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust04.bw000066400000000000000000000123551437514534100245460ustar00rootroot00000000000000@@Rno name?緘鬧DTc/s= M  ] & j 6 z  F  Q])m9}IX!eDDDDDDDCDDDDDDBDDDDDDDDDBDCDDDDDDDDCCADBDDBDDDDDDDDDDDCDDDCBDDDD駒qru{戰挼zsoligkpv~食萵|wvw|颱蘱睇x魯ww|啪槾誨yrmiecbfjox朴僱wrprv缽徻薔勿艕瑔~zsmheb`_aekr{魚雁wroqx匾媕yvrrv嫦襴輶|vqjeb`^]_bhoy麥噫}wtv}銨xqlggkq{仆昵躈~vnhc`_\[]_dkw債伒陝睡牬ypjdbbdhnv妣圖檛糨{rlea_\[]_clw鉻梋譟姦殍坅vke`_^_bflx挫崶褘{rkfb`_`afny希殕睠捈騷栲膷磔sic^\[[\`emy◇嫄湃轗覺~unhecceks詼錝闉斀鏷蠲踼{pgb^ZYY[]ago{岡鎢鍌痄蔚}uojknu耗蹜癭錝蹅xnfa]WWY[]`emz冪崚麎岈蕞謝赫~xwy侍霙鵵崷錤甗vlda\WWY[^ago}壅錪褖揖’紊б蔑怖蕍褉器忣旚鐨橕薨ukdc^\\[]`dju曄癪縝扔蠍噙芍什氂灅賑迄褐恂彌哈vmfdb__`adiq歷轗yvx|巡謊僎絢祼糔砭◥版}vqmgdbcehmt氅斸蛑xrnpsy幸停硎彴鏺煻丑xqooptvtrnligimryˍ濂蠌蚋upklnsz~巨偷栦葃盔恕ridcceippqqrpqs{戒歙駋躁悵~vqmmprw{孝扢蒰鷓戮xjb_\[\`hmpuy{~漿戰戮悖炕yuvwx{}~孜呾籜鏾槦炩qe]ZYVW[`fnx勦燹儕帚{~盂祏籫攡~oe]YXVWX\cly匐蕅ㄘ咫弧忤霝篔pf^XTTVX\cm|組嬾灚玟砠云失◥腋崸鏺篜tib\WWYZ^dp壬襑~~炤趕ㄛ掖敞角╡偯婄贄蘡鸃薜{nga]\]`el{鍚攡蘆魷|狠鱉粟降絲揚邢忨撂鴄壝欙蒶艇ypiedeiqy芹鶁{魯}姦昋す葩惚朱づ妀倵摵离痔~vsqqu糸籙囔捄}釆倵桱摩|y|′偺接複贍迤室翫欚僁斥杺慪冪ztooqrx幼陰ㄞ謬蛷髧隆副塍榃|slh姐pw左予垂悅翔囌帊Ч遘祟岳惟汝趷稹yojfddfkryㄒ妙斑惚眺謐劑捍貁僈{pjgeefjqx坏收陰郎里砡嚦蘦鴃倆葐umigfgkqy旨惇旬痊匯鏸zwvx動觝慰~vpljkou~&滓野~ㄞ筋~根xpnmou~副恉間{trrw~邦っ漣~ywvx}粉揖ywy拓魅pjhhjnu}姚佫蓮△构媃xrnmnqv凰憬}wuv~抨灉駐gcbegjos|汗桋棆6俁劖珖~tlheceho{Ⅲ珫xww~梯鈮餒ecbdefjmry汕噂謳陔び瀄漺~pic`^]_cjwⅩ楩}{~燬醚vlgdbcddfikow啖欗蘮木tib][ZZ[_gs﹍賝堻朕薋襆xqkged逮fjpw扲鯤wnf_[YZZ[_gr及隰彄室蝍髱羲{xqmkhfedcceiq|橘囆skfa\Z]bjv胴皭暆ㄟ濱蜬棨漪{uqmjgdaabemw塗杜揧~umhd`]\^agp燮攮袛咱妓趨笝斻葡哈{uoieacju塔陀攥}xsnifedfjq}胱覶槥漫帛溼圴戴惚垣嶼vngbaadkx踡陀攩}|zyvutuv|椒霘旛簡妝奏螃僧〞曇媦vmheehp}唈譭}ywx{△桄籙攃嶸忖早迨內卹齆坅tmkjnw砌鳦{uqqsx忝曶蜅鵱簣央═yy~杞鯡wssx燬蹓zsnkkns|濬蘮鼞牰wrnnrw氅戃時翪藲}tnighkpy驗籫蘻籩灖虒wnjffjow橇鸆貌◤傢粖硊yqifehjp|豌槷尨劃呬繂飽}qhdbbfkq撿襳蒶援‵嗷礙unheegjpz窕馳忱鐉橛xmea_`cgmx蹬夒痿蔇打插~slheegkqz酋qkhip}翐琠xmfa^_aenz儔債絣甗誨垢unjffimtod_\\aj~恍窷}ogc``chnz#諷誽舠庚yrmjjmpvwf]XUVZan唈懽skheeglr}捩陏窄~vqopru~raXTRSW\fy莘蒺zpnmmpu{捫貌硃陛|wvwz弦o`YTRSV[dw噊藭|wuv|~ㄡ隍7躉狡觼qb[USSW[du翇鯥玨庖玲恅邢衵zj_YWVY^gv坶糐野朵弅仃陞汐笯伝#轄樦禚sf_\\^bk|ろ襋楨什蹬觶賓帑咩矽塝樗產&諜氁邍pgddfjs踱檹穫仄淝勳妤普蜇彴蘡懖純祏穱灒珜wrqqu池殽蚖ㄥ徦儒捕諦蛶籫藲此栱閷錣椿副殗牁匙蕖蘻姨俁籜籽峔副紵樈葔痶臻炙ㄗ笆忐僿埣迤盲桋寔}~姦渫員蟭本奼晊衯椽椳寊欳軘槴鐍餀趙妖蜓痕|yywx}料僳鸉移畈樖蘜穰醲郋砲╮╰駒rstuz2屬蹗藜狠谿謠斃婛鴅觶籩邍芼飢|u駝mnsw弩о楶瀔寲~xxy~ㄤ甄蝴晴曖е砵羭繇譟咱}vo駝mlpv掃づ擱ち繩xttx|偏躅雄囿坎“煬嬿灛牳揪}yr餘lkqw孛臏鼎丰奴{snnsv{狩繙馬紲籙齆庥泵﹝}ulablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust05.bw000066400000000000000000000123651437514534100245500ustar00rootroot00000000000000@@Sno name?緘鬧DTc/s;}  I  X $ h 4 x D Sb.r> N^*mDDDDDDDCDDDDDBDBBDDDCDDDDDDDDDDDDDDCDDDCDDDDDDDDDDDDDDDDDDDDDCDD魯ww~威陏vojgedfkr母旃嶽yspqx肴襝鉖閣裗xpjebaachnz□玾礙|tnlls|〨殫芫}紹聬坅}xrkeb`^^`elw傻挳{tmmos{玄痻xtqt|妓踕鯡~yunhb`^[[]bit腴奜wqqrw匏离xqkgkr{儒狗裔僪欏嬰zunhb_\Z[]`fp~甭衭簫~~江旻}tlfcfjpw凝溘栭籙藰楠zrkea_\]_bhr捺崷郈砥珀梑嬤xohb`abflt榆譏澺嬥髡yqjeb``belv諛槫痽岈噢豁枆錭棌uke`]aeku民勱評灛郅{rmieegkr}朕旚鍞蜛蜼瀎鼭譭{rjd`\[Z]aenz輯鍒埧筐zsnmos}匹澥玁棴碅籗懘wngda_Z[]`dkt儘泔氍赻恛鰾葵}z~蹂鵌羹纖瀄欏~ulfc`_Z\_bflv詹彰縎蔡盛竟囌譫兮稘褋郊首斪蠲虀葅zrkfca`]^aejq}撼籙矐穫仃褥Ъ僥帚紋郩攩腹邪疧嗄簞{tojhdbbacflq{樵藞滯玥蝙辣斯暱僗蟣偎陲~ytqnljhhgjmt~婁擼誘ywx~垠悌悖準椯餖囿{xtrttsqnoptz美玁蚞{wvvx}﹞互睡儚鸉き托|pjhkooqrqtuy玉謪佷zwy}朽н儇痶韁馮摩qga_cimquy}□媺樽郈僕}{}||曳籣碏谾靷睔肮xja]ZYZ]dkpx8栒噬泵走炒妥ぱ劌爦矙灊tg^ZXVXZagp}捺踕妒屆亢睽嵉鱦sg_YWVWY_fr敕嬽′悸◢豆丑托黑訒燹囅via[WWYZ_gu﹠嬽玃妓揹旨痍均左魚疧檉鯥~of`\\]_dn~潸麌縣鴆}仍蝦陪岱拳迨妊藷赸蹗醵侘xohdccfmw拌鏸纇郇魷|ㄧ囌繙敞骨~弗振蘸鋺橖宎|tpnmqy擒齀鵟佶{鴉7旆饕悄zvtvz曳識梛滷爬~|{棲塨瘈冱惕紐婐彖悵}vpmopszㄡ蝦惘‘奶倍迒虮す劃痔本婄袶wojghjmt{垓迤左岳﹞秘僱毽劃導ぜ缺撦祧~tmiedgjpw}型〞探祗坏它’挨豻麧麩禍糌伎wmiffgiow‵惇幼結息阱嫇|z|岐豟袙~rlh男qx0虜╲斑咯營~urpsz秈竦庰}uollpvㄧ齬階}|~奎僚zwx|骯tmjilry珀欿庰zuuz姚笪穡{vtuw}疚繡yurpv樹髮mheehls{穹殙蚆尬赶犕unjjlpv忠捇xtqou灞灅駝gdbabglsz汐碀鍑尷ㄖ排楏爞辿}qidaadhpy怕喍}truzE蹀餓eca_adglpx怛嬾譇嗂踠蠯yog`\Y[^bjt彷毇囮xw|喲椄ykecb`acegjpw嗆光鈳|of`ZVVWY^fr由貘傮戕蠳鮶{nhfdbaccdfjpx郛仿sib\XTTUX]es抿礵蓇並裺瓕蒻vpmjfcbbccdip|鏤阿蟭ypha\YVWY\`hw翎蠰褖惆早嘍趄懞嗋蔚ytojfcbaabekv賃阻鯗xpjd_\ZZ\`fn鏑虀暔僩蛾阺賚硨Ч撥zrlgdacjv塚陀鯥ztnjgdbadhnz胰鼭覣蓿蜓譜楥蚇散捱儐~skgbaackw跡昔眻}{xvusqqsy耙薋酃И眺蜀妀幫2樺睅slgddgo}泂巘|{z}紙碖鵱鑒窄葭釭氅輶~rlijmu≒瑊|vtuv{孚鰓貵矙攢粥掠yxz鮽~urrw脩恬|upnorx怖蜰縪繙揭wrnlot}長譝猷礹龒}tokjkms俱燹犪囔棼誘vmifegkt橙孌直塥熁wnjgfikpy懼樔尨厭斪鍠壓{ogc^_aekw懊蹞鸇蔽岑婠tkgdcgkpy替楷盹襶蟴ukd`[\^bfo噤涾籙譧隊挪覺skgedgkpx岱qkhjr跗艅ukd_[[_cfp~麾椅僔彏5蔑vniedglq|oc_\\bl啾鼒ylfb^^bfhp}姻翫鵏鹿}slhgjpvte\XVW[bq厙巏skheeglqz懼颮債yrmlou}nbXTSTW]i痱靮|romlou{空埱裔儒yutw|〝laYTSSV\f~科撣}zvv{~偭簣空疻有oc[VTSW\g}乓靘狗ㄡ趕舜椊郭仃趨tg^YVW[al>藑仆й延惕祀笭略仃諄蛺蛗~od^[]`fr壬鼭瓿姥郫蘪儒弗陪‵氈蜮蠕弩忳檥矔狻{mfdfhn{屋氄戽匙霙噙革陴硃у斶鈱珊婍蠮籓聾~vrrs{萃雵薊匾嬾劑ㄞ絢纖踣褅局砪蘡蘪橖竄姪粔祣晉澺墨食с霘蝢粗碙蘹氄蒎妡祟悅頂й馲暔產彿砩睠#槽錩皞★眊氆椵嗈椽稌葐瞁樥臩鄶簣弘瑪楝1濘燹鷾}|末殍蓅倷軠澽穰矘矔媊釦ㄓ魷zx{玥轂艗簆yx{介挍觛捈邰瞃瀅覶籫矔桴疏峴tux偎檢嵕斶縓yuuv|掀殌棈謗豳Ю奷楋鸉僧z骷tw}宏擊遜酸ぜ}soopu~凶砮剼葬咩甚裺攦Й咯}x骷ux兜蟈哈丹~unllmqz裡窙霽氾霙縌隍{lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust06.bw000066400000000000000000000123531437514534100245460ustar00rootroot00000000000000@@Sno name?緘鬧DR\(l6x C  R  b . r ; } GW#g3wCScDDBDDDDB@DDDDDDBBDDCCDDDDDDDDDDDDDABCCDDDDDDDDDDDDDDDDDDDDDDDDDD彿圮閎}tnhdbbflu詭謻茧xsqps|缶燿擽楚7厒苀~unhca``cip}耗鍆荋{snllnv髓麌癡鴃仃ц橩|wpica^]_ago{戕澭茧yrljjmv貓觬{xy噹掖裟硻礱耦}ysmf`^[Y\_dlx瓜僿硅}uomlqzⅩ竦藹xroot{噶騫栖齗鮹ysmf`^[Z\_dlx廷儃棯}vtu{捩豽~tmjilqy噢桋檥暲wpica^]_ago{疢鳷袷萱傀寑襤zpjfdfinv萃錩媽蒨~vnhecaaekr~詣鍙葯匢楛悅接т魟庥xnhdbbdgnx京媽礱抪xrlihhkqz俀艬痶恘袃睭槶壛轕竅ulgd``aciq} ̄鼖堐釵xsqqs{颯橏鐘び蕅鯙{slfb`chnwゐu櫇睕疶應脂籚斖彌為蹕碻|vpjfc`chnw儐釳縰斨藍で虯興罟鞚藲秈裺輲|urnkhdbbcfjp{壇檇曫霽岷ㄖ爰蠍厊葛炙迂靨襴瞉紮潞橞簾wrnmkjhffilpw整鶁誧╱源擘歇假鉻氂孋玲恌腹ztqnmlkklmos|氅躄誑幼陶祝垣傭絓罍珣笆竣zxwusqnnoqqsy}蠃薨~}予它辛盡詏瑢甽}qnmlooprrqtw{碣濂醓觸||﹛﹞玨諦軞疰援偎謊{mfbbcgjorwz}ㄥ秫紅慴繩”捆の圔嗄倠摴qe_]`flry8郫憾蔡皎╯”捂譏碨蘟穰簎zk`ZYYZ]bir粕氂′巧炙ㄙ洧◣捱齣澺蟟wia[Y[`ht楮嬿井郎旨皎〝措蘿鞚蟤wia[Y[`iw羽嬾轙炭惟平盔◣窒迾篻}nd^[[\^cm}嗣襌孝僎郁孕足必屬毊薄wkdadlv﹉澬蠂梣鴉~6擢輓悚坐}{|~仃饜籗爟葎屨wnkiinu耘鴄懨楂酈~掙圮蕙恐~xs罕{匙摎棨蕩歇}xuu{7屺笳怤卍屁曶抰略wpmlnouz~局佫戮壯垮隻庖瑪擠賺恄屨腓稄芧{qligjlqvz仄噸玟揚╞之垠裡塤棆怯豟袸yokhgijosx孝陲╳滓揹5剟灢~~萃槼埳|rkhfijou{必僑朱擱葫啪蘞|xwzⅥ筅憀xpjijmsy仄擰窕じ陛~zz}併|ronqv乖蛵慳zsoosy姦怤慾~{{直岈插{tpqt{惢鴉rkhgjow糾魛憀zz~8冓硠ysprwⅥ旃誘vommowO演jdbbeiqz界勱曚慾粕碴駔|qlgfinw誶鉓vommox怠駐gb``bejpy倔霙繉勳晾凎籗鎃ymfb__bfo|嗜鎏yrons}踢齂}餒d`]]_bfksz欽襢旚襴鯗vmc]ZXY\`iu晤囔迉xuw}皮儥zkda^^_adglrx鍚奲zmd^YVX]er栽攥ˍ燹鈰zngcacegkqx肋穴zpg_ZVTTUX]er胼鸄蘋怔匴鯚}vnheecbbddfjr灞頛vmf_[XWZ_gv貊縼蔑赤舒踖欙骳zqmjfcbflx綾改呇vnhc^[YY[_dmる鐓秷講纖錂纕瘑寋|uokgda販ju塔藘xrmieb``cho{修鐖徾狣騰毲臊閟擦騵壁{rkgbaacjw蛤鵏}{xuspnnqx屋錤麌狟衝厒皙Ж′諂橙砦{pjdbcfmz離灄~倩椲曛撒蟾旼悵刈濂鷿薜{pjhils肂葧zxz}飛鹹椷蠮鵸斨擱繒}wtw歷醛{rppt{皿籩蟤}vsrux煉艖醑恉羅unjikqz橋蟜{z~怫蹖獊~uplkns|豬籙矘鼀梀ukebbcgo|擒蟝Ⅱ稑鯰ypkhhkqw組豍楎噱諜錹醲峆}pf`^^`bit嬴澪譭穹槼wmheehls汙繭啤譧wkb][[]`fq凝囷蟭試蛨ulgeegkr~炙pkilt思蒏vjb][[]bgo{匏氂孍羔祫xnheehkq{|nd_]^dn屢賮wke`^^`ejs}斥寀鱧宥祡|skhgimtre]XUW]fw鬊~qjfccekqz倡鋋堀宥婽xqmlosym`YUSTY`p旳齂zplklntz耘瘐翁瘐~xtsvy|j_XTSUX_l幣驞zwvw|~傷Ж棍痸極〞~kaZUSUX_l湘鯄足~征繞兮欸妎姜羅pd]YVW\cp舷靘5衄2輓甭寑襤云鹿邰楅{ld_\\ahw菜鎡末跘瓕麾奎揚知訒瓞屆◢腔娾嚬攢wlgefjr韶櫅壑倀燹噙旬陴限期紺槱楠忝迾糶斔}wtsw岌楩炵耕鐉ㄛ眶蜀俅霟襏舒錩欋庰那疧楎晒蹖凝曲嘆祛籛灊ˇ祽鼥棎襄鬲炭銀砨蜾捃里紬瀁妍談碢灃序凞矔蜞趿窙楸蝆儰斁縺伝ㄝ嘗舊契諧踖鯤zy款譈鼪楉詌鋹礹蠳譇妢芋﹛╮&蜃冓譖鷽zutx升儓蟼詙嵁儰斀賾鐒鵱К炕妊瑤襖崽鍕~toory誅蘟魶堍圪ぞ藏奷碬孻螻鴉~ㄢ遣歇健斂漣unllnu}朕瀦醐У惆允絫鍠蟒盲繳﹝xnigfioy〧踥孻翮~}颱禡童lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust07.bw000066400000000000000000000123551437514534100245510ustar00rootroot00000000000000@@Rno name?緘鬧DTb.r<~  I  X $ h 4 x D T d0s? O^(jDDDDDDBDDDDDDDDBBDDCDCDDDDDDDDDDDDDDDDDDDDDDDDCDDDDDDDDCDDDDBBAB彿で孺}tlgcaaekt賜蘼袕}vqooqz﹎鋷糒扔忭祡}{smgb_^_cis餅欚荇xqkjilu濮鼪薑|y}冪為蜃湇慱~{wtohb`^[]`gq~嗤藘wpjiilu窩誻~vsru}噢藉倧檥攄~ytqke`][Z]bhr嗑犩珧zsmkkox誶馺yqllou憲崿膲籩鸃說zurkd`][[]bgq嫖鐐睆ytpqx怯詈怑xplkmqx摬睫鵋楷ztngb`]^`ekt①犩衖倦殌媃xpkhhkov詣嫌鍶儔{slgdbacip{啃鼭觰警祟里砫蝫さwojecdhox凝翋鎏Ж}upliijpx鏑爦鉎蕈遛曖倗楴襙獑隅xqjdaacjs}儒坭蠌抪}xttuy框襴鯡僮迂懈艗鯚豪}uojda``fnu岷朿瓙錈疻鼓刈錵篫#も鸄ぅ~ysmjfcbbfmu儘崠氍椕椕棔陑筆8羝鸂肱鏺縌|xwsnlifefioz噬濏邍捁斑飩騫衃饕痕丑仁蹕禴醝鎂襘韍|wuuromkjklnt撿籫鍇楊◢朝鷓僩惟扣麻絯鼁薜煤窔插}vronooprqptx機鎯插※溶董咻之捏呿虡馳ㄩ繹}{wtqopprvyz|濂嬮馱◤盛咻ㄐ◣鹵邳捁●膨}uqqsrrttvx|匐濂鍶蟀ㄙ岩井棺庉こ咩妓蟬xnighklouxz4拰灕蚚揖帖失’頁趨衃и樦揧zme`_`cgnv邦敁籙省ざ揹仆痊忖ㄗ笠郯瀔譐菬sf_[_cju死拻蘠噫角壯仁粥岡“第硻}mb[YYZ\aiu窪燿‘府釩ㄛ豭儽}kb\Y[aiw用霘左布鬲朱迼鼘pd^Z]cm{斛鐒蘦暰ㄛ悸奴╯妝阪聧譝xkc_bis詣嚬矘齌坉鴉~玥歲酊壯{xwx{~啻鏾馝ulhfeipz剽睙樄魠縣鴉~}扒擱辣咻wqrssuy{怕鴈蒑Ю彌ytposy&敷妀豻蓇掄Ю膨zqljlnttvz◆晊簞洎翔葵}|“韋諮儆睅直枅彖umigilqrtw}★Ц※飯甜6迿鐔~}棧睧芛ulihikpqux直劑※斃鼎使蘠{xvz岑楌萯zokhilruy~此躁本昈赫~|~鏸vsqsy晃緺鉌ytporvy忠昃|{笮芨zusuy橢vnjikpy勢檍駗xwy}晃楈礎xttw民蚘楚zrmlmr|齊鬧mgdceiq{歐譊蟨尿嵉磃}tnlmpx福棆uniikoz環駟fb`^`cjr~Ⅶ裺鵚簿捌郲爞怚|piedfiq}終髫smihjp}昹養c][[_aekt玄檞謾婞貁蘡駜ylea^^`dlw喇玃wpljnw桅|ga[ZZ\`chnw倘指頛vmc]YWX[_gs啣灄~wsrx氘蠐zib^\\]_beipv箇伉xle^XVUUX\dr啁攢潸嚙{mfb_節bcfkpxB籫蟘xng`[VTTUX\dr喟簐池氂橉─mgbbaababfjq}橡壨sjf`ZXWZ`hu寥鶁翱之棒檛欚鞄xokhfdbaacglw湛萰{rlhc^Z[_fo燿齶嗛講趉鏻蜾葯{tokhea責kw莎敻|uqmjdaabdiq~羚穱鼖堍刳塎貙瑵臘瓚寰xrmicbcdkx梱鸄襯~{ywvronos{啻夒欉訧庍筌蝫妘扑橄椓zrlgcdgo{綠懪5俁齘鵽蚕珋皊澱鷿瞽}qkiims錠痦}|~玨謹蝂齁籔笰昐徆yqnov取懭}sqprx闌蠐zvvyⅡ祜蘡鍕詎蚡skfeeir橘鮸ywx~豢窷}vsrtzⅨ僛蘼覶蠳矘鶂槾tic_^_bit崚察虼~怫闅菄wrnlov~煜靸瓵揹傭湅蘹瑀pe_\\^adn~賜旱肏~賤顈{smjhlsy孚落|泐鉥ylb\[Z[^bkz序琿}厥槱ypljehou|pjhkt歁蝬xlc]ZZ[`dju羌翦藸}屋閛}qliegnt}wld_\^dm啾蹎ylf`]\_dgox允嫇齥牝葇vokhjpu}ylc\XUV[du鬋qjfccejnw絀澣衩屋戫|tpnptzug^WURTX`o垀鷍xplkknsx借窔耘戧膛}zvx}sg^XTRUX_l橇襣yvuuz倣冪棲谹儕xjaZURUY_m熟簂ㄗ介蓮◇眒繕什惜oe]YVX]dq潟廗俸敆捆砟里侞楫丑ㄖ韭撚敆vlc_\^cix遼藬剩錴鴃庖惆邑て凝ㄝ謀魛貗橐vkfeinu鏃黟刈踖辣弘盔牧捱忒迠料摷玂坁|usw}匙緡硊勾縞ㄚ扇眺譜碄蛨菁夒鶈蠕倦逜禛永踛壁炕井捧褡塙鐎磑永凞鼀桾蔆盒措蟲毰氃迠7凎闅噫妖絳巟霟糒耙嬿鍷嗏趹竤馲賥鋋鍎媬巡曖鴃ㄚ雪覦裍蝩|xz嫗蠳籧蜞詌潞蘙爦蘦貘檶牰ㄓ妓普褒紬襶躄wtuw}昦爦歔欶碇緡鳺麧賾礹醵侄互雯溶譁楌瓾zqooqu詻蠲繄捗岕羸遣疑嵉蠃ぐ庖劃雄洩捎撕~rlφx志齁曘宎隻創霙酁妠3噬趕ulgffgks旮攮梴|{~斛籛鵌翮lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust08.bw000066400000000000000000000123621437514534100245500ustar00rootroot00000000000000@@Rno name?緘鬧DTa+o;  K  Z & j 6 z  D  P`,p<L\&jDDDDDCDCCBDDDDDDDDDDCDDDDDDDDDDDDDBD@DDDDDDDDDDDDDDDDDDDDDBDDDDD′裘捙|skc`_`afp欬摀ztoqz賞罾贖|}~黎帛嘍詅か}~~}zrlf`]\^`ep√齉unkjilt嗦錆薑zuwy~噸蝗枎縃炡{zxvsmhb^ZY[agr祄儽~tlhiilu棻鍒uprsx弟笸儇鐀敯}yvspjd_][Z\cju孔蠲鮽wpknw端謼}rmnnrz煨霠壔~xtpjc_][\_emy芙矘駔}wqppu~〡蜦暪ypmpt}郖盟靾}xsmfb`^_bjr}貊鷿妦}}~◎軑諅襯}smljkot墾錔廲穩zskgdccgox卄嬿慞楫知党蜮捊rkjggjox習睫蟼牳}tolkknx殘籗鵜筍早陋祥賺婒魡梪蔑tmjgegkr|坭測鼥牊|utuy勿霙欏縐弧咑賝齀襑耨wpkgdchnvゐ堤鵰觖隅☆絔藸孩翫橛xqljfdhnv儔崌翴緪錛箯狫陞0轔鷽箕蘞顈|vplkihkpy祥踙檹恔謄婟嗏疶噹咫╡傅裎鵷zwz勞檥孻漆~{yvrnmmnqv~擋籙鸄侇岸辛翕蟹倢譟洛旬請楸vsv耘靳Еzvvuuvvuttwy箸ヴ府褕刐粟岷〞黑巠縉zvz剿芮~{wuuvwy|}|~懰妥壁撐馬ㄛ凰蠕}xvvwvvux}六濂鶊憧炸毀神ㄗ偶撐哄ㄩ珫xommptuwy}◥閥謪ぎ爰僩釭ㄛ蜂岊聶譆鳿ujdcehmryㄟ睿僦撾狫楓弗播葡疙貾闇譊暻yjb^]^bgny倩崺鐉噯悟爸炸毓砲打侳蝚re]YY[^clz曩籜╯╲捲哄畎澪菪od\Y[cm{帟嬽云酋分澪犐qd^YYX[dn|耙霟簐ㄔ戍~{z{}~菊猺whb]\\_fq~性樇蘠鱞~~◤洧奴‘yvu安x{佬鐊艬睇ridbbekt念珋踣鐐晙}{奏雯洧式{tqooqssv|邈勷蜳玵蠔unjjmqz弁滅紾臝堹~y~邪謝蔡upmlkmpsux}槳硪葛窄蕃ysruy〞邃齵}y}傅怤勳|snllklnqux暱簞3蝸族巘~xx{忿殍堎}uoklmopsx|威簡ㄣ藕窖卼~vutv}募緡娷xqnnqtux~正抩尿昒等zwx|遼ypnkmr|岌黽櫡ヮytsuz{怔婧zy}匐訧閒ytpos}圉魯pifegjs匿蕅樾}}菩魟レvpqu}匹楬薛yqmkimv科駑hca`adlw菅鐉禚打扜豂堔{qlhjlu蹄駗tmifgjt堊餘d^\\_agq|嫘謳觸健齟羭鵙zngcbdfnz箸礭smhegkv錠颳b[YY\`cks}③鐐錝鐖鸁瞽xkc_\\_cju渲鮹vmigjr釸we_YXWY^`elu皈杉鷾ukb\YWWZ^fr梓鸃{ronr|澗鷵wh`[ZYZ\`diov寞伸幘sjc]XVUUX\cp渥嚃|yz晤蟛xkd^]\]^`bejow窉血tjd^ZVTTUW\cr寤藑嗇籗篳tkd_`acflt⑵踶zoid^ZXWWXY^gw鏖蠳灛佼岳掀蠁tlfddcbaacho{踢蟗wojfa][YZ]_dn±鐒癰棎刳蜅罍縃錧vomjgdbbcemy屢鵏xtnkgda`afkq~潭罍槲詑艗蠆恲褥毳墾xplhcbcemz蛔爝|ywusspnou}賤籗爞摝筈艚鼖阭Ⅰ鍜zrlgddgnz瑜初籟氖紻鼖稊塍檴虒|}受鸁}rljilr}踐蛘挺阺儜謯欹楘覤yolls橈篽|sqprx豢黮~{|社崲蠳鏻瞁馲蛝skdbcgq暹鮵zvw}盃籗屩~xvw{旅翪蘻襡氆蹜灢臝毉蓗wjc^]_aht奮蕻鎯zw}鎢鸉|vttv{☆倜狦釣ㄖ煙檡礯od^\\]`cmz冀惌藚y|~習欑xsppsv}妤|w{壩蝏xia\[[Z]bjv勿燹梁}~盆鼥wpmnqtyvlgeip|崨簀wjb\[_dku匿澪蟳}~或羱ypmmoqu~shb][]bl湖臗xkd_]]^chpy倩毿譠||朗檴}tpoopu}wja[WTV\ev翽}oiebbcinv雌鍎峎嗓謷艦xurrtxqd\WTRTY`p沺蘌toljjlrw菩媊菁歔お}yz{~nc\VSRUX_l樵蟤yvtstx麻貌煜葯螳pf^XTSUX_l踡蝥~|左仍筒9昐蟆坎扛vja[YVY^ft癲朁玻敆為完藝野云祥薩尨qha_\_dl}泐鯠區儜巨仆翻砟○ふ賧劖甝~sjhejox佻矙撘Ⅹ叡噫◢岫丰奕饑漣匏儚謧慼{wux賤鵨堻〣薞蘊帖牧票м梒Ⅴ裺遶窖朮絅懞肏靼籜憩萱ㄓ垢捷譎儋橪皇譀曘佌陰拳蜊杻樦翲帣紜楜壁敞谷妝狗景齟儗灆~煖襴憼寔衲軞儆膹瀎襛挶ㄝ盡凝垣限控眼蜀忳蹖鶄{vw燥矔瘈楀賧黼鐨擨艛斔簪ㄗ尹垓溯虜褲娹籜鵖xssu{建罿詘摦鳵緷嗖馲瀔髱簷曲溶撓接滇枆髣|rmmns鎰鼥棦昒蕈犒頂о旚櫇邾ㄟ噶遘派’奎噸}smi叩w脖鵽郈陞玲楜鍻郅仍馨膨~tmgccdhq盼酃ヵ}|{~畋槴駖插lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust09.bw000066400000000000000000000123641437514534100245530ustar00rootroot00000000000000@@Rno name?緘鬧DT`,p;  F  V ! e 1 u A  P`,p<L\(lDDDDDCDCBDDDDDCDDBCBDDDDCDDDDDDDDDDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDㄠ轄觚穢~|slebaacjs芟糶孍yspoos|Ⅹ骫睇~ywwy麾牲屾瘌聽yvz|~|smfa^^_ahu凍襦|smkjjmv撿縻xsttw}孝褡淼鼨yuwwvsmhb`]]_bjx望艣zrkimv潑鍏}urorv|廷嵕艕鯕{wvtsojd_]\^aemz實嚄}tmkpy_儓糐}sonqtx擇檁蒧}xvtoje`\\_chr⑩鷽禳ysnnow依錂擿~umlmnu~嵅莠鵷~zwrmhb__agnx佩糶灛讀zvz匯薀顈xplsx扰軾襏誚xqlgedfls賣藦凝仄俋錭諆慰}tnmlps~孵嫁鍌揮{uommns~厄霝毊簾云傭婒摴梠驕xpmjlqy桂媾鏻袎~wvwz~嗦蘙懫迂蹋貁耪硥葡祖yrmlknt~儔崠攮駃蔚岐碤鸉掀碭蘼痯情|uollnt}冪湑蘪鐇蠰襛硜階副搿嬣~{乳裷嬲~xrpmot~噬踑縚邲筎錝鍡痷楓五擅雸鴃|vuwⅨ僦繀滯ztsruz擁蘩礭觸挈鉸逋鳷愻譟岷ㄙ傲旻|urt|蹦蜨尷|zz|~~{zy}樹鸆尷弗懍塨慡赫式弁播蔑xux宣梖楠|{xz}剝ン玷倠詎佌惚早普惜兮侁~|~ㄧ灅楷掙晑皊噫炕云雀悼俸蚚zwvxz〞曾祛氅酃ヴ彿朊芢僥均朴蝓翹獐塎蛢snmoqu{庖譜塝襶曄硭楊ㄤ騷蟋炒ㄡ囂鴀斶蘡覹pgddfhmw允屾黓籫ˍ萵郎偏せ隆最檡薷wh`]]^chs匿翪﹜飛僭竺銕pd]ZZ[_co}終〞偺箸滫qd^ZYY\dm|耕瀊鵓予坐|zz{{}框摮ufa\_en{京蜵蘠熀~丹~zxwwvuw|〦譔鷽~ogbaadjr◎尕踣攡~}市咿夾忖ytst叫sx賤厴骱詘珛|qkhgknw弗擁薣欒~z~仁號陬祠yurpr川u|塽楢葭溘倇xroqv~阬裾懟}z|掄Я繙xtpopprruw課Дㄨ囟|~啊鱦xxz}屁倵梠賓{vrqstvwy~副侇8昃楠卼}utsu}菩樘蓛誥yvuvx|}甚堁}}永豜漣zvwz遺vnkjms}民碞鐠珔}~絆萶}uty啟愻誧zspnq{啾鬧mgdcfjr屍澬鍶俸碆輹tnory蜾{rjjilu殷駟fb_]`dkv椎齖邍がㄛ僅堽欘堸slikks潑繉umfegjr堊餒d]ZZ]afmx箝攮甀邲塯蹗嬥~rjebdely瑞玂tmfegku橋|hb[YX[_bir|薚犪片彃ynga^]``ht唾襦xmihjq崨w頡`YXWY]`dmv核攄vle_\YY[_hs梓菗}sonr{渠醾wha\[ZY\_ejqx賡叔鮸tkf_ZXXWY_gq蛭麠}zz眉鶭xld_]]\^`cflr{佩籫攻迉tke`[WVVWY_gs魂鯡啼蘡蠖﹀kd^`__`cdjnv⑴鵊vlhd_[ZY\cl|坯頖釧辰驚矙鵏tlfdbcbbchkq}潯阜擽|rlifa_\]]^bjv眉襶醍恟砨霙獿賟罻vnkhgedefip|鳴攥慫|urmjgecffioy羊爃蘹懤縃蹢鐋挭褲紶墾wokhfefip}塗簆~zwvussrtuz啪蹗癰僿鴈蘮纊炡棋橫梐ytokhhkr|當葴~~8祏籜謱詄槴蘪熏|}受欑說uqnnpt}圓棱0譎殢籩錞嵫儌櫅zpllr}卦壖yusrv看鼚●硻籫齶萫馰鍷ラskdbdgo操藬{wvv{勂藡局絊蘾鵻鳱蜺贂鐏賟闀痚yjc^]_agr蜆譖藯{vvz遴懟{z|~副趼佴仆ほ觶鐖纕峞rf_\`cmz萱僯欂xvz喃簁yvwx{炳}xt}蹄襶踶~mc]Z]bjv鴃厗頞{ux冥懟wtsuy~rjfeks朻嚓{nc][[\`eku潔纚嚝{vy~胳欘呁xusuv}znfa]Z_fq格嚗|of`^^_dipy防趉儩~yz胭攮洈zvutv}{rg_[XUX^j{惢騜qjfccejox倩鳪熂~菌灒挐{xvyvlbZWURU[eu泂儹volkknsyㄨ昅端憵芛ukaZVSTVZcq蠣蘌zvtstz風照褁嶸xmd\XTTWZcqん邅~|足谷ㄥ飄僥圾ㄔ芋岩qh_[ZX[`ix沷撜忽倛仍滷妓褒恮珌znfba^afoK堥怕羰‵結允栯黀蠊珒yrliglr}嗉鯁菰噫互飧啻嬾癰肵|xv}癸嬾撘猿懍童ㄖ巨為蛻匟窗羌蹗鷿ヶ掀碠襐棚鐉撿佴爭妒洎捎鄞倎戧薯牒襶繀螂韌黃孖骭覈駌姻楏擄狦辣斯毓蛻屼趡纋肸曉罿寊笭圔澣澼膰錸珚牴孖壇齬藤臏蕪壇眈蹖躆~{{﹋燿攮篊蜄膴蘟襡毈麧馹憚〞儐翔飄Ъ擦賺紬籗攁xtsu|啊翴颬睼鳲靳笝殑瞂棐提必褫昋翻項飲殙椈|rmmou鏖鵽寍旼蓿敞窄憊碔慔儕姣弝陔葵朽辣}smiijoy喃鶆芼活知貤瑮簫~}~~盲杬蚥~tmgccdjt盼轘嬰|yy羔馵袤|z{~lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust10.bw000066400000000000000000000123671437514534100245460ustar00rootroot00000000000000@@Sno name?緘鬧DTb.r>  J  Y % i 5 y C Sc/s? O_+oDDDDDDBDDDDDDDDDBDCCDCDDDDDDDDDDDBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD酉砮樔翩xw||skda圭ju冢譝vpnmnr{閤痾xrpprvz麩掬淼懃|ttvwxwqlf`]__dkv渡藭ypkihimu端諆|upnnrv{噫籥勯癰罌}trssrplgb_]]`fm|囑屪woigghlu踹蟼癒}tomnqv}導塏燿蠁xtrqpmid`]\^ahr釱嚍zpjhhjoy匹鋿蟝vommot}擄蹜孌~xusrmje`^^`clw格鸉vplmpv侍錤轙zsomnr跖躲輲{wtpkhcaacis鏘轕縝~zutz厥薧駍~volmp{唗盟樆zvplgeeho{併籜縒椰納摐薃縜zsnnov奮蕓鵩祫ytolnpw嫗礹藑椰戊逤雽竤埥xspqs{詻睦鵳祪~ywy|汁澬欏縞旭誼棇挳噯蝸漫{tnmrw脆欚觭漲紛翭輷笙殌隓翮忙﹞~wqosw喔爞罶矘囔凗陝挫粣虒yww}最馲鉲xsrsw壁蕡擼Ь郯夒蠋侀迄薹屨zsqry倒睮堈|wvx{擋籛輴捶奕豐蹜鄶蟒◥章揖wrorx晏頍Д~|橘鼱揣彿絣鼀芼砟╪爸zspu|棹梀揖|~歷瞏岑溈襘蓛蟈╪圻zy}純佷ㄦ濂譧珊湇誾陏楞╞爬傷芼~═玩鉸機鵴ヴ◎拹瘈捙答朽蝦粟挪凈鞄|usrtx底遙ね僨曇葎豪直邳蚡滬酉媎鳵罶蠳漹znkijmoz挫倱蛵譓﹋褸除ㄤ賽饕末暠鱺{lda`beht剩踠礹欚′忙風煽菽翽sf_\[\`fp}敘霠玁旬飢|}脅竀qe_ZYY\dmy晒羬藣妝|yxwㄋ卅蘩嚚uha[ZZ\ckwˉ栱譓斲忖|wuuttru~賈矘蟙qg`_^afnx彿俔齍攢~ㄔ{vsqrrsrtz唱厴槲筈睇shedglr|孛祑毊}y~辛陴捲郎}vropqpqqty勛楎楝偵迖vomnsz公噊懭|x{弧藐藝僥}vsqrtrstx~圖が動芘yz度}vwx{△屺寋妏zxwwxwxy~棵芘捨挼}{⑵yrporx秉塍魨帣~晃袷yvy墅棐悻|usv對鴆qjghkpy勦錤籦帣正逌鈶xqpry〧蜛|tomox芣sida`bgozⅦ祽邆收睡儓襐~qkklr|嫖曛~sliikrWnd_\[]ahp竺唁傶葭敷邰劋癪skfeglv桌橶xngdfip文餓b\YXZ\bjt耿鏸纕豍闅齀橏slfbbchs拋藬wmfdfjs堅鱣z頫_ZYXYZ^dlw領襆sic^\^`hr怒魙zpifhn|沷驫we^YXY^bir~竹蹥味鸄ぁxqib\ZXZ_gr剖幘tolpw喲鷝wha\ZY]bfnx菊材搋tkfc]XWWY_gs啁嚂}yw}巴礹鶱x駝e_\[Z[^aekr|天籫轗zrke`^ZXWWZ`hw魁爚房蘡蠓~髮le`^]^`acinx蘗躄|rkhea[Z[ZZ_gs哳繂僮車濬蘮藜vmgcb軼ehmu踏斖xpjhfc^]^]`fo餅纊寍栲錩羻貏殪xpkhge愣ls塚醙ysnkjheehhks算襶瓙勷濷鐓蚋撳赸縛~vpljhhjms~舫鈮zvsrstwy勿儑欙斁嚬矙纇捄敝橙埴ztolklnt}航鱢|z}~菩踤檶摎檁癪z{濂欑誨vrpopu}佾藸朱弚蹢麠楉蝍穱飺xojjox卦嬭|wtsv|祊擿宋挕蘠鵱衵崽臝悝uldabemz操灃yvvy燴藦笙楜襘誻衭倬詒嗒軘羰蒱}ne^\^`en}嬴齗欒|vuw~冥亹弩騰譟授挃楁賾菢sha\[[^`gw儕禕鱣~wuu|尤囅~╡~wrou尾塛鏺鯬ne_[ZZ\_ft腹祋蝟xuu|I犪痦yx{wohcbgo{盅籫藙{md_[`dku曄梓yvv{忪蠰搛~wuv|~tkc_[Z]en~崌鬌{ogb^cipz麩紜絖篧{wx建灢鉯ywu|~vlc]YVVX]hw欴鬋tlhdcdipxㄞ庄畽{z|唱瓕暋~{~yqg^YVTTVZcr籫騔wqmkkmry2遣~~喀殫挼yof^YUSTVZan矗髂{vsstx丑動疺蔑坎}sh`[WUVX\dp⑸奰|{左偵僭ㄙ眺遘祖{ne^[ZX[ajx秕篕旦庉~}~‵郊次厔雽怹wlfa`^chq立獂Ⅳ絯扣菅爁虀犗zrlignu鎘黫~者霘噪ㄚ乾耿齖玂伬}yx~喝襶蝵~峙譖懈漸﹞ㄕ狀頂戲怩嬽鸉Д死軓矙鶈汀翫曄埬惇垂祗拿瑣刱窔閒欺鏺謳攽遠給襖毳薃鶂訄~凱摙諃筇鐃蝸瑣薦娾擤痯潼謷楬竦矠賟膦賥魤ヴ捐菩笻楺堄岉饒貤蹗縌~{{~⑥翲摦賚賾儵諘嗖詙襤噩с摦甂吇鷗匊摙氍邧ytsv}羞鍺葐摳靸蚐昋恦衶韁捩碔槧抸僱飪檣棔}smmou黴鼁豜Ц歇爭狗瑭刵憮~~宋凊魴妗曲提tmiijoz港鵘妐戊竊陓zxwxy}仍咂馽umgdcdjt盼鵒誨|yz札俶妦|xuttx|lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust11.bw000066400000000000000000000123651437514534100245450ustar00rootroot00000000000000@@Sno name?緘鬧DTb.r> M  ] ) m 8 { D Tb-q= M])mDDDDDDCDCDDDDDDDDDDCDDDDDDDDDDCCDADDDDDBDDDDCDDDDDDDDDDDDDDDDDDD斥剒繌}vwz}tlebabdkv寨餑{snmmotⅡ拏竄yspnqtw}姪郬轕xqruwxwrlga__aely鎚銝umihhjny▽殗炴~vqnmptx~儘解踮鸄wqqrsrqlgc_^_bhq崚幓skfeginw‾殣鞃uollnqx噥盻齍囔汃zurrqomjd`^^`dlx唳鸃tlgfhjpz玉檉襋xqmmnqy懍殢矙灆|vtsqmjea_`bhq沭鱧zsmklou肥隰鼞聾vonot}跍跦駓zvsmjgdacfnx冤鯗zursx~棚贀躆ztqrv彘較毊ヶ}ysnkhegkt輯駏|忿楋壚礱襯{wx{憩爃蠈郅}vqnmpt~或蕻鎯都狠阼睧蜼瑧}}~~釐睛獿慡儔|xwz敝艖鍼弘瞄倰釋薹迋嶽~}|噱禊鐇瓙餂楷純殽硐&褒珂戮壯垮毀噢潾醳塓譊礹謧儐疝騫竅}xuwy窕扂穩}|寰錪蠃ず譏儜鶄幫╱晴郭wrort|掄玴馳歆鶀簧成腓澬殷蚇迭”洶uqnqs|傷挳橘矙糗細燹縠戮xrosv尬昒鳩橈斖慾勤鏸攡葵~yvy~傭糧尹氅鵛鞅籗灚彖砲允簪平拳翔機鵫空碨籓捁陞朽遙揹奎纖朠|wwy}弘酸賽俷蛺曇葎憎敝蝍馺警那栱蜠樇鐇蒴wolmpt●嵕碚豍緡彊褸悵7倰簷汗僤蚺ukebdhmy樑薃觶膻谾&坐香噪砠猾孈zlc_]^agr夢壚鐎儴箾曲悸~桓蹇wg`][[_dmz晏儊籗籦餀予均|z{〥齘巀{ia^]]_ckw裒碭鼖戍}|yww{骯犪鯡rhbaacfmx此眅籗氍ㄖ~}{yxwvx{啼襜槮殙暆smigilr|釆郖懖予洎秧惚|yyxvwwy|紼袼雄粉迕{upquz岔潁躆||仁嘀謄噩}}|zz{~團ヶ務庣脂籫曫~xvx{挫邯桸簷粒芵旅畟悻~⑴yqnnrx˙栖鳿矬●阼肵ywx植覕蓮~wuy瑛魯pifgjox罟踤艬瑢窖有咑魬ゞzqnow轔篋齒~vqnqz芸駕hca_bfnx夤鐉齵埣鬲捷瑭咇嬽襉tkhioz羞襢囥vnkiks文md_[[]ago}汛竽甂砣碚檍蠳獾wngdfkt白欚茤qjffip噊jb\YXZ[ahs個齘鬫欉舠xohdbdhp郘鱠}pidfir禺}h`[XY^enx錘羿毊拑wnga^_ago惌鉒}qjginy闖|h_ZXY^cjt~個蘞杖攁yqmib^[]agp廿暻volow兔~餓a\XYYZ]cipx暸鸅觼}tmigc`][]aht唬螤~xuz哤pf`[稞_bgmt~芳癪wplgdda^^\`em|鏖攥⑧戁{of`_匝bglr{朼甗說wqlifcba_``cju佻繂楨尼煉薣矘轘zoiecbcdgkpv鳳橝{toligddcceflu﹎薣爢梋朊碥蘱憵碚迫{rmjhgghkos塑棱{tqomkjkmlpt}毞礹鵿擨齀纊瓟雀ぱヰxrmkllmps~格黮zutwy}ˉ跇鐏潞觶蠮斔滯允曄珜|vrqoprv~皿藗~{z|晏蜑瑮桉鋹矙縒|z~嚪彃~xt率{坭蟴凰嵂蠳嬲藪拺齍鯗{smknw擔襋{xvuy樺藑挨崲蘱鐇鐠堎虜巍鼭漡|ohddflv憲蘠鸁縛zvux脖甗此挀擤馻Ц衝в醴虞蹤襜秅sib__aenz粽賊}vsu|臣爢瞿1撳贏孜撩褫斠蝻}me`]]`clx芹徹晲wst{矛矘踰奶xrnmt首枆檉鉒wic_^]`ckv芳蒺wttz抹蠮懮|rjeaafn{毅夒琲tica``bfmw儕唗嵿xuv{建矙鎃yof`]YY]eo潔襴埵vlfecehkr|儕模摠蘦畬xvx倪矘嬲zqg`[XVWZ`kz鍔痋xpkjikns{麾收黑晟癟zvy羚蘘颭閎}vmd]XUSTX]ft璦蚺{tqqprw~足}z}博槧狫釦ulc]XTSUX]er蠣蚸zxxz剪斻雄洮岳失zpf_[WVWY_gu昮黭~炮秘疏╲蜂だ隄vkd_\[[^cm|涺奰△弅}~岳局涷縰牉tlgdbcglv凋蓎椎鋋麩ㄘ箕籜欙睅}vqnosz⑩韥~▼翦噥帛迭嗜襶礯蘇Ⅶ暟簋|~℅蕍媦╡炯撚楊敏欏伢咱有贊嬾鸅~需鐉蠌楝悚重健衡倧覂污澺縶疺Юг瓮骭嚬罍茞珍塛橢鼩硨芢Ъе崿膲鍭藺封蕫齶橀颬樥膼擣緛緛硥孛擂錥厴歕棴婭楴鐉遻疢霘蠂蝁樘闃儵髧梊婧佹噢凅錤犩槬恄珋儊纆埴|yy|棻觶罿椳葮葠棞Ш蝓飄ざ齒境踕鼀仴毀黃阹埲vrrtzˍ鼐鍏寪岈僑高言辛馭す恥|{{}汐跘謱庛妤除tlklmt筵鐙馜簷什檄織}yvuvz|□紿憵讀ulgh叨}菲蘾樿}zz}旦岊葷}yvtsswzlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust12.bw000066400000000000000000000123641437514534100245450ustar00rootroot00000000000000@@Tno name?緘鬧DT d0t@  J  Z & j 6 z A  Q`,p<L\(lDDDDDDDDDDDDDDDDDD@BDDDDDDDDDDDDACCDDDDDDCDDDDDDDDDDDDDDDDDDDDDDㄩ絏敺}vtx{}vnhedgjr嬾鱦xqmpw札豖漱ztspnqrw{屁禂熐wqoruwvsmhcaadjrE襴壧|rlhkq}氐窙阭wqomnqrx捺儑鷽vqnnqqolgd`呈jv桑龢zpifefioy氾賧鉡wqnnmpu{凝扜蘡噾zsnnonlida__`fn鏍龢{pjfefjq|肥爁躈ytonosy壇裎鵊wsqqnliea`adku舍譪uokikou啄蘩醟ytrru{戰蹞欏}yurmjgdbeir~遵輵~xtqsw~靼蘩雿|xx{媺躲鍐漸|wsnkhfjo{忱襶巕薊{{}怏塛孋~擂籜纋棆迫|vqnosy詮鸁蠕介は詊膷灖堈擅匷虀嚦樼情{xy|ˇ趉蟼夆ㄟ褐鰻褪栻髧仱憶爃謶僶穱罍睌ㄦ屼秷疙撮楓戍食攫霽憊薤鍠珫湇糶縟童奏獐部|xuvz~紡蓿疝僚戰鞚鶀繪滂秬擼憤╪炎wroptx○謠握云岷祼鼞炩坐征淜鵌耨~uqnnrx旦鰻﹞鋿欑薊˙僤浦擽翱wqoqt{素鬚﹜橋轙滿濮橤漫~yvv{彼藩揭ㄖ言不曳氅擸污錵藢簽倌繒妍紫掠健樵蠂坋者蹗曚И炸雅亢談侉仃酷囟聶谿曄甃嬤楮薀謼狤砟仄癹睒殍蜒熆ytvz玷栲靷桸冞樞岋等母軗硞劓札裺飫{rmjkqv事碡鍣雵絞洧~~玻羶洽箇齂ricabgly擄隬鐠疐挸黎朴熙倫蠙|ne`_`cir時麀蘟錟蚅◥郁}{~升譔懽|nf`_`bgp{脾僦纋娷ㄗ均~|}豢戃tibabejp{介极襶鶌◢炙~}}斜襘誺碲鞀umhgkpv~旦羜懫中貝拿骨~~菸痼熔麻婟ztqsx}宥蕻鱢′晴遛擘略兮恉粕蚗喂|xz~乘晟捀蔚☆玴~封硱揖﹋襳ysoptx六冓緗蓒憚◤戰閞wtu~耽駇Й{x{賃鴆rkhgjnx甭蜰蘾橠膨酊拳眼鄞凅鍞怚xomms釐蟼炩wrpr{祉駙ida_bfmw煨齘鶀倞饑迗嵑膷欒rjggmu能巑zqmjlu血oe`\[]afp}牟匴約襛膹斀籜灕犰zogdeir尺隞tliijs文lb]ZYZ\ags敔缸籦馝膠sjdbcgo~郘蝺~qifgjs芻k`[YZ_eo{_澬伺髬螫smgbaago郛赬~rjgimw闆}j`[YZ_dlw敕鵗馱yrlgbahrI嚙unlnt惌nd^Z[_dks~鱖阿鎃zuqnkhdaabdkv栽懽|wtx鎘駙jb]\\^adkpz晚橛{upmkihedbceir~鏖搮潸鱠qgb__`bejov~祋簆zsoljhheddefjq{啕襶簊除玲噁斸|qjfecegims{鏝蛦}vpmljhhghiknu~胭籜齆埧壇淢鐎懃楸黎}snkjjkkosy瑚藚|urnmmlmmorw~潑襶鐏樘嚦諆膨晷壅xtponnptx盈襶橉|vusstux{~詩爃鵩鼐欘睅擂阯{wurstx泙飺{y|~防湢蠀旽蜅爝}僾旓|xv|鎮鯄孛俋齖鵷噙僅碤蓁xqnqx據蠳擼墨{vvy萇囆孚忯鏺蘘豂縔簪扣福蘞觷vmigjnw嬴嬿齵怉|utv~佾靘○蘸賙篎抸虜瑤輔4唗銇zogcbdhr器錔蟙~wst{J篰#嘉幫中’照黀茛tkea`bgoz噹膣猺wst{K譭戌}vporv’挨裌鄸qida`bgoz萎徹蓎xuuz技鱠wnhdceir~狠寁頝}pjfccfks~噥禖葥xuv|栗葳|skc_\[]air紮薣蓎~smigilpz噶淢檖纋囮yxy晦欑嬪~vmd^ZXVY[al}嗤葖~uomlnsx噤遛褥卍xwz毯犪鍐嶽zsja\XUTVY^gv潘菬xrssw}市}xwz煥糈蚙撈咫{sja\XUY^gu闕搰|xy{{zz~掬匢雇健號隄wmd^ZXWX[ajy朐唭}~姜~~||}奕恭朽證谻覺ske_\[]`fpR蠓掏{{~中宣勱鵻捅tmgdbeip{樹篣~~竺儇墨}~~═鎊鵟膠}urppu}建堥||商齖噥◣咩鎊欒躓倒鞡鯆}yy}羞籫擇薨ㄙ捕蝶郭箋礯捘揪中辰諫氀斖~zz~耗譔纊狤雄悅秩酸劼祲穫救籦髧笢玴衿馲鋋嚭韍~{z~冗趀橈蠊皵衵晟軝緟襛睌內渿謮樉澭擨厴鍣皸摶蚞~{|ㄦ撾齗蘾鐔諙樏嬽齆堋煦霠鼩魟樏旚襜歖媝迋岈窗~}壇祼蠊睟欿濄齌硊◆崹殧稌詅嗈寋珌擘蝨蕭惜~墨擇襳橯繒雀賻婕縝{vvx怕睯雸捗躁敢酊谷帛絢滷~zyx{}宥澪奱齒╲恐zsnnqz鍍懞棨憚食辣~zwutuwz分裎醡xqkhhlu蹂蘘僁}z{~邦翻{wursw}lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust13.bw000066400000000000000000000123741437514534100245470ustar00rootroot00000000000000@@Sno name?緘鬧DT d0t@ O  _ + o ;   J Z&j6zFV d0tDDDDDDDDDDDDDDDDDDDCDDDDDDDDDDDDDCDDDDDDDDDDDDDDDDDDDDDDBDDDDDDD喀鏺橧}vsuy}|yuoiefhmvэ謷あtnlou8宎|vqonmqrx{嗜籗蝢wqnprutqmiecchmw拒籜鄸yoigfgjp|Ⅶ殙捃{tpnmlpsy尿裲樲vpnnpqnliebacho魂屪wmgeegioyや鶅肸}vrnqv|□紻嚁zson峽ifcbbejt天艣xmhfegjq|使蹗鸄薛yuqoosy噙孮矙藣xsqpnliebceho|港簁~rlihjmu啞襴敻yvstw}學踕轗麾}xtpljgdeimv抈磎{tqprv}漿襶鱠}zz嫋弊鼫抾{vsnkijms唱襶藢儘|yxy~阬塥穱藑澮齈矔槢抰|vqnqu|豎齀鍭簧第珆詊檖齆珛心籛癰楺詏雺躑{xx}˙冓隑蟀弧謝蝴敷婇縤酈擄鐊玁蚙黨趡齕袤*酸羹|~音歇*婟佶撻霝嬮噙鹿跖橪‘帛~xvtvy0散妥螃僖操隮鉐砟互や鍉漯xspnptz仇筏垓高碪孻膚椒茗襆翱~uqnlnsz孝楓◥洹槶駋滯★稙浦鵖凝xrnnqu炮答◤洹ㄘ橙襗捅Ⅵ澬嬧蟑~yvuw}有集契疵忙垓闅輷⑥紉蓒漣仃陵╲源輔悟做整諀贖牟檡鸄邾迭巡釭什熊必褡芤像秦懊豝膠{{畋錩蠉芺迭捩尰婠昃昃憫}xz~釆栳楗し韌噶鐘~xx{絀鴇慛膨嗎穱爦鐐蚽wpmnsx分逜篊笵蓿*盒yxx}汙旄佌砲喘龘yngdejp{舜摋糅蚅雲ㄒ╰}{{}○遢隄肢襴儽tkebadku忝砳擫瑧艙炫惆化薤蠯ukdcadir倣郴蘪槸◥豕嫡籫鸆ymfceinu〃ъ籗鶋〞骨們樏樈撂慳{pklotz旦孲蠀成音隄納捚雅笆桲}yz~晉澺ㄜ飯壅艘6ぜ岔痄誇鏺籦|zz}ㄡ蟯衵侚策左芍邢巖~贊捇提勾錤鏾ztqprw~紜嵎摝疰悵帘硫董偽蜊玸戔xtu|米蝆媃葵{x|喜黀鴉tmjgilt~詩鴄蟿秸遠溶賺帊砵賚鉲{qnmr|缽襝慒ztqry肋觾髯lfcabelu倔蕖儴搫俵衯馲澼齀鶀wlhglt+鐒懫{rnklr郟pfa^^_agoz‾禘鱈鐕臇闉襙豂罽怑shdeiq⑴鯄ulhiip哧駝c^[Z[]bit勝蹖獿鍷棈Фxpfccgo}攬鮿qiffipI籛lc^[YY[`hq}廷檞昀蠃佴郊xolfefiq~⑶藫rjegkt脖nf`[ZY\`fnx筵阿襏誑}xpkheegkt厗欂unilp~麟tjc^\\_aflu晃指鵓|zusrqlhgfgiox臾鱦}vpr{旎籗鴆phc__acglt~箝戄}vqqnllmkhhiilt賣磍}反濷禴ypicbceilrx瓜齗隡{tpmmjkklmmou~殼蘠襆倆羭謺徻wpjggilosw~潮櫸wpmlkjjkloptx}詹鄵蕊蜂党鳺硞眙儐zrommnpsw}斛蘡篜vqnlmmnptx|乖錹覈蘻鼩睚瞂葌織炫竅~xustv|亞濊蓐wtrrstx|勒僨槾貺霝皭櫅躑戰庥~{zxy}羞檴獺|yz|~完祜襶犕獄呺籗灛縑擁緷郱}xvy肪貙耵扑т霟橭陞有砏蟗ytsw~嬝翬攦庢|vsv}+蘜皒玷郪鐒欚嚭鍣馝插ˋ叡鉞xpjjou噥嘵灢鉯}uss|坰褆扒幵蝆雎襄斯雩隍詹欗怳zskffkp}噩裾戄wtt{+鐉襋部仁甄臻牒纈ulggfgny像噊蝯xttz忪襶鸇儒丑xropru櫺轗~smjkt~兢踙蝬xuw}相籫駍{rjecdfhp|弦媸鯗|tplqzゅ孌ywz瑯礹篰wpgb]\\]`gq汝迶巀|usqqsz裊楴鳻橖|wy菊嬥{tkd^YVUX\bn~書蹖簏}yuz噬噬厭僖{vy萌蘜櫆芞~xqha\WTSVZ_jz瑕賳~yz}勳wuv{勞蜙捀鰾葛zrha\XUVW[akz闆漜~黎}ztux~挫躁陶馮飄臻wmga[XXY]do唄龘}窕z{yyxwvvy{狐屆仇幵萻ぐsmg`]]`dju梁蠖|玳yyv鈍xz~ㄐ巫氁鶅梬zrjgfgnu扽韏ywz詩儒}yvxxz}╯〢匴斸畹|xww}菲譪|vux■楒噯〝泵〢踛鶋芼恣氖淝皝yuuw~撾擇薊互頃謗凶僪鍱嗀ぜ凳蜂挌錴矘繂xutw}喧橇覤蕃粟秣瑭尥睔媗內絊蘮纍緪槼蝆豍鳹擤鍆窳壓zwvx~汁橈蠂誺嗖笸摋壝瓕傸惜珊湆貗罼棰樇瀦蘾瓙殧嗏疻|yuw威擔齗矘瓘賾禴繇簾屁桏髧衃婃緧闃瀌駂恀ぜ楫~zwy噢湅欙篎軗濈謦袤孛劼珂迖婧眑眛せ蝨遘援}|~壽籛轗議契學玶翰{{~阮珫岒翹僚酊豆忖辛眾惆~|yyz}刈踑彄囿wrsx模祰蔭〝停~yvttvy}菴籜鯗{uollqz諍樈き}ywz~ㄟ歲{vtruylablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust14.bw000066400000000000000000000123721437514534100245460ustar00rootroot00000000000000@@Vno name?緘鬧DSc/s? N  ] ) m 9 }  F V"f2vBRb.rDDDCDDDDDDDDDDDDDDDCDDDCDDDDDDDDBCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD肫齗簃}vtvx|{yvrmkjls~者蜪棳yrmllmot傍螺|vqomnpqv倪鏺篢wqnprttrojhegks萌鏷鈮tmhgghkoz碣袷漣{snnmmorx箏矘碻vqnnppnlkgfdfjt抈銝tkfeefimv鍊鏻袙|uonmnpv|肥蹗鸄籠zsnkihedehl{喇蝥vlgeioy卅薣齶埜xrpopsy氐裱糗xsqpnljgdehks⑨瞏zqkhfjms啞糶懰yvtvz捱渿鸄妧|xtpmjighlp{冤籩鸅鴃ytpnrw}撾糔}|}戰瀊謰旻童{vsnmkkov鎢鵗誘|wvx~岌斠褆曄籩鶋疿恛貌}wsprv者濊纍娷捍栟馯檁鷽拑樺鶆斨豁眣恞{xy酉劼訬蔭偕撰絡覆羰鍗弮洶垢樽爢庛偽槳緱橕簾‵捧像|{}#痊玲粣鬾牮鬲整鍙祧芋╳歾齶桮﹝ywttw{‵派打竊蚔摯韋曄懨仱污蕫藦漯ztqnnqu~收0撢繞偽膴犗敕茶鵔耨wromlot~音弩蝴敞拿樖犓◆朅哼衖}zsomnqv※筐牯蔥悄垮撾魤坒燦鵷膠xusrv|庖隻今謙痕丰豟萯牟蕻缸嬲~|弗畢必嬴劑之憑觛癡肺蹞鶊簫ㄝ釩ㄜ惚延鹹痄筒噶迒滯}zy}耙蹢曚Ё料棇埱雲厭葦~倍婄葰貌噩謠{utu|棉潞罅痁華籗欗鳼慛vrsw{社逌魆鑄╰&韌|vttx札桉豜貍萌灄tmkkot~傚蛵楱賓豆ㄛ咫~{xw|偎臏蕪悼啪蘩眯{oihehox忠媎雵妧筑黎}}玟項雀迤氾濏摀{pigehmu純崺魰蚥黎狗悌帘洩樑蘠斲umjhkqw〃勱纆痾〝掠咧之陋粒摞蜪緺歶wrorx}允渿蟺墨車絢揚弛托掠派笙虭蕈黃玿伀~~穹碤平嘗ち蔔炙身厭摹娃繙疝д憫創燿~}姜婬挳跼帘措騰興洩窒岈棣媓噙咻颯籗vsrtx里党蝃蚧跼祥賻笥釋鰓欻蘇zutz澀誺觙窖}yz帝壛鴉vpkhjnu|嗶蜌魠婽蝦賸嵎靷椴麃駓~somq{皇爁藰~vssy鎢鸄魅nhdacemt倖蛶儵罼笪崵瞅濋闅蠲橝zokilsり囅}tpmms{潮xlc`^`bhoz障瀊禴臝謏鳽氆鴀擫皒vmhhjo|髦孍vmjijo{潺骷ja]Z\^clv區蕅灕媝吇鼴繩}rkffiny賄韥qhffin}⑨qic]YZ]ckt羌翦明襌簣xohefip|踢覹sjefjp翊ulf_[\_cjq}◆跜阿奱楠{rmggiks⑩鼛vmijnx喋|pic^_beipz客濏阿颲{xwxxzytsojjkqx而蘞鱧zropw扰鸄xpidbdfipy嗓邱虼~vqomnoprpqonosz嫗蒚}z{箋蘣檺unjgijlpw晃蕫戄vqljjkklopsu|朕霘顈剴歑羱~tpm酣rwˋ酘噾{rmkjkklnsvy{~濬譊蘻蘻橐僮ㄖ傳欻訰つ噙yusqsuw}怵賝葙xrmkknprv|未嵀罾趡鵯隗尥豝徽壯壇郭{xyxy}~萋蜞yuqoqvz倖裖鯕俓鋿鵩瘊抴噶Х恣}{y|怵嗈{ww{往凈鏸蟝筋倌幁襓噱袃堍極yvx}Ⅷ睙ぁ排溈穰灉鍥餑|vsu{勳涾蘘禜wtu|踱縕ㄤ忔譀蘹嚭豂橎耦倭籫彏}romos|建賅珖vssy潔蟼う疚枆睟芨僑給毽+鐉嚂xnljlow儔翑蝜wtsy鏖轗飾弁厭揮沓奱xqonnrz劑媿簎|vv{B蘠糒{tnlnrw所謺吽ysrrsx墾濏趧wy忱襶鯜~vngcbcfjt踴蠉zyvvx|懍檡矘攄z|毯籩戄|skd_\[\]ajyㄚ毅蘟眻|}{{媎鳷槾薨|z}孵昔暕~yqga\YWWY]es級楻驞~|奮臘董{vw{算蘻謦秸產}vof`[YXVX\am賬籩蠖噙~}ztsw|煦蜛皊岕褶zqgb\YXXZ]cn砓趥}}朱黎|xwvvurrw~偭罈控蛻恘籀wnhb\YZ[_gr芬堥{{}挪zurssprtvz帛孚眄魶价wpjda_`fn{獰艡{uuy允wrprsqux{疤薋矔堇wpkhjqy肋蒟~vrrw汍{vs鈣w}中彤燹謣鑒|yz鎮襦xqqrt牟噥{|~~互祠怩檡鍕埱滬珀裚欒smnpt~床據き旨嘗羹畦勒裱纕緛槦梖鰾薺豗膧瓙犕}rnmov~隙橘橖抳盛結蟬砮槻梀楔傘碃艛歖竤槴鎀臊擨鍙錛鬾芵}tporx旅橙蘜鵻鳲誺膴譀矙謯芵倥倱嗙棨匋殢穰蘹歔桸刓}wtsu{擅檞蠉妠弛◣傢庉遣親崺澼麔殪笵醴輔zxx{}噱絊鼨瞁鳻臄暔邢臏撒壅庋旂眒昉擘歲悟|{{}煞襳禡趕硃薦苃忠藪蕃毀乾洸豆戎貝爭央}|~}zyy}燮踽扛{uw|ˊ齪躉惜ㄗ炒~zwttvxz啡鐉萛~}xsnot}檣皊窖{wx{~奕|xtrrssuzlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust15.bw000066400000000000000000000123741437514534100245510ustar00rootroot00000000000000@@Xno name?緘鬧DSc/s? O  _ + o ;   I Y%i5yET d0tDDCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCDDDDDDDDDDDDDDDDCDDDDDDDDDDDD年生蘞藭}vtx{~}zxtqoosx匐睖怌ysnmpw偏擎恥|vpommos役籙遾wqoqruusqljikox需膻珖soihghkq~碧赻霽{snmlmot脆礹嚌vqnnpqomliefjny用蹖灉~snheefjpz〤羰鼖邽|tonqu‾蕫躽zsononljifegir詨囋tnheefjs}役蹖纇肵~wqonpty棻蘩橑ytqqnljifhjnx疋籙搋xqmkiknu喝麠癟}xusu{劓迶矙蠉妢~yuqmkkijnt瑟孌zvsqtx~醬蒻}}憶薋欋梀劓|wsnomnr|瓦檡擼慫~zyz罔翪欑矇錹槸蓬葦|wusv{羔蜦檴离剪粘蝆鼏襶鵸Ж見ㄙ樵嬣滬偶鰍芤{y}捐弝捑蔣4壇蕉瑪杻鋺橎恲遘機襑蔗弗ц氃桴◢炬偽~{|挾惆朽呿諙葯岕機攢仱尾暟麠炩}yvtvy垢純笸寑眛橢鍌穢ㄨ僓襑楊wspnqt|ㄚ掙昋囟奼樺縖薛候蘠擼蓮~|uomkos{╲邪臍蕃學曆諗竄污檞鶁蟀}{~vomlos{平牯擊歇硃擂槲躑晌鞚藯膜{z~{rqosx帚央今舊僭豆构埼晁譖恆堋~zyxz予式朽褥繩憑抮癸齖拼鉐0揪ㄓ邑竊陑等噹擬yww}校蹗麠炩倖赽襤ㄖ俯殍婽提儕斐~wssw}勦檍蘪蒰儔匯譐蟼媌繒|yx|忿涫瘐髡墨郃wsstyㄨ桉摵棝罹嫗欙蒨{urru|ㄥ幵雺蟒齒角xttuz推庉晟芩陝嗓籫譝vqnnpw~那疧楅幫ㄗ央{zyz~炤蝙豳Ъ楨封爃彏vollot{純涫戫僭ㄞ仁順絲奮せ悻未歆鸆zrootw~ㄥ呫臅蒑仍岷弁兢陴雩襟佌洛4彴膵鉓~zxz~倦塣纆噹炭蝓撈祚期曶芺陞戊蹉芶播騫佸棧儗儕╲鉸虭應爸紡婟怷痔妙溥艘往藤萱旦婑往屼覘ご洸捆м訹恲犖墾繙粒敆ぜ滲Ⅴ幄zvux{末砵葇佷神捆м椴祲旄梊伅yy槭濋閛憫~}序踠ysolnpw|剿楀嗔譯絮賸笚摽睼賙馝ysrt~癸爁鶀麩xuty詼罼skgdfgov敉筎萳狣蟻邳跂詅縃瀀縌vonpwら曫vqnnsz帝魱揆pfcbceks尾湴鳲蝃睧頍棴迓笚蜪萩unlns潺蠯yojny承懃zneb_abgozⅢ砱旚顝謥桫葩晴賽蟆|slklq}賈劙sifgin{啊檶zohb^`bgmy棹蜚陀轗翰ㄑxqklmt綜鼱qiefho~澆籓vke`adhny宦裛阿壖}vqmknv鍔奲slghkt﹎檞|oidefioy內羜長眲zvwwy}~yuqnptz朸鱦xqlmr紱譈xpjjklqy勒噊橦xrmnnpvyz{xvusv}棚蘩廜ztt|化劋翴鴃upnmotz介栨囅{snjklnruxyz{}植踣蠰嬲9媎樔劓wtrtx|冗湅灖wolikmpswz|倥碃豂鴅謥坉完劼蚐釋噥|z}~怔楴蛝zoljkntx允杽齍麌婬鴅窳翻瘧豖繕郎噥賒宦寋|ronrw~挨郲蠮戄繒憾碞鵳摍棴蔽噹戀蔑|}煤郕xtu}征挔蹠蝩紙匴虀榃扣异雺Йywxz羔秺札婰鐎欂啦齗躆~yw{麩薠蘼萺vttx皆慡知紾矘鵨貙觶醷鎳蟙xttu|麩朿爙vusv啞翲怌仃謬睖蚅輒祥攣躑|{嗆蒝wsst|儒朏蹀yvwy嗡邍儘〞捷葫坎}{菽臝玼}wtuy噤稗醢~xz}⑩醠部xsopry賭鵸縞|yz懍嬿籫飺~族籩囆腹zslffdfjq}倡鍎炾整籜瓕愨鏃鸂誥xrid_^\]ahr#抇鷽縣暹臌瑮譬生嬿巑穡~|vqhc^ZZY\al|倏淈黹懊芴砠|y|米薋蘟寲提ztnea\ZZX\_gw櫻蘠鼘~孚噱}zwvvuz勻摞戩倰苂概wphd^YYZ\ajv弭襳簀{xz挪五}yussoqsty7Ь蔡源ё狟陛xpke]dmy賈皏{trt}紜麩xtqoonruw{ㄝ骨′調摲牊|uoheegks厖蹍vqps{紛uqno睏w|ㄕ紹膧嶷觸}tpqrx喳鱠xqlkox缺{vs鈉z“晅燿鍪堌凝細蘩暺tmklox捺噥~{}}城惘紼燹鐠槧椵芨捶巨倏迾鵓{slkmox捺懍膘邪褪彌☆栴蘱懥頎儆錼瘈尌筘斶鏷縩wsoknqy敉扭楱蕙捲蜀籥馯聬裀階‵槽摋槮倰眚摿籜鐏糌桫xronqt{內撾鋋錁蜠濎譈酁弇惚城蜆拵堍器褐貤嬽籦楗斨yurqsw憊踕麌抯釩狀捱謄撥偃酸砮錓蘪毉椿躅援|yvvxz噸适鶅蝆濎耬棽楊妍晰絞捷甄г倳敊ぞ蔆陪{z{}}椎籛縌蔡頂襠尪恣╳絡盒酊谷豆戎赤爸~~~澆噿圻}姜蝨撈炕云炎|xwxzy皈齖摀}ywuv|狠佸~yuwz~╲摒}zwtrrs{lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust16.bw000066400000000000000000000123721437514534100245500ustar00rootroot00000000000000@@Yno name?緘鬧CSb.r> N  \ ( l 8 |  H X$h4xDRb.rCDDDDCDDDDDDDDDDDDDDDBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDBDDDDDDDDDDDD台黴鯰}vux|~~{xupopt{匐豽膘yrmpu亳謠葫zqmmlln駙⑨懟xqoqsuutrokkmrz夢箵癟umhhgikpy棹跁捙都wnkjhjm鬧肴蘡踽xqnoqqomlkhjms}佳贀駔|qlgeehkpx鎂瀦縺牊wplkjkn澆矘褘|tononljjihimw賣襓~slgefilr{佳濷欚褎{snllns巷譀鶌~wsqnljjijlr}肴鐉囋zpkjilou脂糶廲漆zsqqu}廷鋿糲秺提zurol姒y輻轙ztsqsx~㊣噉躈艇~|}俇欉陔遠恐|xtp泗w疢檟籧硌}zy{界翦鵒穫橫嬬趙拿毓迤|wuvz僇塏糅蚅陛掏詏樈楯瀦齶痼僥帛氅鶄誚‵溫岉瓷~{zㄡ匱螞擘釵窒鐘葛捂嵙濋蝀恂氅駏6眊箯蘆之岸{{~挾釧朱拶賚氋蝂歙轗滯曼夒輷zwttx}垢腓碄氆鼐樵攃楚癸鏺襌概~zspnorw版尬畇楸魛橄曚膠床蹖鵔膳yvyxpljjnv郃8ё侂邴曇縖薨ˇ踑巕穩}wvx~ypkjjow洹盂Ц韌懍貥嬤疣嬾鶈墨ywz~~tmlmr{〝央介豁摯器藥窖晅巃蟨}{~﹝{tssx╞邑蠍譯劓犖}~佳嬽蒨}祥~}邑ね捙旨迫~xvuy怛澺邸袘祁喿儒忝甮桫戎zuqpty動裷鷽坋匾觶繀韁郃死杻梀ztonqv○ф膧纆祤終籩斸瑲翱wuv{※橾蚐憚鴃{urqrw亳尕蛷魧鑄啻籜蟝vtoty弧は蚥策&芍|xvuw|姘藉挍颬甡砭畏斖vtrux&槨訹怹隄趕}弗匱蝓倎鳱瓴倍跖欏膛xvw{~朽ぺ豍皙嬝隋有遞葩溫砪錸珗”腎蜎瀔鍡媊′撻膧襜壁陛疚蟻褸偺樁緶魶妏咻府樟倰岒饒鱉ㄠ弚蹢噩牯枅苂隅旭遽樥馺仴假蜈繒恩仁鄞僑祟豕笞蜍癭儒今趹怷砲〝滔氰糋棎藤そ凝威昅玶髒紜貀zwvx|7忒筇憤曲蟠睭魟椆婭芴{~捨碄馺Д}{動詒~wroopu}笠旂芮祠妞聒屼嗂摴睮槲瞻yvv|潛欚熗ytsv~Ⅲ珆wplhhjox狩枅芩葩智藷饑帎俷儆橕麩~vstw菜犪漞vpllow棵tlgcchmu那迕虭齬迍恞僑雀謨睧珛|urru唬戃xnifgku傻tkgaafkt扒к眢欼瞂慔隋庖衛儘zsqqu~胯孍ridceju模ynhabeis~9屺摠覈鐖橝云xsnmu胳皭pgccflw氾竤}rkefhkt~補貾阜瑊z|{urnow喂蘱荂qiddho|參蜪{rlklnt兜絁邸峊{tprvw{yvtqs|筵蘦菢wnijmv諶賥儘xqoorx巡忯糶敶~toklnot||zz}怵摬鵵vppv晒瞅噹}wtux}弩俔蘡鯙xoihijnsx{倍倎緰縓zz岐衾棑噢}}~ㄣ忷翴wnihjlqu{迅ひ椳欶摜頖朮匟蕨噥滬勘稌xnjilou|姨毰贀轚釋軠慛賑玩寰懂均絕臍釦笮弇{qnorx〃び黓藸郎的挔懠が儒懍珂噫|xx|ˊ伒xtv}宏俔齖孍博壛臝窴~誇鴀樛壎wrsw|僅薨匏殣蟪餃懫|ww~喃鸗藞uqptz煤瓞勒摫鵨鍎錎譈麎yx~少襶醝yttw綻篻wqqt{擇瑳甜巡麵蚐繡悍偵挃肏~vty昺褔zutw墨坫黭|ssw所薃鞀〞降租wuy朹鵷閒}|噹覅儽yx|輯礹藘童|vropt}|z羽齀韎悻憩蹠鷽疆紱籩鱠誨{vpjgfehmx賭矔抴澥謼挹怛昂葞~ytnhd`^]`clx公僝躄閎ㄙ暹歔牬朗譖欒藹|wqlfb^ZYY]eq有樞瀊纊臚仃懈Ё~{z{{|倡爁蘱幬价~xrlfb^ZYZ]cl{罔碥鯔}|授噬|xtsqpruy竺睮戧倰抸握~vpjgaZ[[]enz旎籙蝝wssz念ysol痘nsy旦鬚眸敷佫憤xroha`_bjs鍚廱uolmt◇wqlj痠qv~平骨#毚觛簽yrkhilr|抹糶撠zpiehnz齒vplkklqv|丹照槶萩蔔zvwy℅錪懘tlhehmx筒{tqoprw尼勤鴈魧梠釋摩防歅囅zohknx噫}zy{弁敦◆郯臊葨趼塓蓅驕飪蟠楑灚vnijjmqz壇鼠╲暫恄ぐ玲毰雸倇昐湆黼鵿錒濎麑襗傶~sojiilqz忘衃さ斯酵砨鴈謽萯賓奴延о詎芡溢導絓爞蜨き{tpmklou}懈搿鍡緦瀀矙籔蚋僩飪馨侕螺牧側巟檁囔蓅ご|usqoqtz嬴裛鵴秷滷接溶遘祖走祥м鳭嚫儴隓Ф陝zwuuwz絆踑裁羱蜒鍙槮抩洶═幸眷釩ㄓ垓瑰騰迍芢謙輕洽zx{~~絀鐉嬣噫頂襠Ц異ㄙ痍孕壯豆中巨圻尼洮岫嫘鯄圻炯結祕尹咯}zxyz|鴆承籜葍|{y|炤撒竣|xx{z}契洛{xussrvlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust17.bw000066400000000000000000000123751437514534100245540ustar00rootroot00000000000000@@[no name?緘鬧DT d0t> N  ^ * n : ~  J Z&j6zFV"e1uDDDDDDDDDDDDDDCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDDDDDD髯燠灄|z|}|}zxussty傀狣窖wtpnoorw娃饑遘xpmkkns闊鮽wu眩usqnmnpvˊ殌珗~tokijjmr{絃詌蜣郋|tlifhl駙〩齖篽xtsqopmlkkmov紼膰瓡}tojhhikpy賞爁蘺橐}tmhehm魷喘犪駎{urommkiijlq{升蕫鷽襲vpliijls}弟爁欋蕾wpkilr卅霟蟶贗|vsnmkj姊v嗤糶樨{uqomnry嫖鯚}uqqt{鍵蘹蓛凝|wsomllmr~米燹縟|xu{依嬿橁{|壅裱欋芴粟炊yurqqry煥瀊欙餂楷||~煥鐊爦黼鼥侘暸礹簊隍妒眶祐}xvwz汗倎皸硢簞尬絁謶覘迓筀誽甡釩歷鶊間3薦鑒延瑣蝸撒釵汝邲芼派ㄙ腆塝耪楸歷褗捺賚蛩﹞忖|{朵擠敉碡鐀歙轗敕籜鸁|xutx※雅最蜸齖橇斔啃礹齴捃咯~|spnnrw炫~矽婈艖橘鍉慰峒齖鵱螫|vwzzqjgilr}型娃邳窙擒蒑誥民蕫轗禱xssv}zqiehls}帚5薰す飪庌鑑倡哭藦ysqu~}skijou壯§奮興祥揮朗缸噿~wtwxpnos{丑妊薹霽言}{|或蹖鸇嬤~{~3異{wwz五傭倷襤yvttx怛儓藑玲芢妊蹈寔罹~vsposy務跘輴創鳹畷陘1檗祳孺}uqnnpu○濱艕鸅蘑△徦黟狨都延籣蚅}vrnmpw姜р燹鍜筆介屙蠃縉z|{疙眛憔儒yvqqu}牲譁劌鵳瓴郃打呡糐}~|ㄞ諺谻螺屆7洽|xz~延壅娾襶縸臻妒笠歆攄憧朱楩覗攽奮楨爰謄講ぴ蹞玁挼偽頃盷嚧儵閞簣什還賚錭戰螳姪岕蕈絲儸贀轘冱陶裔笸媝躅爾筍◤瘓趄穰憑階娃珃宎惚狙槳澬礭倞撩褲恌蔣布秦盒停絞炎迂囂旚噸4屼疰筐﹛ㄟт臊蒎捚蠅侕憔征曬玶漯玲逜麩}ywy}棟疺滌孚齟寑眕衱尌抶裝馵萹腹~玲朒|uqrsx符珂漫‘掘谿妅塍鳺袧|棒薀蓇yusv}傍~uojjms{倣Ь葦╯◣炸歇眶嘛娹膮砦{xz晌壚搥tpmknu忠{qlfgipx盲藤董陌硃辣陘‘身毚葐炰|wvw股譐菻xnifgjq}秉|qlffinx直霰蝗賺扂芛彿巖膠zvut}忘齀雈rhdcdip|旅uniijpy彼奼栚蛺豍珜為xuvu|用譊ogcbeip~萃zqmmnrz斥栲臲攮邡zvy}}xuvv}供齁隃qidceku邂儒ztrrx~庖齣羬轀wqnosx}xwy{耽壝嵾vnhgip}晌碕噥{xy~妣銓蜍瘨}rlijlqz~福檍蝏tnlpx擋摞奮ㄜ標碞譣xnhdgjpw●ひ魛縜yuy料眧嬴膳次忕鍡vnhfilsz“雀檣珅匋鳱怮彿鰻蕩噥藪捶料棇yokikpy╳瘧挃碲縍け頂侲閟竣必撫隄儐檣芴敞料庥|tppt{弧п黓蠳熇匐蛖瘐虰極勞糋裉膘}yyz僅黎{x|傘碖韥怪踤鐨魶お~缶夒欘硈xtsuy倩躓ㄩ崲籗鬩~~倘籙碻zxz窋篚wrpqw穹抳扒俁臩擯緺濼礹瘜|srx癩瞍|vuv}盾蠓zrqrv耘嗊貌ㄙ耋Ш隄布傳嵒蛃xnmr~賡彄~xvx~闋痳苳~wuv|賴檴庢岡中朮嶼zomq}辨鍇壎劓湋譠}}耗霟轗羲~wroorx丹vsw譀甗羅憶爁纕袟床霘鉧{wrlgedgjr~殖欙萩援谷暹蠲鶋狊汐漦熏{vrlea_]_bhr紱鐎葸恣夾炯蜪棸六稑昌蒯|vqnkea][[^ckz垮裘敳踿仍懍簧|yvwx}分僝欚醍窗xspmgc_\\]bgt煙摷鼱{|副噱ytpnnpsy◆紩罺豜侒蔭~yusnjda_`chs鏡蝎vrrx乖冀xrmkjjmqv}傍昒蔥絢薩噫|wsmiggimx忱蘩轃unkkr|儒tmhefjnsx炭閉ㄛ銀斻隄{wrnou嗉劙wmfceku儒uojghlqw~〞岸6忒挳噫岡丰屋鐊鸅zpga`agr儐zsomotz幼祕粒棇埩擎蝓岉筏2扦幭vle``bgq冪{x|仇蝙鼠允杴楉侁薦逑耩楗侔匋殦鵌sjd``ejr器筆孝欼婽葦仃籥雎尪凳麵碞蘾鐍嚦蘟鼨祤|sjebcinu氐Ы戴毽櫛毲濷蘹蓛螫物魚杬硰懦秧瑭栫鏸囔慪簫{slighnsz噬挀鳿斶鼭礹纈棨噬蟻倷狪僮它炳銜摥籫欙蒰繹~wrnlnsx噸砆欗魃尨螃鏽罈答╮之捐屻槶鎀魵蚙漁{wttw{~儔濯籫纆瘔蜼耪袽興祖革雲高╪炭蜂佮鰱像洶xy|怖錪擸艙章檀ず異巨型坐丹壯貝牧岩旋籩藲戌五控泵ㄗ爬}{|}十蹗鈭~}z}站僩}zz|}玟鬲坎{xvtstlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust18.bw000066400000000000000000000123541437514534100245520ustar00rootroot00000000000000@@_no name?緘鬧CSa&j5y B  P  ` , p < LY$h4xDT dCDDDDBDDDBBADCDDDDADDDDBDDDDDDDDDDDDDDDDADDDCDDDDDDDDDDDDDDDDDDDx燴灈}yv肘ㄤ戀彌{usqqsv|娃庈捈ぜ楔}snllo駙燠鵏{z{zxtsqppu|阮衯拑wqmlkmqv}動鳪擩蜳薇wnjgil徠﹎嬿躽{yxurnmlmos{敖樘袡vpljjknt~擔鷽坌ulhehm魷旋禴暷}xvrnkjjlov灰翪矐壎ysollnqw倡匷躆xokhlq﹎霟鍌ぎ|wrnklr{頗褘~wtrqqw|餅蒢}sonrx燧攮袼撲|uqnmnqx組鏸橪}zyxz朕鐉鄶{z}導翨巕譯秣悚ytqpsw汁碠艬慬楠岑噁艬氄貏駃漲橄蓌迫“掘筋zwwz粕筄摴梤彌匐翬鐓蚋溯覆蜋訰輒濂蟨§鰍仇播撕號輕笮碇祪1塍氆緗濂蝧敖濇蛫ㄔ巧}|捍倰腺粕裷氅鸆敔襴鸅竄~yvux}宋躉~~冗絭輪攩飽旋樿隄|{|~upnnqv硎{z|碣儚歷轗慫萊鵋劑zttv~{rljjlr~韋}|汗桋緦蝃庢晅鐉叟桴wqpt{xojffjp{帛麻昅圮壁羅獅籩壏xrru{zqkhhks}妝偭だ僮丐鴃岩棻蘩徶{uux坏vnkknwㄕ迄薦韃~{y}耽嬾鯕{{~仍窖~vqrv~﹝車嘍旃蟀}wtqty倀踮壒兜侗||旨嘔倗芧}y|xspnosz掏蜅駔9凅萲井溘俶伓|x{|upmllpv○跓磉征絏纕袬惘仁瘉昒慾}~vrnllqw乘枑籙駔援﹜挨跜麠袎略庖賺厊瓷活zuropv~1酷淈縎耨韋歜霙蠀蟀弘數恄譟噪陝zwux~捉嬝俓譔縸艙飭俙鸉价收溘倧棑刉捔~窕鷗藥挓企駌蕙嘍塱齴袎筆╞足翔枌賥鳽晤芘笞倢鬚厭跘襉遜譚緶罼捘楝圾﹞走垢亂砫檍蠰擂蘊紕衲伒郃旨諧錂籧嗋擰й楥埼筍不ㄓ妣晶蝙輓息丹牴忨鼐寰ㄦ忒郈姣桋鳱棦奾軘蚅陝‵溼倷芨砭姥冓劑}zz~ㄦ妅觸╲瘧夼佮邲殙椿舅姚婛慺楷朵ひytssx麻繪妙捲飩蟬軡魬迣阬貁蒘zvux}宋yrmmot|紗蔔之坎‘玨謨儆颮氐瞃搎wpmlot鹿unkkms{捐撞ㄘ洧ㄠ蹼糅贖|}汁儋蚼ynifejp|期vnkkms{捐蔆惚扇滂萱倥俵誨|xy牟鴅洏sic`agnzⅠzqnnou鹿藕壁ж赽薛|捏赫xvx弄膬苳pfb`agoz阱儒zutu{仄蟹曶筎闀鞀|vsux早}xvx弟鋹啈pfb`ahr~絃噥}z}往襠婄薧蒪vpnnr{}yx{或曒蚻ukedflw撼憩迅褒栜嬾獀{pjhhlt|匿樖蒚~pkjls~值楶擁З╪炳嘆娾鐉奲xnhehls{斥屾鳷洢}uru~◇邲甩珌僧丐﹜ㄐ布嘟鳭駍umhgjovㄚ悄妖蜇褲殌晸朝躁噱庍芡撰悟倦殑yokjmu~奏蟯晑笝桻滷偌ふ剸弩擘飢忙碧萫棎螫忠佪}urrv傷塉贂簐念筌訰螟て蟒屏艕鏻珔zww~索縐|z}池絧嬼勻儊瀍罺蚨れ隞zspqw~六蟆穹氀蝐~xw~彷齘藰|yy﹎鏸屩xqnot{˙蓮玷粡豵懨樥齖漰xopu箄譧zww}抿鼲zrnou}希貥幫圻店酷Ы撞豕挽郬蓱ulkow唯灅~zz寡痴浀wttz喀耩埡惟不不據眴xompy啕藞噫郣壖~峙霟礭Дzwspqu~玷usv寧籓郇憾薣囔剸等晃鞡駜{xtpliefio{五}帥蘩鍑岍熒惚整賾禜筐6匎駜{uqnifc``cfq}ㄗ肱嬾糨隆赤措撚蝃炵敖蕫欏ぉxsnkifb`dku炳租蹣鏸鮶○憑桷ztqrv{萍邶魆き{urnljfb``bgo~倥桋壛齥{{傻壇unkjknt}絆歑翴媝岋隋{wtrolgecdho|朗霝靰xroov乖噹wnheehkpz倣倳劦葆瑰輔}|xvpljjmu訾頞zniffmu儕vmgddhmr|弩蔆郊ㄔ捆擠策zxvx午蹧鯆qhdabip~儐vojhhkqx炸祕孚藍蔔見╪妨Ⅳ歃鯙ukca_`emz冪{somprz*殿扒蠅繡陵偵襟疶摹垂倏罣曫}phb`__dky凝{y}捐だ賒#褒佸像秩轄蜤罍誾欻儋籩鶋瓊yngb``aglx噩惕第嵕瘖佷祠它笑攫旼葦妞補僪蠲攮獌wohdaaekq{此螃器溢譚緟蠳鼖梀撥蛻弅梉繭坐幼睡噈鼖邾wokhghkpw噸嵒鴈嚬纋葯佮俶桽陏筆╮平暱僔癰椔提ztpllnqw~掀禘鶅楗倰怚臻式‘飛ぱ僶麑齌袲蔓zvtuw{齒諛籫灗頍撦糋棝鬚凳遞撩疏﹞妙晾攣恄佸噤恕~巫蕓襏懇章褪躉摒巨拳惚圾╞妝囿均啊鯬略‘央◢停高ㄖ囿}|鴉﹌譖隞仆凳答{zz~迅絨神岫|xusvlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust19.bw000066400000000000000000000123611437514534100245510ustar00rootroot00000000000000@@[no name?緘鬧DT d+o4x D  S  c / s ?  O^*n:~JY%iDDDDDDDDDDBADBABDDDDDDDCDDDDDDDDDDDDDDDDCDDDDDDDDDDDDDDDDCDDDDDD魅嫣奱|xuuvw~3藉蔭yuvvwz}局倱摶嗄佽wolln駙寡藘}yxusqpqu{朮拏|vpqprtw}畎劌爦鐓砦|rjgilw鏍縡zvtqn妯t|務葐珗}topnmpx賦籛躈zphegl陣校蘪蓏極xuplklmpw岌碙寱膠xstqpt{敕皕}tkhjo櫻鍷訰漪ytnkklpu窩嬽轗儔}ywwx|怡爃轖禮ypnqx賴謶秶噥惟}wqmmot{勤霠轘轡~|}整籦髣蚘極}|~寰氁謣譬停雪略}tpqty客蜸鐙髲簣參燿齆桫虞融羶迭橄鸀ヶ╰韭擱慫zvw{煙嗈棔恉僧末嵅獾薨亢數昋遘濂醠○忭棌~征噥絞雀葡尿渀醓珍貹膦歷瞉博貘廜妞╪~}溪喍~xx{漿籩氅蒪喘斖縈{wvy}玷侐wssv}牒襳輩欒誨菽巑凝式||vsppsx仍蓿}uqqt|需齍樵鵘憫嗦蠳攦げ{usv~{rmkknu韭zvw|汐湆贂撿覂屍譓攡Дwqpszxojggjr}車哈8з倗鬼菰哥睄}wrpszypjffjq|◣咻朱舊趕泵}}啼籛糨{vtv~丐umjjmu~尼圾旬酸蟈{wvx|紱譓礱贗}|}陋}vrrtz﹝尹革嘆豖憎~{zurooty紹槴爦憼躑的簽}{}丹炤嬝晟|wvxzwrnlmns{笨祔蘮攢お今庄珚═姜薰婞簾{wvw~yuplkjlpw倌剚襴頖陽╳濱豵甝悵妥螢恟簣zz|~xrmlkmrz迄儸燹謳ざ悍催裞籧挩砠亢瑭羹}wqnnpw╲蜊淟欉埥絳凄蘮鵘襤井飭で昈戮勳{ussv~笆嬝凈蘩爢狪鰍楒嬲落╡偶數挍桻噱挼{y{粉臏融眈比楱圪婩礹氍庥◥挾匱騷詊槻颬暹帢~紊齪蕙絢び檟齶萹づ栜鏷蠈堇辛馮講遞薦軠鴄齁曉优彼а褻見╲裊摠歖窔つ挏瀎縓憧仆撬せ換貝偷忐緮憾|}捍織弘檣侔藪г朓澣暌倍虰織狩挌噪{ywy素褻◤掠停魚屼黽嬮笮埩誑~朵ひ麩ytrtx|捆楓﹝﹛尹採湇襚峎彼玴穫yutv|斥zsnmqv{捕捶元剕鐓犰~旁疺vnkjmr~偯wqkkot{站釵╞孩儋瑔~|敗袸xnhechny推yrmlou祥楝失ㄖ振竣棣瘐{y啻慲rhc``flw腋麾xtssz弧謠輕飭欐狊|xz~內Чzvu{奩禡pfb_`emx8勳zy{粉づ圴訒鴅鞀|ursx邑xuu{擔邆pgb`afo|秉奮妊酷彸塎鐉颲wpnnry爬xuw}鎂曘ukdbcir棲懈簪ㄟ飭豳涳嬿撌sljknu|ㄓ|{~分椷蒱pihjozˊ涳擅堁葫尼底敢捧敵趵蘠鱠{ohfhmt}‘忠栵駋}uqrz笞玾學婭狟撩絡飢╰扛腋塙縗{nigjow辰雅妤馭阺凗捐繙勳р魠硨躅六瓮}qmmov挫畇詍倇講輒咧倍笭轡ㄢ蕭畦勦檁鏻桵○鷗xtuz☆盷壚蠮欗檽蘇Ⅴ軝蚙撫蟾霽廷蕻鷿xvux仄蟆岐絜暽需瀇膹箹襯~麟嚓yspnqy捐閎※ш譖蝞|vv{鱖毊zx}⑴鬊xqnlov紗興均ㄘ聒貤樘蜛蛺膇woos|耜籫衚{y~志艡{rompx滑芢撈陬兢遞楣◢諛譀艂tljmu肯蘩餗~粽載懮xutv~刈詌褁懂岷||〡摛wmlow忘蘩鸉う劑祌攮楰~窪闃歶漕|wurmlrw傍~sru~翎籫矔袎揭憲斠灗桷砠屁椼糑}xsomiedhlr身}{或譔蠃斨熒陪據摶挹戊べ籜鸉藺~wrmihecabfjsㄒ肢霝擸鼓尼奏瑪撼堇|yx{旦婍譔纆矞uoljhfdbabflx限狎貓蘩糗疙懍}uomlow凶塥襶醵媌憤xrolkjgebbeir笨陃燿醚yw}缺穠|slg痙q}Ⅳ淔鍡媌羹隍}wtqpomkggilr菅薣鯓vqmlqz噤unfbbchny椅祰輔祚乾~|yxxupnorw輻糶龒vlgdcip勳slfbbdjq}挪羶恐妓惆~|}肺嬾鈺ymfa^_djx噹vojgghnw妊噩2粥芍市高怏暟蝩qga^[\agu噪wqnpry宋擬略ㄢ粥岷香匼硰艙捆嫇懖xmd_\[[`gs器}y|傳衄Й幸撚萼扔夔瀊罍箵摋壛藢ukd_\\^cht噸揪1黽檷桾撞洫瘧岓懂亢槽蕫鼖skea__bgny嘀蕪渟蘮纍葒擦賒曲輿錤鐠衕umiedehmu噪й碚旚蘡蟿楙珆笪梋臻迆憊勱櫆瓞{snkjlou}劓ぷ譀蘟皭鐔蜞旆倛旻蟈式平準粞瀁臄痻ご{vsswz黎菩霘蠊楬葐葠笴ぜ噶擱擊痕’炸薹冼珅羹榆~}Ⅲ裌嬦繡嗾擬噪祖失◢挈散高ㄖ帕偽掠陸迫峒蘠欀椰中扛偃悸什普隻}~〣錹餖弗溢捶飛擰煽項閉{wtulablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust20.bw000066400000000000000000000123661437514534100245460ustar00rootroot00000000000000@@Xno name?緘鬧DT d,p:~  J  Z & j 6 z  F V d0s? O_*nDDDDDDDDDDBBDDBDDDDDDDDDDDDDDDDDDDDDDDDDDBDDDDCDDDDDDDDDDDCDDDDD魅煞謺袪}yvuwz仇蝓萱~zywz|祀絘豂癭颮}rnnp駙誅謤砦{usqprw~死в憮}{vtstv{啟薋齆怐vmijmw醬鍡桴zuqnpw勒赹鑑{vtv|勾澪欋ヮulhko陣朕擫愻噹~wqnllnr{怯塤萭椰~ywvvy爺鐓桼wokns曩懠桱輕~unllmqx凶碀儴祩}z{|終蘞酁蚚憮|vsuy賴檭蚚蝦螂恣wqnnqu}Ⅳ嵅蘟寲簣羌攦庢降晰寰氁旛螫窈嬝膩}tpsv{棲殢鶅痸蔓末稑藑楠偶砟橄熗往晊yvz}岔粔葨旼艘炎匐踛藣ㄩ蕪澱蟴募誺獺笨翻葡悌悚捨檡藟}urvy空塥歷齴癟菁壝隞弗釦念麀搎uolos~㊣嘵歷踽猿熏奴}xwz棣痷qljlp|鍬歷蹁□裺鸁翰}~zurqt}防抻rmknr}汎蕅橄嶷憐汕噌攩簡|uuw~}snkknt偷閒{uoq{耘澽戰抳紱籗藯儐xqpt{{qkgfjp{迅除z尬砣棩儘賭襶躽恐|wqpt|yojgfinx╱咱乘飄噙~|}澄籩鯥楫~{utw~tmjilqz扣見ㄚ翔羹陝{yvutx~萋瀊籧媊甜}什{spopu|市帕眸蛻Э漕{y魯{wtspnmpu{捺塉魠堌麂紗蔚|wwx{井窈褲刵狪{usr魅xvsqmkjlpu紋劼葐蝫蠕盲朊躓◢笑に珇抯}xusq魄ywtqljijmrz炮蠱蕖纇郇郎ㄚ催碄餇窖布嘉俴捗貍|wwvyrmkjkmrz妊贊霘鵰觕噢纓翭灒离略早嘍恦珅蔔~vqmlmou}╲亂淠纊笵甮翪鵽抴互衙迗蚝釋產儒|wqoqu|站敷迾玂眣渟礹擼儐仆曖圴眙笰ざ秧學|vvz}側謠蟹湇穱繀欷踤鍉羲延賽佫晟詅睕婥曄觓zy}掄Ь蓿溝咇膧礵懃敆拫譀灚阯孜檄虯つ奷嵑賝嚪橫荌|{宏鷗趙失必暫婃覕Ц豳郫轘壑彼庉М陴硃趨貺蹜蛨||玻Ф砭ㄝ絕砥翕迻襏紕侐蒂╳諱蜉壅|xwy玷螺◣腌錪簐採ざ邪屻凝{vstv{香策2毞嚆元噱zww{扑~uqnqu|振室澬撘}}索膩vnjmqt~挨|tnmpv接Ⅷ噁囋{|◇Лxnhddimv知}vpoqy朴楹妖}~墅鍻ぁ{x{怔狊rhc``fks紐儘|vuw}偕擠筑拿嘉З{wx}兮婕|wuy畎媄}meb``eku溪噸弩賺だ刱碏蔇|tqrw}倣膚yutx敔蓏~nfc`aelx分憑蒂今薺恮婤儋蠮皛xpnnrx○童xuvz煆諑sidbcho}借擇捔隻ㄗ停學昍栚樖蝏tmkkpv韋{x{種殫}ohginw傻擇靳狪螃擱鐃噪敷貤嬽幙~rmklpv振元拺橪~uqqy矽б彊塍諃葨堄譬芋ㄗ笨紩鍘}rmjmszㄡ噯惘迂銖詄臟弧撓凝靨鼭欙禠椰粗媜tqosy5н嗒陎摹祗牧帑諮秺恣2噬釵朕齘醢倣蠔zwx~社軑譈蘾歞痹童◆衿珌蝨襟伓午瘀ラwttv}偷統氁鷿菸樏膹諃怌囑孇xronov扑筒死祏鐎蝪{tsy嫦籜齆囮|y|灞鬌xpmkms{6蝶惕迆彊笲棑恟嵉襴憍wnnqz由蘩醝{y}壬瘀{qnlmt~屁帎М溶蝴歇畏毿漼uljmt蹞懫}喘毊禮xttuy絀蜾梪僖}yz啦謥vmlou朻鍼冪儓纍袌悵~宥鼏醑簪yurokkow氾虒|squ|倭襶攮瑢僧濱魠牁時氁鐓郱|vqmjfeeinw斑|y~升爃轚珅戴筑懊嗝漆ㄚ亂淶鐀櫆vplhfdbadgnx芍牝錹鵗賓帚韭蜓撻芘{trsy屁婰嚬鐠瑮罹~snkifdcdbdiq岳扣碣燿輶弧+wokjhox巫摙蘻縖狨產}upmlihefjpz偏о檥嚃~xw|剪讀zogd痙r汁蜅鍏蚥蔥洽~ytrqoqpnklotz照澺齵tolkqzⅨ鴃vlda番m{ˋ殎梀滌囿式~|zzy|{yvuwz櫺糶醛rjecciq噢unhcbdjp}釆冞戮央曼鐉欀ujb]]^bgv壁xqkggiow傭螳契祠*翦鸂ymd]YYZ_ds噯xrnos{滔珅憔ㄑ仆塓覕ぜ麵裷餖ri`ZYXY^fr噯悵z|札嵕隗應咱物炫祐死淠矘鐕鍆隮矘繂}pg`[YZ\ahs噪集氖趶皭錈蚕器蝌擦僮此敁籗醷阞}phc_^^aflv景褸藐砩蹜瓕魵豝晑祲ごㄞ諄摬縻穡~slfccdgkr}紡厒濄蘮茹羻糌蜋糈秶楓妙溼郴襴纇袤yqlihkns{斥矧籩堝鐨襝毉瘕跂楬埰懦炒市銜魛臇懠棝簡ytqru{鴃務踕鐓楗崵椳疺釋墾藉た僚芋妍鉸冾倢Ы繳~煞蠳囔秺熊瑭噯揹岩╯玟號殿洛左措遠╯羌嬾鯕僧中戌ㄑ早雪筍仆撬雇帚炯歲汕氁鵽ぇ仁劃竣姣帊恌迍玅楷{xwlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust21.bw000066400000000000000000000123701437514534100245420ustar00rootroot00000000000000@@Yno name?緘鬧DT d.r> N  ^ ( l 8 |  H X#g3wCSc.rDDDDDDDDDBDDDDDDDDDDDDDDBDDDDDDDDDDDDDDDCDDDDDDDDDDDDDDDDDCDDDBD魄勞蜾梒痕zxzy迄遛陽}~創澥籧蛑wrrt髮絀槻棽僮~wusuv|往謐鼓}zyzy{靼籛齆帣{rmmoz障鳱硰懦yuq季|冕玿嶸}zxy{}倨蹞齶衕xokmp疫蛖蜡堍繞{urnoqw挨殎硭握}{}汛匴鍒狫階zsoqv濛瘔祰棑刓ypmmqr{祀崽糈抶ˋ禊欏Ё帘式zxx}麩據糈蚕奷梑かxroptw怔絯鎀獌憚Ⅰ跕攥寰歑縏繒疑婗堇ztqux~閤麃懤秸筐●秮蒆}|﹛橄鸀惕炸杽慲zw{~畏蜄蒎岈僥坎秉禂撘unqsy朽鄞濂灉童′趡廒腎珂懦惇炙阪祹藡umijlr|民塛欀汎檛鯚妥雲棣薃葽|piffgmw朻氅齤庇嬽鮿ㄕ}}污碚峈yngeehmw郛氅藲甜怫蹖篜zwvx傘埡}rlhhkqz相橈鶌嶺宥錹鸁嬪~{|xtrrtz那譫xqmmqz曄痻貌詬茴珧{xxz~uqnnqw捕畦{xy紼麃儘匹蕻葙{xw|}smkjmt~五酊效晊劦}yx|玄燹熂~{yvomlos|五神失◥翔擎~zwvsqtz廷殢謰譬垮zsrprw}店絡蝌翻陛}髯wtqomkmrw怏衲痀噩炊朽噪{xwxy~迅鄙と倷芤插}xvu駙tqnkiijmrx迆鄘蟻釋噤派’麥怤馳~弗親婗椵抯xtsq髮vrmjghikou◥晾匼葮嗩Ц虜酸訒甂薊仃諦圔蜛佶~zwvt魄yvpljijkou|仁樁毿鐨魱梑豗檁謯伀§蹋詏髧狤|{zwrmkklox迂殮檡鵻摳儓纇迮〃謬撦槷蚘漫yrmmns{妤裟渿欉儰蘮磎傅崺樄魡窔劓言壁wrsty奏鄙郴蘩齶摛僔篰●р緡谾樍楉倰囟貊邧ywuv|朽撫噯鰍湉嚧謻葌а淔橝△忳鳱椽嗙賨樹珖}ywy鳥擎祖幸裟冼岏僕拿邀籜銋扑彸梋鐃藐瓮摠齗暸ル{wwz扑撕恣車洧仍砏鸇此Я噙炙ㄕ掉咇艕憾yuv{孚滌界檞灅||次噩※蹙噸|xust{契惜勾錔鯗|}風竣|yz●ひ儒xspru}拿暹嚍}{§隆uolot{死鴃xtrrx2筒~}詮廘zy姜腹wnieekq~腑墨zutv~延榆′閉}|耙儵洈ywx溺qic`agny☆冪y{朵薩噙炫絳冞膝|yx}母稄zwux阪芞pfa_agmyⅤ噶允奻豖っ甮樇禚yutx}剪おwuty耆晸pfa_ago|岑堎姜奿桹崿澞鯄~trrtyㄥ鳩wutx菱窲ujedejp料睟抯陶甄曶眐晟碏邵祂|roorw音xux|夤歕~okjkpx腎撻皸詎婐尌玅講賻湇襴蟔yqnnrx風{Ⅱ趷橪}tpqy娃謠壅淼闅鶂篋韃洹身嘟楑鶌xpmnt|§噢部妊檠摴臟巡董冪蹺蘞齶珨舒嗒ytsu|〃ひ楬狫鬲限垠挾ぱ秺&遜疢嬿醝姪~}釆盻譈獿蜞抪釆衿怹劂豳ぐ⑦鯁wuttz姿鳩料塛鸅煉颬摵鬾坌黴篳zsomns~措筍╲懍魛濼籩曈xw}竭褖}z⑶橦xqnllpx倌聶號褐珋桸昃厒薋擳yqpt|來醝~|志曫{rolmqy腌婭玹囡蕈迨疤薣膃wmkox朾蠁麩韶蠲礯妘yutuw怏塯槲抰悼y{韶轘xomow卞匷樿勳呦鍏庛~◇絇翲蚇ztoklov翅觓~urv~羞籙籧硥隆壁衴牁彿栯謤瓽wqlhdgjns}朱|w侍譖鶈苂熒換憾蚡{z|◣鳥忮澣魶侅~xqlheccdgkr~侍薣鍘葵丰底絡戰ヴwommt|姦桋賧罅訧萱|snkigedefjnw╰ㄣ逄嚁契戰ulggflu翅摿儵葟繪{tolkkiijkmpv弦暫裧簉~xy旅憾zndaabgo}晅鴄樼こ祟}wqpqpsrprqsw紙碖醚tolmr{憶wkb_^`em{疤緧秺釵ywvyz~}||y{|Ⅴ僳醙sjecdiq憶wlfaabhp棋皙簪~匾蹗鯬ujc]^_cjy珥zojg痠w分婟伄迆熔圾1翦奱xmd^ZZ\`fu憶yrnpry樊萳葦念逑蜨斻麵裷餔qh`ZYYZ_gt憑憐{}汁貀魵苂僚限爭§呴穱羻澭薀鯚|mf_YYZ]biu牝羅汝紾蠳爞隗芢藕蝶惜ㄡ鑤鏺懫|mfa^\]`fn{尾饑そ謄挀壚蘼魤椽觚侗惜#嘟椻鐉橪rjcabbflu黍疪儇譈消鏾膮錼裉彌式早曾侲嬽鐓荌zpkhgjnu往极穱蘘闉鎀諙膇睕冱惆ㄗ笛紺瀀襘鳼桴{ursw}姪歅斸蜮欶詗棦旻Ю圴侞繡惆ㄚ準瓬笝眑珌閒俺錹觰髒嗾擦輒酊戎垢滓遘筋〞秩斑溝в譯◥神Ⅴ碖纇捋痍狎咻◢偶殿╱諒捈す瑤奮繙煜縃硥釦弛巡犖竣ㄤ呿瞅瘊摲硪{ywlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust22.bw000066400000000000000000000123651437514534100245470ustar00rootroot00000000000000@@Yno name?緘鬧A Qa+o;  K  Y % i 5 y  C Sc/s? O_*mADDDDDDDDDDBDDDDDDDDDDBDDDDDDDDDDDBDDDDDDDDDDDDDDDDDDDDDDDCDDCDD緹宏倜倓噤陌zyzz╱蜈陲◎彘爦鞁zsz祁笚梤鰻熊zvx~有壁葉切潾鐋堋~upqs粒軗靳笤慾{vu官紗囡趙啻齘鼩棽豪{uqru怏婓瑑髣瓵xtssu{捐曶宎恥翅蹠鷽抳咫xtwzˉ砯椕跁樘瑍~urruy社砮愻耨晉錪攩}z}儒謁摝恌枅樖敹~vssw}祁毳豍蚆飢倆踖鉦utw|憩蜦醓羹購碡糗~wtv{Ⅰ紬鍧硭僧坎矽媵臗}qihkpw橡樿集耋嵂襐yvy俸矠雎繳馬忙介敃矙鱠qgaacgo{Ⅰ濂鸅誚尹詩齀蝩|z|5攪苃澈坐╮匏儑簋zlc^]]aht﹌氅鸇馳今翊灊有葭陞正嫇矐via]\[^dq絟歷鱠誑3栺篜成敖儃珥wjb^][`iu芸歷齤楊╰晏蹗戄~zz|ˉ邯い{neba`emx精歷礱螳畎霝蟓|xuuv~彿髒uligglw唗曄埏詹鱢}~yurqtz捂筒xtssz鍊皭恣卅蹞蒹~|zytqqtw垣洛☆豗硩|xvw{癸霘瞈~|}╯{ronqv}◥偺炒‵馭嶺魅vuronpsw羔樘梫ㄚ祐~spoqw{延匱撕滓螞蕊}駒pnlihjmpx紐侐釦仃獐閎yvuvx{弧檜婭婞芢隊zwu妁nkheefims}玩陶洹孕戌妝圻玨賻玹}~往屾蜪髧芴{usqrnjfe搬kpx╪租晶騫奼虯霰忒飹蒰馳彼侲錝罅抪|zwus髯upkgfegjnt~井黑婑麔瀔鵨懞斁嚧鄶蔽斥枟贄鼩捋~z{yxrljiiknu~五槽澥斸覷鐒欙畹7栫鐎鵯袼隊ytnkkmqx”掄幁貘矙轖飾萃澮爦橕仴郊噩yrnmpu}◥窈譆薠瓕縍蜁磏剩瀄蘻鵻篊蚘髒牒縑wrpty偕僱瘧貣闃檶埱蕉觴錹蝏}{畎碪懞槼瘔瞃∵怢xtsv|3僚帘炸褡虯楨朱翊撟{z}宣欷捑霰剆塓濄樽ゞwttx玥釵收息鎬銩~ywz忠羸隻﹜延證麀擁{vtuz面~嗡萛|wux玥砥完杺壁~vsrtz◤炕xw}晝劙yvw|狙{y|彼凊凝zurru妙}wu|胭艡~xux洶vnmrv捍墨zuttz0釣|vtx拌襶蝬yvuy井wngehmv尿墨|wwy笑撞╲歇}wux〩瀎狺|vuv{弗rhb`ciq~宋劓倌噹秣麥恮ぅ~zy{Ⅷ嗈xsst{肅qha_agp|兮壅○譁衶恀曶楋襡蛃}wuw|勒uppt|汍蚆qha_ahp}岐擋伄見五睽筄睖睔踥鱠xsrtx仄鳩uppt}商蓔ukedekr捌擂嗄ぞ騷氪瘔尰楘齘飫vpprw音wssx煆魱~qkjkqz掄憾蛷蜠膹懥窐聶襞楋籗孍wssu{迅z}墊貏峈~vrs{玫陰噥凎譊轚答丰玫齣鼏糗~wuvy亳螺仆謬瘕臟迅惕黎壽鏸灉馱姚欷艦{y{姪婛硩冪夾帚降裙欶蠔仃葩弄痲肏}~ㄥ醴ㄢ蹲濷獿蜨伢盲眢芞給褲議麟幭|wtrsw3跼偭淀匷廲粗竤嗖葾伬續朣wrnlmox朱像鬥炫鉻筊崳蹢蝟yy~萍澞礵磉~{﹋籛攩zrnllmt}8薩侞迋珫刐眼樞凞擳yqpu~勾蕫簆盃糑~tom負~岑衾雵筇繞斛譓銣vmko{曉鎃公氁黟き}wt趴救僶諔伂yuv{濩轘wnmpz ̄薤鸅妘勳忏瑱插}~尿貰懧侀xsmjjnx紮怓}trw耿齘灖捁釦壇恦膜姥眃蝃珝xqlifgjov店zw佯薣藢葛酋ㄒ憩仴zussx﹞妖嗽晟豽宒zsmigddgkpz依檟嬬策”帑擁藻xoifhow直е婥窐Х筒{vpkghgfijnt|啟燹壖托擅~qhc`chq晏筈蝫拊痕yuplkllkmnpsy”移媺簃xw|並懈wkc^\_dlz參儃楢鳩xvtqqrttstvwz姿剞矙醚wpkkqz〤擅tia\\^dl{勝樉埮~yvuuw{~朮栴簁tkfcbhp撾vld__bgo閩椳悻yvvy粕澮蟗tjc^^_cjy曄|qieegmw者葐媊陛yy|仇撕痔左腆裲囅wkd^ZZ\`fu整|snos{Ⅹ魛諗З坎||煙蜄痸て媎鏸橨pg_ZYYZ_gu擔帤|~怡摷瓕駃譟疵阱跘礵膻錝蘮鸇{ld_YYZ\ahu目捘閎札跓鐓嗔陎滲彿剡葧}nfa]\]_dlz庉迋臍賽絖籫涇瓘賥慡譬曳諺蜧鸆sjdaabekt祭厔摞贂瓕襘篋ご炎收債郪礱瓊{qjggjmu&謁濷欘臊蝔髧蚡跼芍◤睿麀黼蘙鵰茧~vstx}奶扒枙壛儴棪嵫豝旻旽佫恀贍惆有證笱欷楀慲◢哈尿渼蘣痻藩嶽滷洩帛拿遝噥榆迆斑絳譚睖侇﹛玟僑絃蜄慬蔆韌戚芋妣晴葩妍謬鳱棞佮俶陎捌娸陏像敞芋底虜陛ㄤ盻瀔貗鵨縤い}ywlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust23.bw000066400000000000000000000123601437514534100245430ustar00rootroot00000000000000@@Vno name?緘鬧D P`'k7{  G  V d 0 t @  P`,p<L\%iDBBDDDDDDDABDDDDDDDDDCDDDDBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCDBDDC您紋圪а繙}弘虜陘室澪斸鉓ztr魅◎к梤晟狪~yx|必撩畢組齘齌痶げ~vr鴉社拫樄鳽鈲yvvz姘擊援怪蕫毊妡爬{utⅡ倜碕瀎擩珣{vttx~延蟻戲洽江裲攩間yy{傖欿碭齥~vrrvz朵檜珌摯阱稑幘|y{~墨銓嵁崷劌鼘}vstx~扒倷挳漁珊跜魋znkijmu}寰魛誻恟絅籫黮}wuw|排笲埱噫岱丑╰ㄑ互誰蹞琱md`__bkv橄矙鄶釋屾齘髕zwy完庍芶熙爬壯它它妨棟僛聸vf]ZXY[do}氅簊葩衙翦鸅|z{捐齬撞岩它奴戎巨純絪蓂rc\XVWZ^fv卄氅噾祖倣裾醟~#飯隍﹛粒摥擸qb[XWXZ\dt冥餅き赤漿鸇◢央ㄦ俉慳thaXVXZ^fv燠氅鱠蔽╞煞襶巀完奻麩znf^\]acl~絒歷邍嶼教齖壧}|}朴蕨tlheeho|髦擄价Ⅶ澪蒹~}}ywx}曲痕wqoos}盹齒股鏸皛|zy|ㄒxvtu{收恭~封賧}xvuuz羚矙磍~xyx{}五砭xursz旬惇※譚窔髯soljlns{豬諕~~{}妓虞xvuuvy仆瑣蕉斐嗾藍應駛ljgcehmt}本Ю弦蟹驍~{xxwy4蟠尌旄恌應{w駐kgdbbejpw必戚迂溘忒楉邾~}{{ㄣ异澼糈梪閎zur駛khdbcchms}ㄓ夾孕井頁諫跁碇臩氃媕~ㄧ眅譐謮祣~zvrtpmidfkpz尼捕譎蛺鋹蠰穱欙鉰ㄨ淖孋儘~{x{xrmhgfgkqx收銘僗甗◎徥磔|uokjjlry”掙裛欗齖巀}}華藦籀儐}vpllnt{車傲裞耰槮珃翬欀||勛蘞玁訧噪溢=|tonrw妍晰諦碡覈縎蟈咩效裲撌}yy|羔霝蠰鐐糌稊笻橙邟vqptx帕洮炬褒玹羲屍鐉蝜{wvx|孩塕諕崷嗍蜲麃∮犮vssv}ㄙ爬井神~琿漟{wtvz局凝炳敵倱鼐擄|vstx扛xv{冢鱦{wrtz仃釭孝ぴ艖嬴xtst{ㄙ|vtty冤齂yutx|井~|~腌碞噫}vttx狗{vuv~相蟫{vtv{奴yqprx屁崱儕}wuw~有捶失zutz拄蠳蒤wttv~托zpihjo{最儐zz~此翻畢仁輓|wv}弟闇xussx戊tkecekv紜噫此刵侚僩飪譚蒎|}諼蛝vsqrz笨qhcadjs俸壇略倣豗葇衶趿摿蘧輶~||級え{soorz刈蚅qhdcfks玷憊撞面瘉毳鬿睭緮襴藨|xy~○隊{ropt}疢蒰vlihjov姿憊衶俵婬摓歖詍楁蘩藙yvvz辛ursy棚魵~snmov|垓噶癹緱鏵謥訧聶蟬塎齖篳}vtuzㄝzz撼貏洬yvw╪圻冀鄹譖獾霽炊市腋淩鏷廙}wvx}邑熔酉氪棯‘參嬾譧窖里粘袘}今欷徆重面絕絢の狤恕云咫竹嬾懭~}麻宒炤极齁獿魡窏隋姨旽Ш犖噢揖甘蘩熂yussv|倍懂予掃枍籜懭7眕婧眛~~老籫囅|tommos}腔藩葡晾蝨賽淈魌~棲楘毇婸旋籩樨ytomlmqy森婟衃芶撐洧奐枃襶虩wvz汍碞襢婼麩踹灕庢}wrnmmpy煬緱糅挩肢霘銊{squ|豫豵諏冀噙俛謰竄zvttv}樑檁鄶齒zvw}擂駌{trv}汁絯鍷拊墾粖蚢~}怯蛶檺讀{tnjkpx冕黎vv{菱濈窲彌憶棈|wx}弗殔痾zsmifhkpy◢~|耗嚧橐漁丐‘擋牁xplls{ㄕ扣韭銀豖ぐvpjgdegls{耿夒嬲妍撻耀vlgdflt孜擢器犒熄散{smiihhimpv~§酘藬征撻}pfa_`en}旁笫侚趙咻ysomnnmorswz~姨崞鯗{x|並撼vjb]\]bjy耆摽瓵砥|wusrsuuxz{|}玳禂鯙zrnnrz〥禾uia\\]bjz紳槲侀{wvuvx|珊裎譧wlheeiq曇vkb^^afn豎篎ぎzvtvz屁僪趮wke``adl{橄|phddflv用錍晸酗xutw}*毀郃不姨酚鸅{me_\\]bix機狺{snnqx賬皭蓗憮yuvy俸軘蚘謊忐檞鮽rha\ZZ\ajx橈廙轎籩鍪釓釦}xz~最儋鍣鳲麃襴橉nf`[ZZ^ck{橙嗛鼠ㄤ祑爟痾噙3蘿黓籗銇qhb^\]`fp擋笱狣擬н艗醲椋髡奎蹈蛶蝏vleaacgnx阪奮刳婤蝂籛浦瓘痹賒╪炮ぷ霙鯞tlhhkpz捱黎牲ば儋鐇矙灢蘟鏵嚭瀅鍏媏褶恩ㄞ譆薏穰鸃耦xuvy挈扔疪賧懨靸菢棔衵娸俵匟僚岸#懈嗂碭瓙繉楷奎楊怯婒駇芶舊嶽螂敢做蜈壁噥萼邑壁襞塉貘朠答妣溝謗9й筇襄順盔咱走偉劂釦ㄔ迂濠嬽籦蝃椴瘖侀}紡でЦ絕疵ㄛ晴隍耆檞鶆うzwlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust24.bw000066400000000000000000000123531437514534100245460ustar00rootroot00000000000000@@Qno name?緘鬧DRa)k7{  G  T  ] ) m 9 } IY%i5yEScDBDDDCDDDDBBBDDDDDDDCDBDCAADDDDDDDDDDDDDDDDDDDDDDDDDDDBDDDDDDDDD魄弗敷冞衲芴◣接筏汝裐欗檴嗐童~xw弓姜鰓嵕槫椑旨斯悼乖踑繌侚熒砲{x仇檣塕禴籔瓊}||~迂紫痔◎彘曫縉}y|§諦貹襴蝩zyy~旨飧歲岸○哢葀{xy|ㄢ襖逤嬾銝|xwy妤蜀螂痔邪砒篝{okihkq{ㄗ銓嵫塨蹞黹xuvz打壅臘葡岫ㄐ庚檐蕍劙|nd`^^`fnx導塯諘窙氂眱~xuv|紋っ罈疵壯戌帕停翔栯鼒re]ZXXZ^gq~橄籗麌敆郲韥~xvx朵齪羸釭忖戍帑眸嗾с鞚菪~k`XUSSUZaj{氅曫Ъ咈蘩堛xwz的藝輒岩ㄑ巨面陷飯齡澥櫸|j_XURQSX^hx戃繙轂嬿蓂{z{迆僎祐’囿版帕傍郲纍}j_XURQSX^hx氅藣撐睡檇嚝~{}早泵﹞央仃謫蝃ocZVTTVX_j{氅駏摒掄朢韥z{~*檄芺uh_YWVX\dq綴濂磔砭斥媰嵹yxxz姜蕃rib_^`eo禾曉炵京嬿篣vsqqw}丰~}弘揚tmihkr祄凝翎蟛uqnnrw~收恭z{|井祖}{z~續ytruw}る鯇unkkntz玫葩~{yx|什雯孩僗嬯尖snjjmot~個錣wpmmpt}姘龔臻zx|※敷贏陳措籤谻慰駛khecfinw剿埥wssuz娃枘覘屨~yxx{}採軠嗒倰虭饕x餘fdbbcfls|▲蕙}~符逜鍎蒑憧~z{|}6俔濼鼪袲膩xrlfcb粱hnw亢泵介у澞矙蘻鄵馳~||}兮郫酃插ytoojgeccdgls~╡奶妒窄纔趛藞誥~{}末歃暲}xrvqnjfeegjq{‘奐儸澞鵊~{|Ⅱ媱壖|}vpjihhlr{”索嫋欙賾磍~zz~著囅憤yrmkkms{〝棘禊玁梪薹裚齎{wwz啪橏懂囿笞vpllou}ㄙ肅迾鐖灖芫ㄩ僬棜zwux}疤蠆笥妅游zsoorx╪妨掉彶祴闌搊zvsuz乳蜁諙撦霠踫|uqpt}奶布晰{xx唬嵿xusty冗冞躅衛杶瞀蹖曆{ussw丹﹝xrorx抄琲xusuzㄡ雄狩拸燹憊xutv}ㄗ}upoqv我齫}xusu{互Ⅰ拺鐉噥xuwz垢}uposy佾嚙yusux奶{wwz凶絁劓yx{姜楓坐xtsw忸礹犎~ussv{布|rmnpy動蝍冪挪Ь楞”晾鼎~zy{缶瀁vrpqwㄡvlhhjs~札婒噫符欸疻蕈蛾拹睟麩}~正尌~rnmow偯sjfeiq{睽噱除孚杺諙摝棇楌齁蘼硒玻薇yoklox勻畛sjffiq|窒臍董硃纖蜺耩賙隰兩扇{plmr~曼蓛xojjms契褪昐婃緮毉瘕睭燹指葍}{~”tppv奪縤uposz丰噹贈緮蠮齆确闡尥儓棷|y|帘yy污摠磃|x|墨種燹爙譬咩玩瞄碃籜藸}|§像僅粔慪漆書譔簐§歜鳺怌矽眧牮洮捂擱飄恘ご哈◢糸鏸靺倩捀隊直淟蠲鼪雸怷敞振嬴ぜ熊絡筍甩襶囋|xvvx~姚佸釦╡挺昶藜的馨恘恂蟆倭糶篽}vrp赴y傚堄す歲眼飭べ蘩藭次劼睧棼颯鵷馳~wpnmmov們撂瑮岈筑岩曳щ蹓~}副逤樔妗冀扚囔堋ztommov肺艗鵵埣個譖幘xw|玲紵甃伅噯嵉覢yurrsx書蹧鸉坋{xy〡馵穻~wv|紙殽嗋劓彊葮ヰ|{{萍濷擼}uomns{鹿wx禎皸釓捶撻痾xuu{ㄨ凅槾壑vpliknt}絀鴇棯隻‘擄茧|rlilrz巡襟侗{smighkpw啟隰褘′撿siebdjr戊敞咱它韋散yrnkkjlot{組齗鯜5廔{md`]_dl|玻厊葉}xurqqprtvy|元酖戃~凶曆ui`\\]bjy區硞凝~yvuuvxxz}}~~氖酘鷾wstx~樽uia\\]bjz楮馽羲{wuvv{宋嵀鸆}rliknv樹ymd^^`em賴魦竄{xutvz旦栔蓍~ohdcdjs=機riddflw忘臩慳~xustv{捎楛咻妖模澬嚃pfa_^agq=歷菗}sonpx營蠰邆憚yurtw~姦俷芶擬涷戁xjc^\\`epL評蹁〡漦纊蚇恣|xuvz勒楘槦椳蝂襴鯦qga\`fr佾樵縪耨今秬籦葋陽||兜婈鳹艜藭qha^]_cjx唱嗖笢Ъ嬝趷襶茱玁埣延諦粢嬽櫼ukdabeks墊厭蠍扃筀爃齆袬除╞炮儸蕖瑄~rlijnv矽疝籣蛵瀦蠰蠰矙灢檶埧葬弛0蹲檟懭|yz~弦跼朴は嗂瞁摳颬睚靰楥觚恇蕙惆1鼯蜼檖駏朴噥往に玶仱Ы擎虜播螟藤擦僭╳複奼郰糶嬮鰱遛ж陓ㄡ複鷗戴飢ㄖ車硃說釦左垢碳錹蘹豵瀁橕縝z{捂鏽撞ㄙ偉葆岔禘糲炡zwlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust25.bw000066400000000000000000000123511437514534100245450ustar00rootroot00000000000000@@Mno name?緘鬧DRb-q;  K  X " d 0 t >  N^*n:~JTbDBDDDDDDDDCDDBDDDDDDADDDDDBBDDDDDBDDDDDDDDDDDDDDDDDDDDBBDBCCDDDC駑w~狠砬觝籀ㄕ垠咱晃鞚鵵覕卍劓~yx髯}朴м歑櫆阭ㄙ版菱蘩玃芘岷}x今塯籜懖五洸京檡鸆{|姘粡藬~云爭知噌蝜~sollosz倍ぱ羭礹巀zy{弘咻╞純歅懽zlb_^]_emv}═備婬殣撌|xx{中狀圻弛妣頂х鏺鞎pb[XVUW\clw噶栖鳿膫鐉蚸ywy|”洧忙它ㄔ城眸嘗拶鏸鱦┘j]VSQPRW^eq~曆隬鐔氄霠壨~xvx|赤乾坎﹜孕玨蜓藐阺檛鯦zh]UQONPTY`l{爻謷欿薋驞{xx}弁祐’奐疧闅玃xg]TQNMNRW^j~澱嬮б僛齉yyz~平炊ㄘ粉蕃毓溶齟楌葝zh^UQPOPRV^j孌繒諮嬿摁xwy|ㄑㄕ為毽泵中玟鄞眒mbYTQPRSW`m濂褗惚絆薤韏wtsv{╡咿洩旨瑭漱vh^YUTVW[ew澱暵恥氖僓蹓upnou{‘托恩ㄙ眾sg`\YZ^dq橡樸珜佯嬿鯫snkkmpw庚捲陞◤炒ukfcdju脩噩毯龢skgfhkpy0遝僕}|~帕|vsv萇wsrtx﹊隬啥ukgedfks}防昐落}zz|}仃雄Ⅶ噌鸄魄rliilou倔虡xmgccfkr|傯笻媊|yxz}仄а艙鬼棗楒縸駐hfccfioz覜戔tlhikqz俺碪罾捊zxx|~允豗雵蚔邯笳縝w餓db`bcflt防織vssv|匿踠灢檷抭{yz|}札塛蘣錏貥虧zr餓db`bbcio{音釣尿椲襶欗慁||{|}巫翬齵祣|vpkgebbcdhlu妞咩旭濘檛攡薜zwx|倀鞚簊間|wrqnjge搬jr}妨竟蹉貾齁鵛yuw{朗鏸蟴z鴉wqliggikp{”滑楒爞睧檛銋xvw{倘蘩躆誨}uokjjms{“棘裍伽樆楞掏蕫蟟~xvux皆鏸鸄妠眺vplmpv~╡偷俁齁纈峎〦蘡麤yvtw}京藯す蜀擁zsooty╯左腋婬捋|{匪蚻yuru{汛硾豵鎀懥嗕筎整|uqpv迂換wssxP眹wtruy氐衲昒て婛樄瀊擒{ust|╯wpmns惌雥}wtruy內噩岡’煎椻籙懍yutx╡}uomou窅嚗zutsv}妓3枙譀ywx~#馬}uposy郥舕vrrsy悔|~剽踣劓||~〃蝠ㄒzvvy拉鐍wronq{拿wrrvˇ絅冀●攫賑ㄞ獄}屍諘}rmlmr}Ⅳ飾yqkloz副袀儕8忮楙匟遘褕氪嗌★佸xnjknu笞麩vojjmv完飄噙征陃緛摶詘摓齀癰怑曳wmijnv匹覂wokknw垮勳痍扇裟嵕糌碚澼蘠蠯﹜ypjkq|終觭|slnr{╮庖褲倯樦槧衃崿錹陀齎~vpov鎂繀zssy笙崱閷旛岍獄鼯噂藚{z~{z屋賨暊~料碤糑楓央妙該儌蘮篫||ㄟ活岐軜皙伈汀匴鉯妥譆膲鉯笮玴驍絳и贍恕~~彤霝藜珍婭蠕值蜸蘣鍣諘瓴扈眸毓陴鬼神{|朕嬾鷿讀|yxy|裘捙陞宋迼磌’捎嘛撮輔~~箋籗灅楠{vrrstx穹稊仴悚曳辭鱞╲嘆鷓間儐呣鷽贗{tpnnos|〢僶樠臻屁碤藭妥騰侜艇壁裎醲ン~wsonns{醮蘣樆參錂欒|}仃曖羸異戰澥磌}wtrqs|欄矙橑~yx{塹硤{}狩つ臻咫撿膱ラ{xwx轍濿熁~vqorw~庚|~氖昑冱活曇輲}urszˊ笣痸{snmmqv|煜髣蠕曄棬{pkgjpyㄢ藐譟{snmmnqu{菠隮傺∠rhdadjr岫”偃活~wsqoqswz~筵齍囅整ykc_\_dl{孜僖{vtuttruuvx{累蘩隞~蒮ti`\\]bjy珀尨|wz{zz}|{{~匙錩篔}xtu|曇uia\\^cjz創媜楚|yxv{{乖氂醟yspnox耒樹zne``cho夥馹誑|xustvz正僛螤ypkjhmx芝奧ukgfiox甘斶衈xuqqsu{狙泵邦淜鱦ymgdjv桐氅鈳upory鎔犪駗貌yspqsv}斥藪輓偺曾栝勴~rhc``aht脤醝質泰諆縐}vssvy彼刲倛侕挃儗鉒xmd`]^bhw綰橡縜豪〃俖曛蠔~ywx|孝薦崿頎鼏籫颩xkc``biq闊蚔懋絨瘉椼籔价◤肅砨趜幙{necdhq{佯物挈善л裖攢妘曳覲摷簋unmnt}催甽ば蜁鐎浸囔袾僧0憾儓戄~|移冀狩戀氪緛蜠僿隤谾覘噹郁捍逡黼礱薨辰鄞漕鬧~戊瑣ж倓巠吇闡岓そ螂惚*橾跁踥鼞梀騷欶疻{u{~疝甄ぢ臏蔥息丰洫竣虜楝玫蜓彴蘡蘼厴鍡媥yu┤y{弦疑Я藩楞’巨偃敦﹝棣燹鵻萭~wslablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust26.bw000066400000000000000000000123561437514534100245530ustar00rootroot00000000000000@@Ino name?緘鬧DT d.r> N  ] ' k 7 {  G V"f2vBPZ%gDDDDDDDDDBDDDDDDDDDDDDDCDDBDDDDDDDDDCDDDDDDDDDDDDDDDDBBBBDCDDBCDstx~§譏葮袲漲╰夾式玲聤襆翹陷陪炕xu魅z}姨軓蘣孻誥‘丑羔鞚餕|y直祓纚獾﹛˙僝篿ytpruw|偭趵襳戄孚秞鯤|qhdcdegnv~仍齣羰莢吨~|}╞偯淖搷pd\ZYXZ\agr}乘挃艗赬zyz尹版偉褕跘鬋wf\VTQQRUZajw玥р儇襶菻{xx{ㄘ暑數倠蜍撠oaWQONMNQU\cq撻臲蘦蠮儽~ywx|旬複枆馯儓戄l_WPLKJLOSY`m橋蘱斀孇}xxz}奎и嵃萫碕薃擼m_WPMKJIMRZbo綢縍趉嚽{wwy}﹜ㄠ褓衿疺奷氪閛rcYQNKKIMRZcq澱縟饒跖麜xusswㄑㄐㄗ音衝侞噥毀瑣蠍き}j^TPNMLOS[ew澱顈熔補澬櫼wollpx~ㄔ言店給墾膨坏云捎董tg\WSQPRV_l濂駜恥完跖齎slihkpw布狐蜇撕痔布pd^ZWXY\fy拐橙硊肺檁蚳sicabekq|#黃岏楓〝qidaadj{歁噱煨鵘vhc^]`djt}符衴媋萱互xropv釴wsrux廷歔yic][]`emw禍僸慔憤|{{}~捂瓷菌矘魷qkhikov窩鉯~ka]Z\`fnw〡殦鶅捊|{zz||俯侞趙垢鍊懪駐edbcejq~巫桷sga^^biq{啻鐉轕Е|yxvx{值楯皵袀碆鍪薄w餓db`achnx備儔skffir}忌鐉醐縉|xwvw|耆澞鏵毇雎蘋{p養db`abfjs~介僥|wuz胱齖灒挬{xvuv|華齗鼩珚vn颳fcbabehny曲疵缺澺礭縈{wtvyˊ噁鶊縉{wqolifddehmv妞面絳蟹湇蘩矘蠁|wtuy怩薤灈~z魄tokhghimt托盡碙籗酃晊暡鸇|wttx巷譔鱢ysnk油v”嗶踮攡薇死僤頨}xuuy股鸁竄冪}snmmqx╡牲栖隮醲怬綾醚yutw|怫嬿攃蟋秘創xroot{4懍眐~wx|色襦xtsuz序踤瓙箬旃筀喇{ursw仃釧yrnou窋廱}wtsu{岔殗碚隰擔}wtv}{smkmr}坰臕zwtsv|里そ粥硎忤薏憊{ww{巨~vomou淰瘜wtrsx~玥畢●剞矙器|z|旭砠}tposz臣蘾xronpx〃惜窪濷禴儕孚器═yvvy盆鼪{qmklr{捏|vx濤擣墨酉奼韁旭匱畋楱unjhkp{ˊ竄uprz室笝墨孩婝楂侔謙賸嵋嗐楊孛懂tmihlr傷觼{rlnt5蕭儘1轅馰蜛馯貏薏矙襉薨云slghmv百袶zqmpu谷麾ㄖ足僅婤椽稄殣嬭vnjjp{楮槱|srtyㄟ蜆砮雎虮圪紾昂輶|tpqw邃橠xw{ㄦ杴澣葰蕙掠邁隬明蝩{z~{}商濋袟~◇渫籦袗洽姿ね摬穱瑀~{y}妒務塓愻竅~||}蹂礹駎“傢祔瓗棖~~Ⅰ迋翹薰珋桸虯懇炎~|zy}卞薣鷾儘汗貁睄●祑鏵嚦襚媋熄毀韌惟帖|yx{終譖藜~{z{〡塨芘乳錩醡惜╞奕項眼砠}{|奶釐礹橶}xussv}耘諅庢★禕蒪玫絮雇噸湳藰楠ysponqyˍ趠觰慫正裱囅什偉雅戰蹗彏舅ytqonpx颯蘱牄匐踤欈薄╱接悸樽皝xtqnov箝礹蹁~||~腓瓵垮集橡踿~{|zvssx款鐒嚃xsqty“紋罈迤橈鮹xqnqw}yy~倔緺睄vomnrw~剪桽躓橋菛wmiehnw未恮簫vnlmorw{~事蜤壏橘phecdiq}玟釭}vsqppqrvxw{㊣氁鼱蝏ykca_`dkx限}xxvutvvux}喊蘠嚃~~撾uib`__ckx完翰|}|}~~}}|{yxy瓜鞚鱧}xv}撗vjb`甦ky室弇~{{yx}}牒籩斖|wvvC橄{pgbbdio~勤朠瓷yvttuvz翁霘欑xpnnr}售歙牶wmhhinx〦緦袤}wtprsuz帑空噌蹅uoghjp}獰氅蒹xtssy筵鏷橩冀~vqorsu|0獐筏岩妍濛鐊鱣xnifhip泐濂懰韶蠳齵椑xtrsux必趨卍擠褥湅艣qjffilt惢罽蚇2噊浦謣齒~yvwx{ㄠ嬴昍拵毰霘嬼qjgeip{柴鰻蔥限偭渀藢馳迅賽朓歑鮿tmkjnw賬炕╰走音憩僳鍖楷弘憑絘壨~vtty空痀早裔崹鏺毊抪炎2齣殢餑盂贏『|亢樣殽斶鍆闀黀謥桱懋骨ㄢм劋齆丳丑妓嬴霾z訂tz迅親眕梌旃倗嵫媝岉擊敞炊仃憩筅檽婧笚嗔膜yr島tw|弁瘧だ蕈雪瑣擠撒爾毓祕延銘歆鐨罾郱uo┴tw{妍瘧だ撈═狀悅降眾敦﹞捩檞矘蘹翴隓簽~uolablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust27.bw000066400000000000000000000123551437514534100245530ustar00rootroot00000000000000@@Ino name?緘鬧DT b.r> N  ] ) m 9 }  G W#g3wB NX!eDDDDDDDDBDDDDDDDDDDDDDCDDDDDDDDDDBDDDDDDDDDDDDDDCDDDBBABCDDADDDD駛pu{玻豗雵伓活ㄐ﹛尼朴渳鵗翮﹛巨vr髮wz此剚蘣縜漲氖朅譠||zv鴆內婇纚獾飾晉霝痐vljhilqy~忝栝鸃╳鍍銊th_^\[^bjr{里栯壹孍﹛╞成飛變鐊孈xh^XVTSVZaeo|弘齣儑嚍}|}托窄撢籣裷蝎qaXRQONPSX_hs~香俉霘詞葀zz|ㄝ衙挍楀艖菬k_UPNLLNPS[bn|變薧韇|yy}的毳鋺嚬譣﹚j_VPLIJLLPW^hy翦簎}yz|打ひ緦瀅臊瀀襢芃l_WPNKJOU^h{氅豂襶蝮zxx{╳請骫毇葇欶嵫袾rcYQNLJIKPU^j澱酁梊裧幓xvtu{﹛妞嗷逋蜞芶撒遞衝簸}j^TPNMLORW`n澱藯噸諫濊葀{romot{丰妞翔屼詙陏隄丑﹜幼散ug\VSPPRT[g|氅嚁除〞諛縶xojhilqx旬亂倧睟芞砠〞tf^YVVX[du橡搡屎蜛{mebacflr|ㄡ證碇葌嶸豕uid__bhx卼學豫蔇}ke`]^`ekt▲凎臇獌葷|{|陋{rnot哿wssu{倀畹oe`[[]aemw諭夒鵴妘|yuuy~姘概根蠳泖slijmr|諾怬tf_\Z\_dlv呠樻童}xwuzⅢ侜僮府も孌駛gecdgmw捩芠znd_]^afoz胸糶襏蔗}xustuy墅靲笱蜍斸茯{jdb`bekr}母Уynheehnz友欏仵|vtuuw{靼贄鏷犪鎏縛}r姐db`bchnz偏冪xtsw戾嬾斸梮zxuv|燧糶鷽坒wm颳dbacdhlwㄠ僎汕暡廔|xtuwy~巷蹠篱{vo餘hfdfeimt妓須犒蝌尥殦矘篸zwsux}殘僆~ztvqlkjntㄛ頂鰍硾先酁婞塱鯬zwtuy~永踙巘~uqnllpvㄙ鳥盷蘡鸅縝5徫飫zwtvz肺蹞彏麾|tqqsv它牲陃薀鏻衁寨銙|ywy|疥嬾欒蠔ㄞ壁{vtuz炭譁抻xx{舛撌}ywwz晅蹖鍐鱉嬴擋zwyㄚtoou翇蝜|xuvy~捺緟瀌濈謽魟樦擂}|xokms淕幘zwuvy~傚豝Э屼踥籩懍~ㄚ~uonqw矢劙|usqqx腋應旦栴器ㄡ僕urru}喝纊uqnnpy酉蓮稱爁儘ㄤ蠍儐|{端縎xnkjlqz朝Ⅸ椲蘻笨迕伅╳粟元倰skiiko{阬が{x|穹殗媏倍拵棞Щ辣善栚埬迭五歇}pjefkr閡怮{utw偷噸盂眕梊軘椴緰黼欉芮{phcelw缶葋{ttv~央╳嘍囡つ枆艗鸅穠|rigkp}靼禚~wwx妤褥芤撰翕敁昀瑐wpory糸錒囥}}弧籣陓揪孕牴孮指欀~}zz}漿鍏优|z~勒殗埡直郰鏺齵{y}內嵙髱鑄zwvy~禍氄珚孝賻塯齗蒧|z}偯藩螢倎誺訰摹yvux|牟艕橁╱鉼澽敹~屏儌鐙譐鵵挴葛咧不═}xx{著蘙褙疥僿肭◇稙孌憤ㄕ巨帕洶||凝俬斖縐|{勤魶墨著懪╞走泵寰匴藟間{vuv}百濋堋分噂瑎╞壯言曄糶曫儘~wrpsx曆鐏肸Ⅰ栯嚬橛╞奶機斳xtqqx菽灢搮~9薰彌╡角澱懟zvsrx啄贄鞀ywyy}底毀澱亹yvw}{wvz性摋衈xuttv{姥冼糧歷蝜~snkms{|z~8奾部ytqqrtvyz|{~兮溈縖膜比牶tkjginv曳陳|wutqtuty朕蹖齴犰~~曇znfdbciq|~|xtutsrrtw詨觷~|{整vmebbcho}0|zwusstx升嬾嚌~}曆vmebbcio~征憔~yuuv|啃籩齤}||併樺zqhddflr笮抯{xvx||z}錘孋|ww}駁橈wnjjlq{蹦瑲羲{wtqsvz”均朔鐉蓁yusu|哤輜獊xutu{嗎嚦髫憬|urprsy底毀祁漦鯓wrmos|准澱醙煞鏺齵蚨~wsqsu|食職筍坏妤諾譋搯{rnjmq|貲檶芚尾禊哭縳{wuvx}底蝓職遣寰嵉齉xqnmpv灞鬚歇岸“剪僝茱輹~{|~◤飩蟾邲崳爁朁{tqqv峒氆╰曲戰霝鞄ㄙ滅杶蜁蒫~|~Ⅱ迓#磁翭轗簾邢н翫藟完藪駙uy弗謨蜦穰蠲癭樠繞悄盲挀瀊襋噩掘褪岈|v駐nrx牯の軞葮睼貏槧陎擊閉炙姿匼踠鐔糌睼嗋uo▍lpv|牯襠珅鷓藷г佸蝠毽陳屆有曖郳臝錈妦{sm衍lpv|※褥俴蕊扈炫普陳祗悌洧◤偭礹玃蝃稃抻{smlablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust28.bw000066400000000000000000000123521437514534100245510ustar00rootroot00000000000000@@Hno name?緘鬧DTb.r> N  ] ' i 5 y  B  O_+o;IVbDDDDDDDBDDDDDDDDDDDDCDDDDDBBDDDDDDAADDDDDDDDDDDDDDDDDBADDDDCADDDπjmrz裒睙嗋摯岩奶宣翨葝vp駕qsy勘蜰鐔媕洽疤霙漞sooqw}|u魄z}晉噂鞃◇裌儥zlb_`aeiqz}捩毿蝩~}}|~朽栺鼛{k`YWVVY\bjt~●忴籩戄|{yxxwwx}﹜尼炸諱錹撖oaXSQSTY`gt~次盻蠳蟘{xxwwvssuz五智賽豗蹗壧{h]TPMLMOPSX`lx挨渼礹堝蒴~~}}|{yvuv{捐邯蛵壝鯠yf[SNJIJJMOS[fs棟碥邱狳~~xwx{尬挓檁礹樲zg\SNKIKLQXao淠婁篝~z{}6忤檟犪鐐臊彯k^UOKHIKPWap緇灢襶葖ywy|ㄡ邐薏囔馺晊眣瞼rdYRMJIIJLQXcu濂懃塉鵹苺|ussw~旭避鋹鐏嗝糧降景漁l`UPLJJMPS[h濂爚羶諫楥xpllpv|╞爰蘸趜謶埬悼垢yj^VQONQSXbu氅鎯悵”睿梩rkeefjpx迅課儌謺椸賓◢yk`YUTVZ`n機廔祀埬qha__aekpyㄥ呴禴鐋庥~{{~◤}nd_\`ep橢憲睡籟pfa][]_bhp{壽譋攢悻|xsrtz迆tnkqz獰yvtv|紐ヰsga]Z[\^bit賢毊お|xtonos{晾佬齖鴉tliint岑庥|lb]ZZ[]ahs闌鷽仱zvrnmlpw珀尪敞傅儑駛geccioz嘎壓th`]\]^cjv聿輷yvrnmlou灰嗲睩踥爚jdb`bglu挫蟒ridcddhs籐鵗{wtnlmrw糸錓蠮篱u養db`beiq3蕙ysqqsy〨霙攡{wupoquz桓蘠蟺xofcaadeiq|那撲洽嗑鸉|vtx潭譥|sn養gddfhkqzㄢ遞謠蕪螟咇燹鵻濼篘{vtuvv|糸嬽蓁|uqsokjjkmsz辛蜆刱摠齁先轚す蹬懘{usvx}習鱣~{tpooqv{╪振暫逜譀鷿蘑壩懭zutwz瓔巘}{wuv|迂敷涬臄荇俳欚唭|xwz~倔戃漸噪{yzㄝ疑憧xux泐譧{yvx|啪譔嬦摩笑憾}}uoms哿亹ywuwy勝膷麑穰艬畽塯槳~~yolmsG癭}wutvy☆倎祰殏錴犪礹彊&揹{xy}~toot{佻鐓vrpqsx忠昃噹章杽籫熊捉蕊}zzxuu|喝嬮{qlklox笛韃敝薣麩彿в儕~˙尌tlihjnvˊ齒煌瀊鐕笛珇韃互郎挺罈{oheehmx匏牁凶殌梖直庈昒藝滷做褪珃僭角成悅洛vlgcdip蹦扆||爰熙側謐藷拹頍睯瀔鐇鍹庥洹ulecfkt帟歶yy~亢晴董景极籜昀爙罹vnghjp{鍥縒{|╲散咱﹝倦碢卹藸ztopqz佻鼩あ}zyz甽遜敗蕓撱}}|~{|~鎢鵘膠zutuwⅠ昃蔽▼歃鱦~zy{}汐僗橤階|vrruw借覗儒姪崵蜵蠳懰{xx{孝遛蟻逡儵矞砟}vrruy正楶祪府眺べ濼褘zwz~豎檍黼矘麎隅zvwy嫡劖媢勞豍邡~zz}峒籛縒異﹛~|~器徥鍇墅諕~~肥籛攥膠擇齗磈}z|廷緷ヰ寧駉情橋攩憐xtuy澄寲漆殮骭鍎珨歙橶}spqv肴謻堀~}弘絢摹╞歷藸~vrpu}玉鳻傰zx}﹝眺陳氅躆~zzxtqt㊣嵎梴xvwxy{~威娵窗}樵鈮ysqsx~~yvx授侞陽xvttuvwxvx|嗨錥褎~yz|樹猀xokikqx}}炭揚~yvusprpmnrz嗅蘩頧xvx曇|qigeflt~{wsoomklpx趟鯤zxz擇vmffefkp|ㄒ}ytnlmmsz矓鼛|z}擄vngffglp※酗xrnprv}壬齘蝢~忌撾zslfegmr直織{xy{~zuuv{盅襳蟗鏜橄yqkklr{模褁翮|wtrv{巨}z|嫖籩鯬~z喜輪甯zwvv}萋艜橞尷|uqqsv}垓畦亞薣幙}wuz癩濂橨試嬽擼馱~uppsw~奐撰里歅藨yursz郠擒狊ㄧ徦鵙xtruz有撒歇咻庖譆燿趥wtsv核齗高芍打栦浸蹁}yvy}玥蜇臏壇枍霘轃|}詰蜙直跖茱蛝迄彊眕貀夒譠姚旼洲x{釆淠嬭窖疙л摫衚見妖瑰誚{mnrv}ㄤ摷鵸妏迤姣挕齗灚捇蟻岆羅uo頜ilrx笠婝樥膬嚦氋痻鬚惟奶姣盄薕歞緡甂鑄xnh頫hiou|ㄣ蟬旆恄晊跂婧ぜ僑郃角迄蹉碢耰膱慖穩wle頡hjnu|征玴褽兢劃蝨歲神谷央弦泬縏藷臏澈ymflablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust29.bw000066400000000000000000000123501437514534100245500ustar00rootroot00000000000000@@Hno name?緘鬧DT a-q= L  W " c / s < } IX$h4xBR`DDDDDDDDADDDDDDDDDDC@CDDDCDADDDDDDAADDDDDDCDDDDDDDDDDBDDDDDCDCDD養gjos◆砫皙К悔咻╯倖蕓譠|sk駟noty剴趠憵拊岡俺嬿蚳zpoppu{zq髯vx}倔澺襌漸~|}}牒銈via^^`chpzy亞澺奱}{xuruwwy3砉艡wh^XUTVX[bjt~倩毿彏~ywtqmmorx|ㄔ岳城睡蕫搹k^VRPRTY`iu紛氂譠{xvqmjilouy迂嗽で豇嬽襦xe[SNKMOSXalw朱俙襶堝敺zxxtokknpqv仍鼯塯嚬籗簎vdZSNJIIJLOT\er儕擋檟藸~}zuonqttx倥郯譖敶xfZSNKIHHJMQY`l|懾鏺鸅}wvㄉ旦婑鐍鶇彯k^UOJHIIJMPW_m曇犪鮽~棹澥纈喍趹蚋rdYRLJIIJMQWaq氅鐏糋誻}xuw~仆扤襴蠋秸葩陬遣l`UPKJJLOS[e{氅禢а奿肭wqmosz牯俉籛爝織狙zj^UPPOPSXao濂鍼陽市朝薛zpjfgimt}底戰鋿謪冀芍zk`YUTVZ`n歙靽仍漫ymfa_`chou死逄鸇蟑yvwz岡}md_\`ep瑜憊措{mf`\\^aekt□裌攄閎ztmmns╳tnkqz遲|xvx迄of`\[\]`elw鎊嬥|vqihimv牲佬齘鴉unmmqz○ujb][[\^cjv抈攮堋yrlfdhkoz溺噹秩呯駑kigimu~飛sgb^^_`elx彥藞慼zslgegilu剴詅碏襳鸅iedcfjr}姿童qkgeefkt⑩攡蕾yuojgehnw楮蹜譧vhdccejq{弩熙{vssv{薤暩zvsnkjlr{颱鷽々ypheeghkqy2匱僕夥撘|vtrrpsz沶戁}wq始iijkmsz捕衡Ш噬曙桋嬽纍隮撱{wuw氬撊~ywt連ponoqv{店滅奼涫檖鷿尨譚趡鉆{wvwz}峙壨~}{|xuuwz左為飲紶薏矙齵肸棉魴zvwz濰譠戎◣硎籣筄埳‾髧zyy}教亹眷尹垮揪}y{賠蔇zxy}ㄨ淥褙野托懍楚╱恕}~vsv轍蛗~xvw|六淟禴蠮纊棑趹障慰炤陽|xux}zutx屬捖zvtux~兮砡瘊矠壝蘾監朴蝶xsqt|zvvz者嗐~tppsv}屁俴髒暮僪冀挽ぞzusw}}境桵xokjmr|採侄活&ゅ凰恀鳩~z}凰侁~qkhgkpz▼斨敏薋纈※蟠芩產扛倌韁xnhedin|區埳◆赸蜳霾4遛藪艙祝狀硫襟佫懋眼絕泵slfcdjr濛珖~~宏躂悵◣垣硫戀晑筄賟隮鶇餇噹{qjddflv盈禜~y{貝矽剒伏虓zslhilr蹂磈y}|}粕叔敻}wropt}省鼁慼~|{xwxㄖ‾裮篫~zz}}z|_錝棫}wtsuw旨迭菱蛃~zyxy~宦蜚橁zurruw的懋屏夒鯤xvwx|市晷杴瀦鎏儘|vssv{Ⅴ玴縣汙珆楴蹢篜vuvz翁蝍壝攢奀yxx|鞅懧阞平洎捱俋謥薄xvw{玉譔鵙落~噢歅齵悎秉詈疇|xx|皆觾壔陞望襶縼插姻窐|{汛檛鸃穢機糲瓷~割瓴孩殙儰耪畛祠樵鯚漣~yz}池梤妙偺絲熒敞郁歙鸇憧}xxz脾恉弦奮徽}|濂雿~xxy}知б閒~}}{yxy|笮睔蚍}zvx}橈磑|z{||{|頁噩|yvvspnprw~疢霟蟷zuuw樺洇yustx}~{|旨郎~yutojghkox昹彏{wvw~擇yqnlnrx}wslgdfhlu襴幭}ywx憶zsmkjkov{ulfcgiltを朁}{|憊xrkjijnt~ㄓ|rjgijmv扲堜牝擄}unkkmrx〃粟~~戎ytonnrz坭鸉壓釐樸{spoqw剪侜澈}yxy}帑|vttx拄靺箔橇珙{xx{倒碏隗翱}wuuy~玟筍{|嗇藚朗籙樸茧脾儜禴斔黎~vutw}戊犒惜客檇蒹嫘籫憶蟆匏檞蟴yvwz}食蕭釧娃酚鱢~}鍥蠳央#め哮蝩~z|~什甄謗葆絢о薋鱢穹塨2栨唉譭仁複迍婟楁夒廙孚霰誑uux}}救蕅駏5覲筀隬襌滷狗暑謎w餓kosw~●ч鏺鵔簡戊齡儓鼀梖迋糧}sn枸fhnsz笠涳膫貗蘣灗椋勳岸仃轂僽獿槼葒屨ulg苟efkqwㄣ蟲衵眕笯椴訞繙摒圾疝證叡囔諀稃牳ukdefgkpx征俵Щ謝器陪爭丑╱閩謧擊遛蓬xlglablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust30.bw000066400000000000000000000123351437514534100245430ustar00rootroot00000000000000@@Hno name?緘鬧DS^)m9}  G  W  c , p : { C O^*n:~GVDDDDCCDCACDDDDDDDDBDDDDDBDBDCBDDDDBA@DDDDACDCDDDDDDDDDDADDDDDCCD颳eglr~樓靷芤歇悌角勝蘩幮|~{sk孑kmrx匾賧橖Й哈斛襳攛umilmr|yq駙tuz性蕫鷽庢~|xwwz}Ⅶ澪暀oga\\^bhr}y}|~刈漦藑{wuroqty6徥竀rd[VTUUW[ckwˇ裾囆|vspljlot}中ㄖ辰氈嬾鱦}i]VQPQTY`jv忽暠卑衎|upmjgffjlqz延蝙攫郪襴鯇vfZSOKMOSYamw料翬壹噿xsnkhffhkqz7庄僾譊篲tdYRMKIJJLOT\fr~○剟鯕ztnkjiknt}畏摷撱veYRMKIHHJMQYam|萍嬾葴xspnptzˊ祼礯k]UOKHIIJMPW_l湁軾敹}zz~塽嬽攮魨睔媊rcYRMJIIJMQWbo橈鐐罿优|~▲淥灖棽蓬捷撮l`WQLJJLOSZey澱曘怤虯}vrrw|玷崶鶆等狐{j^VQOOPSX`m氅癪劑為號wnijknw╪奏ぼ譖廲が炊ziaYUTUZ`k嫌簆◥砲rjecceipx0邀籙駔{ursu~咫{md_dn剝擄╡rjd`]^adkr|並踖斖嬤}uokklpz咩upoox綻麾|{}戍wkd`][]^cir{る孋慾yqkedfioz4羊嬽zrrsy左~pgb^\]]`flw扽巕膜xpjebbdhq素跼韋抃髮olkmt{0|nhc`_`bflx冥攦薔xojecbcemx汍婃蛵襳篳ljiikqy※筍|qlheehmu坫斳yqlhdccflv儓攥xigffkqy2蝴|vttw}﹟爃鸀縑ztokheejoy佰籙壏xq惰ggimsy3嬝贏隻詣籜爙|wsonmmou~豢瞏{to駝kjlpv|2褐昃囟鰻豳倎蹗纋賧鵻珒}yvuuvvx昝篚{wtp駙qrrv|0瑣饑朊詌澽鷽妡誼棰}zyz}}餅髕}zwxv~||}幼敞滓襟紵薏蠲攁動堎|zz~ㄩ歃藭~~辰陪央妥鹹寎禮Ⅲ抸~{y{△唦蟣陪#敢妍~脹嬤~zx{玲稑灉楷懍豪妥熙{xwz|z~傳嬪|xvy~動碬鵘Ч騵斬儔※撬萱zurprv}{{□刐xutv{動錴鶇觶滑次で簫ztpmosz}}倩妏{tqqtx傘笭珈忳葵孛刲Д~wsprw~汙昄uolkns~◇昑織狙濤今疺舅~xvy}朵Яzpkhilq|阱狣怯蕍齵~|~挽ち蔑坏╞幸滇興tkgdfjp~割捋敗檁嶷蠕|zz旨雪凳雄孚で囡鐃聶隍yqjecejr蹤戙本珃襤魯yyzㄘ蜆旽迖粘濄鏵憼釔甜}unhecgmv脂樀炭陝~z}{倩僗矙企熁{unkhhlr醱磑╯|{y{~□朄伍坁|zywronnr~旌蠉|xvvw}嗯佐茩}|yz}{zwwy供嚦袉~wsruw|{~習鉥~yx~晁爁駍{trrux◤迨{y}毯屩yvuw|互棕僨轗滯|uttw}朮躅~|誠齖廘zvtuw}姦涴鋹糑zyz~儒濱慥Ⅰ畇稊豟厴衒xtstz體鸆孺瓜勯礭縝有犒盔麥粣荋ztsty盈鱠誚攻壒赤次冾xvwz疣燹鵗蔗莞珚丰ㄧ鰱{z~ㄧ砳儰膮懞棐等儂樨隅不直繕◣為捲黑倗蚧楨~z|鵊落zy|祭滲倦笣梪瓷}zwvy~濂蟝插ywy妥葩yvuuy罔鼏骳zutux歙輷ywy~底粥yuokjjmt貉灊ztrrt}樽悜}|}}|}身郃vqkgdcflu示懱~wsqtz楖xuuvy}它失vnhda`cgp}朏篕~wtv}坁zsopsv|‘忙yohda`cgo|癲欂|yz寰~vqopsw|ㄗ咧umgdcego|錠蛢汁悛xr鈣y~之式迂換|slgffir璩鱧巫撿|vuuw~牲蝦榆}|1虜zrmllow鐊欏縞甭錩樹氿}zz~副婃喿簽{x{牯擎}vttw~老蘠餖汕聤踐洉舒儊犪蟶瞿~yvx}仇擭漫|}族襳孍倨鏸弇匏海鯬|xy|次謝趙阬聤幮敏譓岐噊敺||姜豁罈惕孕冕歅簋☆砳葰晉檇藸╱嘉迕恂冞崺懩都五敷簽qqrvy}捺蕅廔狩阹儰瀎蠳灛芮眶滂蔆ztiijnsz排毿縡椰╳槨麀齵楙玵驍yql柚ceipv掬楴斁鼭鵴捔痔姘忨鋷囔槦棎貍ske苔acinu6は笝衿楀魠梀蔡岸ㄛ嘟椯謾棴俵伄sid苔acinv忝邲旼講蠅ぞ蔆恩§懾鸅ぎ洩秩毀ukflablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/caust31.bw000066400000000000000000000123511437514534100245420ustar00rootroot00000000000000@@Hno name?緘鬧DSa-q=  K  Z & j 5 y  E  Q_+o;IW cDDDCDBDDDDDDDDDDCDCDDDCDDDDDCDDDDDDDBBDDDBDDDDDDDDDBDDBDDDDCBCCC颳eekr~Ⅷ軗埧僚咻怫鏸幭|{sk駝kkpw椒鋋憀漪}|{~彷籛攛vmilnt|yq駒rqw~佯蕍襐憎{wursstx~殘堣pe`]^`dkuy{醬蓇}vspmjkkmqw~晒巃竁rf]XVY]ep{潑輶ztoljf夕lr{它奴云煎薤鱦j_XSQQORU[blx六裚鮸ztmjfc口jox姘謝藉桋蹞鯇xg\UPLKKMPUZcoy玻跕噾~wpjgdccdiow朮拶槶贀蹐veZSOKIJJMPT\gs~級噌∥鶈儒~vpkhfegkr{敝氁嚌yfZSOKIHHJMRYbn|匏錵鸇竄{uomknqv些勯糒k^UPLIJMRYao栔嫌欒墨|yvw{汕碢襝耩槧囮scYRNKIIJMQYcr維欚寲縝央岐裍灖痸躉匱藕l`VRNKLLOT\gx氅癰硢抰{wtu~成ㄐㄢ忴籫鵸策庚{j^WRQPQTYbo濂駖輓陬}rlkmqv丹帑磁瀄甗か}~xj`YVUV[al鵛階╞{mig柙pw孝忔糶橑yrpps{zmea`afp祆曉瞻ynjdaabeipx屎錵鸆穢{qkiihltvqnqy粽冀~skd`^_aagnv朸攥縞wnhcbadjt﹞甩譖~zxy~vneca`dir}及廲嬰umfa__^bju拳版傖踖xqpqtzwligedcfjr晦灛藹umfa_^]`fo~剪拫檟鮽ollmqw〝|spmjjmr|壬橭xoida`_ago|終燿敻}kjjkpx幼陪~zy|使齘碻ysmhecbcjq潺襓}u柝kknr{炭遢螂悸祀嫋礹蠀說|vsomjpw朏嚆{vp駛pnrv捂嬝佫帊囡づ赸鐉纆賥魨阰}zwturrty嗥嚆{wvqu誌}仆劂藐巠珃軜儌覤撚и捁~|{y{{}終襴髕}ywxv坍}弦撕僎絨陬溝м殥獿蛜捐警}絀鐉藱}|~╲蜓歲疙陏§滌~{z}ㄦ匎鮸劑芋巡螃萱|}◤爰~{z~0邏襴灉彊賓姨Я馱}vrqtv|捏}zy}朱咈譀襐褶酸懊憫玷恄儒xqmlnou~5趙zwvy~ㄤ忨麧緦蘠欘艛譐蛻玲晊穫xpljlnr{挽蔬}vssv{ㄢと恌妅裍馱宋瓬|tpmnqu~娃繕wqmory旦鼴僖狐蹺~掙珌楔|vtsy}※撳漕ypljknu里羅畋擸}zx|ㄡ播趕巨挈甄繳|skifhlu傀菌鐒蠌ヲ魯xuuy身絲雅弧攣玾玶繕vpkheglw檐罔楀炵鬧vuuw~※薹佫岓枍賧鐀寲襤zsnigeio|紳睌黃貍z髯xvyy}札崹譈蠮糐{wtqmjhhlsみ蔇重}{xwy|~}~{z棻似欀}wuqpolmnr~猷縩~{wvx}|yvvz舍伸棖zywuttrprw所嚭衒xwvwy{wttw~白漞~ywyx{~晅霘駍~vwzzvttw抹阜巀yvuw{姦硻轗誥wxy}弗鼓yvwz翎陀巘zvtux※齟摫縒|~敢瓚捁}z{韶穱犪蘻磔}vsrtyˊ嫄磔耳澨攁祀崵詎笭楂|trrty啄籛鸀癡橢躽ㄟ蝌撐秣滅譟vsquy喝蠳暪綱椇咫╞炫馬妤陛{xvx|晉骭緧濇蘧鍐豪~~}澱欑ぐ爸帘洸ㄗ}{|ㄜ敢陋秘枑膱梏zwvx{濂齆弇鬥戌奴詰貗蒠yussu{似鷿佽見~}~wpu嗡齵衪zspoot}橡繀尷}}~zsmedeho}朳藬~uqmmqy袷vngb``bir臬儩xsqnqxき~╯丑ukd`]]_dm}崌摁xuru|器}{xx{◢悍ulc`][^clx氘藱|y|噪zxwxz~′普瓷}rhc_^`dlx隸蛦▽噶zyxy|ㄓ巡擱wnhb`aeky綠葙姻炟~|ㄚ給熊5騵がvmhddho}樹壒砭ㄤ迼擔}乘彸詍拑|}乘迕贗xpnnov鏢譨部晃巃操麩ㄥц濿瓙磎{z~§鰓徆{wwx甘齘熐◎媵壁捺匴譣~{~ㄡ檢抸嗓籜灈兮嫇爦汗覅敺弗憑狣葬朵栔欀尿砯袷~~~客叡唉懟仆襖婟堄齬倱霝孌蓮ㄐ旭壇赫p褚vz竺澺戁閒必譚鳪膼艜嬧譫斯劃ztiijnrx怵翫鸆簪打譚踣繄埰繡yqk柚ceinu~級碄斀蘜灕媊筆ㄞ諄筅齗齵摍蚘馴ske苔abgmu椅欶梌軞嗕痀赫托傳塣縶堄佫伄sjda沾mv姦珆芶謙蝦遠疏挽絟鸅蟑戎玩毀ulflablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/dino.ml000066400000000000000000000106741437514534100242160ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Wed Sep 18 19:26:06 MDT 2002. *) open Printf (* 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. *) 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* *) static 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} }; static 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} }; static 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} }; static GLfloat eye[].(2) = { {8.75 15} {9 14.7} {9.6 14.7} {10.1 15} {9.6 15.25} {9 15.25} }; static GLfloat skinColor[] = {0.1 1.0 0.1 1.0} eyeColor[] = {1.0 0.2 0.2 1.0}; (* *INDENT-ON* *) static 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 = (int) (dataSize / (2 * sizeof(GLfloat))); if (tobj = NULL) then 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); incr 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); incr 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(); ;; int 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); glPushMatrix(); glTranslatef(-8 -8 -bodyWidth / 2); 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(); glPopMatrix(); glEndList(); return DINOSAUR; ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/dino.mli000066400000000000000000000005611437514534100243610ustar00rootroot00000000000000 (* Original Copyright (c) Mark J. Kilgard, 1997. *) (* Translation Copyright (c) Issac Trotts, 2002. *) (* 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. *) (* return value is display list handle *) val makeDinosaur: unit -> int lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/floor.rgb000066400000000000000000001517761437514534100245610ustar00rootroot00000000000000no name酐甿茥 (08@HPX`hpx !!""#$#$,$%4%&<&'D'(L()T)*\*+d+,l,-t-.|//0011223 34(45056867@78H89P9:X:;`;x>?@@A ABBCCD$DE,EF4FG<GHDHILIJTJK\KLdLMlMNtNO|PPQQRRSST TU(UV0VW8WX@XYHYZPZ[X[\`\]h]^p^_x_`aab bccdde$ef,fg4gh<hiDijLjkTkl\lmdmnlnotop|qqrrssttu uv(vw0wx8xy@yzHz{P{|X|}`}~h~px $,4<DLT\dlt| (08@HPX`hp﹂∥ $夾,辰4弩<社非客昭疣茅倭娉桌留航追埠徠條琍 楔(葫0僑8獐罰酸嘻樟瞑諂鋇擇瘴蹂髭燬聯闈燾雛獸 "*仵2妎:侗夌昄泇迓垟挋柌癹胕剡屖栦烒窆茿gGrㄘ嘟Ur介m[Qeckyqe摒蟈迨襖欷懂L分厊怚移丹痁垠{扃陎埼褡翰ね侜ぁ眸炊ㄜhQd辛履Zwf`L=kj項}Rrx收葛妞xZxippr`k萱R5e}毀簧ct捶失瞽峙倌玻~蛾誼暴邽蕉蜈蠅楀媄劑棺w帘捶cjxwk汃捫a嶽y{汝昍咻打__o玥d竣tSsp五aIPtl怔楷雩蛹滯}腌隆{x郃樅聳q蹊眣橀蕨趹檐葾貣釔蝦魅]]p˙狊t絡洫QYrk肫cjsVoo|稱噪捨腺捍s棠負Esrm˙均﹋訹嗍茼炎俴з馮濛蒴ю頦曶悽扣i脹j}赤x捶陶納ωKgpj:Ih首怹R絢辣楷擊s丹zRtgcx_竟褡そ婟恦瘌侂覜魦陷桍拸鍗軀蚝洮嘗薊掘~提gτfeo夆凸x76Xt\NNm~勳ˊ僮朱馳]d}nel6織妤虜狗犖恐威m玿у剻婘桸梏蚨~ㄨ那iHYw_kw※Xpuqq惟;0:l}qumV萵普捌撕ざ貝’熔╪Ⅸ飩玹暫笴梮L\v畏z忑儒期諜w征倔f賬衱7B屎Ns〝nn4_?Crg㎝U腴嘗握ㄔ尥旆礎扭磌唌k洵厊蚞q;跼纓摍咱粞嬲撐摎車悝r陴の扑殯DJV藪體砬}m4:|肖xqzy晾|`KIKtEEvo嘀藥版屏桋鉅|剩@L迫掛廙r迋蟻в齟言閤慱紵捏檔py韭艙謨酥Ucx蓿敖{祟QlYdxz~邢aw^aszlbOVb]^TXcwvh棋措靼昑櫛{g_y蛾MB;R2M奾薦痶徜tw鹵玾屏伒倆擅皕椳掬〣騰疑史O2e鹿rl鄞銨囡觼洎ioz帕xWs|jeUmWGql^\[|j殤芔旼嘛武OUafUOt未扑〝慝`募祤jt蹉薰謫貺愬篎У谷掖徽珊捫罈\ef~阬bZ蚅恦捗羸b熄u_vx鈇VjvSEgsvc喂uⅠ匙繆G篩FlcWD6_☆筑落兢蜂秧譁懿.S擁х鳹錍謯辛槭章硤旼籤襯砲性噬拿砠”譯首QU\XWWz飢~g汛絆{派守AKzchf怔洸繹棍迕雁fu儸Ⅷ戧蜌p\陡畇豟魵僕策囿溝札佮衾犗謎香掗尨}~q`dr{t□S8褕з撢僕\X~T|Ⅸ絕pkfYy砰lG蜲嚆Ⅳ咯撮楣風匐xw]迪畋甀補籠爍g稱賓z誥郭sn|[|hsh>@鹿摒[nev4嗷檜ii貹}蔔蕉ysZqlr|偭挪崽袢播噙漁洎嘖沙<fd\B複嫋蠖遛抸b佶管蘇沍ンz?y弦薨AQ榭tせUv剚觓Ⅴ齒趵徽秠膠厔佌台z歲恄飪醬摲楪繕楚\謗KLatGf呫鐏幵椗耀客撞蕃瓨:怛`TlxlwihrzMo繞少梮眷抪旂~~撈xp午揖鍾婟剌rz|wU嗽kn|m侈薑oYiWzr96Y>r戚眄礿濘痐X6垢裘z僕w恭檣d^re╮岫y|js謨蔡凱扣ぐ袬岱狗□珥萌椕袉SifAsvS@fSW]S]flnJFf~jB:DVcSW暮楝W}玊l1rwtu﹍捷毒卍sVyc{秀炊直t囿糖公褥陘珂倵薯拋娾瘃謨陽о悁摷糅SJfzgih[福帕_z99Yu|oZZHPxxs磬7mOVs-#i丹漂洎Jduz~g[_觔劂竺as螃釓t佺虯桭媄俓怹ㄚ偵那迤昍~咻z慫眧喒qrI埢KKRk{IHkoz〞教}患OHSFO咱ㄒ爾iGG}O_巧介阬從v插WV炭稄i或撟啖螂揚府馭恄冾捍ぐ佻兗界睕z褲ㄘ佸=1?P($〨拏菠k剌eWV赫kr^i什炕oAEW.l|庤襟盛褫7<椰Λa死鄙狀ㄖ溝ax襟魛愻尪ue滇惆pc腎咫侺鍘lk}^Lq.2怯痐飪h~姥SrkbSUqd\O_[sy畢Ⅰね晴面末飄炒息帷Tz扑が謬傘碚珧w怞UTqpOfㄡ倥謽oy弓XdzTdpS身a撕予羽耨]$)LO>E]phr檢囿}+尒iqbS紐粟怕y}蔑衎{9ihb驕l8\y札帤ч魧妧7m那°Yanq旁褚{帚庰棵▉斂new麾:6xi]|hoMyt限oxaxtnSp給僎迖咳中偌永奐κY僱漯e忿珘啟藝店G○尹x~馴怵扈怔挫紗S"gu~qy@E=6h肓|Fwvq疚溜鰾|裟i純{炮棠凊諕脤饜棸疑敃0粉yyg囿詭睋遉i`t忖Qlnlh80kt||xD>DWmps撩阱垣極豳郱排絲惚髡捻傢悼寍豢雎原悅憩舛ㄋFC{阰漯蝠郖雺晁尨琅朴﹠ㄒ炊贍e偃xj_vy催m43do_jy刉蟋^◣紊順剆芼佫簽ふ捘邲毓Qcny眸旦pmgWd萸鰱蜡侒蒰伊苃昃蛵玶 ̄鉓j舒藉伂蚨Us瀕{糸迫\G涬wJd^zjdiCrㄩ|俸{▆t蜇蕊鄞糾怏郱尨QW予抪~\Qr甘宛瑐堄玅閞伉黎嬴Ж腎瑗觸jGbovA窲优QT徘\;x╪8k扇sLldwL`^oj~g孺斜必憑騵爸咿楹學昃]tm帤_硪刵硊僿碚謰篱b﹊延贈諆xfd謀Fj{eXF|]L^z_w彫[rp岷\jwKtihhxWL庚岆z飩撬貌滲梮支屺嬰r徜LAe\n科禚X誕嫦蝫摜楸n嘐ほ蜌^秉々音噶孜O荌e?3,7mk借ZXZf嘔埭D3\J_QV祕互`史ts堍NA氐窏覲次葂{餞u圴漆槨hk穱Tj丑呬枰裁凊鯢捌旆√緪睒蜞賹{偷社俳Wk^e摹t索鄞蚚JGiy坊a垓乘骨筋qysz魚俵蚡蔣車繙掘k7D葷曾早胰輲O>7a?G晶剆暩ㄈ娹暸槴彗[[tx斑|M今p汁xaPKXxr雪恕捂釣知棒ぷ偏樅矬蚑乖擛粒赻矠寔標狪tQdfQHX]_]4W轅煎邦揹l恛椵膘OVio順sD撙臟hKs\p膩q^Fopb螟誕衵眒偶尿憲佸匟&十擬笰崿嗛陎未儆摁粟瘉〥z今\v`秘黑は悻“棵銓狹-`賬烑|姨VV}蹋繡抭狾鄘Ж褡詏漕qiEKUm洞閂濘乾]lyn{n[釣j擦楹傢ご}②猣薊嗓織動袒\玲懇詫k}vyir亳溧毆祰蓮碩筏lklaD_AL·x抹偑RpU\iqu釩MA挀戔暷裊啶躂蜌洷^bd{衝獂i次盲▍鹿枎笛貍_xKu繹Y阱半M姜蚴菽娼,雁ㄨ炳gi_CR戰萹ZWyQr喝蜬u峇鳴琠艙蟑撿馽繹軔Njt{8f扇拉知侂謬洏豪豌洱坑x_裘}禎恲陳蘇韶齟}v||uRm垣艘a[I45_l蓿y9G妖遣彶ば痻馜毆x妓欹赹廑ㄜ介姦zz~侖檠眐峒溯惴啤}8TY破侍厞槻流Rbそ砨э谿賒m{}UYxΚ"g:So;8Ni灰g玷堹ct侜遠馵|彴篡Xw帢嗃eM花緱涵nudi序洎衛挶躑栻膽J-Fi巡◆祚悔搗kYh姘伝蝌辣T]qe△ЗI"K[;`T[u螫z^疥u俅蚚恩d嗝郈皙{箔m}^禳苺僇虮肣up洞庇岸繹嗎鰱ufk判cy`oЫ痁咽薑姍ja_J^笨怑eD9D3+.K煌層R隋幻皛棧凅婐蟻艙阠6a探w牉z譜椕必輒TzRMO院q溪砡晇藉t匠Cа蜃賻秤|i挎Y^wvX洹_Zur釆值]T~溺羹挕侔檄耋nDch勣熗爰P佛x途Ln利Xg〤t眷至蚞`允旽屆п垠遜弗]Hpo薔薦鉚煽煽介砝邦珈棆時僉民疇wu巧倍萼舠允唧MO?z念誧}|xzp|gT|`ㄘm畋仍碧婠灸B_eWgb腴G糸蹋oj陰u拊}~Д早嵎耬Е們妧δal▋值捎數оZ{颯彄?Rxx薇m辣kたvrgms{拳|mi躁笥s峐A@i^dyR`鬲iWewn蹟ㄔ庛棋觛怮輒煤袢\OLW6Cxr扦槥昅攪牂T(Y庤z弘c田洐hu[P}隄|宦繕l震Aba利Q垓╯蝓羋組dHaqDsu砭蚥掃蠱期{kgwb辿豐Ё@挎緲fd^~杶]籤阞楓袨堥=6c耋P7D﹉rOppglrtwH6MU洬aos殤9?t[FLEkp赦XZ`H^副蓛蚸嗦涴婈ざ刓枑散薯納噯抾津琤q玳彸坁kSg觼砳俶朘釆芨悃擒樘鉖ね靬谿敼COZu遙梮饒寎紡瘍F>ZTl孓獐牁壅坁薦邊磎藍庣~宙椆葦漪龐布鄉孛倳陰jyw|版邊媃笲奶蚋邠吪餅鬿檄俔牄嫦伂^uCV站怛窪薺福豚˙卍茂K霾_R}弋x汙鼴伂斻韋譎侀Йlf炊r蚇d_jO尼辛負d有瓜駋詍ok尾筀廎竹婧賑wymdn鬼蟻嗆鰩孖翔醫挺狾xU櫛挬vsleW駝ㄦrr鄞棳慬jgお{b惦;t51^Xy鈑|rn牟慓郪~jь馜嬴職ぱ熯,=_PMt{諺瑮鑄奎荈異{嘐撳m捁p祁詘滬縣爬N`k赧絮l阱嗦昃昶駌Q[|pYO\床□|旨jm潔梠歾肜挽塝睩寍扂挼寇FUpd[vx漣葥剪hXk絡嗇躁q事簾葵搆otepe泓銀脾換侇}湧疧雿善惘}[lqiYh府fac往ワ妀郪vh浀z狐樞摶珇拶KHUz笞傺蛝{jg夭V秈聿h汕皙RhKSnqgd\ㄗrn迄~鎖慫丹陝rmtp~l官lijQ3D洛vov猖dヾ褐享巠]VUNo~糧楺敆81抒塍梉亢楞uakg^g]e〣sq笱qZp{rwoZn腥r[|絰fZS甚DF@bKZkx懋洹FLNX﹎f炡呏hMf局婌鳽櫆擱悴姪遠銖趼l^qmc|昄之軗ㄤ^sYPt汁げv閎珀M:匹だ_:^8VLj7376Jq./SWEkZC~H`朊naEx衛qr廾拳詬嬬倵鐲:蕊呃'V{ijjr葬wacZ聶~吶RbK~nn諉須zhv核簡L\hU]狗q═fMHJM])E,)!bTA?~M漪asiqs〨毇塹擩孑蕞藝瞻~}ILyhLFpⅥu8Njh解nAcg9U~svvxur抻掙藩^z很躉躑q輻杲eM52Mv玝6@D覺y汁ㄧ>!(7]xbxt玫帑穠奪謎謬媜菄擠yI`}祝fKkv展quq弛W貀早僧z旁嵑襟榜yru●蟋宋居u‵監耆駇葔鼴隘XhJlm;D[@ Ghdxx}豆蚑盔ckhhe諂ftjnwmy阼偉疰|}n停e晏隗矸戎準刉WZ_Y~岑唻塵佪圴脹鉧﹀N$$/(~`pS>-($v飯Dy蟠侕jmPXfg|k祁鈱o|QwXa砳睌煌椇奀s爰諔{悍杶僁てrh換賽捩塎嗩尥恛蛻訃lMj>+&]66rKE!$?$(-~rc尹≒狫稱言挀vM|y俜郕肝ns甚神ㄨ玼撚桽倢wxx撙玩爰枘倍嗾倡諦課卯^p暋jj0.)\lC|[Zo51@W壅℉?Y羚婠迋絨狩犓掏菙除L咫倍閂粕TPbRg雲姦井掖祖roti硅妎潦勾杶ru_X鈣X_zxtn粉t\珀筌忒lP倉硞筈苤[|}威I\偉洎疆^^謐姦笫鑄w^pSp砬朒捰撼甃祩鞊幫晰t8r魔假忤{l^戛^眵F_剡殑雎Уえlmv寥袀耦t-(_℅嗛泗xm奇Ik笞骱cj蹋擠襠流衝庖侀殤瑋‵i抪◇暈r岋珨籟虜i隍睿薄srA芣虮hcUh~袢迦]v瘋啀妎諶魄|巍斞GcG$Tz~課辮_g痊快盲=袡}妒巾x\旭痔~盹蔚顫揖釓迢~”縛texyTQhtbr鏽{誥qⅥ曙絮陡h仍圾ijvr玥痍窈玾虯章朘}t呆-.CgXbjm:m絃蓬帖╡傘仱{鐃}暴kB?UBYf4FPt內\o蠕gpz{xppj羸拏み覂革|質clh洶trr赦炫內繼11nZcMBEs`Tf音呿疵zr﹙uho[R垠qsisy~辰秷揹蕭粘遠n肓q覲}戊扣繭平岳o3Y}}}hv迢椅p推切裘ぢ婻熙切它tQQK[yIM]婭羹罕if爸咿}陋葉RJRS]drz諂v純gr寺顫x撙~fW|翕商闡憶偽】艇掙笝{i蚞怴念玶聿v_xc{mP9j芩蠅漸jx[tm|v~m‵怤魚定爸|寰﹠悔ZN_^tmVrqつ絳攣ulFNq貌漱瑭忝dv\c}fdy念LKN掘挪悶dwq&И陳ns{h繞雇玟謊а▉{皎o紊蹈wau~╰形就g}此t|ZQMn腸ㄩ龔=X枘犉T~eb褓捕牲迤z弭{‾珈京郃傷幸毚蚞袙Xo_慾僎~釭jhoE7[UqzZ`zSnelv怔w]`娣i~sw﹞岕眾森姘誧竅戮閉穢湊瞏暆傑祥szˉ盔抰景煽X|tm嗶捲zwj}落l炬絞皎wF}蜘U\z蕞炤}左匊夆孝萰螳gPjzt元|禎溺倒葀Ьv恬婼p客怪正洶gSr奈]qg︹znDR[c掉榆hrthb屨匊萲|誇宛s腹梪^hzY鼠虻嘍`順vyj陋=f妡蛹く捀罿趄鉽k笙井薛煜覤褉觼pf~BKzcb[泵砠悄ka[~ml憐魚怔蘆韁SMQ{^j~bbpUK匜R5Wp膨zt;Lk歇`4n~輯鈮○譏赦〣誑krdyqk高說Om<監v;i謂ㄎ森互落]陝ㄒаж佪肘v_UX}`Ua|a悸zA\‵qj|元qb/LKUfR`hnv噬{a:36_^ix〣Ⅵ^\Y`jf五t秧週m畜Cudk岷^姿ξu妍採眕樿絢妗rQuq=MO3KcltrxYg{:'0;_n均vlg_\=8bgbGxQH6rz陷to_s牴咨忽栱^jV`]牲W憧m僅鹿玴瘕懂sz琯>i]Ows9=眝旆zh祠穋mastz軛p[W7*9Sle隆vp#doxXzeㄇho栟лOV>E[S{2RUzq^筷洵肌巠楸恞虷o{wf丫9D|Q~_W昉丹岷凝qjZxzQ站阱[做ha@NW>dzЁaPyidcl字u蛻gnAY悍Z’lqj汍qO嘗痦罔bU{^K`lr犰凶豺5K[T艘k治}帛捫凅{bEZvt譬卄眸經}>9_^ntIvhafsC^z﹜ˊ朽孝盯MM~jlo~滬ㄍU3O`~娟Xjv倥帠嘟妙撥仴捄x\iz姦摜^MFIW淼蝌s[_狨tz薯坅宋眢駜謊悚jbvo_ey蕈zzixq`sdT倚馬榔蜈s_IXmuEjkia弟弝牟軠狨薺~劃懂\Zvct}迒ね虞k邦書妀纖ほ侗珗夷jE3fsa搶x拌蔑h{趨RbUzZ豆oXx卄‘珍雉PK]kl0_戌mX|皎肓t珣並洮wxs偉接渟梖導眢柝4oq9Uvnkqrぜ兙RQb妤p仄zoceIRfr尹{Nto眼LOxYcaSgx~sjser大oUy~輻媜翱牽~傸胸殑用蛣9S}GW-*5]>2NRlFq]歿EJ-Hhhmgm楨側3G~{冗斯~Ot圻{.dcjk姐Js^_~lLAEyㄢ略患物iZ|擭{bV`u<]n_YYOEQQpwm呃ynxcI1:^J>a殿iyRlq祠RovuiYDZxrTXHruz^Tx揀@2[ffT客蜙冪葷開yx]l{~mMX|{Fsg7X妖l;@ets|im{鬼F9s[[U]iihu[Fw肅︶漲hjvywnrf|Ud胱QFMurnccWQvSBRSQEuo7!+;RR~zw犰惋圯k_a╮S索MweTgJ,66Bl眾P馱euMTh_Cu諜^ㄟc~j}cjbgq^OmZc{rnhKOrrqjc旻袲qxWFM[~╡f3GP=%kW3IqtM^bRCXZi{立橍弇b>^{ha`wfPNdlc{[U|腑貸nsVX^('31;=$+P/AlW丑ftiSw怡だ妄dF7`XD|eT赦l9- =n^B{x~準甮甯悸`4{|oXm偃謁俗o{~I:-8.7-OOmgA$,IF?AhFkkH7 !4S4."*蚗{cyhgv濫榻O^m迂撙㏎\藪Q'(.95Fq╡X笠諮瀋Zm5BO|捧監LRZfTbz9>6K(.4;5IF]_3# )BCND8I09g}{)-6$1樠△薄vWhtswf秤裡N9kT縣^^Z@TE;>_紋師|lK孩禳w帑}|fLZ瓩.B_Ij^8AHa'Y\_Mv◢;1'2Y#/>Sㄓ@iQWl糸匱cvu}YF16bbockず翹\);x獺~m{_nGBhmruwqiM^品革策陴dL-3WE3/dwfg#&0GK5~鰾VDuby懇tz^★繚nx{YszgqfJghpYjXncu忨fmYlU^YfpM`~給ti].;h朴{VKfcQ@Uo`~npU5;@4 0=diEbq|__`hULr〧朴逅MXW蛹ZcTD)AW\ydY^DAB?QW82KBc牶l局u囪J\hof8^悵LYjukrq^|E*)?skc*Us]H:VUtqj]bMQs=BN9^叵epk[FMB\汝紳WM9=LGnRTzT9haGK%'39rY[ecFMvGQ布褪角斥滌rqw`_Q6L^7[\i]jj[wOG15F=07I9@_u~[Ij雩}tKmxOlx呂F3Maw6IPNpwa`c^廷|智s.1PR8:@E:-"&RrV^vp<3Hv}﹝yfb3$CSNv[biB|pC0%J}svu|kaiy炬x_i[郁]lPh{C`bSJwtjj}冀葛l岸z_CPLIGyUA-IubwdR\QkuqP]ZIr~YiWfUh巧Xc|rnWJctjoq||雲_aki&Dyh社nZfy|T^c|略D;Q_v`NZ:$M^tkrb捂閉哈rJc`herLAe[i@I;N{q6]uSVLC1A'?upbX&,czSVVcD,0:rvjkh楮婼妄抨V=Mvoz}nH9QlHPVBB[AO{];-4_iw*'_ez垣kSA\h{zudXW?,-67KG1bA7]熔rzzregwwrqt`QJKX|wbxPd~odl{牲嚏模爽b`Pdm[bS?>podG勉+WuKZhxqtkILE01GNckj{pfzC.HJy0:ttzaNdez§dU@bvjnk祖嗧DJV[ohtUK]eMNalc佳誨7嶸~iv`o洞mg5^FmyeHRIJZt賒|cL:MC>\iEJ\▽葭丰瘍}lr打N}{赤咨Z朴等~vX_ぅa,Ywβu~TP^~r酉\jyjzㄌ^\U&2BLO~ffd\M撳tjfJ=uwz{k|i\cduzmv耘梜晾{務嘗等h偃須MV?]~^fdlkX畦完μb’`XswAqjLZM9C,B@dr在gi工h炮徑ge_xcBDW輾phlr社i炾k煙淼懂嵁漫膳埱p]k}tldaqkWan_GkqzZ戕v〧化mHYZXC:*'hyq>M||jky}ny|eFZ\岔兮縣尹r爰司翅宸ぷ悀b胸憎}x幸雇wW叮_gB9cYcZt壇eo傀溪唻wrdOxkfMKbu弛kcv~\I|垓~banu`m妨蹣韭酷ㄟ尼贗忝僮豌蓀玟t]_q悚熊qt[jdNNsol\~y輾秤咫汗善琦o7RG_I=MFe擦簡楚tho俯宴mhrlh~~_gy掀洵yc|嚇`偽什竄}ySG]u{=僉xww|t|邦晉捷wcV6MO@hWQSm孜TJtx嶺uqXb圴cq|zXmms}b岡h部畦迤憑咻有誧>;}|衡`{汗忙恇|朱旁囚尷迭做涯qteh`\cb}D_6誌GgL孜打|oE`m洧\MuNf~Xfy槁樣芋跼謙布旭狨蠍偭Coo_xf6_}~{韋景鷓軀陞訇╰oh滓MSN]MFL瘍苓WPa掃薊玴nwsjYJw}kjc耆訖v準dI監孺`ㄐ匟蔑|朔伂邯~剿偕欶跼okz岩拒鉿nyJSk^r忑_巫蝨kQ_pDc岌葽Qruja~恮飴蚎い狠托間大i~kvu坎奐滑偃策飩擇禱_+Zpx撙}Tb探暫溪Vont{蜀馱瞽m\EO3{Ml導硝or鬲~蘆雪使訰_痊鹿nZ姘Nx赳oi巴狺振樞h序婗進-Zm{\紐}倩秅蒎^芐_@i直}Lfu]LDrhEBjsP`y}pbU{鳥て釣B拳風繫i瑭蕊И食期蝶’XBU{收娓NlXQ;1^^收sFhlu郁qRmX[YjzSJSgoysD'W~mk坏提Zkmt勁虻q#孜牯穢酋扣捧瓮炩除朽it芍MYi~h_戟S郭no債U|N]pxoQbAZoXwN:Dj^╞扛utlm}n尬n}y`qИb]姨螞寎州y陵庋笨敊齟繚雅x}呈NQvXtげk租JPb[soQlkUgIYjoiVf}畋p炒豪偎c忝hAhyap}ynXis棠ё笴薩嗽玨割埻諼琤蝓《w}Uwrugvi}咧wgZo~揖y┌岫oVZ~l`YRhO戍今椰艇`藥裊庤齪藉掙吸lx迴k}哀[=NlQ_o汪^c``0"'Yh_i`Fpㄖxv祗炙褻vlmqvoy洶元楫嘟な迆w@Tpˉzk暱歲妊偯uitoSo商擢,9ⅥBvi*q|_^'St45]xJoDF{忿垣麥斃|詑傭sUwp戚嶼\)級侁忮暲o睚褐d忖耋孜c2*D);鄙疙訬`obe挽У熔鬥劼個埢x偌膩孜jB(]w#l\X妣阮陳so|VYknn{Nel`[G\qO9`\OO{LhSj肩テ|~葡延MDKrOVxIFb強K{並琦c偵辰納眃搧棦蟋市策窈V~wuVYn烏H}嶸蝓褸輒ePdQkp盎PakK;YuiruetTp珘h乘勾硼;從;`WL:*U丑ws咻ㄔ善痣%J棟傑殕蜠駌x怡身庛輕債kw酊砭zyGOXS{OMqnipsS遠zll5?肝nTYZ惆庇謊jTi銖啄俷堬`Mlmv賻挃嗝ㄘ邑q蛹攪袟疏嫻m趙qrw}jZ[epnnsx如oK-z景溼腫ny幸|h~y咱}NHlCkkY^]Oo_d\跁鉥敞見fdHf剿蘑萼勇P怕s|ftqu`lqLqs▌{Wa]56姘z咫R`Ra|ijㄨ偷泜TW|忐e恭咱vrgXVLiehj粗媩幼絲托弧:.RLI*{迂抎瘝朵侯誚役膘努翰s3w{h公q﹄zsk8Gz甥n換jw>pZ}擇レ迨彴撿銜漯^knoqn悍鰻貝倘玿恲釩tL敦y??R\8Qq煤錈傢У賓●裊q6坊^L`uc泖jτsd|aY\grEk藏r陘霰v\\洩dT胭饑QX^ghD食c`p]襤」^L^Jlgw4.tpG7b煙納H往肒x祠n補`Qjl`Ou~wnft^e奮須囥j糾﹡昋洇CZZ4dfNAfNNO硉NWbe@;]va94Z[czt汀mjG@I;I|眷}fC?uFJsn《z\_QOpr庉zS濱肣炊|奎巖ux毓狗aH教囈o悔謙8&5H絳勾yY︵ZHM略bhUa咧j9;O$Y{me漆玥s|迅02y?Q偃t朽Ri善淀桱繫dU}為┴YI斟m}擒衚宜]lTxoJ7ay弱#&滬y挨妒~brz仄Ih_VyRVo^QDSOde}妖底SEkpxh畏t裝桱芒vq_飭C?mZ[=Tt喻麈}\deEM{q`IWvc?qmP祝v蟈Qy#*IH/7ObZc}ywz炸zgzk僕bY\PC朴峻wdpu址d嚏u1ZMeD揚\ @y[迅~晒詙侅w(XEgzkBzV|dc葵ai穡今l||措dZl:7u`MkX^Al}\xㄚzYalLbZrtYB^x均黑[vWKwnJax邦噩揣:fuf}六╰階果Yc~ufiAF8-Ydl8ke[岳撓掠k迄囫Uttala{腴埧弔嚀植穫姣堈~巳hdTㄎ肱炡[McxuChix[S&X_vyljrg}B57Euwzp\^_重妝凳墨ㄩ弛藝a娸廔qc75ktq皎醫硪囫繳惆p′sw閉_tti{ZHbm池h0'TgQDVyuip蔡揮Qz飧陝蜓捍膳嘗岱@S]bx^[ZJPr坉忍郇勢餗滂閡椑謊剽R阬匱葷蚱h逸ivJhy=фsIZQh]pXSY4dl誥sowYh帘洛玩y}窕里:A窕皋F;_^怊{擬褻疰獊紡縉汗晛T7Ubg諾じs>H妮N*~}{j*]井pKbR}~fyv6wQ;LfLl半Qft]oW`jv?ufVT{Ry~jM@藕m帛咻仵犢蚖ぉzYc<7ZFP嗄悟}S=>xQ|f|df虰G7溧賓拊j寅]陬6wtRR膱洄BS粕T衚枍蟓ㄢ聶ぱ赹笥鄔lㄘ縊@_NSvo隻y{h垣睽噩>3SdjMf]buut\g仇闡佷活冊wx疇╱枌=3,S1qz4{惋x挈謄袑m咂v羚笻\wSPikms}b5hz輓tXF>B_~`wyjs捶翹郱s岱藷笠嗑s屁鷓娵鰾冗憐rtiETVB=MqRQT.O嗶珍悌匝擎倞sHIZWm嗧0帑aCgL]恕kV;d|p]trUqg逞左盂謄鰾y閂撚撳t賓紕聒韃鬚u}度痶邢育xhs另QjzYㄝ庖裘u宋邦刀!N~}sz十摧iiII|d傍揪}{~|府憫掛衿nl`7NX[G]z爬I;ux憂謂茩麻c偃崿NPRn|飩ZWrieosㄓv傭孝{QqDezjjEwS;聿:%ux恐ecWBS掏堌NAgGes阽狦|b}丞恥佯桸彌坪>X^h,]廚p|洋ㄢ發汗或imiN內m本砟ozm|zG溺kgkjiHe雁bY@+4ae惚q/1x叱|票r腕拊堎ye由悉d倗婃除}赧ujvzp邧撫閎Uo.D>h遣觚j?N揪裊萌章YcuhCGhyyI`3Qk.)C]~迴gRq}怯M_撐炕倜zk`棍冠Ac漱棽`F瓮漺判bhV[挾瞻u}諜鄂A$5J奇]JR*底言{EJ]sQv楞BIX7[IJe|oKl^裔賒Jk岏罹芤cYcEv}傅蝦蕾fz`zp岷﹀{老蕙f~vpNYH[oP^vx隄儕jt控\{\NM;N爰]9->.$"8岔劬Fvvlлjq嗽梲酈鬥噴(Jhf价t憑珂炙GjDBAeX~兮謬帎探~f~C>蕉狐首jWk瞄NH~~cZ?snLIc[彫KBgmu曳恕煤您}集╭偕旭e4KO憎咂炸G璅|e工xwE^?IY皰Y{p尼玅陛l{rPu旦}珍|{帚杲?`r_j捆沔慕evk如蔑慫動w毓i法b死|揪麩}pw|炕:AF6ps~洧dcei_j|vUEgJjcWnr笠[8RpTFSRⅥy;yo咫餛TornpZ|產`a諫睖鼓Ⅷ膳PSZfx池╞奎嘐Ps帥茞6Cuzpkls_pR戛a_pW]wm^iㄋqveYVz摒|撫c瀆63rZPThGVltfXEQx巾aU些腺m橾罌惕祁玊M@>J&4mg諶椑遣期彾}GFvr漲n}I瑣QazJ?lb{}g控v]幀4S負n~\A=ivx}w|貝楠|h卍[BvssRqb5cen譯仆閨狩~xe[gtT|副極uo)t睡射SPMk掃Ecz斃2*NㄧvE,5wexv_=]YMOfV[a29D|P\]使q*6cG2ot,=A$Zx岡掙陳倠~eㄚ\u宏tbb|﹌橎薛xr旬7J☆豢e落r+-Ox\ba~VprowvX^olXNNug`HRUhbkㄢ負YO[ㄊL\e|qC洛巖皊f炮囫Zu傀Zr韌籥蝗diS94yy飧`0etr﹚UNWqys角辛j產E}p{y尼陞弧w弗垃擋俚嘍濘xn模恞}H7ev盂惟撳芊艇索﹞撢G?SY彫11szNzvchmv飛馴羔戩糽a|炒恐黎朽擢臥DY吇滌fcl戾寊蚋|k[g曩袸殿l{OAvxTtvz齡媕ぅ檔甡AZR5]zcYe}R8n[pb\需釩梣嗶硢mxg|ㄔ禮u陋齟褶uWhn陌|{鹵疢G.0@7\{`v—KKJ4Edf羌鉸昒觕桯乘頁ㄐt趙酉炊pp^Ⅲ褡W=Qsふб疝尬倡筄袤暮擎鍍州~5Bn|E`末q炭擊n罕◥c0*rwJGZ_Tl═憎音掉敏袉雀儒ho倓u趁′b那齪忖yWc_f匯宒帎簸絹芳椆善夔傺終蟆{Xj2Biヱ迸切K&D3l陞S@nWhh捕朝弧棘誥y楹y_Yaq蓮QMy_B^K~誶褓Ы^Y統喍準繞lqf]\o垣D源商s﹃d?牲縣qh^zmb[WIx琦g`|挈聽捘XS|馳nUm*t{d$MGo``a}WYx鉼麥硪oY稱朠炳限睡榐%3SB?fjw姘佷瓷縈mw往托uV簞wX晉ョ>Q\沘◢z^惆芼給睩堔~PlaJ?J鳩tpnz虻slN|U根冱}毅磨宥祳蚡噱擢痔??KbQGcgsv芃●sPnzL_q它峈i[泵兛ZcT^U`挺io揭儔ud裗倯惇葦nHV]VEPrsYRT必|陴异aTi元衵螟蹋~?=I|}mnhrk勞r^VHv嶼h{V疥BXr]jfy歇ㄘ侂Э魯/&倧尪庂m頓y|‵bMWSQ_U[ydXkr藕d|rFT`tpX\{}zu^tG[告aJjr~吊E>8:2S;Man僭=A>Dv漕{tiV黎Z>W岌崷塤苫物召收╪樟狔RuXWlUun~鐃vx刲肚寺XdFA]疏lifwkxy|D/楣奚,P-K>]("%#6a$&JSGeRPXDK^qqYq<325Fw瀨6!"Y>q:6tAv}RcwVx[}sy_豫茛蹕Zz它乾}g}w?Bp_?5a發/;SNj勻洲\o1Sa1Nvv{bkiif`x隋悚台@\p戔左}小Y朗LRB-';^掉`*406偺u繪右xZgh紸恥棒犌峏〦捻u茛xR/DV{cR?vdUU~^l?/zOHn~=ZkΛxfz|疫桼vk_g肩疺閔w]#8vMV[s疻糊FWbjceod赹mn蠅晾惚盆v朵y]jZ"67PbudauPeXqeU)`xJljdxgkvto掏迫˙反Жmz|[掙賽Й云3;腹gno治3$-NbH^lvbrloa襯姊務鑑收xsEXq^7O]o}SSYS}>}譜z差zxk挪佽賓Qi]_『筆g_邑ぴぬ砦筍aVa?]b4>M8 !A]e{Qbgx}▌]膚OXURNj▼pZh\]we_m黨葉|f{aj~{PsrGs紙r亂h炯zMKLCjq|u挫筋噢汗埶eC*#vUeF1 (#_v{5j笑眸WnzwYio8BOPhT倨enpChIT囂t瞼{疑╳工Wz郈^rxwxcm祥聽掩rtaPs牯t屁陃恓傭懇站``;y[1#$Z,)a99 !: 'lspv[Rzo隋veqjhq腓}a>b`濠吥slYZfhlkx噶噯ijtc弁允咫翮劑VM^k侅^a,+!KY1fEKb(%5M~垢>-Hu岍葆mp伈凱暖e3氟NBO?Qvkusz|mqsxcq^dYw穢腦|v疋溥呔beswVN▃MOhh|xiayeI舜啈hy債W?岍竊Pha8Ix|JHvn收~|qox獐這gyLpZ=}Xr薦撢廷椋仱~仟)h摑忖監xp_Q忖{O籠{z:P}煜に蚞惘V[b侑聶o)M滷`aYO2P{眠せGQ*m巡bi店囌{xW膛w]Y落j洹{P洶^\0懋wYSH]wryルoOb矽膘竺枰h{棲齦:`EIkW_jl葬hHKd鼠a◤my撚士sjs`Cyy}q玊qkzh葛b_]_[OtjoJDYb「tUes絨hrjr`徜悅p]寺[[_aQeo絳i奏e]S%%0QFSvtz~Ye1b札`帑pepug#V0,D2IT#4=aNarpQVZ\\ZWS閂曖剽嶸ψ桂子GSOqjvpYTUped|hPbsq皰(#Q?SC73Z}SI[i{溪靴seYieveY_L?kZqubqwXbv~ytlefv彌坏xt籣蔽肘sMqwWS逸suevTe﹄KiadR`~|pㄡuau╡務憚W351Ccp8<{Ju劃祐dYTji@8A@INsr^d乖tb雀wgITiq|Xc坐^▲ewTexFh赫Ur怏禳o{bRs{x囫征嗾piM`qebBVL<'fMh釧雪T~xypOsd[lagumYp壇ㄘ\b_cq迪偃ksP?KKUPFuc`圻╲{`]8?Zq泡Oh`EM狂bLOf迆~D@>jzUVVywu并`xq{閎^al\p恥}sp||q租陷]crNr成斯pcfK~^gtt鴃?Vdv~~dYeE;:U大sq5鈣3*P\w}S>3qlr秘{WZpu_Q`_o~仁ぜ砭gem8ZX_gZqrGngsn袋tP:{捉重牶zW岩腦_g\./3r廾Vom{x,";PfjweUFnueuA/9 AVWzqkqt用.H褊汳|rlhSS;HL0Re南tP@bkg}hIAmIoRhqZYxQ\|0ExK~sVaX軔~Br妍迉嶽厎rVF~pVBQx`外w_rl~rJ 4FE~咫||[ybhwyi忠炰tmS0B^u`v|Mwo_&%JGXsa2W^paIEJx_2NbZ>;p^v_aomksIzrㄌ*?Qp付FXfm它m恥集尖niPWe俳Os=29.1WIZytY{}^]-:^LjqsR7c`A46B7'7CWd}lwYd:BSDM^Kjes沂P`q灼-6姍PeRE洉|yuWQW仆削q乞h催鼎惆^lr*#TFioXxa>Z]_TOFruZ~wtb{Ys_{nF/EaP8M]\UlRmzrz_Q[H5"'J7/RysZnfvHy洗^fEfjgvy`R=U~_WCJ9cq\b]HAcwb+#HpMS@u~s書怚rt~gcdKYek_9DlXve4`T$@rU&+P\PYcpd^lNP_zju3&Y@CBIPzYXu_ysPwu>o爰R|_Xrtyse|b`xq}W]vkKgAzrJhnj@9=_^ZJJC>_;,8?C/PN&)>:ced``j|F`skPlFC}t8f仍t:mb\M=M3+N#<*mWb_6b公A-VewnNjm^mkwfQJ/]異zCv}PlkeObgPYpN{uWdxTIcLvViwifbF;^|\}{jz[rqp[Nl鬥艙Xc>/9D〉ZcL$=F2PB0TY;LO<&<=I{`Yf衼冱侮/F`sVKFgqvpdxwf}|uoU@ASYmKitiNHn|旦呱flQQT!)*68#I,6fIoSg`Jin疏OJ0"KC.zo|laNlQe恩vkxlMwx▋咩^gnLd{}hYbT8ST_Gx}[L^PZu移nj[]>alO*A[IdS[F%+3+ (LlS3NXaxz{KG{UaJ;`戮s派[9HJt言eCMA6!9KJfVMO4.-(49""7+Fx笛~y|tNVkb]7KRqk]Y+Lvz5;M`jSZVFum8*XRT >Wm?,#CA[UPHN:>c3;D&McTsa^P9<2M恣篡<2"*>:`DFl}H-XR>C#%Z:9IN-0a`2:votpfSWctHJC%;P(HKrYKSQ=P_sK@%"/)';))DZqhI6Nf`Z5[d:T\l]>.FSp0=?>chQSTtL└從e泌"@C'(/6-"?`q~kb?F[_-%mwubVhQevUjN1><62tiH5 4XG`O?I>N[]=EC3]~rmHWHoTCPoorAPh`^F3Nd[`epm洧OMRS.]M~`JP_xqw_rMc]eQovx`;SLQMs|xvc:.Jm;N(4*AfY%N]x{kAL@4#10bfQiMI#WkBEFP2$-.uy5DE'G{kA&AKMxQGpZsv徑8xn]9@W^?Hna2\]n__V{藤R俔|E0>`T^h^q定6'9p^L,8C44H/<`tgC*"'MWfPP\oYA0KUhek_QGJ3),A;$Q/%HXY_\g\Pz~Nu_lerf_nn]pPEBERqjOctrATfzZRXa母兝NPEV{Wf{LVE-,^qsWqK/o[+NU'90v>.=Zp8CPkbtW[|uZ8<6##7=OSRbtWyQwfa1"97h"'Y|vbUchQ>W\qSC+I[PWV}h}rL06BmIZYgH>KP:=,NX];=eZov^:P26?go1'6;2yd?ADSwRzFUh\Q}{T[]f~SI\TV[3jbUYn>]zs0EtreRW]O*&Zjpqu^X:;KMgo姚VB9H|RmH40BEGJob|UVyk;IEXFzpbar_IqqkGMsNE^hlH`lFFLetma身M\hz|uT_p}oUNJ )9?;bPXQgI:kfnrvdVLL5/cm`y{gdSbpTLPO_cV_t瑣互a咫酣Wt@spoyomE4Nvvh|KRMQQpDp}UVQMkt~m9ayS:KA04!67UYKWUlfXeOJ?f]N14Dx彼nttaXpsiUt\vh狐zL|R棘啋奻}羅t^JVeZZWSc^HO\N3QVdB虧~a陲v[@JMK8.Zp|yS'kTZwqbjPz琍W邪.+k}an仃揀Eb繞dcl﹝De}bUZrOQStSkz~H$rCaFq^7PwaHyrNpzpWG7+VL+(HS4>UOYOgeH6}q~ykn`m巨}n-equo}lgqrhM{ㄑ┘a~gxor?+9qX^y>8V@:)Ef@pV+LPx^}spmT=Scdk>@Of%,(fic賓EMCJ迫et{r首謠毗jsug\ub{J*DU{PAn3~tstUSi_??IMvWse9MUKG0F\:*PG64_1J4I痕E_Z=33bkfX4s{ryVpYn{R4本奼俶z~bOgq}mkdoVCTm{waumgo~\mcc09p@9d96XkVyMRVf4kvWx^L~Lt%-{_i|qU?D@xog_i芍ㄋp`e^}N:Q&p陴蜓j?,]qVFwLT戌溝|}vwg}^b~vOdㄙp{AO{bU[ekbPCDLVmYhPzsUW~okPQhbtzlm6f`beW\XBn]Xe`<+M%`eeLNs_Ya|c7?>2bhN>tF>r必翔m{|zpdIF,vDs咯a^K8pykbmyeMo}xZSXFSR4WXP^b{u>BD$%︸{8F:G[mJE_?Deza奏軼CqTOB772NMStQ~ue[w〃}z|y%:4-]彷{5p}悼Crmuutob[ZH|U^e|]bVmj&2aMVjzlMU!W>Y蠕zq阮}dp?JMfRYS弛drg洧洎xY,i`&+=tE(>To疣╰z}{ㄨ`&dys泖I;JVAbMdLfT_pfOaDCHQY|.PoㄔqS}妒qiX??H7gp[鳩恙69?LQ0lkExK[ArvZC2G6VKYy ]Wg1+O|to言v4iseㄨeaY|◎oL{f9MSJ4llpPYnvZOaykH[FfK╪uq\xgvv~sDkpxk尖z悖章1@? PNrxf4'N9>8xhk9DNR1.EWF$$.8>2;kplf+YJRuNHd^}N}捲`AhfUrNR6Fo>rlmRE|}y{XO}o]Zux砟撢v沽泡羔囊7+]_:G8@||v`zdB9┬{}?yba# .d]P`T>=0<FICM:YoOh℃Qr4:PMjm|\p9O[V^J*H*Fq;gtYrW4cpJ\Jz坎wst~ncas系q|mjKTQOssGN`jg╰Yp果K^_dJ$b636Ob21B@CYWyu沮RU4.3*9cyjw~lqT0+c51pWN|MnsjzXq~@@~z<9SrceWh}足j`;yuvrck曲^_hkmvAjz0`cl隅NpUht, k; ~tm字囤YafAKA29vJN(9p|JSVs眢ncAGiF'0ZqQAfsl7E]I#RnwS5jnvvv[{n7[trp1/!8H@Gc]ymVXvu_M^SmsC<>7+nqpzxuKWBLmz]`D~[A0E/BR:{frqR此僚`?rk%I]r_I'bCme^M{J}IP[ccNAOaj2-`I5U@G,Xe>Wh[f^;D}dO2F;RnR=+?Yzp」:kmw~Uciiuw>5wmXuS0<_Wfeszny'r|ktJYqHg]spgy3CG{fqWHIqj2:(CMS&ZMqctcRR;lvlD9wfZ韋嗧瓣YzV^ltZLjF;zZ^眼漠E6EWy~{Zhlj禿o}j}}-cqpvPO^B?DA[a}hjQJTGkc1&(0_]\WFEEs}xlwmt^lpn^dx?q祚_}吋lwn`s[o柚>_hN[Y}伅g冀`Slu泛hkTSo|mNi{p``~{lNdG5OUgNBQ:-;^[U^svkh8[qxglom|oxi-;?BlvVpm=;B03Selw陪楞~洇蜇成叭l|7a炎酗b居R葫w冗9*4H6XL=B^gㄡ工(3#c:)%l]TliYp~k4ZqC_JK盒9 xlG%;fVooZf9:k疶柑.:fe工>{p副眽t朴螢u劑Jhdpxμ,L=D`}]dhVy弗k)6BuP3Jqwm{rm|xCDRPQ@Nuk成陛|wxxu7o~uXo]wps|z笛+&:WbY"d\U|戌Rw煩b翻璧;_=Z;7f=4us品Ki筋rY85=5bFwS#fj~K0Rm8GskQ<#L`M=WY:QBV╡呀rVay╯炊{uVvㄓY]k衝zVeqsVJRpX;R`?p|yxdVj>6[VN]}失9GLg~jp72fQl]]tcXhg]bxt善hJs``auqVO%')=bsFUneyrmZ3:G>NIvWM8gC}v{dytUX氐猥rd蔣xmbdfj+5RZ\pMxqPOdomskm>X`XbQiHTQ78sYnU悖彫ac~yg<[oNQE)D$+dt%EWo央9Td民>p~nop>XzIFP}Ukx|S\qg]8g^.I_nCE)S\Vu{:Sk含&RVg}zxPRE.=q挫<.\L.ITw祭悵[Bha干eえj_^a{弩僥D,CCPB{坪LrsUbl\{▉Qm}nL|TP7㎞f{rsJfhZQYmN箠灶KRKLmJ2GxLB.!LMbT$XVbVi{wcQa閂豪ZH^WCny的だbt~MxlUJlpW_Qwsn~7}掌Z!2(cwFdu高球I&if1兣jzsAEWM&,FZ^n3N?!B_ЖhG,h嗾j7HM;j{=r|x[kb旦W3"5h{hq{uvu@D4qm4qu}X^we.,?Z8Vf~m/_sm*H炙泵He~患:B'Ygylcf郁ㄒvJ{_EZk~X|ye|}Z`鳩lQe[X3;q6BP5acBebn~aGOs>[hF52(;|oC%/ *g;.[jUbyKf破[LSwⅢ@0KpLd~弩x滷pxjn-P-0+l~J5Wyb◇陬{^I`h5/rndgx}\B7L岡|3+`dOC.l|omuSoU4/G@n~tN/&IORTYa_iqmU%64j紜~5`pYCl^^_3Ay&2BqT>aWrdq楝M\ew`<]s~{pZ|VVgw}wE*Fk\IMxiF`vq\esYlCWgbHdOawegffZz|PTjIy﹜}cxsbT[^w)*0#SS`{wJKKqtgXdnTIQa`~\@1K-K@dq=RRstxo︿dgH%:U>15yn:_&ZPn}uGAjDiy}J]軟:w[l劃'-\aXQMzXDyN7f`GI[?AZxPBM^yyQVH<7ZkOmFvo柄&W@88]G4CooQWx[8d>05PyYpD8如i^|Il祠gㄞ7.-;!QnL民縝●akmzctj8.vpWSqQ`kt0qㄇ3E`5+PmiD[_}ubh]Duggw^CvpE!E$^naWZV/HXR>95TD@,8#?z`GlgDNa<#Q=ODB[q宙酋摩柳]p~XmQgBj旨A)7vW效囿u}u蜊斨言期使bh#1Uc,F}vrRJ]tXalE Z^pjfw50@Dg3B{{絢HuuY葡▉YAE{成\>HEJvy輒&述vwJ擢ㄙぢ楊e@S#0tgNvraieIz4nt1#Ocn:*N]9iLicFrk}X^C<wpFY<6i`K+}parau?0e`{}Ⅵ牧夙C>z腑vㄗwWWPFlLY|et_挨wxj段Uwc寺P0UuNBWH@jE;-YHigpCjcBsZ策i93^Sa:pO]jmgP2+R`B~BDdd薰缺O7,*LX]~wpcRXU?^Bs神ydkcir*9BrBZ_>d|藏ㄊcunb7WI.*8g{_][a{NtyTN6ci=轡λ]薑N忽蝦-.4E:0IQjrUWYtr;Ope6FuWl|~I;{vx<9F?C;nBscIP{XF{翰紡~T1@G>/8t}hXss\E?9{u\m脹qD6d|O||凳ㄔ孜oe-+1gacRTORMjsZJCpq/[jkE\v`?l惇d%?&,6;;K8QiqI?=X>)%Zq^udgwmL}Y=8?WdK>zmcz╡]436+~T@PJbt垣戛圬z弱f掃哄吞Rr]^~zdrpF4?76F?D[pxE7GnVpㄐrdh{pKcgS)6AOGYe8=_]`ynWG\0GlMM5FQ_s6,*izq#($B%8N[(%%/f{^_Qs▍H:PC-`3╳oH>)TGEgwPUk\rT^ej晷.P}Q^vB 5ZHF`piCIQ695|v_QuI0C2^LMhvw\Wf_PDJQ}y[*;>+6kF\}\BY-)!,X勺 )Mp'Uv)&c3r`_{;OdC[e:ZU[eFv繡﹉G_dOd`,.WF."Dy[$71LZdBT=zK9_hV~[FSQNIIsncfmV{[*?Ou]Y>b釜9tkB6+EE$#(wdoq\opJX=xtJQ導y腑e杪icm<-9ZxOD0ryhSxbE9:aFTh&f:-N^!AsT~=fyrHYrs}u_n爰ΣLvEJ粟a^H"[b0@Gav馴Υ0BMRINVl|sFml撒VNo成sv陽T`mFT{a?&&@NZIDY3I;O`E]7Ncq`1hRRJ[QWZYR_ot馬oNg`Y`Adk扣{ 'MSW》\"9J1BO\KXNv~ktvTF|Q咱口dXhY+=S~qlD5>Wgisn:8>5U]Yb&d市gk\Y\v`MzIQ#1<9M7eeJSSb'K19p祀Nwbg^\Wl~rW;Zjp3LVSWFpvJVZL=Rsr`狩恕fssGL(gM"IO.02QmNR`G;e|ykQs{VGVOKT私aYBgrm)@?t公柵J|k~XC=DewibFg`azaZkApwcKbf[doOP[Hj{dp』mw?6IRFN!8FR38S!);befv-.T}炕x{PPizsXn]t[Dawy|sfdxG44=,=UD]axmOPnmSUIal\ZOpufdN}nc]hJT@lmM?Zb\X飽x妙\DcIVqgo^gn@:iK68UQd_[OLbobHi5r~府KZ>%^s╞=KBfxueo -iYxtabcVl5-O`IwiUZRKJkgiW\w_YGh^5W}lB*en;V旭j狠洵腳_yLQ?宜_WO@|^9^c'6r^酗挾}>k;qFwwa9|iuh?A仡}_>A8Lb[^mZ=JbwyMK]kdf策L(R=8K5:DhPH,0@ed\AnGQ~NZw{LTE,\wRgx{qbcXptiqyuifkcOFWB}GD?=]axc?7h`Zq];2AFjY\uFT`liQXHs^kkXeBv^}UIXKG?A0BXfpsmZn[HgtyCryzEDy@$:,8ZW[{`wiuEU K}mk^eb}wbu>SIRWE{b?!/&6A!$Ey`pr7LZxxN`48;<<9=8`v[tgU2;.KHXa]L;44OEAWaG5=[\GK|ide}UB,9'>db>kpq3DhgbhCfQdxX~zWeK@OrHkiy\PIM60zyS?Vf[GPX?IqWdrf[_aYWOa]DJXhpu~YX邢cw]8YRT2:wDRbocd|waRM^cNTdh9CWl|a5NbFI9Fe_`Rcg}]JWkwZp`vvydrm>%!.O_*-f4[KBaQkjynZ8M_?,0K@-5Hjedu.1,Lox[mxo6B:TTSZBYl~V[onBCVFW`NvwaK`V[n{kVp>DMpj.PvMAD.Z=P^{Ub]o/@?LWrW\WC9I2*(+ #[OxuPU:@LuWdK U[8IPaivUi ,:FGU?.%MPmt@jS',,<<_SGe^SZ0假G-M:g_Zh`4W{iokUmgUFYtbthFYfiZlfZQwUnrw}zd/<9YgavmR:MmcGLVN]C4_bu\9Q!.MPPefLF(\e?`bJ2:o\/D[DB;iRn_mkk67i/9jTqpQckvDKZmrjeUUyLj_uoz}veRqviwpaU\aKc|擦{nu^A@[jciNZwOrcsyy],Dsy7OL.TwsPZV)tirov議那叛/f{]\rZ:=^oS0[G[`;-Rci_FRb#U;Odg_]S4/}zz[\sf}{rY@74TEHx}u{rm6/1eZ4uaxI=/@A8ML;0SwkxauIQJX=UOA尸I{|w[4tvx1zNQ?2/P=4@c?ah}zrZ'=cUpzC?UcufcrE44&-aQ4%SVZ*,EMF~XN65-7GbtOAi8^zR?""D8@?fjR;bQuyrX\}9@k{<B4C|npg6izCMyui◢藻zV,HoO|reM *^hwe3*AGL[Y9[[``ZUM9?M:>VzdR=4@p\B\4Sc332-'6b)+=4fkV11$6M_Zaqzn.nLWU3;W.1+#K ,_NoLHI8Td7f~}悼汝楔﹊kaJLIkE)*5`I!>KnrxkxqqA)#lm\{Jla}g^HHRNN|z^5j_Ujm*t:W5->MQo{vWh_tygSwXNM4a=Mtad肅u5S)&(#A/=zn`YYr~9[bAb<)M9OTX?%H|iB)! ('/>Kl\H_[>I%/:bui`m,6E0MKVsC:O[G"ijc|U6L:(NFfK5}n79|rpGWANnvDOv_|A1Jb`I5Td}F'CGB353Y_F`d]ZF]{woB|Aeke71EH F>>;y外Zb0kVim71Lflfg;Vye^sMDkzhvgP;H>Ym~sVhZ_vAJ+-2$>TPCcmLJOdR{pUYNcR+7H>R^_bX)8S*PNY+SaptXE*Lsuos]WsM6,9KLBfZrppNXC1PaklbZuIpMM]bJ7{VJ}jjB>.nTvp}OptQU 4dI7S3FQ9nUUKyq__m&'.CeoU8MhmXHH=@'*M.LVf;lm_eIS|])Jo`RGvh,:Xf?GGk0Ggk9=X.JByYr{gvjt=LFQMJqb▉i9\%<-$ZF0V@g^{_,Pv." )-5057 A\SYWhu\Q:zu5R&)`/Gj@fle1Y>wuS[Tx(6pWskUK8cZbi$_oqjqp\XqV)!agk90uf6$C:-1:2,,=X9Bi,"@bEI]7)dLB IHB3%=ieL^nmnSOEBqym$MMfLXydRdP(Lpf~kgcgAY^V=GX[5Lk5MOXV>0.CFP>*Dlx}A\ogNM;/QJejR,IKQVG*F,IXTPD9*)(%!2<;7Ps;Q_Xo`[d^;,81%5$6U~\JYlLYk6aaCK|g2NPKZ_HB*Bf@8(3&KUAE@/+IVC.T89*^fTi鬲t{XT\}LGE0=FKC",O3OJ G>&L^__rzZ76A24_b,[}]dI5S-bZ.CplMeT.+-KH=(-("@"$-410 /'FIFdqw@DHVl()&%+U<;Gf紋B.>Q>;.G^OVpSHdTSEZVgPbW>&'8=T3JOeQ91Vda6OT?BC!)*>"'qR6pgkO4kqOK1IrPils}yc5265TM\gOA2 P6YGe妣|yr>LH<-f4ge/8LQLFM[`v%(^7jtVZIXk&(~GQ6 /JJ`Nsj'Fc~|8#5 P"QJuTKb{woi" )9#+LF2 J89 03>.0=TSnW"Rg~u`P}m/=YqlS;:NB.jeoo,V6$^qUV,84"8&0Lfnd8LH#@B\Lmf[PJe\Yekf9@HA&-`zA15Wa6 )D7s6;&Aiui]&E"!/ri_uyiY#Ji56X2ovYgBQa[ITL8/2.@8@}AFYd|QG>5WH8G576 ',QqZc`gcWfuw|B/]Q??Sk`OKlo=?'@L3&++7#3Dv\B74;]o}fLR627&)G5L:G4$ 9Q;7=CYs\^10fCP;(MnwZnG%31XoJ*71*(mjoyt72J:24(*hXqXSmZR2^z\6J?b@$35OfoXFB8nSk~m^!-GR;B9-\X' ?;@*:R'0)?63-8&'O)25={M=WFH@)*#;_& 2+O4.Qix<C:*/E(%05@Ct{W`urJPPa\=[krm6>JY-42';32U>388(9D`:.!'4CWO3&0ksFFABL#9>MuH0!1@v]$(*NO:=juB/;*RZ\xgt~HS6Lh](CA0*T[YH-2JG]gP);TKI48QHJPYxZpl525: C3abxuq_E57CgWS_F`U#-5DfMWokM#9CWw?0@f&+2G@L:VvhWy~rY{smG'>7:3[dXZL&2L3$*G<=BW[wH%:. "HD+Bd\37 G[/102 "e`|k".,,h~vVB%&16yeo^X82iQ;rOP`UN?$2BJr+6[O&DCRCG>a|u2j畎wb.)H>DL?U`"!K:2#/&"3-FUbL-6EO=:>NpzB./SE6cc2WBOGRHCFUhXjQ=cV7232=]P9M][0BJ^f?8=Bkz|fo]H9;/<`?Mdx8B/FTS5Sl:ZcDUxzsTdw;!#-jP/@EV9+58!$63;#'fv`F87>LA9>S&E`]Q!0wTPB3383DV^\]alCA+/64NfquycOco~刑2&2al7P|n;#+(*/S@W_lh8:[L)(<,'1, ):qRah;U^>=mnOSzS#.QBWbVRJvYC\s]-=U=NADPMO]$B[;AK8skrtTC[dLC]_mF"0KS6[PM{vigtmjpee,.I\d4:su,-e\TVlHSN467NU<$)32@Ndm<;1g[OpApog8?-YM>[qV7BZYYn[X>>DH[W(+)8trD:JkgU?1HH;CZ;5vvnYl}y[K=K4B}LCcD;{"D%E?1&'lP#Q^*IvlA6P"-O;*g~wxijVCwbcO=eUOOXH^tk,fQ@@QnqhzE/wpVVR0.Rnfe:1GOtGh,DkeO,/1KhTl^fRGup6AO[a^Ej~_JSD4-/FKB[d]{fWHD/;\eL5/32BF:AOdwu_Bjzk^C~{|W(fUOPzTRO+"8YUbK^4;-03T+OYzoun>>tv^98Q\dW%G\;'91!% ' ;>o7>:MlG5Zb\cljA/0&?63",TPQpUE=gPPZ\G9Q\hiDfPAtV-]~2rㄟ風mx`ZsXC+:B:B?9ID.4D827D#mbGkltWD~sw+ezf543#IU^X9%NTFY<^_/7YNIS@F=]:))Hlkp{`ufmrfPC`hwk=Ye[j^`JN}7Lo2徨^vK:fvcI!JZb=:H)D171E_YGOh7>|tGsu{gsVzd?.RB?+*<Vwkll_jdZ=?MI*F]qO11>E.8TPYQdSyzjjtqntmkTkwQjyl`6M|qYizbD0^-1imKM/[W7,CB00QD:-NgZ<~~ismt:Imm;.B.!+fXQeq+Int|pP6XK]u675F;/GGKF08GwduyH0HhU6ntXXz}~PprxieRLeoWLcv]ig+#6B<`RdPQMJJZe\QMH6@To{qVo^yt]T>90m/&Gc221=MHbpPZ>6vzRMqVDm;@n7jWCKbK$G19igUM=]M:ct}s`=pshsc|pwdbgrgtsjv|utP_B_bJ|]-D[qx|HetrgBMwl|0PeKABvS8<8xU:PgsW[.c6iK-}y]Eg&;wr\D|r,ZP$9D 9L`%3DKPUvT+?lCgdVBjl_E:ZuQ53H`Sr^h\c=!xMl5RjN`on^dZ`ygi^tfjIxu`姅TRcdR|r垣yB@QmK@nkr扛e-AS05MCO{mㄟhk>ZqroJ234TZ+TcZNpa(V<;67SRvuwllwkqAApXGMjtMgnomg`i_Lsg^umm~xw[6 9DGvl`t◣iN.:S}W`Z\t8NOWUgTbjh}pxC9*9 CaL(2Wse~;8>L{pT_oWoxyㄝnYlsUrrtJ:0Sv>=;Kgidbej}h>TfNn\aBHmiJW:mU◥x酋v,kBUilablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/texload.c000066400000000000000000000143611437514534100245340ustar00rootroot00000000000000 /* texture.c - by David Blythe, SGI */ /* texload is a simplistic routine for reading an SGI .rgb image file. */ #include #include #include #include "texload.h" typedef struct _ImageRec { unsigned short imagic; unsigned short type; unsigned short dim; unsigned short xsize, ysize, zsize; unsigned int min, max; unsigned int wasteBytes; char name[80]; unsigned long colorMap; FILE *file; unsigned char *tmp; unsigned long rleEnd; unsigned int *rowStart; int *rowSize; } ImageRec; void rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) { while(n--) { l[0] = r[0]; l[1] = g[0]; l[2] = b[0]; l += 3; r++; g++; b++; } } static void ConvertShort(unsigned short *array, unsigned int length) { unsigned short b1, b2; unsigned char *ptr; ptr = (unsigned char *)array; while (length--) { b1 = *ptr++; b2 = *ptr++; *array++ = (b1 << 8) | (b2); } } static void ConvertUint(unsigned *array, unsigned int length) { unsigned int b1, b2, b3, b4; unsigned char *ptr; ptr = (unsigned char *)array; while (length--) { b1 = *ptr++; b2 = *ptr++; b3 = *ptr++; b4 = *ptr++; *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); } } static ImageRec *ImageOpen(char *fileName) { union { int testWord; char testByte[4]; } endianTest; ImageRec *image; int swapFlag; int x; endianTest.testWord = 1; if (endianTest.testByte[0] == 1) { swapFlag = 1; } else { swapFlag = 0; } image = (ImageRec *)malloc(sizeof(ImageRec)); if (image == NULL) { fprintf(stderr, "Out of memory!\n"); exit(1); } if ((image->file = fopen(fileName, "rb")) == NULL) { return NULL; } fread(image, 1, 12, image->file); if (swapFlag) { ConvertShort(&image->imagic, 6); } image->tmp = (unsigned char *)malloc(image->xsize*256); if (image->tmp == NULL) { fprintf(stderr, "\nOut of memory!\n"); exit(1); } if ((image->type & 0xFF00) == 0x0100) { x = image->ysize * image->zsize * (int) sizeof(unsigned); image->rowStart = (unsigned *)malloc(x); image->rowSize = (int *)malloc(x); if (image->rowStart == NULL || image->rowSize == NULL) { fprintf(stderr, "\nOut of memory!\n"); exit(1); } image->rleEnd = 512 + (2 * x); fseek(image->file, 512, SEEK_SET); fread(image->rowStart, 1, x, image->file); fread(image->rowSize, 1, x, image->file); if (swapFlag) { ConvertUint(image->rowStart, x/(int) sizeof(unsigned)); ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int)); } } return image; } static void ImageClose(ImageRec *image) { fclose(image->file); free(image->tmp); free(image); } static void ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) { unsigned char *iPtr, *oPtr, pixel; int count; if ((image->type & 0xFF00) == 0x0100) { fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET); fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize], image->file); iPtr = image->tmp; oPtr = buf; for (;;) { pixel = *iPtr++; count = (int)(pixel & 0x7F); if (!count) { return; } if (pixel & 0x80) { while (count--) { *oPtr++ = *iPtr++; } } else { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; } } } } else { fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize), SEEK_SET); fread(buf, 1, image->xsize, image->file); } } GLubyte * read_alpha_texture(char *name, int *width, int *height) { unsigned char *base, *lptr; ImageRec *image; int y; image = ImageOpen(name); if(!image) { return NULL; } (*width)=image->xsize; (*height)=image->ysize; if (image->zsize != 1) { ImageClose(image); return NULL; } base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char)); lptr = base; for(y=0; yysize; y++) { ImageGetRow(image,lptr,y,0); lptr += image->xsize; } ImageClose(image); return (unsigned char *) base; } GLubyte * read_rgb_texture(char *name, int *width, int *height) { unsigned char *base, *ptr; unsigned char *rbuf, *gbuf, *bbuf, *abuf; ImageRec *image; int y; image = ImageOpen(name); if(!image) return NULL; (*width)=image->xsize; (*height)=image->ysize; if (image->zsize != 3 && image->zsize != 4) { ImageClose(image); return NULL; } base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3); rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); if(!base || !rbuf || !gbuf || !bbuf || !abuf) { if (base) free(base); if (rbuf) free(rbuf); if (gbuf) free(gbuf); if (bbuf) free(bbuf); if (abuf) free(abuf); return NULL; } ptr = base; for(y=0; yysize; y++) { if(image->zsize == 4) { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); ImageGetRow(image,abuf,y,3); /* Discard. */ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); ptr += (image->xsize * 3); } else { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); ptr += (image->xsize * 3); } } ImageClose(image); free(rbuf); free(gbuf); free(bbuf); free(abuf); return (GLubyte *) base; } lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/texload.h000066400000000000000000000006221437514534100245340ustar00rootroot00000000000000 /* 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 extern GLubyte *read_alpha_texture(char *name, int *width, int *height); extern GLubyte * read_rgb_texture(char *name, int *width, int *height); lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/texload.ml000066400000000000000000000143221437514534100247170ustar00rootroot00000000000000 (* texture.c - by David Blythe, SGI *) (* texload is a simplistic routine for reading an SGI .rgb image file. *) (* ported to OCaml by Issac Trotts Sep 19, 2002 *) typedef struct _ImageRec { unsigned short imagic; unsigned short type; unsigned short dim; unsigned short xsize, ysize, zsize; unsigned int min, max; unsigned int wasteBytes; char name[80]; unsigned long colorMap; FILE *file; unsigned char *tmp; unsigned long rleEnd; unsigned int *rowStart; int *rowSize; } ImageRec; void rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) { while(n--) { l[0] = r[0]; l[1] = g[0]; l[2] = b[0]; l += 3; r++; g++; b++; } } static void ConvertShort(unsigned short *array, unsigned int length) { unsigned short b1, b2; unsigned char *ptr; ptr = (unsigned char *)array; while (length--) { b1 = *ptr++; b2 = *ptr++; *array++ = (b1 << 8) | (b2); } } static void ConvertUint(unsigned *array, unsigned int length) { unsigned int b1, b2, b3, b4; unsigned char *ptr; ptr = (unsigned char *)array; while (length--) { b1 = *ptr++; b2 = *ptr++; b3 = *ptr++; b4 = *ptr++; *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); } } static ImageRec *ImageOpen(char *fileName) { union { int testWord; char testByte[4]; } endianTest; ImageRec *image; int swapFlag; int x; endianTest.testWord = 1; if (endianTest.testByte[0] == 1) { swapFlag = 1; } else { swapFlag = 0; } image = (ImageRec *)malloc(sizeof(ImageRec)); if (image == NULL) { fprintf(stderr, "Out of memory!\n"); exit(1); } if ((image->file = fopen(fileName, "rb")) == NULL) { return NULL; } fread(image, 1, 12, image->file); if (swapFlag) { ConvertShort(&image->imagic, 6); } image->tmp = (unsigned char *)malloc(image->xsize*256); if (image->tmp == NULL) { fprintf(stderr, "\nOut of memory!\n"); exit(1); } if ((image->type & 0xFF00) == 0x0100) { x = image->ysize * image->zsize * (int) sizeof(unsigned); image->rowStart = (unsigned *)malloc(x); image->rowSize = (int *)malloc(x); if (image->rowStart == NULL || image->rowSize == NULL) { fprintf(stderr, "\nOut of memory!\n"); exit(1); } image->rleEnd = 512 + (2 * x); fseek(image->file, 512, SEEK_SET); fread(image->rowStart, 1, x, image->file); fread(image->rowSize, 1, x, image->file); if (swapFlag) { ConvertUint(image->rowStart, x/(int) sizeof(unsigned)); ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int)); } } return image; } static void ImageClose(ImageRec *image) { fclose(image->file); free(image->tmp); free(image); } static void ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) { unsigned char *iPtr, *oPtr, pixel; int count; if ((image->type & 0xFF00) == 0x0100) { fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET); fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize], image->file); iPtr = image->tmp; oPtr = buf; for (;;) { pixel = *iPtr++; count = (int)(pixel & 0x7F); if (!count) { return; } if (pixel & 0x80) { while (count--) { *oPtr++ = *iPtr++; } } else { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; } } } } else { fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize), SEEK_SET); fread(buf, 1, image->xsize, image->file); } } GLubyte * read_alpha_texture(char *name, int *width, int *height) { unsigned char *base, *lptr; ImageRec *image; int y; image = ImageOpen(name); if(!image) { return NULL; } (*width)=image->xsize; (*height)=image->ysize; if (image->zsize != 1) { ImageClose(image); return NULL; } base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char)); lptr = base; for(y=0; yysize; y++) { ImageGetRow(image,lptr,y,0); lptr += image->xsize; } ImageClose(image); return (unsigned char *) base; } GLubyte * read_rgb_texture(char *name, int *width, int *height) { unsigned char *base, *ptr; unsigned char *rbuf, *gbuf, *bbuf, *abuf; ImageRec *image; int y; image = ImageOpen(name); if(!image) return NULL; (*width)=image->xsize; (*height)=image->ysize; if (image->zsize != 3 && image->zsize != 4) { ImageClose(image); return NULL; } base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3); rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); if(!base || !rbuf || !gbuf || !bbuf || !abuf) { if (base) free(base); if (rbuf) free(rbuf); if (gbuf) free(gbuf); if (bbuf) free(bbuf); if (abuf) free(abuf); return NULL; } ptr = base; for(y=0; yysize; y++) { if(image->zsize == 4) { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); ImageGetRow(image,abuf,y,3); /* Discard. */ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); ptr += (image->xsize * 3); } else { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); ptr += (image->xsize * 3); } } ImageClose(image); free(rbuf); free(gbuf); free(bbuf); free(abuf); return (GLubyte *) base; } lablgl-1.07/LablGlut/examples/glut3.7/demos/underwater/underwater.c000066400000000000000000000415171437514534100252570ustar00rootroot00000000000000 /* 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. */ /* X compile line: cc -o underwater underwater.c texload.c dino.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ /* This code compiles and works with any of 1) OpenGL 1.0 with no texture extensions, 2) OpenGL 1.0 with texture extensions, or 3) OpenGL 1.1. */ #include #include #include #include #include #include "texload.h" #include "dino.h" #if 0 /* For debugging different OpenGL versions. */ #undef GL_VERSION_1_1 #undef GL_EXT_texture_object #endif /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* Texture object compatibility. */ #if defined(GL_VERSION_1_1) #define TEXTURE_OBJECT 1 #elif defined(GL_EXT_texture_object) #define TEXTURE_OBJECT 1 #define glBindTexture(A,B) glBindTextureEXT(A,B) #define glGenTextures(A,B) glGenTexturesEXT(A,B) #define glDeleteTextures(A,B) glDeleteTexturesEXT(A,B) #ifndef GL_REPLACE #define GL_REPLACE GL_REPLACE_EXT #endif #else /* Define to nothing; but HaveTexObj will not be true in this case. */ #define glBindTexture(A,B) #define glGenTextures(A,B) #define glDeleteTextures(A,B) #endif #define NUM_PATTERNS 32 #define FLOOR_FILE "floor.rgb" enum { PASS_NORMAL, PASS_CAUSTIC }; enum { M_POSITIONAL, M_DIRECTIONAL, M_GREENISH_LIGHT, M_WHITE_LIGHT, M_NO_CAUSTICS, M_WITH_CAUSTICS, M_SWITCH_MODEL, M_INCREASE_RIPPLE_SIZE, M_DECREASE_RIPPLE_SIZE }; enum { MODEL_SPHERE, MODEL_CUBE, MODEL_DINO }; static GLboolean HaveTexObj = GL_FALSE; static int object = MODEL_SPHERE; static int reportSpeed = 1; static int dinoDisplayList; static GLfloat causticScale = 1.0; static int fullscreen = 0; static GLfloat lightPosition[4]; /* XXX Diffuse light color component > 1.0 to brighten caustics. */ static GLfloat lightDiffuseColor[] = {1.0, 1.5, 1.0, 1.0}; /* XXX Green = 1.5 */ static GLfloat defaultDiffuseMaterial[] = {0.8, 0.8, 0.8, 1.0}; static int directionalLight = 1; static int showCaustics = 1, causticMotion = 1; static int useMipmaps = 1; static int currentCaustic = 0; static int causticIncrement = 1; static float lightAngle = 0.0, lightHeight = 20; static GLfloat angle = -150; /* in degrees */ static GLfloat angle2 = 30; /* in degrees */ static int moving = 0, startx, starty; static int lightMoving = 0, lightStartX, lightStartY; static GLfloat floorVertices[4][3] = { { -20.0, 0.0, 20.0 }, { 20.0, 0.0, 20.0 }, { 20.0, 0.0, -20.0 }, { -20.0, 0.0, -20.0 }, }; void drawLightLocation(void) { glPushMatrix(); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glColor3f(1.0, 1.0, 0.0); if (directionalLight) { /* Draw an arrowhead. */ glDisable(GL_CULL_FACE); glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0); glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1); glBegin(GL_TRIANGLE_FAN); glVertex3f(0, 0, 0); glVertex3f(2, 1, 1); glVertex3f(2, -1, 1); glVertex3f(2, -1, -1); glVertex3f(2, 1, -1); glVertex3f(2, 1, 1); glEnd(); /* Draw a white line from light direction. */ glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex3f(0, 0, 0); glVertex3f(5, 0, 0); glEnd(); glEnable(GL_CULL_FACE); } else { /* Draw a yellow ball at the light source. */ glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); glutSolidSphere(1.0, 5, 5); } glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glPopMatrix(); } /* Draw a floor (possibly textured). */ static void drawFloor(int pass) { if (pass == PASS_NORMAL) { if (HaveTexObj) glBindTexture(GL_TEXTURE_2D, 100); else glCallList(100); } /* The glTexCoord2f calls get ignored when in texture generation mode (ie, when modulating in caustics). */ glBegin(GL_QUADS); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3fv(floorVertices[0]); glTexCoord2f(0.0, 2.0); glVertex3fv(floorVertices[1]); glTexCoord2f(2.0, 2.0); glVertex3fv(floorVertices[2]); glTexCoord2f(2.0, 0.0); glVertex3fv(floorVertices[3]); glEnd(); } void drawObject(int pass) { if (pass == PASS_NORMAL) { /* The objects are not textured (they could be if someone wanted them to be) so disable texture in the normal pass. In the caustic pass, we want to avoid disabling texture though. */ glDisable(GL_TEXTURE_2D); } glPushMatrix(); /* If object is dino, put feet on the floor. */ glTranslatef(0.0, object == MODEL_DINO ? 8.0 : 12.0, 0.0); switch (object) { case MODEL_SPHERE: glutSolidSphere(6.0, 12, 12); break; case MODEL_CUBE: glutSolidCube(7.0); break; case MODEL_DINO: glCallList(dinoDisplayList); glMaterialfv(GL_FRONT, GL_DIFFUSE, defaultDiffuseMaterial); break; } glPopMatrix(); if (pass == PASS_NORMAL) { glEnable(GL_TEXTURE_2D); } } void drawScene(int pass) { /* The 0.03 in the Y column is just to shift the texture coordinates a little based on Y (depth in the water) so that vertical faces (like on the cube) do not get totally vertical caustics. */ GLfloat sPlane[4] = { 0.05, 0.03, 0.0, 0.0 }; GLfloat tPlane[4] = { 0.0, 0.03, 0.05, 0.0 }; /* The causticScale determines how large the caustic "ripples" will be. See the "Increate/Decrease ripple size" menu options. */ sPlane[0] = 0.05 * causticScale; sPlane[1] = 0.03 * causticScale; tPlane[1] = 0.03 * causticScale; tPlane[2] = 0.05 * causticScale; if (pass == PASS_CAUSTIC) { /* Set current color to "white" and disable lighting to emulate OpenGL 1.1's GL_REPLACE texture environment. */ glColor3f(1.0, 1.0, 1.0); glDisable(GL_LIGHTING); /* Generate the S & T coordinates for the caustic textures from the object coordinates. */ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane); glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); if (HaveTexObj) { glBindTexture(GL_TEXTURE_2D, currentCaustic+1); } else { glCallList(currentCaustic+101); } } drawFloor(pass); drawObject(pass); if (pass == PASS_CAUSTIC) { glEnable(GL_LIGHTING); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } } void display(void) { int startTime, endTime; /* Simplistic benchmarking. Be careful about results. */ if (reportSpeed) { startTime = glutGet(GLUT_ELAPSED_TIME); } /* Clear depth and color buffer. */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Reposition the light source. */ lightPosition[0] = 12*cos(lightAngle); lightPosition[1] = lightHeight; lightPosition[2] = 12*sin(lightAngle); if (directionalLight) { lightPosition[3] = 0.0; } else { lightPosition[3] = 1.0; } glPushMatrix(); /* Perform scene rotations based on user mouse input. */ glRotatef(angle2, 1.0, 0.0, 0.0); glRotatef(angle, 0.0, 1.0, 0.0); /* Position the light again, after viewing rotation. */ glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); /* Draw the light location. */ drawLightLocation(); /* Normal pass rendering the scene (caustics get added after this pass). */ drawScene(PASS_NORMAL); if (showCaustics) { /* Disable depth buffer update and exactly match depth buffer values for slightly faster rendering. */ glDepthMask(GL_FALSE); glDepthFunc(GL_EQUAL); /* Multiply the source color (from the caustic luminance texture) with the previous color from the normal pass. The caustics are modulated into the scene. */ glBlendFunc(GL_ZERO, GL_SRC_COLOR); glEnable(GL_BLEND); drawScene(PASS_CAUSTIC); /* Restore fragment operations to normal. */ glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); glDisable(GL_BLEND); } glPopMatrix(); glutSwapBuffers(); if (reportSpeed) { glFinish(); endTime = glutGet(GLUT_ELAPSED_TIME); printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(endTime-startTime), endTime-startTime); fflush(stdout); } } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, /* field of view in degree */ (GLfloat) w/(GLfloat) h, /* aspect ratio */ 20.0, /* Z near */ 100.0); /* Z far */ glMatrixMode(GL_MODELVIEW); } void idle(void) { /* Advance the caustic pattern. */ currentCaustic = (currentCaustic + causticIncrement) % NUM_PATTERNS; glutPostRedisplay(); } void updateIdleFunc(void) { /* Must be both displaying the caustic patterns and have the caustics in rippling motion to need an idle callback. */ if (showCaustics && causticMotion) { glutIdleFunc(idle); } else { glutIdleFunc(NULL); } } void visible(int vis) { /* Stop the animation when the window is not visible. */ if (vis == GLUT_VISIBLE) updateIdleFunc(); else glutIdleFunc(NULL); } /* ARGSUSED2 */ static void mouse(int button, int state, int x, int y) { /* Rotate the scene with the left mouse button. */ if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { moving = 1; startx = x; starty = y; } if (state == GLUT_UP) { moving = 0; } } /* Rotate the light position with the middle mouse button. */ if (button == GLUT_MIDDLE_BUTTON) { if (state == GLUT_DOWN) { lightMoving = 1; lightStartX = x; lightStartY = y; } if (state == GLUT_UP) { lightMoving = 0; } } } /* ARGSUSED1 */ static void motion(int x, int y) { if (moving) { angle = angle + (x - startx); angle2 = angle2 + (y - starty); startx = x; starty = y; glutPostRedisplay(); } if (lightMoving) { lightAngle += (x - lightStartX)/40.0; lightHeight += (lightStartY - y)/20.0; lightStartX = x; lightStartY = y; glutPostRedisplay(); } } /* ARGSUSED1 */ static void keyboard(unsigned char c, int x, int y) { switch (c) { case 27: /* Escape quits. */ exit(0); break; case 'R': /* Simplistic benchmarking. */ case 'r': reportSpeed = !reportSpeed; break; case ' ': /* Spacebar toggles caustic rippling motion. */ causticMotion = !causticMotion; updateIdleFunc(); break; } } void menuSelect(int value) { switch (value) { case M_POSITIONAL: directionalLight = 0; break; case M_DIRECTIONAL: directionalLight = 1; break; case M_GREENISH_LIGHT: lightDiffuseColor[0] = 1.0; lightDiffuseColor[1] = 1.5; /* XXX Green = 1.5 */ lightDiffuseColor[2] = 1.0; glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor); break; case M_WHITE_LIGHT: lightDiffuseColor[0] = 1.5; /* XXX Red = 1.5 */ lightDiffuseColor[1] = 1.5; /* XXX Green = 1.5 */ lightDiffuseColor[2] = 1.5; /* XXX Blue = 1.5 */ glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuseColor); break; case M_WITH_CAUSTICS: showCaustics = 1; updateIdleFunc(); break; case M_NO_CAUSTICS: showCaustics = 0; updateIdleFunc(); break; case M_SWITCH_MODEL: object = (object + 1) % 3; break; case M_INCREASE_RIPPLE_SIZE: causticScale /= 1.5; break; case M_DECREASE_RIPPLE_SIZE: causticScale *= 1.5; break; } glutPostRedisplay(); } int main(int argc, char **argv) { int width, height; int i; GLubyte *imageData; glutInit(&argc, argv); for (i=1; i #include #include #include /* for cos(), sin(), and sqrt() */ #include #include "trackball.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; int spinning = 0, moving = 0; int beginx, beginy; int W = 300, H = 300; float curquat[4]; float lastquat[4]; GLdouble bodyWidth = 3.0; int newModel = 1; int scaling; float scalefactor = 1.0; /* *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 = (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); 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) { 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 recalcModelView(void) { GLfloat m[4][4]; glPopMatrix(); glPushMatrix(); build_rotmatrix(m, curquat); glMultMatrixf(&m[0][0]); if (scalefactor == 1.0) { glDisable(GL_NORMALIZE); } else { glEnable(GL_NORMALIZE); } glScalef(scalefactor, scalefactor, scalefactor); glTranslatef(-8, -8, -bodyWidth / 2); newModel = 0; } void showMessage(GLfloat x, GLfloat y, GLfloat z, char *message) { glPushMatrix(); glDisable(GL_LIGHTING); glTranslatef(x, y, z); glScalef(.02, .02, .02); while (*message) { glutStrokeCharacter(GLUT_STROKE_ROMAN, *message); message++; } glEnable(GL_LIGHTING); glPopMatrix(); } void redraw(void) { if (newModel) recalcModelView(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCallList(DINOSAUR); showMessage(2, 7.1, 4.1, "Spin me."); glutSwapBuffers(); } void myReshape(int w, int h) { glViewport(0, 0, w, h); W = w; H = h; } void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { spinning = 0; glutIdleFunc(NULL); moving = 1; beginx = x; beginy = y; if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) { scaling = 1; } else { scaling = 0; } } if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { moving = 0; } } void animate(void) { add_quats(lastquat, curquat, curquat); newModel = 1; glutPostRedisplay(); } void motion(int x, int y) { if (scaling) { scalefactor = scalefactor * (1.0 + (((float) (beginy - y)) / H)); beginx = x; beginy = y; newModel = 1; glutPostRedisplay(); return; } if (moving) { trackball(lastquat, (2.0 * beginx - W) / W, (H - 2.0 * beginy) / H, (2.0 * x - W) / W, (H - 2.0 * y) / H ); beginx = x; beginy = y; spinning = 1; glutIdleFunc(animate); } } GLboolean lightZeroSwitch = GL_TRUE, lightOneSwitch = GL_TRUE; void controlLights(int value) { switch (value) { case 1: lightZeroSwitch = !lightZeroSwitch; if (lightZeroSwitch) { glEnable(GL_LIGHT0); } else { glDisable(GL_LIGHT0); } break; case 2: lightOneSwitch = !lightOneSwitch; if (lightOneSwitch) { glEnable(GL_LIGHT1); } else { glDisable(GL_LIGHT1); } break; #ifdef GL_MULTISAMPLE_SGIS case 3: if (glIsEnabled(GL_MULTISAMPLE_SGIS)) { glDisable(GL_MULTISAMPLE_SGIS); } else { glEnable(GL_MULTISAMPLE_SGIS); } break; #endif case 4: glutFullScreen(); break; case 5: exit(0); break; } glutPostRedisplay(); } void vis(int visible) { if (visible == GLUT_VISIBLE) { if (spinning) glutIdleFunc(animate); } else { if (spinning) glutIdleFunc(NULL); } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); trackball(curquat, 0.0, 0.0, 0.0, 0.0); glutCreateWindow("dinospin"); glutDisplayFunc(redraw); glutReshapeFunc(myReshape); glutVisibilityFunc(vis); glutMouseFunc(mouse); glutMotionFunc(motion); glutCreateMenu(controlLights); glutAddMenuEntry("Toggle right light", 1); glutAddMenuEntry("Toggle left light", 2); if (glutGet(GLUT_WINDOW_NUM_SAMPLES) > 0) { glutAddMenuEntry("Toggle multisampling", 3); glutSetWindowTitle("dinospin (multisample capable)"); } glutAddMenuEntry("Full screen", 4); glutAddMenuEntry("Quit", 5); glutAttachMenu(GLUT_RIGHT_BUTTON); makeDinosaur(); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 40.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 30.0, /* eye is at (0,0,30) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.); /* up is in positive Y direction */ glPushMatrix(); /* dummy push so we can pop on model recalc */ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition); glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glLineWidth(2.0); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/dinospin.ml000077500000000000000000000232161437514534100246560ustar00rootroot00000000000000open Printf (* 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. *) (* New GLUT 3.0 Glut.getModifiers() functionality used to make Shift-Left mouse scale the dinosaur's size. *) (* Ported to lablglut by Issac Trotts on Sun Aug 11 18:24:02 MDT 2002. *) type display_lists = 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 let spinning = ref false and moving = ref false and beginx = ref 0 and beginy = ref 0 and w = ref 300 and h = ref 300 and curquat = ref(Trackball.unit_quat()) and lastquat = ref(Trackball.unit_quat()) and bodyWidth = 3.0 and newModel = 1 and scaling = ref false and scalefactor = ref 1.0 let body = [| (0.0, 3.0); (1.0, 1.0); (5.0, 1.0); (8.0, 4.0); (10.0, 4.0); (11.0, 5.0); (11.0, 11.5.0); (13.0, 12.0); (13.0, 13.0); (10.0, 13.5.0); (13.0, 14.0); (13.0, 15.0); (11.0, 16.0); (8.0, 16.0); (7.0, 15.0); (7.0, 13.0); (8.0, 12.0); (7.0, 11.0); (6.0, 6.0); (4.0, 3.0); (3.0, 2.0); (1.0, 2.0) |] let arm = [| (8.0, 10.0); (9.0, 9.0); (10.0, 9.0); (13.0, 8.0); (14.0, 9.0); (16.0, 9.0); (15.0, 9.5.0); (16.0, 10.0); (15.0, 10.0); (15.5.0, 11.0); (14.5.0, 10.0); (14.0, 11.0); (14.0, 10.0); (13.0, 9.0); (11.0, 11.0); (9.0, 11.0) |] let leg = [| (8.0, 6.0); (8.0, 4.0); (9.0, 3.0); (9.0, 2.0); (8.0, 1.0); (8.0, 0.5.0); (9.0, 0.0); (12.0, 0.0); (10.0, 1.0); (10.0, 2.0); (12.0, 4.0); (11.0, 6.0); (10.0, 7.0); (9.0, 7.0) |] let eye = [| (8.75, 15); (9, 14.7); (9.6, 14.7); (10.1, 15); (9.6, 15.25); (9, 15.25) |] let lightZeroPosition = [| 10.0; 4.0; 10.0; 1.0 |] and lightZeroColor = [| 0.8; 1.0; 0.8; 1.0 |] (* green-tinted *) and lightOnePosition = [| -1.0; -2.0; 1.0; 0.0 |] and lightOneColor = [| 0.6; 0.3; 0.2; 1.0 |] (* red-tinted *) and skinColor = [| 0.1; 1.0; 0.1; 1.0 |] and eyeColor = [| 1.0; 0.2; 0.2; 1.0 |] let extrudeSolidFromPolygon data (thickness:float) (side:int) (edge:int) (whole:int) = static GLUtriangulatorObj *tobj = NULL; GLdouble vertex.(3) dx dy len; int i; int count = (int) (dataSize / (2 * sizeof(GLfloat))); let count = dataSize / (2 * sizeof(GLfloat)) in if (tobj = NULL) then 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); incr 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); incr 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) 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 recalcModelView(void) GLfloat m.(4).(4); glPopMatrix(); glPushMatrix(); build_rotmatrix(m curquat); glMultMatrixf( land m.(0).(0)); if (scalefactor = 1.0) then glDisable(GL_NORMALIZE); } else { glEnable(GL_NORMALIZE); glScalef(scalefactor scalefactor scalefactor); glTranslatef(-8 -8 -bodyWidth / 2); newModel = 0; ;; void showMessage(GLfloat x GLfloat y GLfloat z char *message) glPushMatrix(); glDisable(GL_LIGHTING); glTranslatef(x y z); glScalef(.02 .02 .02); while (*message) { Glut.strokeCharacter(Glut.STROKE_ROMAN *message); incr message; glEnable(GL_LIGHTING); glPopMatrix(); ;; void redraw(void) if (newModel) recalcModelView(); GlClear.clear(GL_COLOR_BUFFER_BIT lor GL_DEPTH_BUFFER_BIT); glCallList(DINOSAUR); showMessage(2 7.1 4.1 "Spin me."); Glut.swapBuffers(); ;; void myReshape(int w int h) glViewport(0 0 w h); W = w; H = h; ;; void mouse(int button int state int x int y) if (button = Glut.LEFT_BUTTON && state = Glut.DOWN) then spinning = 0; Glut.idleFunc(NULL); moving = 1; beginx = x; beginy = y; if (Glut.getModifiers() land Glut.ACTIVE_SHIFT) then scaling = 1; } else { scaling = 0; if (button = Glut.LEFT_BUTTON && state = Glut.UP) then moving = 0; ;; void animate(void) add_quats(lastquat curquat curquat); newModel = 1; Glut.postRedisplay(); ;; void motion(int x int y) if (scaling) then scalefactor = scalefactor * (1.0 + (((float) (beginy - y)) / H)); beginx = x; beginy = y; newModel = 1; Glut.postRedisplay(); return; if (moving) then trackball(lastquat (2.0 * beginx - W) / W (H - 2.0 * beginy) / H (2.0 * x - W) / W (H - 2.0 * y) / H ); beginx = x; beginy = y; spinning = 1; Glut.idleFunc(animate); ;; GLboolean lightZeroSwitch = GL_TRUE lightOneSwitch = GL_TRUE; void controlLights(int value) match value with | 1 -> lightZeroSwitch = not lightZeroSwitch; if (lightZeroSwitch) then glEnable(GL_LIGHT0); } else { glDisable(GL_LIGHT0); break; | 2 -> lightOneSwitch = not lightOneSwitch; if (lightOneSwitch) then glEnable(GL_LIGHT1); } else { glDisable(GL_LIGHT1); break; #ifdef GL_MULTISAMPLE_SGIS | 3 -> if (glIsEnabled(GL_MULTISAMPLE_SGIS)) then glDisable(GL_MULTISAMPLE_SGIS); } else { glEnable(GL_MULTISAMPLE_SGIS); break; #endif | 4 -> Glut.fullScreen(); break; | 5 -> exit(0); break; Glut.postRedisplay(); ;; void vis(int visible) if (visible = Glut.VISIBLE) then if (spinning) Glut.idleFunc(animate); } else { if (spinning) Glut.idleFunc(NULL); ;; int main(int argc char **argv) Glut.init( land argc argv); Glut.initDisplayMode(Glut.RGB lor Glut.DOUBLE lor Glut.DEPTH lor Glut.MULTISAMPLE); trackball(curquat 0.0 0.0 0.0 0.0); Glut.createWindow("dinospin"); Glut.displayFunc(redraw); Glut.reshapeFunc(myReshape); Glut.visibilityFunc(vis); Glut.mouseFunc(mouse); Glut.motionFunc(motion); Glut.createMenu(controlLights); Glut.addMenuEntry("Toggle right light" 1); Glut.addMenuEntry("Toggle left light" 2); if (Glut.get(Glut.WINDOW_NUM_SAMPLES) > 0) then Glut.addMenuEntry("Toggle multisampling" 3); Glut.setWindowTitle("dinospin (multisample capable)"); Glut.addMenuEntry("Full screen" 4); Glut.addMenuEntry("Quit" 5); Glut.attachMenu(Glut.RIGHT_BUTTON); makeDinosaur(); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); gluPerspective( (* field of view in degree *) 40.0 (* aspect ratio *) 1.0 (* Z near *) 1.0 (* Z far *) 40.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0 0.0 30.0 (* eye is at (0 0 30) *) 0.0 0.0 0.0 (* center is at (0 0 0) *) 0.0 1.0 0.); (* up is in positive Y direction *) glPushMatrix(); (* dummy push so we can pop on model recalc *) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER 1); glLightfv(GL_LIGHT0 GL_POSITION lightZeroPosition); glLightfv(GL_LIGHT0 GL_DIFFUSE lightZeroColor); glLightf(GL_LIGHT0 GL_CONSTANT_ATTENUATION 0.1); glLightf(GL_LIGHT0 GL_LINEAR_ATTENUATION 0.05); glLightfv(GL_LIGHT1 GL_POSITION lightOnePosition); glLightfv(GL_LIGHT1 GL_DIFFUSE lightOneColor); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glLineWidth(2.0); Glut.mainLoop(); return 0; (* ANSI C requires main to return int. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/scube.c000066400000000000000000000422451437514534100237460ustar00rootroot00000000000000 /* 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. */ /* * 1992 David G Yu -- Silicon Graphics Computer Systems */ #include #include #include #include #include static int useRGB = 1; static int useLighting = 1; static int useFog = 0; static int useDB = 1; static int useLogo = 0; static int useQuads = 1; static int tick = -1; static int moving = 1; #define GREY 0 #define RED 1 #define GREEN 2 #define BLUE 3 #define CYAN 4 #define MAGENTA 5 #define YELLOW 6 #define BLACK 7 static float materialColor[8][4] = { {0.8, 0.8, 0.8, 1.0}, {0.8, 0.0, 0.0, 1.0}, {0.0, 0.8, 0.0, 1.0}, {0.0, 0.0, 0.8, 1.0}, {0.0, 0.8, 0.8, 1.0}, {0.8, 0.0, 0.8, 1.0}, {0.8, 0.8, 0.0, 1.0}, {0.0, 0.0, 0.0, 0.6}, }; static float lightPos[4] = {2.0, 4.0, 2.0, 1.0}; #if 0 static float lightDir[4] = {-2.0, -4.0, -2.0, 1.0}; #endif static float lightAmb[4] = {0.2, 0.2, 0.2, 1.0}; static float lightDiff[4] = {0.8, 0.8, 0.8, 1.0}; static float lightSpec[4] = {0.4, 0.4, 0.4, 1.0}; static float groundPlane[4] = {0.0, 1.0, 0.0, 1.499}; static float backPlane[4] = {0.0, 0.0, 1.0, 0.899}; static float fogColor[4] = {0.0, 0.0, 0.0, 0.0}; static float fogIndex[1] = {0.0}; static unsigned char shadowPattern[128] = { 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, /* 50% Grey */ 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55 }; static unsigned char sgiPattern[128] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* SGI Logo */ 0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef, 0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef, 0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef, 0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83, 0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff, 0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb, 0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3, 0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf, 0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7, 0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff, 0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb, 0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb, 0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf, 0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 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: scube [options]\n"); printf("\n"); printf(" display a spinning cube and its shadow\n"); printf("\n"); printf(" Options:\n"); printf(" -geometry window size and location\n"); printf(" -c toggle color index mode\n"); printf(" -l toggle lighting\n"); printf(" -f toggle fog\n"); printf(" -db toggle double buffering\n"); printf(" -logo toggle sgi logo for the shadow pattern\n"); printf(" -quads toggle use of GL_QUADS to draw the checkerboard\n"); printf("\n"); #ifndef EXIT_FAILURE /* should be defined by ANSI C */ #define EXIT_FAILURE 1 #endif exit(EXIT_FAILURE); } void buildColormap(void) { if (useRGB) { return; } else { int mapSize = 1 << glutGet(GLUT_WINDOW_BUFFER_SIZE); int rampSize = mapSize / 8; int entry; int i; for (entry = 0; entry < mapSize; ++entry) { int hue = entry / rampSize; GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1)); GLfloat red, green, blue; red = (hue == 0 || hue == 1 || hue == 5 || hue == 6) ? val : 0; green = (hue == 0 || hue == 2 || hue == 4 || hue == 6) ? val : 0; blue = (hue == 0 || hue == 3 || hue == 4 || hue == 5) ? val : 0; glutSetColor(entry, red, green, blue); } for (i = 0; i < 8; ++i) { materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1); materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1); materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1); materialColor[i][3] = 0.0; } fogIndex[0] = -0.2 * (rampSize - 1); } } static void setColor(int c) { if (useLighting) { if (useRGB) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]); } else { glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, &materialColor[c][0]); } } else { if (useRGB) { glColor4fv(&materialColor[c][0]); } else { glIndexf(materialColor[c][1]); } } } static void drawCube(int color) { int i; setColor(color); 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(); } } static void drawCheck(int w, int h, int evenColor, int oddColor) { static int initialized = 0; static int usedLighting = 0; static GLuint checklist = 0; if (!initialized || (usedLighting != useLighting)) { static float square_normal[4] = {0.0, 0.0, 1.0, 0.0}; static float square[4][4]; int i, j; if (!checklist) { checklist = glGenLists(1); } glNewList(checklist, GL_COMPILE_AND_EXECUTE); if (useQuads) { glNormal3fv(square_normal); glBegin(GL_QUADS); } for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { square[0][0] = -1.0 + 2.0 / w * i; square[0][1] = -1.0 + 2.0 / h * (j + 1); square[0][2] = 0.0; square[0][3] = 1.0; square[1][0] = -1.0 + 2.0 / w * i; square[1][1] = -1.0 + 2.0 / h * j; square[1][2] = 0.0; square[1][3] = 1.0; square[2][0] = -1.0 + 2.0 / w * (i + 1); square[2][1] = -1.0 + 2.0 / h * j; square[2][2] = 0.0; square[2][3] = 1.0; square[3][0] = -1.0 + 2.0 / w * (i + 1); square[3][1] = -1.0 + 2.0 / h * (j + 1); square[3][2] = 0.0; square[3][3] = 1.0; if ((i & 1) ^ (j & 1)) { setColor(oddColor); } else { setColor(evenColor); } if (!useQuads) { glBegin(GL_POLYGON); } glVertex4fv(&square[0][0]); glVertex4fv(&square[1][0]); glVertex4fv(&square[2][0]); glVertex4fv(&square[3][0]); if (!useQuads) { glEnd(); } } } if (useQuads) { glEnd(); } glEndList(); initialized = 1; usedLighting = useLighting; } else { glCallList(checklist); } } static void myShadowMatrix(float ground[4], float light[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); } static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)"; static char *windowNameRGB = "shadow cube (OpenGL RGB)"; static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)"; static char *windowNameIndex = "shadow cube (OpenGL Index)"; void idle(void) { tick++; if (tick >= 120) { tick = 0; } glutPostRedisplay(); } /* ARGSUSED1 */ void keyboard(unsigned char ch, int x, int y) { switch (ch) { case 27: /* escape */ exit(0); break; case 'L': case 'l': useLighting = !useLighting; useLighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); glutPostRedisplay(); break; case 'F': case 'f': useFog = !useFog; useFog ? glEnable(GL_FOG) : glDisable(GL_FOG); glutPostRedisplay(); break; case '1': glFogf(GL_FOG_MODE, GL_LINEAR); glutPostRedisplay(); break; case '2': glFogf(GL_FOG_MODE, GL_EXP); glutPostRedisplay(); break; case '3': glFogf(GL_FOG_MODE, GL_EXP2); glutPostRedisplay(); break; case ' ': if (!moving) { idle(); glutPostRedisplay(); } } } void display(void) { GLfloat cubeXform[4][4]; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0, -1.5, 0.0); glRotatef(-90.0, 1, 0, 0); glScalef(2.0, 2.0, 2.0); drawCheck(6, 6, BLUE, YELLOW); /* draw ground */ glPopMatrix(); glPushMatrix(); glTranslatef(0.0, 0.0, -0.9); glScalef(2.0, 2.0, 2.0); drawCheck(6, 6, BLUE, YELLOW); /* draw back */ glPopMatrix(); glPushMatrix(); 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); glScalef(1.0, 2.0, 1.0); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform); drawCube(RED); /* draw cube */ glPopMatrix(); glDepthMask(GL_FALSE); if (useRGB) { glEnable(GL_BLEND); } else { glEnable(GL_POLYGON_STIPPLE); } if (useFog) { glDisable(GL_FOG); } glPushMatrix(); myShadowMatrix(groundPlane, lightPos); glTranslatef(0.0, 0.0, 2.0); glMultMatrixf((const GLfloat *) cubeXform); drawCube(BLACK); /* draw ground shadow */ glPopMatrix(); glPushMatrix(); myShadowMatrix(backPlane, lightPos); glTranslatef(0.0, 0.0, 2.0); glMultMatrixf((const GLfloat *) cubeXform); drawCube(BLACK); /* draw back shadow */ glPopMatrix(); glDepthMask(GL_TRUE); if (useRGB) { glDisable(GL_BLEND); } else { glDisable(GL_POLYGON_STIPPLE); } if (useFog) { glEnable(GL_FOG); } if (useDB) { glutSwapBuffers(); } else { glFlush(); } } void fog_select(int fog) { glFogf(GL_FOG_MODE, fog); glutPostRedisplay(); } void menu_select(int mode) { switch (mode) { case 1: moving = 1; glutIdleFunc(idle); break; case 2: moving = 0; glutIdleFunc(NULL); break; case 3: useFog = !useFog; useFog ? glEnable(GL_FOG) : glDisable(GL_FOG); glutPostRedisplay(); break; case 4: useLighting = !useLighting; useLighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); glutPostRedisplay(); break; case 5: exit(0); break; } } void visible(int state) { if (state == GLUT_VISIBLE) { if (moving) glutIdleFunc(idle); } else { if (moving) glutIdleFunc(NULL); } } int main(int argc, char **argv) { int width = 350, height = 350; int i; char *name; int fog_menu; glutInitWindowSize(width, height); glutInit(&argc, argv); /* process commmand line args */ for (i = 1; i < argc; ++i) { if (!strcmp("-c", argv[i])) { useRGB = !useRGB; } else if (!strcmp("-l", argv[i])) { useLighting = !useLighting; } else if (!strcmp("-f", argv[i])) { useFog = !useFog; } else if (!strcmp("-db", argv[i])) { useDB = !useDB; } else if (!strcmp("-logo", argv[i])) { useLogo = !useLogo; } else if (!strcmp("-quads", argv[i])) { useQuads = !useQuads; } else { usage(); } } /* choose visual */ if (useRGB) { if (useDB) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); name = windowNameRGBDB; } else { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); name = windowNameRGB; } } else { if (useDB) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH); name = windowNameIndexDB; } else { glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH); name = windowNameIndex; } } glutCreateWindow(name); buildColormap(); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutVisibilityFunc(visible); fog_menu = glutCreateMenu(fog_select); glutAddMenuEntry("Linear fog", GL_LINEAR); glutAddMenuEntry("Exp fog", GL_EXP); glutAddMenuEntry("Exp^2 fog", GL_EXP2); glutCreateMenu(menu_select); glutAddMenuEntry("Start motion", 1); glutAddMenuEntry("Stop motion", 2); glutAddMenuEntry("Toggle fog", 3); glutAddMenuEntry("Toggle lighting", 4); glutAddSubMenu("Fog type", fog_menu); glutAddMenuEntry("Quit", 5); glutAttachMenu(GLUT_RIGHT_BUTTON); /* setup context */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -2.0); glEnable(GL_DEPTH_TEST); if (useLighting) { glEnable(GL_LIGHTING); } glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec); #if 0 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir); glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25); #endif glEnable(GL_NORMALIZE); if (useFog) { glEnable(GL_FOG); } glFogfv(GL_FOG_COLOR, fogColor); glFogfv(GL_FOG_INDEX, fogIndex); glFogf(GL_FOG_MODE, GL_EXP); glFogf(GL_FOG_DENSITY, 0.5); glFogf(GL_FOG_START, 1.0); glFogf(GL_FOG_END, 3.0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glShadeModel(GL_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (useLogo) { glPolygonStipple((const GLubyte *) sgiPattern); } else { glPolygonStipple((const GLubyte *) shadowPattern); } glClearColor(0.0, 0.0, 0.0, 1); glClearIndex(0); glClearDepth(1); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/scube.ml000077500000000000000000000421711437514534100241350ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Wed Aug 7 02:29:47 MDT 2002. *) open Printf (* 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. *) (* * 1992 David G Yu -- Silicon Graphics Computer Systems *) static int useRGB = 1; static int useLighting = 1; static int useFog = 0; static int useDB = 1; static int useLogo = 0; static int useQuads = 1; static int tick = -1; static int moving = 1; #define GREY 0 #define RED 1 #define GREEN 2 #define BLUE 3 #define CYAN 4 #define MAGENTA 5 #define YELLOW 6 #define BLACK 7 static float materialColor[8][4] = {0.8 0.8 0.8 1.0} {0.8 0.0 0.0 1.0} {0.0 0.8 0.0 1.0} {0.0 0.0 0.8 1.0} {0.0 0.8 0.8 1.0} {0.8 0.0 0.8 1.0} {0.8 0.8 0.0 1.0} {0.0 0.0 0.0 0.6} }; static float lightPos[4] = {2.0 4.0 2.0 1.0}; #if 0 static float lightDir[4] = {-2.0 -4.0 -2.0 1.0}; #endif static float lightAmb[4] = {0.2 0.2 0.2 1.0}; static float lightDiff[4] = {0.8 0.8 0.8 1.0}; static float lightSpec[4] = {0.4 0.4 0.4 1.0}; static float groundPlane[4] = {0.0 1.0 0.0 1.499}; static float backPlane[4] = {0.0 0.0 1.0 0.899}; static float fogColor[4] = {0.0 0.0 0.0 0.0}; static float fogIndex[1] = {0.0}; static unsigned char shadowPattern[128] = 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 (* 50% Grey *) 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 0xaa 0xaa 0xaa 0xaa 0x55 0x55 0x55 0x55 }; static unsigned char sgiPattern[128] = 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff (* SGI Logo *) 0xff 0xbd 0xff 0x83 0xff 0x5a 0xff 0xef 0xfe 0xdb 0x7f 0xef 0xfd 0xdb 0xbf 0xef 0xfb 0xdb 0xdf 0xef 0xf7 0xdb 0xef 0xef 0xfb 0xdb 0xdf 0xef 0xfd 0xdb 0xbf 0x83 0xce 0xdb 0x73 0xff 0xb7 0x5a 0xed 0xff 0xbb 0xdb 0xdd 0xc7 0xbd 0xdb 0xbd 0xbb 0xbe 0xbd 0x7d 0xbb 0xbf 0x7e 0xfd 0xb3 0xbe 0xe7 0x7d 0xbf 0xbd 0xdb 0xbd 0xbf 0xbb 0xbd 0xdd 0xbb 0xb7 0x7e 0xed 0xc7 0xce 0xdb 0x73 0xff 0xfd 0xdb 0xbf 0xff 0xfb 0xdb 0xdf 0x87 0xf7 0xdb 0xef 0xfb 0xf7 0xdb 0xef 0xfb 0xfb 0xdb 0xdf 0xfb 0xfd 0xdb 0xbf 0xc7 0xfe 0xdb 0x7f 0xbf 0xff 0x5a 0xff 0xbf 0xff 0xbd 0xff 0xc3 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff }; 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: scube [options]\n"); printf("\n"); printf(" display a spinning cube and its shadow\n"); printf("\n"); printf(" Options:\n"); printf(" -geometry window size and location\n"); printf(" -c toggle color index mode\n"); printf(" -l toggle lighting\n"); printf(" -f toggle fog\n"); printf(" -db toggle double buffering\n"); printf(" -logo toggle sgi logo for the shadow pattern\n"); printf(" -quads toggle use of GL_QUADS to draw the checkerboard\n"); printf("\n"); #ifndef EXIT_FAILURE (* should be defined by ANSI C *) #define EXIT_FAILURE 1 #endif exit(EXIT_FAILURE); ;; void buildColormap(void) if (useRGB) then return; } else { int mapSize = 1 << Glut.get(Glut.WINDOW_BUFFER_SIZE); int rampSize = mapSize / 8; int entry; int i; for (entry = 0; entry < mapSize; ++entry) { int hue = entry / rampSize; GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1)); GLfloat red green blue; red = (hue = 0 || hue = 1 || hue = 5 || hue = 6) ? val : 0; green = (hue = 0 || hue = 2 || hue = 4 || hue = 6) ? val : 0; blue = (hue = 0 || hue = 3 || hue = 4 || hue = 5) ? val : 0; Glut.setColor(entry red green blue); for (i = 0; i < 8; ++i) { materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1); materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1); materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1); materialColor[i][3] = 0.0; fogIndex[0] = -0.2 * (rampSize - 1); ;; static void setColor(int c) if (useLighting) then if (useRGB) then glMaterialfv(GL_FRONT_AND_BACK GL_AMBIENT_AND_DIFFUSE &materialColor[c][0]); } else { glMaterialfv(GL_FRONT_AND_BACK GL_COLOR_INDEXES &materialColor[c][0]); } else { if (useRGB) then glColor4fv(&materialColor[c][0]); } else { glIndexf(materialColor[c][1]); ;; static void drawCube(int color) int i; setColor(color); 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(); ;; static void drawCheck(int w int h int evenColor int oddColor) static int initialized = 0; static int usedLighting = 0; static GLuint checklist = 0; if (!initialized || (usedLighting <> useLighting)) then static float square_normal[4] = {0.0 0.0 1.0 0.0}; static float square[4][4]; int i j; if (!checklist) then checklist = glGenLists(1); glNewList(checklist GL_COMPILE_AND_EXECUTE); if (useQuads) then glNormal3fv(square_normal); glBegin(GL_QUADS); for (j = 0; j < h; ++j) { for (i = 0; i < w; ++i) { square[0][0] = -1.0 + 2.0 / w * i; square[0][1] = -1.0 + 2.0 / h * (j + 1); square[0][2] = 0.0; square[0][3] = 1.0; square[1][0] = -1.0 + 2.0 / w * i; square[1][1] = -1.0 + 2.0 / h * j; square[1][2] = 0.0; square[1][3] = 1.0; square[2][0] = -1.0 + 2.0 / w * (i + 1); square[2][1] = -1.0 + 2.0 / h * j; square[2][2] = 0.0; square[2][3] = 1.0; square[3][0] = -1.0 + 2.0 / w * (i + 1); square[3][1] = -1.0 + 2.0 / h * (j + 1); square[3][2] = 0.0; square[3][3] = 1.0; if ((i & 1) ^ (j & 1)) then setColor(oddColor); } else { setColor(evenColor); if (!useQuads) then glBegin(GL_POLYGON); glVertex4fv(&square[0][0]); glVertex4fv(&square[1][0]); glVertex4fv(&square[2][0]); glVertex4fv(&square[3][0]); if (!useQuads) then glEnd(); if (useQuads) then glEnd(); glEndList(); initialized = 1; usedLighting = useLighting; } else { glCallList(checklist); ;; static void myShadowMatrix(float ground[4] float light[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); ;; static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)"; static char *windowNameRGB = "shadow cube (OpenGL RGB)"; static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)"; static char *windowNameIndex = "shadow cube (OpenGL Index)"; void idle(void) incr tick; if (tick >= 120) then tick = 0; Glut.postRedisplay(); ;; (* ARGSUSED1 *) void keyboard(unsigned char ch int x int y) match ch with | 27 -> (* escape *) exit(0); break; | 'L' -> | 'l' -> useLighting = !useLighting; useLighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); Glut.postRedisplay(); break; | 'F' -> | 'f' -> useFog = !useFog; useFog ? glEnable(GL_FOG) : glDisable(GL_FOG); Glut.postRedisplay(); break; | '1' -> glFogf(GL_FOG_MODE GL_LINEAR); Glut.postRedisplay(); break; | '2' -> glFogf(GL_FOG_MODE GL_EXP); Glut.postRedisplay(); break; | '3' -> glFogf(GL_FOG_MODE GL_EXP2); Glut.postRedisplay(); break; | ' ' -> if (!moving) then idle(); Glut.postRedisplay(); ;; void display(void) GLfloat cubeXform[4][4]; GlClear.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0 -1.5 0.0); glRotatef(-90.0 1 0 0); glScalef(2.0 2.0 2.0); drawCheck(6 6 BLUE YELLOW); (* draw ground *) glPopMatrix(); glPushMatrix(); glTranslatef(0.0 0.0 -0.9); glScalef(2.0 2.0 2.0); drawCheck(6 6 BLUE YELLOW); (* draw back *) glPopMatrix(); glPushMatrix(); 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); glScalef(1.0 2.0 1.0); glGetFloatv(GL_MODELVIEW_MATRIX (GLfloat *) cubeXform); drawCube(RED); (* draw cube *) glPopMatrix(); glDepthMask(GL_FALSE); if (useRGB) then glEnable(GL_BLEND); } else { glEnable(GL_POLYGON_STIPPLE); if (useFog) then glDisable(GL_FOG); glPushMatrix(); myShadowMatrix(groundPlane lightPos); glTranslatef(0.0 0.0 2.0); glMultMatrixf((const GLfloat *) cubeXform); drawCube(BLACK); (* draw ground shadow *) glPopMatrix(); glPushMatrix(); myShadowMatrix(backPlane lightPos); glTranslatef(0.0 0.0 2.0); glMultMatrixf((const GLfloat *) cubeXform); drawCube(BLACK); (* draw back shadow *) glPopMatrix(); glDepthMask(GL_TRUE); if (useRGB) then glDisable(GL_BLEND); } else { glDisable(GL_POLYGON_STIPPLE); if (useFog) then glEnable(GL_FOG); if (useDB) then Glut.swapBuffers(); } else { Gl.flush(); ;; void fog_select(int fog) glFogf(GL_FOG_MODE fog); Glut.postRedisplay(); ;; void menu_select(int mode) match mode with | 1 -> moving = 1; Glut.idleFunc(idle); break; | 2 -> moving = 0; Glut.idleFunc(NULL); break; | 3 -> useFog = !useFog; useFog ? glEnable(GL_FOG) : glDisable(GL_FOG); Glut.postRedisplay(); break; | 4 -> useLighting = !useLighting; useLighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); Glut.postRedisplay(); break; | 5 -> exit(0); break; ;; void visible(int state) if (state = Glut.VISIBLE) then if (moving) Glut.idleFunc(idle); } else { if (moving) Glut.idleFunc(NULL); ;; int main(int argc char **argv) int width = 350 height = 350; int i; char *name; int fog_menu; Glut.initWindowSize(width height); Glut.init(&argc argv); (* process commmand line args *) for (i = 1; i < argc; ++i) { if (!strcmp("-c" argv[i])) then useRGB = !useRGB; } else if (!strcmp("-l" argv[i])) then useLighting = !useLighting; } else if (!strcmp("-f" argv[i])) then useFog = !useFog; } else if (!strcmp("-db" argv[i])) then useDB = !useDB; } else if (!strcmp("-logo" argv[i])) then useLogo = !useLogo; } else if (!strcmp("-quads" argv[i])) then useQuads = !useQuads; } else { usage(); (* choose visual *) if (useRGB) then if (useDB) then Glut.initDisplayMode(Glut.DOUBLE | Glut.RGB | Glut.DEPTH); name = windowNameRGBDB; } else { Glut.initDisplayMode(Glut.SINGLE | Glut.RGB | Glut.DEPTH); name = windowNameRGB; } else { if (useDB) then Glut.initDisplayMode(Glut.DOUBLE | Glut.INDEX | Glut.DEPTH); name = windowNameIndexDB; } else { Glut.initDisplayMode(Glut.SINGLE | Glut.INDEX | Glut.DEPTH); name = windowNameIndex; Glut.createWindow(name); buildColormap(); Glut.keyboardFunc(keyboard); Glut.displayFunc(display); Glut.visibilityFunc(visible); fog_menu = Glut.createMenu(fog_select); Glut.addMenuEntry("Linear fog" GL_LINEAR); Glut.addMenuEntry("Exp fog" GL_EXP); Glut.addMenuEntry("Exp^2 fog" GL_EXP2); Glut.createMenu(menu_select); Glut.addMenuEntry("Start motion" 1); Glut.addMenuEntry("Stop motion" 2); Glut.addMenuEntry("Toggle fog" 3); Glut.addMenuEntry("Toggle lighting" 4); Glut.addSubMenu("Fog type" fog_menu); Glut.addMenuEntry("Quit" 5); Glut.attachMenu(Glut.RIGHT_BUTTON); (* setup context *) glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0 1.0 -1.0 1.0 1.0 3.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0 0.0 -2.0); glEnable(GL_DEPTH_TEST); if (useLighting) then glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0 GL_POSITION lightPos); glLightfv(GL_LIGHT0 GL_AMBIENT lightAmb); glLightfv(GL_LIGHT0 GL_DIFFUSE lightDiff); glLightfv(GL_LIGHT0 GL_SPECULAR lightSpec); #if 0 glLightfv(GL_LIGHT0 GL_SPOT_DIRECTION lightDir); glLightf(GL_LIGHT0 GL_SPOT_EXPONENT 80); glLightf(GL_LIGHT0 GL_SPOT_CUTOFF 25); #endif glEnable(GL_NORMALIZE); if (useFog) then glEnable(GL_FOG); glFogfv(GL_FOG_COLOR fogColor); glFogfv(GL_FOG_INDEX fogIndex); glFogf(GL_FOG_MODE GL_EXP); glFogf(GL_FOG_DENSITY 0.5); glFogf(GL_FOG_START 1.0); glFogf(GL_FOG_END 3.0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glShadeModel(GL_SMOOTH); glBlendFunc(GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA); if (useLogo) then glPolygonStipple((const GLubyte *) sgiPattern); } else { glPolygonStipple((const GLubyte *) shadowPattern); GlClear.clearColor(0.0 0.0 0.0 1); GlClear.clearIndex(0); GlClear.clearDepth(1); Glut.mainLoop(); return 0; (* ANSI C requires main to return int. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/splatlogo.c000066400000000000000000000116521437514534100246470ustar00rootroot00000000000000 /* 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 #define MAX_SPLATS 100 extern int logo_width; extern int logo_height; extern unsigned char logo_image[]; typedef struct _SplatInfo { int x, y; GLboolean alphaTest; GLfloat xScale, yScale; GLfloat scale[3]; GLfloat bias[3]; } SplatInfo; int winHeight; int numSplats = 0; SplatInfo splatConfig; SplatInfo splatList[MAX_SPLATS]; SplatInfo splatDefault = { 0, 0, GL_TRUE, 1.0, 1.0, { 1.0, 1.0, 1.0 }, { 0.0, 0.0, 0.0 } }; void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, w, 0, h); glMatrixMode(GL_MODELVIEW); winHeight = h; } void renderSplat(SplatInfo *splat) { glRasterPos2i(splat->x, splat->y); if(splat->yScale >= 0) glBitmap(0, 0, 0, 0, 0, -logo_height * splat->yScale, 0); if(splat->xScale < 0) glBitmap(0, 0, 0, 0, logo_width * -splat->xScale, 0, 0); glPixelZoom(splat->xScale, splat->yScale); glPixelTransferf(GL_RED_SCALE, splat->scale[0]); glPixelTransferf(GL_GREEN_SCALE, splat->scale[1]); glPixelTransferf(GL_BLUE_SCALE, splat->scale[2]); glPixelTransferf(GL_RED_BIAS, splat->bias[0]); glPixelTransferf(GL_GREEN_BIAS, splat->bias[1]); glPixelTransferf(GL_BLUE_BIAS, splat->bias[2]); if (splat->alphaTest) glEnable(GL_ALPHA_TEST); else glDisable(GL_ALPHA_TEST); glDrawPixels(logo_width, logo_height, GL_RGBA, GL_UNSIGNED_BYTE, logo_image); } void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT); for (i = 0; i < numSplats; i++) { renderSplat(&splatList[i]); } glFlush(); } void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { if (numSplats < MAX_SPLATS) { splatConfig.x = x; splatConfig.y = winHeight - y; renderSplat(&splatConfig); splatList[numSplats] = splatConfig; numSplats++; } else { printf("out of splats!\n"); } } } } void mainSelect(int value) { GLfloat rpos[4]; GLboolean valid; switch(value) { case 0: numSplats = 0; glutPostRedisplay(); break; case 1: splatConfig = splatDefault; break; case 2: splatConfig.xScale *= 1.25; splatConfig.yScale *= 1.25; break; case 3: splatConfig.xScale *= 0.75; splatConfig.yScale *= 0.75; break; case 4: splatConfig.xScale *= -1.0; break; case 5: splatConfig.yScale *= -1.0; break; case 6: splatConfig.alphaTest = GL_TRUE; break; case 7: splatConfig.alphaTest = GL_FALSE; break; case 411: glGetFloatv(GL_CURRENT_RASTER_POSITION, rpos); glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); printf("Raster position (%g,%g) is %s\n", rpos[0], rpos[1], valid ? "valid" : "INVALID"); break; case 666: exit(0); break; } } void scaleBiasSelect(int value) { int color = value >> 4; int option = value & 0xf; switch(option) { case 1: splatConfig.bias[color] += 0.25; break; case 2: splatConfig.bias[color] -= 0.25; break; case 3: splatConfig.scale[color] *= 2.0; break; case 4: splatConfig.scale[color] *= 0.75; break; } } int glutScaleBiasMenu(int mask) { int menu; menu = glutCreateMenu(scaleBiasSelect); glutAddMenuEntry("+25% bias", mask | 1); glutAddMenuEntry("-25% bias", mask | 2); glutAddMenuEntry("+25% scale", mask | 3); glutAddMenuEntry("-25% scale", mask | 4); return menu; } int main(int argc, char *argv[]) { int mainMenu, redMenu, greenMenu, blueMenu; glutInitWindowSize(680, 440); glutInit(&argc, argv); splatConfig = splatDefault; glutCreateWindow("splatlogo"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glAlphaFunc(GL_GEQUAL, 0.5); glDisable(GL_ALPHA_TEST); glEnable(GL_DITHER); glClearColor(1.0, 1.0, 1.0, 0.0); redMenu = glutScaleBiasMenu(0 << 4); greenMenu = glutScaleBiasMenu(1 << 4); blueMenu = glutScaleBiasMenu(2 << 4); mainMenu = glutCreateMenu(mainSelect); glutAddMenuEntry("Reset splays", 0); glutAddMenuEntry("Reset splat config", 1); glutAddSubMenu("Red control", redMenu); glutAddSubMenu("Green control", greenMenu); glutAddSubMenu("Blue control", blueMenu); glutAddMenuEntry("+25% zoom", 2); glutAddMenuEntry("-25% zoom", 3); glutAddMenuEntry("X flip", 4); glutAddMenuEntry("Y flip", 5); glutAddMenuEntry("Enable alpha test", 6); glutAddMenuEntry("Disable alpha test", 7); glutSetMenu(mainMenu); glutAddMenuEntry("Query raster position", 411); glutAddMenuEntry("Quit", 666); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; /* Never reached; make ANSI C happy. */ } lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/splatlogo.ml000077500000000000000000000121001437514534100250250ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Wed Aug 7 02:29:50 MDT 2002. *) open Printf (* 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 #define MAX_SPLATS 100 extern int logo_width; extern int logo_height; extern unsigned char logo_image[]; typedef struct _SplatInfo { int x y; GLboolean alphaTest; GLfloat xScale yScale; GLfloat scale[3]; GLfloat bias[3]; } SplatInfo; int winHeight; int numSplats = 0; SplatInfo splatConfig; SplatInfo splatList[MAX_SPLATS]; SplatInfo splatDefault = { 0 0 GL_TRUE 1.0 1.0 { 1.0 1.0 1.0 } { 0.0 0.0 0.0 } }; void reshape(int w int h) glViewport(0 0 w h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0 w 0 h); glMatrixMode(GL_MODELVIEW); winHeight = h; ;; void renderSplat(SplatInfo *splat) glRasterPos2i(splat->x splat->y); if(splat->yScale >= 0) glBitmap(0 0 0 0 0 -logo_height * splat->yScale 0); if(splat->xScale < 0) glBitmap(0 0 0 0 logo_width * -splat->xScale 0 0); glPixelZoom(splat->xScale splat->yScale); glPixelTransferf(GL_RED_SCALE splat->scale[0]); glPixelTransferf(GL_GREEN_SCALE splat->scale[1]); glPixelTransferf(GL_BLUE_SCALE splat->scale[2]); glPixelTransferf(GL_RED_BIAS splat->bias[0]); glPixelTransferf(GL_GREEN_BIAS splat->bias[1]); glPixelTransferf(GL_BLUE_BIAS splat->bias[2]); if (splat->alphaTest) glEnable(GL_ALPHA_TEST); else glDisable(GL_ALPHA_TEST); glDrawPixels(logo_width logo_height GL_RGBA GL_UNSIGNED_BYTE logo_image); ;; void display(void) int i; GlClear.clear(GL_COLOR_BUFFER_BIT); incr for (i = 0; i < numSplats; i) { renderSplat(&splatList[i]); Gl.flush(); ;; void mouse(int button int state int x int y) if (button = Glut.LEFT_BUTTON) then if (state = Glut.DOWN) then if (numSplats < MAX_SPLATS) then splatConfig.x = x; splatConfig.y = winHeight - y; renderSplat(&splatConfig); splatList[numSplats] = splatConfig; incr numSplats; } else { printf("out of splats!\n"); ;; void mainSelect(int value) GLfloat rpos[4]; GLboolean valid; match value with | 0 -> numSplats = 0; Glut.postRedisplay(); break; | 1 -> splatConfig = splatDefault; break; | 2 -> splatConfig.xScale *= 1.25; splatConfig.yScale *= 1.25; break; | 3 -> splatConfig.xScale *= 0.75; splatConfig.yScale *= 0.75; break; | 4 -> splatConfig.xScale *= -1.0; break; | 5 -> splatConfig.yScale *= -1.0; break; | 6 -> splatConfig.alphaTest = GL_TRUE; break; | 7 -> splatConfig.alphaTest = GL_FALSE; break; | 411 -> glGetFloatv(GL_CURRENT_RASTER_POSITION rpos); glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID &valid); printf("Raster position (%g %g) is %s\n" rpos[0] rpos[1] valid ? "valid" : "INVALID"); break; | 666 -> exit(0); break; ;; void scaleBiasSelect(int value) int color = value >> 4; int option = value & 0xf; match option with | 1 -> splatConfig.bias[color] += 0.25; break; | 2 -> splatConfig.bias[color] -= 0.25; break; | 3 -> splatConfig.scale[color] *= 2.0; break; | 4 -> splatConfig.scale[color] *= 0.75; break; ;; int Glut.scaleBiasMenu(int mask) int menu; menu = Glut.createMenu(scaleBiasSelect); Glut.addMenuEntry("+25% bias" mask | 1); Glut.addMenuEntry("-25% bias" mask | 2); Glut.addMenuEntry("+25% scale" mask | 3); Glut.addMenuEntry("-25% scale" mask | 4); return menu; ;; int main(int argc char *argv[]) int mainMenu redMenu greenMenu blueMenu; Glut.initWindowSize(680 440); Glut.init(&argc argv); splatConfig = splatDefault; Glut.createWindow("splatlogo"); Glut.reshapeFunc(reshape); Glut.displayFunc(display); Glut.mouseFunc(mouse); glPixelStorei(GL_UNPACK_ALIGNMENT 1); glAlphaFunc(GL_GEQUAL 0.5); glDisable(GL_ALPHA_TEST); glEnable(GL_DITHER); GlClear.clearColor(1.0 1.0 1.0 0.0); redMenu = Glut.scaleBiasMenu(0 << 4); greenMenu = Glut.scaleBiasMenu(1 << 4); blueMenu = Glut.scaleBiasMenu(2 << 4); mainMenu = Glut.createMenu(mainSelect); Glut.addMenuEntry("Reset splays" 0); Glut.addMenuEntry("Reset splat config" 1); Glut.addSubMenu("Red control" redMenu); Glut.addSubMenu("Green control" greenMenu); Glut.addSubMenu("Blue control" blueMenu); Glut.addMenuEntry("+25% zoom" 2); Glut.addMenuEntry("-25% zoom" 3); Glut.addMenuEntry("X flip" 4); Glut.addMenuEntry("Y flip" 5); Glut.addMenuEntry("Enable alpha test" 6); Glut.addMenuEntry("Disable alpha test" 7); Glut.setMenu(mainMenu); Glut.addMenuEntry("Query raster position" 411); Glut.addMenuEntry("Quit" 666); Glut.attachMenu(Glut.RIGHT_BUTTON); Glut.mainLoop(); return 0; (* Never reached; make ANSI C happy. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/spots.c000066400000000000000000000217601437514534100240140ustar00rootroot00000000000000 /* 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 /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #define TWO_PI (2*M_PI) typedef struct lightRec { float amb[4]; float diff[4]; float spec[4]; float pos[4]; float spotDir[3]; float spotExp; float spotCutoff; float atten[3]; float trans[3]; float rot[3]; float swing[3]; float arc[3]; float arcIncr[3]; } Light; static int useSAME_AMB_SPEC = 1; /* *INDENT-OFF* */ static float modelAmb[4] = {0.2, 0.2, 0.2, 1.0}; static float matAmb[4] = {0.2, 0.2, 0.2, 1.0}; static float matDiff[4] = {0.8, 0.8, 0.8, 1.0}; static float matSpec[4] = {0.4, 0.4, 0.4, 1.0}; static float matEmission[4] = {0.0, 0.0, 0.0, 1.0}; /* *INDENT-ON* */ #define NUM_LIGHTS 3 static Light spots[] = { { {0.2, 0.0, 0.0, 1.0}, /* ambient */ {0.8, 0.0, 0.0, 1.0}, /* diffuse */ {0.4, 0.0, 0.0, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ 20.0, 60.0, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 70.0, 0.0, TWO_PI / 140.0} /* arc increment */ }, { {0.0, 0.2, 0.0, 1.0}, /* ambient */ {0.0, 0.8, 0.0, 1.0}, /* diffuse */ {0.0, 0.4, 0.0, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ 20.0, 60.0, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 120.0, 0.0, TWO_PI / 60.0} /* arc increment */ }, { {0.0, 0.0, 0.2, 1.0}, /* ambient */ {0.0, 0.0, 0.8, 1.0}, /* diffuse */ {0.0, 0.0, 0.4, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ 20.0, 60.0, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 50.0, 0.0, TWO_PI / 100.0} /* arc increment */ } }; static void usage(char *name) { printf("\n"); printf("usage: %s [options]\n", name); printf("\n"); printf(" Options:\n"); printf(" -geometry Specify size and position WxH+X+Y\n"); printf(" -lm Toggle lighting(SPECULAR and AMBIENT are/not same\n"); printf("\n"); #ifndef EXIT_FAILURE /* should be defined by ANSI C */ #define EXIT_FAILURE 1 #endif exit(EXIT_FAILURE); } static void initLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glEnable(lt); glLightfv(lt, GL_AMBIENT, light->amb); glLightfv(lt, GL_DIFFUSE, light->diff); if (useSAME_AMB_SPEC) glLightfv(lt, GL_SPECULAR, light->amb); else glLightfv(lt, GL_SPECULAR, light->spec); glLightf(lt, GL_SPOT_EXPONENT, light->spotExp); glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff); glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]); glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]); glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]); } } static void aimLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; light->rot[0] = light->swing[0] * sin(light->arc[0]); light->arc[0] += light->arcIncr[0]; if (light->arc[0] > TWO_PI) light->arc[0] -= TWO_PI; light->rot[1] = light->swing[1] * sin(light->arc[1]); light->arc[1] += light->arcIncr[1]; if (light->arc[1] > TWO_PI) light->arc[1] -= TWO_PI; light->rot[2] = light->swing[2] * sin(light->arc[2]); light->arc[2] += light->arcIncr[2]; if (light->arc[2] > TWO_PI) light->arc[2] -= TWO_PI; } } static void setLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glPushMatrix(); glTranslatef(light->trans[0], light->trans[1], light->trans[2]); glRotatef(light->rot[0], 1, 0, 0); glRotatef(light->rot[1], 0, 1, 0); glRotatef(light->rot[2], 0, 0, 1); glLightfv(lt, GL_POSITION, light->pos); glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir); glPopMatrix(); } } static void drawLights(void) { int k; glDisable(GL_LIGHTING); for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; glColor4fv(light->diff); glPushMatrix(); glTranslatef(light->trans[0], light->trans[1], light->trans[2]); glRotatef(light->rot[0], 1, 0, 0); glRotatef(light->rot[1], 0, 1, 0); glRotatef(light->rot[2], 0, 0, 1); glBegin(GL_LINES); glVertex3f(light->pos[0], light->pos[1], light->pos[2]); glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]); glEnd(); glPopMatrix(); } glEnable(GL_LIGHTING); } static void drawPlane(int w, int h) { int i, j; float dw = 1.0 / w; float dh = 1.0 / h; glNormal3f(0.0, 0.0, 1.0); for (j = 0; j < h; ++j) { glBegin(GL_TRIANGLE_STRIP); for (i = 0; i <= w; ++i) { glVertex2f(dw * i, dh * (j + 1)); glVertex2f(dw * i, dh * j); } glEnd(); } } int spin = 0; void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0, 1, 0); aimLights(); setLights(); glPushMatrix(); glRotatef(-90.0, 1, 0, 0); glScalef(1.9, 1.9, 1.0); glTranslatef(-0.5, -0.5, 0.0); drawPlane(16, 16); glPopMatrix(); drawLights(); glPopMatrix(); glutSwapBuffers(); } void animate(void) { spin += 0.5; if (spin > 360.0) spin -= 360.0; glutPostRedisplay(); } void visibility(int state) { if (state == GLUT_VISIBLE) { glutIdleFunc(animate); } else { glutIdleFunc(NULL); } } int main(int argc, char **argv) { int i; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); /* process commmand line args */ for (i = 1; i < argc; ++i) { if (!strcmp("-lm", argv[i])) { useSAME_AMB_SPEC = !useSAME_AMB_SPEC; } else { usage(argv[0]); } } glutCreateWindow("GLUT spotlight swing"); glutDisplayFunc(display); glutVisibilityFunc(visibility); glMatrixMode(GL_PROJECTION); glFrustum(-1, 1, -1, 1, 2, 6); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0, 0.0, -3.0); glRotatef(45.0, 1, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); 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); initLights(); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/spots.ml000077500000000000000000000217611437514534100242060ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Wed Aug 7 02:29:51 MDT 2002. *) open Printf (* 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. *) (* Some files do not define M_PI... *) let pi = 3.14159265358979323846;; let two_pi = 2.0*pi;; type lightRec = { amb:Gl.rgba; diff:Gl.rgba; spec:Gl.rgba; pos:Gl.rgba; spotDir:Gl.vect3; spotExp:float; spotCutoff:float; atten:float * float * float * float; trans:Gl.point3; rot:float*float*float; (* rotation about each axis *) float swing[3]; float arc[3]; float arcIncr[3]; } Light; static int useSAME_AMB_SPEC = 1; (* *INDENT-OFF* *) static float modelAmb[4] = {0.2 0.2 0.2 1.0}; static float matAmb[4] = {0.2 0.2 0.2 1.0}; static float matDiff[4] = then0.8 0.8 0.8 1.0}; static float matSpec[4] = {0.4 0.4 0.4 1.0}; static float matEmission[4] = {0.0 0.0 0.0 1.0}; (* *INDENT-ON* *) #define NUM_LIGHTS 3 static Light spots[] = {0.2 0.0 0.0 1.0} (* ambient *) {0.8 0.0 0.0 1.0} (* diffuse *) {0.4 0.0 0.0 1.0} (* specular *) {0.0 0.0 0.0 1.0} (* position *) {0.0 -1.0 0.0} (* direction *) 20.0 60.0 (* exponent cutoff *) {1.0 0.0 0.0} (* attenuation *) {0.0 1.25 0.0} (* translation *) {0.0 0.0 0.0} (* rotation *) {20.0 0.0 40.0} (* swing *) {0.0 0.0 0.0} (* arc *) {two_pi / 70.0 0.0 two_pi / 140.0} (* arc increment *) {0.0 0.2 0.0 1.0} (* ambient *) {0.0 0.8 0.0 1.0} (* diffuse *) {0.0 0.4 0.0 1.0} (* specular *) {0.0 0.0 0.0 1.0} (* position *) {0.0 -1.0 0.0} (* direction *) 20.0 60.0 (* exponent cutoff *) {1.0 0.0 0.0} (* attenuation *) {0.0 1.25 0.0} (* translation *) {0.0 0.0 0.0} (* rotation *) {20.0 0.0 40.0} (* swing *) {0.0 0.0 0.0} (* arc *) {two_pi / 120.0 0.0 two_pi / 60.0} (* arc increment *) {0.0 0.0 0.2 1.0} (* ambient *) {0.0 0.0 0.8 1.0} (* diffuse *) {0.0 0.0 0.4 1.0} (* specular *) {0.0 0.0 0.0 1.0} (* position *) {0.0 -1.0 0.0} (* direction *) 20.0 60.0 (* exponent cutoff *) {1.0 0.0 0.0} (* attenuation *) {0.0 1.25 0.0} (* translation *) {0.0 0.0 0.0} (* rotation *) {20.0 0.0 40.0} (* swing *) {0.0 0.0 0.0} (* arc *) {two_pi / 50.0 0.0 two_pi / 100.0} (* arc increment *) }; static void usage(char *name) printf("\n"); printf("usage: %s [options]\n" name); printf("\n"); printf(" Options:\n"); printf(" -geometry Specify size and position WxH+X+Y\n"); printf(" -lm Toggle lighting(SPECULAR and AMBIENT are/not same\n"); printf("\n"); #ifndef EXIT_FAILURE (* should be defined by ANSI C *) #define EXIT_FAILURE 1 #endif exit(EXIT_FAILURE); ;; static void initLights(void) int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glEnable(lt); glLightfv(lt GL_AMBIENT light->amb); glLightfv(lt GL_DIFFUSE light->diff); if (useSAME_AMB_SPEC) glLightfv(lt GL_SPECULAR light->amb); else glLightfv(lt GL_SPECULAR light->spec); glLightf(lt GL_SPOT_EXPONENT light->spotExp); glLightf(lt GL_SPOT_CUTOFF light->spotCutoff); glLightf(lt GL_CONSTANT_ATTENUATION light->atten[0]); glLightf(lt GL_LINEAR_ATTENUATION light->atten[1]); glLightf(lt GL_QUADRATIC_ATTENUATION light->atten[2]); ;; static void aimLights(void) int k; for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; light->rot[0] = light->swing[0] * sin(light->arc[0]); light->arc[0] += light->arcIncr[0]; if (light->arc[0] > two_pi) light->arc[0] -= two_pi; light->rot[1] = light->swing[1] * sin(light->arc[1]); light->arc[1] += light->arcIncr[1]; if (light->arc[1] > two_pi) light->arc[1] -= two_pi; light->rot[2] = light->swing[2] * sin(light->arc[2]); light->arc[2] += light->arcIncr[2]; if (light->arc[2] > two_pi) light->arc[2] -= two_pi; ;; static void setLights(void) int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glPushMatrix(); glTranslatef(light->trans[0] light->trans[1] light->trans[2]); glRotatef(light->rot[0] 1 0 0); glRotatef(light->rot[1] 0 1 0); glRotatef(light->rot[2] 0 0 1); glLightfv(lt GL_POSITION light->pos); glLightfv(lt GL_SPOT_DIRECTION light->spotDir); glPopMatrix(); ;; static void drawLights(void) int k; glDisable(GL_LIGHTING); for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; glColor4fv(light->diff); glPushMatrix(); glTranslatef(light->trans[0] light->trans[1] light->trans[2]); glRotatef(light->rot[0] 1 0 0); glRotatef(light->rot[1] 0 1 0); glRotatef(light->rot[2] 0 0 1); glBegin(GL_LINES); glVertex3f(light->pos[0] light->pos[1] light->pos[2]); glVertex3f(light->spotDir[0] light->spotDir[1] light->spotDir[2]); glEnd(); glPopMatrix(); glEnable(GL_LIGHTING); ;; static void drawPlane(int w int h) int i j; float dw = 1.0 / w; float dh = 1.0 / h; glNormal3f(0.0 0.0 1.0); for (j = 0; j < h; ++j) { glBegin(GL_TRIANGLE_STRIP); for (i = 0; i <= w; ++i) { glVertex2f(dw * i dh * (j + 1)); glVertex2f(dw * i dh * j); glEnd(); ;; int spin = 0; void display(void) GlClear.clear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin 0 1 0); aimLights(); setLights(); glPushMatrix(); glRotatef(-90.0 1 0 0); glScalef(1.9 1.9 1.0); glTranslatef(-0.5 -0.5 0.0); drawPlane(16 16); glPopMatrix(); drawLights(); glPopMatrix(); Glut.swapBuffers(); ;; void animate(void) spin += 0.5; if (spin > 360.0) spin -= 360.0; Glut.postRedisplay(); ;; void visibility(int state) if (state = Glut.VISIBLE) then Glut.idleFunc(animate); } else { Glut.idleFunc(NULL); ;; let main () = int i; Glut.init(&argc argv); Glut.initDisplayMode(Glut.DOUBLE | Glut.RGB); (* process commmand line args *) for (i = 1; i < argc; ++i) { if (!strcmp("-lm" argv[i])) then useSAME_AMB_SPEC = !useSAME_AMB_SPEC; } else { usage(argv[0]); Glut.createWindow("GLUT spotlight swing"); Glut.displayFunc(display); Glut.visibilityFunc(visibility); glMatrixMode(GL_PROJECTION); glFrustum(-1 1 -1 1 2 6); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0 0.0 -3.0); glRotatef(45.0 1 0 0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glLightModelfv(GL_LIGHT_MODEL_AMBIENT modelAmb); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER GL_TRUE); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE GL_FALSE); 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); initLights(); Glut.mainLoop(); return 0; (* ANSI C requires main to return int. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/stars.c000066400000000000000000000206231437514534100237750ustar00rootroot00000000000000 /* 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 #include #include #include #include #include extern void *__glutCurrentWindow; /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265358979323846 #endif enum { NORMAL = 0, WEIRD = 1 }; enum { STREAK = 0, CIRCLE = 1 }; #define MAXSTARS 400 #define MAXPOS 10000 #define MAXWARP 10 #define MAXANGLES 6000 typedef struct _starRec { GLint type; float x[2], y[2], z[2]; float offsetX, offsetY, offsetR, rotation; } starRec; GLenum doubleBuffer; GLint windW = 300, windH = 300; GLenum flag = NORMAL; GLint starCount = MAXSTARS / 2; float speed = 1.0; GLint nitro = 0; starRec stars[MAXSTARS]; float sinTable[MAXANGLES]; float Sin(float angle) { return (sinTable[(int) angle % MAXANGLES]); } float Cos(float angle) { return (sinTable[((int) angle + (MAXANGLES / 4)) % MAXANGLES]); } void NewStar(GLint n, GLint d) { if (rand() % 4 == 0) { stars[n].type = CIRCLE; } else { stars[n].type = STREAK; } stars[n].x[0] = (float) (rand() % MAXPOS - MAXPOS / 2); stars[n].y[0] = (float) (rand() % MAXPOS - MAXPOS / 2); stars[n].z[0] = (float) (rand() % MAXPOS + d); stars[n].x[1] = stars[n].x[0]; stars[n].y[1] = stars[n].y[0]; stars[n].z[1] = stars[n].z[0]; if (rand() % 4 == 0 && flag == WEIRD) { stars[n].offsetX = (float) (rand() % 100 - 100 / 2); stars[n].offsetY = (float) (rand() % 100 - 100 / 2); stars[n].offsetR = (float) (rand() % 25 - 25 / 2); } else { stars[n].offsetX = 0.0; stars[n].offsetY = 0.0; stars[n].offsetR = 0.0; } } void RotatePoint(float *x, float *y, float rotation) { float tmpX, tmpY; tmpX = *x * Cos(rotation) - *y * Sin(rotation); tmpY = *y * Cos(rotation) + *x * Sin(rotation); *x = tmpX; *y = tmpY; } void MoveStars(void) { float offset; GLint n; offset = speed * 60.0; for (n = 0; n < starCount; n++) { stars[n].x[1] = stars[n].x[0]; stars[n].y[1] = stars[n].y[0]; stars[n].z[1] = stars[n].z[0]; stars[n].x[0] += stars[n].offsetX; stars[n].y[0] += stars[n].offsetY; stars[n].z[0] -= offset; stars[n].rotation += stars[n].offsetR; if (stars[n].rotation >= MAXANGLES) { stars[n].rotation = 0.0; } } } GLenum StarPoint(GLint n) { float x0, y0; x0 = stars[n].x[0] * windW / stars[n].z[0]; y0 = stars[n].y[0] * windH / stars[n].z[0]; RotatePoint(&x0, &y0, stars[n].rotation); x0 += windW / 2.0; y0 += windH / 2.0; if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) { return GL_TRUE; } else { return GL_FALSE; } } void ShowStar(GLint n) { float x0, y0, x1, y1, width; GLint i; x0 = stars[n].x[0] * windW / stars[n].z[0]; y0 = stars[n].y[0] * windH / stars[n].z[0]; RotatePoint(&x0, &y0, stars[n].rotation); x0 += windW / 2.0; y0 += windH / 2.0; if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) { if (stars[n].type == STREAK) { x1 = stars[n].x[1] * windW / stars[n].z[1]; y1 = stars[n].y[1] * windH / stars[n].z[1]; RotatePoint(&x1, &y1, stars[n].rotation); x1 += windW / 2.0; y1 += windH / 2.0; glLineWidth(MAXPOS / 100.0 / stars[n].z[0] + 1.0); glColor3f(1.0, (MAXWARP - speed) / MAXWARP, (MAXWARP - speed) / MAXWARP); if (fabs(x0 - x1) < 1.0 && fabs(y0 - y1) < 1.0) { glBegin(GL_POINTS); glVertex2f(x0, y0); glEnd(); } else { glBegin(GL_LINES); glVertex2f(x0, y0); glVertex2f(x1, y1); glEnd(); } } else { width = MAXPOS / 10.0 / stars[n].z[0] + 1.0; glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); for (i = 0; i < 8; i++) { float x = x0 + width * Cos((float) i * MAXANGLES / 8.0); float y = y0 + width * Sin((float) i * MAXANGLES / 8.0); glVertex2f(x, y); }; glEnd(); } } } void UpdateStars(void) { GLint n; glClear(GL_COLOR_BUFFER_BIT); for (n = 0; n < starCount; n++) { if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) { if (StarPoint(n) == GL_FALSE) { NewStar(n, MAXPOS); } } else { NewStar(n, MAXPOS); } } } void ShowStars(void) { GLint n; glClear(GL_COLOR_BUFFER_BIT); for (n = 0; n < starCount; n++) { if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) { ShowStar(n); } } } static void Init(void) { float angle; GLint n; srand((unsigned int) time(NULL)); for (n = 0; n < MAXSTARS; n++) { NewStar(n, 100); } angle = 0.0; for (n = 0; n < MAXANGLES; n++) { sinTable[n] = sin(angle); angle += M_PI / (MAXANGLES / 2.0); } glClearColor(0.0, 0.0, 0.0, 0.0); glDisable(GL_DITHER); } void Reshape(int width, int height) { windW = width; windH = height; glViewport(0, 0, windW, windH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-0.5, windW + 0.5, -0.5, windH + 0.5); glMatrixMode(GL_MODELVIEW); } /* ARGSUSED1 */ static void Key(unsigned char key, int x, int y) { switch (key) { case ' ': flag = (flag == NORMAL) ? WEIRD : NORMAL; break; case 't': nitro = 1; break; case 27: exit(0); } } void Idle(void) { MoveStars(); UpdateStars(); if (nitro > 0) { speed = (float) (nitro / 10) + 1.0; if (speed > MAXWARP) { speed = MAXWARP; } if (++nitro > MAXWARP * 10) { nitro = -nitro; } } else if (nitro < 0) { nitro++; speed = (float) (-nitro / 10) + 1.0; if (speed > MAXWARP) { speed = MAXWARP; } } glutPostRedisplay(); } void Display(void) { ShowStars(); if (doubleBuffer) { glutSwapBuffers(); } else { glFlush(); } } void Visible(int state) { if (state == GLUT_VISIBLE) { glutIdleFunc(Idle); } else { glutIdleFunc(NULL); } } static void Args(int argc, char **argv) { GLint i; doubleBuffer = GL_TRUE; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-sb") == 0) { doubleBuffer = GL_FALSE; } else if (strcmp(argv[i], "-db") == 0) { doubleBuffer = GL_TRUE; } } } int main(int argc, char **argv) { GLenum type; glutInitWindowSize(windW, windH); glutInit(&argc, argv); Args(argc, argv); type = GLUT_RGB; type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; glutInitDisplayMode(type); glutCreateWindow("Stars"); Init(); glutReshapeFunc(Reshape); glutKeyboardFunc(Key); glutVisibilityFunc(Visible); glutDisplayFunc(Display); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } lablgl-1.07/LablGlut/examples/glut3.7/not_yet_ported/stars.ml000077500000000000000000000210161437514534100241630ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Wed Aug 7 02:29:53 MDT 2002. *) open Printf (* 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 #include #include #include #include #include extern void *__glutCurrentWindow; (* Some files do not define M_PI... *) #ifndef M_PI #define M_PI 3.14159265358979323846 #endif enum { NORMAL = 0 WEIRD = 1 }; enum { STREAK = 0 CIRCLE = 1 }; #define MAXSTARS 400 #define MAXPOS 10000 #define MAXWARP 10 #define MAXANGLES 6000 typedef struct _starRec { GLint type; float x[2] y[2] z[2]; float offsetX offsetY offsetR rotation; } starRec; GLenum doubleBuffer; GLint windW = 300 windH = 300; GLenum flag = NORMAL; GLint starCount = MAXSTARS / 2; float speed = 1.0; GLint nitro = 0; starRec stars[MAXSTARS]; float sinTable[MAXANGLES]; float Sin(float angle) return (sinTable[(int) angle % MAXANGLES]); ;; float Cos(float angle) return (sinTable[((int) angle + (MAXANGLES / 4)) % MAXANGLES]); ;; void NewStar(GLint n GLint d) if (rand() % 4 = 0) then stars[n].type = CIRCLE; } else { stars[n].type = STREAK; stars[n].x[0] = (float) (rand() % MAXPOS - MAXPOS / 2); stars[n].y[0] = (float) (rand() % MAXPOS - MAXPOS / 2); stars[n].z[0] = (float) (rand() % MAXPOS + d); stars[n].x[1] = stars[n].x[0]; stars[n].y[1] = stars[n].y[0]; stars[n].z[1] = stars[n].z[0]; if (rand() % 4 = 0 && flag = WEIRD) then stars[n].offsetX = (float) (rand() % 100 - 100 / 2); stars[n].offsetY = (float) (rand() % 100 - 100 / 2); stars[n].offsetR = (float) (rand() % 25 - 25 / 2); } else { stars[n].offsetX = 0.0; stars[n].offsetY = 0.0; stars[n].offsetR = 0.0; ;; void RotatePoint(float *x float *y float rotation) float tmpX tmpY; tmpX = *x * Cos(rotation) - *y * Sin(rotation); tmpY = *y * Cos(rotation) + *x * Sin(rotation); *x = tmpX; *y = tmpY; ;; void MoveStars(void) float offset; GLint n; offset = speed * 60.0; incr for (n = 0; n < starCount; n) { stars[n].x[1] = stars[n].x[0]; stars[n].y[1] = stars[n].y[0]; stars[n].z[1] = stars[n].z[0]; stars[n].x[0] += stars[n].offsetX; stars[n].y[0] += stars[n].offsetY; stars[n].z[0] -= offset; stars[n].rotation += stars[n].offsetR; if (stars[n].rotation >= MAXANGLES) then stars[n].rotation = 0.0; ;; GLenum StarPoint(GLint n) float x0 y0; x0 = stars[n].x[0] * windW / stars[n].z[0]; y0 = stars[n].y[0] * windH / stars[n].z[0]; RotatePoint(&x0 &y0 stars[n].rotation); x0 += windW / 2.0; y0 += windH / 2.0; if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) then return GL_TRUE; } else { return GL_FALSE; ;; void ShowStar(GLint n) float x0 y0 x1 y1 width; GLint i; x0 = stars[n].x[0] * windW / stars[n].z[0]; y0 = stars[n].y[0] * windH / stars[n].z[0]; RotatePoint(&x0 &y0 stars[n].rotation); x0 += windW / 2.0; y0 += windH / 2.0; if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) then if (stars[n].type = STREAK) then x1 = stars[n].x[1] * windW / stars[n].z[1]; y1 = stars[n].y[1] * windH / stars[n].z[1]; RotatePoint(&x1 &y1 stars[n].rotation); x1 += windW / 2.0; y1 += windH / 2.0; glLineWidth(MAXPOS / 100.0 / stars[n].z[0] + 1.0); glColor3f(1.0 (MAXWARP - speed) / MAXWARP (MAXWARP - speed) / MAXWARP); if (fabs(x0 - x1) < 1.0 && fabs(y0 - y1) < 1.0) then glBegin(GL_POINTS); glVertex2f(x0 y0); glEnd(); } else { glBegin(GL_LINES); glVertex2f(x0 y0); glVertex2f(x1 y1); glEnd(); } else { width = MAXPOS / 10.0 / stars[n].z[0] + 1.0; glColor3f(1.0 0.0 0.0); glBegin(GL_POLYGON); incr for (i = 0; i < 8; i) { float x = x0 + width * Cos((float) i * MAXANGLES / 8.0); float y = y0 + width * Sin((float) i * MAXANGLES / 8.0); glVertex2f(x y); }; glEnd(); ;; void UpdateStars(void) GLint n; GlClear.clear(GL_COLOR_BUFFER_BIT); incr for (n = 0; n < starCount; n) { if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) then if (StarPoint(n) = GL_FALSE) then NewStar(n MAXPOS); } else { NewStar(n MAXPOS); ;; void ShowStars(void) GLint n; GlClear.clear(GL_COLOR_BUFFER_BIT); incr for (n = 0; n < starCount; n) { if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) then ShowStar(n); ;; static void Init(void) float angle; GLint n; srand((unsigned int) time(NULL)); incr for (n = 0; n < MAXSTARS; n) { NewStar(n 100); angle = 0.0; incr for (n = 0; n < MAXANGLES; n) { sinTable[n] = sin(angle); angle += M_PI / (MAXANGLES / 2.0); GlClear.clearColor(0.0 0.0 0.0 0.0); glDisable(GL_DITHER); ;; void Reshape(int width int height) windW = width; windH = height; glViewport(0 0 windW windH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-0.5 windW + 0.5 -0.5 windH + 0.5); glMatrixMode(GL_MODELVIEW); ;; (* ARGSUSED1 *) static void Key(unsigned char key int x int y) match key with | ' ' -> flag = (flag = NORMAL) ? WEIRD : NORMAL; break; | 't' -> nitro = 1; break; | 27 -> exit(0); ;; void Idle(void) MoveStars(); UpdateStars(); if (nitro > 0) then speed = (float) (nitro / 10) + 1.0; if (speed > MAXWARP) then speed = MAXWARP; if (++nitro > MAXWARP * 10) then nitro = -nitro; } else if (nitro < 0) then incr nitro; speed = (float) (-nitro / 10) + 1.0; if (speed > MAXWARP) then speed = MAXWARP; Glut.postRedisplay(); ;; void Display(void) ShowStars(); if (doubleBuffer) then Glut.swapBuffers(); } else { Gl.flush(); ;; void Visible(int state) if (state = Glut.VISIBLE) then Glut.idleFunc(Idle); } else { Glut.idleFunc(NULL); ;; static void Args(int argc char **argv) GLint i; doubleBuffer = GL_TRUE; incr for (i = 1; i < argc; i) { if (strcmp(argv[i] "-sb") = 0) then doubleBuffer = GL_FALSE; } else if (strcmp(argv[i] "-db") = 0) then doubleBuffer = GL_TRUE; ;; int main(int argc char **argv) GLenum type; Glut.initWindowSize(windW windH); Glut.init(&argc argv); Args(argc argv); type = Glut.RGB; type |= (doubleBuffer) ? Glut.DOUBLE : Glut.SINGLE; Glut.initDisplayMode(type); Glut.createWindow("Stars"); Init(); Glut.reshapeFunc(Reshape); Glut.keyboardFunc(Key); Glut.visibilityFunc(Visible); Glut.displayFunc(Display); Glut.mainLoop(); return 0; (* ANSI C requires main to return int. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/000077500000000000000000000000001437514534100204135ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/test/TAGS000066400000000000000000000272171437514534100211050ustar00rootroot00000000000000 cursor_test.ml,443 let c2i c = match c with c2i13,333 let i2c i = match i withi2c39,1098 let cursors = [|cursors66,1926 let name = [|name92,2552 let win = ref (-1);;win118,2945 let futureSetCursor ~value = Glut.setCursor(Glut.CURSOR_HELP) ;;futureSetCursor120,2967 let willret = ref true ;;willret122,3033 let menu ~value = menu124,3060 let display () = display153,3817 let keyboard ~key ~x ~y = keyboard158,3881 let main () = main161,3945 joy_test.ml,220 let joystick ~buttonMask ~x ~y ~z = joystick13,346 let joyPoll () = joyPoll17,449 let menu ~value = menu22,537 let display () = display39,917 let keyboard ~key ~x ~y = keyboard44,981 let main() = main48,1044 keyup_test.ml,259 let keyboard ~key ~x ~y = keyboard13,352 let keyup ~key ~x ~y = keyup17,453 let special ~key ~x ~y = special21,553 let specialup ~key ~x ~y = specialup25,669 let menu ~value = menu29,787 let display () = display45,1341 let main () = main50,1405 menu_test.ml,572 let win = ref(-1)win13,346 let subwin = ref(-1)subwin14,364 let mainmenu = ref(-1)mainmenu15,385 let submenu = ref(-1)submenu16,408 let item = ref 666item17,430 let fail where = failwith ("menu_test failed in "^where)fail19,450 let display () = display21,508 let gokey ~key ~x ~y = gokey26,572 let keyboard ~key ~x ~y = keyboard107,2739 let keyboard2 ~key ~x ~y = keyboard2112,2815 let menu ~value = printf "menu: entry = %d\n" value ;;menu117,2891 let menu2 ~value = printf "menu2: entry = %d\n" value ;;menu2119,2947 let main () = main121,3005 shape_test.ml,387 let w = ref 0 and h = ref 0w13,346 let light_diffuse = (1.0, 1.0, 1.0, 1.0)light_diffuse15,375 let light_position = (1.0, 1.0, 1.0, 1.0)light_position16,416 let qobj = ref Noneqobj18,459 let workaround w' h' = workaround23,682 let reshape ~w ~h = workaround w h;;reshape28,731 let render shape = render30,769 let display () = display147,3498 let main () = main159,3780 test1.ml,24 let main = main14,357 test10.ml,342 let ch = ref (-2);;ch26,725 let fonts = [|fonts28,746 let names = [|names41,1023 let num_fonts = (Array.length fonts);;num_fonts54,1253 let font = ref 0;;font55,1292 let limit = ref 270;; limit57,1312 let tick () = tick58,1335 let output ~x ~y ~msg = output76,1657 let display () =display83,1836 let main() = main108,2741 test11.ml,27 let main () = main13,331 test12.ml,27 let main () = main15,364 test13.ml,613 let window1 = ref (-1);;window115,364 let window2 = ref (-1);;window216,389 let win1reshaped = ref false;;win1reshaped17,414 let win2reshaped = ref false;;win2reshaped18,445 let win1displayed = ref false;;win1displayed19,476 let win2displayed = ref false;;win2displayed20,508 let checkifdone () =checkifdone22,541 let window1reshape ~w ~h =window1reshape31,733 let window1display () =window1display37,898 let window2reshape ~w ~h = window2reshape46,1115 let window2display () =window2display52,1281 let timefunc ~value = failwith(" test13\n") ;;timefunc61,1498 let main () = main63,1546 test14.ml,177 let displayFunc () = displayFunc15,392 let menuFunc ~value = printf "choice = %d\n" value ;;menuFunc20,460 let timefunc ~value = timefunc22,515 let main () = main28,627 test15.ml,287 let light_position = [|1.0, 1.0, 1.0, 0.0|];;light_position20,701 let qobj = GluQuadric.create ();;qobj21,747 let tesselation = ref 3;;tesselation23,782 let displayFunc () = displayFunc25,809 let timefunc ~value = failwith "test15";;timefunc41,1224 let main () = main43,1267 test16.ml,161 let shape = ref 1;;shape16,400 let displayFunc () = displayFunc17,420 let timefunc ~value = failwith "test16";;timefunc49,1362 let main () = main51,1405 test18.ml,769 let transP = ref 0 and opaqueP = ref 0transP14,395 let main_win = ref 0 and sub_win = ref 0main_win15,434 let overlaySupported = ref falseoverlaySupported16,476 let subHidden = ref false and overlayHidden = ref falsesubHidden17,509 let warnIfNormalDisplay = ref falsewarnIfNormalDisplay18,565 let firstTime = ref truefirstTime19,601 let fail18() = failwith "test18"fail1821,627 let time5_cb ~value = time5_cb23,661 let time4_cb ~value = time4_cb29,759 let time3_cb ~value = time3_cb39,1025 let time2_cb ~value = time2_cb48,1229 let time_cb ~value = time_cb61,1513 let display () =display69,1678 let subDisplay () = subDisplay84,2094 let overDisplay () = overDisplay94,2340 let subVis ~state = subVis104,2589 let main () =main116,2970 test19.ml,253 let width = ref (-1);;width14,353 let height = ref (-1);;height15,376 let displayCount = ref 0;;displayCount16,400 let onDone ~value = onDone18,428 let reshape ~w ~h = reshape24,574 let display () = display30,681 let main () = main44,1079 test2.ml,490 let count = ref 0;;count17,329 let save_count = ref 0;;save_count19,350 let head = ref 0;;head20,375 let tail = ref 0;;tail21,394 let diff = ref 0;;diff22,413 let timer2 ~value = timer224,433 let timer ~value = timer31,649 let menuSelect ~value = () ;; (* do nothing *)menuSelect50,1377 let never_void () =never_void52,1425 let never_value ~state = never_value58,1603 let the_win = ref (-1);;the_win64,1785 let display () = display66,1811 let main () =main72,1902 test20.ml,95 let wrangleExtensionName ~extension = wrangleExtensionName15,376 let main () = main46,1464 test22.ml,711 let win = ref(-1)win15,402 let subwin = ref(-1)subwin16,420 let cover = ref(-1)cover17,441 let fail x = failwith ("test22 " ^ x)fail19,462 let display () = display21,501 let time_end ~value = time_end26,581 let time5 ~value = time531,647 let time4 ~value = time436,728 let time3 ~value = time341,801 let sub_state = ref 0sub_state46,874 let cover_state = ref 0cover_state47,896 let super_state = ref 0super_state48,920 let coverstat ~state = coverstat50,945 let time2 ~value = time263,1329 let substat ~state = substat70,1501 let time1 ~value = time197,2290 let winstat ~state = winstat107,2611 let visbad ~state = fail "visbad" ;;visbad121,3055 let main () = main123,3093 test23.ml,164 let modes = [|modes16,448 let strings = [|strings23,587 let ostrings = [| ostrings34,839 let verbose = ref false;;verbose43,993 let main () = main45,1020 test24.ml,140 let display () = display17,536 let timer ~value = timer22,602 let menuSelect ~value = ();;menuSelect28,722 let main () = main30,752 test25.ml,644 let abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"abc15,392 let null = ""null17,458 let space = " "space18,472 let bitmap_fonts = [|bitmap_fonts20,494 let bitmap_names = [| bitmap_names29,715 let bitmap_lens = [|bitmap_lens38,867 let bitmap_abc_lens = [|bitmap_abc_lens47,953 let stroke_fonts = [|stroke_fonts56,1036 let stroke_names = [|stroke_names60,1109 let stroke_lens = [| stroke_lens64,1168 let stroke_abc_lens = [|stroke_abc_lens68,1210 let array_do a f = for i = 0 to ((Array.length a)-1) do f i donearray_do74,1362 let (+=) x y = x := !x + y;; (* :) *)x76,1428 let main () = main78,1467 test26.ml,815 let window1 = ref(-1);;window116,454 let window2 = ref(-1);;window217,478 let win1displayed = ref 0;;win1displayed18,502 let win2displayed = ref 0;;win2displayed19,530 let win1vis = ref Glut.NOT_VISIBLE;;win1vis20,558 let win2vis = ref Glut.NOT_VISIBLE;;win2vis21,595 let overlaySupported = ref false;;overlaySupported26,690 let over1displayed = ref 0;;over1displayed27,725 let checkifdone () = checkifdone29,755 let window1display () = window1display37,960 let overDisplay () =overDisplay46,1177 let window2display () = window2display54,1324 let timefunc ~value = failwith(" test26\n") ;;timefunc63,1547 let count = ref 0;;count65,1595 let idle () = idle66,1615 let window1vis ~state = window1vis78,1943 let window2status ~state = window2status85,2174 let main () = main93,2442 test27.ml,468 let parent = ref 0;;parent17,509 let child = ref 0;;child18,530 let parentDrawn = ref false;;parentDrawn20,551 let childDrawn = ref false;;childDrawn21,581 let failTest ~value = failwith(" test27\n") ;;failTest23,611 let passTest ~value = passTest25,659 let installFinish () = installFinish30,730 let output ~x ~y ~str = output35,839 let displayParent () = displayParent43,1041 let displayChild () = displayChild50,1153 let main () = main61,1399 test28.ml,201 let fake_argv = [| "program" ; "-iconic"; |];;fake_argv13,331 let displayed = ref false;;displayed15,379 let display () = display17,408 let timer ~value = timer24,540 let main () =main31,691 test3.ml,402 let n = 6;;n16,331 let m = 6;;m17,343 let exposed = Array.create (m*n) false;;exposed19,356 let ecount = ref 0;;ecount20,397 let viewable = Array.create (m*n) false;;viewable22,419 let vcount = ref 0;;vcount23,461 let display () = display25,483 let view ~state = view39,781 let timer ~value = if (value <> 23) then failwith "bad timer value";;timer51,1044 let main () = main53,1115 test4.ml,196 let ch = ref(-2);;ch16,331 let font = ref Glut.STROKE_ROMAN;;font18,351 let tick () = tick20,387 let mytick () = ();;mytick33,639 let display () =display35,661 let main() = main44,829 test6.ml,1070 let mouseButtons = ref(-1);;mouseButtons17,501 let display () =display19,531 let time7 ~value = time724,594 let int_of_menu_state s = int_of_menu_state30,716 let mstatus ~status = printf "state : %d\n" (int_of_menu_state status);;mstatus33,811 let mstatus2 ~status ~x ~y = mstatus235,885 let menu2 ~value = menu238,986 let time6 ~value = time646,1227 let estate = ref 0;;estate58,1623 let entry ~state =entry60,1645 let time5 ~value = time572,2007 let motion ~x ~y = motion78,2174 let time4 ~value = time484,2308 let passive ~x ~y =passive90,2491 let time3 ~value = time396,2630 let mode = ref 0;;mode102,2827 let mouse ~button ~state ~x ~y =mouse104,2847 let menu ~value = failwith(" menu callback should never be called\n") ;;menu209,6811 let time2 ~value = time2211,6885 let smode = ref 0;;smode242,8029 let special ~key ~x ~y = special248,8215 let time1 ~value = time1284,9407 let kmode = ref 0;;kmode296,9820 let keyboard ~key ~x ~y = keyboard298,9841 let time0 ~value = time0334,11049 let main() = main341,11256 test7.ml,447 let w1 = ref 0;;w113,331 let w2 = ref 0;;w214,348 let display () = GlClear.clear [`color] ;;display16,366 let time9 ~value = time918,410 let time8 ~value = time824,533 let time7 ~value = time736,889 let time6 ~value = time651,1400 let time5 ~value = time561,1671 let time4 ~value = time489,2775 let time3 ~value = time3101,3110 let time2 ~value = time2111,3353 let time1 ~value = time1121,3597 let main () = main131,3883 test8.ml,352 let main_w = ref(-1)main_w13,352 let w = [| 0; 0; 0; 0 |]w14,373 let win = ref(-1)win15,398 let num = ref(-1)num16,416 let fail_childnum () = fail_childnum18,435 let fail_bad_parent () = fail_bad_parent21,529 let time2 ~value =time224,619 let time1 ~value = time129,680 let display () = ();;display45,1143 let main () = main47,1166 test9.ml,472 let main_w = ref 0;;main_w13,358 let w1 = ref 0;;w114,379 let w2 = ref 0;;w215,396 let w3 = ref 0;;w316,413 let w4 = ref 0;;w417,430 let display () = display19,448 let time8 ~value = time824,520 let time7 ~value = time729,587 let time6 ~value = time634,675 let time5 ~value = time554,1351 let time4 ~value =time468,1806 let time3 ~value = time373,1888 let time2 ~value = time278,1971 let time1 ~value = time183,2054 let main () = main88,2137 timer_test.ml,184 let display () = display24,852 let rec timer ~value = timer29,916 let num_times = ref 0;;num_times34,1024 let keyboard ~key ~x ~y = keyboard36,1049 let main () = main45,1290 lablgl-1.07/LablGlut/examples/glut3.7/test/cursor_test.ml000077500000000000000000000114341437514534100233270ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 2002. *) open Printf (* 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. *) let c2i c = match c with | Glut.CURSOR_RIGHT_ARROW -> 0 | Glut.CURSOR_LEFT_ARROW -> 1 | Glut.CURSOR_INFO -> 2 | Glut.CURSOR_DESTROY -> 3 | Glut.CURSOR_HELP -> 4 | Glut.CURSOR_CYCLE -> 5 | Glut.CURSOR_SPRAY -> 6 | Glut.CURSOR_WAIT -> 7 | Glut.CURSOR_TEXT -> 8 | Glut.CURSOR_CROSSHAIR -> 9 | Glut.CURSOR_UP_DOWN -> 10 | Glut.CURSOR_LEFT_RIGHT -> 11 | Glut.CURSOR_TOP_SIDE -> 12 | Glut.CURSOR_BOTTOM_SIDE -> 13 | Glut.CURSOR_LEFT_SIDE -> 14 | Glut.CURSOR_RIGHT_SIDE -> 15 | Glut.CURSOR_TOP_LEFT_CORNER -> 16 | Glut.CURSOR_TOP_RIGHT_CORNER -> 17 | Glut.CURSOR_BOTTOM_RIGHT_CORNER -> 18 | Glut.CURSOR_BOTTOM_LEFT_CORNER -> 19 | Glut.CURSOR_INHERIT -> 100 | Glut.CURSOR_NONE -> 101 | Glut.CURSOR_FULL_CROSSHAIR -> 102 ;; let i2c i = match i with | 0 -> Glut.CURSOR_RIGHT_ARROW | 1 -> Glut.CURSOR_LEFT_ARROW | 2 -> Glut.CURSOR_INFO | 3 -> Glut.CURSOR_DESTROY | 4 -> Glut.CURSOR_HELP | 5 -> Glut.CURSOR_CYCLE | 6 -> Glut.CURSOR_SPRAY | 7 -> Glut.CURSOR_WAIT | 8 -> Glut.CURSOR_TEXT | 9 -> Glut.CURSOR_CROSSHAIR | 10 -> Glut.CURSOR_UP_DOWN | 11 -> Glut.CURSOR_LEFT_RIGHT | 12 -> Glut.CURSOR_TOP_SIDE | 13 -> Glut.CURSOR_BOTTOM_SIDE | 14 -> Glut.CURSOR_LEFT_SIDE | 15 -> Glut.CURSOR_RIGHT_SIDE | 16 -> Glut.CURSOR_TOP_LEFT_CORNER | 17 -> Glut.CURSOR_TOP_RIGHT_CORNER | 18 -> Glut.CURSOR_BOTTOM_RIGHT_CORNER | 19 -> Glut.CURSOR_BOTTOM_LEFT_CORNER | 100 -> Glut.CURSOR_INHERIT | 101 -> Glut.CURSOR_NONE | 102 -> Glut.CURSOR_FULL_CROSSHAIR | _ -> failwith "bad int given for conversion to Glut.CURSor" ;; let cursors = [| Glut.CURSOR_INHERIT ; Glut.CURSOR_NONE ; Glut.CURSOR_FULL_CROSSHAIR ; Glut.CURSOR_RIGHT_ARROW ; Glut.CURSOR_LEFT_ARROW ; Glut.CURSOR_INFO ; Glut.CURSOR_DESTROY ; Glut.CURSOR_HELP ; Glut.CURSOR_CYCLE ; Glut.CURSOR_SPRAY ; Glut.CURSOR_WAIT ; Glut.CURSOR_TEXT ; Glut.CURSOR_CROSSHAIR ; Glut.CURSOR_UP_DOWN ; Glut.CURSOR_LEFT_RIGHT ; Glut.CURSOR_TOP_SIDE ; Glut.CURSOR_BOTTOM_SIDE ; Glut.CURSOR_LEFT_SIDE ; Glut.CURSOR_RIGHT_SIDE ; Glut.CURSOR_TOP_LEFT_CORNER ; Glut.CURSOR_TOP_RIGHT_CORNER ; Glut.CURSOR_BOTTOM_RIGHT_CORNER ; Glut.CURSOR_BOTTOM_LEFT_CORNER |];; let name = [| "INHERIT" ; "NONE" ; "FULL CROSSHAIR" ; "RIGHT ARROW" ; "LEFT ARROW" ; "INFO" ; "DESTROY" ; "HELP" ; "CYCLE" ; "SPRAY" ; "WAIT" ; "TEXT" ; "CROSSHAIR" ; "UP DOWN" ; "LEFT RIGHT" ; "TOP SIDE" ; "BOTTOM SIDE" ; "LEFT SIDE" ; "RIGHT SIDE" ; "TOP LEFT CORNER" ; "TOP RIGHT CORNER" ; "BOTTOM RIGHT CORNER" ; "BOTTOM LEFT CORNER" |];; let win = ref (-1);; let futureSetCursor ~value = Glut.setCursor(Glut.CURSOR_HELP) ;; let willret = ref true ;; let menu ~value = print_newline(); if(value < 0) then begin match value with | -1 -> begin Glut.setWindow(!win); Glut.warpPointer 25 25 ; end | -2 -> begin Glut.setWindow(!win); Glut.warpPointer(-25) (-25); end | -3 -> begin Glut.setWindow(!win); Glut.warpPointer 250 250 ; end | -4 -> begin Glut.setWindow(!win); Glut.warpPointer 2000 200; end | -5 -> Glut.timerFunc 3000 futureSetCursor (Glut.getWindow()) ; | _ -> willret := false; end else begin Glut.setCursor(i2c value); let i = Glut.get(Glut.WINDOW_CURSOR) in if (i <> value) then failwith "cursor_test : cursor not set right"; end ;; let display () = GlClear.clear [`color]; Gl.flush(); ;; let keyboard ~key ~x ~y = if key = 27 (*esc*) then exit 0;; let main () = ignore(Glut.init Sys.argv); win := Glut.createWindow("cursor test"); GlClear.color (0.49, 0.62, 0.75); Glut.displayFunc(display); Glut.keyboardFunc keyboard; ignore(Glut.createMenu(menu)); for i = 0 to ((Array.length name)-1) do Glut.addMenuEntry name.(i) (c2i cursors.(i)) ; done; Glut.addMenuEntry "Warp to (25 25)" (-1); Glut.addMenuEntry "Warp to (-25 -25)" (-2); Glut.addMenuEntry "Warp to (250 250)" (-3); Glut.addMenuEntry "Warp to (2000 200)" (-4); Glut.addMenuEntry "Set cursor in 3 secs" (-5); Glut.attachMenu(Glut.RIGHT_BUTTON); ignore(Glut.createSubWindow !win 10 10 90 90 ); Glut.attachMenu(Glut.RIGHT_BUTTON); GlClear.color (0.3, 0.82, 0.55); Glut.displayFunc(display); ignore(Glut.createSubWindow !win 80 80 90 90); Glut.attachMenu(Glut.RIGHT_BUTTON); GlClear.color (0.9, 0.2, 0.2); Glut.displayFunc(display); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/joy_test.ml000077500000000000000000000027131437514534100226130ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:22:04 MDT 2002. *) open Printf (* 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. *) let joystick ~buttonMask ~x ~y ~z = printf "joy 0x%x x=%d y=%d z=%d\n" buttonMask x y z; ;; let joyPoll () = printf("force"); print_newline(); Glut.forceJoystickFunc(); ;; let menu ~value = match value with | 1 -> begin Glut.joystickFunc joystick 100 ; Glut.idleFunc None; end | 2 -> begin Glut.joystickFunc (fun ~buttonMask ~x ~y ~z ->()) 0; Glut.idleFunc None; end | 3 -> begin Glut.joystickFunc joystick 0 ; Glut.idleFunc(Some joyPoll); end | _ -> failwith "invalid menu value" ;; let display () = GlClear.clear [`color]; Gl.flush(); ;; let keyboard ~key ~x ~y = if (key = 27) then exit(0); ;; let main() = ignore(Glut.init Sys.argv); ignore(Glut.createWindow("joystick test")); GlClear.color (0.29, 0.62, 1.0) ; Glut.displayFunc(display); Glut.keyboardFunc(keyboard); ignore(Glut.createMenu(menu)); Glut.addMenuEntry "Enable joystick callback" 1 ; Glut.addMenuEntry "Disable joystick callback" 2 ; Glut.addMenuEntry "Force joystick polling" 3 ; Glut.attachMenu(Glut.RIGHT_BUTTON); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/keyup_test.ml000077500000000000000000000042231437514534100231450ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21 -> 18 -> 25 MDT 2002. *) open Printf (* 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. *) let keyboard ~key ~x ~y = printf "kDN -> %d <%d> @ (%d %d)" key key x y; print_newline();; let keyup ~key ~x ~y = printf "kUP -> %d <%d> @ (%d %d)" key key x y ; print_newline();; let special ~key ~x ~y = printf "sDN -> %s @ (%d %d)" (Glut.string_of_special key) x y ; print_newline();; let specialup ~key ~x ~y = printf "sUP -> %s @ (%d %d)" (Glut.string_of_special key) x y ; print_newline();; let menu ~value = printf "menu_cb"; print_newline(); match value with | 1 -> Glut.ignoreKeyRepeat(true); | 2 -> Glut.ignoreKeyRepeat(false); | 3 -> Glut.keyboardFunc (fun ~key ~x ~y -> ()); | 4 -> Glut.keyboardFunc(keyboard); | 5 -> Glut.keyboardUpFunc (fun ~key ~x ~y -> ()); | 6 -> Glut.keyboardUpFunc(keyup); | 7 -> Glut.specialFunc (fun ~key ~x ~y -> ()); | 8 -> Glut.specialFunc(special); | 9 -> Glut.specialUpFunc (fun ~key ~x ~y -> ()); | 10 -> Glut.specialUpFunc(specialup); | _ -> failwith "bad menu in menu_cb" ;; let display () = GlClear.clear [`color]; Gl.flush(); ;; let main () = ignore(Glut.init Sys.argv); ignore(Glut.createWindow("keyup test")); GlClear.color (0.49, 0.62, 0.75); Glut.displayFunc(display); Glut.keyboardFunc(keyboard); Glut.keyboardUpFunc(keyup); Glut.specialFunc(special); Glut.specialUpFunc(specialup); ignore(Glut.createMenu(menu)); Glut.addMenuEntry "Ignore autorepeat" 1; Glut.addMenuEntry "Accept autorepeat" 2; Glut.addMenuEntry "Stop key" 3; Glut.addMenuEntry "Start key" 4; Glut.addMenuEntry "Stop key up" 5; Glut.addMenuEntry "Start key up" 6; Glut.addMenuEntry "Stop special" 7; Glut.addMenuEntry "Start special" 8; Glut.addMenuEntry "Stop special up" 9; Glut.addMenuEntry "Start special up" 10; Glut.attachMenu(Glut.RIGHT_BUTTON); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/menu_test.ml000077500000000000000000000072451437514534100227630ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 17:48:54 MDT 2002. *) open Printf let win = ref(-1) let subwin = ref(-1) let mainmenu = ref(-1) let submenu = ref(-1) let item = ref 666 let fail where = failwith ("menu_test failed in "^where) let display () = GlClear.clear [`color]; Gl.flush(); ;; let gokey ~key ~x ~y = let mods = Glut.getModifiers() in printf "key = %d mods = 0x%x\n" key mods; if (mods land Glut.active_alt <> 0) then match char_of_int key with | '1' -> begin printf "Change to sub menu 1\n"; Glut.changeToSubMenu 1 "sub 1" !submenu; end | '2' -> begin printf "Change to sub menu 2\n"; Glut.changeToSubMenu 2 "sub 2" !submenu; end | '3' -> begin printf "Change to sub menu 3\n"; Glut.changeToSubMenu 3 "sub 3" !submenu; end | '4' -> begin printf "Change to sub menu 4\n"; Glut.changeToSubMenu 4 "sub 4" !submenu; end | '5' -> begin printf "Change to sub menu 5\n"; Glut.changeToSubMenu 5 "sub 5" !submenu; end; | _ -> (); else match char_of_int key with | '1' -> begin printf "Change to menu entry 1\n"; Glut.changeToMenuEntry 1 "entry 1" 1; end | '2' -> begin printf "Change to menu entry 2\n"; Glut.changeToMenuEntry 2 "entry 2" 2; end | '3' -> begin printf "Change to menu entry 3\n"; Glut.changeToMenuEntry 3 "entry 3" 3; end | '4' -> begin printf "Change to menu entry 4\n"; Glut.changeToMenuEntry 4 "entry 4" 4; end | '5' -> begin printf "Change to menu entry 5\n"; Glut.changeToMenuEntry 5 "entry 5" 5; end | 'a' | 'A' -> begin printf "Adding menu entry %d\n" !item; Glut.addMenuEntry (sprintf "added entry %d" !item) !item; incr item; end | 's' | 'S' -> begin printf "Adding !submenu %d\n" !item; Glut.addSubMenu (sprintf "added !submenu %d" !item) !submenu; incr item; end | 'q' -> begin printf "Remove 1\n"; Glut.removeMenuItem 1; end | 'w' -> begin printf "Remove 2\n"; Glut.removeMenuItem 2; end | 'e' -> begin printf "Remove 3\n"; Glut.removeMenuItem 3; end | 'r' -> begin printf "Remove 4\n"; Glut.removeMenuItem 4; end | 't' -> begin printf "Remove 5\n"; Glut.removeMenuItem 5; end | _ -> (); ;; let keyboard ~key ~x ~y = Glut.setMenu !mainmenu; gokey key x y; ;; let keyboard2 ~key ~x ~y = Glut.setMenu !submenu; gokey key x y; ;; let menu ~value = printf "menu: entry = %d\n" value ;; let menu2 ~value = printf "menu2: entry = %d\n" value ;; let main () = ignore(Glut.init Sys.argv); win := Glut.createWindow "menu test"; GlClear.color (0.3, 0.3, 0.3); Glut.displayFunc display; Glut.keyboardFunc keyboard; submenu := Glut.createMenu menu2; Glut.addMenuEntry "Sub menu 1" 1001; Glut.addMenuEntry "Sub menu 2" 1002; Glut.addMenuEntry "Sub menu 3" 1003; mainmenu := Glut.createMenu menu; Glut.addMenuEntry "First" (-1); Glut.addMenuEntry "Second" (-2); Glut.addMenuEntry "Third" (-3); Glut.addSubMenu "Submenu init" !submenu; Glut.attachMenu Glut.RIGHT_BUTTON; subwin := Glut.createSubWindow !win 50 50 50 50; GlClear.color (0.7, 0.7, 0.7); Glut.displayFunc display; Glut.keyboardFunc keyboard2; Glut.mainLoop (); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/000077500000000000000000000000001437514534100234515ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/TAGS000066400000000000000000000010131437514534100241250ustar00rootroot00000000000000 bigtest.ml,0 over_test.ml,0 test17.ml,0 test21.ml,461 let light_diffuse = (1.0,0.0,0.0)light_diffuse16,440 let light_position = (1.0,1.0,1.0)light_position17,474 let x=ref 0 and y=ref 0 and w=ref 0 and h=ref 0x18,509 let dx=ref 0 and dy=ref 0 and dw=ref 0 and dh=ref 0dx19,557 let (-=) x y = x := !x - yx21,610 let (+=) x y = x := !x + yx22,637 let display () = display24,665 let show_video_size() =show_video_size30,766 let keyboard ~key ~x ~y = keyboard41,1156 let time2 ~value = time259,1760 lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/bigtest.c000066400000000000000000001607611437514534100252710ustar00rootroot00000000000000 /** * My first GLUT prog. * Uses most GLUT calls to prove it all works. * G Edwards, 30 Aug 95. * * Notes: * Display lists are not shared between windows, and there doesn't seem to be * any provision for this in GLUT. See glxCreateContext. * * The windows are internally indexed 0,1,2,3,4,5,6. The actual window ids * returned by glut are held in winId[0], ... * * Todo: * * Could reorder the windows so 0,1,2,3,4,5,6 are the gfx, 7,8 text. * * 30 Aug 95 GJE Created. Version 1.00 * 05 Sep 95 GJE Version 1.01. * 07 Sep 95 GJE Version 1.02. More or less complete. All possible GLUT * calls used, except dials/buttons/tablet/spaceball stuff. * 15 Sep 95 GJE Add "trackball" code. * * Calls not used yet: these callbacks are registered but inactive. * * glutSpaceballFunc * glutButtonBoxFunc * glutDialsFunc * glutTabletMotionFunc * glutTabletButtonFunc * * Tested on: * R3K Indigo Starter * R4K Indigo Elan * R4K Indy XZ * R4K Indy XL * R4K Indigo2 Extreme */ #include #include #include #include #include /* Controls */ #define VERSION "1.00" #define DATE "16Sep95" #define DELAY 1000 /* delay for timer test */ #define MENUDELAY 200 /* hack to fix glutMenuStateFunc bug */ #define MAXWIN 9 /* max no. of windows */ unsigned int AUTODELAY = 1500; /* delay in demo mode */ #define VERSIONLONG "Version " VERSION "/" DATE ", compiled " __DATE__ ", " __TIME__ ", file " __FILE__ int pos[MAXWIN][2] = { {50, 150}, /* win 0 */ {450, 150}, /* win 1 */ {50, 600}, /* win 2 */ {450, 600}, /* win 3 */ {10, 10}, /* subwin 4 (relative to parent win 0) */ {300, 400}, /* help win 5 */ {850, 150}, /* cmap win 6 */ {850, 600}, /* cmap win 7 */ {250, 450} /* text win 8 */ }; int size[MAXWIN][2] = { {350, 350}, /* win 0 */ {350, 350}, /* win 1 */ {350, 350}, /* win 2 */ {350, 350}, /* win 3 */ {200, 200}, /* subwin 4 */ {700, 300}, /* help win 5 */ {350, 350}, /* cmap win 6 */ {350, 350}, /* cmap win 7 */ {800, 450} /* text win 8 */ }; /* Macros */ #define PR if(debug)printf /* #define GLNEWLIST(a, b) glNewList(a, b), fprintf(stderr, "creating list %d \n", a); */ /* #define GLCALLLIST(a) glCallList(a), fprintf(stderr, "calling list %d \n", a); */ /* #define GLUTSETWINDOW(x) glutSetWindow(x), fprintf(stderr, "gsw at %d\n", __LINE__) */ /* Globals */ int winId[MAXWIN] = {0}; /* table of glut window id's */ GLboolean winVis[MAXWIN] = {GL_FALSE}; /* is window visible */ GLboolean text[MAXWIN] = {GL_FALSE}; /* is text on */ GLboolean winFreeze[MAXWIN] = {GL_FALSE}; /* user requested menuFreeze */ GLboolean menuFreeze = GL_FALSE; /* menuFreeze while menus posted */ GLboolean timerOn = GL_FALSE; /* timer active */ GLboolean animation = GL_TRUE; /* idle func animation on */ GLboolean debug = GL_FALSE; /* dump all events */ GLboolean showKeys = GL_FALSE; /* dump key events */ GLboolean demoMode = GL_FALSE; /* run automatic demo */ GLboolean backdrop = GL_FALSE; /* use backdrop polygon */ GLboolean passive = GL_FALSE; /* report passive motions */ GLboolean leftDown = GL_FALSE; /* left button down ? */ GLboolean middleDown = GL_FALSE; /* middle button down ? */ int displayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH; int currentShape = 0; /* current glut shape */ int scrollLine = 0, scrollCol = 0; /* help scrolling params */ int lineWidth = 1; /* line width */ int angle = 0; /* global rotation angle */ char *textPtr[1000] = {0}; /* pointers to text window text */ int textCount = 0, helpCount = 0; /* text list indexes */ float scaleFactor = 0.0; /* window size scale factor */ #ifdef ALPHA #undef ALPHA /* Avoid problems with DEC's ALPHA machines. */ #endif int menu1, menu2, menu3, menu4, menu5, menu6 = 0, menu7, menu8; enum { RGBA, INDEX, SINGLE, DOUBLEBUFFER, DEPTH, ACCUM, ALPHA, STENCIL, MULTISAMPLE, STEREO, MODES }; char *modeNames[] = {"RGBA", "INDEX", "SINGLE", "DOUBLE", "DEPTH", "ACCUM", "ALPHA", "STENCIL", "MULTISAMPLE", "STEREO"}; int glutMode[] = {GLUT_RGBA, GLUT_INDEX, GLUT_SINGLE, GLUT_DOUBLE, GLUT_DEPTH, GLUT_ACCUM, GLUT_ALPHA, GLUT_STENCIL, GLUT_MULTISAMPLE, GLUT_STEREO}; int modes[MODES] = {0}; GLboolean menuButton[3] = {0, 0, 1}; enum { MOUSEBUTTON, MOUSEMOTION, APPLY, RESET }; /* Prototypes */ void gfxInit(int); void drawScene(void); void idleFunc(void); void reshapeFunc(int width, int height); void visible(int state); void keyFunc(unsigned char key, int x, int y); void mouseFunc(int button, int state, int x, int y); void motionFunc(int x, int y); void passiveMotionFunc(int x, int y); void entryFunc(int state); void specialFunc(int key, int x, int y); void menuStateFunc(int state); void timerFunc(int value); #if 0 void delayedReinstateMenuStateCallback(int value); #endif void menuFunc(int value); void showText(void); void textString(int x, int y, char *str, void *font); void strokeString(int x, int y, char *str, void *font); void makeMenus(void); int idToIndex(int id); void setInitDisplayMode(void); void createMenu6(void); void removeCallbacks(void); void addCallbacks(void); void dumpIds(void); void updateHelp(void); void updateAll(void); void killWindow(int index); void makeWindow(int index); void warning(char *msg); void autoDemo(int); void positionWindow(int index); void reshapeWindow(int index); void iconifyWindow(int index); void showWindow(int index); void hideWindow(int index); void pushWindow(int index); void popWindow(int index); void attachMenus(void); void killAllWindows(void); void makeAllWindows(void); void updateText(void); void updateScrollWindow(int index, char **ptr); void redefineShapes(int shape); GLboolean match(char *, char *); void checkArgs(int argc, char *argv[]); void scaleWindows(float); void commandLineHelp(void); void trackBall(int mode, int button, int state, int x, int y); void spaceballMotionCB(int, int, int); void spaceballRotateCB(int, int, int); void spaceballButtonCB(int, int); void buttonBoxCB(int, int); void dialsCB(int, int); void tabletMotionCB(int, int); void tabletButtonCB(int, int, int, int); /* 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; } /* main */ int main(int argc, char **argv) { /* General init */ glutInit(&argc, argv); /* Check args */ checkArgs(argc, argv); /* Scale window position/size if needed. Ignore aspect ratios. */ if (scaleFactor > 0.0) scaleWindows(scaleFactor); else scaleWindows(glutGet(GLUT_SCREEN_WIDTH) / 1280.0); /* Set initial display mode */ modes[RGBA] = 1; modes[DOUBLEBUFFER] = 1; modes[DEPTH] = 1; setInitDisplayMode(); /* Set up menus */ makeMenus(); /* Make some windows */ makeWindow(0); makeWindow(1); /* Global callbacks */ glutIdleFunc(idleFunc); glutMenuStateFunc(menuStateFunc); /* Start demo if needed */ if (demoMode) autoDemo(-2); /* Fall into event loop */ glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } /* gfxInit - Init opengl for each window */ void gfxInit(int index) { GLfloat grey10[] = {0.10, 0.10, 0.10, 1.0}; GLfloat grey20[] = {0.2, 0.2, 0.2, 1.0}; GLfloat black[] = {0.0, 0.0, 0.0, 0.0}; GLfloat diffuse0[] = {1.0, 0.0, 0.0, 1.0}; GLfloat diffuse1[] = {0.0, 1.0, 0.0, 1.0}; GLfloat diffuse2[] = {1.0, 1.0, 0.0, 1.0}; GLfloat diffuse3[] = {0.0, 1.0, 1.0, 1.0}; GLfloat diffuse4[] = {1.0, 0.0, 1.0, 1.0}; #define XX 3 #define YY 3 #define ZZ -2.5 float vertex[][3] = { {-XX, -YY, ZZ}, {+XX, -YY, ZZ}, {+XX, +YY, ZZ}, {-XX, +YY, ZZ} }; /* warning: This func mixes RGBA and CMAP calls in an ugly fashion */ redefineShapes(currentShape); /* set up display lists */ glutSetWindow(winId[index]); /* hack - redefineShapes changes glut win */ /* Shaded backdrop square (RGB or CMAP) */ glNewList(100, GL_COMPILE); glPushAttrib(GL_LIGHTING); glDisable(GL_LIGHTING); glBegin(GL_POLYGON); glColor4fv(black); glIndexi(0); glVertex3fv(vertex[0]); glColor4fv(grey10); glIndexi(3); glVertex3fv(vertex[1]); glColor4fv(grey20); glIndexi(4); glVertex3fv(vertex[2]); glColor4fv(grey10); glIndexi(7); glVertex3fv(vertex[3]); glEnd(); glPopAttrib(); glIndexi(9); glEndList(); /* Set proj+view */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, 1.0, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.); glTranslatef(0.0, 0.0, -1.0); if (index == 6 || index == 7) goto colorindex; /* Set basic material, lighting for RGB windows */ if (index == 0) glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse0); else if (index == 1) glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse1); else if (index == 2) glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse2); else if (index == 3) glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse3); else if (index == 4) glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse4); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); if (index == 4) glClearColor(0.15, 0.15, 0.15, 1); else glClearColor(0.1, 0.1, 0.1, 1.0); return; /* Set GL basics for CMAP windows 6,7 */ colorindex: glEnable(GL_DEPTH_TEST); if (glutGet(GLUT_WINDOW_COLORMAP_SIZE) < 16) warning("Color map size too small for color index window"); /* Try to reuse an existing color map */ if ((index == 6) && (winId[7] != 0)) { glutCopyColormap(winId[7]); } else if ((index == 7) && (winId[6] != 0)) { glutCopyColormap(winId[6]); } else { glutSetColor(8, 0.1, 0.1, 0.1); glutSetColor(9, 1.0, 0.5, 0.0); glutSetColor(10, 1.0, 0.6, 0.8); } glClearIndex(8); glIndexi(index + 3); } /* makeMenus - Create popup menus */ void makeMenus(void) { /* General control / debug */ menu2 = glutCreateMenu(menuFunc); glutAddMenuEntry("toggle auto demo mode (a)", 312); glutAddMenuEntry("toggle freezing in menus", 300); glutAddMenuEntry("toggle text per window (t)", 301); glutAddMenuEntry("toggle global timer", 302); glutAddMenuEntry("toggle global animation", 303); glutAddMenuEntry("toggle per window animation", 304); glutAddMenuEntry("toggle debug prints (D)", 305); glutAddMenuEntry("toggle shaded backdrop", 307); glutAddMenuEntry("toggle passive motion callback", 308); glutAddMenuEntry("increase line width (l)", 310); glutAddMenuEntry("decrease line width (L)", 311); /* Shapes */ menu3 = glutCreateMenu(menuFunc); glutAddMenuEntry("sphere", 200); glutAddMenuEntry("cube", 201); glutAddMenuEntry("cone", 202); glutAddMenuEntry("torus", 203); glutAddMenuEntry("dodecahedron", 204); glutAddMenuEntry("octahedron", 205); glutAddMenuEntry("tetrahedron", 206); glutAddMenuEntry("icosahedron", 207); glutAddMenuEntry("teapot", 208); /* Open/close windows */ menu4 = glutCreateMenu(menuFunc); glutAddMenuEntry("open all windows", 450); glutAddMenuEntry("close all windows", 451); glutAddMenuEntry(" ", 9999); glutAddMenuEntry("create win 0", 400); glutAddMenuEntry("create win 1", 401); glutAddMenuEntry("create win 2", 402); glutAddMenuEntry("create win 3", 403); glutAddMenuEntry("create sub window", 404); glutAddMenuEntry("create color index win 6", 406); glutAddMenuEntry("create color index win 7", 407); glutAddMenuEntry(" ", 9999); glutAddMenuEntry("destroy win 0", 410); glutAddMenuEntry("destroy win 1", 411); glutAddMenuEntry("destroy win 2", 412); glutAddMenuEntry("destroy win 3", 413); glutAddMenuEntry("destroy sub window", 414); glutAddMenuEntry("destroy color index win 6", 416); glutAddMenuEntry("destroy color index win 7", 417); /* Window manager stuff */ menu5 = glutCreateMenu(menuFunc); glutAddMenuEntry("move current win", 430); glutAddMenuEntry("resize current win", 431); glutAddMenuEntry("iconify current win", 432); glutAddMenuEntry("show current win", 433); glutAddMenuEntry("hide current win", 434); glutAddMenuEntry("push current win", 435); glutAddMenuEntry("pop current win", 436); glutAddMenuEntry(" ", 9999); glutAddMenuEntry("move win 1", 420); glutAddMenuEntry("resize win 1", 421); glutAddMenuEntry("iconify win 1", 422); glutAddMenuEntry("show win 1", 423); glutAddMenuEntry("hide win 1", 424); glutAddMenuEntry("push win 1", 425); glutAddMenuEntry("pop win 1", 426); /* Gfx modes */ createMenu6(); /* build dynamically */ /* Texty reports */ menu7 = glutCreateMenu(menuFunc); glutAddMenuEntry("report current win modes", 700); glutAddMenuEntry("report current device data", 701); glutAddMenuEntry("check OpenGL extensions", 702); glutAddMenuEntry("dump internal data (d)", 703); /* Play with menus */ menu8 = glutCreateMenu(menuFunc); glutAddMenuEntry("toggle menus on left button", 805); glutAddMenuEntry("toggle menus on middle button", 806); glutAddMenuEntry("toggle menus on right button", 807); glutAddMenuEntry("---------------------------", 9999); glutAddMenuEntry("add plain items", 800); glutAddMenuEntry("add submenu items", 801); glutAddMenuEntry("change new entries to plain items", 802); glutAddMenuEntry("change new entries to submenus", 803); glutAddMenuEntry("remove all new items", 804); glutAddMenuEntry("---------------------------", 9999); /* Main menu */ menu1 = glutCreateMenu(menuFunc); glutAddSubMenu("control", menu2); glutAddSubMenu("shapes", menu3); glutAddSubMenu("windows", menu4); glutAddSubMenu("window ops", menu5); glutAddSubMenu("gfx modes", menu6); glutAddSubMenu("reports", menu7); glutAddSubMenu("menus", menu8); glutAddMenuEntry("help (h)", 101); glutAddMenuEntry("quit (esc)", 100); } /* createMenu6 - Dynamically rebuild menu of display modes to show current choices */ void createMenu6(void) { char str[100]; int i; if (menu6 != 0) glutDestroyMenu(menu6); menu6 = glutCreateMenu(menuFunc); for (i = 0; i < MODES; i++) { sprintf(str, "%srequest %s", (modes[i] ? "+ " : " "), modeNames[i]); glutAddMenuEntry(str, 602 + i); } } /* menuFunc - Process return codes from popup menus */ void menuFunc(int value) { static int initItems = 10; int items, m; if (initItems == 0) { glutSetMenu(menu8); initItems = glutGet(GLUT_MENU_NUM_ITEMS); } PR("Menu returned value %d \n", value); switch (value) { /* GLUT shapes */ case 200: case 201: case 202: case 203: case 204: case 205: case 206: case 207: case 208: redefineShapes(value - 200); break; /* Overall controls */ case 300: menuFreeze = !menuFreeze; break; case 301: text[idToIndex(glutGetWindow())] = !(text[idToIndex(glutGetWindow())]); break; case 302: timerOn = !timerOn; if (timerOn) glutTimerFunc(DELAY, timerFunc, 1); break; case 303: animation = !animation; if (animation) glutIdleFunc(idleFunc); else glutIdleFunc(NULL); break; case 304: winFreeze[idToIndex(glutGetWindow())] = !(winFreeze[idToIndex( glutGetWindow())]); break; case 305: debug = !debug; break; case 307: backdrop = !backdrop; break; case 308: passive = !passive; if (passive) glutPassiveMotionFunc(passiveMotionFunc); else glutPassiveMotionFunc(NULL); break; case 310: lineWidth += 1; updateAll(); break; case 311: lineWidth -= 1; if (lineWidth < 1) lineWidth = 1; updateAll(); break; case 312: demoMode = !demoMode; if (demoMode) autoDemo(-2); break; /* Window create/destroy. */ /* Creates */ case 400: makeWindow(0); break; case 401: makeWindow(1); break; case 402: makeWindow(2); break; case 403: makeWindow(3); break; case 404: makeWindow(4); break; case 406: makeWindow(6); break; case 407: makeWindow(7); break; /* Destroys */ case 410: killWindow(0); break; case 411: killWindow(1); break; case 412: killWindow(2); break; case 413: killWindow(3); break; case 414: killWindow(4); break; case 416: killWindow(6); break; case 417: killWindow(7); break; case 450: makeAllWindows(); break; case 451: killAllWindows(); break; /* Window movements etc. */ case 420: positionWindow(1); break; case 421: reshapeWindow(1); break; case 422: iconifyWindow(1); break; case 423: showWindow(1); break; case 424: hideWindow(1); break; case 425: pushWindow(1); break; case 426: popWindow(1); break; case 430: positionWindow(idToIndex(glutGetWindow())); break; case 431: reshapeWindow(idToIndex(glutGetWindow())); break; case 432: iconifyWindow(idToIndex(glutGetWindow())); break; case 433: showWindow(idToIndex(glutGetWindow())); break; case 434: hideWindow(idToIndex(glutGetWindow())); break; case 435: pushWindow(idToIndex(glutGetWindow())); break; case 436: popWindow(idToIndex(glutGetWindow())); break; /* Test gfx modes. */ case 600: makeWindow(3); break; case 601: killWindow(3); break; case 602: case 603: case 604: case 605: case 606: case 607: case 608: case 609: case 610: case 611: modes[value - 602] = !modes[value - 602]; setInitDisplayMode(); break; /* Text reports */ /* This is pretty ugly. */ #define INDENT 30 #define REPORTSTART(text) \ printf("\n" text "\n"); \ textPtr[0] = (char *)malloc(strlen(text)+1); \ strcpy(textPtr[0], text); \ textCount = 1; #define REPORTEND \ scrollLine = 0; \ textPtr[textCount] = NULL; \ makeWindow(8); \ updateText(); #define GLUTGET(name) \ { \ char str[100], str2[100]; \ int s, len; \ sprintf(str, # name); \ len = (int) strlen(# name); \ for(s = 0 ; s < INDENT-len; s++) \ strcat(str, " "); \ sprintf(str2, ": %d\n",glutGet(name)); \ strcat(str, str2); \ printf(str); \ textPtr[textCount] = stralloc(str); \ textCount++; \ } case 700: printf("XXXXXX glutGetWindow = %d\n", glutGetWindow()); REPORTSTART("glutGet():"); GLUTGET(GLUT_WINDOW_X); GLUTGET(GLUT_WINDOW_Y); GLUTGET(GLUT_WINDOW_WIDTH); GLUTGET(GLUT_WINDOW_HEIGHT); GLUTGET(GLUT_WINDOW_BUFFER_SIZE); GLUTGET(GLUT_WINDOW_STENCIL_SIZE); GLUTGET(GLUT_WINDOW_DEPTH_SIZE); GLUTGET(GLUT_WINDOW_RED_SIZE); GLUTGET(GLUT_WINDOW_GREEN_SIZE); GLUTGET(GLUT_WINDOW_BLUE_SIZE); GLUTGET(GLUT_WINDOW_ALPHA_SIZE); GLUTGET(GLUT_WINDOW_ACCUM_RED_SIZE); GLUTGET(GLUT_WINDOW_ACCUM_GREEN_SIZE); GLUTGET(GLUT_WINDOW_ACCUM_BLUE_SIZE); GLUTGET(GLUT_WINDOW_ACCUM_ALPHA_SIZE); GLUTGET(GLUT_WINDOW_DOUBLEBUFFER); GLUTGET(GLUT_WINDOW_RGBA); GLUTGET(GLUT_WINDOW_PARENT); GLUTGET(GLUT_WINDOW_NUM_CHILDREN); GLUTGET(GLUT_WINDOW_COLORMAP_SIZE); GLUTGET(GLUT_WINDOW_NUM_SAMPLES); GLUTGET(GLUT_STEREO); GLUTGET(GLUT_SCREEN_WIDTH); GLUTGET(GLUT_SCREEN_HEIGHT); GLUTGET(GLUT_SCREEN_HEIGHT_MM); GLUTGET(GLUT_SCREEN_WIDTH_MM); GLUTGET(GLUT_MENU_NUM_ITEMS); GLUTGET(GLUT_DISPLAY_MODE_POSSIBLE); GLUTGET(GLUT_INIT_DISPLAY_MODE); GLUTGET(GLUT_INIT_WINDOW_X); GLUTGET(GLUT_INIT_WINDOW_Y); GLUTGET(GLUT_INIT_WINDOW_WIDTH); GLUTGET(GLUT_INIT_WINDOW_HEIGHT); GLUTGET(GLUT_ELAPSED_TIME); REPORTEND; break; #define GLUTDEVGET(name) \ { \ char str[100], str2[100]; \ int len, s; \ sprintf(str, # name); \ len = (int) strlen(# name); \ for(s = 0 ; s < INDENT-len; s++) \ strcat(str, " "); \ sprintf(str2, ": %d\n", \ glutDeviceGet(name)); \ strcat(str, str2); \ printf(str); \ textPtr[textCount] = stralloc(str); \ textCount++; \ } case 701: REPORTSTART("glutDeviceGet():"); GLUTDEVGET(GLUT_HAS_KEYBOARD); GLUTDEVGET(GLUT_HAS_MOUSE); GLUTDEVGET(GLUT_HAS_SPACEBALL); GLUTDEVGET(GLUT_HAS_DIAL_AND_BUTTON_BOX); GLUTDEVGET(GLUT_HAS_TABLET); GLUTDEVGET(GLUT_NUM_MOUSE_BUTTONS); GLUTDEVGET(GLUT_NUM_SPACEBALL_BUTTONS); GLUTDEVGET(GLUT_NUM_BUTTON_BOX_BUTTONS); GLUTDEVGET(GLUT_NUM_DIALS); GLUTDEVGET(GLUT_NUM_TABLET_BUTTONS); REPORTEND; break; #define EXTCHECK(name) \ { \ char str[100], str2[100]; \ int len, s; \ sprintf(str, # name); \ len = (int) strlen(# name); \ for(s = 0 ; s < INDENT-len; s++) \ strcat(str, " "); \ sprintf(str2, ": %s\n", \ glutExtensionSupported(# name)? \ "yes": "no"); \ strcat(str, str2); \ printf(str); \ textPtr[textCount] = stralloc(str); \ textCount++; \ } case 702: REPORTSTART("glutExtensionSupported():"); EXTCHECK(GL_EXT_abgr); EXTCHECK(GL_EXT_blend_color); EXTCHECK(GL_EXT_blend_minmax); EXTCHECK(GL_EXT_blend_logic_op); EXTCHECK(GL_EXT_blend_subtract); EXTCHECK(GL_EXT_polygon_offset); EXTCHECK(GL_EXT_texture); EXTCHECK(GL_EXT_guaranteed_to_fail); EXTCHECK(GLX_SGI_swap_control); EXTCHECK(GLX_SGI_video_sync); EXTCHECK(GLX_SGIS_multi_sample); REPORTEND; break; case 703: dumpIds(); break; /* Mess around with menus */ case 800: if (glutGetMenu() != menu8) /* just a test */ printf("glutGetMenu() returned unexpected value\n"); glutAddMenuEntry("help", 101); glutAddMenuEntry("help", 101); glutAddMenuEntry("help", 101); glutAddMenuEntry("help", 101); glutAddMenuEntry("help", 101); break; case 801: glutAddSubMenu("shapes", menu3); glutAddSubMenu("shapes", menu3); glutAddSubMenu("shapes (a long string to break menus with)", menu3); glutAddSubMenu("shapes", menu3); glutAddSubMenu("shapes", menu3); break; case 802: items = glutGet(GLUT_MENU_NUM_ITEMS); for (m = initItems + 1; m <= items; m++) { glutChangeToMenuEntry(m, "help", 101); } break; case 803: items = glutGet(GLUT_MENU_NUM_ITEMS); for (m = initItems + 1; m <= items; m++) { glutChangeToSubMenu(m, "shapes", menu3); } break; case 804: items = glutGet(GLUT_MENU_NUM_ITEMS); /* reverse order so renumbering not aproblem */ for (m = items; m >= initItems + 1; m--) { glutRemoveMenuItem(m); } break; case 805: menuButton[0] = !menuButton[0]; attachMenus(); break; case 806: menuButton[1] = !menuButton[1]; attachMenus(); break; case 807: menuButton[2] = !menuButton[2]; attachMenus(); break; /* Direct menu items. */ case 100: exit(0); break; case 101: if (winId[5] == 0) makeWindow(5); else killWindow(5); break; case 9999: break; default: fprintf(stderr, "\007Unhandled case %d in menu callback\n", value); } } /* redefineShapes - Remake the shapes display lists */ void redefineShapes(int shape) { int i; #define C3 \ switch(i) \ { \ case 0: \ case 3: \ C1; \ break; \ \ case 1: \ case 2: \ case 4: \ case 6: \ case 7: \ C2; \ break; \ } \ currentShape = shape for (i = 0; i < MAXWIN; i++) { if (winId[i]) { glutSetWindow(winId[i]); if (glIsList(i + 1)) glDeleteLists(i + 1, 1); glNewList(i + 1, GL_COMPILE); switch (shape) { #undef C1 #define C1 glutSolidSphere(1.5, 10, 10) #undef C2 #define C2 glutWireSphere(1.5, 10, 10) case 0: C3; break; #undef C1 #define C1 glutSolidCube(2) #undef C2 #define C2 glutWireCube(2) case 1: C3; break; #undef C1 #define C1 glutSolidCone(1.5, 1.75, 10, 10); #undef C2 #define C2 glutWireCone(1.5, 1.75, 10, 10); case 2: C3; break; #undef C1 #define C1 glutSolidTorus(0.5, 1.1, 10, 10) #undef C2 #define C2 glutWireTorus(0.5, 1.1, 10, 10) case 3: C3; break; #undef C1 #define C1 glScalef(.8, .8, .8);glutSolidDodecahedron() #undef C2 #define C2 glScalef(.8, .8, .8);glutWireDodecahedron() case 4: C3; break; #undef C1 #define C1 glScalef(1.5, 1.5, 1.5);glutSolidOctahedron() #undef C2 #define C2 glScalef(1.5, 1.5, 1.5);glutWireOctahedron() case 5: C3; break; #undef C1 #define C1 glScalef(1.8, 1.8, 1.8);glutSolidTetrahedron() #undef C2 #define C2 glScalef(1.8, 1.8, 1.8);glutWireTetrahedron() case 6: C3; break; #undef C1 #define C1 glScalef(1.5, 1.5, 1.5);glutSolidIcosahedron() #undef C2 #define C2 glScalef(1.5, 1.5, 1.5);glutWireIcosahedron() case 7: C3; break; #undef C1 #define C1 glutSolidTeapot(1.5); #undef C2 #define C2 glutWireTeapot(1.5); case 8: C3; break; } glEndList(); } } } /* positionWindow - Shift a window */ void positionWindow(int index) { int x, y; if (winId[index] == 0) return; glutSetWindow(winId[index]); x = glutGet(GLUT_WINDOW_X); y = glutGet(GLUT_WINDOW_Y); glutPositionWindow(x + 50, y + 50); } /* reshapeWindow - Change window size a little */ void reshapeWindow(int index) { int x, y; if (winId[index] == 0) return; glutSetWindow(winId[index]); x = glutGet(GLUT_WINDOW_WIDTH); y = glutGet(GLUT_WINDOW_HEIGHT); /* glutReshapeWindow(x * (index % 2? 0.8: 1.2), y * (index % 2? 1.2: 0.8)); */ glutReshapeWindow((int) (x * 1.0), (int) (y * 0.8)); } /* iconifyWindow - Iconify a window */ void iconifyWindow(int index) { if (winId[index] == 0) return; glutSetWindow(winId[index]); glutIconifyWindow(); } /* showWindow - Show a window (map or uniconify it) */ void showWindow(int index) { if (winId[index] == 0) return; glutSetWindow(winId[index]); glutShowWindow(); } /* hideWindow - Hide a window (unmap it) */ void hideWindow(int index) { if (winId[index] == 0) return; glutSetWindow(winId[index]); glutHideWindow(); } /* pushWindow - Push a window */ void pushWindow(int index) { if (winId[index] == 0) return; glutSetWindow(winId[index]); glutPushWindow(); } /* popWindow - Pop a window */ void popWindow(int index) { if (winId[index] == 0) return; glutSetWindow(winId[index]); glutPopWindow(); } /* drawScene - Draw callback, triggered by expose events etc. in GLUT. */ void drawScene(void) { int winIndex; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); winIndex = idToIndex(glutGetWindow()); /* printf("drawScene for index %d, id %d\n", winIndex, glutGetWindow()); */ glPushMatrix(); glLineWidth(lineWidth); if (backdrop) glCallList(100); /* Left button spinning */ trackBall(APPLY, 0, 0, 0, 0); /* Apply continuous spinning */ glRotatef(angle, 0, 1, 0); glCallList(winIndex + 1); glPopMatrix(); if (text[winIndex]) showText(); glutSwapBuffers(); } /* showText - Render some text in the current GLUT window */ void showText(void) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 100, 0, 100); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); glIndexi(7); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glLineWidth(lineWidth); textString(1, 1, "GLUT_BITMAP_8_BY_13", GLUT_BITMAP_8_BY_13); textString(1, 5, "GLUT_BITMAP_9_BY_15", GLUT_BITMAP_9_BY_15); textString(1, 10, "GLUT_BITMAP_TIMES_ROMAN_10", GLUT_BITMAP_TIMES_ROMAN_10); textString(1, 15, "GLUT_BITMAP_TIMES_ROMAN_24", GLUT_BITMAP_TIMES_ROMAN_24); strokeString(1, 25, "GLUT_STROKE_ROMAN", GLUT_STROKE_ROMAN); strokeString(1, 35, "GLUT_STROKE_MONO_ROMAN", GLUT_STROKE_MONO_ROMAN); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } /* textString - Bitmap font string */ void textString(int x, int y, char *msg, void *font) { glRasterPos2f(x, y); while (*msg) { glutBitmapCharacter(font, *msg); msg++; } } /* strokeString - Stroke font string */ void strokeString(int x, int y, char *msg, void *font) { glPushMatrix(); glTranslatef(x, y, 0); glScalef(.04, .04, .04); while (*msg) { glutStrokeCharacter(font, *msg); msg++; } glPopMatrix(); } /* idleFunc - GLUT idle func callback - animates windows */ void idleFunc(void) { int i; if (!leftDown && !middleDown) angle += 1; angle = angle % 360; for (i = 0; i < MAXWIN; i++) { if (winId[i] && winVis[i] && !winFreeze[i]) { glutSetWindow(winId[i]); glutPostRedisplay(); } } } /* reshapeFunc - Reshape callback. */ void reshapeFunc(int width, int height) { int winId; float aspect; winId = glutGetWindow(); PR("reshape callback for window id %d \n", winId); glViewport(0, 0, width, height); aspect = (float) width / height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, aspect, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); } /* visible - Visibility callback. Turn off rendering in invisible windows */ void visible(int state) { int winId; static GLboolean someVisible = GL_TRUE; winId = glutGetWindow(); /* printf("visible: state = %d \n", state); */ if (state == GLUT_VISIBLE) { PR("Window id %d visible \n", winId); winVis[idToIndex(winId)] = GL_TRUE; } else { PR("Window %d not visible \n", winId); winVis[idToIndex(winId)] = GL_FALSE; } if ((winVis[0] == GL_FALSE) && (winVis[1] == GL_FALSE) && (winVis[2] == GL_FALSE) && (winVis[3] == GL_FALSE) && (winVis[6] == GL_FALSE) && (winVis[7] == GL_FALSE)) { glutIdleFunc(NULL); PR("All windows not visible; idle func disabled\n"); someVisible = GL_FALSE; } else { if (!someVisible) { PR("Some windows now visible; idle func enabled\n"); someVisible = GL_TRUE; if (animation) glutIdleFunc(idleFunc); } } } /* keyFunc - Ascii key callback */ /* ARGSUSED1 */ void keyFunc(unsigned char key, int x, int y) { int i, ii; if (debug || showKeys) printf("Ascii key '%c' 0x%02x\n", key, key); switch (key) { case 0x1b: exit(0); break; case 'a': demoMode = !demoMode; if (demoMode) autoDemo(-2); break; case 's': AUTODELAY = AUTODELAY * 0.666; break; case 'S': AUTODELAY = AUTODELAY * 1.5; break; case 'q': killWindow(idToIndex(glutGetWindow())); break; case 'k': showKeys = !showKeys; break; case 'p': demoMode = !demoMode; if (demoMode) autoDemo(-999); break; case 'D': debug = !debug; break; case 'd': dumpIds(); break; case 'h': if (winId[5] == 0) makeWindow(5); else killWindow(5); break; case 't': ii = idToIndex(glutGetWindow()); text[ii] = !text[ii]; break; case 'r': trackBall(RESET, 0, 0, 0, 0); break; case 'l': lineWidth += 1; updateAll(); break; case 'L': lineWidth -= 1; if (lineWidth < 1) lineWidth = 1; updateAll(); break; case '0': case '1': case '2': case '3': case '4': case '6': i = key - '0'; winVis[i] = !winVis[i]; break; case ')': makeWindow(0); break; case '!': makeWindow(1); break; case '@': makeWindow(2); break; case '#': makeWindow(3); break; } } /* specialFunc - Special keys callback (F keys, cursor keys etc. */ /* ARGSUSED1 */ void specialFunc(int key, int x, int y) { if (debug || showKeys) printf("Special key %d\n", key); switch (key) { case GLUT_KEY_PAGE_DOWN: scrollLine += 10; updateHelp(); updateText(); break; case GLUT_KEY_PAGE_UP: scrollLine -= 10; updateHelp(); updateText(); break; case GLUT_KEY_DOWN: scrollLine += 1; updateHelp(); updateText(); break; case GLUT_KEY_UP: scrollLine -= 1; updateHelp(); updateText(); break; case GLUT_KEY_HOME: scrollLine = 0; updateHelp(); updateText(); break; case GLUT_KEY_END: scrollLine = 9999; updateHelp(); updateText(); break; case GLUT_KEY_RIGHT: scrollCol -= 1; updateHelp(); updateText(); break; case GLUT_KEY_LEFT: scrollCol += 1; updateHelp(); updateText(); break; } } /* mouseFunc - Mouse button callback */ void mouseFunc(int button, int state, int x, int y) { PR("Mouse button %d, state %d, at pos %d, %d\n", button, state, x, y); trackBall(MOUSEBUTTON, button, state, x, y); } /* motionFunc - Mouse movement (with a button down) callback */ void motionFunc(int x, int y) { PR("Mouse motion at %d, %d\n", x, y); trackBall(MOUSEMOTION, 0, 0, x, y); glutPostRedisplay(); } /* passiveMotionFunc - Mouse movement (with no button down) callback */ void passiveMotionFunc(int x, int y) { printf("Mouse motion at %d, %d\n", x, y); } /* entryFunc - Window entry event callback */ void entryFunc(int state) { int winId = glutGetWindow(); PR("Entry event: window id %d (index %d), state %d \n", winId, idToIndex( winId), state); } /* menuStateFunc - Callback to tell us when menus are popped up/down. */ int menu_state = GLUT_MENU_NOT_IN_USE; void menuStateFunc(int state) { printf("menu stated = %d\n", state); menu_state = state; if (glutGetWindow() == 0) { PR("menuStateFunc: window invalid\n"); return; } PR("Menus are%sin use\n", state == GLUT_MENU_IN_USE ? " " : " not "); if ((state == GLUT_MENU_IN_USE) && menuFreeze) glutIdleFunc(NULL); else if (animation) glutIdleFunc(idleFunc); } /* timerFunc - General test of global timer */ void timerFunc(int value) { printf("timer callback: value %d\n", value); if (timerOn) { glutTimerFunc(DELAY, timerFunc, 1); } } #if 0 /* delayedReinstateMenuStateCallback - Hack to reinstate MenuStateCallback after a while. */ void delayedReinstateMenuStateCallback(int state) { glutMenuStateFunc(menuStateFunc); } #endif /* setInitDisplayMode - update display modes from display mode menu */ void setInitDisplayMode(void) { int i; displayMode = 0; for (i = 0; i < MODES; i++) { if (modes[i]) { /* printf("Requesting %s \n", modeNames[i]); */ displayMode |= glutMode[i]; } } glutInitDisplayMode(displayMode); createMenu6(); if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) warning("This display mode not supported\n"); } /* makeWindow - Create one of the windows */ void makeWindow(int index) { char str[99]; if (winId[index] != 0) { /* warning("Attempt to create window which is already created"); */ return; } switch (index) { case 0: /* ordinary RGB windows */ case 1: case 2: case 3: setInitDisplayMode(); glutInitWindowPosition(pos[index][0], pos[index][1]); glutInitWindowSize(size[index][0], size[index][1]); winId[index] = glutCreateWindow(" "); PR("Window %d id = %d \n", index, winId[index]); gfxInit(index); addCallbacks(); sprintf(str, "window %d (RGB)", index); glutSetWindowTitle(str); sprintf(str, "icon %d", index); glutSetIconTitle(str); glutSetMenu(menu1); glutAttachMenu(GLUT_RIGHT_BUTTON); break; case 4: /* subwindow */ setInitDisplayMode(); winId[index] = glutCreateSubWindow(winId[0], pos[index][0], pos[index] [1], size[index][0], size[index][1]); PR("Window %d id = %d \n", index, winId[index]); gfxInit(index); glutDisplayFunc(drawScene); glutVisibilityFunc(visible); glutReshapeFunc(reshapeFunc); break; case 5: /* help window */ case 8: /* text window */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowPosition(pos[index][0], pos[index][1]); glutInitWindowSize(size[index][0], size[index][1]); winId[index] = glutCreateWindow(" "); PR("Window %d id = %d \n", index, winId[index]); /* addCallbacks(); */ glutKeyboardFunc(keyFunc); glutSpecialFunc(specialFunc); glClearColor(0.15, 0.15, 0.15, 1.0); glColor3f(1, 1, 1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, 300, 0, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (index == 5) { glutDisplayFunc(updateHelp); glutSetWindowTitle("help (RGB) win 5"); glutSetIconTitle("help"); } else { glutDisplayFunc(updateText); glutSetWindowTitle("text (RGB) win 8"); glutSetIconTitle("text"); } glutSetMenu(menu1); glutAttachMenu(GLUT_RIGHT_BUTTON); break; case 6: /* color index window */ case 7: /* color index window */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH); glutInitWindowPosition(pos[index][0], pos[index][1]); glutInitWindowSize(size[index][0], size[index][1]); winId[index] = glutCreateWindow(" "); PR("Window %d id = %d \n", index, winId[index]); gfxInit(index); addCallbacks(); sprintf(str, "window %d (color index)", index); glutSetWindowTitle(str); sprintf(str, "icon %d", index); glutSetIconTitle(str); glutSetMenu(menu1); glutAttachMenu(GLUT_RIGHT_BUTTON); break; } } /* killWindow - Kill one of the main windows */ void killWindow(int index) { int i; if (winId[index] == 0) { /* fprintf(stderr, "Attempt to kill invalid window in killWindow\n"); */ return; } PR("Killing win %d\n", index); glutSetWindow(winId[index]); /* Disable all callbacks for safety, although glutDestroyWindow should do this. */ removeCallbacks(); glutDestroyWindow(winId[index]); winId[index] = 0; winVis[index] = GL_FALSE; #if 0 /* If we reinstate the menu state func here, prog breaks. So reinstate it a little later. */ glutTimerFunc(MENUDELAY, delayedReinstateMenuStateCallback, 1); #endif if (index == 5) { /* help */ scrollLine = 0; scrollCol = 0; } if (index == 8) { /* text window */ for (i = 0; textPtr[i] != NULL; i++) { free(textPtr[i]); /* free the text strings */ textPtr[i] = NULL; } } } /* addCallbacks - Add some standard callbacks after creating a window */ void addCallbacks(void) { glutDisplayFunc(drawScene); glutVisibilityFunc(visible); glutReshapeFunc(reshapeFunc); glutKeyboardFunc(keyFunc); glutSpecialFunc(specialFunc); glutMouseFunc(mouseFunc); glutMotionFunc(motionFunc); glutEntryFunc(entryFunc); /* Callbacks for exotic input devices. Must get my dials & buttons back. */ glutSpaceballMotionFunc(spaceballMotionCB); glutSpaceballRotateFunc(spaceballRotateCB); glutSpaceballButtonFunc(spaceballButtonCB); glutButtonBoxFunc(buttonBoxCB); glutDialsFunc(dialsCB); glutTabletMotionFunc(tabletMotionCB); glutTabletButtonFunc(tabletButtonCB); } /* removeCallbacks - Remove all callbacks before destroying a window. GLUT probably does this anyway but we'll be safe. */ void removeCallbacks(void) { glutVisibilityFunc(NULL); glutReshapeFunc(NULL); glutKeyboardFunc(NULL); glutSpecialFunc(NULL); glutMouseFunc(NULL); glutMotionFunc(NULL); glutEntryFunc(NULL); } /* updateHelp - Update the help window after user scrolls. */ void updateHelp(void) { static char *helpPtr[] = { "(Use PGUP, PGDN, HOME, END, arrows to scroll help text) ", " ", "A demo program for GLUT. ", "G Edwards, Aug 95 ", "Exercises 99% of GLUT calls ", VERSIONLONG, " ", "This text uses GLUT_STROKE_MONO_ROMAN font, a built-in vector font.", "(Try resizing the help window). ", " ", "Keys: ", " esc quit ", " t toggle text on/off in each window ", " h toggle help ", " q quit current window ", " a auto demo ", " p pause/unpause demo ", " l increase line width (gfx & stroke text) ", " L decrease line width (gfx & stroke text) ", " r reset transforms ", " k show keyboard events ", " D show all events ", " ", "Mouse: ", " Left button: rotate ", " Middle button: pan ", " Left + middle: zoom ", NULL}; updateScrollWindow(5, helpPtr); } /* updateText - Update a text window */ void updateText(void) { int i; if (textPtr[0] == NULL) { for (i = 0; i < 20; i++) { textPtr[i] = (char *) malloc(50); strcpy(textPtr[i], "no current text"); } textPtr[20] = NULL; } updateScrollWindow(8, textPtr); } /* updateScrollWindow */ void updateScrollWindow(int index, char **ptr) { int i, j, lines = 0; if (winId[index] == 0) return; glutSetWindow(winId[index]); for (i = 0; ptr[i] != NULL; i++) lines++; if (scrollLine < 0) scrollLine = 0; if (scrollLine > (lines - 5)) scrollLine = lines - 5; glClear(GL_COLOR_BUFFER_BIT); glLineWidth(lineWidth); for (i = scrollLine, j = 1; ptr[i] != NULL; i++, j++) strokeString(scrollCol * 50, 100 - j * 6, ptr[i], GLUT_STROKE_MONO_ROMAN); glutSwapBuffers(); } /* updateAll - Update all visible windows after soem global change, eg. line width */ void updateAll(void) { int i; if (winId[5] != 0) updateHelp(); if (winId[8] != 0) updateText(); for (i = 0; i < MAXWIN; i++) if (winId[i]) { glutSetWindow(winId[i]); glutPostRedisplay(); } } /* idToIndex - Convert GLUT window id to our internal index */ int idToIndex(int id) { int i; for (i = 0; i < MAXWIN; i++) { if (winId[i] == id) return i; } fprintf(stderr, "error: id %d not found \n", id); return (-1); } /* warning - warning messages */ void warning(char *msg) { fprintf(stderr, "\007"); if (debug) { fprintf(stderr, "%s", msg); if (msg[strlen(msg)] != '\n') fprintf(stderr, "%s", "\n"); } } /* dumpIds - Debug: dump some internal data */ void dumpIds(void) { int i, j; printf("\nInternal data:\n"); for (i = 0; i < MAXWIN; i++) printf("Index %d, glut win id %d, visibility %d\n", i, winId[i], winVis[i]); for (i = 0; i < MAXWIN; i++) { if (winId[i]) glutSetWindow(winId[i]); else { printf("index %d - no glut window\n", i); continue; } for (j = 1; j <= MAXWIN; j++) printf("Index %d, display list %d %s defined\n", i, j, glIsList(j) ? "is " : "not"); } } /* autoDemo - Run auto demo/test This is a bit tricky. We need to start a timer sequence which progressively orders things to be done. The work really gets done when we return from our callback. Have to think about the event loop / callback design here. */ void autoDemo(int value) { #define STEP(a, b) \ case a: \ action(a); \ glutTimerFunc(AUTODELAY * b, autoDemo, next(a); \ break; static int index = 0; static int count = 0; static int restartValue = -2; if (value == -999) value = restartValue; restartValue = value; #define AUTODELAY2 (unsigned int) (AUTODELAY*0.66) /* fprintf(stderr, "autoDemo: value %d \n", value); */ if (!demoMode) return; if (menu_state == GLUT_MENU_IN_USE) { glutTimerFunc(AUTODELAY / 2, autoDemo, value); return; } switch (value) { /* Entry point; kill off existing windows. */ case -2: killAllWindows(); glutTimerFunc(AUTODELAY / 2, autoDemo, 1); break; /* Start making windows */ case -1: makeWindow(0); glutTimerFunc(AUTODELAY, autoDemo, 0); /* skip case 0 first time */ break; /* Change shape & backdrop */ case 0: currentShape = (currentShape + 1) % 9; redefineShapes(currentShape); count += 1; if (count % 2) backdrop = !backdrop; glutTimerFunc(AUTODELAY, autoDemo, 1); break; /* Keep making windows */ case 1: makeWindow(1); glutTimerFunc(AUTODELAY, autoDemo, 2); break; case 2: makeWindow(2); glutTimerFunc(AUTODELAY, autoDemo, 3); break; case 3: makeWindow(3); glutTimerFunc(AUTODELAY, autoDemo, 4); break; case 4: makeWindow(4); glutTimerFunc(AUTODELAY, autoDemo, 5); break; case 5: makeWindow(5); glutTimerFunc(AUTODELAY * 2, autoDemo, 51); break; case 51: makeWindow(6); glutTimerFunc(AUTODELAY * 2, autoDemo, 52); break; case 52: makeWindow(7); glutTimerFunc(AUTODELAY * 2, autoDemo, 53); break; /* Kill last 3 windows, leave 4 up. */ case 53: killWindow(7); glutTimerFunc(AUTODELAY, autoDemo, 54); break; case 54: killWindow(6); glutTimerFunc(AUTODELAY, autoDemo, 6); break; case 6: killWindow(5); glutTimerFunc(AUTODELAY, autoDemo, 7); break; case 7: killWindow(4); glutTimerFunc(AUTODELAY, autoDemo, 700); break; /* Change shape again */ case 700: currentShape = (currentShape + 1) % 9; redefineShapes(currentShape); glutTimerFunc(AUTODELAY, autoDemo, 701); break; /* Cycle 4 main windows through various window ops. */ case 701: positionWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 701 : 702); break; case 702: reshapeWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 702 : 703); break; case 703: iconifyWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 703 : 704); break; case 704: showWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 704 : 705); break; case 705: hideWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 705 : 706); break; case 706: showWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 706 : 707); break; case 707: pushWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 707 : 708); break; case 708: popWindow(index); index = (index + 1) % 4; glutTimerFunc(AUTODELAY2, autoDemo, index > 0 ? 708 : 8); break; /* Kill all windows */ case 8: killWindow(3); glutTimerFunc(AUTODELAY, autoDemo, 9); break; case 9: killWindow(2); glutTimerFunc(AUTODELAY, autoDemo, 10); break; case 10: killWindow(1); glutTimerFunc(AUTODELAY, autoDemo, 11); break; case 11: killWindow(0); glutTimerFunc(AUTODELAY, autoDemo, -1); /* back to start */ break; } } /* attachMenus - Attach/detach menus to/from mouse buttons */ void attachMenus(void) { int i, b; int button[3] = {GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON}; for (i = 0; i < MAXWIN; i++) { if (winId[i] != 0) { for (b = 0; b < 3; b++) { glutSetWindow(winId[i]); glutSetMenu(menu1); if (menuButton[b]) glutAttachMenu(button[b]); else glutDetachMenu(button[b]); } } } } /* killAllWindows - Kill all windows (except 0) */ void killAllWindows(void) { int w; for (w = 1; w < MAXWIN; w++) if (winId[w]) killWindow(w); } /* makeAllWindows - Make all windows */ void makeAllWindows(void) { int w; for (w = 0; w < MAXWIN; w++) if (!winId[w]) makeWindow(w); } /* checkArgs - Check command line args */ void checkArgs(int argc, char *argv[]) { int argp; GLboolean quit = GL_FALSE; GLboolean error = GL_FALSE; #define AA argv[argp] #if 0 #define NEXT argp++; \ if(argp >= argc) \ { \ Usage(); \ Exit(1); \ } #endif argp = 1; while (argp < argc) { if (match(AA, "-help")) { commandLineHelp(); quit = GL_TRUE; } else if (match(AA, "-version")) { printf(VERSIONLONG "\n"); quit = GL_TRUE; } else if (match(AA, "-auto")) { demoMode = GL_TRUE; } else if (match(AA, "-scale")) { argp++; scaleFactor = atof(argv[argp]); } else { fprintf(stderr, "Unknown arg: %s\n", AA); error = GL_TRUE; quit = GL_TRUE; } argp++; } if (error) { commandLineHelp(); exit(1); } if (quit) exit(0); } /* commandLineHelp - Command line help */ void commandLineHelp(void) { printf("Usage:\n"); printf(" -h[elp] this stuff\n"); printf(" -v[ersion] show version\n"); printf(" -a[uto] start in auto demo mode\n"); printf(" -s[cale] f scale windows by f\n"); printf("Standard GLUT args:\n"); printf(" -iconic start iconic\n"); printf(" -display DISP use display DISP\n"); printf(" -direct use direct rendering (default)\n"); printf(" -indirect use indirect rendering\n"); printf(" -sync use synchronous X protocol\n"); printf(" -gldebug check OpenGL errors\n"); printf(" -geometry WxH+X+Y standard X window spec (overridden here) \n"); } /* match - Match a string (any unique substring). */ GLboolean match(char *arg, char *t) { if (strstr(t, arg)) return GL_TRUE; else return GL_FALSE; } /* scaleWindows - Scale initial window sizes ansd positions */ void scaleWindows(float scale) { int i; for (i = 0; i < MAXWIN; i++) { pos[i][0] = pos[i][0] * scale; pos[i][1] = pos[i][1] * scale; size[i][0] = size[i][0] * scale; size[i][1] = size[i][1] * scale; } } /* trackBall - A simple trackball (not with proper rotations). */ /** A simple trackball with spin = left button pan = middle button zoom = left + middle Doesn't have proper trackball rotation, ie axes which remain fixed in the scene. We should use the trackball code from 4Dgifts. */ #define STARTROTATE(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPROTATE(x, y) \ { \ steadyXangle = varXangle; \ steadyYangle = varYangle; \ } #define STARTPAN(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPPAN(x, y) \ { \ steadyX = varX; \ steadyY = varY; \ } #define STARTZOOM(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPZOOM(x, y) \ { \ steadyZ = varZ; \ } static float fixAngle(float angle) { return angle - floor(angle / 360.0) * 360.0; } void trackBall(int mode, int button, int state, int x, int y) { static int startMX = 0, startMY = 0; /* initial mouse pos */ static int deltaMX = 0, deltaMY = 0; /* initial mouse pos */ static float steadyXangle = 0.0, steadyYangle = 0.0; static float varXangle = 0.0, varYangle = 0.0; static float steadyX = 0.0, steadyY = 0.0, steadyZ = 0.0; static float varX = 0.0, varY = 0.0, varZ = 0.0; switch (mode) { case RESET: steadyXangle = steadyYangle = steadyX = steadyY = steadyZ = 0.0; break; case MOUSEBUTTON: if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !middleDown) { STARTROTATE(x, y); leftDown = GL_TRUE; } else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && middleDown) { STOPPAN(x, y); STARTZOOM(x, y); leftDown = GL_TRUE; } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN && !leftDown) { STARTPAN(x, y); middleDown = GL_TRUE; } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN && leftDown) { STOPROTATE(x, y); STARTZOOM(x, y); middleDown = GL_TRUE; } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && !middleDown) { STOPROTATE(x, y); leftDown = GL_FALSE; } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && middleDown) { STOPZOOM(x, y); STARTROTATE(x, y); leftDown = GL_FALSE; } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && !leftDown) { STOPPAN(x, y); middleDown = GL_FALSE; } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && leftDown) { STOPZOOM(x, y); STARTROTATE(x, y); middleDown = GL_FALSE; } break; case APPLY: if (leftDown && !middleDown) { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(varXangle, 0, 1, 0); glRotatef(varYangle, 1, 0, 0); } /* Middle button pan */ else if (middleDown && !leftDown) { glTranslatef(varX, varY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Left + middle zoom. */ else if (leftDown && middleDown) { glTranslatef(steadyX, steadyY, varZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Nothing down. */ else { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } break; case MOUSEMOTION: deltaMX = x - startMX; deltaMY = startMY - y; if (leftDown && !middleDown) { varXangle = fixAngle(steadyXangle + deltaMX); varYangle = fixAngle(steadyYangle + deltaMY); } else if (middleDown && !leftDown) { varX = steadyX + deltaMX / 100.0; varY = steadyY + deltaMY / 100.0; } else if (leftDown && middleDown) { varZ = steadyZ - deltaMY / 50.0; } break; } } /* Callbacks for exotic input devices. These have not been tested yet owing to the usual complete absence of such devices in the UK support group. */ /* spaceballMotionCB */ void spaceballMotionCB(int x, int y, int z) { printf("spaceballMotionCB: translations are X %d, Y %d, Z %d\n", x, y, z); } /* spaceballRotateCB */ void spaceballRotateCB(int x, int y, int z) { printf("spaceballRotateCB: rotations are X %d, Y %d, Z %d\n", x, y, z); } /* spaceballButtonCB */ void spaceballButtonCB(int button, int state) { printf("spaceballButtonCB: button %d, state %d\n", button, state); } /* buttonBoxCB */ void buttonBoxCB(int button, int state) { printf("buttonBoxCB: button %d, state %d\n", button, state); } /* dialsCB */ void dialsCB(int dial, int value) { printf("dialsCB: dial %d, value %d\n", dial, value); } /* tabletMotionCB */ void tabletMotionCB(int x, int y) { printf("tabletMotionCB: X %d, Y %d\n", x, y); } /* tabletButtonCB */ /* ARGSUSED2 */ void tabletButtonCB(int button, int state, int dummy1, int dummy2) { printf("tabletButtonCB: button %d, state %d\n", button, state); } lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/bigtest.ml000077500000000000000000001552351437514534100254620ustar00rootroot00000000000000 (* Ported to lablglut by Issac Trotts on Sun Aug 11 14:56:08 MDT 2002. *) open Printf (** * My first GLUT prog. * Uses most GLUT calls to prove it all works. * G Edwards 30 Aug 95. * * Notes: * Display lists are not shared between windows and there doesn't seem to be * any provision for this in GLUT. See glxCreateContext. * * The windows are internally indexed 0 1 2 3 4 5 6. The actual window ids * returned by Glut. are held in winId.(0) ... * * Todo: * * Could reorder the windows so 0 1 2 3 4 5 6 are the gfx 7 8 text. * * 30 Aug 95 GJE Created. Version 1.00 * 05 Sep 95 GJE Version 1.01. * 07 Sep 95 GJE Version 1.02. More or less complete. All possible GLUT * calls used except dials/buttons/tablet/spaceball stuff. * 15 Sep 95 GJE Add "trackball" code. * * Calls not used yet: these callbacks are registered but inactive. * * Glut.spaceballFunc * Glut.buttonBoxFunc * Glut.dialsFunc * Glut.tabletMotionFunc * Glut.tabletButtonFunc * * Tested on: * R3K Indigo Starter * R4K Indigo Elan * R4K Indy XZ * R4K Indy XL * R4K Indigo2 Extreme *) (* Controls *) let version = "1.00" let date = "17Aug02" let delay = ref 1000 (* delay for timer test *) let menudelay = ref 200 (* hack to fix Glut.menuStateFunc bug *) let maxwin = ref 9 (* max no. of windows *) let autodelay = ref 1500;(* delay in demo mode *) let pos = [| (50, 150); (* win 0 *) (450, 150); (* win 1 *) (50, 600); (* win 2 *) (450, 600); (* win 3 *) (10, 10); (* subwin 4 (relative to parent win 0) *) (300, 400); (* help win 5 *) (850, 150); (* cmap win 6 *) (850, 600); (* cmap win 7 *) (250, 450); (* text win 8 *) |] let size = [| (350, 350); (* win 0 *) (350, 350); (* win 1 *) (350, 350); (* win 2 *) (350, 350); (* win 3 *) (200, 200); (* subwin 4 *) (700, 300); (* help win 5 *) (350, 350); (* cmap win 6 *) (350, 350); (* cmap win 7 *) (800, 450); (* text win 8 *) |] let pr stuff = if !debug printf stuff (* #define GLNEWLIST(a b) glNewList(a b) fprintf(stderr "creating list %d \n" a); *) (* #define GLCALLLIST(a) glCallList(a) fprintf(stderr "calling list %d \n" a); *) (* #define GLUTSETWINDOW(x) Glut.setWindow(x) fprintf(stderr "gsw at %d\n" __LINE__) *) (* Globals *) let winId = ref [| 0 |] (* table of Glut. window IDs *) let winVis = ref [| false |] (* is window visible *) let text = ref [| false |] (* is text on *) let winFreeze = ref [| false |] (* user requested menuFreeze *) let menuFreeze = ref false (* menuFreeze while menus posted *) let timerOn = ref false (* timer active *) let animation = ref true (* idle func animation on *) let debug = ref false; (* dump all events *) let showKeys = ref false (* dump key events *) let demoMode = ref false (* run automatic demo *) let backdrop = ref false (* use backdrop polygon *) let passive = ref false (* report passive motions *) let leftDown = ref false (* left button down ? *) let middleDown = ref false (* middle button down ? *) let displayMode = Glut.double lor Glut.rgb lor Glut.depth let currentShape = ref 0 (* current Glut. shape *) let scrollLine = ref 0 and scrollCol = ref 0;(* help scrolling params *) let lineWidth = ref 1 (* line width *) let angle = ref 0 (* global rotation angle *) let textPtr = "" (* pointers to text window text *) let textCount = ref 0 and helpCount = ref 0(* text list indexes *) let scaleFactor = ref 0.0; (* window size scale factor *) let menu1 = ref(-1) and menu2 = ref(-1) and menu3 = ref(-1) let menu4 = ref(-1) and menu5 = ref(-1) and menu6 = ref 0 let menu7 = ref(-1) and menu8 = ref(-1) let modeNames m = (if m land Glut.rgba then "RGBA " else "") ^ (if m land Glut.index then "INDEX " else "") ^ (if m land Glut.single then "SINGLE " else "") ^ (if m land Glut.doublebuffer then "DOUBLEBUFFER " else "") ^ (if m land Glut.depth then "DEPTH " else "") ^ (if m land Glut.accum then "ACCUM " else "") ^ (if m land Glut.alpha then "ALPHA " else "") ^ (if m land Glut.stencil then "STENCIL " else "") ^ (if m land Glut.multisample then "MULTISAMPLE " else "") ^ (if m land Glut.stereo then "STEREO " else "") ^ let modes = ref 0 (* bit set for modes *) let menuButton = [| false; false; true |] type mode_t = | MOUSEBUTTON | MOUSEMOTION | APPLY | RESET let main () = ignore(Glut.init Sys.argv); checkArgs (); (* Scale window position/size if needed. Ignore aspect ratios. *) if (scaleFactor > 0.0) then scaleWindows(scaleFactor) else scaleWindows((Glut.get Glut.SCREEN_WIDTH) / 1280.0); (* Set initial display mode *) modes := Glut.rgba lor Glut.doublebuffer lor Glut.depth; setInitDisplayMode(); makeMenus(); makeWindow(0); makeWindow(1); Glut.idleFunc(idleFunc); Glut.menuStateFunc(menuStateFunc); if (demoMode) then autoDemo(-2); Glut.mainLoop(); ;; (* gfxInit - Init opengl for each window *) let gfxInit index = let grey10 = (0.10, 0.10, 0.10, 1.0) in let grey20 = (0.2, 0.2, 0.2, 1.0) in let black = (0.0, 0.0, 0.0, 0.0) in let diffuse0 = (1.0, 0.0, 0.0, 1.0) in let diffuse1 = (0.0, 1.0, 0.0, 1.0) in let diffuse2 = (1.0, 1.0, 0.0, 1.0) in let diffuse3 = (0.0, 1.0, 1.0, 1.0) in let diffuse4 = (1.0, 0.0, 1.0, 1.0) in let xx = 3.0 in let yy = 3.0 in let zz = (-2.5) in let vertex = [| (-. xx, -. yy, zz); ( xx, -. yy, zz); ( xx, yy, zz); (-. xx, yy, zz); |] (* warning: This func mixes RGBA and CMAP calls in an ugly fashion *) redefineShapes(!currentShape); (* set up display lists *) Glut.setWindow(winId.(index)); (* hack - redefineShapes changes Glut. win *) (* Shaded backdrop square (RGB or CMAP) *) glNewList(100 GL_COMPILE); glPushAttrib(GL_LIGHTING); glDisable(GL_LIGHTING); glBegin(GL_POLYGON); glColor4fv(black); glIndexi(0); glVertex3fv(vertex.(0)); glColor4fv(grey10); glIndexi(3); glVertex3fv(vertex.(1)); glColor4fv(grey20); glIndexi(4); glVertex3fv(vertex.(2)); glColor4fv(grey10); glIndexi(7); glVertex3fv(vertex.(3)); glEnd(); glPopAttrib(); glIndexi(9); glEndList(); (* Set proj+view *) glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0 1.0 1.0 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0 0.0 5.0 0.0 0.0 0.0 0.0 1.0 0.); glTranslatef(0.0 0.0 -1.0); if (index = 6 || index = 7) goto colorindex; (* Set basic material lighting for RGB windows *) if (index = 0) glMaterialfv(GL_FRONT GL_DIFFUSE diffuse0); else if (index = 1) glMaterialfv(GL_FRONT GL_DIFFUSE diffuse1); else if (index = 2) glMaterialfv(GL_FRONT GL_DIFFUSE diffuse2); else if (index = 3) glMaterialfv(GL_FRONT GL_DIFFUSE diffuse3); else if (index = 4) glMaterialfv(GL_FRONT GL_DIFFUSE diffuse4); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); if (index = 4) GlClear.clearColor(0.15 0.15 0.15 1); else GlClear.clearColor(0.1 0.1 0.1 1.0); return; (* Set GL basics for CMAP windows 6 7 *) colorindex: glEnable(GL_DEPTH_TEST); if (Glut.get(Glut.WINDOW_COLORMAP_SIZE) < 16) warning("Color map size too small for color index window"); (* Try to reuse an existing color map *) if ((index = 6) && (winId.(7) <> 0)) then Glut.copyColormap(winId.(7)); } else if ((index = 7) && (winId.(6) <> 0)) then Glut.copyColormap(winId.(6)); } else { Glut.setColor(8 0.1 0.1 0.1); Glut.setColor(9 1.0 0.5 0.0); Glut.setColor(10 1.0 0.6 0.8); GlClear.clearIndex(8); glIndexi(index + 3); ;; (* makeMenus - Create popup menus *) void makeMenus(void) (* General control / debug *) menu2 = Glut.createMenu(menuFunc); Glut.addMenuEntry("toggle auto demo mode (a)" 312); Glut.addMenuEntry("toggle freezing in menus" 300); Glut.addMenuEntry("toggle text per window (t)" 301); Glut.addMenuEntry("toggle global timer" 302); Glut.addMenuEntry("toggle global animation" 303); Glut.addMenuEntry("toggle per window animation" 304); Glut.addMenuEntry("toggle debug prints (D)" 305); Glut.addMenuEntry("toggle shaded backdrop" 307); Glut.addMenuEntry("toggle passive motion callback" 308); Glut.addMenuEntry("increase line width (l)" 310); Glut.addMenuEntry("decrease line width (L)" 311); (* Shapes *) menu3 = Glut.createMenu(menuFunc); Glut.addMenuEntry("sphere" 200); Glut.addMenuEntry("cube" 201); Glut.addMenuEntry("cone" 202); Glut.addMenuEntry("torus" 203); Glut.addMenuEntry("dodecahedron" 204); Glut.addMenuEntry("octahedron" 205); Glut.addMenuEntry("tetrahedron" 206); Glut.addMenuEntry("icosahedron" 207); Glut.addMenuEntry("teapot" 208); (* Open/close windows *) menu4 = Glut.createMenu(menuFunc); Glut.addMenuEntry("open all windows" 450); Glut.addMenuEntry("close all windows" 451); Glut.addMenuEntry(" " 9999); Glut.addMenuEntry("create win 0" 400); Glut.addMenuEntry("create win 1" 401); Glut.addMenuEntry("create win 2" 402); Glut.addMenuEntry("create win 3" 403); Glut.addMenuEntry("create sub window" 404); Glut.addMenuEntry("create color index win 6" 406); Glut.addMenuEntry("create color index win 7" 407); Glut.addMenuEntry(" " 9999); Glut.addMenuEntry("destroy win 0" 410); Glut.addMenuEntry("destroy win 1" 411); Glut.addMenuEntry("destroy win 2" 412); Glut.addMenuEntry("destroy win 3" 413); Glut.addMenuEntry("destroy sub window" 414); Glut.addMenuEntry("destroy color index win 6" 416); Glut.addMenuEntry("destroy color index win 7" 417); (* Window manager stuff *) menu5 = Glut.createMenu(menuFunc); Glut.addMenuEntry("move current win" 430); Glut.addMenuEntry("resize current win" 431); Glut.addMenuEntry("iconify current win" 432); Glut.addMenuEntry("show current win" 433); Glut.addMenuEntry("hide current win" 434); Glut.addMenuEntry("push current win" 435); Glut.addMenuEntry("pop current win" 436); Glut.addMenuEntry(" " 9999); Glut.addMenuEntry("move win 1" 420); Glut.addMenuEntry("resize win 1" 421); Glut.addMenuEntry("iconify win 1" 422); Glut.addMenuEntry("show win 1" 423); Glut.addMenuEntry("hide win 1" 424); Glut.addMenuEntry("push win 1" 425); Glut.addMenuEntry("pop win 1" 426); (* Gfx modes *) createMenu6(); (* build dynamically *) (* Texty reports *) menu7 = Glut.createMenu(menuFunc); Glut.addMenuEntry("report current win modes" 700); Glut.addMenuEntry("report current device data" 701); Glut.addMenuEntry("check OpenGL extensions" 702); Glut.addMenuEntry("dump internal data (d)" 703); (* Play with menus *) menu8 = Glut.createMenu(menuFunc); Glut.addMenuEntry("toggle menus on left button" 805); Glut.addMenuEntry("toggle menus on middle button" 806); Glut.addMenuEntry("toggle menus on right button" 807); Glut.addMenuEntry("---------------------------" 9999); Glut.addMenuEntry("add plain items" 800); Glut.addMenuEntry("add submenu items" 801); Glut.addMenuEntry("change new entries to plain items" 802); Glut.addMenuEntry("change new entries to submenus" 803); Glut.addMenuEntry("remove all new items" 804); Glut.addMenuEntry("---------------------------" 9999); (* Main menu *) menu1 = Glut.createMenu(menuFunc); Glut.addSubMenu("control" menu2); Glut.addSubMenu("shapes" menu3); Glut.addSubMenu("windows" menu4); Glut.addSubMenu("window ops" menu5); Glut.addSubMenu("gfx modes" menu6); Glut.addSubMenu("reports" menu7); Glut.addSubMenu("menus" menu8); Glut.addMenuEntry("help (h)" 101); Glut.addMenuEntry("quit (esc)" 100); ;; (* createMenu6 - Dynamically rebuild menu of display modes to show current choices *) void createMenu6(void) char str.(100); int i; if (menu6 <> 0) Glut.destroyMenu(menu6); menu6 = Glut.createMenu(menuFunc); incr for (i = 0; i < MODES; i) { sprintf(str "%srequest %s" (modes land ((i) ? "+ " : " ") modeNames.(i)); Glut.addMenuEntry(str 602 + i); ;; (* menuFunc - Process return codes from popup menus *) void menuFunc(int value) static int initItems = 10; int items m; if (initItems = 0) then Glut.setMenu(menu8); initItems = Glut.get(Glut.MENU_NUM_ITEMS); PR("Menu returned value %d \n" value); match value with (* GLUT shapes *) | 200 -> | 201 -> | 202 -> | 203 -> | 204 -> | 205 -> | 206 -> | 207 -> | 208 -> redefineShapes(value - 200); break; (* Overall controls *) | 300 -> menuFreeze = not menuFreeze; break; | 301 -> text.(idToIndex(Glut.getWindow())) = not (text.(idToIndex(Glut.getWindow()))); break; | 302 -> timerOn = not timerOn; if (timerOn) Glut.timerFunc(DELAY timerFunc 1); break; | 303 -> animation = not animation; if (animation) Glut.idleFunc(idleFunc); else Glut.idleFunc(NULL); break; | 304 -> winFreeze.(idToIndex(Glut.getWindow())) = not (winFreeze[idToIndex( Glut.getWindow())]); break; | 305 -> debug = not debug; break; | 307 -> backdrop = not backdrop; break; | 308 -> passive = not passive; if (passive) Glut.passiveMotionFunc(passiveMotionFunc); else Glut.passiveMotionFunc(NULL); break; | 310 -> lineWidth += 1; updateAll(); break; | 311 -> lineWidth -= 1; if (lineWidth < 1) lineWidth = 1; updateAll(); break; | 312 -> demoMode = not demoMode; if (demoMode) autoDemo(-2); break; (* Window create/destroy. *) (* Creates *) | 400 -> makeWindow(0); break; | 401 -> makeWindow(1); break; | 402 -> makeWindow(2); break; | 403 -> makeWindow(3); break; | 404 -> makeWindow(4); break; | 406 -> makeWindow(6); break; | 407 -> makeWindow(7); break; (* Destroys *) | 410 -> killWindow(0); break; | 411 -> killWindow(1); break; | 412 -> killWindow(2); break; | 413 -> killWindow(3); break; | 414 -> killWindow(4); break; | 416 -> killWindow(6); break; | 417 -> killWindow(7); break; | 450 -> makeAllWindows(); break; | 451 -> killAllWindows(); break; (* Window movements etc. *) | 420 -> positionWindow(1); break; | 421 -> reshapeWindow(1); break; | 422 -> iconifyWindow(1); break; | 423 -> showWindow(1); break; | 424 -> hideWindow(1); break; | 425 -> pushWindow(1); break; | 426 -> popWindow(1); break; | 430 -> positionWindow(idToIndex(Glut.getWindow())); break; | 431 -> reshapeWindow(idToIndex(Glut.getWindow())); break; | 432 -> iconifyWindow(idToIndex(Glut.getWindow())); break; | 433 -> showWindow(idToIndex(Glut.getWindow())); break; | 434 -> hideWindow(idToIndex(Glut.getWindow())); break; | 435 -> pushWindow(idToIndex(Glut.getWindow())); break; | 436 -> popWindow(idToIndex(Glut.getWindow())); break; (* Test gfx modes. *) | 600 -> makeWindow(3); break; | 601 -> killWindow(3); break; | 602 -> | 603 -> | 604 -> | 605 -> | 606 -> | 607 -> | 608 -> | 609 -> | 610 -> | 611 -> modes.(value - 602) = not modes.(value - 602); setInitDisplayMode(); break; (* Text reports *) (* This is pretty ugly. *) #define INDENT 30 #define REPORTSTART(text) \ printf("\n" text "\n"); \ textPtr.(0) = (char *)malloc(strlen(text)+1); \ strcpy(textPtr.(0) text); \ textCount = 1; #define REPORTEND \ scrollLine = 0; \ textPtr.(textCount) = NULL; \ makeWindow(8); \ updateText(); #define GLUTGET(name) \ { \ char str.(100) str2.(100); \ int s len; \ sprintf(str # name); \ len = (int) strlen(# name); \ incr for(s = 0 ; s < INDENT-len; s) \ strcat(str " "); \ sprintf(str2 ": %d\n" Glut.get(name)); \ strcat(str str2); \ printf(str); \ textPtr.(textCount) = str \ incr textCount; \ | 700 -> printf("XXXXXX Glut.getWindow = %d\n" Glut.getWindow()); REPORTSTART("Glut.get():"); GLUTGET(Glut.WINDOW_X); GLUTGET(Glut.WINDOW_Y); GLUTGET(Glut.WINDOW_WIDTH); GLUTGET(Glut.WINDOW_HEIGHT); GLUTGET(Glut.WINDOW_BUFFER_SIZE); GLUTGET(Glut.WINDOW_STENCIL_SIZE); GLUTGET(Glut.WINDOW_DEPTH_SIZE); GLUTGET(Glut.WINDOW_RED_SIZE); GLUTGET(Glut.WINDOW_GREEN_SIZE); GLUTGET(Glut.WINDOW_BLUE_SIZE); GLUTGET(Glut.WINDOW_ALPHA_SIZE); GLUTGET(Glut.WINDOW_ACCUM_RED_SIZE); GLUTGET(Glut.WINDOW_ACCUM_GREEN_SIZE); GLUTGET(Glut.WINDOW_ACCUM_BLUE_SIZE); GLUTGET(Glut.WINDOW_ACCUM_ALPHA_SIZE); GLUTGET(Glut.WINDOW_DOUBLEBUFFER); GLUTGET(Glut.WINDOW_RGBA); GLUTGET(Glut.WINDOW_PARENT); GLUTGET(Glut.WINDOW_NUM_CHILDREN); GLUTGET(Glut.WINDOW_COLORMAP_SIZE); GLUTGET(Glut.WINDOW_NUM_SAMPLES); GLUTGET(Glut.STEREO); GLUTGET(Glut.SCREEN_WIDTH); GLUTGET(Glut.SCREEN_HEIGHT); GLUTGET(Glut.SCREEN_HEIGHT_MM); GLUTGET(Glut.SCREEN_WIDTH_MM); GLUTGET(Glut.MENU_NUM_ITEMS); GLUTGET(Glut.DISPLAY_MODE_POSSIBLE); GLUTGET(Glut.INIT_DISPLAY_MODE); GLUTGET(Glut.INIT_WINDOW_X); GLUTGET(Glut.INIT_WINDOW_Y); GLUTGET(Glut.INIT_WINDOW_WIDTH); GLUTGET(Glut.INIT_WINDOW_HEIGHT); GLUTGET(Glut.ELAPSED_TIME); REPORTEND; break; #define GLUTDEVGET(name) \ { \ char str.(100) str2.(100); \ int len s; \ sprintf(str # name); \ len = (int) strlen(# name); \ incr for(s = 0 ; s < INDENT-len; s) \ strcat(str " "); \ sprintf(str2 ": %d\n" \ Glut.deviceGet(name)); \ strcat(str str2); \ printf(str); \ textPtr.(textCount) = str; \ incr textCount; \ | 701 -> REPORTSTART("Glut.deviceGet():"); GLUTDEVGET(Glut.HAS_KEYBOARD); GLUTDEVGET(Glut.HAS_MOUSE); GLUTDEVGET(Glut.HAS_SPACEBALL); GLUTDEVGET(Glut.HAS_DIAL_AND_BUTTON_BOX); GLUTDEVGET(Glut.HAS_TABLET); GLUTDEVGET(Glut.NUM_MOUSE_BUTTONS); GLUTDEVGET(Glut.NUM_SPACEBALL_BUTTONS); GLUTDEVGET(Glut.NUM_BUTTON_BOX_BUTTONS); GLUTDEVGET(Glut.NUM_DIALS); GLUTDEVGET(Glut.NUM_TABLET_BUTTONS); REPORTEND; break; #define EXTCHECK(name) \ { \ char str.(100) str2.(100); \ int len s; \ sprintf(str # name); \ len = (int) strlen(# name); \ incr for(s = 0 ; s < INDENT-len; s) \ strcat(str " "); \ sprintf(str2 ": %s\n" \ Glut.extensionSupported(# name)? \ "yes": "no"); \ strcat(str str2); \ printf(str); \ textPtr.(textCount) = str; \ incr textCount; \ | 702 -> REPORTSTART("Glut.extensionSupported():"); EXTCHECK(GL_EXT_abgr); EXTCHECK(GL_EXT_blend_color); EXTCHECK(GL_EXT_blend_minmax); EXTCHECK(GL_EXT_blend_logic_op); EXTCHECK(GL_EXT_blend_subtract); EXTCHECK(GL_EXT_polygon_offset); EXTCHECK(GL_EXT_texture); EXTCHECK(GL_EXT_guaranteed_to_fail); EXTCHECK(GLX_SGI_swap_control); EXTCHECK(GLX_SGI_video_sync); EXTCHECK(GLX_SGIS_multi_sample); REPORTEND; break; | 703 -> dumpIds(); break; (* Mess around with menus *) | 800 -> if (Glut.getMenu() <> menu8) (* just a test *) printf("Glut.getMenu() returned unexpected value\n"); Glut.addMenuEntry("help" 101); Glut.addMenuEntry("help" 101); Glut.addMenuEntry("help" 101); Glut.addMenuEntry("help" 101); Glut.addMenuEntry("help" 101); break; | 801 -> Glut.addSubMenu("shapes" menu3); Glut.addSubMenu("shapes" menu3); Glut.addSubMenu("shapes (a long string to break menus with)" menu3); Glut.addSubMenu("shapes" menu3); Glut.addSubMenu("shapes" menu3); break; | 802 -> items = Glut.get(Glut.MENU_NUM_ITEMS); incr for (m = initItems + 1; m <= items; m) { Glut.changeToMenuEntry(m "help" 101); break; | 803 -> items = Glut.get(Glut.MENU_NUM_ITEMS); incr for (m = initItems + 1; m <= items; m) { Glut.changeToSubMenu(m "shapes" menu3); break; | 804 -> items = Glut.get(Glut.MENU_NUM_ITEMS); (* reverse order so renumbering not aproblem *) for (m = items; m >= initItems + 1; m--) { Glut.removeMenuItem(m); break; | 805 -> menuButton.(0) = not menuButton.(0); attachMenus(); break; | 806 -> menuButton.(1) = not menuButton.(1); attachMenus(); break; | 807 -> menuButton.(2) = not menuButton.(2); attachMenus(); break; (* Direct menu items. *) | 100 -> exit(0); break; | 101 -> if (winId.(5) = 0) makeWindow(5); else killWindow(5); break; | 9999 -> break; | _ -> fprintf(stderr "\007Unhandled case %d in menu callback\n" value); ;; (* redefineShapes - Remake the shapes display lists *) void redefineShapes(int shape) int i; #define C3 \ switch(i) \ { \ | 0 -> \ | 3 -> \ C1; \ break; \ \ | 1 -> \ | 2 -> \ | 4 -> \ | 6 -> \ | 7 -> \ C2; \ break; \ } \ currentShape = shape incr for (i = 0; i < MAXWIN; i) { if (winId.(i)) then Glut.setWindow(winId.(i)); if (glIsList(i + 1)) glDeleteLists(i + 1 1); glNewList(i + 1 GL_COMPILE); match shape with #undef C1 #define C1 Glut.solidSphere(1.5 10 10) #undef C2 #define C2 Glut.wireSphere(1.5 10 10) | 0 -> C3; break; #undef C1 #define C1 Glut.solidCube(2) #undef C2 #define C2 Glut.wireCube(2) | 1 -> C3; break; #undef C1 #define C1 Glut.solidCone(1.5 1.75 10 10); #undef C2 #define C2 Glut.wireCone(1.5 1.75 10 10); | 2 -> C3; break; #undef C1 #define C1 Glut.solidTorus(0.5 1.1 10 10) #undef C2 #define C2 Glut.wireTorus(0.5 1.1 10 10) | 3 -> C3; break; #undef C1 #define C1 glScalef(.8 .8 .8);Glut.solidDodecahedron() #undef C2 #define C2 glScalef(.8 .8 .8);Glut.wireDodecahedron() | 4 -> C3; break; #undef C1 #define C1 glScalef(1.5 1.5 1.5);Glut.solidOctahedron() #undef C2 #define C2 glScalef(1.5 1.5 1.5);Glut.wireOctahedron() | 5 -> C3; break; #undef C1 #define C1 glScalef(1.8 1.8 1.8);Glut.solidTetrahedron() #undef C2 #define C2 glScalef(1.8 1.8 1.8);Glut.wireTetrahedron() | 6 -> C3; break; #undef C1 #define C1 glScalef(1.5 1.5 1.5);Glut.solidIcosahedron() #undef C2 #define C2 glScalef(1.5 1.5 1.5);Glut.wireIcosahedron() | 7 -> C3; break; #undef C1 #define C1 Glut.solidTeapot(1.5); #undef C2 #define C2 Glut.wireTeapot(1.5); | 8 -> C3; break; glEndList(); ;; (* positionWindow - Shift a window *) void positionWindow(int index) int x y; if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); x = Glut.get(Glut.WINDOW_X); y = Glut.get(Glut.WINDOW_Y); Glut.positionWindow(x + 50 y + 50); ;; (* reshapeWindow - Change window size a little *) void reshapeWindow(int index) int x y; if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); x = Glut.get(Glut.WINDOW_WIDTH); y = Glut.get(Glut.WINDOW_HEIGHT); (* Glut.reshapeWindow(x * (index % 2? 0.8: 1.2) y * (index % 2? 1.2: 0.8)); *) Glut.reshapeWindow((int) (x * 1.0) (int) (y * 0.8)); ;; (* iconifyWindow - Iconify a window *) void iconifyWindow(int index) if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); Glut.iconifyWindow(); ;; (* showWindow - Show a window (map or uniconify it) *) void showWindow(int index) if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); Glut.showWindow(); ;; (* hideWindow - Hide a window (unmap it) *) void hideWindow(int index) if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); Glut.hideWindow(); ;; (* pushWindow - Push a window *) void pushWindow(int index) if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); Glut.pushWindow(); ;; (* popWindow - Pop a window *) void popWindow(int index) if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); Glut.popWindow(); ;; (* drawScene - Draw callback triggered by expose events etc. in GLUT. *) void drawScene(void) int winIndex; GlClear.clear(GL_COLOR_BUFFER_BIT lor GL_DEPTH_BUFFER_BIT); winIndex = idToIndex(Glut.getWindow()); (* printf("drawScene for index %d id %d\n" winIndex Glut.getWindow()); *) glPushMatrix(); glLineWidth(lineWidth); if (backdrop) glCallList(100); (* Left button spinning *) trackBall(APPLY 0 0 0 0); (* Apply continuous spinning *) glRotatef(angle 0 1 0); glCallList(winIndex + 1); glPopMatrix(); if (text.(winIndex)) showText(); Glut.swapBuffers(); ;; (* showText - Render some text in the current GLUT window *) void showText(void) glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0 100 0 100); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0 1.0 1.0); glIndexi(7); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glLineWidth(lineWidth); textString(1 1 "Glut.BITMAP_8_BY_13" Glut.BITMAP_8_BY_13); textString(1 5 "Glut.BITMAP_9_BY_15" Glut.BITMAP_9_BY_15); textString(1 10 "Glut.BITMAP_TIMES_ROMAN_10" Glut.BITMAP_TIMES_ROMAN_10); textString(1 15 "Glut.BITMAP_TIMES_ROMAN_24" Glut.BITMAP_TIMES_ROMAN_24); strokeString(1 25 "Glut.STROKE_ROMAN" Glut.STROKE_ROMAN); strokeString(1 35 "Glut.STROKE_MONO_ROMAN" Glut.STROKE_MONO_ROMAN); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); ;; (* textString - Bitmap font string *) void textString(int x int y char *msg void *font) glRasterPos2f(x y); while (*msg) { Glut.bitmapCharacter(font *msg); incr msg; ;; (* strokeString - Stroke font string *) void strokeString(int x int y char *msg void *font) glPushMatrix(); glTranslatef(x y 0); glScalef(.04 .04 .04); while (*msg) { Glut.strokeCharacter(font *msg); incr msg; glPopMatrix(); ;; (* idleFunc - GLUT idle func callback - animates windows *) void idleFunc(void) int i; if ( not leftDown && not middleDown) angle += 1; angle = angle % 360; incr for (i = 0; i < MAXWIN; i) { if (winId.(i) && winVis.(i) && not winFreeze.(i)) then Glut.setWindow(winId.(i)); Glut.postRedisplay(); ;; (* reshapeFunc - Reshape callback. *) void reshapeFunc(int width int height) int winId; float aspect; winId = Glut.getWindow(); PR("reshape callback for window id %d \n" winId); glViewport(0 0 width height); aspect = (float) width / height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0 aspect 1.0 20.0); glMatrixMode(GL_MODELVIEW); ;; (* visible - Visibility callback. Turn off rendering in invisible windows *) void visible(int state) int winId; static GLboolean someVisible = GL_TRUE; winId = Glut.getWindow(); (* printf("visible: state = %d \n" state); *) if (state = Glut.VISIBLE) then PR("Window id %d visible \n" winId); winVis.(idToIndex(winId)) = GL_TRUE; } else { PR("Window %d not visible \n" winId); winVis.(idToIndex(winId)) = GL_FALSE; if ((winVis.(0) = GL_FALSE) && (winVis.(1) = GL_FALSE) && (winVis.(2) = GL_FALSE) && (winVis.(3) = GL_FALSE) && (winVis.(6) = GL_FALSE) && (winVis.(7) = GL_FALSE)) { Glut.idleFunc(NULL); PR("All windows not visible; idle func disabled\n"); someVisible = GL_FALSE; } else { if ( not someVisible) then PR("Some windows now visible; idle func enabled\n"); someVisible = GL_TRUE; if (animation) Glut.idleFunc(idleFunc); ;; (* keyFunc - Ascii key callback *) (* ARGSUSED1 *) void keyFunc(unsigned char key int x int y) int i ii; if (debug || showKeys) printf("Ascii key '%c' 0x%02x\n" key key); match key with | 0x1b -> exit(0); break; | 'a' -> demoMode = not demoMode; if (demoMode) autoDemo(-2); break; | 's' -> AUTODELAY = AUTODELAY * 0.666; break; | 'S' -> AUTODELAY = AUTODELAY * 1.5; break; | 'q' -> killWindow(idToIndex(Glut.getWindow())); break; | 'k' -> showKeys = not showKeys; break; | 'p' -> demoMode = not demoMode; if (demoMode) autoDemo(-999); break; | 'D' -> debug = not debug; break; | 'd' -> dumpIds(); break; | 'h' -> if (winId.(5) = 0) makeWindow(5); else killWindow(5); break; | 't' -> ii = idToIndex(Glut.getWindow()); text.(ii) = not text.(ii); break; | 'r' -> trackBall(RESET 0 0 0 0); break; | 'l' -> lineWidth += 1; updateAll(); break; | 'L' -> lineWidth -= 1; if (lineWidth < 1) lineWidth = 1; updateAll(); break; | '0' -> | '1' -> | '2' -> | '3' -> | '4' -> | '6' -> i = key - '0'; winVis.(i) = not winVis.(i); break; | ')' -> makeWindow(0); break; | ' not ' -> makeWindow(1); break; | '@' -> makeWindow(2); break; | '#' -> makeWindow(3); break; ;; (* specialFunc - Special keys callback (F keys cursor keys etc. *) (* ARGSUSED1 *) void specialFunc(int key int x int y) if (debug || showKeys) printf("Special key %d\n" key); match key with | Glut.KEY_PAGE_DOWN -> scrollLine += 10; updateHelp(); updateText(); break; | Glut.KEY_PAGE_UP -> scrollLine -= 10; updateHelp(); updateText(); break; | Glut.KEY_DOWN -> scrollLine += 1; updateHelp(); updateText(); break; | Glut.KEY_UP -> scrollLine -= 1; updateHelp(); updateText(); break; | Glut.KEY_HOME -> scrollLine = 0; updateHelp(); updateText(); break; | Glut.KEY_END -> scrollLine = 9999; updateHelp(); updateText(); break; | Glut.KEY_RIGHT -> scrollCol -= 1; updateHelp(); updateText(); break; | Glut.KEY_LEFT -> scrollCol += 1; updateHelp(); updateText(); break; ;; (* mouseFunc - Mouse button callback *) void mouseFunc(int button int state int x int y) PR("Mouse button %d state %d at pos %d %d\n" button state x y); trackBall(MOUSEBUTTON button state x y); ;; (* motionFunc - Mouse movement (with a button down) callback *) void motionFunc(int x int y) PR("Mouse motion at %d %d\n" x y); trackBall(MOUSEMOTION 0 0 x y); Glut.postRedisplay(); ;; (* passiveMotionFunc - Mouse movement (with no button down) callback *) void passiveMotionFunc(int x int y) printf("Mouse motion at %d %d\n" x y); ;; (* entryFunc - Window entry event callback *) void entryFunc(int state) int winId = Glut.getWindow(); PR("Entry event: window id %d (index %d) state %d \n" winId idToIndex( winId) state); ;; (* menuStateFunc - Callback to tell us when menus are popped up/down. *) int menu_state = Glut.MENU_NOT_IN_USE; void menuStateFunc(int state) printf("menu stated = %d\n" state); menu_state = state; if (Glut.getWindow() = 0) then PR("menuStateFunc: window invalid\n"); return; PR("Menus are%sin use\n" state = Glut.MENU_IN_USE ? " " : " not "); if ((state = Glut.MENU_IN_USE) && menuFreeze) Glut.idleFunc(NULL); else if (animation) Glut.idleFunc(idleFunc); ;; (* timerFunc - General test of global timer *) void timerFunc(int value) printf("timer callback: value %d\n" value); if (timerOn) then Glut.timerFunc(DELAY timerFunc 1); ;; #if 0 (* delayedReinstateMenuStateCallback - Hack to reinstate MenuStateCallback after a while. *) void delayedReinstateMenuStateCallback(int state) Glut.menuStateFunc(menuStateFunc); ;; #endif (* setInitDisplayMode - update display modes from display mode menu *) void setInitDisplayMode(void) int i; displayMode = 0; incr for (i = 0; i < MODES; i) { if (modes.(i)) then (* printf("Requesting %s \n" modeNames.(i)); *) displayMode lor = Glut.mode.(i); Glut.initDisplayMode(displayMode); createMenu6(); if ( not Glut.get(Glut.DISPLAY_MODE_POSSIBLE)) warning("This display mode not supported\n"); ;; (* makeWindow - Create one of the windows *) void makeWindow(int index) char str.(99); if (winId.(index) <> 0) then (* warning("Attempt to create window which is already created"); *) return; match index with | 0 -> (* ordinary RGB windows *) | 1 -> | 2 -> | 3 -> setInitDisplayMode(); Glut.initWindowPosition(pos.(index).(0) pos.(index).(1)); Glut.initWindowSize(size.(index).(0) size.(index).(1)); winId.(index) = Glut.createWindow(" "); PR("Window %d id = %d \n" index winId.(index)); gfxInit(index); addCallbacks(); sprintf(str "window %d (RGB)" index); Glut.setWindowTitle(str); sprintf(str "icon %d" index); Glut.setIconTitle(str); Glut.setMenu(menu1); Glut.attachMenu(Glut.RIGHT_BUTTON); break; | 4 -> (* subwindow *) setInitDisplayMode(); winId.(index) = Glut.createSubWindow(winId.(0) pos.(index).(0) pos.(index) .(1) size.(index).(0) size.(index).(1)); PR("Window %d id = %d \n" index winId.(index)); gfxInit(index); Glut.displayFunc(drawScene); Glut.visibilityFunc(visible); Glut.reshapeFunc(reshapeFunc); break; | 5 -> (* help window *) | 8 -> (* text window *) Glut.initDisplayMode(Glut.DOUBLE lor Glut.RGB lor Glut.DEPTH); Glut.initWindowPosition(pos.(index).(0) pos.(index).(1)); Glut.initWindowSize(size.(index).(0) size.(index).(1)); winId.(index) = Glut.createWindow(" "); PR("Window %d id = %d \n" index winId.(index)); (* addCallbacks(); *) Glut.keyboardFunc(keyFunc); Glut.specialFunc(specialFunc); GlClear.clearColor(0.15 0.15 0.15 1.0); glColor3f(1 1 1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0 300 0 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (index = 5) then Glut.displayFunc(updateHelp); Glut.setWindowTitle("help (RGB) win 5"); Glut.setIconTitle("help"); } else { Glut.displayFunc(updateText); Glut.setWindowTitle("text (RGB) win 8"); Glut.setIconTitle("text"); Glut.setMenu(menu1); Glut.attachMenu(Glut.RIGHT_BUTTON); break; | 6 -> (* color index window *) | 7 -> (* color index window *) Glut.initDisplayMode(Glut.DOUBLE lor Glut.INDEX lor Glut.DEPTH); Glut.initWindowPosition(pos.(index).(0) pos.(index).(1)); Glut.initWindowSize(size.(index).(0) size.(index).(1)); winId.(index) = Glut.createWindow(" "); PR("Window %d id = %d \n" index winId.(index)); gfxInit(index); addCallbacks(); sprintf(str "window %d (color index)" index); Glut.setWindowTitle(str); sprintf(str "icon %d" index); Glut.setIconTitle(str); Glut.setMenu(menu1); Glut.attachMenu(Glut.RIGHT_BUTTON); break; ;; (* killWindow - Kill one of the main windows *) void killWindow(int index) int i; if (winId.(index) = 0) then (* fprintf(stderr "Attempt to kill invalid window in killWindow\n"); *) return; PR("Killing win %d\n" index); Glut.setWindow(winId.(index)); (* Disable all callbacks for safety although Glut.destroyWindow should do this. *) removeCallbacks(); Glut.destroyWindow(winId.(index)); winId.(index) = 0; winVis.(index) = GL_FALSE; #if 0 (* If we reinstate the menu state func here prog breaks. So reinstate it a little later. *) Glut.timerFunc(MENUDELAY delayedReinstateMenuStateCallback 1); #endif if (index = 5) then (* help *) scrollLine = 0; scrollCol = 0; if (index = 8) then (* text window *) incr for (i = 0; textPtr.(i) <> NULL; i) { free(textPtr.(i)); (* free the text strings *) textPtr.(i) = NULL; ;; (* addCallbacks - Add some standard callbacks after creating a window *) void addCallbacks(void) Glut.displayFunc(drawScene); Glut.visibilityFunc(visible); Glut.reshapeFunc(reshapeFunc); Glut.keyboardFunc(keyFunc); Glut.specialFunc(specialFunc); Glut.mouseFunc(mouseFunc); Glut.motionFunc(motionFunc); Glut.entryFunc(entryFunc); (* Callbacks for exotic input devices. Must get my dials & buttons back. *) Glut.spaceballMotionFunc(spaceballMotionCB); Glut.spaceballRotateFunc(spaceballRotateCB); Glut.spaceballButtonFunc(spaceballButtonCB); Glut.buttonBoxFunc(buttonBoxCB); Glut.dialsFunc(dialsCB); Glut.tabletMotionFunc(tabletMotionCB); Glut.tabletButtonFunc(tabletButtonCB); ;; (* removeCallbacks - Remove all callbacks before destroying a window. GLUT probably does this anyway but we'll be safe. *) void removeCallbacks(void) Glut.visibilityFunc(NULL); Glut.reshapeFunc(NULL); Glut.keyboardFunc(NULL); Glut.specialFunc(NULL); Glut.mouseFunc(NULL); Glut.motionFunc(NULL); Glut.entryFunc(NULL); ;; (* updateHelp - Update the help window after user scrolls. *) void updateHelp(void) static char *helpPtr[] = "(Use PGUP PGDN HOME END arrows to scroll help text) " " " "A demo program for GLUT. " "G Edwards Aug 95 " "Exercises 99% of GLUT calls " VERSIONLONG " " "This text uses Glut.STROKE_MONO_ROMAN font a built-in vector font." "(Try resizing the help window). " " " "Keys: " " esc quit " " t toggle text on/off in each window " " h toggle help " " q quit current window " " a auto demo " " p pause/unpause demo " " l increase line width (gfx land stroke text) " " L decrease line width (gfx land stroke text) " " r reset transforms " " k show keyboard events " " D show all events " " " "Mouse: " " Left button: rotate " " Middle button: pan " " Left + middle: zoom " NULL}; updateScrollWindow(5 helpPtr); ;; (* updateText - Update a text window *) void updateText(void) int i; if (textPtr.(0) = NULL) then incr for (i = 0; i < 20; i) { textPtr.(i) = (char *) malloc(50); strcpy(textPtr.(i) "no current text"); textPtr.(20) = NULL; updateScrollWindow(8 textPtr); ;; (* updateScrollWindow *) void updateScrollWindow(int index char **ptr) int i j lines = 0; if (winId.(index) = 0) return; Glut.setWindow(winId.(index)); incr for (i = 0; ptr.(i) <> NULL; i) incr lines; if (scrollLine < 0) scrollLine = 0; if (scrollLine > (lines - 5)) scrollLine = lines - 5; GlClear.clear(GL_COLOR_BUFFER_BIT); glLineWidth(lineWidth); incr for (i = scrollLine j = 1; ptr.(i) <> NULL; i++ j) strokeString(scrollCol * 50 100 - j * 6 ptr.(i) Glut.STROKE_MONO_ROMAN); Glut.swapBuffers(); ;; (* updateAll - Update all visible windows after soem global change eg. line width *) void updateAll(void) int i; if (winId.(5) <> 0) updateHelp(); if (winId.(8) <> 0) updateText(); incr for (i = 0; i < MAXWIN; i) if (winId.(i)) then Glut.setWindow(winId.(i)); Glut.postRedisplay(); ;; (* idToIndex - Convert GLUT window id to our internal index *) int idToIndex(int id) int i; incr for (i = 0; i < MAXWIN; i) { if (winId.(i) = id) return i; fprintf(stderr "error: id %d not found \n" id); return (-1); ;; (* warning - warning messages *) void warning(char *msg) fprintf(stderr "\007"); if (debug) then fprintf(stderr "%s" msg); if (msg.(strlen(msg)) <> '\n') fprintf(stderr "%s" "\n"); ;; (* dumpIds - Debug: dump some internal data *) void dumpIds(void) int i j; printf("\nInternal data:\n"); incr for (i = 0; i < MAXWIN; i) printf("Index %d Glut. win id %d visibility %d\n" i winId.(i) winVis.(i)); incr for (i = 0; i < MAXWIN; i) { if (winId.(i)) Glut.setWindow(winId.(i)); else { printf("index %d - no Glut. window\n" i); continue; incr for (j = 1; j <= MAXWIN; j) printf("Index %d display list %d %s defined\n" i j glIsList(j) ? "is " : "not"); ;; (* autoDemo - Run auto demo/test This is a bit tricky. We need to start a timer sequence which progressively orders things to be done. The work really gets done when we return from our callback. Have to think about the event loop / callback design here. *) void autoDemo(int value) #define STEP(a b) \ | a -> \ action(a); \ Glut.timerFunc(AUTODELAY * b autoDemo next(a); \ break; static int index = 0; static int count = 0; static int restartValue = -2; if (value = -999) value = restartValue; restartValue = value; #define AUTODELAY2 (unsigned int) (AUTODELAY*0.66) (* fprintf(stderr "autoDemo: value %d \n" value); *) if ( not demoMode) return; if (menu_state = Glut.MENU_IN_USE) then Glut.timerFunc(AUTODELAY / 2 autoDemo value); return; match value with (* Entry point; kill off existing windows. *) | -2 -> killAllWindows(); Glut.timerFunc(AUTODELAY / 2 autoDemo 1); break; (* Start making windows *) | -1 -> makeWindow(0); Glut.timerFunc(AUTODELAY autoDemo 0); (* skip case 0 first time *) break; (* Change shape land backdrop *) | 0 -> currentShape = (currentShape + 1) % 9; redefineShapes(currentShape); count += 1; if (count % 2) backdrop = not backdrop; Glut.timerFunc(AUTODELAY autoDemo 1); break; (* Keep making windows *) | 1 -> makeWindow(1); Glut.timerFunc(AUTODELAY autoDemo 2); break; | 2 -> makeWindow(2); Glut.timerFunc(AUTODELAY autoDemo 3); break; | 3 -> makeWindow(3); Glut.timerFunc(AUTODELAY autoDemo 4); break; | 4 -> makeWindow(4); Glut.timerFunc(AUTODELAY autoDemo 5); break; | 5 -> makeWindow(5); Glut.timerFunc(AUTODELAY * 2 autoDemo 51); break; | 51 -> makeWindow(6); Glut.timerFunc(AUTODELAY * 2 autoDemo 52); break; | 52 -> makeWindow(7); Glut.timerFunc(AUTODELAY * 2 autoDemo 53); break; (* Kill last 3 windows leave 4 up. *) | 53 -> killWindow(7); Glut.timerFunc(AUTODELAY autoDemo 54); break; | 54 -> killWindow(6); Glut.timerFunc(AUTODELAY autoDemo 6); break; | 6 -> killWindow(5); Glut.timerFunc(AUTODELAY autoDemo 7); break; | 7 -> killWindow(4); Glut.timerFunc(AUTODELAY autoDemo 700); break; (* Change shape again *) | 700 -> currentShape = (currentShape + 1) % 9; redefineShapes(currentShape); Glut.timerFunc(AUTODELAY autoDemo 701); break; (* Cycle 4 main windows through various window ops. *) | 701 -> positionWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 701 : 702); break; | 702 -> reshapeWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 702 : 703); break; | 703 -> iconifyWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 703 : 704); break; | 704 -> showWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 704 : 705); break; | 705 -> hideWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 705 : 706); break; | 706 -> showWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 706 : 707); break; | 707 -> pushWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 707 : 708); break; | 708 -> popWindow(index); index = (index + 1) % 4; Glut.timerFunc(AUTODELAY2 autoDemo index > 0 ? 708 : 8); break; (* Kill all windows *) | 8 -> killWindow(3); Glut.timerFunc(AUTODELAY autoDemo 9); break; | 9 -> killWindow(2); Glut.timerFunc(AUTODELAY autoDemo 10); break; | 10 -> killWindow(1); Glut.timerFunc(AUTODELAY autoDemo 11); break; | 11 -> killWindow(0); Glut.timerFunc(AUTODELAY autoDemo -1); (* back to start *) break; ;; (* attachMenus - Attach/detach menus to/from mouse buttons *) void attachMenus(void) int i b; int button.(3) = {Glut.LEFT_BUTTON Glut.MIDDLE_BUTTON Glut.RIGHT_BUTTON}; incr for (i = 0; i < MAXWIN; i) { if (winId.(i) <> 0) then incr for (b = 0; b < 3; b) { Glut.setWindow(winId.(i)); Glut.setMenu(menu1); if (menuButton.(b)) Glut.attachMenu(button.(b)); else Glut.detachMenu(button.(b)); ;; (* killAllWindows - Kill all windows (except 0) *) void killAllWindows(void) int w; incr for (w = 1; w < MAXWIN; w) if (winId.(w)) killWindow(w); ;; (* makeAllWindows - Make all windows *) void makeAllWindows(void) int w; incr for (w = 0; w < MAXWIN; w) if ( not winId.(w)) makeWindow(w); ;; (* checkArgs - Check command line args *) void checkArgs(int argc char *argv[]) int argp; GLboolean quit = GL_FALSE; GLboolean error = GL_FALSE; #define AA argv.(argp) #if 0 #incr define NEXT argp; \ if(argp >= argc) \ { \ Usage(); \ Exit(1); \ #endif argp = 1; while (argp < argc) { if (match(AA "-help")) then commandLineHelp(); quit = GL_TRUE; } else if (match(AA "-version")) then printf(VERSIONLONG "\n"); quit = GL_TRUE; } else if (match(AA "-auto")) then demoMode = GL_TRUE; } else if (match(AA "-scale")) then incr argp; scaleFactor = atof(argv.(argp)); } else { fprintf(stderr "Unknown arg: %s\n" AA); error = GL_TRUE; quit = GL_TRUE; incr argp; if (error) then commandLineHelp(); exit(1); if (quit) exit(0); ;; (* commandLineHelp - Command line help *) void commandLineHelp(void) printf("Usage:\n"); printf(" -h.(elp) this stuff\n"); printf(" -v.(ersion) show version\n"); printf(" -a.(uto) start in auto demo mode\n"); printf(" -s.(cale) f scale windows by f\n"); printf("Standard GLUT args:\n"); printf(" -iconic start iconic\n"); printf(" -display DISP use display DISP\n"); printf(" -direct use direct rendering (default)\n"); printf(" -indirect use indirect rendering\n"); printf(" -sync use synchronous X protocol\n"); printf(" -gldebug check OpenGL errors\n"); printf(" -geometry WxH+X+Y standard X window spec (overridden here) \n"); ;; (* match - Match a string (any unique substring). *) GLboolean match(char *arg char *t) if (strstr(t arg)) return GL_TRUE; else return GL_FALSE; ;; (* scaleWindows - Scale initial window sizes ansd positions *) void scaleWindows(float scale) int i; incr for (i = 0; i < MAXWIN; i) { pos.(i).(0) = pos.(i).(0) * scale; pos.(i).(1) = pos.(i).(1) * scale; size.(i).(0) = size.(i).(0) * scale; size.(i).(1) = size.(i).(1) * scale; ;; (* trackBall - A simple trackball (not with proper rotations). *) (** A simple trackball with spin = left button pan = middle button zoom = left + middle Doesn't have proper trackball rotation ie axes which remain fixed in the scene. We should use the trackball code from 4Dgifts. *) #define STARTROTATE(x y) \ { \ startMX = x; \ startMY = y; \ ;; #define STOPROTATE(x y) \ { \ steadyXangle = varXangle; \ steadyYangle = varYangle; \ ;; #define STARTPAN(x y) \ { \ startMX = x; \ startMY = y; \ ;; #define STOPPAN(x y) \ { \ steadyX = varX; \ steadyY = varY; \ ;; #define STARTZOOM(x y) \ { \ startMX = x; \ startMY = y; \ ;; #define STOPZOOM(x y) \ { \ steadyZ = varZ; \ ;; static float fixAngle(float angle) return angle - floor(angle / 360.0) * 360.0; ;; void trackBall(int mode int button int state int x int y) static int startMX = 0 startMY = 0; (* initial mouse pos *) static int deltaMX = 0 deltaMY = 0; (* initial mouse pos *) static float steadyXangle = 0.0 steadyYangle = 0.0; static float varXangle = 0.0 varYangle = 0.0; static float steadyX = 0.0 steadyY = 0.0 steadyZ = 0.0; static float varX = 0.0 varY = 0.0 varZ = 0.0; match mode with | RESET -> steadyXangle = steadyYangle = steadyX = steadyY = steadyZ = 0.0; break; | MOUSEBUTTON -> if (button = Glut.LEFT_BUTTON && state = Glut.DOWN && not middleDown) then STARTROTATE(x y); leftDown = GL_TRUE; } else if (button = Glut.LEFT_BUTTON && state = Glut.DOWN && middleDown) { STOPPAN(x y); STARTZOOM(x y); leftDown = GL_TRUE; } else if (button = Glut.MIDDLE_BUTTON && state = Glut.DOWN && not leftDown) { STARTPAN(x y); middleDown = GL_TRUE; } else if (button = Glut.MIDDLE_BUTTON && state = Glut.DOWN && leftDown) { STOPROTATE(x y); STARTZOOM(x y); middleDown = GL_TRUE; } else if (state = Glut.UP && button = Glut.LEFT_BUTTON && not middleDown) then STOPROTATE(x y); leftDown = GL_FALSE; } else if (state = Glut.UP && button = Glut.LEFT_BUTTON && middleDown) then STOPZOOM(x y); STARTROTATE(x y); leftDown = GL_FALSE; } else if (state = Glut.UP && button = Glut.MIDDLE_BUTTON && not leftDown) then STOPPAN(x y); middleDown = GL_FALSE; } else if (state = Glut.UP && button = Glut.MIDDLE_BUTTON && leftDown) then STOPZOOM(x y); STARTROTATE(x y); middleDown = GL_FALSE; break; | APPLY -> if (leftDown && not middleDown) then glTranslatef(steadyX steadyY steadyZ); glRotatef(varXangle 0 1 0); glRotatef(varYangle 1 0 0); (* Middle button pan *) else if (middleDown && not leftDown) then glTranslatef(varX varY steadyZ); glRotatef(steadyXangle 0 1 0); glRotatef(steadyYangle 1 0 0); (* Left + middle zoom. *) else if (leftDown && middleDown) then glTranslatef(steadyX steadyY varZ); glRotatef(steadyXangle 0 1 0); glRotatef(steadyYangle 1 0 0); (* Nothing down. *) else { glTranslatef(steadyX steadyY steadyZ); glRotatef(steadyXangle 0 1 0); glRotatef(steadyYangle 1 0 0); break; | MOUSEMOTION -> deltaMX = x - startMX; deltaMY = startMY - y; if (leftDown && not middleDown) then varXangle = fixAngle(steadyXangle + deltaMX); varYangle = fixAngle(steadyYangle + deltaMY); } else if (middleDown && not leftDown) then varX = steadyX + deltaMX / 100.0; varY = steadyY + deltaMY / 100.0; } else if (leftDown && middleDown) then varZ = steadyZ - deltaMY / 50.0; break; ;; (* Callbacks for exotic input devices. These have not been tested yet owing to the usual complete absence of such devices in the UK support group. *) (* spaceballMotionCB *) void spaceballMotionCB(int x int y int z) printf("spaceballMotionCB: translations are X %d Y %d Z %d\n" x y z); ;; (* spaceballRotateCB *) void spaceballRotateCB(int x int y int z) printf("spaceballRotateCB: rotations are X %d Y %d Z %d\n" x y z); ;; (* spaceballButtonCB *) void spaceballButtonCB(int button int state) printf("spaceballButtonCB: button %d state %d\n" button state); ;; (* buttonBoxCB *) void buttonBoxCB(int button int state) printf("buttonBoxCB: button %d state %d\n" button state); ;; (* dialsCB *) void dialsCB(int dial int value) printf("dialsCB: dial %d value %d\n" dial value); ;; (* tabletMotionCB *) void tabletMotionCB(int x int y) printf("tabletMotionCB: X %d Y %d\n" x y); ;; (* tabletButtonCB *) (* ARGSUSED2 *) void tabletButtonCB(int button int state int dummy1 int dummy2) printf("tabletButtonCB: button %d state %d\n" button state); let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/over_test.c000066400000000000000000000176161437514534100256420ustar00rootroot00000000000000 /* 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 int on = 0; int independent = 0; int main_w, hidden_w, s1, s2; float x = 0, y = 0; void overlay_display(void) { printf("overlay_display: damaged=%d\n", glutLayerGet(GLUT_OVERLAY_DAMAGED)); if (on) { glutUseLayer(GLUT_OVERLAY); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(.2 + x, .2 + y); glVertex2f(.5 + x, .5 + y); glVertex2f(.2 + x, .5 + y); glEnd(); glFlush(); } } void display(void) { printf("normal_display: damaged=%d\n", glutLayerGet(GLUT_NORMAL_DAMAGED)); glutUseLayer(GLUT_NORMAL); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex2f(.2, .28); glVertex2f(.5, .58); glVertex2f(.2, .58); glEnd(); if (!independent) { overlay_display(); } else { printf("not calling overlay_display\n"); } } void hidden_display(void) { printf("hidden_display: this should not be called ever\n"); } void reshape(int w, int h) { glutUseLayer(GLUT_NORMAL); glViewport(0, 0, w, h); if (on) { glutUseLayer(GLUT_OVERLAY); glViewport(0, 0, w, h); printf("w=%d, h=%d\n", w, h); } } void special(int c, int w, int h) { printf("special %d w=%d h=%d\n", c, w, h); if (on) { switch (c) { case GLUT_KEY_LEFT: x -= 0.1; break; case GLUT_KEY_RIGHT: x += 0.1; break; case GLUT_KEY_UP: y += 0.1; break; case GLUT_KEY_DOWN: y -= 0.1; break; } glutPostOverlayRedisplay(); } } void key(unsigned char c, int w, int h) { int transP; printf("c=%d w=%d h=%d\n", c, w, h); switch (c) { case 'e': glutEstablishOverlay(); independent = 0; transP = glutLayerGet(GLUT_TRANSPARENT_INDEX); glClearIndex(transP); glutSetColor((transP + 1) % 2, 1.0, 1.0, 0.0); glIndexi((transP + 1) % 2); on = 1; break; case 'r': glutRemoveOverlay(); on = 0; break; case 'm': if (glutLayerGet(GLUT_HAS_OVERLAY)) { int pixel; GLfloat red, green, blue; transP = glutLayerGet(GLUT_TRANSPARENT_INDEX); pixel = (transP + 1) % 2; red = glutGetColor(pixel, GLUT_RED) + 0.2; if (red > 1.0) red = red - 1.0; green = glutGetColor(pixel, GLUT_GREEN) - 0.1; if (green > 1.0) green = green - 1.0; blue = glutGetColor(pixel, GLUT_BLUE) + 0.1; if (blue > 1.0) blue = blue - 1.0; glutSetColor(pixel, red, green, blue); } break; case 'h': glutSetWindow(hidden_w); glutHideWindow(); glutSetWindow(s2); glutHideWindow(); break; case 's': glutSetWindow(hidden_w); glutShowWindow(); glutSetWindow(s2); glutShowWindow(); break; case 'H': glutHideOverlay(); break; case 'S': glutShowOverlay(); break; case 'D': glutDestroyWindow(main_w); exit(0); break; case ' ': printf("overlay possible: %d\n", glutLayerGet(GLUT_OVERLAY_POSSIBLE)); printf("layer in use: %d\n", glutLayerGet(GLUT_LAYER_IN_USE)); printf("has overlay: %d\n", glutLayerGet(GLUT_HAS_OVERLAY)); printf("transparent index: %d\n", glutLayerGet(GLUT_TRANSPARENT_INDEX)); break; } } /* ARGSUSED1 */ void key2(unsigned char c, int w, int h) { int transP; printf("c=%d\n", c); switch (c) { case 'g': glutReshapeWindow( glutGet(GLUT_WINDOW_WIDTH) + 2, glutGet(GLUT_WINDOW_HEIGHT) + 2); break; case 's': glutReshapeWindow( glutGet(GLUT_WINDOW_WIDTH) - 2, glutGet(GLUT_WINDOW_HEIGHT) - 2); break; case 'u': glutPopWindow(); break; case 'd': glutPushWindow(); break; case 'e': glutEstablishOverlay(); transP = glutLayerGet(GLUT_TRANSPARENT_INDEX); glClearIndex(transP); glutSetColor((transP + 1) % 2, 0.0, 0.25, 0.0); glIndexi((transP + 1) % 2); break; case 'c': if (glutLayerGet(GLUT_HAS_OVERLAY)) { glutUseLayer(GLUT_OVERLAY); glutCopyColormap(main_w); } break; case 'r': glutRemoveOverlay(); break; case ' ': printf("overlay possible: %d\n", glutLayerGet(GLUT_OVERLAY_POSSIBLE)); printf("layer in use: %d\n", glutLayerGet(GLUT_LAYER_IN_USE)); printf("has overlay: %d\n", glutLayerGet(GLUT_HAS_OVERLAY)); printf("transparent index: %d\n", glutLayerGet(GLUT_TRANSPARENT_INDEX)); break; } } void vis(int state) { if (state == GLUT_VISIBLE) printf("visible %d\n", glutGetWindow()); else printf("NOT visible %d\n", glutGetWindow()); } void entry(int state) { if (state == GLUT_LEFT) printf("LEFT %d\n", glutGetWindow()); else printf("entered %d\n", glutGetWindow()); } void motion(int x, int y) { printf("motion x=%x y=%d\n", x, y); } void mouse(int b, int s, int x, int y) { printf("b=%d s=%d x=%d y=%d\n", b, s, x, y); } void display2(void) { glutUseLayer(GLUT_NORMAL); glClear(GL_COLOR_BUFFER_BIT); glFlush(); if (glutLayerGet(GLUT_HAS_OVERLAY)) { glutUseLayer(GLUT_OVERLAY); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(.2, .28); glVertex2f(.5, .58); glVertex2f(.2, .58); glEnd(); glFlush(); } } void dial(int dial, int value) { printf("dial %d %d (%d)\n", dial, value, glutGetWindow()); } void box(int button, int state) { printf("box %d %d (%d)\n", button, state, glutGetWindow()); } void main_menu(int option) { switch (option) { case 1: if (glutLayerGet(GLUT_HAS_OVERLAY)) { independent = 1; glutOverlayDisplayFunc(overlay_display); } break; case 2: if (glutLayerGet(GLUT_HAS_OVERLAY)) { independent = 0; glutOverlayDisplayFunc(NULL); } break; case 666: exit(0); break; } } void s2_menu(int option) { int transP; switch (option) { case 1: glutRemoveOverlay(); break; case 2: glutEstablishOverlay(); transP = glutLayerGet(GLUT_TRANSPARENT_INDEX); glClearIndex(transP); glutSetColor((transP + 1) % 2, 0.0, 0.25, 0.0); glIndexi((transP + 1) % 2); break; case 666: exit(0); break; } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(210, 210); main_w = glutCreateWindow("overlay test"); glutDisplayFunc(display); glutReshapeFunc(reshape); glClearColor(1.0, 0.0, 1.0, 1.0); glutKeyboardFunc(key); glutVisibilityFunc(vis); glutEntryFunc(entry); glutSpecialFunc(special); glutMotionFunc(motion); glutMouseFunc(mouse); glutCreateMenu(main_menu); glutAddMenuEntry("Dual display callbacks", 1); glutAddMenuEntry("Single display callbacks", 2); glutAddMenuEntry("Quit", 666); glutAttachMenu(GLUT_RIGHT_BUTTON); hidden_w = glutCreateSubWindow(main_w, 10, 10, 100, 90); /* hidden_w is completely obscured by its own s1 subwindow. While display, entry and visibility callbacks are registered, they will never be called. */ glutDisplayFunc(hidden_display); glutEntryFunc(entry); glutVisibilityFunc(vis); s1 = glutCreateSubWindow(hidden_w, 0, 0, 100, 90); glClearColor(0.0, 0.0, 1.0, 1.0); glutDisplayFunc(display2); #if 0 glutKeyboardFunc(key2); #endif glutVisibilityFunc(vis); glutEntryFunc(entry); s2 = glutCreateSubWindow(main_w, 35, 35, 100, 90); glClearColor(0.5, 0.0, 0.5, 1.0); glutDisplayFunc(display2); #if 1 glutKeyboardFunc(key2); #endif glutVisibilityFunc(vis); glutEntryFunc(entry); #if 1 glutCreateMenu(s2_menu); glutAddMenuEntry("Remove overlay", 1); glutAddMenuEntry("Establish overlay", 2); glutAddMenuEntry("Quit", 666); glutAttachMenu(GLUT_RIGHT_BUTTON); #endif glutInitDisplayMode(GLUT_INDEX); #if 1 glutSetWindow(main_w); glutDialsFunc(dial); glutButtonBoxFunc(box); #endif glutMainLoop(); return 0; /* ANSI C requires main to return int. */ } lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/over_test.ml000077500000000000000000000202151437514534100260200ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Sun Aug 11 14:56:22 MDT 2002. *) open Printf (* 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 int on = 0; int independent = 0; int main_w hidden_w s1 s2; float x = 0 y = 0; void overlay_display(void) printf("overlay_display: damaged=%d\n" Glut.layerGet(Glut.OVERLAY_DAMAGED)); if (on) then Glut.useLayer(Glut.OVERLAY); GlClear.clear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(.2 + x .2 + y); glVertex2f(.5 + x .5 + y); glVertex2f(.2 + x .5 + y); glEnd(); Gl.flush(); ;; void display(void) printf("normal_display: damaged=%d\n" Glut.layerGet(Glut.NORMAL_DAMAGED)); Glut.useLayer(Glut.NORMAL); GlClear.clear(GL_COLOR_BUFFER_BIT); glColor3f(1.0 0.0 0.0); glBegin(GL_POLYGON); glVertex2f(.2 .28); glVertex2f(.5 .58); glVertex2f(.2 .58); glEnd(); if ( not independent) then overlay_display(); } else { printf("not calling overlay_display\n"); ;; void hidden_display(void) printf("hidden_display: this should not be called ever\n"); ;; void reshape(int w int h) Glut.useLayer(Glut.NORMAL); glViewport(0 0 w h); if (on) then Glut.useLayer(Glut.OVERLAY); glViewport(0 0 w h); printf("w=%d h=%d\n" w h); ;; void special(int c int w int h) printf("special %d w=%d h=%d\n" c w h); if (on) then match c with | Glut.KEY_LEFT -> x -= 0.1; break; | Glut.KEY_RIGHT -> x += 0.1; break; | Glut.KEY_UP -> y += 0.1; break; | Glut.KEY_DOWN -> y -= 0.1; break; Glut.postOverlayRedisplay(); ;; void key(unsigned char c int w int h) int transP; printf("c=%d w=%d h=%d\n" c w h); match c with | 'e' -> Glut.establishOverlay(); independent = 0; transP = Glut.layerGet(Glut.TRANSPARENT_INDEX); GlClear.clearIndex(transP); Glut.setColor((transP + 1) % 2 1.0 1.0 0.0); glIndexi((transP + 1) % 2); on = 1; break; | 'r' -> Glut.removeOverlay(); on = 0; break; | 'm' -> if (Glut.layerGet(Glut.HAS_OVERLAY)) then int pixel; GLfloat red green blue; transP = Glut.layerGet(Glut.TRANSPARENT_INDEX); pixel = (transP + 1) % 2; red = Glut.getColor(pixel Glut.RED) + 0.2; if (red > 1.0) red = red - 1.0; green = Glut.getColor(pixel Glut.GREEN) - 0.1; if (green > 1.0) green = green - 1.0; blue = Glut.getColor(pixel Glut.BLUE) + 0.1; if (blue > 1.0) blue = blue - 1.0; Glut.setColor(pixel red green blue); break; | 'h' -> Glut.setWindow(hidden_w); Glut.hideWindow(); Glut.setWindow(s2); Glut.hideWindow(); break; | 's' -> Glut.setWindow(hidden_w); Glut.showWindow(); Glut.setWindow(s2); Glut.showWindow(); break; | 'H' -> Glut.hideOverlay(); break; | 'S' -> Glut.showOverlay(); break; | 'D' -> Glut.destroyWindow(main_w); exit(0); break; | ' ' -> printf("overlay possible: %d\n" Glut.layerGet(Glut.OVERLAY_POSSIBLE)); printf("layer in use: %d\n" Glut.layerGet(Glut.LAYER_IN_USE)); printf("has overlay: %d\n" Glut.layerGet(Glut.HAS_OVERLAY)); printf("transparent index: %d\n" Glut.layerGet(Glut.TRANSPARENT_INDEX)); break; ;; (* ARGSUSED1 *) void key2(unsigned char c int w int h) int transP; printf("c=%d\n" c); match c with | 'g' -> Glut.reshapeWindow( Glut.get(Glut.WINDOW_WIDTH) + 2 Glut.get(Glut.WINDOW_HEIGHT) + 2); break; | 's' -> Glut.reshapeWindow( Glut.get(Glut.WINDOW_WIDTH) - 2 Glut.get(Glut.WINDOW_HEIGHT) - 2); break; | 'u' -> Glut.popWindow(); break; | 'd' -> Glut.pushWindow(); break; | 'e' -> Glut.establishOverlay(); transP = Glut.layerGet(Glut.TRANSPARENT_INDEX); GlClear.clearIndex(transP); Glut.setColor((transP + 1) % 2 0.0 0.25 0.0); glIndexi((transP + 1) % 2); break; | 'c' -> if (Glut.layerGet(Glut.HAS_OVERLAY)) then Glut.useLayer(Glut.OVERLAY); Glut.copyColormap(main_w); break; | 'r' -> Glut.removeOverlay(); break; | ' ' -> printf("overlay possible: %d\n" Glut.layerGet(Glut.OVERLAY_POSSIBLE)); printf("layer in use: %d\n" Glut.layerGet(Glut.LAYER_IN_USE)); printf("has overlay: %d\n" Glut.layerGet(Glut.HAS_OVERLAY)); printf("transparent index: %d\n" Glut.layerGet(Glut.TRANSPARENT_INDEX)); break; ;; void vis(int state) if (state = Glut.VISIBLE) printf("visible %d\n" Glut.getWindow()); else printf("NOT visible %d\n" Glut.getWindow()); ;; void entry(int state) if (state = Glut.LEFT) printf("LEFT %d\n" Glut.getWindow()); else printf("entered %d\n" Glut.getWindow()); ;; void motion(int x int y) printf("motion x=%x y=%d\n" x y); ;; void mouse(int b int s int x int y) printf("b=%d s=%d x=%d y=%d\n" b s x y); ;; void display2(void) Glut.useLayer(Glut.NORMAL); GlClear.clear(GL_COLOR_BUFFER_BIT); Gl.flush(); if (Glut.layerGet(Glut.HAS_OVERLAY)) then Glut.useLayer(Glut.OVERLAY); GlClear.clear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(.2 .28); glVertex2f(.5 .58); glVertex2f(.2 .58); glEnd(); Gl.flush(); ;; void dial(int dial int value) printf("dial %d %d (%d)\n" dial value Glut.getWindow()); ;; void box(int button int state) printf("box %d %d (%d)\n" button state Glut.getWindow()); ;; void main_menu(int option) match option with | 1 -> if (Glut.layerGet(Glut.HAS_OVERLAY)) then independent = 1; Glut.overlayDisplayFunc(overlay_display); break; | 2 -> if (Glut.layerGet(Glut.HAS_OVERLAY)) then independent = 0; Glut.overlayDisplayFunc(NULL); break; | 666 -> exit(0); break; ;; void s2_menu(int option) int transP; match option with | 1 -> Glut.removeOverlay(); break; | 2 -> Glut.establishOverlay(); transP = Glut.layerGet(Glut.TRANSPARENT_INDEX); GlClear.clearIndex(transP); Glut.setColor((transP + 1) % 2 0.0 0.25 0.0); glIndexi((transP + 1) % 2); break; | 666 -> exit(0); break; ;; int main(int argc char **argv) Glut.init( land argc argv); Glut.initDisplayMode(Glut.RGB); Glut.initWindowSize(210 210); main_w = Glut.createWindow("overlay test"); Glut.displayFunc(display); Glut.reshapeFunc(reshape); GlClear.clearColor(1.0 0.0 1.0 1.0); Glut.keyboardFunc(key); Glut.visibilityFunc(vis); Glut.entryFunc(entry); Glut.specialFunc(special); Glut.motionFunc(motion); Glut.mouseFunc(mouse); Glut.createMenu(main_menu); Glut.addMenuEntry("Dual display callbacks" 1); Glut.addMenuEntry("Single display callbacks" 2); Glut.addMenuEntry("Quit" 666); Glut.attachMenu(Glut.RIGHT_BUTTON); hidden_w = Glut.createSubWindow(main_w 10 10 100 90); (* hidden_w is completely obscured by its own s1 subwindow. While display entry and visibility callbacks are registered they will never be called. *) Glut.displayFunc(hidden_display); Glut.entryFunc(entry); Glut.visibilityFunc(vis); s1 = Glut.createSubWindow(hidden_w 0 0 100 90); GlClear.clearColor(0.0 0.0 1.0 1.0); Glut.displayFunc(display2); #if 0 Glut.keyboardFunc(key2); #endif Glut.visibilityFunc(vis); Glut.entryFunc(entry); s2 = Glut.createSubWindow(main_w 35 35 100 90); GlClear.clearColor(0.5 0.0 0.5 1.0); Glut.displayFunc(display2); #if 1 Glut.keyboardFunc(key2); #endif Glut.visibilityFunc(vis); Glut.entryFunc(entry); #if 1 Glut.createMenu(s2_menu); Glut.addMenuEntry("Remove overlay" 1); Glut.addMenuEntry("Establish overlay" 2); Glut.addMenuEntry("Quit" 666); Glut.attachMenu(Glut.RIGHT_BUTTON); #endif Glut.initDisplayMode(Glut.INDEX); #if 1 Glut.setWindow(main_w); Glut.dialsFunc(dial); Glut.buttonBoxFunc(box); #endif Glut.mainLoop(); return 0; (* ANSI C requires main to return int. *) let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/not_yet_ported/test6.ml000077500000000000000000000267251437514534100250670ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 9 2002. *) open Printf (* 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. *) (* This is an interactive test (not automatically run by "make test") that requires user interaction to verify that input callbacks operate as expected. *) let mouseButtons = ref(-1);; let display () = GlClear.clear [`color]; Gl.flush(); ;; let time7 ~value = if (value <> 7) then failwith(" time7 expected 6\n"); printf("PASS : test6\n"); exit(0); ;; let int_of_menu_state s = match s with Glut.MENU_NOT_IN_USE -> 0 | Glut.MENU_IN_USE -> 1;; let mstatus ~status = printf "state : %d\n" (int_of_menu_state status);; let mstatus2 ~status ~x ~y = printf "state : %d x=%d y=%d\n" (int_of_menu_state status) x y ;; let menu2 ~value = printf "menu item selected : %d\n" value ; if (value <> 46) then failwith(" time6 expected 45\n"); Glut.destroyMenu(Glut.getMenu()); Glut.destroyWindow(Glut.getWindow()); Glut.timerFunc 1000 time7 7 ; ;; let time6 ~value = if (value <> 6) then failwith(" time6 expected 6\n"); Glut.menuStateFunc(mstatus); Glut.menuStatusFunc(mstatus2); ignore(Glut.createMenu(menu2)); Glut.addMenuEntry "name" 46 ; Glut.attachMenu(Glut.LEFT_BUTTON); Glut.attachMenu(Glut.MIDDLE_BUTTON); Glut.attachMenu(Glut.RIGHT_BUTTON); printf("Pop up menu with any mouse button and select the item\n"); ;; let estate = ref 0;; let entry ~state = printf "entry : %s\n" (if state = Glut.LEFT then "left" else "entered"); match !estate with | 0 -> if (state = Glut.LEFT) then incr estate | 1 -> begin if (state = Glut.ENTERED) then incr estate; Glut.timerFunc 1000 time6 6; Glut.entryFunc (fun ~state->()); end | _ -> failwith "unrecignized state in entry()" ;; let time5 ~value = if (value <> 5) then failwith(" time5 expected 5\n"); Glut.entryFunc(entry); printf "In the black window leave it then enter it\n" ; ;; let motion ~x ~y = printf "motion x=%d y=%d\n" x y ; Glut.motionFunc (fun ~x ~y -> ()); Glut.timerFunc 1000 time5 5 ; ;; let time4 ~value = if (value <> 4) then failwith(" time4 expected 4\n"); Glut.motionFunc(motion); printf "In the black window move mouse with some button held down\n" ; ;; let passive ~x ~y = printf "passive x=%d y=%d\n" x y ; Glut.timerFunc 1000 time4 4 ; Glut.passiveMotionFunc (fun ~x ~y->()) ; ;; let time3 ~value = if (value <> 3) then failwith(" time3 expected 3\n"); Glut.passiveMotionFunc(passive); printf("In the black window mouse the mouse around with NO buttons down\n"); ;; let mode = ref 0;; let mouse ~button ~state ~x ~y = printf "but=%s state=%s x=%d y=%d modifiers=%i\n" (Glut.string_of_button button) (Glut.string_of_button_state state) x y (Glut.getModifiers()) ; match !mode with | 0 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.DOWN) then failwith(" mouse left down not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); incr mode; end | 1 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.UP) then failwith(" mouse left up not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); match !mouseButtons with | 1 -> begin mode := 6; (* Skip right or middle button tests. *) printf("In the black window please click : Shift-left Ctrl-left then Alt-left (in that order)\n"); end | 2 -> mode := 4; (* Continue with right button test (skip middle button). *) | 3 -> mode := 2; (* Continue with middle button test. *) | _ -> failwith (sprintf "invalid value for mouseButtons: %i" !mouseButtons) end | 2 -> begin if (button <> Glut.MIDDLE_BUTTON && state = Glut.DOWN) then failwith(" mouse center down not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); incr mode; end | 3 -> begin if (button <> Glut.MIDDLE_BUTTON && state = Glut.UP) then failwith(" mouse center up not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); incr mode; end | 4 -> begin if (button <> Glut.RIGHT_BUTTON && state = Glut.DOWN) then failwith(" mouse right down not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); incr mode; end | 5 -> begin if (button <> Glut.RIGHT_BUTTON && state = Glut.UP) then failwith(" mouse right up not found\n"); if (Glut.getModifiers() <> 0) then failwith(" mouse expected no modifier\n"); printf("In the black window please click : Shift-left Ctrl-left then Alt-left (in that order)\n"); incr mode; end | 6 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.DOWN) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_shift <> 1 then failwith(" mouse expected shift modifier\n"); incr mode; end | 7 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.UP) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_shift <> 1 then failwith(" mouse expected shift modifier\n"); incr mode; end | 8 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.DOWN) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_ctrl <> 1 then failwith(" mouse expected ctrl modifier\n"); incr mode; end | 9 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.UP) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_ctrl = 0 then failwith(" mouse expected ctrl modifier\n"); incr mode; end | 10 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.DOWN) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_alt = 0 then failwith(" mouse expected alt modifier\n"); incr mode; end | 11 -> begin if (button <> Glut.LEFT_BUTTON && state = Glut.UP) then failwith(" mouse right down not found\n"); if Glut.getModifiers() land Glut.active_alt = 0 then failwith(" mouse expected alt modifier\n"); Glut.timerFunc 1000 time3 3 ; Glut.mouseFunc (fun ~button ~state ~x ~y -> ()); incr mode; end | _ -> failwith(sprintf " mouse called with bad mode : %d\n" !mode); ;; let menu ~value = failwith(" menu callback should never be called\n") ;; let time2 ~value = if (value <> 2) then failwith(" time2 expected 2\n"); Glut.mouseFunc(mouse); (* By attaching and detaching a menu to each button make sure button usage for menus does not mess up normal button callback. *) ignore(Glut.createMenu(menu)); Glut.attachMenu(Glut.RIGHT_BUTTON); Glut.attachMenu(Glut.MIDDLE_BUTTON); Glut.attachMenu(Glut.LEFT_BUTTON); Glut.detachMenu(Glut.RIGHT_BUTTON); Glut.detachMenu(Glut.MIDDLE_BUTTON); Glut.detachMenu(Glut.LEFT_BUTTON); Glut.destroyMenu(Glut.getMenu()); match !mouseButtons with | 3 -> printf("In the black window please click : left then middle then right buttons (in that order)\n"); | 2 -> printf("In the black window please click : left then right buttons (in that order)\n"); | 1 -> printf("In the black window please click : left button\n"); | 0 -> (* No mouse buttons?? Skip all subsequent tests since they involve the mouse. *) Glut.timerFunc 1000 time7 7; Glut.mouseFunc (fun ~button ~state ~x ~y -> ()); | _ -> failwith(sprintf "invalid number for mouseButtons: %i" !mouseButtons) ;; let smode = ref 0;; (* XXX Warning sometimes an X window manager will intercept some keystroke like Alt-F2. Be careful about window manager interference when running test6. *) let special ~key ~x ~y = printf "key=%s x=%d y=%d modifiers=%i" (Glut.string_of_special key) x y (Glut.getModifiers()); print_newline(); let _ = match !smode with | 0 -> begin if (key <> Glut.KEY_F2) then failwith(" special expected F2\n"); if (Glut.getModifiers() <> 0) then failwith(" special expected no modifier\n"); end | 1 -> begin if (key <> Glut.KEY_F2) then failwith(" special expected F2\n"); if Glut.getModifiers() land Glut.active_shift = 0 then failwith(" special expected shift modifier\n"); end | 2 -> begin if (key <> Glut.KEY_F2) then failwith(" special expected F2\n"); if Glut.getModifiers() land Glut.active_ctrl = 0 then failwith(" special expected ctrl modifier\n"); end | 3 -> begin if (key <> Glut.KEY_F2) then failwith(" special expected F2\n"); if Glut.getModifiers() land Glut.active_alt = 0 then failwith(" special expected alt modifier\n"); Glut.specialFunc (fun ~key ~x ~y -> ()); Glut.timerFunc 1000 time2 2; end | _ -> failwith(sprintf "special called with bad mode : %d\n" !smode) in incr smode; ;; let time1 ~value = printf("PLEASE EXPECT TO SEE A WARNING ON THE NEXT LINE : "); print_newline(); ignore(Glut.getModifiers()); printf("DID YOU SEE A WARNING? IT IS AN ERROR NOT TO SEE ONE."); print_newline(); if (value <> 1) then failwith(" time1 expected 1"); Glut.specialFunc(special); printf("In the black window please press : F2 Shift-F2 Ctrl-F2 then Alt-F2"); print_newline(); ;; let kmode = ref 0;; let keyboard ~key ~x ~y = let c = key in printf "char=%d x=%d y=%d modifiers=%i" c x y (Glut.getModifiers()); print_newline(); let _ = match !kmode with | 0 -> begin if c <> int_of_char 'g' then failwith(" keyboard expected g\n"); if Glut.getModifiers() <> 0 then failwith(" keyboard expected no modifier\n"); end; | 1 -> begin if (c <> int_of_char 'G') then failwith(" keyboard expected G\n"); if Glut.getModifiers() land Glut.active_shift = 0 then failwith(" keyboard expected shift modifier\n"); end | 2 -> begin if (c <> 0x7) then (* Bell Ctrl-g *) failwith(" keyboard expected g\n"); if Glut.getModifiers() land Glut.active_ctrl = 0 then failwith(" keyboard expected ctrl modifier\n"); end | 3 -> begin if (c <> int_of_char 'g') then failwith(" keyboard expected g\n"); if Glut.getModifiers() land Glut.active_alt = 0 then failwith(" keyboard expected alt modifier\n"); Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.timerFunc 1000 time1 1 ; end | _ -> failwith(sprintf "keyboard called with bad mode : %d\n" !kmode) in incr kmode; ;; let time0 ~value = if (value <> 0) then failwith(" time0 expected 0\n"); Glut.keyboardFunc(keyboard); printf("In the black window please press : g G Ctrl-g then Alt-g"); print_newline(); ;; let main() = ignore(Glut.init Sys.argv); mouseButtons := Glut.deviceGet(Glut.NUM_MOUSE_BUTTONS); if (!mouseButtons < 0) then failwith(sprintf "negative mouse buttons? mouseButtons=%d\n" !mouseButtons); if !mouseButtons > 3 then begin printf "More than 3 mouse buttons (ok). mouseButtons=%d\n" !mouseButtons; mouseButtons := 3; (* Testing only of 3 mouse buttons. *) end; mouseButtons := 0; ignore(Glut.createWindow("test")); Glut.displayFunc(display); Glut.timerFunc 1000 time0 0 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/shape_test.ml000077500000000000000000000107521437514534100231140ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 13:41:10 MDT 2002. *) open Printf let w = ref 0 and h = ref 0 let light_diffuse = (1.0, 1.0, 1.0, 1.0) let light_position = (1.0, 1.0, 1.0, 1.0) let qobj = ref None (* reshape has to have arguments labled w and h, but this masks the w and h in the global scope. I don't know if OCaml let's to do something like C++'s ::myvar trick for getting around this. *) let workaround w' h' = w:=w'; h:=h'; ;; let reshape ~w ~h = workaround w h;; let render shape = match shape with | 1 -> begin GlMat.push() ; GlMat.scale3 (1.2, 1.2, 1.2); Glut.wireSphere ~radius:1.0 ~slices:20 ~stacks:20; GlMat.pop() ; end | 10 -> begin GlMat.push() ; GlMat.scale3 (1.2, 1.2, 1.2); Gl.enable `lighting; Glut.solidSphere 1.0 20 20; Gl.disable `lighting; GlMat.pop() ; end | 2 -> begin GlMat.push() ; GlMat.rotate ~angle:(-90.0) ~x:1.0 (); Glut.wireCone ~base:1.0 ~height:1.3 ~slices:20 ~stacks:20; GlMat.pop() ; end | 11 -> begin GlMat.push() ; GlMat.rotate ~angle:(-90.0) ~x:1.0 (); Gl.enable `lighting; Glut.solidCone 1.0 1.3 20 20; Gl.disable `lighting; GlMat.pop() ; end | 3 -> begin GlMat.push() ; GlMat.rotate ~angle:(-20.0) ~z:1.0 (); GlMat.scale3 (1.8, 1.8, 1.8); Glut.wireCube ~size:1.0; GlMat.pop() ; end | 12 -> begin GlMat.push() ; GlMat.rotate ~angle:(-20.0) ~z:1.0 (); GlMat.scale3 (1.8, 1.8, 1.8); Gl.enable `lighting; Glut.solidCube 1.0; Gl.disable `lighting; GlMat.pop() ; end | 4 -> begin GlMat.push() ; GlMat.scale3 (0.9, 0.9, 0.9); Glut.wireTorus ~innerRadius:0.5 ~outerRadius:1.0 ~sides:15 ~rings:15; GlMat.pop() ; end | 13 -> begin GlMat.push() ; GlMat.scale3 (0.9, 0.9, 0.9); Gl.enable `lighting; Glut.solidTorus ~innerRadius:0.5 ~outerRadius:1.0 ~sides:15 ~rings:15; Gl.disable `lighting; GlMat.pop() ; end | 5 -> begin GlMat.push() ; GlMat.scale3 (0.8, 0.8, 0.8); Glut.wireDodecahedron (); GlMat.pop() ; end | 14 -> begin GlMat.push() ; GlMat.scale3 (0.8, 0.8, 0.8); Gl.enable `lighting; Glut.solidDodecahedron (); Gl.disable `lighting; GlMat.pop() ; end | 6 -> begin GlMat.push() ; GlMat.scale3 (0.9, 0.9, 0.9); Glut.wireTeapot 1.0; GlMat.pop() ; end | 15 -> begin GlMat.push() ; GlMat.scale3 (0.9, 0.9, 0.9); Gl.enable `lighting; Glut.solidTeapot 1.0; Gl.disable `lighting; GlMat.pop() ; end | 7 -> Glut.wireOctahedron (); | 16 -> begin Gl.enable `lighting; Glut.solidOctahedron (); Gl.disable `lighting; end | 8 -> begin GlMat.push() ; GlMat.scale3 (1.2, 1.2, 1.2); Glut.wireTetrahedron (); GlMat.pop() ; end | 17 -> begin GlMat.push() ; GlMat.scale3 (1.2, 1.2, 1.2); Gl.enable `lighting; Glut.solidTetrahedron (); Gl.disable `lighting; GlMat.pop() ; end | 9 -> Glut.wireIcosahedron (); | 18 -> begin Gl.enable `lighting; Glut.solidIcosahedron (); Gl.disable `lighting; end | _ -> failwith "invalid shape index" ;; let display () = GlDraw.viewport ~x:0 ~y:0 ~w:!w ~h:!h; GlClear.clear [`color; `depth]; for j = 0 to 5 do for i = 0 to 2 do GlDraw.viewport (!w / 3 * i) (!h / 6 * j) (!w / 3) (!h / 6); render (18 - (j * 3 + (2 - i))); done; done; Gl.flush (); ;; let main () = Glut.initWindowSize ~w:475 ~h:950; ignore(Glut.init Sys.argv); Glut.initDisplayMode ~depth:true (); ignore(Glut.createWindow "GLUT geometric shapes"); Glut.displayFunc display; Glut.reshapeFunc reshape; GlClear.color (1.0, 1.0, 1.0); GlDraw.color (0.0, 0.0, 0.0); GlLight.light ~num:0 (`diffuse light_diffuse); GlLight.light ~num:0 (`position light_position); Gl.enable `light0; Gl.enable `depth_test; GlMat.mode `projection; GluMat.perspective ~fovy:22.0 ~aspect:1.0 ~z:(1.0, 10.0); GlMat.mode `modelview; GluMat.look_at ~eye:(0.0, 0.0, 5.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0); GlMat.translate3 (0.0, 0.0, -3.0); GlMat.rotate ~angle:25.0 ~x:1.0 (); GlMat.rotate ~angle:5.0 ~y:1.0 (); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test1.ml000077500000000000000000000046521437514534100220170ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* ported to lablglut by Issac Trotts on Aug. 3, 2002 *) open Printf exception Failure of string let main = let fake_argv = [| "program"; "-display"; ":0"; "-geometry"; "500x400-34-23"; "-indirect"; "-iconic" |] in let alt() = try let altdisplay = Sys.getenv("GLUT_TEST_ALT_DISPLAY") in fake_argv.(2) <- altdisplay; with Not_found -> printf "GLUT_TEST_ALT_DISPLAY not set\n"; in alt(); let new_argv = Glut.init fake_argv in if ((Array.length new_argv) != 1) then raise (Failure "argument processing"); let w = Glut.get(Glut.INIT_WINDOW_WIDTH) in if w != 500 then raise (Failure(sprintf "width wrong, got %d, not 500" w)); let h = Glut.get(Glut.INIT_WINDOW_HEIGHT) in if h != 400 then raise (Failure(sprintf "width height, got %d, not 400" h)); let screen_width = Glut.get(Glut.SCREEN_WIDTH) in let screen_height = Glut.get(Glut.SCREEN_HEIGHT) in let x = Glut.get(Glut.INIT_WINDOW_X) in if x != (screen_width - 500 - 34) then raise (Failure (sprintf "width x, got %i, not %i" x (screen_width - 500 - 34))); let y = Glut.get(Glut.INIT_WINDOW_Y) in if y != (screen_height - 400 - 23) then raise (Failure (sprintf "width y, got %d, not %d" y (screen_height - 400 - 23))); (* need to figure out a way to deal with this -ijt *) (* if Glut.get(Glut.INIT_DISPLAY_MODE) != *) (* (Glut.RGBA | Glut.SINGLE | Glut.DEPTH) then *) (* raise (Failure "width wrong 0"); *) Glut.initWindowPosition 10 10; Glut.initWindowSize 200 200; (* Glut.initDisplayMode(Glut.DOUBLE | Glut.RGB | Glut.DEPTH | Glut.STENCIL); *) if (Glut.get(Glut.INIT_WINDOW_WIDTH) != 200) then raise (Failure "width wrong 1"); if (Glut.get(Glut.INIT_WINDOW_HEIGHT) != 200) then raise (Failure "width wrong 2"); if (Glut.get(Glut.INIT_WINDOW_X) != 10) then raise (Failure "width wrong 3"); if (Glut.get(Glut.INIT_WINDOW_Y) != 10) then raise (Failure "width wrong 4"); (* FIXME if (Glut.get(Glut.INIT_DISPLAY_MODE) != (Glut.DOUBLE | Glut.RGB | Glut.DEPTH | Glut.STENCIL)) { printf("FAIL: width wrong"); exit(1); *) printf("PASS: test1\n"); exit 0 ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test10.ml000077500000000000000000000061511437514534100220730ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21 -> 18 -> 29 MDT 2002. *) open Printf (* 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. *) (* XXX As a test of 16-bit font support in capturexfont I made a font out of the 16-bit Japanese font named '-jis-fixed-medium-r-normal--24-230-75-75-c-240-jisx0208.1' and tried it out. Defining JIS_FONT uses it in this test. *) (* #define JIS_FONT *) (* hmmm... how do we emulate this in OCaml? -ijt #ifdef JIS_FONT extern void *Glut.bitmapJis; #endif *) let ch = ref (-2);; let fonts = [| Glut.BITMAP_TIMES_ROMAN_24 ; Glut.BITMAP_TIMES_ROMAN_10 ; Glut.BITMAP_9_BY_15 ; Glut.BITMAP_8_BY_13 ; Glut.BITMAP_HELVETICA_10 ; Glut.BITMAP_HELVETICA_12 ; Glut.BITMAP_HELVETICA_18 (* #ifdef JIS_FONT *) (* &glutBitmapJis *) (* #endif *) |];; let names = [| "Times Roman 24" ; " Times Roman 10" ; " 9 by 15" ; " 8 by 13" ; " Helvetica 10" ; " Helvetica 12" ; " Helvetica 18" (* #ifdef JIS_FONT *) (* " Mincho JIS" *) (* #endif *) |];; let num_fonts = (Array.length fonts);; let font = ref 0;; let limit = ref 270;; let tick () = ch := !ch + 5; if (!ch > !limit) then begin ch := -2; incr font; end; (* #ifdef JIS_FONT if (font = 4) then limit = 0x747e; ch = 0x2121; #endif *) if (!font = num_fonts) then begin printf("PASS -> test10\n"); exit(0); end Glut.postRedisplay(); ;; let output ~x ~y ~msg = GlPix.raster_pos ~x ~y (); for i=0 to ((String.length msg)-1) do Glut.bitmapCharacter Glut.BITMAP_9_BY_15 (int_of_char msg.[i]); done ;; let display () = Glut.idleFunc(Some tick); GlClear.clear [`color]; GlPix.raster_pos ~x:0.0 ~y:0.0 (); Glut.bitmapCharacter fonts.(!font) !ch ; GlPix.raster_pos 30.0 30.0 (); Glut.bitmapCharacter fonts.(!font) (!ch + 1) ; GlPix.raster_pos (-30.0) (-30.0) (); Glut.bitmapCharacter fonts.(!font) (!ch + 2) ; GlPix.raster_pos 30.0 (-30.0) (); Glut.bitmapCharacter fonts.(!font) (!ch + 3) ; GlPix.raster_pos (-30.0) 30.0 (); Glut.bitmapCharacter fonts.(!font) (!ch + 4) ; GlPix.raster_pos 0.0 30.0 (); Glut.bitmapCharacter fonts.(!font) (!ch + 5) ; GlPix.raster_pos 0.0 (-30.0) (); Glut.bitmapCharacter fonts.(!font) (!ch + 6) ; GlPix.raster_pos(-30.0) 0.0 (); Glut.bitmapCharacter fonts.(!font) (!ch + 7) ; GlPix.raster_pos 30.0 0.0 (); Glut.bitmapCharacter fonts.(!font) (!ch + 8) ; output (-48.0) (-48.0) names.(!font); Glut.swapBuffers(); ;; let main() = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~double_buffer:true ~alpha:false (); Glut.initWindowSize 200 200 ; ignore(Glut.createWindow("Test bitmap fonts")); GlMat.mode `projection ; GlMat.load_identity (); GluMat.ortho2d ~x:(-50.0, 50.0) ~y:(-50.0, 50.0); GlClear.color (0.0, 0.0, 0.0); GlDraw.color (1.0, 1.0, 1.0); Glut.displayFunc(display); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test11.ml000077500000000000000000000025071437514534100220750ustar00rootroot00000000000000#!/usr/bin/env lablglut open Printf (* 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. *) (* ported to lablglut by Issac Trotts on August 6, 2002 *) let main () = ignore(Glut.init Sys.argv); printf "Keyboard : %s\n" (if Glut.deviceGet(Glut.HAS_KEYBOARD) <> 0 then "YES" else "no") ; printf "Mouse : %s\n" (if Glut.deviceGet(Glut.HAS_MOUSE) <> 0 then "YES" else "no") ; printf "Spaceball : %s\n" (if Glut.deviceGet(Glut.HAS_SPACEBALL) <> 0 then "YES" else "no") ; printf "Dials : %s\n" (if Glut.deviceGet(Glut.HAS_DIAL_AND_BUTTON_BOX) <> 0 then "YES" else "no") ; printf "Tablet : %s\n\n" (if Glut.deviceGet(Glut.HAS_TABLET) <> 0 then "YES" else "no") ; printf "Mouse buttons : %d\n" (Glut.deviceGet(Glut.NUM_MOUSE_BUTTONS)) ; printf "Spaceball buttons : %d\n" (Glut.deviceGet(Glut.NUM_SPACEBALL_BUTTONS)) ; printf "Button box buttons : %d\n" (Glut.deviceGet(Glut.NUM_BUTTON_BOX_BUTTONS)) ; printf "Dials : %d\n" (Glut.deviceGet(Glut.NUM_DIALS)) ; printf "Tablet buttons : %d\n\n" (Glut.deviceGet(Glut.NUM_TABLET_BUTTONS)) ; printf "PASS : test11\n" ; ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test12.ml000077500000000000000000000067261437514534100221050ustar00rootroot00000000000000#!/usr/bin/env lablglut #load "unix.cma" (* 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. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 13:41:11 MDT 2002. *) open Printf let main () = ignore(Glut.init Sys.argv); let a = Glut.get Glut.ELAPSED_TIME in Unix.sleep 1; let b = Glut.get Glut.ELAPSED_TIME in let d = b - a in if d < 990 || d > 1200 then failwith " test12\n"; ignore(Glut.createWindow "dummy"); (* try all Glut.WINDOW_* Glut.get's *) let value = ref (Glut.get Glut.WINDOW_X) in value := Glut.get(Glut.WINDOW_Y); value := Glut.get(Glut.WINDOW_WIDTH); if (!value <> 300) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_HEIGHT); if (!value <> 300) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_BUFFER_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_STENCIL_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_DEPTH_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_RED_SIZE); if (!value < 1) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_GREEN_SIZE); if (!value < 1) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_BLUE_SIZE); if (!value < 1) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_ALPHA_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_ACCUM_RED_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_ACCUM_GREEN_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_ACCUM_BLUE_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_ACCUM_ALPHA_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_DOUBLEBUFFER); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_RGBA); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_CURSOR); if !value <> (Glut.int_of_cursor Glut.CURSOR_INHERIT) then failwith " test12\n"; printf "Window format id = 0x%x (%d)\n" (Glut.get(Glut.WINDOW_FORMAT_ID)) (Glut.get(Glut.WINDOW_FORMAT_ID)); Glut.setCursor(Glut.CURSOR_NONE); value := Glut.get(Glut.WINDOW_CURSOR); if !value <> (Glut.int_of_cursor Glut.CURSOR_NONE) then failwith " test12\n"; Glut.warpPointer 0 0; Glut.warpPointer(-5) (-5); Glut.warpPointer 2000 2000; Glut.warpPointer(-4000) 4000; value := Glut.get(Glut.WINDOW_COLORMAP_SIZE); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_PARENT); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_NUM_CHILDREN); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_NUM_SAMPLES); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.WINDOW_STEREO); if (!value < 0) then failwith(" test12\n"); (* touch Glut.SCREEN_* Glut.get's supported *) value := Glut.get(Glut.SCREEN_WIDTH); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.SCREEN_HEIGHT); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.SCREEN_WIDTH_MM); if (!value < 0) then failwith(" test12\n"); value := Glut.get(Glut.SCREEN_HEIGHT_MM); if (!value < 0) then failwith(" test12\n"); printf("PASS: test12\n"); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test13.ml000077500000000000000000000045561437514534100221050ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:18:31 MDT 2002. *) #load "unix.cma" open Printf (* 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. *) let window1 = ref (-1);; let window2 = ref (-1);; let win1reshaped = ref false;; let win2reshaped = ref false;; let win1displayed = ref false;; let win2displayed = ref false;; let checkifdone () = if (!win1reshaped && !win2reshaped && !win1displayed && !win2displayed) then begin Unix.sleep(1); printf("PASS -> test13\n"); exit(0); end ;; let window1reshape ~w ~h = if (Glut.getWindow() <> !window1) then failwith(" window1reshape\n"); GlDraw.viewport ~x:0 ~y:0 ~w ~h ; win1reshaped := true ;; let window1display () = if (Glut.getWindow() <> !window1) then failwith(" window1display\n"); GlClear.color (0.0, 1.0, 0.0); GlClear.clear [`color]; Gl.flush(); win1displayed := true; checkifdone(); ;; let window2reshape ~w ~h = if (Glut.getWindow() <> !window2) then failwith(" window2reshape\n"); GlDraw.viewport ~x:0 ~y:0 ~w ~h ; win2reshaped := true; ;; let window2display () = if (Glut.getWindow() <> !window2) then failwith(" window2display\n"); GlClear.color (0.0, 0.0, 1.0); GlClear.clear [`color]; Gl.flush(); win2displayed := true; checkifdone(); ;; let timefunc ~value = failwith(" test13\n") ;; let main () = ignore (Glut.init Sys.argv); Glut.initWindowSize 100 100 ; Glut.initWindowPosition 50 100 ; Glut.initDisplayMode ~double_buffer:false ~alpha:false (); window1 := Glut.createWindow("1"); if (Glut.get(Glut.WINDOW_X) <> 50) then failwith(" test13\n"); if (Glut.get(Glut.WINDOW_Y) <> 100) then failwith(" test13\n"); Glut.reshapeFunc(window1reshape); Glut.displayFunc(window1display); Glut.initWindowSize 100 100 ; Glut.initWindowPosition 250 100 ; Glut.initDisplayMode ~double_buffer:false ~alpha:false (); window2 := Glut.createWindow("2"); if (Glut.get(Glut.WINDOW_X) <> 250) then failwith(" test13\n"); if (Glut.get(Glut.WINDOW_Y) <> 100) then failwith(" test13\n"); Glut.reshapeFunc(window2reshape); Glut.displayFunc(window2display); Glut.timerFunc 7000 timefunc 1 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test14.ml000077500000000000000000000070611437514534100221000ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* Try testing menu item removal and menu destruction. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 2002. *) open Printf let displayFunc () = GlClear.clear [`color]; Gl.flush(); ;; let menuFunc ~value = printf "choice = %d\n" value ;; let timefunc ~value = if (value <> 1) then failwith "test14\n"; printf("PASS: test14\n"); exit(0); ;; let main () = ignore(Glut.init Sys.argv); ignore(Glut.createWindow("test14")); Glut.displayFunc(displayFunc); let submenu = Glut.createMenu(menuFunc) in Glut.addMenuEntry "First" 10101; Glut.addMenuEntry "Second" 20202; let menu = Glut.createMenu menuFunc in Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2----------" 102; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "oEntry1" 201; Glut.addMenuEntry "o----------" 200; Glut.addMenuEntry "oEntry2----------" 202; Glut.addMenuEntry "oEntry3" 203; Glut.removeMenuItem 2; Glut.destroyMenu menu; let menu = Glut.createMenu menuFunc in Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2----------" 102; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "oEntry1" 201; Glut.addMenuEntry "o----------" 200; Glut.addMenuEntry "oEntry2----------" 202; Glut.addMenuEntry "oEntry3" 203; Glut.removeMenuItem 2; Glut.attachMenu Glut.RIGHT_BUTTON; let menu = Glut.createMenu menuFunc in for i = 0 to 9 do Glut.addMenuEntry "YES" i done; for i = 0 to 9 do Glut.removeMenuItem 1 done; Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2" 102; Glut.addMenuEntry "Entry3" 103; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "----------" 303; for i = 0 to 9 do Glut.addMenuEntry "YES**************************" i; done; for i = 0 to 8 do Glut.removeMenuItem(3); done; Glut.destroyMenu menu; let menu = Glut.createMenu menuFunc in for i = 0 to 9 do Glut.addMenuEntry "YES" i; done; for i = 0 to 9 do Glut.removeMenuItem 1; done; Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2" 102; Glut.addMenuEntry "Entry3" 103; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "----------" 303; for i = 0 to 9 do Glut.addMenuEntry "YES**************************" i; done; for i = 0 to 8 do Glut.removeMenuItem 3; done; Glut.attachMenu Glut.MIDDLE_BUTTON; let menu = Glut.createMenu menuFunc in Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2" 102; Glut.addMenuEntry "Entry3" 103; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "nEntry1" 201; Glut.addMenuEntry "nEntry2----------" 202; Glut.addMenuEntry "nEntry3" 203; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "n----------" 303; Glut.changeToMenuEntry 1 "HELLO" 34; Glut.changeToSubMenu 2 "HELLO menu" submenu; Glut.destroyMenu menu; let menu = Glut.createMenu(menuFunc) in Glut.addMenuEntry "Entry1" 101; Glut.addMenuEntry "Entry2" 102; Glut.addMenuEntry "Entry3" 103; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "nEntry1" 201; Glut.addMenuEntry "nEntry2----------" 202; Glut.addMenuEntry "nEntry3" 203; Glut.removeMenuItem 2; Glut.removeMenuItem 1; Glut.addMenuEntry "n----------" 303; Glut.attachMenu Glut.LEFT_BUTTON; Glut.timerFunc 2000 timefunc 1; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test15.ml000077500000000000000000000042261437514534100221010ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:18:32 MDT 2002. *) open Printf (* 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. *) (* This test makes sure that if you post a redisplay within a display callback another display callback will be generated. I believe this is useful for progressive refinement of an image. Draw it once at a coarse tesselation to get something on the screen; then redraw at a higher level of tesselation. Pre-GLUT 2.3 fails this test. *) let light_position = [|1.0, 1.0, 1.0, 0.0|];; let qobj = GluQuadric.create ();; let tesselation = ref 3;; let displayFunc () = fprintf stderr " %d" !tesselation ; flush stderr; (* if (!tesselation > 23) then begin *) if (!tesselation > 60) then begin printf("\nPASS -> test15\n"); exit(0); end; GlClear.clear [`color; `depth]; GluQuadric.sphere ~quad:qobj ~radius:1.0 ~slices:!tesselation ~stacks:!tesselation (); Glut.swapBuffers(); incr tesselation; Glut.postRedisplay(); ;; let timefunc ~value = failwith "test15";; let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~depth:true ~double_buffer:true ~alpha:false (); ignore(Glut.createWindow("test15")); Glut.displayFunc(displayFunc); GluQuadric.draw_style qobj `fill ; GlLight.light ~num:0 (`diffuse (1.0, 0.0, 0.0, 1.0)); GlLight.light ~num:0 (`position (1.0, 1.0, 1.0, 0.)); Gl.enable `lighting; Gl.enable `light0; Gl.enable `depth_test; GlMat.mode `projection; GluMat.perspective ~fovy:22.0 ~aspect:1.0 ~z:(1.0, 10.0); GlMat.mode `modelview; GluMat.look_at ~eye:(0.0, 0.0, 5.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0); (* up is in postivie Y direction *) GlMat.translate3 (0.0, 0.0, -1.0); (* Have a reasonably large timeout since some machines make take a while to render all those polygons. *) Glut.timerFunc 15000 timefunc 1 ; fprintf stderr "tesselations =" ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test16.ml000077500000000000000000000045141437514534100221020ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:18:33 MDT 2002. *) (* 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. *) (* Exercise all the GLUT shapes. *) #load "unix.cma" open Printf let shape = ref 1;; let writeln s = print_string s; print_newline();; let displayFunc () = fprintf stderr " %d\n" !shape ; flush stderr; GlClear.clear [`color; `depth]; begin match !shape with | 1 -> Glut.wireSphere 1.0 20 20 ; | 2 -> Glut.solidSphere 1.0 20 20 ; | 3 -> Glut.wireCone 1.0 1.0 20 20 ; | 4 -> Glut.solidCone 1.0 1.0 20 20 ; | 5 -> Glut.wireCube 1.0; | 6 -> Glut.solidCube 1.0; | 7 -> Glut.wireTorus 0.5 1.0 15 15 ; | 8 -> Glut.solidTorus 0.5 1.0 15 15 ; | 9 -> Glut.wireDodecahedron(); | 10 -> Glut.solidDodecahedron(); | 11 -> Glut.wireTeapot 1.0; | 12 -> Glut.solidTeapot 1.0; | 13 -> Glut.wireOctahedron(); | 14 -> Glut.solidOctahedron(); | 15 -> Glut.wireTetrahedron(); | 16 -> Glut.solidTetrahedron(); | 17 -> Glut.wireIcosahedron(); | 18 -> Glut.solidIcosahedron(); | _ -> begin printf("\nPASS : test16\n"); exit(0); end; end; Glut.swapBuffers(); incr shape; Unix.sleep(1); Glut.postRedisplay(); ;; let timefunc ~value = failwith "test16";; let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~depth:true ~double_buffer:true ~alpha:false (); ignore(Glut.createWindow("test16")); Glut.displayFunc(displayFunc); GlLight.light ~num:0 (`diffuse (1.0, 0.0, 0.0, 1.0)) ; GlLight.light ~num:0 (`position (1.0, 1.0, 1.0, 1.0)) ; List.iter Gl.enable [`lighting; `light0; `depth_test ]; GlMat.mode `projection; GluMat.perspective ~fovy:22.0 ~aspect:1.0 ~z:(1.0, 10.0) ; GlMat.mode `modelview ; GluMat.look_at ~eye:(0.0, 0.0, 5.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0); GlMat.translate3 (0.0, 0.0, -3.0); GlMat.rotate ~angle:25.0 ~x:1.0 ~y:0.0 ~z:0.0 (); (* Have a reasonably large timeout since some machines make take a while to render all those polygons. *) Glut.timerFunc 35000 timefunc 1; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test17.ml000077500000000000000000000143461437514534100221070ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Sun Aug 11 14:55:37 MDT 2002. *) open Printf (* 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. *) (* Test for GLUT 3.0's overlay functionality. *) let transP = ref 0 let main_win = ref 0 let x = ref 0.0 and y = ref 0.0 let render_normal () = Glut.useLayer(Glut.NORMAL); GlClear.clear [`color]; GlDraw.color (0.0,0.0,1.0); GlDraw.begins `polygon; GlDraw.vertex ~x:0.2 ~y:0.28 (); GlDraw.vertex ~x:0.5 ~y:0.58 (); GlDraw.vertex ~x:0.2 ~y:0.58 (); GlDraw.ends(); Gl.flush(); ;; let render_overlay () = GlClear.clear [`color]; GlDraw.begins `polygon; GlDraw.vertex ~x:(0.2 +. !x) ~y:(0.2 +. !y) (); GlDraw.vertex ~x:(0.5 +. !x) ~y:(0.5 +. !y) (); GlDraw.vertex ~x:(0.2 +. !x) ~y:(0.5 +. !y) (); GlDraw.ends(); Gl.flush(); ;; let render () = Glut.useLayer(Glut.NORMAL); render_normal(); if (Glut.layerGet(Glut.HAS_OVERLAY)) then begin Glut.useLayer(Glut.OVERLAY); render_overlay(); end ;; let render_sub () = printf("render_sub\n"); Glut.useLayer(Glut.NORMAL); render_normal(); if (Glut.layerGet(Glut.HAS_OVERLAY)) then begin Glut.useLayer(Glut.OVERLAY); render_overlay(); end ;; let display_count = ref 0 let damage_expectation = ref false let timer ~value = if (value <> 777) then failwith("unexpected timer value"); damage_expectation := true; Glut.showWindow(); ;; let rec time2 ~value = if (value = 666) then begin printf("PASS: test17\n"); exit(0); end; if (value <> 888) then failwith("bad value"); Glut.destroyWindow(!main_win); Glut.timerFunc 500 time2 666; ;; let move_on () = incr display_count; if (!display_count = 2) then begin damage_expectation := true; Glut.iconifyWindow(); Glut.timerFunc 500 timer 777; end; if !display_count = 4 then begin printf "display_count = 4\n"; Glut.initDisplayMode (); ignore(Glut.createSubWindow !main_win 10 10 150 150); GlClear.color (0.5, 0.5, 0.5); Glut.displayFunc(render_sub); Glut.initDisplayMode ~index:true (); Glut.establishOverlay(); Glut.copyColormap !main_win; Glut.setColor ~cell:((!transP + 1) mod 2) ~red:0.0 ~green:1.0 ~blue:1.0; Glut.removeOverlay(); Glut.establishOverlay(); Glut.copyColormap(!main_win); Glut.copyColormap(!main_win); Glut.setColor ~cell:((!transP + 1) mod 2) ~red:1.0 ~green:1.0 ~blue:1.0; GlClear.index ((float_of_int !transP)); GlDraw.index (float_of_int ((!transP + 1) mod 2)); Glut.setWindow(!main_win); Glut.removeOverlay(); Glut.timerFunc 500 time2 888; end ;; let display_normal() = if (Glut.layerGet(Glut.NORMAL_DAMAGED) <> !damage_expectation) then failwith(" normal damage not expected\n"); render_normal(); move_on(); ;; let display_overlay() = if (Glut.layerGet(Glut.OVERLAY_DAMAGED) <> !damage_expectation) then failwith(" overlay damage not expected\n"); render_overlay(); move_on(); ;; let been_here = ref false (* strange: this never gets set to true... -ijt *) let display2() = if Glut.layerGet(Glut.NORMAL_DAMAGED) then failwith(" normal damage not expected\n"); if Glut.layerGet(Glut.OVERLAY_DAMAGED) then failwith(" overlay damage not expected\n"); if (!been_here) then Glut.postOverlayRedisplay() else begin Glut.overlayDisplayFunc(display_overlay); Glut.displayFunc(display_normal); damage_expectation := true; Glut.postOverlayRedisplay(); Glut.postRedisplay(); end ;; let display() = if not (Glut.layerGet(Glut.NORMAL_DAMAGED)) then failwith(" normal damage expected\n"); if not (Glut.layerGet(Glut.OVERLAY_DAMAGED)) then failwith(" overlay damage expected\n"); render(); Glut.displayFunc(display2); Glut.postRedisplay(); ;; let main () = ignore(Glut.init Sys.argv); Glut.initWindowSize 300 300; Glut.initDisplayMode ~index:true (); if not (Glut.layerGet(Glut.OVERLAY_POSSIBLE)) then begin printf "UNRESOLVED: need overlays for this test (your window system "; printf "lacks overlays)\n"; exit(0); end; Glut.initDisplayMode (); main_win := Glut.createWindow("test17"); if Glut.layerGetInUse() = Glut.OVERLAY then failwith(" overlay should not be in use\n"); if Glut.layerGet(Glut.HAS_OVERLAY) then failwith(" overlay should not exist\n"); if Glut.layerGetTransparentIndex() <> -1 then failwith(" transparent pixel of normal plane should be -1\n"); if Glut.layerGet(Glut.NORMAL_DAMAGED) then failwith(" no normal damage yet\n"); (* raises exception if overlay is not in use: *) ignore(Glut.layerGet(Glut.OVERLAY_DAMAGED)); GlClear.color (0.0, 1.0, 0.0); Glut.initDisplayMode ~index:true (); (* Small torture test. *) Glut.establishOverlay(); Glut.removeOverlay(); Glut.establishOverlay(); Glut.establishOverlay(); Glut.showOverlay(); Glut.hideOverlay(); Glut.showOverlay(); Glut.removeOverlay(); Glut.removeOverlay(); Glut.establishOverlay(); if (Glut.get(Glut.WINDOW_RGBA) <> 0) then failwith(" overlay should not be RGBA\n"); Glut.useLayer(Glut.NORMAL); if not (Glut.get(Glut.WINDOW_RGBA) <> 0) then failwith(" normal should be RGBA\n"); Glut.useLayer(Glut.OVERLAY); if (Glut.get(Glut.WINDOW_RGBA) <> 0) then failwith(" overlay should not be RGBA\n"); if (Glut.layerGetInUse() = Glut.NORMAL) then failwith(" overlay should be in use\n"); if not (Glut.layerGet(Glut.HAS_OVERLAY)) then failwith(" overlay should exist\n"); if (Glut.layerGetTransparentIndex() = -1) then failwith(" transparent pixel should exist\n"); if Glut.layerGet(Glut.NORMAL_DAMAGED) then failwith(" no normal damage yet\n"); if Glut.layerGet(Glut.OVERLAY_DAMAGED) then failwith(" no overlay damage yet\n"); transP := Glut.layerGetTransparentIndex(); GlClear.index (float_of_int (Glut.layerGetTransparentIndex())); Glut.setColor ((!transP + 1) mod 2) 1.0 0.0 1.0; GlDraw.index (float_of_int ((!transP + 1) mod 2)); Glut.useLayer(Glut.NORMAL); if (Glut.layerGetInUse() = Glut.OVERLAY) then failwith(" overlay should not be in use\n"); Glut.displayFunc(display); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test18.ml000077500000000000000000000100441437514534100220770ustar00rootroot00000000000000(* 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. *) (* Test display callbacks are not called for non-viewable windows and overlays. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 2002. *) open Printf let transP = ref 0 and opaqueP = ref 0 let main_win = ref 0 and sub_win = ref 0 let overlaySupported = ref false let subHidden = ref false and overlayHidden = ref false let warnIfNormalDisplay = ref false let firstTime = ref true let fail18() = failwith "test18" let time5_cb ~value = if value <> -3 then fail18(); printf "PASS: test18\n"; exit 0; ;; let time4_cb ~value = if value <> -6 then fail18(); warnIfNormalDisplay := false; Glut.timerFunc 750 time5_cb (-3); Glut.setWindow !sub_win; Glut.postRedisplay(); Glut.setWindow !main_win; if !overlaySupported then Glut.postOverlayRedisplay(); ;; let time3_cb ~value = if value <> 6 then fail18(); Glut.setWindow !main_win; Glut.hideOverlay(); overlayHidden := true; warnIfNormalDisplay := true; Glut.timerFunc 500 time4_cb (-6); ;; let time2_cb ~value = if value <> 56 then fail18(); Glut.setWindow !main_win; if !overlaySupported then begin Glut.showOverlay(); overlayHidden := false; end; Glut.setWindow !sub_win; Glut.hideWindow(); subHidden := true; Glut.timerFunc 500 time3_cb 6; ;; let time_cb ~value = if value <> 456 then fail18(); Glut.setWindow !sub_win; subHidden := false; Glut.showWindow(); Glut.timerFunc 500 time2_cb 56; ;; let display () = if !warnIfNormalDisplay then begin printf "WARNING: hiding overlay should not generate normal plane expose not \n"; printf "does overlay operation work correctly?"; print_newline(); end; if Glut.layerGetInUse() <> Glut.NORMAL then fail18(); GlClear.clear [`color]; Gl.flush(); if !firstTime then begin Glut.timerFunc 500 time_cb 456; firstTime := false; end; ;; let subDisplay () = if Glut.layerGetInUse() <> Glut.NORMAL then fail18(); if !subHidden then begin printf "display callback generated when subwindow was hidden not \n"; fail18(); end; GlClear.clear [`color]; Gl.flush (); ;; let overDisplay () = if Glut.layerGetInUse() <> Glut.OVERLAY then fail18(); if !overlayHidden then begin printf "display callback generated when overlay was hidden not \n"; fail18(); end; GlClear.clear [`color]; Gl.flush(); ;; let subVis ~state = if Glut.layerGetInUse() <> Glut.NORMAL then fail18(); if !subHidden && state = Glut.VISIBLE then begin printf "visible callback generated when overlay was hidden not \n"; fail18(); end; if not !subHidden && state = Glut.NOT_VISIBLE then begin printf "non-visible callback generated when overlay was shown not \n"; fail18() end; ;; let main () = ignore(Glut.init Sys.argv); Glut.initWindowSize ~w:300 ~h:300; Glut.initDisplayMode ~alpha:true (); main_win := Glut.createWindow "test18"; if Glut.get Glut.WINDOW_COLORMAP_SIZE <> 0 then begin printf "RGBA color model windows should report zero colormap entries.\n"; fail18(); end; Glut.initDisplayMode ~index:true (); Glut.displayFunc display; overlaySupported := Glut.layerGet Glut.OVERLAY_POSSIBLE ; if !overlaySupported then begin Glut.establishOverlay (); Glut.hideOverlay (); overlayHidden := true; Glut.overlayDisplayFunc overDisplay; transP := Glut.layerGetTransparentIndex(); GlClear.index (float_of_int(Glut.layerGetTransparentIndex())); opaqueP := !transP + 1 mod (Glut.get Glut.WINDOW_COLORMAP_SIZE); Glut.setColor !opaqueP 1.0 0.0 1.0; GlClear.index (float_of_int !opaqueP); end; Glut.initDisplayMode ~alpha:true (); sub_win := Glut.createSubWindow !main_win 10 10 20 20; GlClear.color (0.0, 1.0, 0.0); Glut.displayFunc subDisplay; Glut.visibilityFunc subVis; Glut.hideWindow(); subHidden := true; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test19.ml000077500000000000000000000023561437514534100221070ustar00rootroot00000000000000#!/usr/bin/env lablglut open Printf (* 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. *) (* This test makes sure damaged gets set when a window is resized smaller. *) let width = ref (-1);; let height = ref (-1);; let displayCount = ref 0;; let onDone ~value = if (!displayCount <> 2) then failwith "test19 damage expected\n"; fprintf stderr "PASS : test19\n" ; exit(0); ;; let reshape ~w ~h = printf "window reshaped : w=%d h=%d\n" w h ; width := w; height := h; ;; let display () = if not (Glut.layerGet Glut.NORMAL_DAMAGED) then failwith "test19 damage expected\n" ; incr displayCount; if (!width = -1 || !height = -1) then failwith "test19 reshape not called\n" ; GlClear.clear [`color]; Gl.flush(); if (!displayCount = 1) then begin Glut.reshapeWindow (!width / 2) (!height / 2); Glut.timerFunc 1000 onDone 0 ; end ;; let main () = ignore(Glut.init Sys.argv); ignore(Glut.createWindow("test19")); Glut.displayFunc(display); Glut.reshapeFunc(reshape); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test2.ml000077500000000000000000000113421437514534100220120ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. Ported to lablglut by Issac Trotts on August 5, 2002. *) open Printf let count = ref 0;; let save_count = ref 0;; let head = ref 0;; let tail = ref 0;; let diff = ref 0;; let timer2 ~value = if (value <> 36) then raise (Failure "timer value wrong\n"); if (!count <> !save_count) then raise (Failure "counter still counting\n"); printf("PASS: test2\n"); exit 0 ; ;; let timer ~value = if (value <> 42) then raise (Failure "timer value wrong\n"); if (!count <= 0) then raise (Failure "idle func not running\n"); Glut.idleFunc None; save_count := !count; tail := Glut.get(Glut.ELAPSED_TIME); diff := !tail - !head; printf "diff = %d (%d - %d)\n" !diff !tail !head ; if !diff > int_of_float(500.0 *. 1.2) then begin printf("THIS TEST IS TIME SENSITIVE; IF IT FAILS, TRY RUNNING IT AGAIN.\n"); raise (Failure "timer too late\n"); end; if !diff < int_of_float(500.0 *. 0.9) then begin printf("THIS TEST IS TIME SENSITIVE; IF IT FAILS, TRY RUNNING IT AGAIN.\n"); raise (Failure "timer too soon\n"); end; Glut.timerFunc 100 timer2 36 ;; let menuSelect ~value = () ;; (* do nothing *) let never_void () = if false then begin printf "never_void shouldn't be called."; print_newline() end else raise (Failure "never_void should never be called\n") ;; let never_value ~state = if false then begin printf "never_value shouldn't be called."; print_newline() end else raise (Failure "never_value most be NOT visible\n") ;; let the_win = ref (-1);; let display () = Glut.setWindow !the_win; GlClear.clear [`color]; Gl.flush(); ;; let main () = ignore (Glut.init Sys.argv); Glut.initWindowPosition 10 10 ; Glut.initWindowSize 200 200 ; Glut.initDisplayMode ~double_buffer:false ~alpha:false ~depth:true (); let win = (Glut.createWindow "test2") in (* this doesn't seem to be in lablGL glGetIntegerv(GL_INDEX_MODE, &isIndex); if isIndex <> 0 then raise (Failure "window should be RGB\n"); *) the_win:=win; Glut.setWindow win ; Glut.displayFunc display ; let menu = Glut.createMenu menuSelect in Glut.setMenu menu ; Glut.reshapeFunc (fun ~w ~h -> () ); Glut.reshapeFunc (fun ~w ~h -> () ); Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.mouseFunc (fun ~button ~state ~x ~y -> ()); Glut.mouseFunc (fun ~button ~state ~x ~y -> ()); Glut.motionFunc (fun ~x ~y -> ()); Glut.motionFunc (fun ~x ~y -> ()); Glut.visibilityFunc (fun ~state -> ()); Glut.visibilityFunc (fun ~state -> ()); Glut.menuStateFunc (fun ~status -> ()); Glut.menuStateFunc (fun ~status -> ()); Glut.menuStatusFunc (fun ~status ~x ~y -> ()); Glut.menuStatusFunc (fun ~status ~x ~y -> ()); Glut.specialFunc (fun ~key ~x ~y -> ()); Glut.specialFunc (fun ~key ~x ~y -> ()); Glut.spaceballMotionFunc (fun ~x ~y ~z -> ()); Glut.spaceballMotionFunc (fun ~x ~y ~z -> ()); Glut.spaceballRotateFunc (fun ~x ~y ~z -> ()); Glut.spaceballRotateFunc (fun ~x ~y ~z -> ()); Glut.spaceballButtonFunc (fun ~button ~state -> ()); Glut.spaceballButtonFunc (fun ~button ~state -> ()); Glut.buttonBoxFunc (fun ~button ~state -> ()); Glut.buttonBoxFunc (fun ~button ~state -> ()); Glut.dialsFunc (fun ~dial ~value -> ()); Glut.dialsFunc (fun ~dial ~value -> ()); Glut.tabletMotionFunc (fun ~x ~y -> ()); Glut.tabletMotionFunc (fun ~x ~y -> ()); Glut.tabletButtonFunc (fun ~button ~state ~x ~y -> ()); Glut.tabletButtonFunc (fun ~button ~state ~x ~y -> ()); let menus = ref [] in let windows = ref [] in let num = 1 in for i = 0 to (num-1) do (* let menu = Glut.createMenu menuSelect in *) let window = Glut.createWindow "test" in windows := window :: !windows; menus := menu :: !menus; Glut.displayFunc(display); for j = 0 to (i-1) do Glut.addMenuEntry "Hello" 1 ; Glut.addSubMenu "Submenu" menu ; done; if menu <> Glut.getMenu() then raise (Failure (sprintf "current menu not %d\n" menu)); if window <> Glut.getWindow() then raise (Failure (sprintf "current window not %d\n" window)); Glut.displayFunc never_void ; Glut.visibilityFunc never_value ; Glut.hideWindow(); done; List.iter (fun m -> Glut.destroyMenu m) !menus ; List.iter (fun w -> Glut.destroyWindow w) !windows ; (* Glut.setWindow win; (* ijt *) *) Glut.timerFunc 500 timer 42 ; head := Glut.get(Glut.ELAPSED_TIME); Glut.idleFunc (Some(fun () -> incr count)); Glut.mainLoop(); exit 0;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test20.ml000077500000000000000000000100541437514534100220710ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* Test Glut.extensionSupported. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 2002. *) open Printf let wrangleExtensionName ~extension = let buffer = ref "" in buffer := sprintf " %s" extension; let rc = Glut.extensionSupported !buffer in if rc then failwith "test20 space prefix"; buffer := sprintf "%s " extension; let rc = Glut.extensionSupported !buffer in if rc then failwith "test20 space suffix"; buffer := sprintf "GL_%s" extension; let rc = Glut.extensionSupported !buffer in if rc then failwith "test20 GL_ prefix"; let len = (String.length extension) in let rc = Glut.extensionSupported (String.sub extension 1 (len-1)) in if rc then failwith "test20 missing first character"; buffer := sprintf "%s" extension; let len = (String.length !buffer) in if len > 0 then buffer := String.sub !buffer 0 (len-1); let rc = Glut.extensionSupported !buffer in if rc then failwith "test20 mising last character"; buffer := sprintf "%s" extension; let len = (String.length !buffer) in if len > 0 then (!buffer).[len-1] <- 'X'; let rc = Glut.extensionSupported !buffer in if rc then failwith "test20 changed last character"; ;; let main () = ignore(Glut.init Sys.argv); ignore(Glut.createWindow "test20"); let extension = ref "" in extension := "GL_EXT_blend_color"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_abgr"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_blend_minmax"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_blend_logic_op"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_blend_subtract"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_polygon_offset"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_subtexture"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_texture"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_EXT_texture_object"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; extension := "GL_SGIX_framezoom"; let rc = Glut.extensionSupported !extension in printf "extension %s is %s by your OpenGL.\n" !extension (if rc then "SUPPORTED\n" else "NOT supported"); if rc then wrangleExtensionName !extension; let rc = Glut.extensionSupported "" in if rc then failwith "test20 null string"; printf "PASS: test20"; ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test21.ml000077500000000000000000000101561437514534100220750ustar00rootroot00000000000000(* 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 tests GLUT's video resize API (currently only supported on SGI's InfiniteReality hardware). *) (* Ported to lablglut by Issac Trotts on Sat Aug 11 2002. *) open Printf let light_diffuse = (1.0,0.0,0.0) let light_position = (1.0,1.0,1.0) let x=ref 0 and y=ref 0 and w=ref 0 and h=ref 0 let dx=ref 0 and dy=ref 0 and dw=ref 0 and dh=ref 0 let (-=) x y = x := !x - y let (+=) x y = x := !x + y let display () = GlClear.clear [`color; `depth]; Glut.solidTeapot 1.0; Glut.swapBuffers(); ;; let show_video_size() = printf "Glut.VIDEO_RESIZE_X = %d\n" (Glut.videoResizeGet Glut.VIDEO_RESIZE_X); printf "Glut.VIDEO_RESIZE_Y = %d\n" (Glut.videoResizeGet Glut.VIDEO_RESIZE_Y); printf "Glut.VIDEO_RESIZE_WIDTH = %d\n" (Glut.videoResizeGet Glut.VIDEO_RESIZE_WIDTH); printf "Glut.VIDEO_RESIZE_HEIGHT = %d\n" (Glut.videoResizeGet Glut.VIDEO_RESIZE_HEIGHT); ;; let keyboard ~key ~x ~y = printf "c = %c\n" (char_of_int key); if key = 27 then exit 0; match (char_of_int key) with | 'a' -> Glut.videoPan 0 0 1280 1024; | 'b' -> Glut.videoPan 0 0 1600 1024; | 'c' -> Glut.videoPan 640 512 640 512; | 'q' -> Glut.videoPan 320 256 640 512; | '1' -> Glut.videoResize 0 0 640 512; | '2' -> Glut.videoResize 0 512 640 512; | '3' -> Glut.videoResize 512 512 640 512; | '4' -> Glut.videoResize 512 0 640 512; | 's' -> Glut.stopVideoResizing (); | '=' -> show_video_size(); | ' ' -> Glut.postRedisplay(); | _ -> () ;; let rec time2 ~value = Glut.videoResize !x !y !w !h; Glut.postRedisplay(); x -= !dx; y -= !dy; w += !dx * 2; h += !dy * 2; if !x > 0 then Glut.timerFunc 100 time2 0 else begin Glut.stopVideoResizing(); printf "PASS: test21 with video resizing tested\n"; exit 0; end ;; let rec time1 ~value = Glut.videoPan !x !y !w !h; x += !dx; y += !dy; w -= !dx * 2; h -= !dy * 2; if !x < 200 then Glut.timerFunc 100 time1 0 else Glut.timerFunc 100 time2 0 ;; let main() = let interact = ref false in ignore(Glut.init Sys.argv); for i = 1 to ((Array.length Sys.argv)-1) do if "-i" = Sys.argv.(i) then interact := true; done; Glut.initDisplayMode ~double_buffer:true (); ignore(Glut.createWindow "test21"); if Glut.videoResizeGet Glut.VIDEO_RESIZE_POSSIBLE = 0 then begin printf "video resizing not supported\n"; printf "PASS: test21\n"; exit 0; end; Glut.setupVideoResizing(); printf "Glut.VIDEO_RESIZE_X_DELTA = %d\n" (dx := Glut.videoResizeGet Glut.VIDEO_RESIZE_X_DELTA; !dx); printf "Glut.VIDEO_RESIZE_Y_DELTA = %d\n" (dy := Glut.videoResizeGet Glut.VIDEO_RESIZE_Y_DELTA; !dy); printf "Glut.VIDEO_RESIZE_WIDTH_DELTA = %d\n" (dw := Glut.videoResizeGet Glut.VIDEO_RESIZE_WIDTH_DELTA; !dw); printf "Glut.VIDEO_RESIZE_HEIGHT_DELTA = %d\n" (dh := Glut.videoResizeGet Glut.VIDEO_RESIZE_HEIGHT_DELTA; !dh); printf "Glut.VIDEO_RESIZE_X = %d\n" (x := Glut.videoResizeGet Glut.VIDEO_RESIZE_X; !x); printf "Glut.VIDEO_RESIZE_Y = %d\n" (y := Glut.videoResizeGet Glut.VIDEO_RESIZE_Y; !y); printf "Glut.VIDEO_RESIZE_WIDTH = %d\n" (w := Glut.videoResizeGet Glut.VIDEO_RESIZE_WIDTH; !w); printf "Glut.VIDEO_RESIZE_HEIGHT = %d\n" (h := Glut.videoResizeGet Glut.VIDEO_RESIZE_HEIGHT; !h); Glut.stopVideoResizing(); Glut.setupVideoResizing(); Glut.displayFunc display; Glut.fullScreen(); GlLight.light ~num:0 (`diffuse (1.0, 0.0, 0.0, 0.0)); GlLight.light ~num:0 (`position (1.0, 1.0, 1.0, 1.0)); Gl.enable `lighting; Gl.enable `light0; Gl.enable `depth_test; GlMat.mode `projection; GluMat.perspective ~fovy:22.0 ~aspect:1.0 ~z:(1.0, 10.0); GlMat.mode `modelview; GluMat.look_at ~eye:(0.0, 0.0, 5.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0); GlMat.translate ~z:(-1.0) (); Glut.keyboardFunc keyboard; if not !interact then Glut.timerFunc 100 time1 0; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test22.ml000077500000000000000000000067131437514534100221020ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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 tests GLUT's Glut.windowStatusFunc rotuine. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 16:07:37 MDT 2002. *) open Printf let win = ref(-1) let subwin = ref(-1) let cover = ref(-1) let fail x = failwith ("test22 " ^ x) let display () = GlClear.clear [`color; `depth]; Glut.swapBuffers(); ;; let time_end ~value = printf "PASS: test22\n"; exit 0; ;; let time5 ~value = Glut.setWindow !subwin; Glut.positionWindow 40 40; ;; let time4 ~value = Glut.setWindow !subwin; Glut.showWindow(); ;; let time3 ~value = Glut.setWindow !subwin; Glut.hideWindow(); ;; let sub_state = ref 0 let cover_state = ref 0 let super_state = ref 0 let coverstat ~state = if !cover <> Glut.getWindow() then fail "coverstat"; printf "%d: cover = %s" !cover_state (Glut.string_of_window_status state); print_newline(); ignore(match !cover_state with | 0 -> begin if state <> Glut.FULLY_RETAINED then fail "coverstat 2"; Glut.timerFunc 1000 time3 0; end | _ -> fail "coverstat 3"); incr cover_state; ;; let time2 ~value = cover := Glut.createSubWindow !win 5 5 105 105; GlClear.color (0.0, 1.0, 0.0); Glut.displayFunc display; Glut.windowStatusFunc coverstat; ;; let substat ~state = if !subwin <> Glut.getWindow() then fail "substat"; printf "%d: substate = %s" !sub_state (Glut.string_of_window_status state); print_newline(); ignore(match !sub_state with | 0 -> begin if state <> Glut.FULLY_RETAINED then fail "substat 2"; Glut.timerFunc 1000 time2 0; end | 1 -> if state <> Glut.FULLY_COVERED then fail "substat 3"; | 2 -> begin if state <> Glut.HIDDEN then fail "substat 4"; Glut.timerFunc 1000 time4 0; end | 3 -> begin if state <> Glut.FULLY_COVERED then fail "substat 5"; Glut.timerFunc 1000 time5 0; end | 4 -> begin if state <> Glut.PARTIALLY_RETAINED then fail "substat 6"; Glut.timerFunc 1000 time_end 0; end | _ -> fail "substat 7"); incr sub_state; ;; let time1 ~value = printf "time1"; print_newline(); subwin := Glut.createSubWindow !win 10 10 100 100; printf "subwin = %i" !subwin; print_newline(); printf "get window = %i" (Glut.getWindow()); print_newline(); GlClear.color (0.0, 1.0, 1.0); Glut.displayFunc display; Glut.windowStatusFunc substat; ;; let winstat ~state = if !win <> Glut.getWindow() then fail "winstat 1"; printf "%d: win = %s" !super_state (Glut.string_of_window_status state); print_newline(); ignore(match !super_state with | 0 -> begin if state <> Glut.FULLY_RETAINED then fail "winstat 2"; Glut.timerFunc 1000 time1 0; end | 1 -> if state <> Glut.PARTIALLY_RETAINED then fail "winstat 3"; | _ -> fail "winstat 4"); incr super_state; ;; let visbad ~state = fail "visbad" ;; let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:false ~double_buffer:false (); win := Glut.createWindow "test22"; GlClear.color (1.0, 0.0, 1.0); Glut.displayFunc display; Glut.visibilityFunc visbad; Glut.visibilityFunc (fun ~state -> ()); Glut.windowStatusFunc (fun ~state -> ()); Glut.visibilityFunc (fun ~state -> ()); Glut.windowStatusFunc winstat; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test23.ml000077500000000000000000000073231437514534100221010ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Sat Aug 10 12:12:42 MDT 2002. *) open Printf (* 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 tests unexpected interactions between Glut.initDisplayMode and Glut.initDisplayString. *) let modes = [| Glut.rgb lor Glut.single; Glut.rgb lor Glut.double; Glut.index lor Glut.single; Glut.index lor Glut.double |];; let strings = [| "rgb double" ; "rgba double" ; "rgba single" ; "index" ; "index double" ; "rgb samples=4" ; "stencil depth red green blue alpha conformant auxbufs buffer acc acca double rgb rgba" ; "stereo index samples slow" |];; let ostrings = [| "index double" ; "index single" ; "index buffer=4" ; "index buffer=8" ; "index buffer~4" ; "index buffer=4 depth" |];; let verbose = ref false;; let main () = ignore(Glut.init Sys.argv); if Array.length Sys.argv > 1 then if Sys.argv.(1) <> "-v" then verbose := true; Glut.initWindowPosition 10 10; Glut.initWindowSize 200 200; for k = 0 to ((Array.length modes)-1) do let m = modes.(k) in Glut.initDisplayMode ~index:(m land Glut.index <> 0) ~double_buffer:(m land Glut.double <> 0) (); printf "Display Mode = %d (%s %s)" m (if m land Glut.index <> 0 then "index" else "rgba") (if m land Glut.double <> 0 then "double" else "single"); print_newline(); for i = 0 to ((Array.length strings)-1) do Glut.initDisplayString(strings.(i)); if Glut.getBool Glut.DISPLAY_MODE_POSSIBLE then begin if !verbose then printf " Possible: %s\n" strings.(i); let win = Glut.createWindow("test23") in if !verbose then printf " Created: %s\n" strings.(i); for j = 0 to ((Array.length ostrings)-1) do Glut.initDisplayString(ostrings.(j)); if (Glut.layerGet Glut.OVERLAY_POSSIBLE) then begin if !verbose then begin printf " Overlay possible: %s" ostrings.(j); print_newline(); end; Glut.establishOverlay(); if !verbose then begin printf " Overlay establish: %s" ostrings.(j); print_newline(); end; Glut.removeOverlay(); if !verbose then begin printf " Overlay remove: %s" ostrings.(j); print_newline(); end; end; done; Glut.destroyWindow(win); if !verbose then printf " Destroyed: %s\n" strings.(i); end else if !verbose then printf "Not possible: %s\n" strings.(i); done done; Glut.initDisplayString ""; let num = ref 1 and exists = ref true in while !exists do let mode = sprintf "rgb num=%d" !num in Glut.initDisplayString mode; exists := Glut.getBool Glut.DISPLAY_MODE_POSSIBLE; if !exists then begin if !verbose then printf " Possible: %s\n" mode; let win = Glut.createWindow("test23") in if !verbose then printf " Created: %s\n" mode; Glut.destroyWindow(win); if !verbose then printf " Destroyed: %s\n" mode; let mode = sprintf "rgb num=0x%x" !num in Glut.initDisplayString(mode); exists := Glut.getBool Glut.DISPLAY_MODE_POSSIBLE; if not !exists then failwith("test23 (hex num= don't work)\n"); let win = Glut.createWindow "test23" in Glut.destroyWindow win; incr num; end else if !verbose then printf "Not possible: %s\n" mode; done; Glut.initDisplayString ""; printf "PASS: test23\n"; ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test24.ml000077500000000000000000000065141437514534100221030ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:18:40 MDT 2002. *) open Printf (* 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 tests various obscure interactions in menu creation and destruction including the support for Sun's Creator 3D overlay "high cell" overlay menu colormap cell allocation. *) let display () = GlClear.clear [`color]; Gl.finish(); ;; let timer ~value = if (value <> 23) then failwith("bad timer value\n"); printf("PASS: test24\n"); exit(0); ;; let menuSelect ~value = ();; let main () = (* win2 men1 men2 men3; *) ignore(Glut.init Sys.argv); if (0 <> Glut.getMenu()) then failwith("current menu wrong, should be zero\n"); if (0 <> Glut.getWindow()) then failwith("current window wrong, should be zero\n"); Glut.initWindowSize 140 140; (* Make sure initial Glut. init display mode is right. *) if (Glut.get(Glut.INIT_DISPLAY_MODE) <> (Glut.rgba lor Glut.single lor Glut.depth)) then failwith(" init display mode wrong\n"); Glut.initDisplayMode ~double_buffer:false ~alpha:false ~stencil:true (); if (Glut.get(Glut.INIT_DISPLAY_MODE) <> (Glut.rgba lor Glut.single lor Glut.stencil)) then failwith(" display mode wrong\n"); (* Interesting : creating menu before creating windows. *) let men1 = Glut.createMenu(menuSelect) in (* Make sure Glut.createMenu doesn't change init display mode. *) if (Glut.get(Glut.INIT_DISPLAY_MODE) <> (Glut.rgba lor Glut.single lor Glut.stencil)) then failwith(" display mode changed\n"); if (men1 <> Glut.getMenu()) then failwith(" current menu wrong\n"); Glut.addMenuEntry "hello" 1; Glut.addMenuEntry "bye" 2; Glut.addMenuEntry "yes" 3; Glut.addMenuEntry "no" 4; Glut.addSubMenu "submenu" 5; let win1 = Glut.createWindow("test24") in Glut.displayFunc(display); if (win1 <> Glut.getWindow()) then failwith(" current window wrong\n"); if (men1 <> Glut.getMenu()) then failwith(" current menu wrong\n"); let men2 = Glut.createMenu(menuSelect) in Glut.addMenuEntry "yes" 3; Glut.addMenuEntry "no" 4; Glut.addSubMenu "submenu" 5; (* Make sure Glut.createMenu doesn't change init display mode. *) if (Glut.get(Glut.INIT_DISPLAY_MODE) <> (Glut.rgba lor Glut.single lor Glut.stencil)) then failwith(" display mode changed\n"); if (men2 <> Glut.getMenu()) then failwith(" current menu wrong\n"); if (win1 <> Glut.getWindow()) then failwith(" current window wrong\n"); let win2 = Glut.createWindow("test24 second") in Glut.displayFunc(display); if (win2 <> Glut.getWindow()) then failwith(" current window wrong\n"); Glut.destroyWindow(win2); if (0 <> Glut.getWindow()) then failwith(" current window wrong should be zero\n"); let men3 = Glut.createMenu(menuSelect) in Glut.addMenuEntry "no" 4; Glut.addSubMenu "submenu" 5; if (Glut.get(Glut.INIT_DISPLAY_MODE) <> (Glut.rgba lor Glut.single lor Glut.stencil)) then failwith(" display mode changed\n"); Glut.destroyMenu(men3); if (0 <> Glut.getMenu()) then failwith(" current menu wrong should be zero\n"); Glut.timerFunc(2 * 1000) timer 23; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test25.ml000077500000000000000000000067241437514534100221070ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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 tests Glut.bitmapLength and Glut.strokeLength. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 2002. *) open Printf let abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" let null = "" let space = " " let bitmap_fonts = [| Glut.BITMAP_TIMES_ROMAN_24 ; Glut.BITMAP_TIMES_ROMAN_10 ; Glut.BITMAP_9_BY_15 ; Glut.BITMAP_8_BY_13 ; Glut.BITMAP_HELVETICA_10 ; Glut.BITMAP_HELVETICA_12 ; Glut.BITMAP_HELVETICA_18 |] let bitmap_names = [| "Times Roman 24" ; "Times Roman 10" ; "9 by 15" ; "8 by 13" ; "Helvetica 10" ; "Helvetica 12" ; "Helvetica 18" |] let bitmap_lens = [| 2399 ; 1023 ; 2016 ; 1792 ; 1080 ; 1291 ; 1895 |] let bitmap_abc_lens = [| 713 ; 305 ; 468 ; 416 ; 318 ; 379 ; 572 |] let stroke_fonts = [| Glut.STROKE_ROMAN ; Glut.STROKE_MONO_ROMAN |] let stroke_names = [| "Roman" ; "Monospaced Roman" |] let stroke_lens = [| 6635 ; 9984 |] let stroke_abc_lens = [| 3683 ; 5408 |] (* apply the given function to values of [i] running from 0 to the length of the array [a] minus one *) let array_do a f = for i = 0 to ((Array.length a)-1) do f i done let (+=) x y = x := !x + y;; (* :) *) let main () = ignore(Glut.init Sys.argv); (* Touch test the width determination of all bitmap characters. *) array_do bitmap_fonts (fun i -> let font = bitmap_fonts.(i) and total = ref 0 in for j = -2 to 258 do total := !total + Glut.bitmapWidth font j done; printf " %s: bitmap total = %d (expected %d)" bitmap_names.(i) !total bitmap_lens.(i); print_newline(); if !total <> bitmap_lens.(i) then failwith " test25\n"; ); (* Touch test the width determination of all stroke characters. *) (* for i = 0 to ((Array.length stroke_fonts)-1) do *) array_do stroke_fonts (fun i -> let font = stroke_fonts.(i) and total = ref 0 in for j = -1 to 258 do total += Glut.strokeWidth font j done; printf " %s: stroke total = %d (expected %d)\n" stroke_names.(i) !total stroke_lens.(i); if !total <> stroke_lens.(i) then failwith(" test25\n"); ); array_do bitmap_fonts (fun i -> let font = bitmap_fonts.(i) in let total = Glut.bitmapLength font abc in printf " %s: bitmap abc len = %d (expected %d)\n" bitmap_names.(i) total bitmap_abc_lens.(i); if total <> bitmap_abc_lens.(i) then failwith " test25\n"; ); array_do bitmap_fonts (fun i -> let font = bitmap_fonts.(i) in let total = Glut.bitmapLength font "" in printf " %s: bitmap abc len = %d (expected %d)\n" bitmap_names.(i) total 0; if total <> 0 then failwith " test25\n"; ); array_do stroke_fonts (fun i -> let font = stroke_fonts.(i) in let total = Glut.strokeLength font abc in printf " %s: stroke abc len = %d (expected %d)\n" stroke_names.(i) total stroke_abc_lens.(i); if (total <> stroke_abc_lens.(i)) then failwith " test25\n"; ); array_do stroke_fonts (fun i -> let font = stroke_fonts.(i) in let total = Glut.strokeLength font "" in printf " %s: stroke null len = %d (expected %d)\n" stroke_names.(i) total 0; if total <> 0 then failwith " test25\n"; ); printf("PASS: test25\n"); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test26.ml000077500000000000000000000067631437514534100221130ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21:18:42 MDT 2002. *) open Printf (* 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. *) (* Test for Glut.postWindowRedisplay and Glut.postWindowOverlayRedisplay introduced with GLUT 4 API. *) let window1 = ref(-1);; let window2 = ref(-1);; let win1displayed = ref 0;; let win2displayed = ref 0;; let win1vis = ref Glut.NOT_VISIBLE;; let win2vis = ref Glut.NOT_VISIBLE;; (* let win1vis = ref false;; let win2vis = ref false;; *) let overlaySupported = ref false;; let over1displayed = ref 0;; let checkifdone () = if ((!win1displayed > 15) && (!win2displayed > 15) && ((not !overlaySupported) || !over1displayed>15)) then begin printf("PASS -> test26\n"); exit(0); end ;; let window1display () = if (Glut.getWindow() <> !window1) then failwith(" window1display\n"); GlClear.color (0.0, 1.0, 0.0); GlClear.clear [`color]; Gl.flush(); incr win1displayed; checkifdone(); ;; let overDisplay () = GlClear.clear [`color]; GlDraw.rect (-0.5, -0.5) (0.5, 0.5); Gl.flush(); incr over1displayed; checkifdone(); ;; let window2display () = if (Glut.getWindow() <> !window2) then failwith(" window2display\n"); GlClear.color (0.0, 0.0, 1.0); GlClear.clear [`color]; Glut.swapBuffers(); incr win2displayed; checkifdone(); ;; let timefunc ~value = failwith(" test26\n") ;; let count = ref 0;; let idle () = if (!count mod 2 <> 0) then begin Glut.postWindowRedisplay(!window1); Glut.postWindowRedisplay(!window2); end else begin Glut.postWindowRedisplay(!window2); Glut.postWindowRedisplay(!window1); end; if (!overlaySupported) then Glut.postWindowOverlayRedisplay(!window1); incr count; ;; let window1vis ~state = win1vis := state ; (* if (!win1vis <> Glut.NOT_VISIBLE && !win2vis <> Glut.NOT_VISIBLE) then *) if (!win1vis <> Glut.NOT_VISIBLE && !win2vis <> Glut.NOT_VISIBLE) then Glut.idleFunc(Some idle) ;; let window2status ~state = win2vis := if (state = Glut.FULLY_RETAINED) || (state = Glut.PARTIALLY_RETAINED) then Glut.VISIBLE else Glut.NOT_VISIBLE; if (!win1vis <> Glut.NOT_VISIBLE && !win2vis <> Glut.NOT_VISIBLE) then Glut.idleFunc(Some idle); ;; let main () = ignore(Glut.init Sys.argv); Glut.initWindowSize 100 100 ; Glut.initWindowPosition 50 100 ; Glut.initDisplayMode ~double_buffer:false ~alpha:false (); window1 := Glut.createWindow("1"); Glut.displayFunc(window1display); Glut.visibilityFunc(window1vis); Glut.initDisplayMode ~double_buffer:false ~index:true (); overlaySupported := Glut.layerGet Glut.OVERLAY_POSSIBLE; if (!overlaySupported) then begin printf("testing Glut.postWindowOverlayRedisplay since overlay supported\n"); Glut.establishOverlay(); Glut.overlayDisplayFunc(overDisplay); let transP = Glut.layerGetTransparentIndex() in GlClear.index (float_of_int(Glut.layerGetTransparentIndex())); let opaqueP = (transP + 1) mod Glut.get(Glut.WINDOW_COLORMAP_SIZE) in Glut.setColor opaqueP 1.0 0.0 0.0 ; end; Glut.initWindowPosition 250 100 ; Glut.initDisplayMode ~double_buffer:true ~alpha:false (); window2 := Glut.createWindow("2"); Glut.displayFunc(window2display); Glut.windowStatusFunc(window2status); Glut.timerFunc 9000 timefunc 1 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test27.ml000077500000000000000000000041261437514534100221030ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21 -> 18 -> 43 MDT 2002. *) open Printf (* 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 tests creation of a subwindow that gets "popped" to check if it also (erroneously) gets moved. GLUT 3.5 had this bug (fixed in GLUT 3.6). *) let parent = ref 0;; let child = ref 0;; let parentDrawn = ref false;; let childDrawn = ref false;; let failTest ~value = failwith(" test27\n") ;; let passTest ~value = printf("PASS -> test27\n"); exit(0); ;; let installFinish () = if (!childDrawn && !parentDrawn) then Glut.timerFunc 1000 passTest 0 ; ;; let output ~x ~y ~str = GlPix.raster_pos ~x ~y (); let len = (String.length str) in for i = 0 to (len-1) do Glut.bitmapCharacter Glut.BITMAP_9_BY_15 (int_of_char str.[i]) ; done ;; let displayParent () = GlClear.clear [`color]; Gl.flush(); parentDrawn := true; installFinish(); ;; let displayChild () = GlClear.clear [`color]; output(-0.4) (0.5) "this"; output(-0.8) (0.1) "subwindow"; output(-0.8) (-0.3) "should be"; output(-0.7) (-0.7) "centered"; Gl.flush(); childDrawn := true; installFinish(); ;; let main () = ignore(Glut.init Sys.argv); Glut.initWindowSize 300 300 ; Glut.initWindowPosition 5 5 ; Glut.initDisplayMode ~alpha:false (); parent := Glut.createWindow("test27"); GlClear.color (1.0, 0.0, 0.0); Glut.displayFunc(displayParent); let possible = Glut.getBool Glut.DISPLAY_MODE_POSSIBLE in if not possible then failwith(sprintf " Glut.get returned display mode not possible -> %d\n" (if possible then 1 else 0)); child := Glut.createSubWindow ~win:!parent ~x:100 ~y:100 ~w:100 ~h:100 ; GlClear.color (0.0, 1.0, 0.0); GlDraw.color (0.0, 0.0, 0.0); Glut.displayFunc(displayChild); Glut.popWindow(); Glut.timerFunc 10000 failTest 0 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test28.ml000077500000000000000000000017741437514534100221120ustar00rootroot00000000000000#!/usr/bin/env lablglut open Printf (* 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. *) (* ported to lablglut by Issac Trotts on August 6, 2002 *) let fake_argv = [| "program" ; "-iconic"; |];; let displayed = ref false;; let display () = printf "display\n"; print_newline(); GlClear.clear [`color]; Glut.swapBuffers(); displayed := true; ;; let timer ~value = printf "timer\n"; print_newline(); if (!displayed) then failwith(" test28\n"); printf("PASS -> test28\n"); exit(0); ;; let main () = ignore (Glut.init fake_argv); if ((Array.length Sys.argv) <> 1) then failwith(" argument processing\n"); Glut.initDisplayMode ~double_buffer:true ~alpha:false (); ignore (Glut.createWindow("test28")); Glut.displayFunc(display); Glut.timerFunc 2000 timer 0 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test3.ml000077500000000000000000000034351437514534100220170ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. Ported to lablglut by Issac Trotts on Aug 5, 2002. *) open Printf let n = 6;; let m = 6;; let exposed = Array.create (m*n) false;; let ecount = ref 0;; let viewable = Array.create (m*n) false;; let vcount = ref 0;; let display () = let win = Glut.getWindow() - 1 in if not exposed.(win) then begin exposed.(win) <- true; incr ecount; end; GlClear.clear [`depth]; Gl.flush(); if (!ecount == (m * n)) && (!vcount == (m * n)) then begin printf("PASS: test3\n"); exit(0); end ;; let view ~state = let win = Glut.getWindow() - 1 in if not viewable.(win) then begin viewable.(win) <- true; incr vcount; end; if ((!ecount == (m * n)) && (!vcount == (m * n))) then begin printf("PASS: test3\n"); exit(0); end ;; let timer ~value = if (value <> 23) then failwith "bad timer value";; let main () = ignore(Glut.init Sys.argv); Glut.initWindowSize 10 10 ; Glut.initDisplayMode ~double_buffer:false ~alpha:false (); for i = 0 to (m - 1) do for j = 0 to (n - 1) do exposed.(i * n + j) <- false; viewable.(i * n + j) <- false; Glut.initWindowPosition (100 * i) (100 * j); ignore(Glut.createWindow(sprintf "%d\n" (i*n + j + 1))); Glut.displayFunc display ; Glut.visibilityFunc view ; GlClear.color ~alpha:1.0 (1.0, 0.0, 0.0) ; done done; (* XXX Hopefully in 45 seconds, all the windows should appear, or they probably won't ever appear! *) Glut.timerFunc (45 * 1000) timer 23; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test4.ml000077500000000000000000000025001437514534100220100ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. Ported to lablglut by Issac Trotts on Aug 5, 2002. *) open Printf;; let ch = ref(-2);; let font = ref Glut.STROKE_ROMAN;; let tick () = incr ch; if (!ch > 180) then begin if (!font == Glut.STROKE_MONO_ROMAN) then begin printf("PASS: test4\n"); exit(0); end ch := -2; font := Glut.STROKE_MONO_ROMAN; end; Glut.postRedisplay(); ;; let mytick () = ();; let display () = GlClear.clear [`color]; GlMat.push (); Glut.strokeCharacter !font !ch ; GlMat.pop (); Glut.swapBuffers(); ;; let main() = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~double_buffer:true ~alpha:false (); Glut.initWindowSize 200 200 ; ignore(Glut.createWindow "Test stroke fonts"); Glut.idleFunc (Some tick); if (Glut.get(Glut.WINDOW_COLORMAP_SIZE) <> 0) then failwith "bad RGBA colormap size"; GlMat.mode `projection; GlMat.load_identity(); GluMat.ortho2d (-50.0, 150.0) (-50.0, 150.0); GlClear.color (0.0, 0.0, 0.0); GlDraw.color (1.0, 1.0, 1.0); Glut.displayFunc(display); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test7.ml000077500000000000000000000102421437514534100220150ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* ported to lablglut by Issac Trotts on August 6, 2002 *) open Printf let w1 = ref 0;; let w2 = ref 0;; let display () = GlClear.clear [`color] ;; let time9 ~value = if (value <> 9) then failwith(" time9 expected 9\n"); printf("PASS -> test7\n"); exit(0); ;; let time8 ~value = if (value <> 8) then failwith(" time8 expected 8\n"); printf("window 1 to 350x250+20+200; window 2 to 50x150+50+50\n"); Glut.setWindow(!w1); Glut.reshapeWindow 350 250 ; Glut.positionWindow 20 200 ; Glut.setWindow(!w2); Glut.reshapeWindow 50 150 ; Glut.positionWindow 50 50 ; Glut.timerFunc 1000 time9 9 ; ;; let time7 ~value = if (value <> 7) then failwith(" time7 expected 7\n"); printf("window 1 fullscreen; window 2 popped on top\n"); Glut.setWindow(!w1); Glut.showWindow(); Glut.fullScreen(); Glut.setWindow(!w2); Glut.showWindow(); Glut.popWindow(); (* It can take a long time for Glut.fullScreen to really happen on a Windows 95 PC. I believe this has to do with the memory overhead for resizing a huge soft color and/or ancillary buffers. *) Glut.timerFunc 6000 time8 8 ; ;; let time6 ~value = if (value <> 6) then failwith(" time6 expected 6\n"); printf("change icon tile for both windows\n"); Glut.setWindow(!w1); Glut.setIconTitle("icon1"); Glut.setWindow(!w2); Glut.setIconTitle("icon2"); Glut.timerFunc 1000 time7 7 ; ;; let time5 ~value = if (value <> 5) then failwith(" time5 expected 5\n"); Glut.setWindow(!w1); let wx = Glut.get(Glut.WINDOW_X) and wy = Glut.get(Glut.WINDOW_Y) in printf "window x = %i, y = %i\n" wx wy; if (wx <> 20) then printf("WARNING: x position expected to be 20\n"); if (wy <> 20) then printf("WARNING: y position expected to be 20\n"); if (Glut.get(Glut.WINDOW_WIDTH) <> 250) then printf("WARNING: width expected to be 250\n"); if (Glut.get(Glut.WINDOW_HEIGHT) <> 250) then printf("WARNING: height expected to be 250\n"); Glut.setWindow(!w2); if (Glut.get(Glut.WINDOW_X) <> 250) then printf("WARNING: x position expected to be 250\n"); if (Glut.get(Glut.WINDOW_Y) <> 250) then printf("WARNING: y position expected to be 250\n"); if (Glut.get(Glut.WINDOW_WIDTH) <> 150) then printf("WARNING: width expected to be 150\n"); if (Glut.get(Glut.WINDOW_HEIGHT) <> 150) then printf("WARNING: height expected to be 150\n"); printf("iconify both windows\n"); Glut.setWindow(!w1); Glut.iconifyWindow(); Glut.setWindow(!w2); Glut.iconifyWindow(); Glut.timerFunc 1000 time6 6 ; ;; let time4 ~value = if (value <> 4) then failwith(" time4 expected 4\n"); printf("reshape and reposition window\n"); Glut.setWindow(!w1); Glut.reshapeWindow 250 250 ; Glut.positionWindow 20 20 ; Glut.setWindow(!w2); Glut.reshapeWindow 150 150 ; Glut.positionWindow 250 250 ; Glut.timerFunc 1000 time5 5 ; ;; let time3 ~value = if (value <> 3) then failwith(" time3 expected 3\n"); printf("show both windows again\n"); Glut.setWindow(!w1); Glut.showWindow(); Glut.setWindow(!w2); Glut.showWindow(); Glut.timerFunc 1000 time4 4 ; ;; let time2 ~value = if (value <> 2) then failwith(" time2 expected 2\n"); printf("hiding w1; iconify w2\n"); Glut.setWindow(!w1); Glut.hideWindow(); Glut.setWindow(!w2); Glut.iconifyWindow(); Glut.timerFunc 1000 time3 3 ; ;; let time1 ~value = if (value <> 1) then failwith(" time1 expected 1\n"); printf("changing window titles\n"); Glut.setWindow(!w1); Glut.setWindowTitle("changed title"); Glut.setWindow(!w2); Glut.setWindowTitle("changed other title"); Glut.timerFunc 2000 time2 2 ; ;; let main () = Glut.initWindowPosition 20 20 ; ignore(Glut.init Sys.argv); w1 := Glut.createWindow("test 1"); Glut.displayFunc(display); Glut.initWindowPosition 200 200 ; w2 := Glut.createWindow("test 2"); Glut.displayFunc(display); Glut.timerFunc 1000 time1 1 ; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test8.ml000077500000000000000000000076321437514534100220270ustar00rootroot00000000000000#!/usr/bin/env lablglut (* 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. *) (* Ported to lablglut by Issac Trotts on Sat Aug 10 13:41:20 MDT 2002. *) open Printf let main_w = ref(-1) let w = [| 0; 0; 0; 0 |] let win = ref(-1) let num = ref(-1) let fail_childnum () = failwith(sprintf " Glut.get returned wrong # children: %d\n" !num) let fail_bad_parent () = failwith(sprintf " Glut.get returned bad parent: %d\n" !num) let time2 ~value = printf "PASS: test8\n"; exit 0; ;; let time1 ~value = Glut.setWindow w.(1); Glut.idleFunc None; Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.setWindow w.(0); Glut.idleFunc None; Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.setWindow !main_w; Glut.idleFunc None; (* redundant *) Glut.keyboardFunc (fun ~key ~x ~y -> ()); Glut.destroyWindow w.(1); Glut.destroyWindow w.(0); Glut.destroyWindow !main_w; Glut.timerFunc 500 time2 0; ;; let display () = ();; let main () = ignore(Glut.init Sys.argv); if Glut.get Glut.INIT_WINDOW_WIDTH <> 300 then failwith " init width wrong"; if Glut.get Glut.INIT_WINDOW_HEIGHT <> 300 then failwith " init height wrong"; if Glut.get Glut.INIT_WINDOW_X <> -1 then failwith " init x wrong"; if Glut.get Glut.INIT_WINDOW_Y <> -1 then failwith " init y wrong"; if Glut.get Glut.INIT_DISPLAY_MODE <> Glut.rgba lor Glut.single lor Glut.depth then failwith " init display mode wrong"; Glut.initDisplayMode (); main_w := Glut.createWindow "main"; Glut.displayFunc display; num := if Glut.getBool Glut.DISPLAY_MODE_POSSIBLE then 1 else 0; if !num <> 1 then failwith (sprintf "Glut.get returned display mode not possible: %d\n" !num); num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 0 <> !num then failwith " Glut.get returned wrong # children: %d\n" !num; w.(0) <- Glut.createSubWindow !main_w 10 10 20 20; Glut.displayFunc display; num := Glut.get Glut.WINDOW_PARENT; if !main_w <> !num then fail_bad_parent(); Glut.setWindow !main_w; num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 1 <> !num then fail_childnum(); w.(1) <- Glut.createSubWindow !main_w 40 10 20 20; Glut.displayFunc display; num := Glut.get Glut.WINDOW_PARENT; if !main_w <> !num then fail_bad_parent(); Glut.setWindow !main_w; num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 2 <> !num then fail_childnum(); w.(2) <- Glut.createSubWindow !main_w 10 40 20 20; Glut.displayFunc display; num := Glut.get Glut.WINDOW_PARENT; if !main_w <> !num then fail_bad_parent(); Glut.setWindow !main_w; num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 3 <> !num then fail_childnum(); w.(3) <- Glut.createSubWindow !main_w 40 40 20 20; Glut.displayFunc display; num := Glut.get Glut.WINDOW_PARENT; if !main_w <> !num then fail_bad_parent(); Glut.setWindow !main_w; num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 4 <> !num then fail_childnum(); Glut.destroyWindow w.(3); num := Glut.get Glut.WINDOW_NUM_CHILDREN; if 3 <> !num then fail_childnum(); w.(3) <- Glut.createSubWindow !main_w 40 40 20 20; Glut.displayFunc display; ignore(Glut.createSubWindow w.(3) 40 40 20 20); Glut.displayFunc display; ignore(Glut.createSubWindow w.(3) 40 40 20 20); Glut.displayFunc display; win := Glut.createSubWindow w.(3) 40 40 20 20; Glut.displayFunc display; ignore(Glut.createSubWindow !win 40 40 20 20); Glut.displayFunc display; win := Glut.createSubWindow w.(3) 40 40 20 20; Glut.displayFunc display; ignore(Glut.createSubWindow !win 40 40 20 20); Glut.displayFunc display; Glut.destroyWindow w.(3); w.(3) <- Glut.createSubWindow !main_w 40 40 20 20; Glut.displayFunc display; Glut.timerFunc 500 time1 0; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/test9.ml000077500000000000000000000063251437514534100220260ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21 -> 18 -> 47 MDT 2002. *) open Printf (* 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. *) let main_w = ref 0;; let w1 = ref 0;; let w2 = ref 0;; let w3 = ref 0;; let w4 = ref 0;; let display () = GlClear.clear [`color]; Glut.swapBuffers(); ;; let time8 ~value = printf("PASS -> test9\n"); exit(0); ;; let time7 ~value = Glut.destroyWindow(!main_w); Glut.timerFunc 500 time8 0 ; ;; let time6 ~value = Glut.destroyWindow(!w1); Glut.timerFunc 500 time7 0 ; Glut.initDisplayMode ~index:true (); if not (Glut.getBool Glut.DISPLAY_MODE_POSSIBLE) then begin printf("UNRESOLVED : test9 (your OpenGL lacks color index support)\n"); exit(0); end; w1 := Glut.createSubWindow !main_w 10 10 10 10 ; Glut.displayFunc(display); w2 := Glut.createSubWindow !w1 10 10 30 30 ; Glut.displayFunc(display); w3 := Glut.createSubWindow !w2 10 10 50 50 ; Glut.displayFunc(display); Glut.initDisplayMode ~alpha:false (); w4 := Glut.createSubWindow !w3 10 10 70 70 ; GlClear.color (1.0,1.0,1.0); Glut.displayFunc(display); ;; let time5 ~value = w1 := Glut.createSubWindow !main_w 10 10 10 10 ; Glut.displayFunc(display); w2 := Glut.createSubWindow !w1 10 10 30 30 ; Glut.displayFunc(display); w3 := Glut.createSubWindow !w2 10 10 50 50 ; Glut.displayFunc(display); Glut.initDisplayMode ~alpha:false (); w4 := Glut.createSubWindow !w3 10 10 70 70 ; GlClear.color (1.0, 1.0, 1.0) ; Glut.displayFunc(display); Glut.timerFunc 500 time6 0 ; ;; let time4 ~value = Glut.destroyWindow(!w4); Glut.timerFunc 500 time5 0; ;; let time3 ~value = Glut.destroyWindow(!w3); Glut.timerFunc 500 time4 0; ;; let time2 ~value = Glut.destroyWindow(!w2); Glut.timerFunc 500 time3 0; ;; let time1 ~value = Glut.destroyWindow(!w1); Glut.timerFunc 500 time2 0; ;; let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:false (); main_w := Glut.createWindow("test9"); GlClear.color (0.0, 0.0, 0.0); Glut.displayFunc(display); Glut.initDisplayMode ~index:true (); if not (Glut.getBool Glut.DISPLAY_MODE_POSSIBLE) then begin printf("UNRESOLVED -> test9 (your OpenGL lacks color index support)\n"); exit(0); end; w1 := Glut.createSubWindow !main_w 10 10 10 10 ; Glut.setColor 1 1.0 0.0 0.0 ; (* red *) Glut.setColor 2 0.0 1.0 0.0 ; (* green *) Glut.setColor 3 0.0 0.0 1.0 ; (* blue *) GlClear.index 1.0; Glut.displayFunc(display); w2 := Glut.createSubWindow !main_w 30 30 10 10; Glut.copyColormap(!w1); GlClear.index 2.0; Glut.displayFunc(display); w3 := Glut.createSubWindow !main_w 50 50 10 10; Glut.copyColormap(!w1); GlClear.index 3.0; Glut.displayFunc(display); w4 := Glut.createSubWindow !main_w 70 70 10 10; Glut.copyColormap(!w1); Glut.setColor 3 1.0 1.0 1.0; (* white *) GlClear.index 3.0; Glut.displayFunc(display); Glut.timerFunc 750 time1 0; Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/test/timer_test.ml000077500000000000000000000041151437514534100231300ustar00rootroot00000000000000#!/usr/bin/env lablglut (* Ported to lablglut by Issac Trotts on Tue Aug 6 21 -> 18 -> 48 MDT 2002. *) #load "unix.cma" open Printf (* 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. *) (* timer_test is supposed to demonstrate that window system event related callbacks (like the keyboard callback) do not "starve out" the dispatching of timer callbacks. Run this program and hold down the space bar. The correct behavior (assuming the system does autorepeat) is interleaved "key is 32" and "timer called" messages. If you don't see "timer called" messages that's a problem. This problem exists in GLUT implementations through GLUT 3.2. *) let display () = GlClear.clear [`color]; Gl.flush(); ;; let rec timer1 ~value = printf "timer %d called\n" value ; print_newline(); Glut.timerFunc 500 timer1 value ; ;; let rec timer2 ~value = printf "timer %d called\n" value ; print_newline(); Glut.timerFunc 1000 timer2 value ; ;; let num_times = ref 0;; let keyboard ~key ~x ~y = if (!num_times = 0) then Glut.timerFunc 500 timer1 1 ; if (!num_times = 0) then Glut.timerFunc 1000 timer2 2 ; incr num_times; if !num_times = 5 then exit 0; printf "key is %d\n" key ; print_newline(); if key = 27 then exit 0; (* esc *) Unix.sleep(1); ;; let main () = printf "\n== timer test ==\n\n"; printf "Please the spacebar.\n" ; printf "The correct behavior (assuming the system does autorepeat)\n" ; printf "is \"key is 32\" and then \"timer X called\" messages\n" ; printf "with X = 1 or 2 and about two 1 for one 2.\n" ; printf "If you don't see \"timer X called\" messages that's a problem.\n\n" ; printf "Press \"Esc\" to quit\n" ; print_newline(); ignore(Glut.init Sys.argv); ignore(Glut.createWindow("timer test")); GlClear.color (0.49, 0.62, 0.75); Glut.displayFunc(display); Glut.keyboardFunc(keyboard); Glut.mainLoop(); ;; let _ = main();; lablgl-1.07/LablGlut/examples/glut3.7/trackball/000077500000000000000000000000001437514534100213735ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/glut3.7/trackball/Makefile000066400000000000000000000006051437514534100230340ustar00rootroot00000000000000INCLDIRS = -I +lablGL -I +lablglut teaspin: trackball.cmi trackball.cmo teaspin.cmo ocamlc $(INCLDIRS) -o teaspin lablgl.cma lablglut.cma trackball.cmo teaspin.cmo teaspin.cmo: teaspin.ml ocamlc $(INCLDIRS) -c teaspin.ml trackball.cmi: trackball.mli ocamlc $(INCLDIRS) -c trackball.mli trackball.cmo: trackball.ml ocamlc $(INCLDIRS) -c trackball.ml clean: rm *.cm* teaspin lablgl-1.07/LablGlut/examples/glut3.7/trackball/teaspin.ml000066400000000000000000000115611437514534100233740ustar00rootroot00000000000000open Printf (* Original program 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. *) (* Adapted and ported to lablglut by Issac Trotts on Sun Sep 1 2002. *) let spinning = ref false and moving = ref false and scaling = ref false and xlating = ref false and beginx = ref 0 and beginy = ref 0 and w = ref 300 and h = ref 300 and curquat = ref (Trackball.trackball (0.0,0.0) (0.0,0.0)) and lastquat = ref (Trackball.unit_quat()) and newModel = ref true and scalefactor = ref 1.0 let f2i f = int_of_float f let i2f i = float_of_int i let recalcModelView () = GlMat.pop(); GlMat.push(); let m = Trackball.build_rotmatrix !curquat in GlMat.mult m ; GlMat.scale ~x:!scalefactor ~y:!scalefactor ~z:!scalefactor (); newModel := false; ;; let showMessage x y z message = GlMat.push(); Gl.disable `lighting; GlMat.translate ~x ~y ~z (); GlMat.scale ~x:0.005 ~y:0.005 ~z:0.005 (); String.iter (function c->Glut.strokeCharacter Glut.STROKE_ROMAN (int_of_char c)) message; Gl.enable `lighting ; GlMat.pop(); ;; let redraw () = if (!newModel) then recalcModelView(); GlClear.clear [`color; `depth]; Glut.solidTeapot 1.0 ; showMessage 0.0 1.0 0.0 "Spin me."; Glut.swapBuffers(); ;; let update_wh w' h' = w := w'; h := h'; ;; let myReshape ~w ~h = printf "reshape\n"; GlDraw.viewport ~x:0 ~y:0 ~w ~h; update_wh w h; ;; let mouse ~button ~state ~x ~y = if (button = Glut.LEFT_BUTTON && state = Glut.DOWN) then begin spinning := false; Glut.idleFunc (Some (function () -> ())); moving := true; beginx := x; beginy := y; scaling := if (Glut.getModifiers() land Glut.active_shift <> 0) then true else false; end; if (button = Glut.LEFT_BUTTON && state = Glut.UP) then moving := false; ;; let animate () = curquat := Trackball.add_quats !lastquat !curquat ; newModel := true; Glut.postRedisplay(); ;; let motion ~x ~y = if (!scaling) then begin scalefactor := !scalefactor *. (1.0 +. ((float_of_int(!beginy - y)) /. (float_of_int !h))); beginx := x; beginy := y; newModel := true; Glut.postRedisplay(); end else if (!moving) then begin let x0 = i2f !beginx and y0 = i2f !beginy and w = i2f !w and h = i2f !h in lastquat := Trackball.trackball ~p1:((2.0 *. x0 -. w) /. w, (h -. 2.0 *. y0) /. h) ~p2:((2.0 *. (i2f x) -. w) /. w, (h -. 2.0 *. (i2f y)) /. h); beginx := x; beginy := y; spinning := true; Glut.idleFunc(Some animate); end ;; let lightZeroSwitch = ref true and lightOneSwitch = ref true let controlLights ~value = match value with | 1 -> begin lightZeroSwitch := not !lightZeroSwitch; if (!lightZeroSwitch) then Gl.enable `light0 else Gl.disable `light0 end | 2 -> begin lightOneSwitch := not !lightOneSwitch; if (!lightOneSwitch) then Gl.enable `light1 else Gl.disable `light1 end (* #ifdef GL_MULTISAMPLE_SGIS | 3 -> if (glIsEnabled(GL_MULTISAMPLE_SGIS)) then glDisable(GL_MULTISAMPLE_SGIS); } else { glEnable(GL_MULTISAMPLE_SGIS); break; #endif *) | 4 -> Glut.fullScreen() | 5 -> exit(0) | _ -> (); Glut.postRedisplay(); ;; let vis ~state = if state = Glut.VISIBLE then begin if !spinning then Glut.idleFunc(Some animate); end else if !spinning then Glut.idleFunc(Some (function () -> ())); ;; let main() = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:false ~double_buffer:true ~depth:true ~multisample:true (); ignore(Glut.createWindow "teaspin"); Glut.displayFunc redraw; Glut.reshapeFunc myReshape; Glut.visibilityFunc vis; Glut.mouseFunc mouse; Glut.motionFunc motion; ignore(Glut.createMenu controlLights); Glut.addMenuEntry "Toggle right light" 1; Glut.addMenuEntry "Toggle left light" 2; (* if Glut.get Glut.WINDOW_NUM_SAMPLES > 0 then begin Glut.addMenuEntry "Toggle multisampling" 3; Glut.setWindowTitle "teaspin (multisample capable)"; end *) Glut.addMenuEntry "Full screen" 4; Glut.addMenuEntry "Quit" 5; Glut.attachMenu Glut.RIGHT_BUTTON; (* Gl.enable `cull_face; *) GlMat.mode `projection; GluMat.perspective ~fovy:40.0 ~aspect:1.0 ~z:(1.0, 40.0) ; GlMat.mode `modelview; GluMat.look_at ~eye:(0.0,0.0,10.0) ~center:(0.0,0.0,0.0) ~up:(0.0,1.0,0.0); GlMat.push(); (* dummy push so we can pop on model recalc *) List.iter Gl.enable [`lighting; `light0; `light1; `depth_test ]; GlLight.light ~num:0 (`diffuse (0.9, 0.3, 0.3, 1.0)) ; GlLight.light ~num:0 (`position (1.0, 1.0, 1.0, 1.0)) ; GlLight.light ~num:1 (`diffuse (0.3, 0.2, 0.9, 1.0)) ; GlLight.light ~num:1 (`position (-1.0, -1.0, 1.0, 1.0)) ; GlDraw.line_width 2.0; Glut.mainLoop(); ;; let _ = main() lablgl-1.07/LablGlut/examples/glut3.7/trackball/trackball.ml000066400000000000000000000170571437514534100236760ustar00rootroot00000000000000open Printf type vec = { x:float; y:float; z:float } type quat = { v:vec ; w:float } let as_tuple v = v.x, v.y, v.z (* * 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. *) let trackballsize = 0.8 (* * Local function prototypes (not defined in trackball.h) *) let vzero = (0.0, 0.0, 0.0) (* vector subtract *) let (-^) a b = { x=a.x-.b.x; y=a.y-.b.y; z=a.z-.b.z; } (* vector add *) let (+^) a b = { x=a.x+.b.x; y=a.y+.b.y; z=a.z+.b.z; } (* cross product *) let (^^) a b = { x=a.y *. b.z -. a.z *. b.y; y=a.z *. b.x -. a.x *. b.z; z=a.x *. b.y -. a.y *. b.x } let vlength v = sqrt (v.x *. v.x +. v.y *. v.y +. v.z *. v.z) let vscale s v = { x=s *. v.x; y=s *. v.y; z=s *. v.z } let vnormal v = vscale (1.0 /. (vlength v)) v (* dot product *) let (^.^) a b = a.x *. b.x +. a.y *. b.y +. a.z *. b.z (* * 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. *) let tb_project_to_sphere r x y = let d = sqrt(x*.x +. y*.y) in let z = if (d < r *. 0.70710678118654752440) then (* Inside sphere *) sqrt(r*.r -. d*.d) else begin (* On hyperbola *) let t = r /. 1.41421356237309504880 in t*.t /. d end in z ;; (* * Given an axis and angle compute quaternion. *) let axis_to_quat ~axis ~phi = let ax = match axis with x,y,z-> {x=x; y=y; z=z} in let sax = vscale (sin (phi/.2.0)) (vnormal ax) in { v=sax; w=(cos (phi /. 2.0)) } ;; (* * 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) *) let trackball ~p1 ~p2 = match p1 with p1x, p1y -> match p2 with p2x, p2y -> if (p1 = p2) then (* zero rotation *) { v={x=0.0; y=0.0; z=0.0}; w=1.0 } else begin (* * First figure out z-coordinates for projection of P1 and P2 to * deformed sphere *) let pp1 = {x=p1x; y=p1y; z=(tb_project_to_sphere trackballsize p1x p1y) } in let pp2 = {x=p2x; y=p2y; z=(tb_project_to_sphere trackballsize p2x p2y) } in let ax = pp2 ^^ pp1 in (* cross product *) (* Figure out how much to rotate around that axis. *) let d = pp1 -^ pp2 in let t = (vlength d) /. (2.0 *. trackballsize) in (* Avoid problems with out-of-control values... *) let clamp x a b = if x < a then a else if x > b then b else x in let t = clamp t (-1.0) 1.0 in let phi = 2.0 *. asin(t) in axis_to_quat (as_tuple ax) phi end ;; (* * 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). *) let renormcount = 97 let count = ref 0 (* * 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. *) let normalized_quat q = let minv = 1.0 /. (sqrt((q.v ^.^ q.v) +. q.w *. q.w)) in { v = vscale minv q.v; w = q.w *. minv } ;; let add_quats ~q1 ~q2 = let t1 = vscale q2.w q1.v in let t2 = vscale q1.w q2.v in let t3 = q2.v ^^ q1.v in let q = { v = t1 +^ t2 +^ t3; w = q1.w *. q2.w -. (q1.v ^.^ q2.v) } in incr count; if (!count > renormcount) then begin count := 0; normalized_quat q; end else q ;; let unit_quat () = { v={x=0.0;y=0.0;z=0.0}; w=1.0 } (* * Build a rotation matrix given a quaternion rotation. * *) (* -- need to write a test for this ... -ijt *) let build_rotmatrix ~q = GlMat.of_array [| [| 1.0 -. 2.0 *. (q.v.y *. q.v.y +. q.v.z *. q.v.z); 2.0 *. (q.v.x *. q.v.y -. q.v.z *. q.w); 2.0 *. (q.v.z *. q.v.x +. q.v.y *. q.w); 0.0 |]; [| 2.0 *. (q.v.x *. q.v.y +. q.v.z *. q.w); 1.0 -. 2.0 *. (q.v.z *. q.v.z +. q.v.x *. q.v.x); 2.0 *. (q.v.y *. q.v.z -. q.v.x *. q.w); 0.0 |]; [| 2.0 *. (q.v.z *. q.v.x -. q.v.y *. q.w); 2.0 *. (q.v.y *. q.v.z +. q.v.x *. q.w); 1.0 -. 2.0 *. (q.v.y *. q.v.y +. q.v.x *. q.v.x); 0.0 |]; [| 0.0; 0.0; 0.0; 1.0; |] |] (* * (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 *) (* Ported to lablglut by Issac Trotts on Sun Aug 11 2002. *) lablgl-1.07/LablGlut/examples/glut3.7/trackball/trackball.mli000066400000000000000000000060421437514534100240370ustar00rootroot00000000000000type quat (* * return a unit quaternion *) val unit_quat: unit -> quat (* * 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 *) val trackball: p1:(float*float) -> p2:(float*float) -> quat (* * 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. *) (* quaternion multiplication -ijt *) val add_quats: q1:quat -> q2:quat -> quat (* * A useful function builds a rotation matrix based on given quaternion. *) val build_rotmatrix: q:quat -> GlMat.t (* * 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. *) val axis_to_quat: axis:Gl.vect3 -> phi:float -> quat (* * (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. *) (* Ported to lablglut by Issac Trotts on Sun Aug 11 2002. *) lablgl-1.07/LablGlut/examples/lablGL/000077500000000000000000000000001437514534100173665ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/lablGL/README000066400000000000000000000001661437514534100202510ustar00rootroot00000000000000Here are a few examples for LablGL. They can be run with the lablglut toplevel. For example: lablglut gears.ml lablgl-1.07/LablGlut/examples/lablGL/checker.ml000066400000000000000000000040541437514534100213270ustar00rootroot00000000000000(* $Id: checker.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* converted by Issac Trotts. July 25, 2002 *) let image_height = 64 and image_width = 64 let make_image () = let image = GlPix.create `ubyte ~format:`rgb ~width:image_width ~height:image_height in for i = 0 to image_width - 1 do for j = 0 to image_height - 1 do Raw.sets (GlPix.to_raw image) ~pos:(3*(i*image_height+j)) (if (i land 8 ) lxor (j land 8) = 0 then [|255;255;255|] else [|0;0;0|]) done done; image let myinit () = GlClear.color (0.0, 0.0, 0.0); Gl.enable `depth_test; GlFunc.depth_func `less; let image = make_image () in GlPix.store (`unpack_alignment 1); GlTex.image2d image; List.iter (GlTex.parameter ~target:`texture_2d) [ `wrap_s `clamp; `wrap_t `clamp; `mag_filter `nearest; `min_filter `nearest ]; GlTex.env (`mode `decal); Gl.enable `texture_2d; GlDraw.shade_model `flat let display () = GlClear.clear [`color;`depth]; GlDraw.begins `quads; GlTex.coord2(0.0, 0.0); GlDraw.vertex3(-2.0, -1.0, 0.0); GlTex.coord2(0.0, 1.0); GlDraw.vertex3(-2.0, 1.0, 0.0); GlTex.coord2(1.0, 1.0); GlDraw.vertex3(0.0, 1.0, 0.0); GlTex.coord2(1.0, 0.0); GlDraw.vertex3(0.0, -1.0, 0.0); GlTex.coord2(0.0, 0.0); GlDraw.vertex3(1.0, -1.0, 0.0); GlTex.coord2(0.0, 1.0); GlDraw.vertex3(1.0, 1.0, 0.0); GlTex.coord2(1.0, 1.0); GlDraw.vertex3(2.41421, 1.0, -1.41421); GlTex.coord2(1.0, 0.0); GlDraw.vertex3(2.41421, -1.0, -1.41421); GlDraw.ends (); Gl.flush () let reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective ~fovy:60.0 ~aspect:(1.0 *. float w /. float h) ~z:(1.0,30.0); GlMat.mode `modelview; GlMat.load_identity (); GlMat.translate ~z:(-3.6) () let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true () ; Glut.initWindowSize ~w:500 ~h:500 ; ignore(Glut.createWindow ~title:"checker"); myinit (); Glut.displayFunc ~cb:display ; Glut.reshapeFunc ~cb:reshape ; Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/lablGL/gears.ml000066400000000000000000000166011437514534100210250ustar00rootroot00000000000000(* $Id: gears.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* * 3-D gear wheels. This program is in the public domain. * * Brian Paul * LablGL version by Jacques Garrigue * LablGLUT version by Issac Trotts *) open Printf;; let pi = acos (-1.) (* * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth *) let gear ~inner ~outer ~width ~teeth ~tooth_depth = let r0 = inner and r1 = outer -. tooth_depth /. 2.0 and r2 = outer +. tooth_depth /. 2.0 in let ta = 2.0 *. pi /. float teeth in let da = ta /. 4.0 in GlDraw.shade_model `flat; GlDraw.normal ~z:1.0 (); let vertex ~r ~z ?(s=0) i = let angle = float i *. ta +. float s *. da in GlDraw.vertex ~x:(r *. cos angle) ~y:(r *. sin angle) ~z () in (* draw front face *) let z = width *. 0.5 in GlDraw.begins `quad_strip; for i=0 to teeth do vertex i ~r:r0 ~z; vertex i ~r:r1 ~z; vertex i ~r:r0 ~z; vertex i ~r:r1 ~z ~s:3; done; GlDraw.ends (); (* draw front sides of teeth *) GlDraw.begins `quads; for i=0 to teeth - 1 do vertex i ~r:r1 ~z; vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r1 ~s:3 ~z; done; GlDraw.ends (); GlDraw.normal ~z:(-1.0) (); (* draw back face *) let z = -. width *. 0.5 in GlDraw.begins `quad_strip; for i=0 to teeth do vertex i ~r:r1 ~z; vertex i ~r:r0 ~z; vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r0 ~z; done; GlDraw.ends (); (* draw back sides of teeth *) GlDraw.begins `quads; for i=0 to teeth - 1 do vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r1 ~z; done; GlDraw.ends (); (* draw outward faces of teeth *) let z = width *. 0.5 and z' = width *. (-0.5) in GlDraw.begins `quad_strip; for i=0 to teeth - 1 do let angle = float i *. ta in vertex i ~r:r1 ~z; vertex i ~r:r1 ~z:z'; let u = r2 *. cos(angle+.da) -. r1 *. cos(angle) and v = r2 *. sin(angle+.da) -. r1 *. sin(angle) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r2 ~s:1 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r2 ~s:2 ~z:z'; let u = r1 *. cos(angle +. 3. *. da) -. r2 *. cos(angle +. 2. *. da) and v = r1 *. sin(angle +. 3. *. da) -. r2 *. sin(angle +. 2. *. da) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r1 ~s:3 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); done; vertex 0 ~r:r1 ~z; vertex 0 ~r:r1 ~z:z'; GlDraw.ends (); GlDraw.shade_model `smooth; (* draw inside radius cylinder *) GlDraw.begins `quad_strip; for i=0 to teeth do let angle = float i *. ta in GlDraw.normal ~x:(-. cos angle) ~y:(-. sin angle) (); vertex i ~r:r0 ~z:z'; vertex i ~r:r0 ~z; done; GlDraw.ends () class view ~gear1 ~gear2 ~gear3 ~limit = object (self) val mutable view_rotx = 0.0 val mutable view_roty = 0.0 val mutable view_rotz = 0.0 val mutable angle = 0.0 val mutable count = 1 method rotx a = view_rotx <- view_rotx +. a method roty a = view_roty <- view_roty +. a method draw = GlClear.clear [`color;`depth]; GlMat.push (); GlMat.rotate ~angle:view_rotx ~x:1.0 (); GlMat.rotate ~angle:view_roty ~y:1.0 (); GlMat.rotate ~angle:view_rotz ~z:1.0 (); GlMat.push (); GlMat.translate ~x:(-3.0) ~y:(-2.0) (); GlMat.rotate ~angle:angle ~z:1.0 (); (* gear inner:1.0 outer:4.0 width:1.0 teeth:20 tooth_depth:0.7; *) GlList.call gear1; GlMat.pop (); GlMat.push (); GlMat.translate ~x:3.1 ~y:(-2.0) (); GlMat.rotate ~angle:(-2.0 *. angle -. 9.0) ~z:1.0 (); (* gear inner:0.5 outer:2.0 width:2.0 teeth:10 tooth_depth:0.7; *) GlList.call gear2; GlMat.pop (); GlMat.push (); GlMat.translate ~x:(-3.1) ~y:4.2 (); GlMat.rotate ~angle:(-2.0 *. angle -. 25.0) ~z:1.0 (); (* gear inner:1.3 outer:2.0 width:0.5 teeth:10 tooth_depth:0.7; *) GlList.call gear3; GlMat.pop (); GlMat.pop (); Glut.swapBuffers(); count <- count + 1; if count =limit then exit 0 method idle = angle <- angle +. 2.0; self#draw method reshape w h = GlDraw.viewport ~x:0 ~y:0 ~w:w ~h:h; GlMat.mode `projection; GlMat.load_identity (); let r = float w /. float h in let r' = 1. /. r in if (w>h) then GlMat.frustum ~x:(-. r,r) ~y:(-1.0,1.0) ~z:(5.0,60.0) else GlMat.frustum ~x:(-1.0,1.0) ~y:(-.r',r') ~z:(5.0,60.0); GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate ~z:(-40.0) (); GlClear.clear[`color;`depth] end let init () = let pos = 5.0, 5.0, 10.0, 0.0 and red = 0.8, 0.1, 0.0, 1.0 and green = 0.0, 0.8, 0.2, 1.0 and blue = 0.2, 0.2, 1.0, 1.0 in GlLight.light ~num:0 (`position pos); List.iter Gl.enable [`cull_face;`lighting;`light0;`depth_test;`normalize]; (* make the gears *) let make_gear ~inner ~outer ~width ~teeth ~color = let list = GlList.create `compile in GlLight.material ~face:`front (`ambient_and_diffuse color); gear ~inner ~outer ~width ~teeth ~tooth_depth:0.7; GlList.ends (); list in let gear1 = make_gear ~inner:1.0 ~outer:4.0 ~width:1.0 ~teeth:20 ~color:red and gear2 = make_gear ~inner:0.5 ~outer:2.0 ~width:2.0 ~teeth:10 ~color:green and gear3 = make_gear ~inner:1.3 ~outer:2.0 ~width:0.5 ~teeth:10 ~color:blue in (gear1, gear2, gear3) let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~double_buffer:true ~depth:true () ; Glut.initWindowSize ~w:300 ~h:300; ignore (Glut.createWindow ~title:"gears demo"); let gear1, gear2, gear3 = init() in let view = new view ~gear1 ~gear2 ~gear3 ~limit:0 in let _reshape ~w ~h = view#reshape w h in let _keyboard_callback ~key ~x ~y = match (char_of_int key) with 'q' -> exit 0; | _ -> () in let _special_key_callback ~key ~x ~y = (* let dummy = x+y in *) let delta = 5.0 in let redisp = ref true in match key with | Glut.KEY_LEFT -> view#roty (-. delta) ; | Glut.KEY_RIGHT -> view#roty delta ; | Glut.KEY_DOWN -> view#rotx (-. delta) ; | Glut.KEY_UP -> view#rotx delta ; | _ -> begin redisp := false; (); end; if !redisp then Glut.postRedisplay (); in Glut.keyboardFunc ~cb:_keyboard_callback ; Glut.reshapeFunc ~cb:_reshape ; Glut.displayFunc ~cb:(fun () -> view#draw) ; Glut.idleFunc(Some (fun () -> view#idle)); Glut.specialFunc ~cb:_special_key_callback ; Glut.mainLoop(); ;; let _ = main () lablgl-1.07/LablGlut/examples/lablGL/morph3d.ml000066400000000000000000000502071437514534100213000ustar00rootroot00000000000000(* $Id: morph3d.ml,v 1.2 2005-10-17 11:27:04 garrigue Exp $ *) open StdLabels open Printf (*- * morph3d.c - Shows 3D morphing objects (TK Version) * * This program was inspired on a WindowsNT(R)'s screen saver. It was written * from scratch and it was not based on any other source code. * * Porting it to xlock (the final objective of this code since the moment I * decided to create it) was possible by comparing the original Mesa's gear * demo with it's ported version, so thanks for Danny Sung for his indirect * help (look at gear.c in xlock source tree). NOTE: At the moment this code * was sent to Brian Paul for package inclusion, the XLock Version was not * available. In fact, I'll wait it to appear on the next Mesa release (If you * are reading this, it means THIS release) to send it for xlock package * inclusion). It will probably there be a GLUT version too. * * Thanks goes also to Brian Paul for making it possible and inexpensive * to use OpenGL at home. * * Since I'm not a native english speaker, my apologies for any gramatical * mistake. * * My e-mail addresses are * * vianna@cat.cbpf.br * and * marcelo@venus.rdc.puc-rio.br * * Marcelo F. Vianna (Feb-13-1997) *) (* This document is VERY incomplete, but tries to describe the mathematics used in the program. At this moment it just describes how the polyhedra are generated. On futhurer versions, this document will be probabbly improved. Since I'm not a native english speaker, my apologies for any gramatical mistake. Marcelo Fernandes Vianna - Undergraduate in Computer Engeneering at Catholic Pontifical University - of Rio de Janeiro (PUC-Rio) Brasil. - e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br - Feb-13-1997 POLYHEDRA GENERATION For the purpose of this program it's not sufficient to know the polyhedra vertexes coordinates. Since the morphing algorithm applies a nonlinear transformation over the surfaces (faces) of the polyhedron, each face has to be divided into smaller ones. The morphing algorithm needs to transform each vertex of these smaller faces individually. It's a very time consoming task. In order to reduce calculation overload, and since all the macro faces of the polyhedron are transformed by the same way, the generation is made by creating only one face of the polyhedron, morphing it and then rotating it around the polyhedron center. What we need to know is the face radius of the polyhedron (the radius of the inscribed sphere) and the angle between the center of two adjacent faces using the center of the sphere as the angle's vertex. The face radius of the regular polyhedra are known values which I decided to not waste my time calculating. Following is a table of face radius for the regular polyhedra with edge length = 1: TETRAHEDRON : 1/(2*sqrt(2))/sqrt(3) CUBE : 1/2 OCTAHEDRON : 1/sqrt(6) DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2 -> where T=(sqrt(5)+1)/2 ICOSAHEDRON : (3*sqrt(3)+sqrt(15))/12 I've not found any reference about the mentioned angles, so I needed to calculate them, not a trivial task until I figured out how :) Curiously these angles are the same for the tetrahedron and octahedron. A way to obtain this value is inscribing the tetrahedron inside the cube by matching their vertexes. So you'll notice that the remaining unmatched vertexes are in the same straight line starting in the cube/tetrahedron center and crossing the center of each tetrahedron's face. At this point it's easy to obtain the bigger angle of the isosceles triangle formed by the center of the cube and two opposite vertexes on the same cube face. The edges of this triangle have the following lenghts: sqrt(2) for the base and sqrt(3)/2 for the other two other edges. So the angle we want is: +-----------------------------------------------------------+ | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +-----------------------------------------------------------+ For the cube this angle is obvious, but just for formality it can be easily obtained because we also know it's isosceles edge lenghts: sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we want is: +-----------------------------------------------------------+ | 2*ARCSIN((sqrt(2)/2)/1) = 90.000000000000000000 degrees | +-----------------------------------------------------------+ For the octahedron we use the same idea used for the tetrahedron, but now we inscribe the cube inside the octahedron so that all cubes's vertexes matches excatly the center of each octahedron's face. It's now clear that this angle is the same of the thetrahedron one: +-----------------------------------------------------------+ | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +-----------------------------------------------------------+ For the dodecahedron it's a little bit harder because it's only relationship with the cube is useless to us. So we need to solve the problem by another way. The concept of Face radius also exists on 2D polygons with the name Edge radius: Edge Radius For Pentagon (ERp) ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905 (VRp is the pentagon's vertex radio). Face Radius For Dodecahedron FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404 Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle, completing this triangle, the lesser angle is a half of the angle we are looking for, so this angle is: +-----------------------------------------------------------+ | 2*ARCTAN(ERp/FRd) = 63.434948822922009981 degrees | +-----------------------------------------------------------+ For the icosahedron we can use the same method used for dodecahedron (well the method used for dodecahedron may be used for all regular polyhedra) Edge Radius For Triangle (this one is well known: 1/3 of the triangle height) ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655 Face Radius For Icosahedron FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538 So the angle is: +-----------------------------------------------------------+ | 2*ARCTAN(ERt/FRi) = 41.810314895778596167 degrees | +-----------------------------------------------------------+ *) let scale = 0.3 let vect_mul (x1,y1,z1) (x2,y2,z2) = (y1 *. z2 -. z1 *. y2, z1 *. x2 -. x1 *. z2, x1 *. y2 -. y1 *. x2) let sqr a = a *. a (* Increasing this values produces better image quality, the price is speed. *) (* Very low values produces erroneous/incorrect plotting *) let tetradivisions = 23 let cubedivisions = 20 let octadivisions = 21 let dodecadivisions = 10 let icodivisions = 15 let tetraangle = 109.47122063449069174 let cubeangle = 90.000000000000000000 let octaangle = 109.47122063449069174 let dodecaangle = 63.434948822922009981 let icoangle = 41.810314895778596167 let pi = acos (-1.) let sqrt2 = sqrt 2. let sqrt3 = sqrt 3. let sqrt5 = sqrt 5. let sqrt6 = sqrt 6. let sqrt15 = sqrt 15. let cossec36_2 = 0.8506508083520399322 let cosd x = cos (float x /. 180. *. pi) let sind x = sin (float x /. 180. *. pi) let cos72 = cosd 72 let sin72 = sind 72 let cos36 = cosd 36 let sin36 = sind 36 (*************************************************************************) let front_shininess = 60.0 let front_specular = 0.7, 0.7, 0.7, 1.0 let ambient = 0.0, 0.0, 0.0, 1.0 let diffuse = 1.0, 1.0, 1.0, 1.0 let position0 = 1.0, 1.0, 1.0, 0.0 let position1 = -1.0,-1.0, 1.0, 0.0 let lmodel_ambient = 0.5, 0.5, 0.5, 1.0 let lmodel_twoside = true let materialRed = 0.7, 0.0, 0.0, 1.0 let materialGreen = 0.1, 0.5, 0.2, 1.0 let materialBlue = 0.0, 0.0, 0.7, 1.0 let materialCyan = 0.2, 0.5, 0.7, 1.0 let materialYellow = 0.7, 0.7, 0.0, 1.0 let materialMagenta = 0.6, 0.2, 0.5, 1.0 let materialWhite = 0.7, 0.7, 0.7, 1.0 let materialGray = 0.2, 0.2, 0.2, 1.0 let all_gray = Array.create 20 materialGray let vertex ~xf ~yf ~zf ~ampvr2 = let xa = xf +. 0.01 and yb = yf +. 0.01 in let xf2 = sqr xf and yf2 = sqr yf in let factor = 1. -. (xf2 +. yf2) *. ampvr2 and factor1 = 1. -. (sqr xa +. yf2) *. ampvr2 and factor2 = 1. -. (xf2 +. sqr yb) *. ampvr2 in let vertx = factor *. xf and verty = factor *. yf and vertz = factor *. zf in let neiax = factor1 *. xa -. vertx and neiay = factor1 *. yf -. verty and neiaz = factor1 *. zf -. vertz and neibx = factor2 *. xf -. vertx and neiby = factor2 *. yb -. verty and neibz = factor2 *. zf -. vertz in GlDraw.normal3 (vect_mul (neiax, neiay, neiaz) (neibx, neiby, neibz)); GlDraw.vertex3 (vertx, verty, vertz) let triangle ~edge ~amp ~divisions ~z = let divi = float divisions in let vr = edge *. sqrt3 /. 3. in let ampvr2 = amp /. sqr vr and zf = edge *. z in let ax = edge *. (0.5 /. divi) and ay = edge *. (-0.5 *. sqrt3 /. divi) and bx = edge *. (-0.5 /. divi) in for ri = 1 to divisions do GlDraw.begins `triangle_strip; for ti = 0 to ri - 1 do vertex ~zf ~ampvr2 ~xf:(float (ri-ti) *. ax +. float ti *. bx) ~yf:(vr +. float (ri-ti) *. ay +. float ti *. ay); vertex ~zf ~ampvr2 ~xf:(float (ri-ti-1) *. ax +. float ti *. bx) ~yf:(vr +. float (ri-ti-1) *. ay +. float ti *. ay) done; vertex ~xf:(float ri *. bx) ~yf:(vr +. float ri *. ay) ~zf ~ampvr2; GlDraw.ends () done let square ~edge ~amp ~divisions ~z = let divi = float divisions in let zf = edge *. z and ampvr2 = amp /. sqr (edge *. sqrt2 /. 2.) in for yi = 0 to divisions - 1 do let yf = edge *. (-0.5 +. float yi /. divi) in let yf2 = sqr yf in let y = yf +. 1.0 /. divi *. edge in let y2 = sqr y in GlDraw.begins `quad_strip; for xi = 0 to divisions do let xf = edge *. (-0.5 +. float xi /. divi) in vertex ~xf ~yf:y ~zf ~ampvr2; vertex ~xf ~yf ~zf ~ampvr2 done; GlDraw.ends () done let pentagon ~edge ~amp ~divisions ~z = let divi = float divisions in let zf = edge *. z and ampvr2 = amp /. sqr(edge *. cossec36_2) in let x = Array.init 6 ~f:(fun fi -> -. cos (float fi *. 2. *. pi /. 5. +. pi /. 10.) /. divi *. cossec36_2 *. edge) and y = Array.init 6 ~f:(fun fi -> sin (float fi *. 2. *. pi /. 5. +. pi /. 10.) /. divi *. cossec36_2 *. edge) in for ri = 1 to divisions do for fi = 0 to 4 do GlDraw.begins `triangle_strip; for ti = 0 to ri-1 do vertex ~zf ~ampvr2 ~xf:(float(ri-ti) *. x.(fi) +. float ti *. x.(fi+1)) ~yf:(float(ri-ti) *. y.(fi) +. float ti *. y.(fi+1)); vertex ~zf ~ampvr2 ~xf:(float(ri-ti-1) *. x.(fi) +. float ti *. x.(fi+1)) ~yf:(float(ri-ti-1) *. y.(fi) +. float ti *. y.(fi+1)) done; vertex ~xf:(float ri *. x.(fi+1)) ~yf:(float ri *. y.(fi+1)) ~zf ~ampvr2; GlDraw.ends () done done let call_list list color = GlLight.material ~face:`both (`diffuse color); GlList.call list let draw_tetra ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:2.0 ~amp ~divisions ~z:(0.5 /. sqrt6); GlList.ends(); call_list list color.(0); GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-.tetraangle) ~x:1.0 (); call_list list color.(1); GlMat.pop(); GlMat.push(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(sqrt3 /. 2.) (); call_list list color.(2); GlMat.pop(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(-.sqrt3 /. 2.) (); call_list list color.(3); GlList.delete list let draw_cube ~amp ~divisions ~color = let list = GlList.create `compile in square ~edge:2.0 ~amp ~divisions ~z:0.5; GlList.ends (); call_list list color.(0); for i = 1 to 3 do GlMat.rotate ~angle:cubeangle ~x:1.0 (); call_list list color.(i) done; GlMat.rotate ~angle:cubeangle ~y:1.0 (); call_list list color.(4); GlMat.rotate ~angle:(2.0 *. cubeangle) ~y:1.0 (); call_list list color.(5); GlList.delete list let draw_octa ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:2.0 ~amp ~divisions ~z:(1.0 /. sqrt6); GlList.ends (); let do_list (i,y) = GlMat.push(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-.octaangle) ~x:0.5 ~y (); call_list list color.(i); GlMat.pop() in call_list list color.(0); GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); call_list list color.(1); GlMat.pop(); List.iter [2, sqrt3 /. 2.0; 3, -.sqrt3 /. 2.0] ~f:do_list; GlMat.rotate ~angle:180.0 ~x:1.0 (); GlLight.material ~face:`both (`diffuse color.(4)); GlList.call list; GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); GlLight.material ~face:`both (`diffuse color.(5)); GlList.call list; GlMat.pop(); List.iter [6, sqrt3 /. 2.0; 7, -.sqrt3 /. 2.0] ~f:do_list; GlList.delete list let draw_dodeca ~amp ~divisions ~color = let tau = (sqrt5 +. 1.0) /. 2.0 in let list = GlList.create `compile in pentagon ~edge:2.0 ~amp ~divisions ~z:(sqr(tau) *. sqrt ((tau+.2.0)/.5.0) /. 2.0); GlList.ends (); let do_list (i,angle,x,y) = GlMat.push(); GlMat.rotate ~angle:angle ~x ~y (); call_list list color.(i); GlMat.pop(); in GlMat.push (); call_list list color.(0); GlMat.rotate ~angle:180.0 ~z:1.0 (); List.iter ~f:do_list [ 1, -.dodecaangle, 1.0, 0.0; 2, -.dodecaangle, cos72, sin72; 3, -.dodecaangle, cos72, -.sin72; 4, dodecaangle, cos36, -.sin36; 5, dodecaangle, cos36, sin36 ]; GlMat.pop (); GlMat.rotate ~angle:180.0 ~x:1.0 (); call_list list color.(6); GlMat.rotate ~angle:180.0 ~z:1.0 (); List.iter ~f:do_list [ 7, -.dodecaangle, 1.0, 0.0; 8, -.dodecaangle, cos72, sin72; 9, -.dodecaangle, cos72, -.sin72; 10, dodecaangle, cos36, -.sin36 ]; GlMat.rotate ~angle:dodecaangle ~x:cos36 ~y:sin36 (); call_list list color.(11); GlList.delete list let draw_ico ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:1.5 ~amp ~divisions ~z:((3.0 *. sqrt3 +. sqrt15) /. 12.0); GlList.ends (); let do_list1 i = GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(sqrt3/.2.0) (); call_list list color.(i) and do_list2 i = GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(-.sqrt3/.2.0) (); call_list list color.(i) and do_list3 i = GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-.icoangle) ~x:1.0 (); call_list list color.(i) in GlMat.push (); call_list list color.(0); GlMat.push (); do_list3 1; GlMat.push (); do_list1 2; GlMat.pop (); do_list2 3; GlMat.pop (); GlMat.push (); do_list1 4; GlMat.push (); do_list1 5; GlMat.pop(); do_list3 6; GlMat.pop (); do_list2 7; GlMat.push (); do_list2 8; GlMat.pop (); do_list3 9; GlMat.pop (); GlMat.rotate ~angle:180.0 ~x:1.0 (); call_list list color.(10); GlMat.push (); do_list3 11; GlMat.push (); do_list1 12; GlMat.pop (); do_list2 13; GlMat.pop (); GlMat.push (); do_list1 14; GlMat.push (); do_list1 15; GlMat.pop (); do_list3 16; GlMat.pop (); do_list2 17; GlMat.push (); do_list2 18; GlMat.pop (); do_list3 19; GlList.delete list class view = object (self) val mutable smooth = true val mutable step = 0. val mutable obj = 1 val mutable draw_object = fun ~amp -> () val mutable magnitude = 0. val mutable my_width = 640 val mutable my_height = 480 method width = my_width method height = my_height method draw = let ratio = float self#height /. float self#width in GlClear.clear [`color;`depth]; GlMat.push (); GlMat.translate () ~z:(-10.0); GlMat.scale () ~x:(scale *. ratio) ~y:scale ~z:scale; GlMat.translate () ~x:(2.5 *. ratio *. sin (step *. 1.11)) ~y:(2.5 *. cos (step *. 1.25 *. 1.11)); GlMat.rotate ~angle:(step *. 100.) ~x:1.0 (); GlMat.rotate ~angle:(step *. 95.) ~y:1.0 (); GlMat.rotate ~angle:(step *. 90.) ~z:1.0 (); draw_object ~amp:((sin step +. 1.0/.3.0) *. (4.0/.5.0) *. magnitude); GlMat.pop(); Gl.flush(); Glut.swapBuffers (); step <- step +. 0.05 method reshape ~w ~h = my_width <- w; my_height <- h; GlDraw.viewport ~x:0 ~y:0 ~w:self#width ~h:self#height; GlMat.mode `projection; GlMat.load_identity(); GlMat.frustum ~x:(-1.0, 1.0) ~y:(-1.0, 1.0) ~z:(5.0, 15.0); GlMat.mode `modelview method keyboard key = begin match (char_of_int key) with | '1' -> obj <- 1 | '2' -> obj <- 2 | '3' -> obj <- 3 | '4' -> obj <- 4 | '5' -> obj <- 5 | _ -> match key with | 10(*return*) -> smooth <- not smooth | 27(*escape*) -> exit 0 | _ -> (); end; self#pinit method pinit = begin match obj with 1 -> draw_object <- draw_tetra ~divisions:tetradivisions ~color:[|materialRed; materialGreen; materialBlue; materialWhite|]; magnitude <- 2.5 | 2 -> draw_object <- draw_cube ~divisions:cubedivisions ~color:[|materialRed; materialGreen; materialCyan; materialMagenta; materialYellow; materialBlue|]; magnitude <- 2.0 | 3 -> draw_object <- draw_octa ~divisions:octadivisions ~color:[|materialRed; materialGreen; materialBlue; materialWhite; materialCyan; materialMagenta; materialGray; materialYellow|]; magnitude <- 2.5 | 4 -> draw_object <- draw_dodeca ~divisions:dodecadivisions ~color:[|materialRed; materialGreen; materialCyan; materialBlue; materialMagenta; materialYellow; materialGreen; materialCyan; materialRed; materialMagenta; materialBlue; materialYellow|]; magnitude <- 2.0 | 5 -> draw_object <- draw_ico ~divisions:icodivisions ~color:[|materialRed; materialGreen; materialBlue; materialCyan; materialYellow; materialMagenta; materialRed; materialGreen; materialBlue; materialWhite; materialCyan; materialYellow; materialMagenta; materialRed; materialGreen; materialBlue; materialCyan; materialYellow; materialMagenta; materialGray|]; magnitude <- 3.5 | _ -> () end; GlDraw.shade_model (if smooth then `smooth else `flat) end let main () = List.iter ~f:print_string [ "Morph 3D - Shows morphing platonic polyhedra\n"; "Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n"; "Ported to LablGL by Jacques Garrigue\n"; "Ported to lablglut by Issac Trotts\n\n"; " [1] - Tetrahedron\n"; " [2] - Hexahedron (Cube)\n"; " [3] - Octahedron\n"; " [4] - Dodecahedron\n"; " [5] - Icosahedron\n"; (* "[RETURN] - Toggle smooth/flat shading\n"; *) (* not working ... ??? *) " [ESC] - Quit\n" ]; flush stdout; ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:false ~double_buffer:true ~depth:true (); Glut.initWindowSize ~w:640 ~h:480; ignore(Glut.createWindow ~title:"Morph 3D - Shows morphing platonic polyhedra"); GlClear.depth 1.0; GlClear.color (0.0, 0.0, 0.0); GlDraw.color (1.0, 1.0, 1.0); GlClear.clear [`color;`depth]; Gl.flush(); Glut.swapBuffers(); List.iter ~f:(GlLight.light ~num:0) [`ambient ambient; `diffuse diffuse; `position position0]; List.iter ~f:(GlLight.light ~num:1) [`ambient ambient; `diffuse diffuse; `position position1]; GlLight.light_model (`ambient lmodel_ambient); GlLight.light_model (`two_side lmodel_twoside); List.iter ~f:Gl.enable [`lighting;`light0;`light1;`depth_test;`normalize]; GlLight.material ~face:`both (`shininess front_shininess); GlLight.material ~face:`both (`specular front_specular); GlMisc.hint `fog `fastest; GlMisc.hint `perspective_correction `fastest; GlMisc.hint `polygon_smooth `fastest; let view = new view in view#pinit; Glut.displayFunc ~cb:(fun () -> view#draw); Glut.reshapeFunc ~cb:(fun ~w ~h -> view#reshape w h); let rec idle ~value = view#draw; Glut.timerFunc ~ms:20 ~cb:idle ~value:0 in Glut.timerFunc ~ms:20 ~cb:idle ~value:0; Glut.keyboardFunc ~cb:(fun ~key ~x ~y -> view#keyboard key); Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/lablGL/planet.ml000066400000000000000000000074561437514534100212170ustar00rootroot00000000000000(* $Id: planet.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* converted to lablglut by Issac Trotts on July 25, 2002 *) #load"unix.cma";; class planet = object (self) val mutable year = 0.0 val mutable day = 0.0 val mutable eye = 0.0 val mutable time = 0.0 method tick new_time = if time = 0. then time <- new_time else let diff = new_time -. time in time <- new_time; day <- mod_float (day +. diff *. 200.) 360.0; year <- mod_float (year +. diff *. 20.) 360.0; method day_add = day <- mod_float (day +. 10.0) 360.0 method day_subtract = day <- mod_float (day -. 10.0) 360.0 method year_add = year <- mod_float (year +. 5.0) 360.0 method year_subtract = year <- mod_float (year -. 5.0) 360.0 method eye x = eye <- x; self#display method display = GlClear.clear [`color;`depth]; GlDraw.color (1.0, 1.0, 1.0); GlMat.push(); GlMat.rotate ~angle:eye ~x:1. (); (* draw sun *) GlLight.material ~face:`front (`specular (1.0,1.0,0.0,1.0)); GlLight.material ~face:`front (`shininess 5.0); GluQuadric.sphere ~radius:1.0 ~slices:32 ~stacks:32 (); (* draw smaller planet *) GlMat.rotate ~angle:year ~y:1.0 (); GlMat.translate () ~x:3.0; GlMat.rotate ~angle:day ~y:1.0 (); GlDraw.color (0.0, 1.0, 1.0); GlDraw.shade_model `flat; GlLight.material ~face:`front(`shininess 128.0); GluQuadric.sphere ~radius:0.2 ~slices:10 ~stacks:10 (); GlDraw.shade_model `smooth; GlMat.pop (); Gl.flush (); Glut.swapBuffers (); end let myinit () = let light_ambient = 0.5, 0.5, 0.5, 1.0 and light_diffuse = 1.0, 0.8, 0.2, 1.0 and light_specular = 1.0, 1.0, 1.0, 1.0 (* light_position is NOT default value *) and light_position = 1.0, 1.0, 1.0, 0.0 in List.iter (GlLight.light ~num:0) [ `ambient light_ambient; `diffuse light_diffuse; `specular light_specular; `position light_position ]; GlFunc.depth_func `less; List.iter Gl.enable [`lighting; `light0; `depth_test]; GlDraw.shade_model `smooth let my_reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity(); GluMat.perspective ~fovy:60.0 ~aspect:(float w /. float h) ~z:(1.0,20.0); GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate () ~z:(-5.0) (* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. *) let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~double_buffer:true ~depth:true (); Glut.initWindowSize ~w:700 ~h:500; ignore(Glut.createWindow "Planet"); myinit (); let planet = new planet in (* let scale = Scale.create top ~min:(-45.) ~max:45. ~orient:`Vertical ~command:(planet#eye) ~showvalue:false ~highlightbackground:`Black in *) (* bind togl ~events:[`Enter] ~action:(fun _ -> Focus.set togl); bind scale ~events:[`Enter] ~action:(fun _ -> Focus.set scale); bind togl ~events:[`KeyPress] ~fields:[`KeySymString] *) Glut.specialFunc ~cb:(fun ~key ~x ~y -> match key with | Glut.KEY_LEFT -> planet#year_subtract | Glut.KEY_RIGHT -> planet#year_add | Glut.KEY_UP -> planet#day_add | Glut.KEY_DOWN -> planet#day_subtract | _ -> (); planet#display); Glut.keyboardFunc ~cb:(fun ~key ~x ~y -> match key with | 27(*esc*) -> exit 0 | _ -> ()); (*Glut.timerFunc ~ms:20 ~cb:(fun ~value -> planet#tick (Unix.gettimeofday()); planet#display) ~value:0;*) let rec _timedUpdate ~value = planet#tick (Unix.gettimeofday()); Glut.postRedisplay(); Glut.timerFunc ~ms:20 ~cb:_timedUpdate ~value:0 in Glut.timerFunc ~ms:20 ~cb:_timedUpdate ~value:0; Glut.displayFunc ~cb:(fun () -> planet#display); Glut.reshapeFunc ~cb:my_reshape; my_reshape ~w:700 ~h:500; Glut.mainLoop () let _ = Printexc.print main () lablgl-1.07/LablGlut/examples/lablGL/scene.ml000066400000000000000000000057061437514534100210250ustar00rootroot00000000000000(* $Id: scene.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* converted to lablglut by Issac Trotts on July 25, 2002 *) (* Initialize material property and light source. *) let myinit () = let light_ambient = 0.0, 0.0, 0.0, 1.0 and light_diffuse = 1.0, 1.0, 1.0, 1.0 and light_specular = 1.0, 1.0, 1.0, 1.0 (* light_position is NOT default value *) and light_position = 1.0, 1.0, 1.0, 0.0 in GlLight.light ~num:0 (`ambient light_ambient); GlLight.light ~num:0 (`diffuse light_diffuse); GlLight.light ~num:0 (`specular light_specular); GlLight.light ~num:0 (`position light_position); GlFunc.depth_func `less; List.iter Gl.enable [`lighting; `light0; `depth_test] let pi = acos (-1.) let solid_torus ~inner ~outer = let slices = 32 and faces = 16 in let slice_angle = 2.0 *. pi /. float slices and face_angle = 2.0 *. pi /. float faces in let vertex ~i ~j = let angle1 = slice_angle *. float i and angle2 = face_angle *. float j in GlDraw.normal3 (cos angle1 *. cos angle2, -. sin angle1 *. cos angle2, sin angle2); GlDraw.vertex3 ((outer +. inner *. cos angle2) *. cos angle1, -. (outer +. inner *. cos angle2) *. sin angle1, inner *. sin angle2) in GlDraw.begins `quads; for i = 0 to slices - 1 do for j = 0 to faces - 1 do vertex ~i ~j; vertex ~i:(i+1) ~j; vertex ~i:(i+1) ~j:(j+1); vertex ~i ~j:(j+1); done done; GlDraw.ends () let solid_cone ~radius ~height = GluQuadric.cylinder ~base:radius ~top:0. ~height ~slices:15 ~stacks:10 () let solid_sphere ~radius = GluQuadric.sphere ~radius ~slices:32 ~stacks:32 () let display () = GlClear.clear [`color; `depth]; GlMat.push (); GlMat.rotate ~angle:20.0 ~x:1.0 (); GlMat.push (); GlMat.translate ~x:(-0.75) ~y:0.5 (); GlMat.rotate ~angle:90.0 ~x:1.0 (); solid_torus ~inner:0.275 ~outer:0.85; GlMat.pop (); GlMat.push (); GlMat.translate ~x:(-0.75) ~y:(-0.5) (); GlMat.rotate ~angle:270.0 ~x:1.0 (); solid_cone ~radius:1.0 ~height:2.0; GlMat.pop (); GlMat.push (); GlMat.translate ~x:0.75 ~z:(-1.0) (); solid_sphere ~radius:1.0; GlMat.pop (); GlMat.pop (); Gl.flush () let my_reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); if w <= h then GlMat.ortho ~x:(-2.5,2.5) ~z:(-10.0,10.0) ~y:(-2.5 *. float h /. float w, 2.5 *. float h /. float w) else GlMat.ortho ~y:(-2.5,2.5) ~z:(-10.0,10.0) ~x:(-2.5 *. float w /. float h, 2.5 *. float w /. float h); GlMat.mode `modelview (* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. *) let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true () ; Glut.initWindowSize ~w:500 ~h:500 ; ignore(Glut.createWindow "Scene"); myinit (); Glut.reshapeFunc ~cb:my_reshape ; Glut.displayFunc ~cb:display ; Glut.mainLoop () let _ = Printexc.print main () lablgl-1.07/LablGlut/examples/lablGL/simple.ml000066400000000000000000000016301437514534100212110ustar00rootroot00000000000000(* $Id: simple.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* open Tk *) let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true () ; Glut.initWindowSize ~w:500 ~h:500 ; ignore(Glut.createWindow ~title:"lablglut & LablGL"); Glut.displayFunc ~cb: begin fun () -> (* display callback *) GlClear.color (0.0, 0.0, 0.0); GlClear.clear [`color]; GlDraw.color (1.0, 1.0, 1.0); GlMat.mode `projection; GlMat.load_identity (); GlMat.ortho ~x:(-1.0,1.0) ~y:(-1.0,1.0) ~z:(-1.0,1.0); GlDraw.begins `polygon; GlDraw.vertex ~x:(-0.5) ~y:(-0.5) (); GlDraw.vertex ~x:(-0.5) ~y:(0.5) (); GlDraw.vertex ~x:(0.5) ~y:(0.5) (); GlDraw.vertex ~x:(0.5) ~y:(-0.5) (); GlDraw.ends (); Gl.flush () end; (* ignore (Timer.add ~ms:10000 ~callback:(fun () -> exit 0)); *) Glut.mainLoop(); ;; let _ = main () lablgl-1.07/LablGlut/examples/lablGL/test_glsl.ml000066400000000000000000000055741437514534100217330ustar00rootroot00000000000000(* Simple Demo for GLSL *) (* This demo comes from this tutorial: *) (* http://www.lighthouse3d.com/opengl/glsl/ *) (* The tutorial and this demo was made by Ant籀nio Ramires Fernandes. *) (* No restrictions apply to the use of this program. *) (* Converted from C to OCaml by Florent Monnier. *) let changeSize ~w ~h = (* Prevent a divide by zero, when window is too short (you cant make a window of zero width). *) let h = if h = 0 then 1 else h in let ratio = 1.0 *. float w /. float h in (* Reset the coordinate system before modifying *) GlMat.mode `projection; GlMat.load_identity(); (* Set the viewport to be the entire window *) GlDraw.viewport 0 0 w h; (* Set the correct perspective. *) GluMat.perspective 45.0 ratio (1.0, 1000.0); GlMat.mode `modelview; ;; let renderScene() = GlClear.clear [`color; `depth]; GlMat.load_identity(); GluMat.look_at (0.0, 0.0, 5.0) (0.0, 0.0, -1.0) (0.0, 1.0, 0.0); let lpos = (1.0, 0.5, 1.0, 0.0) in GlLight.light 0 (`position lpos); Glut.solidTeapot 1.0; Glut.swapBuffers(); ;; let processNormalKeys ~key ~x ~y = if key = 27 then exit 0; ;; let toon_frag = " // simple toon fragment shader varying vec3 normal, lightDir; vec4 toonify(in float intensity) { vec4 color; if (intensity > 0.98) color = vec4(0.9,0.9,0.9,1.0); else if (intensity > 0.5) color = vec4(0.4,0.4,0.8,1.0); else if (intensity > 0.25) color = vec4(0.3,0.3,0.5,1.0); else color = vec4(0.1,0.1,0.1,1.0); return(color); } void main() { float intensity; vec3 norm; norm = normalize(normal); intensity = max(dot(lightDir,norm),0.0); gl_FragColor = toonify(intensity); // or use this line to get a classic lighting: //gl_FragColor = intensity * vec4(0.9,0.2,0.0,1.0); } " let toon_vert = " // simple toon vertex shader varying vec3 normal, lightDir; void main() { lightDir = normalize(vec3(gl_LightSource[0].position)); normal = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } " let setShaders() = let v = GlShader.create `vertex_shader and f = GlShader.create `fragment_shader in GlShader.source v toon_vert; GlShader.source f toon_frag; GlShader.compile v; GlShader.compile f; let p = GlShader.create_program() in GlShader.attach p f; GlShader.attach p v; GlShader.link_program p; GlShader.use_program p; ;; (* main *) let () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~double_buffer:true ~depth:true (); Glut.initWindowPosition 100 100; Glut.initWindowSize 320 320; ignore(Glut.createWindow "simple GLSL demo"); Glut.displayFunc renderScene; Glut.reshapeFunc changeSize; Glut.keyboardFunc processNormalKeys; Glut.idleFunc (Some renderScene); Gl.enable `depth_test; GlClear.color (1.0, 1.0, 1.0); setShaders(); Glut.mainLoop(); ;; lablgl-1.07/LablGlut/examples/lablGL/texturesurf.ml000066400000000000000000000063561437514534100223320ustar00rootroot00000000000000(* $Id: texturesurf.ml,v 1.1 2003-09-25 13:54:10 raffalli Exp $ *) (* Converted to lablglut by Issac Trotts on July 25, 2002 *) open StdLabels let texpts = [|[|0.0; 0.0; 0.0; 1.0|]; [|1.0; 0.0; 1.0; 1.0|]|] let ctrlpoints = [|[|-1.5; -1.5; 4.9; -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|]|] let image_width = 64 and image_height = 64 let pi = acos (-1.0) let display () = GlClear.clear [`color;`depth]; GlDraw.color (1.0,1.0,1.0); GlMap.eval_mesh2 ~mode:`fill ~range1:(0,20) ~range2:(0,20); Gl.flush (); Glut.swapBuffers () let make_image () = let image = GlPix.create `ubyte ~height:image_height ~width:image_width ~format:`rgb in let raw = GlPix.to_raw image and pos = GlPix.raw_pos image in for i = 0 to image_width - 1 do let ti = 2.0 *. pi *. float i /. float image_width in for j = 0 to image_height - 1 do let tj = 2.0 *. pi *. float j /. float image_height in Raw.sets raw ~pos:(pos ~x:j ~y:i) (Array.map ~f:(fun x -> truncate (127.0 *. (1.0 +. x))) [|sin ti; cos (2.0 *. ti); cos (ti +. tj)|]); done; done; image let myinit () = let ctrlpoints = Raw.of_matrix ~kind:`double ctrlpoints and texpts = Raw.of_matrix ~kind:`double texpts in GlMap.map2 ~target:`vertex_3 (0.0, 1.0) ~order:4 (0.0, 1.0) ~order:4 ctrlpoints; GlMap.map2 ~target:`texture_coord_2 (0.0,1.0) ~order:2 (0.0,1.0) ~order:2 texpts; Gl.enable `map2_texture_coord_2; Gl.enable `map2_vertex_3; GlMap.grid2 ~n1:20 ~range1:(0.0,1.0) ~n2:20 ~range2:(0.0,1.0); let image = make_image () in GlTex.env (`mode `decal); List.iter ~f:(GlTex.parameter ~target:`texture_2d) [ `wrap_s `repeat; `wrap_t `repeat; `mag_filter `nearest; `min_filter `nearest ]; GlTex.image2d image; List.iter ~f:Gl.enable [`texture_2d;`depth_test;`normalize]; GlDraw.shade_model `flat let my_reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); let r = float h /. float w in if w <= h then GlMat.ortho ~x:(-4.0, 4.0) ~y:(-4.0 *. r, 4.0 *. r) ~z:(-4.0, 4.0) else GlMat.ortho ~x:(-4.0 /. r, 4.0 /. r) ~y:(-4.0, 4.0) ~z:(-4.0, 4.0); GlMat.mode `modelview; GlMat.load_identity (); GlMat.rotate ~angle:85. ~x:1. ~y:1. ~z:1. () let main () = ignore(Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true ~double_buffer:true () ; Glut.initWindowSize ~w:300 ~h:300 ; ignore(Glut.createWindow ~title:"Texture Surf"); myinit (); Glut.reshapeFunc ~cb:my_reshape ; Glut.displayFunc ~cb:display ; Glut.specialFunc ~cb:(fun ~key ~x ~y -> match key with | Glut.KEY_UP -> GlMat.rotate ~angle:(-5.) ~z:1.0 (); display () | Glut.KEY_DOWN -> GlMat.rotate ~angle:(5.) ~z:1.0 (); display () | Glut.KEY_LEFT -> GlMat.rotate ~angle:(5.) ~x:1.0 (); display () | Glut.KEY_RIGHT -> GlMat.rotate ~angle:(-5.) ~x:1.0 (); display () | _ -> ()); Glut.keyboardFunc ~cb:(fun ~key ~x ~y -> match key with | 27 (*esc*) -> exit 0 | _ -> ()); Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/nehe/000077500000000000000000000000001437514534100171505ustar00rootroot00000000000000lablgl-1.07/LablGlut/examples/nehe/lesson2.ml000066400000000000000000000037441437514534100210770ustar00rootroot00000000000000(* * This code was created by Jeff Molofee '99 * If you've found this code useful, please let me know. * * Visit Jeff at http://nehe.gamedev.net/ * * Ported to O'Caml/lablglut by Jeffrey Palmer 8/02 * For port-specific issues, comments, etc., please * contact jeffrey.palmer@acm.org *) let init_gl width height = GlDraw.shade_model `smooth; GlClear.color (0.0, 0.0, 0.0); GlClear.depth 1.0; GlClear.clear [`color; `depth]; Gl.enable `depth_test; GlFunc.depth_func `lequal; GlMisc.hint `perspective_correction `nicest let draw_gl_scene () = GlClear.clear [`color; `depth]; GlMat.load_identity (); (* Draw the triangle *) GlMat.translate3 (-1.5, 0.0, -6.0); GlDraw.color (1.0, 1.0, 1.0); GlDraw.begins `triangles; GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.ends (); (* Draw the square *) GlMat.translate3 (3.0, 0.0, 0.0); GlDraw.begins `quads; GlDraw.vertex3 (-1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.ends (); Glut.swapBuffers () (* Handle window reshape events *) let reshape_cb ~w ~h = let ratio = (float_of_int w) /. (float_of_int h) in GlDraw.viewport 0 0 w h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective 45.0 ratio (0.1, 100.0); GlMat.mode `modelview; GlMat.load_identity () (* Handle keyboard events *) let keyboard_cb ~key ~x ~y = match key with | 27 (* ESC *) -> exit 0 | _ -> () let main () = let width = 640 and height = 480 in ignore (Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true ~double_buffer:true (); Glut.initWindowSize width height; ignore (Glut.createWindow "O'Caml OpenGL Lesson 2"); Glut.displayFunc draw_gl_scene; Glut.keyboardFunc keyboard_cb; Glut.reshapeFunc reshape_cb; init_gl width height; Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/nehe/lesson3.ml000066400000000000000000000041231437514534100210700ustar00rootroot00000000000000(* * This code was created by Jeff Molofee '99 * If you've found this code useful, please let me know. * * Visit Jeff at http://nehe.gamedev.net/ * * Ported to O'Caml/lablglut by Jeffrey Palmer 8/02 * For port-specific issues, comments, etc., please * contact jeffrey.palmer@acm.org *) let init_gl width height = GlDraw.shade_model `smooth; GlClear.color (0.0, 0.0, 0.0); GlClear.depth 1.0; GlClear.clear [`color; `depth]; Gl.enable `depth_test; GlFunc.depth_func `lequal; GlMisc.hint `perspective_correction `nicest let draw_gl_scene () = GlClear.clear [`color; `depth]; GlMat.load_identity (); (* Draw the triangle *) GlMat.translate3 (-1.5, 0.0, -6.0); GlDraw.begins `triangles; GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.ends (); (* Draw the square *) GlMat.translate3 (3.0, 0.0, 0.0); GlDraw.begins `quads; GlDraw.color ( 0.5, 0.5, 1.0); GlDraw.vertex3 (-1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.ends (); Glut.swapBuffers () (* Handle window reshape events *) let reshape_cb ~w ~h = let ratio = (float_of_int w) /. (float_of_int h) in GlDraw.viewport 0 0 w h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective 45.0 ratio (0.1, 100.0); GlMat.mode `modelview; GlMat.load_identity () (* Handle keyboard events *) let keyboard_cb ~key ~x ~y = match key with | 27 (* ESC *) -> exit 0 | _ -> () let main () = let width = 640 and height = 480 in ignore (Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true ~double_buffer:true (); Glut.initWindowSize width height; ignore (Glut.createWindow "O'Caml OpenGL Lesson 3"); Glut.displayFunc draw_gl_scene; Glut.keyboardFunc keyboard_cb; Glut.reshapeFunc reshape_cb; init_gl width height; Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/nehe/lesson4.ml000066400000000000000000000045771437514534100211060ustar00rootroot00000000000000(* * This code was created by Jeff Molofee '99 * If you've found this code useful, please let me know. * * Visit Jeff at http://nehe.gamedev.net/ * * Ported to O'Caml/lablglut by Jeffrey Palmer 8/02 * For port-specific issues, comments, etc., please * contact jeffrey.palmer@acm.org *) let rtri = ref 0.0 let rquad = ref 0.0 let init_gl width height = GlDraw.shade_model `smooth; GlClear.color (0.0, 0.0, 0.0); GlClear.depth 1.0; GlClear.clear [`color; `depth]; Gl.enable `depth_test; GlFunc.depth_func `lequal; GlMisc.hint `perspective_correction `nicest let draw_gl_scene () = GlClear.clear [`color; `depth]; GlMat.load_identity (); (* Draw the triangle *) GlMat.translate3 (-1.5, 0.0, -6.0); GlMat.rotate3 !rtri (0.0, 1.0, 0.0); GlDraw.begins `triangles; GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.ends (); (* Draw the square *) GlMat.load_identity (); GlMat.translate3 (1.5, 0.0, -6.0); GlMat.rotate3 !rquad (1.0, 0.0, 0.0); GlDraw.begins `quads; GlDraw.color ( 0.5, 0.5, 1.0); GlDraw.vertex3 (-1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0, -1.0, 0.0); GlDraw.vertex3 (-1.0, -1.0, 0.0); GlDraw.ends (); Glut.swapBuffers (); rtri := !rtri +. 0.2; rquad := !rquad -. 0.15 (* Handle window reshape events *) let reshape_cb ~w ~h = let ratio = (float_of_int w) /. (float_of_int h) in GlDraw.viewport 0 0 w h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective 45.0 ratio (0.1, 100.0); GlMat.mode `modelview; GlMat.load_identity () (* Handle keyboard events *) let keyboard_cb ~key ~x ~y = match key with | 27 (* ESC *) -> exit 0 | _ -> () (* Draw the scene whever idle *) let idle_cb () = draw_gl_scene () let main () = let width = 640 and height = 480 in ignore (Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true ~double_buffer:true (); Glut.initWindowSize width height; ignore (Glut.createWindow "O'Caml OpenGL Lesson 4"); Glut.displayFunc draw_gl_scene; Glut.keyboardFunc keyboard_cb; Glut.reshapeFunc reshape_cb; Glut.idleFunc(Some idle_cb); init_gl width height; Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/examples/nehe/lesson5.ml000066400000000000000000000101671437514534100210770ustar00rootroot00000000000000(* * This code was created by Jeff Molofee '99 * If you've found this code useful, please let me know. * * Visit Jeff at http://nehe.gamedev.net/ * * Ported to O'Caml/lablglut by Jeffrey Palmer 8/02 * For port-specific issues, comments, etc., please * contact jeffrey.palmer@acm.org *) let rtri = ref 0.0 let rquad = ref 0.0 let init_gl width height = GlDraw.shade_model `smooth; GlClear.color (0.0, 0.0, 0.0); GlClear.depth 1.0; GlClear.clear [`color; `depth]; Gl.enable `depth_test; GlFunc.depth_func `lequal; GlMisc.hint `perspective_correction `nicest let draw_gl_scene () = GlClear.clear [`color; `depth]; GlMat.load_identity (); (* Draw the pyramid *) GlMat.translate3 (-1.5, 0.0, -6.0); GlMat.rotate3 !rtri (0.0, 1.0, 0.0); GlDraw.begins `triangles; GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 (-1.0,-1.0, 1.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 ( 1.0,-1.0, 1.0); GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 ( 1.0,-1.0, 1.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0,-1.0,-1.0); GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 ( 1.0,-1.0,-1.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 (-1.0,-1.0,-1.0); GlDraw.color ( 1.0, 0.0, 0.0); GlDraw.vertex3 ( 0.0, 1.0, 0.0); GlDraw.color ( 0.0, 0.0, 1.0); GlDraw.vertex3 (-1.0,-1.0,-1.0); GlDraw.color ( 0.0, 1.0, 0.0); GlDraw.vertex3 (-1.0,-1.0, 1.0); GlDraw.ends (); (* Draw the square *) GlMat.load_identity (); GlMat.translate3 (1.5, 0.0, -7.0); GlMat.rotate3 !rquad (1.0, 1.0, 1.0); GlDraw.begins `quads; GlDraw.color (0.0,1.0,0.0); GlDraw.vertex3 ( 1.0, 1.0,-1.0); GlDraw.vertex3 (-1.0, 1.0,-1.0); GlDraw.vertex3 (-1.0, 1.0, 1.0); GlDraw.vertex3 ( 1.0, 1.0, 1.0); GlDraw.color (1.0,0.5,0.0); GlDraw.vertex3 ( 1.0,-1.0, 1.0); GlDraw.vertex3 (-1.0,-1.0, 1.0); GlDraw.vertex3 (-1.0,-1.0,-1.0); GlDraw.vertex3 ( 1.0,-1.0,-1.0); GlDraw.color (1.0,0.0,0.0); GlDraw.vertex3 ( 1.0, 1.0, 1.0); GlDraw.vertex3 (-1.0, 1.0, 1.0); GlDraw.vertex3 (-1.0,-1.0, 1.0); GlDraw.vertex3 ( 1.0,-1.0, 1.0); GlDraw.color (1.0,1.0,0.0); GlDraw.vertex3 ( 1.0,-1.0,-1.0); GlDraw.vertex3 (-1.0,-1.0,-1.0); GlDraw.vertex3 (-1.0, 1.0,-1.0); GlDraw.vertex3 ( 1.0, 1.0,-1.0); GlDraw.color (0.0,0.0,1.0); GlDraw.vertex3 (-1.0, 1.0, 1.0); GlDraw.vertex3 (-1.0, 1.0,-1.0); GlDraw.vertex3 (-1.0,-1.0,-1.0); GlDraw.vertex3 (-1.0,-1.0, 1.0); GlDraw.color (1.0,0.0,1.0); GlDraw.vertex3 ( 1.0, 1.0,-1.0); GlDraw.vertex3 ( 1.0, 1.0, 1.0); GlDraw.vertex3 ( 1.0,-1.0, 1.0); GlDraw.vertex3 ( 1.0,-1.0,-1.0); GlDraw.ends (); Glut.swapBuffers (); rtri := !rtri +. 0.2; rquad := !rquad -. 0.15 (* Handle window reshape events *) let reshape_cb ~w ~h = let ratio = (float_of_int w) /. (float_of_int h) in GlDraw.viewport 0 0 w h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective 45.0 ratio (0.1, 100.0); GlMat.mode `modelview; GlMat.load_identity () (* Handle keyboard events *) let keyboard_cb ~key ~x ~y = match key with | 27 (* ESC *) -> exit 0 | _ -> () (* Draw the scene whever idle *) let idle_cb () = draw_gl_scene () let main () = let width = 640 and height = 480 in ignore (Glut.init Sys.argv); Glut.initDisplayMode ~alpha:true ~depth:true ~double_buffer:true (); Glut.initWindowSize width height; ignore (Glut.createWindow "O'Caml OpenGL Lesson 5"); Glut.displayFunc draw_gl_scene; Glut.keyboardFunc keyboard_cb; Glut.reshapeFunc reshape_cb; Glut.idleFunc(Some idle_cb); init_gl width height; Glut.mainLoop () let _ = main () lablgl-1.07/LablGlut/lgcompile000077500000000000000000000007121437514534100163140ustar00rootroot00000000000000#!/usr/bin/env perl # compile a single-file lablglut demo sub sys { $cmd = @_[0]; print "$cmd\n"; system $cmd; } $bname = shift @ARGV; $bname =~ s/\.ml$//; $OCAML = $ENV{OCAML}; sys("ocamlc -I $OCAML/lablglut -I $OCAML/lablGL -g -c $bname.ml") or sys("ocamlc -I $OCAML/lablglut -I $OCAML/lablGL -g -o $bname " . "$OCAML/lablglut/lablglut.cma $OCAML/lablGL/lablgl.cma $bname.cmo") or sys("rm $bname.{cmi,cmo}") or # sys("ocamldebug $bname"); lablgl-1.07/LablGlut/src/000077500000000000000000000000001437514534100152025ustar00rootroot00000000000000lablgl-1.07/LablGlut/src/.cvsignore000066400000000000000000000000411437514534100171750ustar00rootroot00000000000000lablglut lablgluttop* dll* *.lib lablgl-1.07/LablGlut/src/.depend000066400000000000000000000005721437514534100164460ustar00rootroot00000000000000gl_constants.cmo: gl_constants.cmi gl_constants.cmx: gl_constants.cmi glocaml.cmo: glutcaml.cmi glocaml.cmx: glutcaml.cmx glu_constants.cmo: glu_constants.cmi glu_constants.cmx: glu_constants.cmi glut.cmo: glut.cmi glut.cmx: glut.cmi glut_constants.cmo: glut_constants.cmi glut_constants.cmx: glut_constants.cmi glutcaml.cmo: glutcaml.cmi glutcaml.cmx: glutcaml.cmi lablgl-1.07/LablGlut/src/Makefile000066400000000000000000000053241437514534100166460ustar00rootroot00000000000000# Include shared parts TOPDIR = ../.. include $(TOPDIR)/Makefile.common # Composite options INCLUDES = $(GLINCLUDES) $(XINCLUDES) -I$(SRCDIR) LIBS = $(GLUTLIBS) $(GLLIBS) $(XLIBS) LIBDIRS = OCAMLINC= # Files LIBOBJS = glut.cmo OPTOBJS = $(LIBOBJS:.cmo=.cmx) COBJS = wrap_glut$(XO) all: lib lablgluttop$(XE) lablglut$(XB) opt: libopt lib: lablglut.cma libopt: lablglut.cmxa ifeq ($(TOOLCHAIN), msvc) liblablglut$(XA): $(COBJS) $(MKLIB)$@ $(COBJS) dlllablglut.dll: $(COBJS:$(XO)=.d$(XO)) $(MKDLL)$@ $(COBJS:$(XO)=.d$(XO)) $(GLUTLIBS) $(GLLIBS) $(OCAMLDLL) lablglut.cma: liblablglut$(XA) dlllablglut.dll $(LIBOBJS) ../../Makefile.config $(LINKER) -a -o $@ $(LIBOBJS) \ -cclib -llablglut -dllib -llablglut \ -cclib "$(GLLIBS)" -cclib "$(GLUTLIBS)" lablglut.cmxa: liblablglut$(XA) $(OPTOBJS) ../../Makefile.config $(OPTLINK) -a -o $@ $(OPTOBJS) -cclib -llablglut \ -cclib "$(GLLIBS)" -cclib "$(GLUTLIBS)" else liblablglut$(XA): lablglut.cma lablglut.cma: $(COBJS) $(LIBOBJS) ../../Makefile.config $(LIBRARIAN) -o lablglut $(COBJS) $(LIBOBJS) $(GLUTLIBS) $(GLLIBS) $(XLIBS) lablglut.cmxa: $(COBJS) $(OPTOBJS) ../../Makefile.config $(LIBRARIAN) -o lablglut $(COBJS) $(OPTOBJS) $(GLUTLIBS) $(GLLIBS) $(XLIBS) endif lablgluttop$(XE): lablglut.cma ocamlmktop $(CUSTOMTOP) -I . -I $(SRCDIR) $(OCAMLINC) -o $@ \ lablglut.cma lablgl.cma lablglut: $(CONFIG) Makefile liblablglut$(XA) $(MAKE) INSTALLDIR="$(INSTALLDIR)" real-$@ real-lablglut: @echo generate lablglut echo "#!/bin/sh" > lablglut echo "# toplevel with lablGL and LablGlut" >> lablglut if test -f dlllablglut$(XS); then \ echo 'exec ocaml -I "$(INSTALLDIR)" lablgl.cma lablglut.cma $$*' >> lablglut; \ else echo 'exec "$(INSTALLDIR)/lablgluttop" -I "$(INSTALLDIR)" $$*' >> lablglut; fi chmod 755 lablglut install: @if test -f lablglut.cma; then $(MAKE) real-install; fi preinstall: if test -d "$(INSTALLDIR)"; then : ; else mkdir -p "$(INSTALLDIR)"; fi cp $(LIBOBJS:.cmo=.ml) $(LIBOBJS:.cmo=.mli) "$(INSTALLDIR)" cp liblablglut$(XA) "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) liblablglut$(XA) @if test -f dlllablglut$(XS); then $(MAKE) installdll; \ else $(MAKE) installtop; fi cp lablglut$(XB) "$(BINDIR)" real-install: preinstall cp $(LIBOBJS:.cmo=.cmi) lablglut.cma "$(INSTALLDIR)" @if test -f lablglut.cmxa; then $(MAKE) installopt; fi installdll: cp dlllablglut$(XS) "$(DLLDIR)" installtop: cp lablgluttop$(XE) "$(INSTALLDIR)" installopt: cp lablglut.cmxa lablglut$(XA) $(LIBOBJS:.cmo=.cmx) "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) lablglut$(XA) clean: rm -f *.cm* *.o *.obj *.a lib*.lib *.so *.dll *.exe *.opt \ *_tags.c *_tags.h *~ lablgluttop$(EX) lablglut depend: ocamldep -pp camlp4o *.ml *.mli > .depend include .depend lablgl-1.07/LablGlut/src/glut.ml000066400000000000000000000663111437514534100165160ustar00rootroot00000000000000(* ==== types ==== *) type button_t = | LEFT_BUTTON | MIDDLE_BUTTON | RIGHT_BUTTON | OTHER_BUTTON of int type mouse_button_state_t = | DOWN | UP type special_key_t = | KEY_F1 | KEY_F2 | KEY_F3 | KEY_F4 | KEY_F5 | KEY_F6 | KEY_F7 | KEY_F8 | KEY_F9 | KEY_F10 | KEY_F11 | KEY_F12 (* directional keys *) | KEY_LEFT | KEY_UP | KEY_RIGHT | KEY_DOWN | KEY_PAGE_UP | KEY_PAGE_DOWN | KEY_HOME | KEY_END | KEY_INSERT (* for undefined keys *) | KEY_OTHER of int type entry_exit_state_t = | LEFT | ENTERED type menu_state_t = | MENU_NOT_IN_USE | MENU_IN_USE type visibility_state_t = | NOT_VISIBLE | VISIBLE type window_status_t = | HIDDEN | FULLY_RETAINED | PARTIALLY_RETAINED | FULLY_COVERED type color_index_component_t = | RED | GREEN | BLUE type layer_t = | NORMAL | OVERLAY type font_t = | STROKE_ROMAN | STROKE_MONO_ROMAN | BITMAP_9_BY_15 | BITMAP_8_BY_13 | BITMAP_TIMES_ROMAN_10 | BITMAP_TIMES_ROMAN_24 | BITMAP_HELVETICA_10 | BITMAP_HELVETICA_12 | BITMAP_HELVETICA_18 type glut_get_t = | WINDOW_X | WINDOW_Y | WINDOW_WIDTH | WINDOW_HEIGHT | WINDOW_BUFFER_SIZE | WINDOW_STENCIL_SIZE | WINDOW_DEPTH_SIZE | WINDOW_RED_SIZE | WINDOW_GREEN_SIZE | WINDOW_BLUE_SIZE | WINDOW_ALPHA_SIZE | WINDOW_ACCUM_RED_SIZE | WINDOW_ACCUM_GREEN_SIZE | WINDOW_ACCUM_BLUE_SIZE | WINDOW_ACCUM_ALPHA_SIZE | WINDOW_DOUBLEBUFFER | WINDOW_RGBA | WINDOW_PARENT | WINDOW_NUM_CHILDREN | WINDOW_COLORMAP_SIZE | WINDOW_NUM_SAMPLES | WINDOW_STEREO | WINDOW_CURSOR | SCREEN_WIDTH | SCREEN_HEIGHT | SCREEN_WIDTH_MM | SCREEN_HEIGHT_MM | MENU_NUM_ITEMS (* | DISPLAY_MODE_POSSIBLE : use getBool *) | INIT_WINDOW_X | INIT_WINDOW_Y | INIT_WINDOW_WIDTH | INIT_WINDOW_HEIGHT | INIT_DISPLAY_MODE | ELAPSED_TIME | WINDOW_FORMAT_ID type glut_get_bool_t = | DISPLAY_MODE_POSSIBLE let rgb = 0;; let rgba = rgb;; (* same as in glut.h *) let index = 1;; let single = 0;; let double = 2;; let accum = 4;; let alpha = 8;; let depth = 16;; let stencil = 32;; let multisample = 128;; let stereo = 256;; let luminance = 512;; type device_get_t = | HAS_KEYBOARD | HAS_MOUSE | HAS_SPACEBALL | HAS_DIAL_AND_BUTTON_BOX | HAS_TABLET | NUM_MOUSE_BUTTONS | NUM_SPACEBALL_BUTTONS | NUM_BUTTON_BOX_BUTTONS | NUM_DIALS | NUM_TABLET_BUTTONS | DEVICE_IGNORE_KEY_REPEAT | DEVICE_KEY_REPEAT | HAS_JOYSTICK | OWNS_JOYSTICK | JOYSTICK_BUTTONS | JOYSTICK_AXES | JOYSTICK_POLL_RATE type layerget_t = | OVERLAY_POSSIBLE (* | LAYER_IN_USE : use layerGetInUse *) | HAS_OVERLAY (* | TRANSPARENT_INDEX : use layerGetTransparentIndex *) | NORMAL_DAMAGED | OVERLAY_DAMAGED type video_resize_t = | VIDEO_RESIZE_POSSIBLE | VIDEO_RESIZE_IN_USE | VIDEO_RESIZE_X_DELTA | VIDEO_RESIZE_Y_DELTA | VIDEO_RESIZE_WIDTH_DELTA | VIDEO_RESIZE_HEIGHT_DELTA | VIDEO_RESIZE_X | VIDEO_RESIZE_Y | VIDEO_RESIZE_WIDTH | VIDEO_RESIZE_HEIGHT type get_modifiers_t = | ACTIVE_SHIFT | ACTIVE_CTRL | ACTIVE_ALT let active_shift = 1 let active_ctrl = 2 let active_alt = 4 type cursor_t = (* Basic arrows. *) | CURSOR_RIGHT_ARROW | CURSOR_LEFT_ARROW (* Symbolic cursor shapes. *) | CURSOR_INFO | CURSOR_DESTROY | CURSOR_HELP | CURSOR_CYCLE | CURSOR_SPRAY | CURSOR_WAIT | CURSOR_TEXT | CURSOR_CROSSHAIR (* Directional cursors. *) | CURSOR_UP_DOWN | CURSOR_LEFT_RIGHT (* Sizing cursors. *) | CURSOR_TOP_SIDE | CURSOR_BOTTOM_SIDE | CURSOR_LEFT_SIDE | CURSOR_RIGHT_SIDE | CURSOR_TOP_LEFT_CORNER | CURSOR_TOP_RIGHT_CORNER | CURSOR_BOTTOM_RIGHT_CORNER | CURSOR_BOTTOM_LEFT_CORNER | CURSOR_INHERIT (* inherit cursor from parent window *) | CURSOR_NONE (* blank cursor *) | CURSOR_FULL_CROSSHAIR (* full-screen crosshair : if available *) type game_mode_t = | GAME_MODE_ACTIVE | GAME_MODE_POSSIBLE | GAME_MODE_WIDTH | GAME_MODE_HEIGHT | GAME_MODE_PIXEL_DEPTH | GAME_MODE_REFRESH_RATE | GAME_MODE_DISPLAY_CHANGED type key_repeat_t = | KEY_REPEAT_OFF | KEY_REPEAT_ON | KEY_REPEAT_DEFAULT exception BadEnum of string exception InvalidState of string exception OverlayNotInUse of string open Printf;; (* ==== file-local variables ==== *) let is_init = ref false;; let is_displayModeInit = ref false;; let is_windowSizeInit = ref false;; let is_windowPositionInit = ref false;; let has_createdWindow = ref false;; (* === GLUT initialization sub-API. === *) external _glutInit : int -> string array -> int = "ml_glutInit" let init ~argv = if !is_init then argv else begin is_init := true; let argc = Array.length argv in let argv = Array.append argv [|""|] in let argc = _glutInit argc argv in Array.sub argv 0 argc end external _glutInitDisplayMode : double_buffer:bool -> index:bool -> accum:bool -> alpha:bool -> depth:bool -> stencil:bool -> multisample:bool -> stereo:bool -> luminance:bool -> unit = "bytecode_glutInitDisplayMode" "native_glutInitDisplayMode" let initDisplayMode ?(double_buffer=false) ?(index=false) ?(accum=false) ?(alpha=false) ?(depth=false) ?(stencil=false) ?(multisample=false) ?(stereo=false) ?(luminance=false) dummy_unit = is_displayModeInit := true; _glutInitDisplayMode double_buffer index accum alpha depth stencil multisample stereo luminance ;; external _glutInitWindowSize : int->int->unit = "ml_glutInitWindowSize" external _glutInitWindowPosition : int->int->unit = "ml_glutInitWindowPosition" let initWindowPosition ~x ~y = is_windowPositionInit := true; _glutInitWindowPosition x y;; let initWindowSize ~w ~h = is_windowSizeInit := true; _glutInitWindowSize w h;; external mainLoop : unit->unit = "ml_glutMainLoop" (* === GLUT window sub-API. === *) external _glutCreateWindow : string->int = "ml_glutCreateWindow" let createWindow ~title = has_createdWindow := true; let winid = _glutCreateWindow title in winid;; external postRedisplay : unit->unit = "ml_glutPostRedisplay" external swapBuffers : unit->unit = "ml_glutSwapBuffers" external createSubWindow: win:int->x:int->y:int->w:int->h:int->int = "ml_glutCreateSubWindow" external destroyWindow: win:int -> unit = "ml_glutDestroyWindow" external setWindow: win:int -> unit = "ml_glutSetWindow" external getWindow: unit -> int = "ml_glutGetWindow" external setWindowTitle: title:string -> unit = "ml_glutSetWindowTitle" external setIconTitle: title:string -> unit = "ml_glutSetIconTitle" external positionWindow: x:int -> y:int -> unit = "ml_glutPositionWindow" external reshapeWindow: w:int -> h:int -> unit = "ml_glutReshapeWindow" external popWindow: unit -> unit = "ml_glutPopWindow" external pushWindow: unit -> unit = "ml_glutPushWindow" external iconifyWindow: unit -> unit = "ml_glutIconifyWindow" external showWindow: unit -> unit = "ml_glutShowWindow" external hideWindow: unit -> unit = "ml_glutHideWindow" external fullScreen: unit -> unit = "ml_glutFullScreen" external _setCursor: c:int -> unit = "ml_glutSetCursor" let setCursor c = let ic = match c with (* Basic arrows. *) | CURSOR_RIGHT_ARROW -> 0 (* values from glut.h *) | CURSOR_LEFT_ARROW -> 1 (* Symbolic cursor shapes. *) | CURSOR_INFO -> 2 | CURSOR_DESTROY -> 3 | CURSOR_HELP -> 4 | CURSOR_CYCLE -> 5 | CURSOR_SPRAY -> 6 | CURSOR_WAIT -> 7 | CURSOR_TEXT -> 8 | CURSOR_CROSSHAIR -> 9 (* Directional cursors. *) | CURSOR_UP_DOWN -> 10 | CURSOR_LEFT_RIGHT -> 11 (* Sizing cursors. *) | CURSOR_TOP_SIDE -> 12 | CURSOR_BOTTOM_SIDE -> 13 | CURSOR_LEFT_SIDE -> 14 | CURSOR_RIGHT_SIDE -> 15 | CURSOR_TOP_LEFT_CORNER -> 16 | CURSOR_TOP_RIGHT_CORNER -> 17 | CURSOR_BOTTOM_RIGHT_CORNER -> 18 | CURSOR_BOTTOM_LEFT_CORNER -> 19 | CURSOR_INHERIT -> 100 | CURSOR_NONE -> 101 | CURSOR_FULL_CROSSHAIR -> 102 in _setCursor ic ;; (* === GLUT overlay sub-API. === *) external establishOverlay: unit->unit = "ml_glutEstablishOverlay" external removeOverlay: unit->unit = "ml_glutRemoveOverlay" external postOverlayRedisplay: unit->unit = "ml_glutPostOverlayRedisplay" external showOverlay: unit->unit = "ml_glutShowOverlay" external hideOverlay: unit->unit = "ml_glutHideOverlay" external _useLayer: int -> unit = "ml_glutUseLayer" let useLayer layer = _useLayer (match layer with NORMAL -> 0 | OVERLAY -> 1) (* === GLUT menu sub-API. === *) external createMenu: cb:(value:int -> unit) ->int = "ml_glutCreateMenu" external destroyMenu: menu:int->unit = "ml_glutDestroyMenu" external getMenu: unit->int = "ml_glutGetMenu" external setMenu: menu:int->unit = "ml_glutSetMenu" external addMenuEntry: label:string->value:int->unit = "ml_glutAddMenuEntry" external addSubMenu: label:string->submenu:int->unit = "ml_glutAddSubMenu" external changeToMenuEntry: item:int->label:string->value:int->unit = "ml_glutChangeToMenuEntry" external changeToSubMenu: item:int->label:string->submenu:int->unit = "ml_glutChangeToSubMenu" external removeMenuItem: item:int->unit= "ml_glutRemoveMenuItem" let int_of_button b = match b with | LEFT_BUTTON -> 0 | MIDDLE_BUTTON -> 1 | RIGHT_BUTTON -> 2 | OTHER_BUTTON n -> n let b2i b = int_of_button b;; external _attachMenu: button:int->unit= "ml_glutAttachMenu" let attachMenu ~button = _attachMenu (b2i button);; external _detachMenu: button:int->unit= "ml_glutDetachMenu" let detachMenu ~button = _detachMenu (b2i button);; (* === GLUT window callback sub-API. === *) let window_wrapper cbFunc wr = let table = Hashtbl.create 3 in fun ~cb -> Hashtbl.add table (getWindow()) cb; cbFunc ~cb:(wr (fun () -> Hashtbl.find table (getWindow()))) external _displayFunc : cb:(unit->unit)->unit = "ml_glutDisplayFunc" let displayFunc = window_wrapper _displayFunc (fun cb () -> cb () ()) external _reshapeFunc : cb:(w:int->h:int->unit)->unit = "ml_glutReshapeFunc" let reshapeFunc = window_wrapper _reshapeFunc (fun cb ~w -> cb () ~w) external _keyboardFunc : cb:(key:int->x:int->y:int->unit)->unit = "ml_glutKeyboardFunc" let keyboardFunc = window_wrapper _keyboardFunc (fun cb ~key -> cb () ~key) external _glutMouseFunc : cb:(int -> int -> int -> int -> unit)->unit = "ml_glutMouseFunc" let mouse_cb_wrapper user_func ibutton istate x y = let b = match ibutton with | 0 -> LEFT_BUTTON | 1 -> MIDDLE_BUTTON | 2 -> RIGHT_BUTTON | n -> OTHER_BUTTON n in let s = match istate with | 0 -> DOWN | 1 -> UP | _ -> raise (BadEnum "istate in mouse_cb_wrapper") in user_func () ~button:b ~state:s ~x ~y;; let mouseFunc = window_wrapper _glutMouseFunc mouse_cb_wrapper let eta_x cb ~x = cb () ~x external _motionFunc : cb:(x:int->y:int->unit)->unit = "ml_glutMotionFunc" let motionFunc = window_wrapper _motionFunc eta_x external _passiveMotionFunc : cb:(x:int->y:int->unit)->unit = "ml_glutPassiveMotionFunc" let passiveMotionFunc = window_wrapper _passiveMotionFunc eta_x let eta_state cb ~state = cb () ~state external _entryFunc : cb:(state:entry_exit_state_t->unit)->unit = "ml_glutEntryFunc" let entryFunc = window_wrapper _entryFunc eta_state external _visibilityFunc : cb:(state:visibility_state_t->unit)->unit = "ml_glutVisibilityFunc" let visibilityFunc = window_wrapper _visibilityFunc eta_state (* idleFunc is for the entire program, not just a single window, so its name does not depend on the window id *) external _glutIdleFunc:(unit->unit)->unit="ml_glutIdleFunc" external _setIdleFuncToNull:unit->unit="ml_glutSetIdleFuncToNull" let idleFunc ~cb = match cb with | None -> _setIdleFuncToNull(); | Some cb -> begin _glutIdleFunc cb; end ;; (* timerFunc is non-window-dependent *) external _timerFunc : int -> int -> unit = "ml_glutTimerFunc" external init_timerFunc : (int -> unit) -> unit = "init_glutTimerFunc_cb" let timer_hashtbl = Hashtbl.create 101 let real_call_back i = Hashtbl.find timer_hashtbl i () let _ = init_timerFunc real_call_back let timer_count = ref 0 let timerFunc ~ms ~cb:(cb:(value:'a -> unit)) ~value = let i = !timer_count in incr timer_count; Hashtbl.add timer_hashtbl i (fun () -> Hashtbl.remove timer_hashtbl i; cb value); _timerFunc ms i let special_of_int = function | 1 -> KEY_F1 (* values from glut.h *) | 2 -> KEY_F2 | 3 -> KEY_F3 | 4 -> KEY_F4 | 5 -> KEY_F5 | 6 -> KEY_F6 | 7 -> KEY_F7 | 8 -> KEY_F8 | 9 -> KEY_F9 | 10 -> KEY_F10 | 11 -> KEY_F11 | 12 -> KEY_F12 | 100 -> KEY_LEFT | 101 -> KEY_UP | 102 -> KEY_RIGHT | 103 -> KEY_DOWN | 104 -> KEY_PAGE_UP | 105 -> KEY_PAGE_DOWN | 106 -> KEY_HOME | 107 -> KEY_END | 108 -> KEY_INSERT | i -> KEY_OTHER i external _glutSpecialFunc : cb:(key:int->x:int->y:int->unit)->unit = "ml_glutSpecialFunc" let specialFunc = window_wrapper _glutSpecialFunc (fun cb ~key -> cb () ~key:(special_of_int key)) external _spaceballMotionFunc: cb:(x:int->y:int->z:int->unit)->unit = "ml_glutSpaceballMotionFunc" let spaceballMotionFunc = window_wrapper _spaceballMotionFunc eta_x external _spaceballRotateFunc: cb:(x:int->y:int->z:int->unit)->unit = "ml_glutSpaceballRotateFunc" let spaceballRotateFunc = window_wrapper _spaceballRotateFunc eta_x let eta_button cb ~button = cb () ~button external _spaceballButtonFunc: cb:(button:int->state:int->unit)->unit = "ml_glutSpaceballButtonFunc" let spaceballButtonFunc = window_wrapper _spaceballButtonFunc eta_button external _buttonBoxFunc: cb:(button:int->state:int->unit)->unit = "ml_glutButtonBoxFunc" let buttonBoxFunc = window_wrapper _buttonBoxFunc eta_button external _dialsFunc: cb:(dial:int->value:int->unit)->unit = "ml_glutDialsFunc" let dialsFunc = window_wrapper _dialsFunc (fun cb ~dial -> cb () ~dial) external _tabletMotionFunc: cb:(x:int->y:int->unit)->unit = "ml_glutTabletMotionFunc" let tabletMotionFunc = window_wrapper _tabletMotionFunc eta_x external _tabletButtonFunc: cb:(button:int->state:int->x:int->y:int->unit)->unit = "ml_glutTabletButtonFunc" let tabletButtonFunc = window_wrapper _tabletButtonFunc eta_button external menuStatusFunc: cb:(status:menu_state_t->x:int->y:int->unit)->unit = "ml_glutMenuStatusFunc" external _overlayDisplayFunc: cb:(unit->unit)->unit = "ml_glutOverlayDisplayFunc" let overlayDisplayFunc = window_wrapper _overlayDisplayFunc (fun cb () -> cb () ()) (* === GLUT color index sub-API. === === *) external setColor: cell:int->red:float->green:float->blue:float->unit = "ml_glutSetColor" external getColor: index:int->component:int->float = "ml_glutGetColor" external copyColormap: win:int->unit = "ml_glutCopyColormap" (* === GLUT state retrieval sub-API. === *) external _get: igtype:int->int = "ml_glutGet" let get ~gtype = let igtype = match gtype with | WINDOW_X -> 100 | WINDOW_Y -> 101 | WINDOW_WIDTH -> 102 | WINDOW_HEIGHT -> 103 | WINDOW_BUFFER_SIZE -> 104 | WINDOW_STENCIL_SIZE -> 105 | WINDOW_DEPTH_SIZE -> 106 | WINDOW_RED_SIZE -> 107 | WINDOW_GREEN_SIZE -> 108 | WINDOW_BLUE_SIZE -> 109 | WINDOW_ALPHA_SIZE -> 110 | WINDOW_ACCUM_RED_SIZE -> 111 | WINDOW_ACCUM_GREEN_SIZE -> 112 | WINDOW_ACCUM_BLUE_SIZE -> 113 | WINDOW_ACCUM_ALPHA_SIZE -> 114 | WINDOW_DOUBLEBUFFER -> 115 | WINDOW_RGBA -> 116 | WINDOW_PARENT -> 117 | WINDOW_NUM_CHILDREN -> 118 | WINDOW_COLORMAP_SIZE -> 119 | WINDOW_NUM_SAMPLES -> 120 | WINDOW_STEREO -> 121 | WINDOW_CURSOR -> 122 | SCREEN_WIDTH -> 200 | SCREEN_HEIGHT -> 201 | SCREEN_WIDTH_MM -> 202 | SCREEN_HEIGHT_MM -> 203 | MENU_NUM_ITEMS -> 300 (* | DISPLAY_MODE_POSSIBLE -> 400 *) | INIT_WINDOW_X -> 500 | INIT_WINDOW_Y -> 501 | INIT_WINDOW_WIDTH -> 502 | INIT_WINDOW_HEIGHT -> 503 | INIT_DISPLAY_MODE -> 504 | ELAPSED_TIME -> 700 | WINDOW_FORMAT_ID -> 123 in _get igtype ;; let getBool ~gtype = _get (match gtype with DISPLAY_MODE_POSSIBLE -> 400) <> 0 external _deviceGet: idgtype:int->int = "ml_glutDeviceGet" let deviceGet ~dgtype = let idgtype = match dgtype with | HAS_KEYBOARD -> 600 | HAS_MOUSE -> 601 | HAS_SPACEBALL -> 602 | HAS_DIAL_AND_BUTTON_BOX -> 603 | HAS_TABLET -> 604 | NUM_MOUSE_BUTTONS -> 605 | NUM_SPACEBALL_BUTTONS -> 606 | NUM_BUTTON_BOX_BUTTONS -> 607 | NUM_DIALS -> 608 | NUM_TABLET_BUTTONS -> 609 | DEVICE_IGNORE_KEY_REPEAT -> 610 | DEVICE_KEY_REPEAT -> 611 | HAS_JOYSTICK -> 612 | OWNS_JOYSTICK -> 613 | JOYSTICK_BUTTONS -> 614 | JOYSTICK_AXES -> 615 | JOYSTICK_POLL_RATE -> 616 in _deviceGet idgtype;; (* === GLUT extension support sub-API === *) external extensionSupported: name:string->bool = "ml_glutExtensionSupported" external getModifiers: unit->int = "ml_glutGetModifiers" (* let getModifiers () = let m = _getModifiers() in if m land 1 <> 0 then [ACTIVE_SHIFT] else [] @ if m land 2 <> 0 then [ACTIVE_CTRL] else [] @ if m land 4 <> 0 then [ACTIVE_ALT] else [];; *) let int_of_modifiers m = let ret = ref 0 in let rec f = function | [] -> () | h::t -> begin ret := (!ret lor (match h with | ACTIVE_SHIFT -> 1 | ACTIVE_CTRL -> 2 | ACTIVE_ALT -> 4)); f t end in f m; !ret;; external _layerGet: int->int = "ml_glutLayerGet" let layerGet ~lgtype = let ilgtype = match lgtype with | OVERLAY_POSSIBLE -> 800 | HAS_OVERLAY -> 802 | NORMAL_DAMAGED -> 804 | OVERLAY_DAMAGED -> 805 in let ret = _layerGet ilgtype in if lgtype = OVERLAY_DAMAGED && ret = -1 then raise (OverlayNotInUse "in layerGet OVERLAY_DAMAGED") else ret <> 0 ;; let layerGetTransparentIndex() = _layerGet 803 ;; (* from glut.h *) let layerGetInUse () = match _layerGet 801 with | 0 -> NORMAL | 1 -> OVERLAY | _ -> failwith "unexpected value in layerGetInUse" (* === GLUT font sub-API === *) (* convert font to integer value from glut.h *) let f2i font = match font with | STROKE_ROMAN -> 0 | STROKE_MONO_ROMAN -> 1 | BITMAP_9_BY_15 -> 2 | BITMAP_8_BY_13 -> 3 | BITMAP_TIMES_ROMAN_10 -> 4 | BITMAP_TIMES_ROMAN_24 -> 5 | BITMAP_HELVETICA_10 -> 6 | BITMAP_HELVETICA_12 -> 7 | BITMAP_HELVETICA_18 -> 8;; external _bitmapCharacter: font:int->c:int->unit = "ml_glutBitmapCharacter" let bitmapCharacter ~font ~c = _bitmapCharacter (f2i font) c;; external _bitmapWidth: font:int->c:int->int = "ml_glutBitmapWidth" let bitmapWidth ~font ~c = _bitmapWidth (f2i font) c;; external _strokeCharacter: font:int->c:int->unit = "ml_glutStrokeCharacter" let strokeCharacter ~font ~c = _strokeCharacter (f2i font) c;; external _strokeWidth: font:int->c:int->int = "ml_glutStrokeWidth" let strokeWidth ~font ~c = _strokeWidth (f2i font) c;; (* === GLUT pre-built models sub-API === *) external wireSphere: radius:float->slices:int->stacks:int->unit = "ml_glutWireSphere" external solidSphere: radius:float->slices:int->stacks:int->unit = "ml_glutSolidSphere" external wireCone: base:float->height:float->slices:int->stacks:int->unit = "ml_glutWireCone" external solidCone: base:float->height:float->slices:int->stacks:int->unit = "ml_glutSolidCone" external wireCube: size:float->unit = "ml_glutWireCube" external solidCube: size:float->unit = "ml_glutSolidCube" external wireTorus: innerRadius:float->outerRadius:float->sides:int->rings:int ->unit = "ml_glutWireTorus" external solidTorus: innerRadius:float->outerRadius:float->sides:int->rings:int ->unit = "ml_glutSolidTorus" external wireDodecahedron: unit->unit = "ml_glutWireDodecahedron" external solidDodecahedron: unit->unit = "ml_glutSolidDodecahedron" external wireTeapot: size:float->unit = "ml_glutWireTeapot" external solidTeapot: size:float->unit = "ml_glutSolidTeapot" external wireOctahedron: unit->unit = "ml_glutWireOctahedron" external solidOctahedron: unit->unit = "ml_glutSolidOctahedron" external wireTetrahedron: unit->unit = "ml_glutWireTetrahedron" external solidTetrahedron: unit->unit = "ml_glutSolidTetrahedron" external wireIcosahedron: unit->unit = "ml_glutWireIcosahedron" external solidIcosahedron: unit->unit = "ml_glutSolidIcosahedron" (* GLUT version 4 functions included in the GLUT 3.7 distribution *) external initDisplayString: str:string->unit = "ml_glutInitDisplayString" external warpPointer: x:int->y:int->unit = "ml_glutWarpPointer" external _bitmapLength: font:int->str:string->int = "ml_glutBitmapLength" let bitmapLength ~font ~str = _bitmapLength (f2i font) str;; external _strokeLength: font:int->str:string->int = "ml_glutStrokeLength" let strokeLength ~font ~str = _strokeLength (f2i font) str;; external _windowStatusFunc: (int->unit)->unit = "ml_glutWindowStatusFunc" let windowStatusFunc ~cb = _windowStatusFunc (fun s -> cb ~state:(match s with | 0 -> HIDDEN | 1 -> FULLY_RETAINED | 2 -> PARTIALLY_RETAINED | 3 -> FULLY_COVERED | _ -> failwith "invalid value in glutWindowStatus ocaml callback")) ;; external postWindowRedisplay: win:int->unit = "ml_glutPostWindowRedisplay" external postWindowOverlayRedisplay: win:int->unit = "ml_glutPostWindowOverlayRedisplay" external keyboardUpFunc: cb:(key:int->x:int->y:int->unit)->unit = "ml_glutKeyboardUpFunc" external _glutSpecialUpFunc : (key:int->x:int->y:int->unit)->unit = "ml_glutSpecialUpFunc" let specialUpFunc ~cb = _glutSpecialUpFunc (fun ~key ->cb ~key:(special_of_int key));; external _ignoreKeyRepeat: ignore:int->unit = "ml_glutIgnoreKeyRepeat" let ignoreKeyRepeat ~ignore = _ignoreKeyRepeat (if ignore = true then 1 else 0) external _setKeyRepeat: mode:int->unit = "ml_glutSetKeyRepeat" let setKeyRepeat ~mode = _setKeyRepeat (match mode with | KEY_REPEAT_OFF -> 0 | KEY_REPEAT_ON -> 1 | KEY_REPEAT_DEFAULT -> 2 );; external joystickFunc: cb:(buttonMask:int->x:int->y:int->z:int->unit)-> pollInterval:int->unit = "ml_glutJoystickFunc" external forceJoystickFunc: unit->unit = "ml_glutForceJoystickFunc" (* GLUT video resize sub-API. *) external _videoResizeGet: int->int = "ml_glutVideoResizeGet" let videoResizeGet which = let i = match which with | VIDEO_RESIZE_POSSIBLE -> 900 | VIDEO_RESIZE_IN_USE -> 901 | VIDEO_RESIZE_X_DELTA -> 902 | VIDEO_RESIZE_Y_DELTA -> 903 | VIDEO_RESIZE_WIDTH_DELTA -> 904 | VIDEO_RESIZE_HEIGHT_DELTA -> 905 | VIDEO_RESIZE_X -> 906 | VIDEO_RESIZE_Y -> 907 | VIDEO_RESIZE_WIDTH -> 908 | VIDEO_RESIZE_HEIGHT -> 909 in _videoResizeGet i ;; external setupVideoResizing: unit->unit = "ml_glutSetupVideoResizing" external stopVideoResizing: unit->unit = "ml_glutStopVideoResizing" external videoResize: x:int->y:int->width:int->height:int->unit = "ml_glutVideoResize" external videoPan: x:int->y:int->width:int->height:int->unit = "ml_glutVideoPan" (* GLUT debugging sub-API. *) external reportErrors: unit->unit = "ml_glutReportErrors" (* GLUT game mode sub-API *) external gameModeString: str:string->unit = "ml_glutGameModeString" external enterGameMode: unit->unit = "ml_glutEnterGameMode" external leaveGameMode: unit->unit = "ml_glutLeaveGameMode" external _gameModeGet: mode:int->int = "ml_glutGameModeGet" let gameModeGet ~mode = let imode = match mode with | GAME_MODE_ACTIVE -> 0 | GAME_MODE_POSSIBLE -> 1 | GAME_MODE_WIDTH -> 2 | GAME_MODE_HEIGHT -> 3 | GAME_MODE_PIXEL_DEPTH -> 4 | GAME_MODE_REFRESH_RATE -> 5 | GAME_MODE_DISPLAY_CHANGED -> 6 in _gameModeGet imode;; (* ocaml specific *) let string_of_special key = match key with | KEY_F1 -> "KEY_F1" | KEY_F2 -> "KEY_F2" | KEY_F3 -> "KEY_F3" | KEY_F4 -> "KEY_F4" | KEY_F5 -> "KEY_F5" | KEY_F6 -> "KEY_F6" | KEY_F7 -> "KEY_F7" | KEY_F8 -> "KEY_F8" | KEY_F9 -> "KEY_F9" | KEY_F10 -> "KEY_F10" | KEY_F11 -> "KEY_F11" | KEY_F12 -> "KEY_F12" | KEY_LEFT -> "KEY_LEFT" | KEY_UP -> "KEY_UP" | KEY_RIGHT -> "KEY_RIGHT" | KEY_DOWN -> "KEY_DOWN" | KEY_PAGE_UP -> "KEY_PAGE_UP" | KEY_PAGE_DOWN -> "KEY_PAGE_DOWN" | KEY_HOME -> "KEY_HOME" | KEY_END -> "KEY_END" | KEY_INSERT -> "KEY_INSERT" | KEY_OTHER i -> "KEY_OTHER " ^ string_of_int i let int_of_cursor c = match c with | CURSOR_RIGHT_ARROW -> 0 | CURSOR_LEFT_ARROW -> 1 | CURSOR_INFO -> 2 | CURSOR_DESTROY -> 3 | CURSOR_HELP -> 4 | CURSOR_CYCLE -> 5 | CURSOR_SPRAY -> 6 | CURSOR_WAIT -> 7 | CURSOR_TEXT -> 8 | CURSOR_CROSSHAIR -> 9 | CURSOR_UP_DOWN -> 10 | CURSOR_LEFT_RIGHT -> 11 | CURSOR_TOP_SIDE -> 12 | CURSOR_BOTTOM_SIDE -> 13 | CURSOR_LEFT_SIDE -> 14 | CURSOR_RIGHT_SIDE -> 15 | CURSOR_TOP_LEFT_CORNER -> 16 | CURSOR_TOP_RIGHT_CORNER -> 17 | CURSOR_BOTTOM_RIGHT_CORNER -> 18 | CURSOR_BOTTOM_LEFT_CORNER -> 19 | CURSOR_INHERIT -> 100 | CURSOR_NONE -> 101 | CURSOR_FULL_CROSSHAIR -> 102 let string_of_cursor c = match c with | CURSOR_RIGHT_ARROW -> "CURSOR_RIGHT_ARROW" | CURSOR_LEFT_ARROW -> "CURSOR_LEFT_ARROW" | CURSOR_INFO -> "CURSOR_INFO" | CURSOR_DESTROY -> "CURSOR_DESTROY" | CURSOR_HELP -> "CURSOR_HELP" | CURSOR_CYCLE -> "CURSOR_CYCLE" | CURSOR_SPRAY -> "CURSOR_SPRAY" | CURSOR_WAIT -> "CURSOR_WAIT" | CURSOR_TEXT -> "CURSOR_TEXT" | CURSOR_CROSSHAIR -> "CURSOR_CROSSHAIR" | CURSOR_UP_DOWN -> "CURSOR_UP_DOWN" | CURSOR_LEFT_RIGHT -> "CURSOR_LEFT_RIGHT" | CURSOR_TOP_SIDE -> "CURSOR_TOP_SIDE" | CURSOR_BOTTOM_SIDE -> "CURSOR_BOTTOM_SIDE" | CURSOR_LEFT_SIDE -> "CURSOR_LEFT_SIDE" | CURSOR_RIGHT_SIDE -> "CURSOR_RIGHT_SIDE" | CURSOR_TOP_LEFT_CORNER -> "CURSOR_TOP_LEFT_CORNER" | CURSOR_TOP_RIGHT_CORNER -> "CURSOR_TOP_RIGHT_CORNER" | CURSOR_BOTTOM_RIGHT_CORNER -> "CURSOR_BOTTOM_RIGHT_CORNER" | CURSOR_BOTTOM_LEFT_CORNER -> "CURSOR_BOTTOM_LEFT_CORNER" | CURSOR_INHERIT -> "CURSOR_INHERIT" | CURSOR_NONE -> "CURSOR_NONE" | CURSOR_FULL_CROSSHAIR -> "CURSOR_FULL_CROSSHAIR" ;; let int_of_modifier m = match m with | ACTIVE_SHIFT -> 1 | ACTIVE_CTRL -> 2 | ACTIVE_ALT -> 4 ;; (* let int_of_modifiers ms = List.fold_left (lor) 0 (List.map int_of_modifier ms);; *) let string_of_button b = match b with | LEFT_BUTTON -> "LEFT_BUTTON" | MIDDLE_BUTTON -> "MIDDLE_BUTTON" | RIGHT_BUTTON -> "RIGHT_BUTTON" | OTHER_BUTTON n -> "OTHER_BUTTON" ^ string_of_int n ;; let string_of_button_state s = match s with | DOWN -> "DOWN" | UP -> "UP" ;; let string_of_modifier m = match m with | ACTIVE_SHIFT -> "ACTIVE_SHIFT" | ACTIVE_CTRL -> "ACTIVE_CTRL" | ACTIVE_ALT -> "ACTIVE_ALT" ;; (* convert a list of strings to a single string *) let string_of_strings l = let rec _string_of_list l = match l with | [] -> "" | h::t -> h^(if t=[] then "" else ", "^(_string_of_list t)) in "[ " ^ (_string_of_list l) ^ " ]";; let string_of_modifiers ml = string_of_strings (List.map string_of_modifier ml);; let string_of_window_status status = match status with | HIDDEN -> "HIDDEN" | FULLY_RETAINED -> "FULLY_RETAINED" | PARTIALLY_RETAINED -> "PARTIALLY_RETAINED" | FULLY_COVERED -> "FULLY_COVERED" ;; let string_of_vis_state vis = match vis with | NOT_VISIBLE -> "NOT_VISIBLE" | VISIBLE -> "VISIBLE" ;; lablgl-1.07/LablGlut/src/glut.mli000066400000000000000000000243431437514534100166660ustar00rootroot00000000000000(* glut.mli: interface for the lablglut GLUT binding. *) type button_t = | LEFT_BUTTON | MIDDLE_BUTTON | RIGHT_BUTTON | OTHER_BUTTON of int type mouse_button_state_t = | DOWN | UP type special_key_t = | KEY_F1 | KEY_F2 | KEY_F3 | KEY_F4 | KEY_F5 | KEY_F6 | KEY_F7 | KEY_F8 | KEY_F9 | KEY_F10 | KEY_F11 | KEY_F12 (* directional keys *) | KEY_LEFT | KEY_UP | KEY_RIGHT | KEY_DOWN | KEY_PAGE_UP | KEY_PAGE_DOWN | KEY_HOME | KEY_END | KEY_INSERT (* for undefined keys *) | KEY_OTHER of int type entry_exit_state_t = | LEFT | ENTERED type menu_state_t = | MENU_NOT_IN_USE | MENU_IN_USE type visibility_state_t = | NOT_VISIBLE | VISIBLE type window_status_t = | HIDDEN | FULLY_RETAINED | PARTIALLY_RETAINED | FULLY_COVERED type color_index_component_t = | RED | GREEN | BLUE type layer_t = | NORMAL | OVERLAY type font_t = | STROKE_ROMAN | STROKE_MONO_ROMAN | BITMAP_9_BY_15 | BITMAP_8_BY_13 | BITMAP_TIMES_ROMAN_10 | BITMAP_TIMES_ROMAN_24 | BITMAP_HELVETICA_10 | BITMAP_HELVETICA_12 | BITMAP_HELVETICA_18 type glut_get_t = | WINDOW_X | WINDOW_Y | WINDOW_WIDTH | WINDOW_HEIGHT | WINDOW_BUFFER_SIZE | WINDOW_STENCIL_SIZE | WINDOW_DEPTH_SIZE | WINDOW_RED_SIZE | WINDOW_GREEN_SIZE | WINDOW_BLUE_SIZE | WINDOW_ALPHA_SIZE | WINDOW_ACCUM_RED_SIZE | WINDOW_ACCUM_GREEN_SIZE | WINDOW_ACCUM_BLUE_SIZE | WINDOW_ACCUM_ALPHA_SIZE | WINDOW_DOUBLEBUFFER | WINDOW_RGBA | WINDOW_PARENT | WINDOW_NUM_CHILDREN | WINDOW_COLORMAP_SIZE | WINDOW_NUM_SAMPLES | WINDOW_STEREO | WINDOW_CURSOR | SCREEN_WIDTH | SCREEN_HEIGHT | SCREEN_WIDTH_MM | SCREEN_HEIGHT_MM | MENU_NUM_ITEMS (* | DISPLAY_MODE_POSSIBLE : use getBool *) | INIT_WINDOW_X | INIT_WINDOW_Y | INIT_WINDOW_WIDTH | INIT_WINDOW_HEIGHT | INIT_DISPLAY_MODE | ELAPSED_TIME | WINDOW_FORMAT_ID type glut_get_bool_t = | DISPLAY_MODE_POSSIBLE (* display mode bit masks *) val rgb:int val rgba:int val index:int val single:int val double:int val accum:int val alpha:int val depth:int val stencil:int val multisample:int val stereo:int val luminance:int type device_get_t = | HAS_KEYBOARD | HAS_MOUSE | HAS_SPACEBALL | HAS_DIAL_AND_BUTTON_BOX | HAS_TABLET | NUM_MOUSE_BUTTONS | NUM_SPACEBALL_BUTTONS | NUM_BUTTON_BOX_BUTTONS | NUM_DIALS | NUM_TABLET_BUTTONS | DEVICE_IGNORE_KEY_REPEAT | DEVICE_KEY_REPEAT | HAS_JOYSTICK | OWNS_JOYSTICK | JOYSTICK_BUTTONS | JOYSTICK_AXES | JOYSTICK_POLL_RATE type layerget_t = | OVERLAY_POSSIBLE (* | LAYER_IN_USE : use layerGetInUse *) | HAS_OVERLAY (* | TRANSPARENT_INDEX : use layerGetTransparentIndex *) | NORMAL_DAMAGED | OVERLAY_DAMAGED type video_resize_t = | VIDEO_RESIZE_POSSIBLE | VIDEO_RESIZE_IN_USE | VIDEO_RESIZE_X_DELTA | VIDEO_RESIZE_Y_DELTA | VIDEO_RESIZE_WIDTH_DELTA | VIDEO_RESIZE_HEIGHT_DELTA | VIDEO_RESIZE_X | VIDEO_RESIZE_Y | VIDEO_RESIZE_WIDTH | VIDEO_RESIZE_HEIGHT (* key modifier bit masks *) val active_shift:int val active_ctrl:int val active_alt:int type cursor_t = (* Basic arrows. *) | CURSOR_RIGHT_ARROW | CURSOR_LEFT_ARROW (* Symbolic cursor shapes. *) | CURSOR_INFO | CURSOR_DESTROY | CURSOR_HELP | CURSOR_CYCLE | CURSOR_SPRAY | CURSOR_WAIT | CURSOR_TEXT | CURSOR_CROSSHAIR (* Directional cursors. *) | CURSOR_UP_DOWN | CURSOR_LEFT_RIGHT (* Sizing cursors. *) | CURSOR_TOP_SIDE | CURSOR_BOTTOM_SIDE | CURSOR_LEFT_SIDE | CURSOR_RIGHT_SIDE | CURSOR_TOP_LEFT_CORNER | CURSOR_TOP_RIGHT_CORNER | CURSOR_BOTTOM_RIGHT_CORNER | CURSOR_BOTTOM_LEFT_CORNER | CURSOR_INHERIT (* inherit cursor from parent window *) | CURSOR_NONE (* blank cursor *) | CURSOR_FULL_CROSSHAIR (* full-screen crosshair (if available) *) type game_mode_t = | GAME_MODE_ACTIVE | GAME_MODE_POSSIBLE | GAME_MODE_WIDTH | GAME_MODE_HEIGHT | GAME_MODE_PIXEL_DEPTH | GAME_MODE_REFRESH_RATE | GAME_MODE_DISPLAY_CHANGED type key_repeat_t = | KEY_REPEAT_OFF | KEY_REPEAT_ON | KEY_REPEAT_DEFAULT exception BadEnum of string exception InvalidState of string (* GLUT initialization sub-API. *) val init: argv:(string array)->string array (* returns new argv *) val initDisplayMode: (* The last argument must be () *) ?double_buffer:bool-> ?index:bool-> ?accum:bool-> ?alpha:bool-> ?depth:bool-> ?stencil:bool-> ?multisample:bool-> ?stereo:bool-> ?luminance:bool-> unit-> unit val initWindowPosition: x:int->y:int->unit val initWindowSize: w:int->h:int->unit val mainLoop: unit->unit (* GLUT window sub-API. *) val createWindow: title:string->int (* returns window id *) val postRedisplay: unit->unit val swapBuffers: unit->unit val createSubWindow: win:int->x:int->y:int->w:int->h:int->int val destroyWindow: win:int->unit val getWindow: unit->int val setWindow: win:int->unit val setWindowTitle: title:string->unit val setIconTitle: title:string->unit val positionWindow: x:int->y:int->unit val reshapeWindow: w:int->h:int->unit val popWindow: unit->unit val pushWindow: unit->unit val iconifyWindow: unit->unit val showWindow: unit->unit val hideWindow: unit->unit val fullScreen: unit->unit val setCursor: cursor_t->unit (* GLUT overlay sub-API. *) val establishOverlay: unit->unit val removeOverlay: unit->unit val useLayer: layer_t->unit val postOverlayRedisplay: unit->unit val showOverlay: unit->unit val hideOverlay: unit->unit (* GLUT menu sub-API. *) val createMenu: cb:(value:int->unit)->int val destroyMenu: menu:int->unit val getMenu: unit->int val setMenu: menu:int->unit val addMenuEntry: label:string->value:int->unit val addSubMenu: label:string->submenu:int->unit val changeToMenuEntry: item:int->label:string->value:int->unit val changeToSubMenu: item:int->label:string->submenu:int->unit val removeMenuItem: item:int->unit val attachMenu: button:button_t->unit val detachMenu: button:button_t->unit (* GLUT window callback sub-API. *) val displayFunc: cb:(unit->unit)->unit val reshapeFunc: cb:(w:int->h:int->unit)->unit val keyboardFunc: cb:(key:int->x:int->y:int->unit)->unit val mouseFunc: cb:(button:button_t->state:mouse_button_state_t-> x:int->y:int->unit)->unit val motionFunc: cb:(x:int->y:int->unit)->unit val passiveMotionFunc: cb:(x:int->y:int->unit)->unit val entryFunc: cb:(state:entry_exit_state_t->unit)->unit val visibilityFunc: cb:(state:visibility_state_t->unit)->unit val idleFunc: cb:((unit->unit) option)->unit (* you can set as many timer as you want simultanesouly *) val timerFunc: ms:int->cb:(value:'a->unit)->value:'a->unit val specialFunc: cb:(key:special_key_t->x:int->y:int->unit)->unit val spaceballMotionFunc: cb:(x:int->y:int->z:int->unit)->unit val spaceballRotateFunc: cb:(x:int->y:int->z:int->unit)->unit val spaceballButtonFunc: cb:(button:int->state:int->unit)->unit val buttonBoxFunc: cb:(button:int->state:int->unit)->unit val dialsFunc: cb:(dial:int->value:int->unit)->unit val tabletMotionFunc: cb:(x:int->y:int->unit)->unit val tabletButtonFunc: cb:(button:int->state:int->x:int->y:int->unit)->unit val menuStatusFunc: cb:(status:menu_state_t->x:int->y:int->unit)->unit val overlayDisplayFunc: cb:(unit->unit)->unit (* GLUT color index sub-API. *) val setColor: cell:int->red:float->green:float->blue:float->unit val getColor: index:int->component:int->float val copyColormap: win:int->unit (* GLUT state retrieval sub-API. *) val get: gtype:glut_get_t->int val getBool: gtype:glut_get_bool_t->bool val deviceGet: dgtype:device_get_t->int (* GLUT extension support sub-API *) val extensionSupported: name:string->bool val getModifiers: unit->int val layerGetTransparentIndex: unit->int val layerGetInUse: unit->layer_t val layerGet: lgtype:layerget_t->bool (* GLUT font sub-API *) val bitmapCharacter: font:font_t->c:int->unit val bitmapWidth: font:font_t->c:int->int val strokeCharacter: font:font_t->c:int->unit val strokeWidth: font:font_t->c:int->int (* GLUT pre-built models sub-API *) val wireSphere: radius:float->slices:int->stacks:int->unit val solidSphere: radius:float->slices:int->stacks:int->unit val wireCone: base:float->height:float->slices:int->stacks:int->unit val solidCone: base:float->height:float->slices:int->stacks:int->unit val wireCube: size:float->unit val solidCube: size:float->unit val wireTorus: innerRadius:float->outerRadius:float->sides:int->rings:int->unit val solidTorus: innerRadius:float->outerRadius:float->sides:int->rings:int->unit val wireDodecahedron: unit->unit val solidDodecahedron: unit->unit val wireTeapot: size:float->unit val solidTeapot: size:float->unit val wireOctahedron: unit->unit val solidOctahedron: unit->unit val wireTetrahedron: unit->unit val solidTetrahedron: unit->unit val wireIcosahedron: unit->unit val solidIcosahedron: unit->unit (* GLUT game mode sub-API *) val gameModeString: str:string->unit val enterGameMode: unit->unit val leaveGameMode: unit->unit val gameModeGet: mode:game_mode_t->int (* GLUT version 4 functions included in the GLUT 3.7 distribution *) val initDisplayString: str:string->unit val warpPointer: x:int->y:int->unit val bitmapLength: font:font_t->str:string->int val strokeLength: font:font_t->str:string->int val windowStatusFunc: cb:(state:window_status_t->unit)->unit val postWindowRedisplay: win:int->unit val postWindowOverlayRedisplay: win:int->unit val keyboardUpFunc: cb:(key:int->x:int->y:int->unit)->unit val specialUpFunc: cb:(key:special_key_t->x:int->y:int->unit)->unit val ignoreKeyRepeat: ignore:bool->unit val setKeyRepeat: mode:key_repeat_t->unit val joystickFunc: cb:(buttonMask:int->x:int->y:int->z:int->unit)-> pollInterval:int->unit val forceJoystickFunc: unit->unit (* GLUT video resize sub-API. *) val videoResizeGet: video_resize_t->int val setupVideoResizing: unit->unit val stopVideoResizing: unit->unit val videoResize: x:int->y:int->width:int->height:int->unit val videoPan: x:int->y:int->width:int->height:int->unit (* GLUT debugging sub-API. *) val reportErrors: unit->unit (* ocaml-specific *) val string_of_button: button_t->string val string_of_button_state: mouse_button_state_t->string val string_of_special: special_key_t->string val string_of_window_status: window_status_t->string val string_of_vis_state: visibility_state_t->string val string_of_cursor: cursor_t->string val int_of_cursor: cursor_t->int lablgl-1.07/LablGlut/src/lablglut.bat000077500000000000000000000001561437514534100175050ustar00rootroot00000000000000@rem toplevel for lablGL with glut support ocaml -I +lablgl lablgl.cma lablglut.cma %1 %2 %3 %4 %5 %6 %7 %8 %9lablgl-1.07/LablGlut/src/ml_gl.h000066400000000000000000000137061437514534100164540ustar00rootroot00000000000000/* $Id: ml_gl.h,v 1.2 2003-10-28 05:16:37 ijtrotts Exp $ */ /* This file was copied (gratefully) from J. Garrigue's LablGL */ #ifndef _ml_gl_ #define _ml_gl_ void ml_raise_gl (const char *errmsg) Noreturn; #define copy_string_check lablgl_copy_string_check value copy_string_check (const char *str); GLenum GLenum_val (value); #define Float_val(dbl) ((GLfloat) Double_val(dbl)) #define Addr_val(addr) ((GLvoid *) addr) #define Val_addr(addr) ((value) addr) #define Type_raw(raw) (GLenum_val(Kind_raw(raw))) #define Type_void_raw(raw) Type_raw(raw), Void_raw(raw) #define ML_0(cname) \ CAMLprim value ml_##cname (value unit) \ { cname (); return Val_unit; } #define ML_1(cname, conv1) \ CAMLprim value ml_##cname (value arg1) \ { cname (conv1(arg1)); return Val_unit; } #define ML_2(cname, conv1, conv2) \ CAMLprim value ml_##cname (value arg1, value arg2) \ { cname (conv1(arg1), conv2(arg2)); return Val_unit; } #define ML_3(cname, conv1, conv2, conv3) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3)); return Val_unit; } #define ML_4(cname, conv1, conv2, conv3, conv4) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4)); \ return Val_unit; } #define ML_5(cname, conv1, conv2, conv3, conv4, conv5) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5)); \ return Val_unit; } #define ML_6(cname, conv1, conv2, conv3, conv4, conv5, conv6) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6)); \ return Val_unit; } #define ML_7(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6), conv7(arg7)); \ return Val_unit; } #define ML_8(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7, value arg8) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6), conv7(arg7), conv8(arg8)); \ return Val_unit; } #define ML_0_(cname, conv) \ CAMLprim value ml_##cname (value unit) \ { return conv (cname ()); } #define ML_1_(cname, conv1, conv) \ CAMLprim value ml_##cname (value arg1) \ { return conv (cname (conv1(arg1))); } #define ML_2_(cname, conv1, conv2, conv) \ CAMLprim value ml_##cname (value arg1, value arg2) \ { return conv (cname (conv1(arg1), conv2(arg2))); } #define ML_3_(cname, conv1, conv2, conv3, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3))); } #define ML_4_(cname, conv1, conv2, conv3, conv4, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4))); } #define ML_5_(cname, conv1, conv2, conv3, conv4, conv5, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5))); } #define ML_6_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6))); } #define ML_7_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6), conv7(arg7))); } #define ML_8_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8, \ conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7, value arg8) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6), conv7(arg7), conv8(arg8))); } /* Use with care: needs the argument index */ #define Ignore(x) #define Split(x,f,g) f(x), g(x) Ignore #define Split3(x,f,g,h) f(x), g(x), h(x) Ignore #define Pair(x,f,g) f(Field(x,0)), g(Field(x,1)) Ignore #define Triple(x,f,g,h) f(Field(x,0)), g(Field(x,1)), h(Field(x,2)) Ignore /* For more than 5 arguments */ #define ML_bc6(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5]); } #define ML_bc7(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5],argv[6]); } #define ML_bc8(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5],argv[6], \ argv[7]); } /* subtleties of openGL 1.1 vs 1.2 */ #if !defined(GL_DOUBLE) && defined(GL_DOUBLE_EXT) #define GL_DOUBLE GL_DOUBLE_EXT #endif #if !defined(GL_TEXTURE_PRIORITY) && defined(GL_TEXTURE_PRIORITY_EXT) #define GL_TEXTURE_PRIORITY GL_TEXTURE_PRIORITY_EXT #endif #if !defined(GL_PROXY_TEXTURE_1D) && defined(GL_PROXY_TEXTURE_1D_EXT) #define GL_PROXY_TEXTURE_1D GL_PROXY_TEXTURE_1D_EXT #endif #if !defined(GL_PROXY_TEXTURE_2D) && defined(GL_PROXY_TEXTURE_2D_EXT) #define GL_PROXY_TEXTURE_2D GL_PROXY_TEXTURE_2D_EXT #endif #endif lablgl-1.07/LablGlut/src/wrap_gl.c000066400000000000000000000066621437514534100170130ustar00rootroot00000000000000#define CAML_NAME_SPACE #ifdef __APPLE__ #include #else #include #endif #include #include #include #include static void ocaml_gl_warning(const char msg[]) { fprintf(stderr, "OCaml Open GL warning : %s", msg); fflush(stderr); } value ocaml_glClear ( value will_clear_color_buffer, value will_clear_depth_buffer) { GLbitfield mask = 0; mask |= (Bool_val(will_clear_color_buffer) ? GL_COLOR_BUFFER_BIT : 0); mask |= (Bool_val(will_clear_depth_buffer) ? GL_DEPTH_BUFFER_BIT : 0); glClear(mask); return Val_unit; } value ocaml_glClearColor (value r, value g, value b, value a) { glClearColor(Double_val(r), Double_val(g), Double_val(b), Double_val(a)); return Val_unit; } value ocaml_glBegin (value primitive_type) { switch( Int_val(primitive_type) ) { case 0: glBegin(GL_POINTS); break; case 1: glBegin(GL_LINES); break; case 2: glBegin(GL_LINE_LOOP); break; case 3: glBegin(GL_LINE_STRIP); break; case 4: glBegin(GL_TRIANGLES); break; case 5: glBegin(GL_TRIANGLE_STRIP); break; case 6: glBegin(GL_TRIANGLE_FAN); break; case 7: glBegin(GL_QUADS); break; case 8: glBegin(GL_QUAD_STRIP); break; case 9: glBegin(GL_POLYGON); break; default: ocaml_gl_warning("Unrecognized primitive type in ocaml_glBegin()\n"); } return Val_unit; } value ocaml_glVertex3d (value vx, value vy, value vz) { double x,y,z; x = Double_val(vx); y = Double_val(vy); z = Double_val(vz); glVertex3d(x,y,z); return Val_unit; } value ocaml_glVertex2d (value vx, value vy) { double x,y; x = Double_val(vx); y = Double_val(vy); glVertex2d(x,y); return Val_unit; } value ocaml_glColor3d (value r, value g, value b) { glColor3d(Double_val(r), Double_val(g), Double_val(b)); return Val_unit; } // TexCoord // Normal value ocaml_glEnd () { glEnd(); return Val_unit; } value ocaml_glFlush () { glFlush(); return Val_unit; } value ocaml_glViewport (value vx, value vy, value vwidth, value vheight) { int x,y,w,h; x=Int_val(vx); y=Int_val(vy); w=Int_val(vwidth); h=Int_val(vheight); glViewport(x, y, w, h); return Val_unit; } value ocaml_glMatrixMode (value mode) { int imode = Int_val(mode); switch(imode) { case 0: glMatrixMode(GL_MODELVIEW); break; case 1: glMatrixMode(GL_PROJECTION); break; case 2: glMatrixMode(GL_TEXTURE); break; default: ocaml_gl_warning("Unrecognized mode in ocaml_glMatrixMode()\n"); } return Val_unit; } value ocaml_glLoadIdentity () { glLoadIdentity(); return Val_unit; } value ocaml_glShadeModel (value model) { switch(Int_val(model)) { case 0: glShadeModel(GL_FLAT); break; case 1: glShadeModel(GL_SMOOTH); break; default: ocaml_gl_warning("Unrecognized mode in ocaml_glShadeModel()\n"); } return Val_unit; } value native_ocaml_glOrtho( value left, value right, value bot, value top, value znear, value zfar) { glOrtho(Double_val(left), Double_val(right), Double_val(bot), Double_val(top), Double_val(znear), Double_val(zfar)); return Val_unit; } value bytecode_ocaml_glOrtho(value * args, int num_args) { native_ocaml_glOrtho(args[0], args[1], args[2], args[3], args[4], args[5]); return Val_unit; } lablgl-1.07/LablGlut/src/wrap_glut.c000066400000000000000000000344261437514534100173630ustar00rootroot00000000000000/* * wrap_glut.c * * an OCaml wrapper for a subset of Mark Kilgard's GLUT * * written by ijt * */ #define CAML_NAME_SPACE #ifdef _WIN32 #define GLUT_DISABLE_ATEXIT_HACK #include #endif #ifdef __APPLE__ #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include "ml_gl.h" #define VoidPtr_val(x) ((void*) Int_val(x)) /* ML_0(glutMainLoop) */ CAMLprim value ml_glutMainLoop (value unit) \ { caml_enter_blocking_section (); glutMainLoop (); caml_leave_blocking_section (); return Val_unit; } ML_0(glutSwapBuffers) /* makes a function called ml_glutSwapBuffers() */ ML_0(glutPostRedisplay) ML_2(glutInitWindowSize, Int_val, Int_val) ML_2(glutInitWindowPosition, Int_val, Int_val) ML_1_(glutCreateWindow, String_val, Val_int) ML_5_(glutCreateSubWindow, Int_val, Int_val, Int_val, Int_val, Int_val, Val_int) ML_1(glutDestroyWindow, Int_val) ML_0_(glutGetWindow, Val_int) /* return win id */ ML_1(glutSetWindow, Int_val) ML_1(glutSetWindowTitle, String_val) ML_1(glutSetIconTitle, String_val) ML_2(glutPositionWindow, Int_val, Int_val) ML_2(glutReshapeWindow, Int_val, Int_val) ML_0(glutPopWindow) ML_0(glutPushWindow) ML_0(glutIconifyWindow) ML_0(glutShowWindow) ML_0(glutHideWindow) ML_0(glutFullScreen) ML_1(glutSetCursor, Int_val) ML_0(glutEstablishOverlay) ML_0(glutRemoveOverlay) ML_1(glutUseLayer, Int_val) ML_0(glutPostOverlayRedisplay) ML_0(glutShowOverlay) ML_0(glutHideOverlay) ML_1(glutDestroyMenu, Int_val) ML_0_(glutGetMenu, Val_int) ML_1(glutSetMenu, Int_val) ML_2(glutAddMenuEntry, String_val, Int_val) ML_2(glutAddSubMenu, String_val, Int_val) ML_3(glutChangeToMenuEntry, Int_val, String_val, Int_val) ML_3(glutChangeToSubMenu, Int_val, String_val, Int_val) ML_1(glutRemoveMenuItem, Int_val) ML_1(glutAttachMenu, Int_val) ML_1(glutDetachMenu, Int_val) ML_4(glutSetColor, Int_val, Float_val, Float_val, Float_val) ML_2_(glutGetColor, Int_val, Int_val, caml_copy_double) ML_1(glutCopyColormap, Int_val) ML_1_(glutGet, Int_val, Val_int) ML_1_(glutDeviceGet, Int_val, Val_int) ML_1_(glutExtensionSupported, String_val, Val_bool) ML_0_(glutGetModifiers, Val_int) ML_1_(glutLayerGet, Int_val, Val_int) ML_1_(glutVideoResizeGet, Int_val, Val_int) ML_0(glutSetupVideoResizing) ML_0(glutStopVideoResizing) ML_4(glutVideoResize, Int_val, Int_val, Int_val, Int_val) ML_4(glutVideoPan, Int_val, Int_val, Int_val, Int_val) ML_0(glutReportErrors) ML_3(glutWireSphere, Float_val, Int_val, Int_val) ML_3(glutSolidSphere, Float_val, Int_val, Int_val) ML_4(glutWireCone, Float_val, Float_val, Int_val, Int_val) ML_4(glutSolidCone, Float_val, Float_val, Int_val, Int_val) ML_1(glutWireCube, Float_val) ML_1(glutSolidCube, Float_val) ML_4(glutWireTorus, Float_val, Float_val, Int_val, Int_val) ML_4(glutSolidTorus, Float_val, Float_val, Int_val, Int_val) ML_0(glutWireDodecahedron) ML_0(glutSolidDodecahedron) ML_1(glutWireTeapot, Float_val) ML_1(glutSolidTeapot, Float_val) ML_0(glutWireOctahedron) ML_0(glutSolidOctahedron) ML_0(glutWireTetrahedron) ML_0(glutSolidTetrahedron) ML_0(glutWireIcosahedron) ML_0(glutSolidIcosahedron) ML_1(glutGameModeString, String_val) ML_0(glutEnterGameMode) ML_0(glutLeaveGameMode) ML_1_(glutGameModeGet, Int_val, Val_int) CAMLprim value ml_glutInit( value v_argc, char **argv ) { int argc = Int_val(v_argc); /* The input array must have one more element */ argv[argc] = NULL; glutInit(&argc, argv); /* Safe: no callback */ return Val_int(argc); } CAMLprim value native_glutInitDisplayMode( value double_buffer, value index, value accum, value alpha, value depth, value stencil, value multisample, value stereo, value luminance) { unsigned int acc = 0; acc |= Bool_val(double_buffer) ? GLUT_DOUBLE : 0; acc |= Bool_val(index) ? GLUT_INDEX : 0; acc |= Bool_val(accum) ? GLUT_ACCUM : 0; acc |= Bool_val(alpha) ? GLUT_RGBA : 0; acc |= Bool_val(depth) ? GLUT_DEPTH : 0; acc |= Bool_val(stencil) ? GLUT_STENCIL : 0; acc |= Bool_val(multisample) ? GLUT_MULTISAMPLE : 0; acc |= Bool_val(stereo) ? GLUT_STEREO : 0; acc |= Bool_val(luminance) ? GLUT_LUMINANCE : 0; glutInitDisplayMode(acc); return Val_unit; } CAMLprim value bytecode_glutInitDisplayMode ( value * args, int num_args) { assert(num_args == 9); native_glutInitDisplayMode( args[0],/*double_buffer*/ args[1],/*index*/ args[2],/*accum*/ args[3],/*alpha*/ args[4],/*depth*/ args[5],/*stencil*/ args[6],/*multisample*/ args[7],/*stereo*/ args[8] /*luminance*/ ); return Val_unit; } /* associations between callback functions and window ids are made on the OCaml side. */ /* TODO: make these easier to read. gcc was complaining about backslashes, for reasons that aren't clear to me. */ #define REGISTER_CB(glut_func) \ CAMLprim value ml_##glut_func(value cb) { \ glut_func(glut_func##_cb ); \ if (glut_func##_value) { \ if (glut_func##_value == cb) return Val_unit; \ caml_remove_global_root(&glut_func##_value); \ } \ glut_func##_value = cb; \ caml_register_global_root(&glut_func##_value); \ return Val_unit; \ } // for callback with return value for the hooking function #define REGISTER_CB_(glut_func, conv) \ CAMLprim value ml_##glut_func(value cb) { \ value r = conv(glut_func(glut_func##_cb )); \ if (glut_func##_value) { \ if (glut_func##_value == cb) return r; \ caml_remove_global_root(&glut_func##_value); \ } \ glut_func##_value = cb; \ caml_register_global_root(&glut_func##_value); \ return r; \ } // for callback with one extra argument for the hooking function #define REGISTER__CB(glut_func, conv) \ CAMLprim value ml_##glut_func(value cb, value arg) { \ glut_func(glut_func##_cb, conv(arg) ); \ if (glut_func##_value) { \ if (glut_func##_value == cb) return Val_unit; \ caml_remove_global_root(&glut_func##_value); \ } \ glut_func##_value = cb; \ caml_register_global_root(&glut_func##_value); \ return Val_unit; \ } #define CB_0(glut_func) \ value glut_func##_value = 0; \ static void glut_func##_cb( void ) { \ caml_leave_blocking_section (); \ caml_callback(glut_func##_value, Val_unit); \ caml_enter_blocking_section (); \ } \ REGISTER_CB(glut_func) #define CB_1(glut_func, type1, conv1) \ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1 ) { \ caml_leave_blocking_section (); \ caml_callback(glut_func##_value, conv1(arg1)); \ caml_enter_blocking_section (); \ } \ REGISTER_CB(glut_func) // for callback with return value for the hooking function #define CB_1_(glut_func, type1, conv1, conv) \ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1 ) { \ caml_leave_blocking_section (); \ caml_callback(glut_func##_value, conv1(arg1)); \ caml_enter_blocking_section (); \ } \ REGISTER_CB_(glut_func, conv) #define CB_2(glut_func, type1, conv1, type2, conv2) \ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1, type2 arg2 ) { \ caml_leave_blocking_section (); \ caml_callback2(glut_func##_value, conv1(arg1), conv2(arg2)); \ caml_enter_blocking_section (); \ } \ REGISTER_CB(glut_func) #define CB_3(glut_func, type1, conv1, type2, conv2, type3, conv3) \ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1, type2 arg2, type3 arg3 ) { \ caml_leave_blocking_section (); \ caml_callback3(glut_func##_value, conv1(arg1), conv2(arg2), conv3(arg3)); \ caml_enter_blocking_section (); \ } \ REGISTER_CB(glut_func) #define CB_4(glut_func, type1, conv1, type2, conv2, type3, conv3, type4, conv4)\ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1, type2 arg2, type3 arg3, type4 arg4 )\ { \ value args[4]; \ caml_leave_blocking_section (); \ args[0] = conv1(arg1); \ args[1] = conv2(arg2); \ args[2] = conv3(arg3); \ args[3] = conv4(arg4); \ caml_callbackN (glut_func##_value, 4, args); \ caml_enter_blocking_section (); \ } \ REGISTER_CB(glut_func) // for callback with one extra argument for the hooking function #define CB__4(glut_func, type1, conv1, type2, conv2, type3, conv3, type4, conv4, conv) \ value glut_func##_value = 0; \ static void glut_func##_cb( type1 arg1, type2 arg2, type3 arg3, type4 arg4 )\ { \ value args[4]; \ caml_leave_blocking_section (); \ args[0] = conv1(arg1); \ args[1] = conv2(arg2); \ args[2] = conv3(arg3); \ args[3] = conv4(arg4); \ caml_callbackN (glut_func##_value, 4, args); \ caml_enter_blocking_section (); \ } \ REGISTER__CB(glut_func, conv) CB_0(glutDisplayFunc) CB_1(glutVisibilityFunc, int, Val_int) CB_1_(glutCreateMenu,int, Val_int, Val_int) CB_2(glutReshapeFunc, int, Val_int, int, Val_int) CB_3(glutKeyboardFunc, unsigned char, Val_int, int, Val_int, int, Val_int) CB_2(glutMotionFunc, int, Val_int, int, Val_int) CB_3(glutSpecialFunc, int, Val_int, int, Val_int, int, Val_int) CB_2(glutPassiveMotionFunc, int, Val_int, int, Val_int) CB_1(glutEntryFunc, int, Val_int) CB_3(glutSpaceballMotionFunc, int, Val_int, int, Val_int, int, Val_int) CB_3(glutSpaceballRotateFunc, int, Val_int, int, Val_int, int, Val_int) CB_2(glutSpaceballButtonFunc, int, Val_int, int, Val_int) CB_2(glutButtonBoxFunc, int, Val_int, int, Val_int) CB_2(glutDialsFunc, int, Val_int, int, Val_int) CB_2(glutTabletMotionFunc, int, Val_int, int, Val_int) CB_4(glutTabletButtonFunc, int, Val_int, int, Val_int, int, Val_int, int, Val_int) CB_3(glutMenuStatusFunc, int, Val_int, int, Val_int, int, Val_int) CB_0(glutOverlayDisplayFunc) CB_4(glutMouseFunc, int, Val_int, int, Val_int, int, Val_int, int, Val_int) CB_0(glutIdleFunc) CAMLprim value ml_glutSetIdleFuncToNull( value unit ) { glutIdleFunc(NULL); if (glutIdleFunc_value) { caml_remove_global_root(&glutIdleFunc_value); glutIdleFunc_value = 0; } return Val_unit; } static value caml_glutTimerFunc_cb = 0; CAMLprim void init_glutTimerFunc_cb(value v) { caml_glutTimerFunc_cb = v; caml_register_global_root(&caml_glutTimerFunc_cb); } static void glutTimerFunc_cb(int val) { caml_leave_blocking_section (); caml_callback (caml_glutTimerFunc_cb, (value) val); caml_enter_blocking_section (); } CAMLprim value ml_glutTimerFunc(value millis, value timer_count) // set Timer callback { glutTimerFunc(Int_val(millis), &glutTimerFunc_cb, (int) timer_count); // register with GLUT return Val_unit; } /* font stuff */ /* integer code to font */ static void* i2font(int i) { switch(i) { case 0: return GLUT_STROKE_ROMAN; case 1: return GLUT_STROKE_MONO_ROMAN; case 2: return GLUT_BITMAP_9_BY_15; case 3: return GLUT_BITMAP_8_BY_13; case 4: return GLUT_BITMAP_TIMES_ROMAN_10; case 5: return GLUT_BITMAP_TIMES_ROMAN_24; case 6: return GLUT_BITMAP_HELVETICA_10; case 7: return GLUT_BITMAP_HELVETICA_12; case 8: return GLUT_BITMAP_HELVETICA_18; default: caml_failwith("wrap_glut.c: unrecognized font. impossible...\n"); } } CAMLprim value ml_glutBitmapCharacter(value font, value c) { glutBitmapCharacter(i2font(Int_val(font)), Int_val(c)); return Val_unit; } CAMLprim value ml_glutBitmapWidth(value font, value c) { return Val_int(glutBitmapWidth(i2font(Int_val(font)), Int_val(c))); } CAMLprim value ml_glutStrokeCharacter(value font, value c) { glutStrokeCharacter(i2font(Int_val(font)), Int_val(c)); return Val_unit; } CAMLprim value ml_glutStrokeWidth(value font, value c) { return Val_int(glutStrokeWidth(i2font(Int_val(font)), Int_val(c))); } /* GLUT 4 functions included with GLUT 3.7 */ ML_1(glutInitDisplayString, String_val) ML_2(glutWarpPointer, Int_val, Int_val) CAMLprim value ml_glutBitmapLength(value font, value str) { /* need to do something about the unsignedness of the chars expected? */ return Val_int(glutBitmapLength(i2font(Int_val(font)), String_val(str))); } CAMLprim value ml_glutStrokeLength(value font, value str) { /* need to do something about the unsignedness of the chars expected? */ return Val_int(glutStrokeLength(i2font(Int_val(font)), String_val(str))); } CB_1(glutWindowStatusFunc, int, Val_int) ML_1(glutPostWindowRedisplay, Int_val) ML_1(glutPostWindowOverlayRedisplay, Val_int) CB_3(glutKeyboardUpFunc, unsigned char, Val_int, int, Val_int, int, Val_int) CB_3(glutSpecialUpFunc, int, Val_int, int, Val_int, int, Val_int) ML_1(glutIgnoreKeyRepeat, Int_val) ML_1(glutSetKeyRepeat, Int_val) CB__4(glutJoystickFunc, unsigned int, Val_int, int, Val_int, int, Val_int, int, Val_int, Int_val) ML_0(glutForceJoystickFunc) lablgl-1.07/META000066400000000000000000000006541437514534100133630ustar00rootroot00000000000000description "Bindings for OpenGL" version="1.05" directory="+lablGL" archive(byte) = "lablgl.cma" archive(native) = "lablgl.cmxa" package "togl" ( exists_if = "togl.cma,togl.cmxa" requires = "labltk lablgl" archive(byte) = "togl.cma" archive(native) = "togl.cmxa" ) package "glut" ( exists_if = "lablglut.cma,lablglut.cmxa" requires = "lablgl" archive(byte) = "lablglut.cma" archive(native) = "lablglut.cmxa" )lablgl-1.07/Makefile000066400000000000000000000017251437514534100143520ustar00rootroot00000000000000# Main Makefile, to compile subdirectories # default TOPDIR = . include Makefile.common all: lib togl glut opt: libopt toglopt glutopt lib: cd src && $(MAKE) all LIBDIR="$(LIBDIR)" libopt: cd src && $(MAKE) opt togl: lib cd Togl/src && $(MAKE) LABLTKDIR="$(LABLTKDIR)" all toglopt: libopt cd Togl/src && $(MAKE) LABLTKDIR="$(LABLTKDIR)" opt glut: lib cd LablGlut/src && $(MAKE) glutopt: libopt cd LablGlut/src && $(MAKE) opt preinstall: cd src && $(MAKE) preinstall INSTALLDIR="$(INSTALLDIR)" DLLDIR="$(DLLDIR)" cd Togl/src && $(MAKE) preinstall INSTALLDIR="$(INSTALLDIR)" DLLDIR="$(DLLDIR)" cd LablGlut/src && $(MAKE) preinstall INSTALLDIR="$(INSTALLDIR)" DLLDIR="$(DLLDIR)" install: @$(MAKE) real-install INSTALLDIR="$(INSTALLDIR)" DLLDIR="$(DLLDIR)" real-install: cd src && $(MAKE) install cd Togl/src && $(MAKE) install cd LablGlut/src && $(MAKE) install clean: cd src && $(MAKE) clean cd Togl/src && $(MAKE) clean cd LablGlut/src && $(MAKE) clean lablgl-1.07/Makefile.common000066400000000000000000000023231437514534100156340ustar00rootroot00000000000000# Common parts of the Makefile, shared by everybody # Ocaml commands CAMLC=ocamlc CAMLOPT=ocamlopt CAMLP4O=camlp5o pr_o.cmo OCAMLFIND=ocamlfind COMPILER=$(CAMLC) -c -w s #-warn-error A OPTCOMP=$(CAMLOPT) -c LIBRARIAN=ocamlmklib OPTLIB=$(CAMLOPT) -a LINKER=$(CAMLC) OPTLINK=$(CAMLOPT) SRCDIR=$(TOPDIR)/src VAR2DEF=ocamlrun $(SRCDIR)/var2def VAR2SWITCH=ocamlrun $(SRCDIR)/var2switch # Default settings CONFIG = $(TOPDIR)/Makefile.config LIBDIR = `$(CAMLC) -where` LABLTKDIR = `$(OCAMLFIND) query -qe labltk || echo +labltk` DLLDIR = $(LIBDIR)/stublibs INSTALLDIR = $(LIBDIR)/lablGL TOGLDIR = Togl TOGL_WS = TOGL_X11 COPTS = -c -O # Default toolchain (unix) TOOLCHAIN = unix XA = .a XB = XE = XO = .o XS = .so # Windows specific MKLIB=link /lib /nologo /debugtype:CV /out: MKDLL=link /nologo /dll /out: OCAMLDLL= "$(LIBDIR)/ocamlrun$(XA)" include $(CONFIG) # Default rules .SUFFIXES: .ml .mli .cmo .cmi .cmx .c .var .h .opt $(XA) $(XO) $(XE) .d$(XO) .SUFFIXES: .ml4 .ml.cmo: $(COMPILER) $(OCAMLINC) $< .ml.cmx: $(OPTCOMP) $(OCAMLINC) $< .mli.cmi: $(COMPILER) $(OCAMLINC) $< .c$(XO): $(COMPILER) -ccopt "$(COPTS) $(INCLUDES)" $< .var.h: $(VAR2DEF) < $< > $@ ifneq ($(CAMLP4O),no) .ml4.ml: $(CAMLP4O) -impl $< -o $@ endif lablgl-1.07/Makefile.config.ex000066400000000000000000000035421437514534100162300ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # ##### Adjust these always # Uncomment if you have the fast ".opt" compilers and are not using findlib #CAMLC = ocamlc.opt #CAMLOPT = ocamlopt.opt # Where to put the lablgl script BINDIR = /usr/local/bin # Where to find X headers XINCLUDES = -I/usr/X11R6/include # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) #XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lX11 -lXi # Where to find Tcl/Tk headers # This must the same version as for LablTk TKINCLUDES = -I/usr/local/include # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) #TKLIBS = -L/usr/local/lib -ltk84 -ltcl84 # Where to find OpenGL/Mesa/Glut headers and libraries GLINCLUDES = GLLIBS = -lGL -lGLU GLUTLIBS = -lglut # The following libraries may be required (try to add them one at a time) #GLLIBS = -lGL -lGLU -lXmu -lXext -lXi -lcipher -lpthread # How to index a library after installing (ranlib required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TKLIBS = tk83.lib tcl83.lib gdi32.lib user32.lib #GLLIBS = opengl32.lib glu32.lib #TOOLCHAIN = msvc #XA = .lib #XB = .bat #XE = .exe #XO = .obj #XS = .dll ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # Togl Window System # Should be one of TOGL_X11, TOGL_WGL (windows), TOGL_AGL (macosx) # TOGL_AGL isn't supported currently #TOGL_WS = TOGL_X11 # C Compiler options #COPTS = -c -O # Which camlp4o to use: camlp4o or camlp5o # It is only required when modifying .ml4 files #CAMLP4O=camlp5o pr_o.cmo lablgl-1.07/Makefile.config.freebsd000066400000000000000000000027571437514534100172350ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # # Makefile.config that has been tested under FreeBSD 4.8 ##### Adjust these always # Where to put the lablgl script BINDIR = /usr/local/bin # Where to find X headers XINCLUDES = -I/usr/X11R6/include # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lX11 # Where to find Tcl/Tk headers # This must the same version as for LablTk TKINCLUDES = -I/usr/local/include/tcl8.4 -I/usr/local/include/tk8.4 # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) TKLIBS = -L/usr/local/lib -ltk84 -ltcl84 # Where to find OpenGL/Mesa headers and libraries GLINCLUDES = GLLIBS = -lGL -lGLU GLUTLIBS = -lglut # The following libraries may be required (try to add them one at a time) # How to index a library after installing (required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TKLIBS = tk83.lib tcl83.lib gdi32.lib user32.lib #GLLIBS = opengl32.lib glu32.lib #TOOLCHAIN = msvc #XA = .lib #XB = .bat #XE = .exe #XO = .obj #XS = .dll ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # C Compiler options #COPTS = -c -O lablgl-1.07/Makefile.config.linux.mdk000066400000000000000000000026411437514534100175240ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # # Makefile.config that has been tested under Linux Mandrake 9.1 ##### Adjust these always # Where to put the lablgl script BINDIR = /usr/local/bin # Where to find X headers XINCLUDES = -I/usr/X11R6/include # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lX11 # Where to find Tcl/Tk headers # This must the same version as for LablTk TKINCLUDES = # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) TKLIBS = # Where to find OpenGL/Mesa headers and libraries GLINCLUDES = GLLIBS = -lGL -lGLU GLUTLIBS = -lglut # The following libraries may be required (try to add them one at a time) # How to index a library after installing (required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TKLIBS = tk83.lib tcl83.lib gdi32.lib user32.lib #GLLIBS = opengl32.lib glu32.lib #TOOLCHAIN = msvc #XA = .lib #XB = .bat #XE = .exe #XO = .obj #XS = .dll ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # C Compiler options #COPTS = -c -O lablgl-1.07/Makefile.config.mingw000066400000000000000000000044141437514534100167340ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # ##### Adjust these always # Uncomment if you have the fast ".opt" compilers CAMLC = ocamlc.opt CAMLOPT = ocamlopt.opt LIBRARIAN = ocamlmklib -verbose -ocamlc ocamlc -ocamlopt ocamlopt # Where to put the lablgl script OCAMLDIR = c:/OCaml BINDIR = $(OCAMLDIR)/bin DLLDIR = $(OCAMLDIR)/lib/stublibs INSTALLDIR = $(OCAMLDIR)/lib/lablGL # Where to find X headers #XINCLUDES = -I/usr/X11R6/include # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) #XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lX11 # Where to find Tcl/Tk headers # This must the same version as for LablTk TK_ROOT = C:/Tcl TKINCLUDES = -I"$(TK_ROOT)/include" # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) #TKLIBS = -ltk83 -ltcl83 #TKLIBS = -ldopt "$(TK_ROOT)/bin/tcl85.dll" -ldopt "$(TK_ROOT)/bin/tk85.dll" TKLIBS0 = -L$(TK_ROOT)/lib tcl85.lib tk85.lib -lws2_32 -luser32 -lgdi32 TKLIBS = -ldopt -L$(TK_ROOT)/bin -ldopt tcl85.dll -ldopt tk85.dll \ -ccopt -L$(TK_ROOT)/lib -cclib tcl85.lib -cclib tk85.lib \ -lws2_32 -luser32 -lgdi32 # Where to find OpenGL/Mesa/Glut headers and libraries GLINCLUDES = -DHAS_GLEXT_H -DGL_GLEXT_PROTOTYPES -DGLU_VERSION_1_3 GLLIBS = -lglu32 -lopengl32 GLLIBS0 = $(GLLIBS) GLUTLIBS = -lglut32 GLUTLIBS0 = $(GLUTLIBS) # The following libraries may be required (try to add them one at a time) #GLLIBS = -lGL -lGLU -lXmu -lXext -lXi -lcipher -lpthread # How to index a library after installing (ranlib required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TOOLCHAIN = msvc XB = .bat XE = .exe XS = .dll MKLIB = ar rcs MKDLL = gcc -mno-cygwin -shared -o ##### Adjust these if non standard # The Objective Caml library directory # must set it by hand as spaces are not allowed #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # Togl Window System # Should be one of TOGL_X11, TOGL_WGL (windows), TOGL_AGL (macosx) # TOGL_AGL isn't supported currently TOGL_WS = TOGL_WGL # C Compiler options COPTS = -c -O -DHAS_SYS_TIME lablgl-1.07/Makefile.config.msvc000066400000000000000000000037731437514534100165720ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # ##### Adjust these always # Uncomment if you have the fast ".opt" compilers CAMLC = ocamlc.opt CAMLOPT = ocamlopt.opt LIBRARIAN = ocamlmklib -verbose -ocamlc ocamlc -ocamlopt ocamlopt # Where to put the lablgl script OCAMLDIR = c:/Program Files/Objective Caml MSVC BINDIR = $(OCAMLDIR)/bin DLLDIR = $(OCAMLDIR)/lib/stublibs INSTALLDIR = $(OCAMLDIR)/lib/lablGL # Where to find X headers XINCLUDES = -I/usr/X11R6/include # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) #XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lX11 # Where to find Tcl/Tk headers # This must the same version as for LablTk TK_ROOT = C:/Tcl TKINCLUDES = -I$(TK_ROOT)/include # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) TKLIBS0 = -L$(TK_ROOT)/lib tk84.lib tcl84.lib gdi32.lib user32.lib TKLIBS = -ldopt "$(TKLIBS0)" -cclib "$(TKLIBS0)" # Where to find OpenGL/Mesa/Glut headers and libraries GLINCLUDES = GLLIBS0 = opengl32.lib glu32.lib GLLIBS = -ldopt "$(GLLIBS0)" -cclib "$(GLLIBS0)" GLUTLIBS0 = glut32.lib GLUTLIBS = -ldopt "$(GLUTLIBS0)" -cclib "$(GLUTLIBS0)" # The following libraries may be required (try to add them one at a time) #GLLIBS = -lGL -lGLU -lXmu -lXext -lXi -lcipher -lpthread # How to index a library after installing (ranlib required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TOOLCHAIN = msvc XA = .lib XB = .bat XE = .exe XO = .obj XS = .dll ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # Togl Window System # Should be one of TOGL_X11, TOGL_WGL (windows), TOGL_AGL (macosx) # TOGL_AGL isn't supported currently TOGL_WS = TOGL_WGL # C Compiler options COPTS = -c lablgl-1.07/Makefile.config.osx000066400000000000000000000027001437514534100164200ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # ##### Adjust these always # Uncomment if you have the fast ".opt" compilers and are not using findlib #CAMLC = ocamlc.opt #CAMLOPT = ocamlopt.opt # Where to put the lablgl script BINDIR = /usr/local/bin # Where to find Tcl/Tk headers # This must be the same version as for LablTk # On OSX, Togl works only with the X11 version of Tk # Here we use the X11 version of tk and mesa installed by macports # While we only use the GLX part of mesa, the libGL.dylib in # /usr/X11/lib is not compatible with macports. TKINCLUDES = -I/opt/local/include # Libs for Togl TKLIBS = -L/opt/local/lib -lGL -lXmu # Where to find OpenGL/Mesa headers and libraries GLINCLUDES = GLLIBS = -framework OpenGL GLUTLIBS = -framework GLUT # How to index a library after installing (ranlib required on MacOSX) RANLIB = ranlib ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # Togl Window System # Should be one of TOGL_X11, TOGL_WGL (windows), TOGL_AGL (macosx) # TOGL_AGL isn't supported currently #TOGL_WS = TOGL_X11 # C Compiler options #COPTS = -c -O lablgl-1.07/Makefile.config.ubuntu000066400000000000000000000026201437514534100171320ustar00rootroot00000000000000# LablGL and Togl configuration file # # Please have a look at the config/Makefile in the Objective Caml distribution, # or at the labltklink script to get the information needed here # # Makefile.config that has been tested under Linux Mandrake 9.1 ##### Adjust these always # Where to put the lablgl script BINDIR = /usr/local/bin # Where to find X headers XINCLUDES = # X libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) XLIBS = -lXext -lXmu -lX11 # Where to find Tcl/Tk headers # This must the same version as for LablTk TKINCLUDES = -I/usr/include/tcl8.5 # Tcl/Tk libs (for broken RTLD_GLOBAL: e.g. FreeBSD 4.0) TKLIBS = # Where to find OpenGL/Mesa headers and libraries GLINCLUDES = GLLIBS = -lGL -lGLU GLUTLIBS = -lglut # The following libraries may be required (try to add them one at a time) # How to index a library after installing (required on MacOSX) RANLIB = : #RANLIB = ranlib ##### Uncomment these for windows #TKLIBS = tk83.lib tcl83.lib gdi32.lib user32.lib #GLLIBS = opengl32.lib glu32.lib #TOOLCHAIN = msvc #XA = .lib #XB = .bat #XE = .exe #XO = .obj #XS = .dll ##### Adjust these if non standard # The Objective Caml library directory #LIBDIR = `ocamlc -where` # Where to put dlls (if dynamic loading available) #DLLDIR = `ocamlc -where`/stublibs # Where to put LablGL (standard) #INSTALLDIR = $(LIBDIR)/lablGL # Where is Togl (default) #TOGLDIR = Togl # C Compiler options #COPTS = -c -O lablgl-1.07/README000066400000000000000000000251731437514534100135750ustar00rootroot00000000000000 LablGL 1.07: Installation and Use instructions 1. Description LablGL is an OpenGL interface for Objective Caml. It includes two interfaces: the Togl widget, for comfortable use with LablTk, and LablGlut for standalone applications not using Tcl/Tk. https://github.com/garrigue/lablgl http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgl.html 2. Requisites * Objective Caml since 4.14 * LablTk (included in Objective Caml, requires Tcl/Tk) for Togl support (only works for Tcl/Tk older than 8.4) * OpenGL * glut (included in Mesa) for glut support * GNU make (for conditionals) Objective Caml can be obtained from http://ocaml.org OpenGL (with hardware support) may already be on your machine. XFree86 supports the GLX protocol since version 4.0, with hardware acceleration on some platforms. It is available on most recent Linux configurations. If you are not lucky enough to have built-in OpenGL support, you can still use Mesa, an openGL-compatible freeware, which works on almost everything. http://www.mesa3d.org/ LablGl also uses the Togl widget, but the code is already included in this distribution (version 1.7). You may obtain more information about Togl at: http://www.mesa3d.org/brianp/Togl.html Note that Togl is only compatible with vanilla Tcl/Tk older than 8.4: specially patched versions may not work. For instance 8.2.3+ included in old debian distributions does not work, and recent versions do not work either. LablGlut requires glut, which is already included in recent versions of Mesa and XFree86. For windows you need to obtain it from http://www.xmission.com/~nate/glut.html 3. Installation Precompiled versions of lablGL are available for Windows, and a number of Unix versions. For Linux, just install the package. Windows binary distribution: The file lablgl-1.05-win32.zip supports the mingw windows installer for ocaml 4.01. a) Install the lablGL distribution. The simplest way is to use the command-line version of unzip, and unpack it on top of your Objective Caml distribution. C:\Program Files\Objective Caml> unzip lablgl-1.04-win32.zip If you unpacked it somewhere else you must copy manually the contents of the bin, lib\stublibs and lib\lablGL directories to the corresponding directories of the Objective Caml distribution. b) Compile the Caml parts. Go to the lib\lablGL directory, and execute the following command C:\...\lib\lablGL\> ocaml build.ml It will generate the bytecode and native versions of the library. Note that every time you install a new version of Objective Caml you will need to repeat this last step. Look carefully at the last line of output of this script, it should tell you which ocaml port you are using. If the guess is wrong, you edit build.ml to correct this. c) For glut support, download glut32.dll and copy it to the bin directory of the OCaml distribution (or somewhere else in your path.) After this, you should be able to compile and run programs as either bytecode or native code. Compilation from source (if there is no package): 0) On MacOSX, if you want to use Togl, you must use the X11 version of Tcl/Tk. Here we assume that ocaml was installed from macports. Then you must also install the mesa port from macports, to obtain a compatible version of GLX. a) Create Makefile.config. Some tested configurations are provided. If none of them fits your needs, start with Makefile.config.ex. b) Build LablGL with both Togl(Tcl/Tk) and Glut support. % make If you need only Togl support, do % make togl If you need only Glut support, do % make glut If you need neither (use the library with lablGtk for instance) % make lib c) For the native code version (you need the native code version of LablTk), % make opt Similarly, you can also do % make {toglopt,glutopt,libopt} d) Install LablGL % make install This will install all the available parts. To compile for Windows, Makefile.config.msvc and Makefile.config.mingw are provided. Note however that the DLL produced for Togl by mingw does not work with the ocaml 3.11 binary distribution, you must use the one produced by MSVC, included in the binary distribution above. 4. Use Examples are in the Togl/examples and LablGlut/examples directories. * The lablgl toplevel This is a toplevel, like ocaml, including LablTk, Unix, Str, LablGL and Togl. You may use it either as a toplevel, or directly to run scripts. To run an example in Togl/examples, type: % lablgl example.ml where example.ml is one of: (by order of complexity) simple.ml scene.ml checker.ml double.ml planet.ml texturesurf.ml gears.ml morph3d.ml tennis.ml Note that some XFree86 do not seem to support single buffer rendering. The first 3 examples will not work in that case. * Similarely, there is a lablglut toplevel. For instance, move to the folder LablGlut/examples/lablGL and type % lablglut gears.ml * compiling and linking You need to include either labltk.cma, lablgl.cma and togl.cma or' lablgl.cma and lablglut.cma in your link: ocamlc -I +labltk -I +lablGL \ labltk.cma lablgl.cma togl.cma ... -o program ocamlc -I +lablGL lablgl.cma lablglut.cma ... -o program 5. Writing programs All of the GL and GLU libraries are available. Read a good book about how to use these. Translating from OpenGL to LablGL is rather straightforward: there is a LablGL function for each OpenGL one. For ease of retrieving, both GL and GLU are cut in smaller modules of related functions. See in appendix A which modules your function is in. By default it has the same name, gl or glu omited, and capitals replaced by underscores. When arguments are labelled, the names are taken from the man page or the C prototype. OpenGL makes heavy use of enumerations, with names starting with GL_ or GLU_ . Since their meaning is often overloaded, they are all converted to polymorphic variants. In most cases just replace prefix by a backquote and convert to low case. When you have a doubt the best way is to have a look with OCamlBrowser. Using Togl is also straightforward. Everything works like in LablTk. You create an openGL widget with Togl.create, and then you apply various functions on it. See Togl's README in Togl/src/Togl/README for details. To use LablGlut you need to look at glut's documentation on your system. The approach is close to LablGL's. 6. Comments and bug reports https://github.com/garrigue/lablgl/issues This library has been tested on a number of programs, but this is far from testing all of OpenGL functionality. There are bugs, but at least we didn't find any in our examples. 7. Authors Jacques Garrigue, Isaac Trotts, Erick Tryzelaar and Christophe Raffali participated to this release. A. Modules There are 12 modules for GL and 5 modules for GLU. Modules marked with (*) contain LablGL specific functions. Gl: Common data types and functions. glFlush glFinish glEnable glDisable glIsEnabled glGetError GlArray: Array functions glEdgeFlagPointer -> edge_flag glTexCoordPointer -> tex_coord glIndexPointer -> index glNormalPointer -> normal glVertexPointer -> vertex glEnableClientState -> enable glDisableClientState -> disable glArrayElement -> element glDrawArrays glDrawElements GlClear: Clearing functions. glClear glClearAccum -> accum glClearColor -> color glClearDepth -> depth glClearIndex -> index glClearStencil -> stencil GlDraw: Drawing functions. glBegin -> begins glColor glCullFace glEdgeFlag glEnd -> ends glFrontFace glIndex glLineStipple glLineWidth glNormal glPointSize glPolygonOffset glPolygonMode glPolygonStipple glRect glShadeModel glVertex glViewport GlFunc: Filtering functions. glAccum glAlphaFunc glBlendFunc glColorMask glDepthFunc glDepthMask glDrawBuffer glIndexMask glLogicOp glReadBuffer glStencilFunc glStencilMask glStencilOp GlLight: Lighting functions. glColorMaterial glFog glLight glLightModel (gl 1.2 with `color_control) glMaterial GlList: Call list functions. (*) glCallList -> call glCallLists glDeleteLists glEndList -> ends glGenLists glIsList glNewList -> begins GlMap: Map and meshes functions. glEvalCoord1 glEvalCoord2 glEvalMesh1 glEvalMesh2 glEvalPoint1 glEvalPoint2 glMap1 glMap2 glMapGrid1 -> grid1 glMapGrid2 -> grid2 GlMat: Matrix functions. (*) glFrustum glLoadIdentity glLoadMatrix -> load glLoadTransposeMatrix -> load_transpose (gl 1.3) glMatrixMode -> mode glMultMatrix -> mult glMultTransposeMatrix -> mult_transpose (gl 1.3) glOrtho glPopMatrix -> pop glPushMatrix -> push glRotate glScale glTranslate glGetDoublev -> get_matrix (only for modelview, projection, and texture) GlMisc: Miscellanous functions. glClipPlane glGetString glHint glInitNames glLoadName glPassThrough glPopAttrib glPopName glPushAttrib glPushName glRenderMode glScissor glSelectBuffer GlPix: Rasterized pixel functions. (*) glBitmap glCopyPixels -> copy glDrawPixels -> draw glPixelMap -> map glPixelStore -> store glPixelTransfer -> transfer glPixelZoom -> zoom glRasterPos glReadPixels -> read GlTex: Texturing functions. glTexCoord -> coord glTexEnv -> env glTexGen -> gen glTexImage1D -> image1d glTexImage2D -> image2d glTexParameter -> parameter (gl 1.4 with generate_mipmap) GluMat: GLU matrix functions. gluLookAt gluOrtho2D gluPerspective gluPickMatrix gluProject gluUnProject GluMisc: GLU miscellanous functions. gluBuild1DMipmaps gluBuild2DMipmaps gluGetString gluScaleImage GluNurbs: Nurbs functions. gluBeginCurve gluBeginSurface gluBeginTrim gluEndCurve gluEndSurface gluEndTrim gluLoadSamplingMatrices gluNewNurbsRenderer -> create gluNurbsCurve -> curve gluNurbsProperty -> property gluNurbsPwlCurve -> pwl_curve gluNurbsSurface -> surface GluQuadric: Quadric functions. gluCylinder gluDisk gluNewQuadric -> create gluPartialDisk gluQuadricDrawStyle -> draw_style gluQuadricNormals -> normals gluQuadricOrientation -> orientation gluQuadricTexture -> texture gluSphere GluTess: Tessalating functions. Only glu 1.2 API is supported. Either render directly or produce lists of triangles. lablgl-1.07/Togl/000077500000000000000000000000001437514534100136125ustar00rootroot00000000000000lablgl-1.07/Togl/examples/000077500000000000000000000000001437514534100154305ustar00rootroot00000000000000lablgl-1.07/Togl/examples/Makefile000066400000000000000000000000761437514534100170730ustar00rootroot00000000000000# Makefile for examples subdir clean: rm -f *.cm* *.o *.opt lablgl-1.07/Togl/examples/README000066400000000000000000000001321437514534100163040ustar00rootroot00000000000000$Id: README,v 1.3 2003-09-26 08:25:27 garrigue Exp $ Here are a few examples for LablGL. lablgl-1.07/Togl/examples/checker.ml000066400000000000000000000040761437514534100173750ustar00rootroot00000000000000(* $Id: checker.ml,v 1.8 2001-05-08 01:58:25 garrigue Exp $ *) let image_height = 64 and image_width = 64 let make_image () = let image = GlPix.create `ubyte ~format:`rgb ~width:image_width ~height:image_height in for i = 0 to image_width - 1 do for j = 0 to image_height - 1 do Raw.sets (GlPix.to_raw image) ~pos:(3*(i*image_height+j)) (if (i land 8 ) lxor (j land 8) = 0 then [|255;255;255|] else [|0;0;0|]) done done; image let myinit () = GlClear.color (0.0, 0.0, 0.0); Gl.enable `depth_test; GlFunc.depth_func `less; let image = make_image () in GlPix.store (`unpack_alignment 1); GlTex.image2d image; List.iter (GlTex.parameter ~target:`texture_2d) [ `wrap_s `clamp; `wrap_t `clamp; `mag_filter `nearest; `min_filter `nearest ]; GlTex.env (`mode `decal); Gl.enable `texture_2d; GlDraw.shade_model `flat let display () = GlClear.clear [`color;`depth]; GlDraw.begins `quads; GlTex.coord2(0.0, 0.0); GlDraw.vertex3(-2.0, -1.0, 0.0); GlTex.coord2(0.0, 1.0); GlDraw.vertex3(-2.0, 1.0, 0.0); GlTex.coord2(1.0, 1.0); GlDraw.vertex3(0.0, 1.0, 0.0); GlTex.coord2(1.0, 0.0); GlDraw.vertex3(0.0, -1.0, 0.0); GlTex.coord2(0.0, 0.0); GlDraw.vertex3(1.0, -1.0, 0.0); GlTex.coord2(0.0, 1.0); GlDraw.vertex3(1.0, 1.0, 0.0); GlTex.coord2(1.0, 1.0); GlDraw.vertex3(2.41421, 1.0, -1.41421); GlTex.coord2(1.0, 0.0); GlDraw.vertex3(2.41421, -1.0, -1.41421); GlDraw.ends (); Gl.flush () let reshape togl = let w = Togl.width togl and h = Togl.height togl in GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective ~fovy:60.0 ~aspect:(1.0 *. float w /. float h) ~z:(1.0,30.0); GlMat.mode `modelview; GlMat.load_identity (); GlMat.translate ~z:(-3.6) () open Tk let main () = let top = openTk () in let togl = Togl.create ~width:500 ~height:500 ~rgba:true ~depth:true top in myinit (); Togl.display_func togl ~cb:display; Togl.reshape_func togl ~cb:(fun () -> reshape togl); pack ~expand:true ~fill:`Both [togl]; mainLoop () let _ = main () lablgl-1.07/Togl/examples/double.ml000066400000000000000000000100361437514534100172340ustar00rootroot00000000000000(* $Id: double.ml,v 1.11 2001-05-08 01:58:25 garrigue Exp $ *) class view togl ~title = object (self) val mutable corner_x = 0. val mutable corner_y = 0. val mutable corner_z = 0. val font_base = Togl.load_bitmap_font togl ~font:`Fixed_8x13 val mutable x_angle = 0. val mutable y_angle = 0. val mutable z_angle = 0. method togl = togl method reshape = let width = Togl.width togl and height = Togl.height togl in let aspect = float width /. float height in GlDraw.viewport ~x:0 ~y:0 ~w:width ~h:height; (* Set up projection transform *) GlMat.mode `projection; GlMat.load_identity (); GlMat.frustum ~x:(-.aspect, aspect) ~y:(-1.0, 1.0) ~z:(1.0, 10.0); corner_x <- -. aspect; corner_y <- -1.0; corner_z <- -1.1; (* Change back to model view transform for rendering *) GlMat.mode `modelview method print_string s = GlList.call_lists ~base:font_base(`byte s) method display = GlClear.clear [`color;`depth]; GlMat.load_identity(); (* Reset modelview matrix to the identity matrix *) GlMat.translate ~z:(-3.0) (); (* Move the camera back three units *) GlMat.rotate ~angle:x_angle ~x:1. (); (* Rotate by X, Y, Z angles *) GlMat.rotate ~angle:y_angle ~y:1. (); GlMat.rotate ~angle:z_angle ~z:1. (); Gl.enable `depth_test; (* Front face *) GlDraw.begins `quads; GlDraw.color (0.0, 0.7, 0.1); (* Green *) GlDraw.vertex3 (-1.0, 1.0, 1.0); GlDraw.vertex3(1.0, 1.0, 1.0); GlDraw.vertex3(1.0, -1.0, 1.0); GlDraw.vertex3(-1.0, -1.0, 1.0); (* Back face *) GlDraw.color (0.9, 1.0, 0.0); (* Yellow *) GlDraw.vertex3(-1.0, 1.0, -1.0); GlDraw.vertex3(1.0, 1.0, -1.0); GlDraw.vertex3(1.0, -1.0, -1.0); GlDraw.vertex3(-1.0, -1.0, -1.0); (* Top side face *) GlDraw.color (0.2, 0.2, 1.0); (* Blue *) GlDraw.vertex3(-1.0, 1.0, 1.0); GlDraw.vertex3(1.0, 1.0, 1.0); GlDraw.vertex3(1.0, 1.0, -1.0); GlDraw.vertex3(-1.0, 1.0, -1.0); (* Bottom side face *) GlDraw.color (0.7, 0.0, 0.1); (* Red *) GlDraw.vertex3(-1.0, -1.0, 1.0); GlDraw.vertex3(1.0, -1.0, 1.0); GlDraw.vertex3(1.0, -1.0, -1.0); GlDraw.vertex3(-1.0, -1.0, -1.0); GlDraw.ends(); Gl.disable `depth_test; GlMat.load_identity(); GlDraw.color( 1.0, 1.0, 1.0 ); GlPix.raster_pos ~x:corner_x ~y:corner_y ~z:corner_z (); self#print_string title; Togl.swap_buffers togl method x_angle a = x_angle <- a; Togl.render togl method y_angle a = y_angle <- a; Togl.render togl method z_angle a = z_angle <- a; Togl.render togl end let create_view ~parent ~double = new view (Togl.create ~width:200 ~height:200 ~depth:true ~rgba:true ~double parent) open Tk let main () = let top = openTk () in let f = Frame.create top in let single = create_view ~parent:f ~double:false ~title:"Single buffer" and double = create_view ~parent:f ~double:true ~title:"Double buffer" in let sx = Scale.create ~label:"X Axis" ~min:0. ~max:360. ~orient:`Horizontal ~command:(fun x -> single#x_angle x; double#x_angle x) top and sy = Scale.create ~label:"Y Axis" ~min:0. ~max:360. ~orient:`Horizontal ~command:(fun y -> single#y_angle y; double#y_angle y) top and button = Button.create ~text:"Quit" ~command:(fun () -> destroy top) top in List.iter (fun o -> Togl.display_func o#togl ~cb:(fun () -> o#display); Togl.reshape_func o#togl ~cb:(fun () -> o#reshape); bind o#togl ~events:[`Modified([`Button1],`Motion)] ~fields:[`MouseX;`MouseY] ~action:(fun ev -> let width = Togl.width o#togl and height =Togl.height o#togl and x = ev.ev_MouseX and y = ev.ev_MouseY in let x_angle = 360. *. float y /. float height and y_angle = 360. *. float (width - x) /. float width in Scale.set sx x_angle; Scale.set sy y_angle)) [single;double]; pack ~side:`Left ~padx:3 ~pady:3 ~fill:`Both ~expand:true [single#togl; double#togl]; pack ~fill:`Both ~expand:true [f]; pack ~fill:`X [coe sx; coe sy; coe button]; mainLoop () let _ = main () lablgl-1.07/Togl/examples/gears.ml000066400000000000000000000151011437514534100170610ustar00rootroot00000000000000(* $Id: gears.ml,v 1.16 2001-05-08 01:58:25 garrigue Exp $ *) (* * 3-D gear wheels. This program is in the public domain. * * Brian Paul * LablGL version by Jacques Garrigue *) let pi = acos (-1.) (* * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth *) let gear ~inner ~outer ~width ~teeth ~tooth_depth = let r0 = inner and r1 = outer -. tooth_depth /. 2.0 and r2 = outer +. tooth_depth /. 2.0 in let ta = 2.0 *. pi /. float teeth in let da = ta /. 4.0 in GlDraw.shade_model `flat; GlDraw.normal ~z:1.0 (); let vertex ~r ~z ?(s=0) i = let angle = float i *. ta +. float s *. da in GlDraw.vertex ~x:(r *. cos angle) ~y:(r *. sin angle) ~z () in (* draw front face *) let z = width *. 0.5 in GlDraw.begins `quad_strip; for i=0 to teeth do vertex i ~r:r0 ~z; vertex i ~r:r1 ~z; vertex i ~r:r0 ~z; vertex i ~r:r1 ~z ~s:3; done; GlDraw.ends (); (* draw front sides of teeth *) GlDraw.begins `quads; for i=0 to teeth - 1 do vertex i ~r:r1 ~z; vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r1 ~s:3 ~z; done; GlDraw.ends (); GlDraw.normal ~z:(-1.0) (); (* draw back face *) let z = -. width *. 0.5 in GlDraw.begins `quad_strip; for i=0 to teeth do vertex i ~r:r1 ~z; vertex i ~r:r0 ~z; vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r0 ~z; done; GlDraw.ends (); (* draw back sides of teeth *) GlDraw.begins `quads; for i=0 to teeth - 1 do vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r1 ~z; done; GlDraw.ends (); (* draw outward faces of teeth *) let z = width *. 0.5 and z' = width *. (-0.5) in GlDraw.begins `quad_strip; for i=0 to teeth - 1 do let angle = float i *. ta in vertex i ~r:r1 ~z; vertex i ~r:r1 ~z:z'; let u = r2 *. cos(angle+.da) -. r1 *. cos(angle) and v = r2 *. sin(angle+.da) -. r1 *. sin(angle) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r2 ~s:1 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r2 ~s:2 ~z:z'; let u = r1 *. cos(angle +. 3. *. da) -. r2 *. cos(angle +. 2. *. da) and v = r1 *. sin(angle +. 3. *. da) -. r2 *. sin(angle +. 2. *. da) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r1 ~s:3 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); done; vertex 0 ~r:r1 ~z; vertex 0 ~r:r1 ~z:z'; GlDraw.ends (); GlDraw.shade_model `smooth; (* draw inside radius cylinder *) GlDraw.begins `quad_strip; for i=0 to teeth do let angle = float i *. ta in GlDraw.normal ~x:(-. cos angle) ~y:(-. sin angle) (); vertex i ~r:r0 ~z:z'; vertex i ~r:r0 ~z; done; GlDraw.ends () class view ~gear1 ~gear2 ~gear3 ?(limit=0) togl = object (self) val mutable view_rotx = 0.0 val mutable view_roty = 0.0 val mutable view_rotz = 0.0 val mutable angle = 0.0 val mutable count = 1 method rotx a = view_rotx <- a method roty a = view_roty <- a method draw = GlClear.clear [`color;`depth]; GlMat.push (); GlMat.rotate ~angle:view_rotx ~x:1.0 (); GlMat.rotate ~angle:view_roty ~y:1.0 (); GlMat.rotate ~angle:view_rotz ~z:1.0 (); GlMat.push (); GlMat.translate ~x:(-3.0) ~y:(-2.0) (); GlMat.rotate ~angle:angle ~z:1.0 (); (* gear inner:1.0 outer:4.0 width:1.0 teeth:20 tooth_depth:0.7; *) GlList.call gear1; GlMat.pop (); GlMat.push (); GlMat.translate ~x:3.1 ~y:(-2.0) (); GlMat.rotate ~angle:(-2.0 *. angle -. 9.0) ~z:1.0 (); (* gear inner:0.5 outer:2.0 width:2.0 teeth:10 tooth_depth:0.7; *) GlList.call gear2; GlMat.pop (); GlMat.push (); GlMat.translate ~x:(-3.1) ~y:4.2 (); GlMat.rotate ~angle:(-2.0 *. angle -. 25.0) ~z:1.0 (); (* gear inner:1.3 outer:2.0 width:0.5 teeth:10 tooth_depth:0.7; *) GlList.call gear3; GlMat.pop (); GlMat.pop (); Togl.swap_buffers togl; count <- count + 1; if count =limit then exit 0 method idle = angle <- angle +. 2.0; self#draw method reshape = let w = Togl.width togl and h = Togl.height togl in GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); let r = float w /. float h in let r' = 1. /. r in if (w>h) then GlMat.frustum ~x:(-. r,r) ~y:(-1.0,1.0) ~z:(5.0,60.0) else GlMat.frustum ~x:(-1.0,1.0) ~y:(-.r',r') ~z:(5.0,60.0); GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate ~z:(-40.0) (); GlClear.clear[`color;`depth] end let init () = let pos = 5.0, 5.0, 10.0, 0.0 and red = 0.8, 0.1, 0.0, 1.0 and green = 0.0, 0.8, 0.2, 1.0 and blue = 0.2, 0.2, 1.0, 1.0 in GlLight.light ~num:0 (`position pos); List.iter Gl.enable [`cull_face;`lighting;`light0;`depth_test;`normalize]; (* make the gears *) let make_gear ~inner ~outer ~width ~teeth ~color = let list = GlList.create `compile in GlLight.material ~face:`front (`ambient_and_diffuse color); gear ~inner ~outer ~width ~teeth ~tooth_depth:0.7; GlList.ends (); list in let gear1 = make_gear ~inner:1.0 ~outer:4.0 ~width:1.0 ~teeth:20 ~color:red and gear2 = make_gear ~inner:0.5 ~outer:2.0 ~width:2.0 ~teeth:10 ~color:green and gear3 = make_gear ~inner:1.3 ~outer:2.0 ~width:0.5 ~teeth:10 ~color:blue in (gear1, gear2, gear3) open Tk let main () = let top = openTk () in let f = Frame.create top in let v = Textvariable.create () in let my_scale = Scale.create ~min:0. ~max:180. ~showvalue:false ~highlightbackground:`Black in let togl = Togl.create f ~width:300 ~height:300 ~rgba:true ~depth:true ~double:true and sh = my_scale f ~orient:`Horizontal and sv = my_scale top ~orient:`Vertical in Wm.title_set top "Gears"; let gear1, gear2, gear3 = init() in let view = new view togl ~gear1 ~gear2 ~gear3 in Scale.configure sv ~command:(view#rotx); Scale.configure sh ~command:(view#roty); Scale.set sh 20.; Scale.set sv 40.; Togl.reshape_func togl ~cb:(fun () -> view#reshape); Togl.display_func togl ~cb:(fun () -> view#draw); Togl.timer_func ~ms:20 ~cb:(fun () -> view#idle); pack [sv] ~side:`Right ~fill:`Y; pack [f] ~expand:true ~fill:`Both; pack [togl] ~side:`Top ~expand:true ~fill:`Both; pack [sh] ~side:`Bottom ~fill:`X; Tk.mainLoop () let _ = main () lablgl-1.07/Togl/examples/gears_a.ml000066400000000000000000000160571437514534100173740ustar00rootroot00000000000000(* $Id: gears_a.ml,v 1.2 2003-10-01 10:11:41 raffalli Exp $ *) (* * 3-D gear wheels. This program is in the public domain. * * Brian Paul * LablGL version by Jacques Garrigue * * gears_a.ml: use vertex arrays *) let pi = acos (-1.) (* * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth *) let gear ~inner ~outer ~width ~teeth ~tooth_depth = let r0 = inner and r1 = outer -. tooth_depth /. 2.0 and r2 = outer +. tooth_depth /. 2.0 in let ta = 2.0 *. pi /. float teeth in let da = ta /. 4.0 in GlDraw.shade_model `flat; GlDraw.normal ~z:1.0 (); let vertex ~r ~z ?(s=0) i = let angle = float i *. ta +. float s *. da in GlDraw.vertex ~x:(r *. cos angle) ~y:(r *. sin angle) ~z () in let raw = Raw.create `float (12 * (teeth+1)) in GlArray.vertex `three raw; let count = ref 0 in let vertexa ~r ~z ?(s=0) i = let angle = float i *. ta +. float s *. da in let pos = !count * 3 in Raw.set_float raw ~pos (r *. cos angle); Raw.set_float raw ~pos:(pos+1) (r *. sin angle); Raw.set_float raw ~pos:(pos+2) z; incr count in (* draw front face *) let z = width *. 0.5 in for i=0 to teeth do vertexa i ~r:r0 ~z; vertexa i ~r:r1 ~z; vertexa i ~r:r0 ~z; vertexa i ~r:r1 ~z ~s:3; done; GlArray.draw_arrays `quad_strip 0 !count; count := 0; (* draw front sides of teeth *) for i=0 to teeth - 1 do vertexa i ~r:r1 ~z; vertexa i ~r:r2 ~s:1 ~z; vertexa i ~r:r2 ~s:2 ~z; vertexa i ~r:r1 ~s:3 ~z; done; GlArray.draw_arrays `quads 0 !count; count := 0; GlDraw.normal ~z:(-1.0) (); (* draw back face *) let z = -. width *. 0.5 in for i=0 to teeth do vertexa i ~r:r1 ~z; vertexa i ~r:r0 ~z; vertexa i ~r:r1 ~s:3 ~z; vertexa i ~r:r0 ~z; done; GlArray.draw_arrays `quad_strip 0 !count; count := 0; (* draw back sides of teeth *) for i=0 to teeth - 1 do vertexa i ~r:r1 ~s:3 ~z; vertexa i ~r:r2 ~s:2 ~z; vertexa i ~r:r2 ~s:1 ~z; vertexa i ~r:r1 ~z; done; GlArray.draw_arrays `quads 0 !count; count := 0; (* draw outward faces of teeth *) let z = width *. 0.5 and z' = width *. (-0.5) in GlDraw.begins `quad_strip; for i=0 to teeth - 1 do let angle = float i *. ta in vertex i ~r:r1 ~z; vertex i ~r:r1 ~z:z'; let u = r2 *. cos(angle+.da) -. r1 *. cos(angle) and v = r2 *. sin(angle+.da) -. r1 *. sin(angle) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r2 ~s:1 ~z; vertex i ~r:r2 ~s:1 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); vertex i ~r:r2 ~s:2 ~z; vertex i ~r:r2 ~s:2 ~z:z'; let u = r1 *. cos(angle +. 3. *. da) -. r2 *. cos(angle +. 2. *. da) and v = r1 *. sin(angle +. 3. *. da) -. r2 *. sin(angle +. 2. *. da) in GlDraw.normal ~x:v ~y:(-.u) (); vertex i ~r:r1 ~s:3 ~z; vertex i ~r:r1 ~s:3 ~z:z'; GlDraw.normal ~x:(cos angle) ~y:(sin angle) (); done; vertex 0 ~r:r1 ~z; vertex 0 ~r:r1 ~z:z'; GlDraw.ends (); GlDraw.shade_model `smooth; (* draw inside radius cylinder *) GlDraw.begins `quad_strip; for i=0 to teeth do let angle = float i *. ta in GlDraw.normal ~x:(-. cos angle) ~y:(-. sin angle) (); vertex i ~r:r0 ~z:z'; vertex i ~r:r0 ~z; done; GlDraw.ends () class view ~gear1 ~gear2 ~gear3 ?(limit=0) togl = object (self) val mutable view_rotx = 0.0 val mutable view_roty = 0.0 val mutable view_rotz = 0.0 val mutable angle = 0.0 val mutable count = 1 method rotx a = view_rotx <- a method roty a = view_roty <- a method draw = GlClear.clear [`color;`depth]; GlMat.push (); GlMat.rotate ~angle:view_rotx ~x:1.0 (); GlMat.rotate ~angle:view_roty ~y:1.0 (); GlMat.rotate ~angle:view_rotz ~z:1.0 (); GlMat.push (); GlMat.translate ~x:(-3.0) ~y:(-2.0) (); GlMat.rotate ~angle:angle ~z:1.0 (); (* gear inner:1.0 outer:4.0 width:1.0 teeth:20 tooth_depth:0.7; *) GlList.call gear1; GlMat.pop (); GlMat.push (); GlMat.translate ~x:3.1 ~y:(-2.0) (); GlMat.rotate ~angle:(-2.0 *. angle -. 9.0) ~z:1.0 (); (* gear inner:0.5 outer:2.0 width:2.0 teeth:10 tooth_depth:0.7; *) GlList.call gear2; GlMat.pop (); GlMat.push (); GlMat.translate ~x:(-3.1) ~y:4.2 (); GlMat.rotate ~angle:(-2.0 *. angle -. 25.0) ~z:1.0 (); (* gear inner:1.3 outer:2.0 width:0.5 teeth:10 tooth_depth:0.7; *) GlList.call gear3; GlMat.pop (); GlMat.pop (); Togl.swap_buffers togl; count <- count + 1; if count =limit then exit 0 method idle = angle <- angle +. 2.0; self#draw method reshape = let w = Togl.width togl and h = Togl.height togl in GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); let r = float w /. float h in let r' = 1. /. r in if (w>h) then GlMat.frustum ~x:(-. r,r) ~y:(-1.0,1.0) ~z:(5.0,60.0) else GlMat.frustum ~x:(-1.0,1.0) ~y:(-.r',r') ~z:(5.0,60.0); GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate ~z:(-40.0) (); GlClear.clear[`color;`depth] end let init () = let pos = 5.0, 5.0, 10.0, 0.0 and red = 0.8, 0.1, 0.0, 1.0 and green = 0.0, 0.8, 0.2, 1.0 and blue = 0.2, 0.2, 1.0, 1.0 in GlLight.light ~num:0 (`position pos); List.iter Gl.enable [`cull_face;`lighting;`light0;`depth_test;`normalize]; GlArray.enable `vertex; (* make the gears *) let make_gear ~inner ~outer ~width ~teeth ~color = let list = GlList.create `compile in GlLight.material ~face:`front (`ambient_and_diffuse color); gear ~inner ~outer ~width ~teeth ~tooth_depth:0.7; GlList.ends (); list in let gear1 = make_gear ~inner:1.0 ~outer:4.0 ~width:1.0 ~teeth:20 ~color:red and gear2 = make_gear ~inner:0.5 ~outer:2.0 ~width:2.0 ~teeth:10 ~color:green and gear3 = make_gear ~inner:1.3 ~outer:2.0 ~width:0.5 ~teeth:10 ~color:blue in (gear1, gear2, gear3) open Tk let main () = let top = openTk () in let f = Frame.create top in let v = Textvariable.create () in let my_scale = Scale.create ~min:0. ~max:180. ~showvalue:false ~highlightbackground:`Black in let togl = Togl.create f ~width:300 ~height:300 ~rgba:true ~depth:true ~double:true and sh = my_scale f ~orient:`Horizontal and sv = my_scale top ~orient:`Vertical in Wm.title_set top "Gears"; let gear1, gear2, gear3 = init() in let view = new view togl ~gear1 ~gear2 ~gear3 in Scale.configure sv ~command:(view#rotx); Scale.configure sh ~command:(view#roty); Scale.set sh 20.; Scale.set sv 40.; Togl.reshape_func togl ~cb:(fun () -> view#reshape); Togl.display_func togl ~cb:(fun () -> view#draw); Togl.timer_func ~ms:20 ~cb:(fun () -> view#idle); pack [sv] ~side:`Right ~fill:`Y; pack [f] ~expand:true ~fill:`Both; pack [togl] ~side:`Top ~expand:true ~fill:`Both; pack [sh] ~side:`Bottom ~fill:`X; Tk.mainLoop () let _ = main () lablgl-1.07/Togl/examples/morph3d.ml000066400000000000000000000477361437514534100173570ustar00rootroot00000000000000(* $Id: morph3d.ml,v 1.18 2001-05-08 01:58:25 garrigue Exp $ *) open StdLabels (*- * morph3d.c - Shows 3D morphing objects (TK Version) * * This program was inspired on a WindowsNT(R)'s screen saver. It was written * from scratch and it was not based on any other source code. * * Porting it to xlock (the final objective of this code since the moment I * decided to create it) was possible by comparing the original Mesa's gear * demo with it's ported version, so thanks for Danny Sung for his indirect * help (look at gear.c in xlock source tree). NOTE: At the moment this code * was sent to Brian Paul for package inclusion, the XLock Version was not * available. In fact, I'll wait it to appear on the next Mesa release (If you * are reading this, it means THIS release) to send it for xlock package * inclusion). It will probably there be a GLUT version too. * * Thanks goes also to Brian Paul for making it possible and inexpensive * to use OpenGL at home. * * Since I'm not a native english speaker, my apologies for any gramatical * mistake. * * My e-mail addresses are * * vianna@cat.cbpf.br * and * marcelo@venus.rdc.puc-rio.br * * Marcelo F. Vianna (Feb-13-1997) *) (* This document is VERY incomplete, but tries to describe the mathematics used in the program. At this moment it just describes how the polyhedra are generated. On futhurer versions, this document will be probabbly improved. Since I'm not a native english speaker, my apologies for any gramatical mistake. Marcelo Fernandes Vianna - Undergraduate in Computer Engeneering at Catholic Pontifical University - of Rio de Janeiro (PUC-Rio) Brasil. - e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br - Feb-13-1997 POLYHEDRA GENERATION For the purpose of this program it's not sufficient to know the polyhedra vertexes coordinates. Since the morphing algorithm applies a nonlinear transformation over the surfaces (faces) of the polyhedron, each face has to be divided into smaller ones. The morphing algorithm needs to transform each vertex of these smaller faces individually. It's a very time consoming task. In order to reduce calculation overload, and since all the macro faces of the polyhedron are transformed by the same way, the generation is made by creating only one face of the polyhedron, morphing it and then rotating it around the polyhedron center. What we need to know is the face radius of the polyhedron (the radius of the inscribed sphere) and the angle between the center of two adjacent faces using the center of the sphere as the angle's vertex. The face radius of the regular polyhedra are known values which I decided to not waste my time calculating. Following is a table of face radius for the regular polyhedra with edge length = 1: TETRAHEDRON : 1/(2*sqrt(2))/sqrt(3) CUBE : 1/2 OCTAHEDRON : 1/sqrt(6) DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2 -> where T=(sqrt(5)+1)/2 ICOSAHEDRON : (3*sqrt(3)+sqrt(15))/12 I've not found any reference about the mentioned angles, so I needed to calculate them, not a trivial task until I figured out how :) Curiously these angles are the same for the tetrahedron and octahedron. A way to obtain this value is inscribing the tetrahedron inside the cube by matching their vertexes. So you'll notice that the remaining unmatched vertexes are in the same straight line starting in the cube/tetrahedron center and crossing the center of each tetrahedron's face. At this point it's easy to obtain the bigger angle of the isosceles triangle formed by the center of the cube and two opposite vertexes on the same cube face. The edges of this triangle have the following lenghts: sqrt(2) for the base and sqrt(3)/2 for the other two other edges. So the angle we want is: +-----------------------------------------------------------+ | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +-----------------------------------------------------------+ For the cube this angle is obvious, but just for formality it can be easily obtained because we also know it's isosceles edge lenghts: sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we want is: +-----------------------------------------------------------+ | 2*ARCSIN((sqrt(2)/2)/1) = 90.000000000000000000 degrees | +-----------------------------------------------------------+ For the octahedron we use the same idea used for the tetrahedron, but now we inscribe the cube inside the octahedron so that all cubes's vertexes matches excatly the center of each octahedron's face. It's now clear that this angle is the same of the thetrahedron one: +-----------------------------------------------------------+ | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +-----------------------------------------------------------+ For the dodecahedron it's a little bit harder because it's only relationship with the cube is useless to us. So we need to solve the problem by another way. The concept of Face radius also exists on 2D polygons with the name Edge radius: Edge Radius For Pentagon (ERp) ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905 (VRp is the pentagon's vertex radio). Face Radius For Dodecahedron FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404 Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle, completing this triangle, the lesser angle is a half of the angle we are looking for, so this angle is: +-----------------------------------------------------------+ | 2*ARCTAN(ERp/FRd) = 63.434948822922009981 degrees | +-----------------------------------------------------------+ For the icosahedron we can use the same method used for dodecahedron (well the method used for dodecahedron may be used for all regular polyhedra) Edge Radius For Triangle (this one is well known: 1/3 of the triangle height) ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655 Face Radius For Icosahedron FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538 So the angle is: +-----------------------------------------------------------+ | 2*ARCTAN(ERt/FRi) = 41.810314895778596167 degrees | +-----------------------------------------------------------+ *) let scale = 0.3 let vect_mul (x1,y1,z1) (x2,y2,z2) = (y1 *. z2 -. z1 *. y2, z1 *. x2 -. x1 *. z2, x1 *. y2 -. y1 *. x2) let sqr a = a *. a (* Increasing this values produces better image quality, the price is speed. *) (* Very low values produces erroneous/incorrect plotting *) let tetradivisions = 23 let cubedivisions = 20 let octadivisions = 21 let dodecadivisions = 10 let icodivisions = 15 let tetraangle = 109.47122063449069174 let cubeangle = 90.000000000000000000 let octaangle = 109.47122063449069174 let dodecaangle = 63.434948822922009981 let icoangle = 41.810314895778596167 let pi = acos (-1.) let sqrt2 = sqrt 2. let sqrt3 = sqrt 3. let sqrt5 = sqrt 5. let sqrt6 = sqrt 6. let sqrt15 = sqrt 15. let cossec36_2 = 0.8506508083520399322 let cosd x = cos (float x /. 180. *. pi) let sind x = sin (float x /. 180. *. pi) let cos72 = cosd 72 let sin72 = sind 72 let cos36 = cosd 36 let sin36 = sind 36 (*************************************************************************) let front_shininess = 60.0 let front_specular = 0.7, 0.7, 0.7, 1.0 let ambient = 0.0, 0.0, 0.0, 1.0 let diffuse = 1.0, 1.0, 1.0, 1.0 let position0 = 1.0, 1.0, 1.0, 0.0 let position1 = -1.0,-1.0, 1.0, 0.0 let lmodel_ambient = 0.5, 0.5, 0.5, 1.0 let lmodel_twoside = true let materialRed = 0.7, 0.0, 0.0, 1.0 let materialGreen = 0.1, 0.5, 0.2, 1.0 let materialBlue = 0.0, 0.0, 0.7, 1.0 let materialCyan = 0.2, 0.5, 0.7, 1.0 let materialYellow = 0.7, 0.7, 0.0, 1.0 let materialMagenta = 0.6, 0.2, 0.5, 1.0 let materialWhite = 0.7, 0.7, 0.7, 1.0 let materialGray = 0.2, 0.2, 0.2, 1.0 let all_gray = Array.create 20 materialGray let vertex ~xf ~yf ~zf ~ampvr2 = let xa = xf +. 0.01 and yb = yf +. 0.01 in let xf2 = sqr xf and yf2 = sqr yf in let factor = 1. -. (xf2 +. yf2) *. ampvr2 and factor1 = 1. -. (sqr xa +. yf2) *. ampvr2 and factor2 = 1. -. (xf2 +. sqr yb) *. ampvr2 in let vertx = factor *. xf and verty = factor *. yf and vertz = factor *. zf in let neiax = factor1 *. xa -. vertx and neiay = factor1 *. yf -. verty and neiaz = factor1 *. zf -. vertz and neibx = factor2 *. xf -. vertx and neiby = factor2 *. yb -. verty and neibz = factor2 *. zf -. vertz in GlDraw.normal3 (vect_mul (neiax, neiay, neiaz) (neibx, neiby, neibz)); GlDraw.vertex3 (vertx, verty, vertz) let triangle ~edge ~amp ~divisions ~z = let divi = float divisions in let vr = edge *. sqrt3 /. 3. in let ampvr2 = amp /. sqr vr and zf = edge *. z in let ax = edge *. (0.5 /. divi) and ay = edge *. (-0.5 *. sqrt3 /. divi) and bx = edge *. (-0.5 /. divi) in for ri = 1 to divisions do GlDraw.begins `triangle_strip; for ti = 0 to ri - 1 do vertex ~zf ~ampvr2 ~xf:(float (ri-ti) *. ax +. float ti *. bx) ~yf:(vr +. float (ri-ti) *. ay +. float ti *. ay); vertex ~zf ~ampvr2 ~xf:(float (ri-ti-1) *. ax +. float ti *. bx) ~yf:(vr +. float (ri-ti-1) *. ay +. float ti *. ay) done; vertex ~xf:(float ri *. bx) ~yf:(vr +. float ri *. ay) ~zf ~ampvr2; GlDraw.ends () done let square ~edge ~amp ~divisions ~z = let divi = float divisions in let zf = edge *. z and ampvr2 = amp /. sqr (edge *. sqrt2 /. 2.) in for yi = 0 to divisions - 1 do let yf = edge *. (-0.5 +. float yi /. divi) in let yf2 = sqr yf in let y = yf +. 1.0 /. divi *. edge in let y2 = sqr y in GlDraw.begins `quad_strip; for xi = 0 to divisions do let xf = edge *. (-0.5 +. float xi /. divi) in vertex ~xf ~yf:y ~zf ~ampvr2; vertex ~xf ~yf ~zf ~ampvr2 done; GlDraw.ends () done let pentagon ~edge ~amp ~divisions ~z = let divi = float divisions in let zf = edge *. z and ampvr2 = amp /. sqr(edge *. cossec36_2) in let x = Array.init 6 ~f:(fun fi -> -. cos (float fi *. 2. *. pi /. 5. +. pi /. 10.) /. divi *. cossec36_2 *. edge) and y = Array.init 6 ~f:(fun fi -> sin (float fi *. 2. *. pi /. 5. +. pi /. 10.) /. divi *. cossec36_2 *. edge) in for ri = 1 to divisions do for fi = 0 to 4 do GlDraw.begins `triangle_strip; for ti = 0 to ri-1 do vertex ~zf ~ampvr2 ~xf:(float(ri-ti) *. x.(fi) +. float ti *. x.(fi+1)) ~yf:(float(ri-ti) *. y.(fi) +. float ti *. y.(fi+1)); vertex ~zf ~ampvr2 ~xf:(float(ri-ti-1) *. x.(fi) +. float ti *. x.(fi+1)) ~yf:(float(ri-ti-1) *. y.(fi) +. float ti *. y.(fi+1)) done; vertex ~xf:(float ri *. x.(fi+1)) ~yf:(float ri *. y.(fi+1)) ~zf ~ampvr2; GlDraw.ends () done done let call_list list color = GlLight.material ~face:`both (`diffuse color); GlList.call list let draw_tetra ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:2.0 ~amp ~divisions ~z:(0.5 /. sqrt6); GlList.ends(); call_list list color.(0); GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-.tetraangle) ~x:1.0 (); call_list list color.(1); GlMat.pop(); GlMat.push(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(sqrt3 /. 2.) (); call_list list color.(2); GlMat.pop(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(-.sqrt3 /. 2.) (); call_list list color.(3); GlList.delete list let draw_cube ~amp ~divisions ~color = let list = GlList.create `compile in square ~edge:2.0 ~amp ~divisions ~z:0.5; GlList.ends (); call_list list color.(0); for i = 1 to 3 do GlMat.rotate ~angle:cubeangle ~x:1.0 (); call_list list color.(i) done; GlMat.rotate ~angle:cubeangle ~y:1.0 (); call_list list color.(4); GlMat.rotate ~angle:(2.0 *. cubeangle) ~y:1.0 (); call_list list color.(5); GlList.delete list let draw_octa ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:2.0 ~amp ~divisions ~z:(1.0 /. sqrt6); GlList.ends (); let do_list (i,y) = GlMat.push(); GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-.octaangle) ~x:0.5 ~y (); call_list list color.(i); GlMat.pop() in call_list list color.(0); GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); call_list list color.(1); GlMat.pop(); List.iter [2, sqrt3 /. 2.0; 3, -.sqrt3 /. 2.0] ~f:do_list; GlMat.rotate ~angle:180.0 ~x:1.0 (); GlLight.material ~face:`both (`diffuse color.(4)); GlList.call list; GlMat.push(); GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); GlLight.material ~face:`both (`diffuse color.(5)); GlList.call list; GlMat.pop(); List.iter [6, sqrt3 /. 2.0; 7, -.sqrt3 /. 2.0] ~f:do_list; GlList.delete list let draw_dodeca ~amp ~divisions ~color = let tau = (sqrt5 +. 1.0) /. 2.0 in let list = GlList.create `compile in pentagon ~edge:2.0 ~amp ~divisions ~z:(sqr(tau) *. sqrt ((tau+.2.0)/.5.0) /. 2.0); GlList.ends (); let do_list (i,angle,x,y) = GlMat.push(); GlMat.rotate ~angle:angle ~x ~y (); call_list list color.(i); GlMat.pop(); in GlMat.push (); call_list list color.(0); GlMat.rotate ~angle:180.0 ~z:1.0 (); List.iter ~f:do_list [ 1, -.dodecaangle, 1.0, 0.0; 2, -.dodecaangle, cos72, sin72; 3, -.dodecaangle, cos72, -.sin72; 4, dodecaangle, cos36, -.sin36; 5, dodecaangle, cos36, sin36 ]; GlMat.pop (); GlMat.rotate ~angle:180.0 ~x:1.0 (); call_list list color.(6); GlMat.rotate ~angle:180.0 ~z:1.0 (); List.iter ~f:do_list [ 7, -.dodecaangle, 1.0, 0.0; 8, -.dodecaangle, cos72, sin72; 9, -.dodecaangle, cos72, -.sin72; 10, dodecaangle, cos36, -.sin36 ]; GlMat.rotate ~angle:dodecaangle ~x:cos36 ~y:sin36 (); call_list list color.(11); GlList.delete list let draw_ico ~amp ~divisions ~color = let list = GlList.create `compile in triangle ~edge:1.5 ~amp ~divisions ~z:((3.0 *. sqrt3 +. sqrt15) /. 12.0); GlList.ends (); let do_list1 i = GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(sqrt3/.2.0) (); call_list list color.(i) and do_list2 i = GlMat.rotate ~angle:180.0 ~y:1.0 (); GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(-.sqrt3/.2.0) (); call_list list color.(i) and do_list3 i = GlMat.rotate ~angle:180.0 ~z:1.0 (); GlMat.rotate ~angle:(-.icoangle) ~x:1.0 (); call_list list color.(i) in GlMat.push (); call_list list color.(0); GlMat.push (); do_list3 1; GlMat.push (); do_list1 2; GlMat.pop (); do_list2 3; GlMat.pop (); GlMat.push (); do_list1 4; GlMat.push (); do_list1 5; GlMat.pop(); do_list3 6; GlMat.pop (); do_list2 7; GlMat.push (); do_list2 8; GlMat.pop (); do_list3 9; GlMat.pop (); GlMat.rotate ~angle:180.0 ~x:1.0 (); call_list list color.(10); GlMat.push (); do_list3 11; GlMat.push (); do_list1 12; GlMat.pop (); do_list2 13; GlMat.pop (); GlMat.push (); do_list1 14; GlMat.push (); do_list1 15; GlMat.pop (); do_list3 16; GlMat.pop (); do_list2 17; GlMat.push (); do_list2 18; GlMat.pop (); do_list3 19; GlList.delete list class view togl = object (self) val togl = togl val mutable smooth = true val mutable step = 0. val mutable obj = 1 val mutable draw_object = fun ~amp -> () val mutable magnitude = 0. method width = Togl.width togl method height = Togl.height togl method draw = let ratio = float self#height /. float self#width in GlClear.clear [`color;`depth]; GlMat.push (); GlMat.translate () ~z:(-10.0); GlMat.scale () ~x:(scale *. ratio) ~y:scale ~z:scale; GlMat.translate () ~x:(2.5 *. ratio *. sin (step *. 1.11)) ~y:(2.5 *. cos (step *. 1.25 *. 1.11)); GlMat.rotate ~angle:(step *. 100.) ~x:1.0 (); GlMat.rotate ~angle:(step *. 95.) ~y:1.0 (); GlMat.rotate ~angle:(step *. 90.) ~z:1.0 (); draw_object ~amp:((sin step +. 1.0/.3.0) *. (4.0/.5.0) *. magnitude); GlMat.pop(); Gl.flush(); Togl.swap_buffers togl; step <- step +. 0.05 method reshape = GlDraw.viewport ~x:0 ~y:0 ~w:self#width ~h:self#height; GlMat.mode `projection; GlMat.load_identity(); GlMat.frustum ~x:(-1.0, 1.0) ~y:(-1.0, 1.0) ~z:(5.0, 15.0); GlMat.mode `modelview method key sym = begin match sym with "1" -> obj <- 1 | "2" -> obj <- 2 | "3" -> obj <- 3 | "4" -> obj <- 4 | "5" -> obj <- 5 | "Return" -> smooth <- not smooth | "Escape" -> Tk.destroy (Winfo.toplevel togl); exit 0 | _ -> () end; self#pinit method pinit = begin match obj with 1 -> draw_object <- draw_tetra ~divisions:tetradivisions ~color:[|materialRed; materialGreen; materialBlue; materialWhite|]; magnitude <- 2.5 | 2 -> draw_object <- draw_cube ~divisions:cubedivisions ~color:[|materialRed; materialGreen; materialCyan; materialMagenta; materialYellow; materialBlue|]; magnitude <- 2.0 | 3 -> draw_object <- draw_octa ~divisions:octadivisions ~color:[|materialRed; materialGreen; materialBlue; materialWhite; materialCyan; materialMagenta; materialGray; materialYellow|]; magnitude <- 2.5 | 4 -> draw_object <- draw_dodeca ~divisions:dodecadivisions ~color:[|materialRed; materialGreen; materialCyan; materialBlue; materialMagenta; materialYellow; materialGreen; materialCyan; materialRed; materialMagenta; materialBlue; materialYellow|]; magnitude <- 2.0 | 5 -> draw_object <- draw_ico ~divisions:icodivisions ~color:[|materialRed; materialGreen; materialBlue; materialCyan; materialYellow; materialMagenta; materialRed; materialGreen; materialBlue; materialWhite; materialCyan; materialYellow; materialMagenta; materialRed; materialGreen; materialBlue; materialCyan; materialYellow; materialMagenta; materialGray|]; magnitude <- 3.5 | _ -> () end; GlDraw.shade_model (if smooth then `smooth else `flat) end open Tk let main () = List.iter ~f:print_string [ "Morph 3D - Shows morphing platonic polyhedra\n"; "Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n"; "Ported to LablGL by Jacques Garrigue\n\n"; " [1] - Tetrahedron\n"; " [2] - Hexahedron (Cube)\n"; " [3] - Octahedron\n"; " [4] - Dodecahedron\n"; " [5] - Icosahedron\n"; "[RETURN] - Toggle smooth/flat shading\n"; " [ESC] - Quit\n" ]; flush stdout; let top = openTk () in let togl = Togl.create top ~width:640 ~height:480 ~depth:true ~double:true ~rgba:true in Wm.title_set top "Morph 3D - Shows morphing platonic polyhedra"; GlClear.depth 1.0; GlClear.color (0.0, 0.0, 0.0); GlDraw.color (1.0, 1.0, 1.0); GlClear.clear [`color;`depth]; Gl.flush(); Togl.swap_buffers togl; List.iter ~f:(GlLight.light ~num:0) [`ambient ambient; `diffuse diffuse; `position position0]; List.iter ~f:(GlLight.light ~num:1) [`ambient ambient; `diffuse diffuse; `position position1]; GlLight.light_model (`ambient lmodel_ambient); GlLight.light_model (`two_side lmodel_twoside); List.iter ~f:Gl.enable [`lighting;`light0;`light1;`depth_test;`normalize]; GlLight.material ~face:`both (`shininess front_shininess); GlLight.material ~face:`both (`specular front_specular); GlMisc.hint `fog `fastest; GlMisc.hint `perspective_correction `fastest; GlMisc.hint `polygon_smooth `fastest; let view = new view togl in view#pinit; Togl.display_func togl ~cb:(fun () -> view#draw); Togl.reshape_func togl ~cb:(fun () -> view#reshape); Togl.timer_func ~ms:20 ~cb:(fun () -> view#draw); bind togl ~events:[`KeyPress] ~fields:[`KeySymString] ~action:(fun ev -> view#key ev.ev_KeySymString); bind togl ~events:[`Enter] ~action:(fun _ -> Focus.set togl); pack [togl] ~expand:true ~fill:`Both; mainLoop () let _ = main () lablgl-1.07/Togl/examples/planet.ml000066400000000000000000000071431437514534100172520ustar00rootroot00000000000000(* $Id: planet.ml,v 1.17 2001-09-07 06:50:01 garrigue Exp $ *) #load"unix.cma";; class planet togl = object (self) val togl = togl val mutable year = 0.0 val mutable day = 0.0 val mutable eye = 0.0 val mutable time = 0.0 method tick new_time = if time = 0. then time <- new_time else let diff = new_time -. time in time <- new_time; day <- mod_float (day +. diff *. 200.) 360.0; year <- mod_float (year +. diff *. 20.) 360.0 method day_add = day <- mod_float (day +. 10.0) 360.0 method day_subtract = day <- mod_float (day -. 10.0) 360.0 method year_add = year <- mod_float (year +. 5.0) 360.0 method year_subtract = year <- mod_float (year -. 5.0) 360.0 method eye x = eye <- x; self#display method display = GlClear.clear [`color;`depth]; GlDraw.color (1.0, 1.0, 1.0); GlMat.push(); GlMat.rotate ~angle:eye ~x:1. (); (* draw sun *) GlLight.material ~face:`front (`specular (1.0,1.0,0.0,1.0)); GlLight.material ~face:`front (`shininess 5.0); GluQuadric.sphere ~radius:1.0 ~slices:32 ~stacks:32 (); (* draw smaller planet *) GlMat.rotate ~angle:year ~y:1.0 (); GlMat.translate () ~x:3.0; GlMat.rotate ~angle:day ~y:1.0 (); GlDraw.color (0.0, 1.0, 1.0); GlDraw.shade_model `flat; GlLight.material ~face:`front(`shininess 128.0); GluQuadric.sphere ~radius:0.2 ~slices:10 ~stacks:10 (); GlDraw.shade_model `smooth; GlMat.pop (); Gl.flush (); Togl.swap_buffers togl end let myinit () = let light_ambient = 0.5, 0.5, 0.5, 1.0 and light_diffuse = 1.0, 0.8, 0.2, 1.0 and light_specular = 1.0, 1.0, 1.0, 1.0 (* light_position is NOT default value *) and light_position = 1.0, 1.0, 1.0, 0.0 in List.iter (GlLight.light ~num:0) [ `ambient light_ambient; `diffuse light_diffuse; `specular light_specular; `position light_position ]; GlFunc.depth_func `less; List.iter Gl.enable [`lighting; `light0; `depth_test]; GlDraw.shade_model `smooth let my_reshape togl = let w = Togl.width togl and h = Togl.height togl in GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity(); GluMat.perspective ~fovy:60.0 ~aspect:(float w /. float h) ~z:(1.0,20.0); GlMat.mode `modelview; GlMat.load_identity(); GlMat.translate () ~z:(-5.0) (* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. *) open Tk let main () = let top = openTk () in let togl = Togl.create top ~width:700 ~height:500 ~double:true ~rgba:true ~depth:true in Wm.title_set top "Planet"; myinit (); let planet = new planet togl in let scale = Scale.create top ~min:(-45.) ~max:45. ~orient:`Vertical ~command:(planet#eye) ~showvalue:false ~highlightbackground:`Black in bind togl ~events:[`Enter] ~action:(fun _ -> Focus.set togl); bind scale ~events:[`Enter] ~action:(fun _ -> Focus.set scale); bind togl ~events:[`KeyPress] ~fields:[`KeySymString] ~action:(fun ev -> begin match ev.ev_KeySymString with "Left" -> planet#year_subtract | "Right" -> planet#year_add | "Up" -> planet#day_add | "Down" -> planet#day_subtract | "Escape" -> destroy top; exit 0 | _ -> () end; planet#display); Togl.timer_func ~ms:20 ~cb:(fun () -> planet#tick (Unix.gettimeofday()); planet#display); Togl.display_func togl ~cb:(fun () -> planet#display); Togl.reshape_func togl ~cb:(fun () -> my_reshape togl); my_reshape togl; pack [togl] ~side:`Left ~expand:true ~fill:`Both; pack [scale] ~side:`Right ~fill:`Y; Focus.set togl; mainLoop () let _ = Printexc.print main () lablgl-1.07/Togl/examples/scene.ml000066400000000000000000000057441437514534100170710ustar00rootroot00000000000000(* $Id: scene.ml,v 1.12 2001-05-08 01:58:26 garrigue Exp $ *) (* Initialize material property and light source. *) let myinit () = let light_ambient = 0.0, 0.0, 0.0, 1.0 and light_diffuse = 1.0, 1.0, 1.0, 1.0 and light_specular = 1.0, 1.0, 1.0, 1.0 (* light_position is NOT default value *) and light_position = 1.0, 1.0, 1.0, 0.0 in GlLight.light ~num:0 (`ambient light_ambient); GlLight.light ~num:0 (`diffuse light_diffuse); GlLight.light ~num:0 (`specular light_specular); GlLight.light ~num:0 (`position light_position); GlFunc.depth_func `less; List.iter Gl.enable [`lighting; `light0; `depth_test] let pi = acos (-1.) let solid_torus ~inner ~outer = let slices = 32 and faces = 16 in let slice_angle = 2.0 *. pi /. float slices and face_angle = 2.0 *. pi /. float faces in let vertex ~i ~j = let angle1 = slice_angle *. float i and angle2 = face_angle *. float j in GlDraw.normal3 (cos angle1 *. cos angle2, -. sin angle1 *. cos angle2, sin angle2); GlDraw.vertex3 ((outer +. inner *. cos angle2) *. cos angle1, -. (outer +. inner *. cos angle2) *. sin angle1, inner *. sin angle2) in GlDraw.begins `quads; for i = 0 to slices - 1 do for j = 0 to faces - 1 do vertex ~i ~j; vertex ~i:(i+1) ~j; vertex ~i:(i+1) ~j:(j+1); vertex ~i ~j:(j+1); done done; GlDraw.ends () let solid_cone ~radius ~height = GluQuadric.cylinder ~base:radius ~top:0. ~height ~slices:15 ~stacks:10 () let solid_sphere ~radius = GluQuadric.sphere ~radius ~slices:32 ~stacks:32 () let display () = GlClear.clear [`color; `depth]; GlMat.push (); GlMat.rotate ~angle:20.0 ~x:1.0 (); GlMat.push (); GlMat.translate ~x:(-0.75) ~y:0.5 (); GlMat.rotate ~angle:90.0 ~x:1.0 (); solid_torus ~inner:0.275 ~outer:0.85; GlMat.pop (); GlMat.push (); GlMat.translate ~x:(-0.75) ~y:(-0.5) (); GlMat.rotate ~angle:270.0 ~x:1.0 (); solid_cone ~radius:1.0 ~height:2.0; GlMat.pop (); GlMat.push (); GlMat.translate ~x:0.75 ~z:(-1.0) (); solid_sphere ~radius:1.0; GlMat.pop (); GlMat.pop (); Gl.flush () let my_reshape ~w ~h = GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); if w <= h then GlMat.ortho ~x:(-2.5,2.5) ~z:(-10.0,10.0) ~y:(-2.5 *. float h /. float w, 2.5 *. float h /. float w) else GlMat.ortho ~y:(-2.5,2.5) ~z:(-10.0,10.0) ~x:(-2.5 *. float w /. float h, 2.5 *. float w /. float h); GlMat.mode `modelview (* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. *) open Tk let main () = let top = openTk () in let togl = Togl.create top ~rgba:true ~depth:true ~width:500 ~height:500 in Wm.title_set top "Scene"; myinit (); Togl.reshape_func togl ~cb:(fun () -> my_reshape ~w:(Togl.width togl) ~h:(Togl.height togl)); Togl.display_func togl ~cb:display; pack [togl] ~expand:true ~fill:`Both; mainLoop () let _ = Printexc.print main () lablgl-1.07/Togl/examples/simple.ml000066400000000000000000000020321437514534100172500ustar00rootroot00000000000000(* $Id: simple.ml,v 1.10 2002-04-27 02:35:45 garrigue Exp $ *) open Tk let main () = (* Aux.init_display_mode [`rgb;`single;`depth]; Aux.init_position ~x:0 ~y:0 ~w:500 ~h:500; Aux.init_window ~title:"LablGL"; *) let top = openTk () in let togl = Togl.create top ~width:500 ~height:500 ~rgba:true ~depth:true ~double:true in Wm.title_set top "LablGL"; pack ~fill:`Both [togl]; Togl.display_func togl ~cb: begin fun () -> GlClear.color (0.0, 0.0, 0.0); GlClear.clear [`color]; GlDraw.color (1.0, 1.0, 1.0); GlMat.mode `projection; GlMat.load_identity (); GlMat.ortho ~x:(-1.0,1.0) ~y:(-1.0,1.0) ~z:(-1.0,1.0); GlDraw.begins `polygon; GlDraw.vertex ~x:(-0.5) ~y:(-0.5) (); GlDraw.vertex ~x:(-0.5) ~y:(0.5) (); GlDraw.vertex ~x:(0.5) ~y:(0.5) (); GlDraw.vertex ~x:(0.5) ~y:(-0.5) (); GlDraw.ends (); Gl.flush (); Togl.swap_buffers togl end; ignore (Timer.add ~ms:10000 ~callback:(fun () -> destroy top)); mainLoop () let _ = main () lablgl-1.07/Togl/examples/tennis.ml000066400000000000000000000333711437514534100172710ustar00rootroot00000000000000(* This program was written by Yasuhiko Minamide, nan@kurims.kyoto-u.ac.jp *) (* $Id: tennis.ml,v 1.17 2001-05-08 01:58:26 garrigue Exp $ *) open StdLabels let image_height = 64 and image_width = 64 let make_image () = let image = GlPix.create `ubyte ~width:image_width ~height:image_height ~format:`rgba in for i = 0 to image_width - 1 do for j = 0 to image_height - 1 do Raw.sets (GlPix.to_raw image) ~pos:(4*(i*image_height+j)) (if (((i land 6 ) = 6) or ((j land 6) = 6)) then [|0;0;0;255|] else [|255;255;255;0|]) done done; image let image_height = 256 and image_width = 256 let make_image2 () = let on_circle (x0,y0) (x,y) = let d = (x -. x0) *. (x -. x0) +. (y -. y0) *. (y -. y0) in ((d > 0.9 *. 0.9) && (d < 1.1 *. 1.1)) in let on_line (x,y) = if x <= -.2.0 then on_circle (-. 2.0, 0.0) (x,y) else if x >= 2.0 then on_circle (2.0, 0.0) (x,y) else ((0.9 < y) && (y < 1.1)) || ((-1.1 <= y) && ( y <= -0.9)) in let on_white (i,j) = let x = (float (i - 128) /. 128.0) *. 6.0 in let y = (float (j - 128) /. 128.0) *. 2.0 in on_line (x,y) in let image = GlPix.create `ubyte ~width:image_width ~height:image_height ~format:`rgb in for i = 0 to image_width - 1 do for j = 0 to image_height - 1 do Raw.sets (GlPix.to_raw image) ~pos:(3*(i*image_height+j)) (if on_white (j,i) then [|255;255;255|] else [|255;255;0|]) done done; image let ft x = x *. 0.03 let cw = ft (9.0 +. 4.5) let cl = ft 39.0 let sw = ft 9.0 let sl = ft 21.0 let lw = 0.015 let wlw = 0.02 let square (x1, y1) (x2, y2) = List.iter ~f:GlDraw.vertex2 [ x1, y1; x2, y1; x2, y2; x1, y2 ] let collide ~pos ~vel ~plane ~func = let between (a,b,x) = let (a,b) = if a > b then (b,a) else (a,b) in (x > a) && (x < b) in let (xpos,ypos,zpos) = pos in let (dx,dy,dz) = vel in if dx = 0.0 then (xpos, ypos +. dy, zpos +. dz) else let ((x1,y1,z1),(x2,y2,z2)) = plane in let y = if dy = 0.0 then ypos else (dy /. dx) *. (x1 -. xpos) +. ypos in let z = if dz = 0.0 then zpos else (dz /. dx) *. (x1 -. xpos) +. zpos in if between (y1, y2, y) && between (z1, z2, z) && between (xpos, xpos +. dx, x1) then begin func (); (x1, y, z) end else (xpos +. dx, ypos +. dy, zpos +. dz) class ball () = object (self) val mutable x = 0.0 val mutable y = 0.0 val mutable z = 0.2 val mutable target_x = 0.0 val mutable target_y = 0.0 val mutable velocity = 0.0 val mutable angle_z = 0.0 val mutable vel_z = 0.0 val mutable vel_y = 0.0 val mutable vel_x = 0.0 val mutable moving = false val image = make_image2 () method set_vel v = velocity <- v /. 36.0; method set_velz v = angle_z <- v method reset = () method draw = Gl.disable `blend; GlDraw.color (1.0, 1.0, 0.0); GlMat.push (); GlMat.translate ~x ~y ~z (); GluQuadric.sphere ~radius:0.01 ~slices:8 ~stacks:8 (); GlMat.pop () method drawtexture = let q = GluQuadric.create () in GlMat.push (); Gl.enable `texture_2d; GlTex.image2d image; List.iter ~f:(GlTex.parameter ~target:`texture_2d) [ `wrap_s `repeat; `wrap_t `repeat; `mag_filter `nearest; `min_filter `nearest ]; GlMat.translate ~x ~y ~z (); GluQuadric.texture q true; GluQuadric.sphere ~radius:0.01 ~slices:16 ~stacks:8 ~quad:q (); Gl.disable `texture_2d; GlMat.pop () method draw_shadow = Gl.disable `blend; GlDraw.color (0.0, 0.0, 0.0); GlMat.push (); GlMat.translate ~x ~y (); GluQuadric.disk ~inner:0.0 ~outer:0.01 ~slices:8 ~loops:8 (); GlMat.pop () method draw_target = let (x,y) = (target_x, target_y) in GlDraw.begins `quads; GlDraw.color (0.0, 0.0, 1.0); square (x -. 0.05, y +. 0.05) (x +. 0.05, y -. 0.05); GlDraw.ends () method do_tick delta = if moving then let (x',y',z') = collide ~pos:(x,y,z) ~vel:(-. vel_x *. delta, vel_y *. delta, vel_z *. delta) ~plane:((0.0, -. cw, 0.0), (0.0, cw, 0.1)) ~func:(function () -> begin vel_x <- 0.0; vel_y <- 0.0; vel_z <- 0.0 end) in let vel_z' = vel_z in let (z',vel_z') = if z' < 0.01 then (-. (z' -. 0.01) +. 0.01, -. vel_z' *. 0.7) else (z',vel_z') in let vel_z' = vel_z' -. delta *. 0.98 in vel_z <- vel_z'; x <- x'; y <- y'; z <- z' else (); moving method set_position x' y' = x <- x'; y <- y' method set_target x' y' = target_x <- x'; target_y <- y' method set_z z' = z <- z' /. 100. method get_position = (x, y) method calc_vel = let dx = x -. target_x and dy = target_y -. y in let d' = sqrt ( dx *. dx +. dy *. dy) in let cos_z = cos(angle_z /. 180. *. 3.14) in if cos_z = 0.0 or d' = 0.0 then () else let dz = d' *. (tan(angle_z /. 180. *. 3.14)) in let d = d' /. cos_z in begin vel_x <- velocity *. dx /. d; vel_y <- velocity *. dy /. d; vel_z <- velocity *. dz /. d end method switch = if moving then self#reset else self#calc_vel; moving <- not moving; moving end class poll = object val r = 0.008 val y = cw +. 0.05 +. 0.008 method draw = Gl.disable `blend; GlDraw.color (0.0, 0.0, 0.0); GlMat.push (); GlMat.translate ~y (); GluQuadric.cylinder ~slices:8 ~stacks:8 ~height:0.12 ~top:r ~base:r (); GlMat.pop (); GlMat.push (); GlMat.translate ~y:(-. y) (); GluQuadric.cylinder ~slices:8 ~stacks:8 ~height:0.12 ~top:r ~base:r (); GlMat.pop () end class court ~togl = object val court = Togl.make_current togl; let court = GlList.create `compile in GlDraw.shade_model `flat; GlDraw.begins `quads; GlDraw.color (0.2, 0.7, 0.2); square (cl, cw) (-.cl, -.cw); (* Lines *) GlDraw.color (1.0, 1.0, 1.0); square (-.cl, cw) (cl, cw -. lw); square (-.cl, -.cw) (cl, -.cw +. lw); square (cl, cw) (cl -. wlw, -. cw); square (-.cl, cw) (-.cl +. wlw, -.cw); square (-.sl, lw /. 2.) (sl, -.lw /. 2.); square (-.cl, sw) (cl, sw -. lw); square (-.cl, -.sw) (cl, -.sw +. lw); square (sl, sw) (sl -. lw, -. sw); square (-.sl, sw) (-.sl +. lw, -.sw); GlDraw.ends (); GlList.ends (); court method draw = GlList.call court end class player = object (* position of a player *) val mutable x = -1.0 val mutable y = 0.5 method move x' y' = x <- -. x'; y <- y' method position = (x,y) end class net ~togl = object val texture = Togl.make_current togl; make_image () (* let image = make_image () in GlTex.image2d image; List.iter f:(GlTex.parameter target:`texture_2d) [ `wrap_s `repeat; `wrap_t `repeat; `mag_filter `nearest; `min_filter `nearest ]; *) method draw = Gl.enable `blend; GlFunc.blend_func ~src:`src_alpha ~dst:`one_minus_src_alpha; GlDraw.color (0.0, 0.0, 0.0) ~alpha:1.0; GlTex.env (`mode `replace); Gl.enable `texture_2d; GlTex.image2d texture; List.iter ~f:(GlTex.parameter ~target:`texture_2d) [ `wrap_s `repeat; `wrap_t `repeat; `mag_filter `nearest; `min_filter `nearest ]; GlDraw.begins `quads; GlTex.coord2(0.0, 0.0); GlDraw.vertex3(0.0, cw +. 0.05, 0.0); GlTex.coord2(0.0, 3.0); GlDraw.vertex3(0.0, cw +. 0.05, 0.115); GlTex.coord2(9.0, 3.0); GlDraw.vertex3(0.0, 0.0, 0.09); GlTex.coord2(9.0, 0.0); GlDraw.vertex3(0.0, 0.0, 0.0); GlTex.coord2(0.0, 0.0); GlDraw.vertex3(0.0, 0.0, 0.0); GlTex.coord2(0.0, 3.0); GlDraw.vertex3(0.0, 0.0, 0.09); GlTex.coord2(9.0, 3.0); GlDraw.vertex3(0.0, -.cw -. 0.05, 0.115); GlTex.coord2(9.0, 0.0); GlDraw.vertex3(0.0, -.cw -. 0.05, 0.0); GlDraw.ends (); Gl.disable `texture_2d; Gl.disable `blend; GlDraw.color (1.0, 1.0, 1.0); GlDraw.begins `quad_strip; List.iter ~f:(fun (y,z) -> GlDraw.vertex ~x:0. ~y ~z ()) [ cw +. 0.05, 0.11; cw +. 0.05, 0.115; 0.0, 0.085; 0.0, 0.09; -.cw -. 0.05, 0.11; -.cw -. 0.05, 0.115 ]; GlDraw.ends () end class view3d ~togl ~ball ~player ~viewtype = object val ball : ball = ball val player : player = player val court = new court ~togl val net = new net ~togl val poll = new poll method draw = Togl.make_current togl; GlClear.color (0.5, 0.5, 1.0); GlClear.clear [`color;`depth]; if viewtype () = "Top View" then begin GlMat.mode `projection; GlMat.load_identity (); GlMat.rotate ~angle:90.0 ~z:1.0 (); GlMat.ortho ~x:(-1.2,1.2) ~y:(-1.2,1.2) ~z:(0.0,2.0); GlMat.mode `modelview; GlMat.load_identity (); GluMat.look_at ~eye:(0.0, 0.0, 2.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0) end else begin GlMat.mode `projection; GlMat.load_identity (); GluMat.perspective ~fovy:40.0 ~aspect:1.0 ~z:(0.1,4.0); GlMat.mode `modelview; if viewtype () = "Center" then begin GlMat.load_identity (); let (x,y) = player#position in GluMat.look_at ~eye:(x, y, 0.2) ~center:(0.0, 0.0, 0.09) ~up:(-. x, -. y, 0.0) end else begin GlMat.load_identity (); let (x,y) = player#position in let (x',y') = ball#get_position in GluMat.look_at ~eye:(x, y, 0.2) ~center:(x', y', 0.09) ~up:(x' -. x, y' -. y, 0.0) end; end; GlDraw.shade_model `flat; (* Ground *) GlDraw.begins `quads; GlDraw.color (0.5, 0.5, 0.5); square (-5.0, 5.0) (5.0, -5.0); GlDraw.ends (); court#draw; let (x,y) = ball#get_position in if x < 0.0 then (net#draw; ball#draw_shadow; ball#draw) else (ball#draw_shadow; ball#draw; net#draw); poll#draw; Togl.swap_buffers togl; Gl.flush () end class view2d ~togl ~ball ~player = object val ball : ball = ball val player : player = player val court = new court ~togl:togl method draw = Togl.make_current togl; GlClear.clear [`color;`depth]; GlMat.mode `projection; GlMat.load_identity (); GlMat.rotate ~angle:90.0 ~z:1.0 (); GlMat.ortho ~x:(-1.5,1.5) ~y:(-1.5,1.5) ~z:(0.0,2.0); GlMat.mode `modelview; GlMat.load_identity (); let (x,y) = player#position in GluMat.look_at ~eye:(0.0, 0.0, 2.0) ~center:(0.0, 0.0, 0.0) ~up:(0.0, 1.0, 0.0); court#draw; ball#draw; let (x,y) = player#position in GlDraw.begins `quads; GlDraw.color (1.0, 0.0, 0.0); square (x -. 0.02, y +. 0.02) (x +. 0.02, y -. 0.02); GlDraw.ends (); ball#draw_target; Togl.swap_buffers togl; Gl.flush () end open Tk let main () = let top = openTk () in Wm.title_set top "Tennis Court"; let f0 = Frame.create top in let court3d = Togl.create f0 ~width:600 ~height:600 ~rgba:true ~double:true ~depth:true and f1 = Frame.create f0 in let court2d = Togl.create f1 ~width:200 ~height:200 ~rgba:true ~double:true ~depth:true and sx = Scale.create f1 ~label:"Velocity" ~min:0. ~max:200. ~orient:`Horizontal and sz = Scale.create f1 ~label:"Direction" ~min: (-. 90.) ~max:90. ~orient:`Horizontal and sht = Scale.create f1 ~label:"Height" ~min: 0. ~max:100. ~orient:`Horizontal and start = Button.create f1 ~text:"Start" in let viewseltv = Textvariable.create () in Textvariable.set viewseltv "Top View"; let viewself = Frame.create f1 in let viewsel = List.map ["Top View"; "Center"; "Ball"] ~f: begin fun t -> Radiobutton.create viewself ~text: t ~value: t ~variable: viewseltv end in pack viewsel; let viewtype = fun () -> Textvariable.get viewseltv in let ball = new ball () in let player = new player in let view3d = new view3d ~togl:court3d ~viewtype ~ball ~player and view2d = new view2d ~togl:court2d ~ball ~player in Scale.configure sx ~command:(ball#set_vel); Scale.configure sz ~command:(ball#set_velz); Button.configure start ~command: begin fun () -> Button.configure start ~text:(if ball#switch then "Stop" else "Start") end; Togl.timer_func ~ms:20 ~cb:(fun () -> if ball#do_tick 0.02 then (view3d#draw; view2d#draw)); Togl.display_func court3d ~cb:(fun () -> view3d#draw); Togl.display_func court2d ~cb:(fun () -> view2d#draw); bind court3d ~events:[`Modified([`Button1],`Motion)] ~fields:[`MouseX;`MouseY] ~action:(fun ev -> let width = Togl.width court3d and height =Togl.height court3d in let y = -. (float ev.ev_MouseX /. float width) +. 0.5 and x = float ev.ev_MouseY /. float height in player#move x y; view2d#draw; view3d#draw); bind court2d ~events:[`Modified([`Button1],`Motion)] ~fields:[`MouseX;`MouseY] ~action:(fun ev -> let width = Togl.width court2d and height =Togl.height court2d in let y = (float ev.ev_MouseX /. float width ) -. 0.5 and x = (float ev.ev_MouseY /. float height) -. 0.5 in let y = -. (y *. 3.0) and x = -. (x *. 3.0) in ball#set_position x y; view2d#draw; view3d#draw); bind court2d ~events:[`Modified([`Button2],`Motion)] ~fields:[`MouseX;`MouseY] ~action:(fun ev -> let width = Togl.width court2d and height =Togl.height court2d in let y = (float ev.ev_MouseX /. float width ) -. 0.5 and x = (float ev.ev_MouseY /. float height) -. 0.5 in let y = -. (y *. 3.0) and x = -. (x *. 3.0) in ball#set_target x y; print_float x; print_float y; print_string "\n"; view2d#draw; view3d#draw); let rec viewselfn () = begin Textvariable.handle viewseltv ~callback:viewselfn; view3d#draw end in viewselfn (); Scale.configure sht ~command:(fun z -> ball#set_z z; view3d#draw); pack [coe court2d; coe sx; coe sz; coe sht;coe start; coe viewself]; pack [coe court3d; coe f1] ~side:`Left; pack [f0] ~expand:true ~fill:`Both; mainLoop () let _ = main () lablgl-1.07/Togl/examples/tesselate.ml000066400000000000000000000013531437514534100177550ustar00rootroot00000000000000(* $Id: tesselate.ml,v 1.1 2004-07-13 07:55:18 garrigue Exp $ *) open Tk let top = openTk() let togl = Togl.create top ~width:500 ~height:500 ~rgba:true ~depth:true ~double:true let () = Wm.title_set top "LablGL"; pack ~fill:`Both [togl]; Togl.display_func togl ~cb: begin fun () -> GlClear.color (0.0, 0.0, 0.0); GlClear.clear [`color]; GlDraw.color (1.0, 1.0, 1.0); GlMat.mode `projection; GlMat.load_identity (); GlMat.ortho ~x:(-1.0,2.0) ~y:(-1.0,2.0) ~z:(-1.0,2.0); GluTess.tesselate [[0.,0.,0.;1.,0.,0.;1.,1.,0.;0.,1.,0.]; [0.2,0.2,0.;0.2,0.8,0.;0.8,0.8,0.;0.8,0.2,0.]]; Gl.flush (); Togl.swap_buffers togl end; mainLoop() lablgl-1.07/Togl/examples/texturesurf.ml000066400000000000000000000063621437514534100203710ustar00rootroot00000000000000(* $Id: texturesurf.ml,v 1.13 2001-05-08 01:58:26 garrigue Exp $ *) open StdLabels let texpts = [|[|0.0; 0.0; 0.0; 1.0|]; [|1.0; 0.0; 1.0; 1.0|]|] let ctrlpoints = [|[|-1.5; -1.5; 4.9; -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|]|] let image_width = 64 and image_height = 64 let pi = acos (-1.0) let display togl = GlClear.clear [`color;`depth]; GlDraw.color (1.0,1.0,1.0); GlMap.eval_mesh2 ~mode:`fill ~range1:(0,20) ~range2:(0,20); Gl.flush (); Togl.swap_buffers togl let make_image () = let image = GlPix.create `ubyte ~height:image_height ~width:image_width ~format:`rgb in let raw = GlPix.to_raw image and pos = GlPix.raw_pos image in for i = 0 to image_width - 1 do let ti = 2.0 *. pi *. float i /. float image_width in for j = 0 to image_height - 1 do let tj = 2.0 *. pi *. float j /. float image_height in Raw.sets raw ~pos:(pos ~x:j ~y:i) (Array.map ~f:(fun x -> truncate (127.0 *. (1.0 +. x))) [|sin ti; cos (2.0 *. ti); cos (ti +. tj)|]); done; done; image let myinit () = let ctrlpoints = Raw.of_matrix ~kind:`double ctrlpoints and texpts = Raw.of_matrix ~kind:`double texpts in GlMap.map2 ~target:`vertex_3 (0.0, 1.0) ~order:4 (0.0, 1.0) ~order:4 ctrlpoints; GlMap.map2 ~target:`texture_coord_2 (0.0,1.0) ~order:2 (0.0,1.0) ~order:2 texpts; Gl.enable `map2_texture_coord_2; Gl.enable `map2_vertex_3; GlMap.grid2 ~n1:20 ~range1:(0.0,1.0) ~n2:20 ~range2:(0.0,1.0); let image = make_image () in GlTex.env (`mode `decal); List.iter ~f:(GlTex.parameter ~target:`texture_2d) [ `wrap_s `repeat; `wrap_t `repeat; `mag_filter `nearest; `min_filter `nearest ]; GlTex.image2d image; List.iter ~f:Gl.enable [`texture_2d;`depth_test;`normalize]; GlDraw.shade_model `flat let my_reshape togl = let h = Togl.height togl and w = Togl.width togl in GlDraw.viewport ~x:0 ~y:0 ~w ~h; GlMat.mode `projection; GlMat.load_identity (); let r = float h /. float w in if w <= h then GlMat.ortho ~x:(-4.0, 4.0) ~y:(-4.0 *. r, 4.0 *. r) ~z:(-4.0, 4.0) else GlMat.ortho ~x:(-4.0 /. r, 4.0 /. r) ~y:(-4.0, 4.0) ~z:(-4.0, 4.0); GlMat.mode `modelview; GlMat.load_identity (); GlMat.rotate ~angle:85. ~x:1. ~y:1. ~z:1. () open Tk let main () = let top = openTk () in let togl = Togl.create top ~rgba:true ~depth:true ~width:300 ~height:300 ~double:true in Wm.title_set top "Texture Surf"; myinit (); Togl.reshape_func togl ~cb:(fun () -> my_reshape togl); Togl.display_func togl ~cb:(fun () -> display togl); bind top ~events:[`KeyPress] ~fields:[`KeySymString] ~action:(fun ev -> match ev.ev_KeySymString with "Up" -> GlMat.rotate ~angle:(-5.) ~z:1.0 (); display togl | "Down" -> GlMat.rotate ~angle:(5.) ~z:1.0 (); display togl | "Left" -> GlMat.rotate ~angle:(5.) ~x:1.0 (); display togl | "Right" -> GlMat.rotate ~angle:(-5.) ~x:1.0 (); display togl | "Escape" -> destroy top; exit 0 | _ -> ()); pack [togl] ~expand:true ~fill:`Both; mainLoop () let _ = main () lablgl-1.07/Togl/src/000077500000000000000000000000001437514534100144015ustar00rootroot00000000000000lablgl-1.07/Togl/src/.cvsignore000066400000000000000000000000561437514534100164020ustar00rootroot00000000000000lablgl lablgltop *_tags.c *_tags.h dll* *.lib lablgl-1.07/Togl/src/.depend000066400000000000000000000000501437514534100156340ustar00rootroot00000000000000togl.cmo: togl.cmi togl.cmx: togl.cmi lablgl-1.07/Togl/src/Makefile000066400000000000000000000051161437514534100160440ustar00rootroot00000000000000# Include shared parts TOPDIR = ../.. include $(TOPDIR)/Makefile.common # Composite options INCLUDES = -I$(SRCDIR) -I$(TOGLDIR) \ $(TKINCLUDES) -I. $(GLINCLUDES) $(XINCLUDES) LIBS = $(TKLIBS) $(GLLIBS) $(XLIBS) LIBDIRS = ifeq (TOGL_WS,TOGL_X11) COPTS += -DUSE_TCL_STUBS -DUSE_TK_STUBS endif OCAMLINC=-I $(LABLTKDIR) -I $(SRCDIR) # Files TOGLOBJS = ml_togl$(XO) $(TOGLDIR)/togl$(XO) # Extra rules .cmx.opt: $(TOPDIR)/src/lablgl.cmxa togl.cmxa $(OPTLINK) -o $@ $(OCAMLINC) -ccopt -L. \ unix.cmxa labltk.cmxa ../../lablgl.cmxa togl.cmxa $< all: lablgltop$(XE) lablgl$(XB) opt: togl.cmxa libtogl.a: togl.cma togl.cma: togl.cmo $(TOGLOBJS) $(CONFIG) $(LIBRARIAN) -o togl togl.cmo $(TOGLOBJS) $(GLLIBS) $(TKLIBS) $(XLIBS) togl.cmxa: togl.cmx $(TOGLOBJS) $(CONFIG) $(LIBRARIAN) -o togl togl.cmx $(TOGLOBJS) $(GLLIBS) $(TKLIBS) $(XLIBS) $(TOGLDIR)/togl$(XO): $(TOGLDIR)/togl.c $(TOPDIR)/Makefile.config cd $(TOGLDIR) && \ $(CAMLC) -verbose -c -ccopt "-D$(TOGL_WS) $(COPTS) $(INCLUDES)" togl.c lablgltop$(XE): ../../src/lablgl.cma togl.cma ocamlmktop $(CUSTOMTOP) -I . $(OCAMLINC) -o $@ \ labltk.cma lablgl.cma togl.cma lablgl: $(CONFIG) Makefile libtogl$(XA) $(MAKE) INSTALLDIR="$(INSTALLDIR)" real-$@ real-lablgl: @echo generate lablgl echo "#!/bin/sh" > lablgl echo "# toplevel with lablGL and Togl" >> lablgl if test -f dlltogl$(XS); then \ echo 'exec ocaml -I +labltk -I "$(INSTALLDIR)" lablgl.cma labltk.cma togl.cma $$*' >> lablgl; \ else echo 'exec "$(INSTALLDIR)/lablgltop" -I +labltk -I "$(INSTALLDIR)" $$*' >> lablgl; fi chmod 755 lablgl togl_tags.c: togl_tags.var $(VAR2SWITCH) TOGL_ < togl_tags.var > $@ preinstall: cp togl.mli togl.ml libtogl$(XA) "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) libtogl$(XA) @if test -f dlltogl$(XS); then $(MAKE) installdll; \ else $(MAKE) installtop; fi cp lablgl$(XB) "$(BINDIR)" install: @if test -f lablgltop$(XE); then $(MAKE) toglinstall; fi toglinstall: preinstall cp togl.cmi togl.cma $(INSTTOP) "$(INSTALLDIR)" @if test -f togl.cmxa; then $(MAKE) toglinstallopt; fi installdll: cp dlltogl$(XS) "$(DLLDIR)" installtop: cp lablgltop$(XE) "$(INSTALLDIR)" toglinstallopt: cp togl.cmxa togl$(XA) togl.cmx "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) togl$(XA) clean: rm -f *.cm* *.o *.obj *.so *.lib *.a *.dll *.exe *.opt *_tags.c \ *_tags.h *~ lablgltop$(EX) lablgl rm -f $(TOGLDIR)/Makefile $(TOGLDIR)/*.o $(TOGLDIR)/*.obj depend: ocamldep -pp camlp4o *.ml *.mli > .depend #dependencies ml_tk$(XO): $(TOPDIR)/src/ml_gl.h tk_tags.h tk_tags.c ml_togl$(XO) : $(TOPDIR)/src/ml_gl.h togl_tags.h togl_tags.c include .depend lablgl-1.07/Togl/src/Togl/000077500000000000000000000000001437514534100153065ustar00rootroot00000000000000lablgl-1.07/Togl/src/Togl/LICENSE000066400000000000000000000027051437514534100163170ustar00rootroot00000000000000This software is copyrighted by Brian Paul (brian@mesa3d.org) and Benjamin Bederson (bederson@cs.umd.edu). The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. lablgl-1.07/Togl/src/Togl/Togl.html000066400000000000000000001020101437514534100170730ustar00rootroot00000000000000 Togl

Togl — a Tk OpenGL widget

Copyright (C) 1996-2002 Brian Paul and Ben Bederson


Contents


Introduction

Togl is a Tk widget for OpenGL rendering. Togl was originally based on OGLTK, written by Benjamin Bederson at the University of New Mexico. Togl adds the new features:
  • color-index mode support including color allocation functions
  • support for requesting stencil, accumulation, alpha buffers, etc
  • multiple OpenGL drawing widgets
  • OpenGL extension testing from Tcl
  • simple, portable font support
  • overlay plane support

Togl allows one to create and manage a special Tk/OpenGL widget with Tcl and render into it with a C program. That is, a typical Togl program will have Tcl code for managing the user interface and a C program for computations and OpenGL rendering.

Togl is copyrighted by Brian Paul (brian_e_paul@yahoo.com) and Benjamin Bederson (bederson@cs.umd.edu). See the LICENSE file for details.

The Togl project and home page are hosted by SourceForge.

Prerequisites

You should have Tcl and Tk installed on your computer. Togl works with Tcl/Tk version 8.0 and up. The Mac OS X version requires version 8.4.

You must also have OpenGL or Mesa (a free alternative to OpenGL) installed on your computer.

One should be familiar with Tcl, Tk, OpenGL, and C programming to use Togl effectively.

Getting Togl

The current version of Togl is 1.7. Togl can be downloaded from SourceForge.

Mailing list

See the Togl project at SourceForge for mailing list information.

Using Togl With Your Application

There are basically two ways of using Togl with your application:

  • Link or "compile in" Togl with your executable or shared library. In this case you must call Togl_Init() from your C code to initialize Togl. This is the way the included Togl examples are built.
  • Install the Togl shared library and pkgIndex.tcl file (using make install) and then load it into wish using package require Togl. Then, before creating the Togl widget, call functions in your application code (also a compiled into a shared library and loaded into wish) to setup the Togl widget for the OpenGL rendering. Create the blank Togl widget, and then you're managing redraws and buffer swapping from the Tcl level.
Since Togl is compiled into a shared library using the Tcl/Tk stubs-interface, the same binary can be used with any version of Tck/Tk from 8.06 and up. See README.stubs for more info.

Unix/X11 usage

Unix/X systems only need the togl.c, togl.h and the public Tcl/Tk include files.

Windows 95/NT/2000/XP usage

Windows platforms need tkWinInt.h and other internal Tk header files. So you need a Tcl/Tk source distribution in addition to the Togl distribution (or copy over the various include files).

Here's the minimal way to build Togl with Tcl/Tk using the gcc that is distributed as part of the cygwin tools (Microsoft's compilers work too):

VER=8.4.12
SRCDIR=`pwd`

cd $SRCDIR/tcl$VER/win
env 'CC=gcc -mno-cygwin' ./configure --enable-threads
make libtclstub84.a

cd $SRCDIR/tk$VER/win
env 'CC=gcc -mno-cygwin' ./configure --enable-threads
make libtkstub84.a

cd $SRCDIR/Togl
env 'CC=gcc -mno-cygwin' ./configure --with-tcl=../tcl$VER/win --with-tk=../tk$VER/win

make
The resulting Togl17.dll and pkgIndex.tcl should be installed into your Tcl distribution just like any other package.

Mac OS X usage

These special instructions are for building the Aqua version of Togl. Mac OS X needs tkMacOSXInt.h and other internal Tk header files. Unfortunately, the Tcl and Tk frameworks that Apple distributes are missing the internal headers. So you need a Tcl/Tk source distribution in addition to the Togl distribution (or copy over the various include files). You would probably want a newer version of Tcl and Tk anyway because each minor revision of 8.4 has many Aqua bug fixes.

Here's one way to build Tcl, Tk, and Togl on Mac OS X (assuming they are all in the same directory) to install in your home directory:

VER=8.4.12

mkdir -p ~/bin
make -C tcl$VER/macosx install PREFIX="${HOME}" INSTALL_PATH="${HOME}/Library/Frameworks"
make -C tk$VER/macosx install PREFIX="${HOME}" INSTALL_PATH="${HOME}/Library/Frameworks"

(cd Togl; ./configure --prefix="${HOME}")
make -C Togl install

C Togl Functions

These are the Togl functions one may call from a C program.

#include "togl.h"

For portability, you should include the togl.h header before any other OpenGL header so that various Windows 95/NT/2000/XP stuff falls into place.

Setup and Initialization Functions

int Togl_Init(Tcl_Interp *interp)
Initializes the Togl module. This is typically called from the Tk_Main() function or via Tcl's package require command.
void Togl_CreateFunc(Togl_Callback *proc)
void Togl_DisplayFunc(Togl_Callback *proc)
void Togl_ReshapeFunc(Togl_Callback *proc)
void Togl_DestroyFunc(Togl_Callback *proc)
Register C functions to be called by Tcl/Tk when a widget is realized, must be redrawn, is resized, or is destroyed respectively.

Each C callback must be of the form:

	void callback(Togl *togl)
	{
	   ...your code...
	}
void Togl_TimerFunc(Togl_Callback *proc)
Register a C timer callback function which will be called every n milliseconds. The interval n is specified by the -time option to the Togl Tcl command.

The C callback must be of the form:

	void my_timer_callback(Togl *togl)
	{
	   ...your code...
	}
void Togl_ResetDefaultCallbacks(void)
Reset all default callback pointers to NULL.
void Togl_CreateCommand(char *cmd_name, Togl_CmdProc *cmd_proc)
Used to create a new Togl sub-command. The C function which implements the command must be of the form:

	int callback(Togl *togl, int argc, char *argv[])
	{
	   ...your code...
	   return TCL_OK or TCL_ERROR;
	}

Drawing-related Commands

void Togl_PostRedisplay(Togl *togl)
Signals that the widget should be redrawn. When Tk is next idle the user's C render callback will be invoked. This is typically called from within a Togl sub-command which was registered with Togl_CreateCommand().
void Togl_SwapBuffers(const Togl *togl)
Swaps the front and back color buffers for a double-buffered widget. glFlush() is executed if the window is single-buffered. This is typically called in the rendering function which was registered with Togl_DisplayFunc().
void Togl_MakeCurrent(const Togl *togl)
Sets the current rendering context to the given widget. This is done automatically before the Togl callback functions are called. So the call is only needed if you have multiple widgets with separate OpenGL contexts. If the argument is NULL, then the rendering context is cleared and subsequent OpenGL commands will fail.

Query Functions

char *Togl_Ident(const Togl *togl)
Returns a pointer to the identification string associated with a Togl widget or NULL if there's no identifier string.
int Togl_Width(const Togl *togl)
Returns the width of the given Togl widget. Typically called in the function registered with Togl_ReshapeFunc().
int Togl_Height(const Togl *togl)
Returns the height of the given Togl widget. Typically called in the function registered with Togl_ReshapeFunc().
Tcl_Interp *Togl_Interp(const Togl *togl)
Returns the Tcl interpreter associated with the given Togl widget.
Tk_Window Togl_TkWin(const Togl *togl)
Returns the Tk window associated with the given Togl widget.

Color Index Mode Functions

These functions are only used for color index mode.

unsigned long Togl_AllocColor(Togl *togl, float red, float green, float blue)
Allocate a color from a read-only colormap. Given a color specified by red, green, and blue return a colormap index (aka pixel value) whose entry most closely matches the red, green, blue color. Red, green, and blue are values in [0,1]. This function is only used in color index mode when the -privatecmap option is false.
void Togl_FreeColor(Togl *togl, unsigned long index)
Free a color in a read-only colormap. Index is a value which was returned by the Togl_AllocColor() function. This function is only used in color index mode when the -privatecmap option is false.
void Togl_SetColor(Togl *togl, int index, float red, float green, float blue)
Load the colormap entry specified by index with the given red, green and blue values. Red, green, and blue are values in [0,1]. This function is only used in color index mode when the -privatecmap option is true.

Font Functions

GLuint Togl_LoadBitmapFont(Togl *togl, const char *fontname)
Load the named font as a set of glBitmap display lists. fontname may be one of
  • TOGL_BITMAP_8_BY_13
  • TOGL_BITMAP_9_BY_15
  • TOGL_BITMAP_TIMES_ROMAN_10
  • TOGL_BITMAP_TIMES_ROMAN_24
  • TOGL_BITMAP_HELVETICA_10
  • TOGL_BITMAP_HELVETICA_12
  • TOGL_BITMAP_HELVETICA_18
  • or any X11 font name
Zero is returned if this function fails.
After Togl_LoadBitmapFont() has been called, returning fontbase, you can render a string s with:
glListBase(fontbase);
glCallLists(strlen(s), GL_BYTE, s);
To maximize the portability of your application it is best to use one of the predefined TOGL_BITMAP_* fonts.
void Togl_UnloadBitmapFont(Togl *togl, GLuint fontbase)
Destroys the bitmap display lists created by by Togl_LoadBitmapFont().

Client Data Functions

void Togl_SetClientData(Togl *togl, ClientData clientData)
clientData is a pointer to an arbitrary user data structure. Each Togl struct has such a pointer. This function sets the Togl widget's client data pointer.
ClientData Togl_GetClientData(const Togl *togl)
clientData is a pointer to an arbitrary user data structure. Each Togl struct has such a pointer. This function returns the Togl widget's client data pointer.
void Togl_ClientData(ClientData clientData)
clientData is a pointer to an arbitrary user data structure. Set default client data pointer for subsequent new Togl widgets. Default value is NULL.

Overlay Functions

These functions are modelled after GLUT's overlay sub-API.

void Togl_UseLayer(Togl *togl, int layer)
Select the layer into which subsequent OpenGL rendering will be directed. layer may be either TOGL_OVERLAY or TOGL_NORMAL.
void Togl_ShowOverlay(Togl *togl)
Display the overlay planes, if any.
void Togl_HideOverlay(Togl *togl)
Hide the overlay planes, if any.
void Togl_PostOverlayRedisplay(Togl *togl)
Signal that the overlay planes should be redraw. When Tk is next idle the user's C overlay display callback will be invoked. This is typically called from within a Togl sub-command which was registered with Togl_CreateCommand().
void Togl_OverlayDisplayFunc(Togl_Callback *proc)
Registers the C callback function which should be called to redraw the overlay planes. This is the function which will be called in response to Togl_PostOverlayRedisplay(). The callback must be of the form:

	void RedrawOverlay(Togl *togl)
	{
	   ...your code...
	}
int Togl_ExistsOverlay(Togl *togl)
Returns 1 if overlay planes exist, 0 otherwise.
int Togl_GetOverlayTransparentValue(const Togl *togl)
Returns the color index of the overlay's transparent pixel value.
int Togl_IsMappedOverlay(const Togl *togl)
Returns 1 if the overlay planes are currently displayed, 0 otherwise.
unsigned long Togl_AllocColorOverlay(const Togl *togl, float red, float green, float blue)
Allocate a color in the overlay planes. Red, green, and blue are values in [0,1]. Return the color index or -1 if the allocation fails.
void Togl_FreeColorOverlay(const Togl *togl, unsigned long index)
Free a color which was allocated with Togl_AllocColorOverlay().

X11-only Functions

These functions are only implemented on systems using the X Window System. We recommend that you avoid using these functions in your application since they are not portable to other operating/window systems (use Togl_TkWin() and normal Tk functions instead).

Display *Togl_Display(const Togl *togl)
Returns the X Display of a Togl widget.
Screen *Togl_Screen(const Togl *togl)
Returns the X Screen of a Togl widget.
int Togl_ScreenNumber(const Togl *togl)
Returns the X screen number of a Togl widget.
Colormap Togl_Colormap(const Togl *togl)
Returns the X Colormap used by a Togl widget.

Postscript Output

int Togl_DumpToEpsFile(const Togl *togl, const char *filename, int rgbFlag, void (*user_redraw)())
Generate an encapsulated Postscript file of the image in a Togl widget. filename is the name of the file to generate. If rgbFlag is non-zero then an RGB image file is written, else a grayscale image file is written. user_redraw is a pointer to the function which will render the desired image. This will typically be the same as the function passed to Togl_DisplayFunc().

Tcl Togl commands

These are the Togl commands one may call from a Tcl program.

togl pathName [options]
Creates a new togl widget with name pathName and an optional list of configuration options. Options include:

Option Default Comments
-width 400 Width of widget in pixels.
-height 400 Height of widget in pixels.
 
-ident "" A user identification string. This is used match widgets for the -sharecontext and the -sharelist options (see below). This is also useful in your callback functions to determine which Togl widget is the caller.
 
-rgba true If true, use RGB(A) mode, otherwise use Color Index mode.
-redsize 1 Minimum number of bits in red component.
-greensize 1 Minimum number of bits in green component.
-bluesize 1 Minimum number of bits in blue component.
-alpha 1 If true and -rgba is true, request an alpha channel.
-alphasize 1 Minimum number of bits in alpha component.
 
-double false If true, request a double-buffered window, otherwise request a single-buffered window.
 
-depth false If true, request a depth buffer.
-depthsize 1 Minimum number of bits in depth buffer.
 
-accum false If true, request an accumulation buffer.
-accumredsize 1 Minimum number of bits in accumulation buffer red component.
-accumgreensize 1 Minimum number of bits in accumulation buffer green component.
-accumbluesize 1 Minimum number of bits in accumulation buffer blue component.
-accumalphasize 1 Minimum number of bits in accumulation buffer alpha component.
 
-stencil false If true, request a stencil buffer.
-stencilsize 1 Minimum number of bits in stencil component.
 
-auxbuffers 0 Desired number of auxiliary buffers.
 
-privatecmap false Only applicable in color index mode. If false, use a shared read-only colormap. If true, use a private read/write colormap.
 
-overlay false If true, request overlay planes.
 
-stereo false If true, request a stereo-capable window.
-oldstereo false On SGI workstations only: if true, request divided-screen stereo.
 
-time 1 Specifies the interval, in milliseconds, for calling the C timer callback function which was registered with Togl_TimerFunc.
 
-sharelist "" Name of an existing Togl widget with which to share display lists.
-sharecontext "" Name of an existing Togl widget with which to share the OpenGL context. NOTE: most other attributes such as double buffering, RGBA vs CI, ancillary buffer specs, etc are then ignored.
 
-indirect false If present, request an indirect rendering context. A direct rendering context is normally requested. Only significant on Unix/X11.
 
-cursor "" Set the cursor in the widget window.
 
-pixelformat 0 Set the pixel format to the (platform-dependent) given value.

pathName configure
Returns all configuration records for the named togl widget.
pathName configure -option
Returns configuration information for the specifed option which may be one of:
-width
Returns the width configuration of the widget in the form:
-width width Width W w
where W is the default width in pixels and w is the current width in pixels
-height
Returns the height configuration of the widget in the form:
-height height Height H h
where H is the default height in pixels and h is the current height in pixels
-extensions
Returns a list of OpenGL extensions available. For example: GL_EXT_polygon_offset GL_EXT_vertex_array
pathName configure -option value
Reconfigure a Togl widget. option may be any one of the options listed in the togl command above.
pathName render
Causes the render callback function to be called for pathName.
pathName swapbuffers
Causes front/back buffers to be swapped if in double buffer mode. And flushs the OpenGL command buffer if in single buffer mode. (So this is appropriate to call after every frame is drawn.)
pathName makecurrent
Make the widget specified by pathName and its OpenGL context the current ones.

Demo Programs

There are six demo programs:

double.tcl — compares single vs double buffering with two Togl widgets
texture.tcl — lets you play with texture mapping options
index.tcl — demo of using color index mode
overlay.tcl — example of using overlay planes (requires overlay hardware)
stereo.tcl — stereo example
gears.tcl — spinning gears demo

To compile the demos, edit the Makefile to suit your system, then type make demos. The demos are compiled into shared libraries, that can are loaded into the Tcl interpreter as Tcl/Tk-extensions. Demos are started by running the corrsponding Tcl script. To run a demo just type ./double.tcl or ./texture.tcl etc.

Stereo Rendering

Quad-buffered stereo-in-a-window is supported. Quad-buffer stereo is only available on workstation-class graphics cards (3Dlabs Wildcat series, ATI FireGL series, NVidia Quadro series, and SGI workstations). Legacy support for divided-screen stereo on SGI workstations is available via the -oldstereo option. Developers for SGI workstations might also like the autostereo package to automatically switch the display in and out of stereo (other systems already do it automatically).

Full-screen stereo that gaming graphics cards support (ATI Radeon, NVidia GeForce) is not supported.

Common Questions and Problems

If you have something to add to this section please let us know.

Bad Match X errors on Sun systems

There's a bug in Sun's XmuLookupStandardColormap X library function. If you compile togl.c with the SOLARIS_BUG symbol defined (-DSOLARIS_BUG) this function call will be omitted.

Reporting Bugs

There is a bug database on the Togl Project Page. You may also discuss bugs on the mailing list.

When reporting bugs please provide as much information as possible. Also, it's very helpful to us if you can provide an example program which demonstrates the problem.

Version History

Version 1.0 — March, 1996

  • Initial version

Version 1.1 (never officially released)

  • Added Togl_LoadBitmapFont function
  • Fixed a few bugs

Version 1.2 — November, 1996

  • added swapbuffers and makecurrent Tcl commands
  • More bug fixes
  • Upgraded to suport Tcl 7.6 and Tk 4.2
  • Added stereo and overlay plane support
  • Added Togl_Get/SetClientData() functions
  • Added Togl_DestroyFunc()

Version 1.3 — May 2, 1997

  • fixed a bug in Togl_Configure()
  • fixed a compilation problem in using Tcl_PkgProvide() with Tcl < 7.4
  • new overlay functions: Togl_ExistsOverlay, Togl_GetOverlayTransparentValue, Togl_IsMappedOverlay, Togl_AllocColorOverlay, Togl_FreeColorOverlay
  • added X11 functions: Togl_Display, Togl_Screen, Togl_ScreenNumber, Togl_Colormap
  • added Togl_DumpToEpsFile function
  • fixed a C++ compilation problem
  • more robust overlay code
  • added timers (Togl_TimerFunc) from Peter Dern and Elmar Gerwalin

Version 1.4 — September 17, 1997

  • Ported to Windows NT (Robert Casto)
  • Updated for Tcl/Tk 8.0
  • Added many config flags (-redsize, -depthsize, etc) (Matthias Ott)
  • Added Togl_Set*Func() functions to reassign callback functions (Matthias Ott)
  • Added Togl_ResetDefaultCallbacks() and Togl_ClientData() functions (Greg Couch)

Version 1.5 — September 18, 1998

  • Fixed a few Unix and Windows compilation bugs
  • Added Ben Evan's SGI stereo functions
  • Multiple expose events now reduced to one redraw
  • Destroying Togl widgets caused problems, patched by Adrian J. Chung
  • Added Togl_TkWin() function
  • Updated for Tcl/Tk 8.0p2
  • Added gears demo from Philip Quaife
  • Added -sharelist and -sharecontext config flags
  • Fixed a few overlay update bugs
  • Added -indirect config flag

Version 1.6 — May 7, 2003

  • Added Togl_SetTimerFunc function
  • Updated for Tcl/Tk 8.0.5 and 8.1
  • Context sharing added for Windows
  • Macintosh support (by Paul Thiessen)
  • Tcl/Tk stubs support — see README.tcl (by Jonas Beskow)

Version 1.7 — Jan 2006

  • Added Mac OS X support
  • Enabled asking for quad-buffered stereo pixel formats on all platforms (use -oldstereo on SGIs for splitscreen stereo — C API changed too)
  • Configuring the cursor is no longer slow
  • Added -pixelformat config flag
  • Added setgrid support (unfortunately many window managers can't cope with 1x1 pixel grid)
  • Only free context when last reference is gone
  • Switched to TEA-based configure (instead of editting make files)

Version 2.0 — ??? 2006


Future plans

  • add callback command options for create/display/reshape/destroy
  • add vertical sync control
  • multisampling support (can be worked-around by passing in a pixelformat)
  • replace EPS support with TK photo image support
  • simplify C API by requiring callback command options
  • stubify C API
  • Use Tcl object interface for callbacks
  • allow (require?) private colormap to given with TK photo image

Contributors

Several people have contributed new features to Togl. Among them are:

  • Ramon Ramsan — overlay plane support
  • Miguel A. De Riera Pasenau — more overlay functions, X11 functions and EPS output
  • Peter Dern and Elmar Gerwalin — Togl_TimerFunc and related code
  • Robert Casto — Windows NT port
  • Geza Groma — Windows 95/NT patches
  • Ben Evans — SGI stereo support
  • Paul Thiessen — Macintosh support
  • Jonas Beskow — Tcl/Tk stubs support
  • Paul Kienzle — TEA debugging and patches
  • Greg Couch — version 1.7
Many others have contributed bug fixes. Thanks for your contributions!

Last edited on 25 October 2005 by Greg Couch. lablgl-1.07/Togl/src/Togl/ben.rgb000066400000000000000000001414471437514534100165610ustar00rootroot00000000000000no nameXj} 0!#;$&G')T*,U-/]02a35b68\9;V<>f?AwCDF GIJLMOPRSU VXY[\u]_Y`b>ce"fh i{jlPmo"pqsLtv wXxy{%|^}~%477*&2/.& o}Tf5Ob#Y7p五尖吮步拐疝柙耑泰胰乾設>'嗟楚羨道 綱銖締3暹縝閻檗翳鍥齋謹Sg{$ "6#%>&(K)+S,.U/1]24]57^8:W;=c>@lACEFH IKLNOQRTUWXZ[x\^b_aEbd&eghikbln1oqresuvvwyzQ{|} Famz|{zt>[sWLH ]+『兝;爪申牟妞肚咐 返客洹娣=基斛笮痠詖瑙董旗: 歐蔓餘%謁黔檬穡鎮_p !1"$;%'H(*U+-U.0Z13]46]79[:<^=?k@BDEGHJKMNPQSTVWYZ[]m^`Rac0dfghjnkmBnpq|rt5uvx6ytz{})~Zq/GMJqH﹉╱口且杏乳沸6籽們恐送婚+喫棻絰戢4跦嘖漕嘩!踡儘瞥5講(璿臏 |}}|{|w}~~{{y||}xyx{yzw}z}{z{vxsxwpvrmslljhia\ZVZTTOP^J\XS[N3H<B7?^@>XG=A=9>?7:8=;GBICHIIO?9C<9C=ABH@DDHBMF@DIAAKE@FC9?0,0(!~~{~}~}}z}}||u}xvxtzx{ursvpkehfcbcbY\XSWOXXVZTLTK3<9@7B\C;VG:CEAAFDIFJEPMPLHLKOJJKMFHLIKLMPSMQNNJEJFDPIBGE<C:-5,!~~}}{|{|}|z|~z|y{yuwurmqlifeg_]\]\UUTVMZSRXL:@5>6VXLQXC=A>BCPFMPIHGMLOGH[VLBOJOZOJROIRUHNNLG@>KDMHGK?>>616'&叉2!C!v2eC!2e2肐Ce!2e坢Te!!e嗈!e嗛eCeee2eeeTee坢TeTeeTe佫2e2e2!22Ce坢杈ee狁eT!e2C22!!v22C!22e肐2!22佫T2!!2嗈e!22C22狁2沚2狁T22T坢2Te22!2!2Ce2杈2e222T!2C22!!v22C!22肐2!22坢T2!!2嗈2!2嗛2Cee2ee2沚2e2eT22T坢2eeT2佫2!22C2e22坢杈2e222eT!222C瞠2!!2e!C22!!222!e2e諼ee!ee昊e2e2錚Ce2ee嫆CeeTee!eCe坢郼eee鈃!2委!!T2!ve坢e坢鈃ee4κ2!!22!C2!!22e2!22諼e1!2怩2親C2嫆eC22T22!2e2ee2C22郼2e坢2e2!22委!!T2!ve2坢2222e22!!22!C2!!2e2!2諼e!24昊2親C2嫆eC22T22!ee2eeCe2坢郼2e22!222!!T2!ve22e2坢狁2佫22鈃2ee2TC!2!2e2!!2!2!e22!ee2e!e狁2eee坢ee嫆eeCe坢e嫆e2eeeTv2!!!eeCeee坢狁ee2eT!2!22!!!!e22!22狁22!22e2坢2坢2嫆22C22狁2嫆222鈃2e2Tv2!!!2ee2C22坢e2坢22e2佫T!!e2!!!!e2!22坢e22!224e222e22e22嫆2e2C2e坢ee2ee嫆2鈃22Tv!!!2e2C2222ee坢22狁e2前!e!C!22T!!!!C蕞ee2e!ee!ev鈃e2ee嗛Ce坢委2ee嫆eCTe狁eeeee昊Te怩!委e!!!CveTeeeee!e!eee22!ee!!22T!!!!C蕞222!e22!2v呿2嗛C22嫆2Ce沚2坢2ee2昊T22!ee!!v2T2坢e2坢2!ee22!e2κ!e!!2T!!!!C蕞2422!嗛22!2v2C222e2嫆2C坢T2佣2e22e2e2e昊T224怩!e4e!!veT2e坢e2e2e2!e22!2e2e2e222!!!e!!!!CC佪e2!ee咀22Te坢Tee2e呿e2ee坢e嫆e錚Ce沚eTe狁e狁e2e2C!Teeeeee2ee坢22e2!!!2!!!!C22!22e邥C222坢T22e2鈃2嫆e2錚2C2T2T2ee2e22222!T22ee2e2e2!!!2!!!!C佪22!22咀222T2呿22e2e22e嫆e2錚鈃Ce2eT2T2eee22e2e222!T2e2e鈃22ee22e2!!ee2!2!22!!2!C佪T!e!!嗛e2eCe坢eeT2TeTe坢eTe坢eeee狁e2eCT2!e2!eeee坢Teee!!2e2!!22!!2!C燜!2!!e22C2坢222T2Tee2坢2沚22e坢222鈃22CT2!22!22eT2ee2坢!!ee2!!2!!2!C佪T!2!!e嗛224C2坢222T狁22Te2e222e2沚e22e坢狁22ee2▄22鈃22CT2!e2!2e22e2e22T2422e!2eC!!!!ee!e沚e22ee嗈e!e狁2e2T鈃2ee坢eTee喝eeevee錚鈃ee狁eee!e2e2eeCee狁e坢eee2!22C!!!!e2!2沚2嗈2!2e2T呿2坢e2T坢2e2嫆e2ev2錚222瞠22!22ee22C22e22e2!2eC!!!e2!2佫T2e嗈2!22T2坢e22eT2e2e嫆e2e22v2e阮2e22e222!22e2eCe2ee2ee鈃22ee2e!!2!v22!C!!怩2Ce2e佫Ce!eee嫆e杈eeTeTe坢C嫆eT坢eTe2Ceev!e2eeT坢ee!!!ve2!Ce!!怩e22杈2!22佫2嗛e22eC2沚2T坢e22eC2e嫆e2Te狁2eT2e2eC2ev!22T2e2怩!!!ve2!Ce!!怩e22佫C2!222嫆e242C2T2Te2坢eeCee嗛ee2Te2T22eC2ev!22e2e2e2T坢狁22e2涎!!eee!2!!!!ee22e!ee諼Tee!eeTee2e錚eC!e嗛eTe坢eTTeeeTee狁ve2e2!eeeee!!2e2!2!!e22e狁22!2諼T22!22沚222錚2C!2嗛2T2e222坢2eeT22T坢2ee2Te222v22e22!2狁2坢2e2佫!!2ee!!!e2e22!42諼T22!2e沚2錚2C!2嗛22eTee224e坢2e2TeeT2e22eTe222v2222!2e2e2e2e坢2e222e!2ve!22ve!2e!佫e!eeT坢eeCeeee委Cee坢e嫆Te坢eeee!TeeC2C2e佫e嫆Cee狁C!2v2!!!!!!2v2!22!狁2!2T佫e2C22e2ee22C22222嫆e2Te2e2e坢2e2!Te22Ce22ee2狁2嫆eC222C!2v2!!!!!!22v2!22!佫2!24T坢e2C222e2狑2C22坢242e嫆eeT2e坢e2ee22e222!Tee2C22e22e2e22ee嫆Ce222eCeee!C!CeT!2!22v嗛C2e2ee2e!e坢e2ev軥eeCee嗈ee坢狁昊Cee坢沚eee2!e!eeeeeee怩佫2!!eT!!2vC2222!2佫e222v呿C2C2佫2e嗈2e2e22e昊eC2T222e2!e2!22狁2e22昊2!!T!!v嗛C2422呿2!2e2v軥24Ce22ee嗈22坢2eㄘC22e坢沚2e2224e2!2!22e222e2e2e2委2!2!!e!!!C!C!!T瞠e2e!呿2ee2e坢Cee坢e錚e嫆e昊eeT昊eee2ee杈eeTeeeCe2!!!2e!!C!!!T佪2!e2eC2坢e2e2錚2e嫆e2昊22e2e22T2昊2e2e2e2鈃2T2e狁2e杈222!!!2!!C!!!T2!嗛2坢C2ee2憲e22e錚22e2e嫆e22e昊鈃e2e2eTe昊鈃e2e狁e224ee22eT2eee2eeCe2e22!e!e2!!2C呿e2e2e嗛Ce2ee昊e2e嫆eCee昊e坢沚ee嫆eCTeTeee2T!佫e佫eeTee22!2!22!!C呿2C222怩2嫆e2C22怩2沚2嫆e2eeC22e坢2T22eeT22e222e沚!22e2eT222!2!22!!C2嗛C2昊2嫆2C22昊2e2坢沚e22e嫆2eeC2ee鈃T2eeeT22222eT!22e2佫2狁2T22e苟!C!C2e委!v2!!e2!e錚Tee2eT狁Ce!e狁C2ee坢ee昊e嫆e狁e嫆eTTeeTve錚2e2坢鈃ee坢e2!!22委!v2!22!2親T222T佫2C2!2e2C22e2e2昊狁2嫆2坢2e2e嫆狁2e坢2T2T2e2eev2親2222坢坢呈!!2e委!v2!22!2錚T2422T2C2!22C2坢2e2昊e2前嫆22e2e2e2嫆e2e2eeTeT狁22e2v2e親222e2坢e2eev2!!2!e!!2!2C2坢e22e2e鈃e2e2e嗛eCeCT郼eTeeee坢C坢T坢ee!坢!ee呿e坢瞠e坢Teev2!!22e!e!!!22e22e呿22CCT呿T22eeT2狁2狁22Ceee2T2坢2鈃2!!e2呿2122坢T22佫v2!!22!e!!!22坢e2e2呿2呿2C4CT郼2eeTe22坢狁22eeCeTe坢瞠22e2!!42e鈃2坢瞠e22T22ee!!T22v!2e2!eee2ee嫆ve2ee佫Ce2eee眉ee嫆沚e坢TeTC嫆e坢Teee親e!eTeee坢eeTeTee!!22ve!2ee2!22222嗛v222e佫C222e22嫆e22e嫆T22eeT22T坢eCe2嫆e2ee2T222e2親22!2T22呿e22T坢2Teee!!22v!2e!22e2嫆v2e杈2242嫆e22e嫆T2e2坢eTe2TeC2e嫆e屎鈃Te2佫2e2ee錚e2!2T24e呿e42坢2e2T22eT2e倒委!!e2e2e2!!2!!委2e2e坢e2e2T鈃eCeCe坢eTCT嫆T坢e諼e佫Tee2嫆!e坢Cee!e邥2!!22ee2!!!!2坢e2T呿22C2Ce呿222T坢22C2ee2T22嫆2T狁2ee2諼2T22e2嫆e!2eC22!2e邥2!!2ee2!!!!2e2T鈃2C2C2e2坢2eT坢鈃eCe2T2e嫆eTe2ee2e諼e22e2佫T2242嫆e!2Ce2e2!2呿2e!e2e2!2eT!!22e呿2e2ee嫆ee坢狁T昊T沚T坢狁e昊eeee坢ee坢eee2!鈃22!2!2eT!!2佪2鈃2嗛e222e呿22T2昊eeT2T2T2坢e2e呿e2e2怩e2ee22坢2e2e2!呿e22!22e!2T!!222呿2牠嫆e2422e鈃2e2e坢2Te昊eeT2TeTe坢ee22e昊e2e22e2委2224坢ee2ee22e!瞠2!C2e!ee!2鈃2e2e昊e2e坢CeCeTe鈃e嫆eC坢錚eeeee佫ee坢瞠e坢Tee!2佪22!22!2e!2222昊2佫eC2CT坢e2e2ee2嫆2Cee2ee錚e2e坢2e2e22222T22e2!222!22!2e!2e2昊2坢eC2C4Te22ee嫆狁2eC坢e錚e附鈃22e狁e2ee2e22佫24坢22坢eT222e22!圯嗈e2e!2!C!2!Te!eTTee2e瞠C2ee呿e嫆e鈃eeT坢C坢坢eee嫆ee坢狁eee坢eeeC2Ce2嗈e2!2!!!T2!2T沚222e佪2C222嫆e2e鈃2e2坢狁2Te鈃2Ceee2e2e坢鈃2坢e22e2嫆2222e鈃2ee2CeCe2嗈e24!2!!!T2!2TT22C2呿2e嫆ee2鈃2ee狁eTe坢鈃eCee坢e倒鈃e2eee22e2ee嫆2222鈃2ee2e22C2C2222!e2!2C!2!!eTeCe坢狁Ce嫆ee錚Te坢T佫T嫆狁eeTee狁e坢eTeee22!2!C!!!2坢T2Ce22C2嫆e2狁2錚2T22狁2T2e2ee坢eT2e嫆2e2坢T2e22e22Tee2坢2!22!2C!!!eT2C2委坢2C22e嫆22e2ee2ee錚鈃T2e坢eeT2e鈃e坢eTee嫆22e2e2eeT222e狁2e2ee2T222eee嗈e!2Cee2!ee嫆CeeC嗈TeCeee坢eeeT坢坢T嫆佫坢狁T坢eeCeeeee狁T坢e22嗈2!2e2222!22嫆eC22C2嗈T2C22e22e22Teee2eeT22e嫆e狁2eee22Te2e2C22e2222Tee2e2佫22嗈2!2e222!22嫆Ce2C嗈T2C222e2坢2ee2TeeTe嫆鈃ee竹2eT鈃222C2eee2e狁222eTe坢e2e!e!T2e2!!CC!2e坢evee昊沚e委eee坢e坢eeee昊eeee坢T!2!2e2!!C!222v呿2e2昊T2坢2ee2e2eee22ee2e坢e2e2e22ee22ee2昊2佫e22委2T2e2!2呿!222!!C!22坢2v鈃2鈃2昊沚22e22e2ee2ee坢eee2ee坢e2eeee2ee2e2昊鈃22狁22委2ee坢Tee2eeeee嗛!!2怩T2C2!2!C2e昊e嫆eTe坢e嫆狁eTe昊坢狁坢T狁ee坢ee呿eeTeT2e!!2T22!2!22昊2e嫆e2e沚22嫆22Teee2e坢2e2e昊e2e2Te22e2e22鈃22ee22T坢22T2e邥24e!!2怩T22!2!22昊2e2嫆e2e22eT2e2e2嫆e2Teeee2e昊e坢e瞠Tee22ee2ee坢狁22呿ee2ee2eT坢eeTe2e2邥!eCe嗛e!e!eCe嗈eT嫆ee坢狁ee坢坢〩eeeeTe委eC22!2e2!!Ce2嗈e2T嫆e2e22牠坢2e2e坢22e2e2e2ee22ee鈃2e2222e坢2T2e2e2222e坢22eC2邥!22!4!4C2e2ee嗈2e2eT嫆ee2鈃2e坢22ee坢eee坢2e杠鈃2ee坢狁22e2e坢eT2鈃e2e22e狁2eCee!ev2!eC佫T2!!C2CCe郼e坢e嫆eTe昊鈃e坢T坢e坢TC坢CeeT狁T2!2v2!2CT2!!2C2e郼2坢2嫆e2沚2怩22e2坢ee2T坢鈃e2ee坢e丙2T2e坢狁22Ce2Ce2e坢ee22e沚e2222T222!2v2!2C佫T2!!2C2郼22ee嫆22e2eT2e22昊鈃2ee坢eT坢ee2TeeeCeeC狁2ee2eeTe2eeeTeee2!eC22C2邥22!!2!2eeCe錚e嫆ee坢T坢坢錚狁e錚狁TT狁eeT2!2Ce22邥2!!2!22e2C2親2嫆2e坢e22T22e2e2e22錚e2e2錚e2e2e2ee2e狁T22e狁2Te22e狁22T2!2C222邥2!!2!22e鈃C2e2錚2e22e嫆2e22ee2e鈃Teee坢e2e錚e22e錚ee2e2eTeeeTe2ee2eTe2e2ee2e!22佫e2!ee坢郼ee坢e嫆委eeeeTT坢坢ee坢坢郼ee坢ee2!222!22坢e2郼2坢2嫆2〔e2Tee坢e2Te2e2eee2e2坢2ee2e2佫e2e22e郼2e2e222e22e22e2!22坢e22!42ee22e2佫郼2▄坢狁22ee嫆委2e2e2TeeeeTe坢e坢鈃2eeee坢ee郼2e2e22e2e2Ce2CC2e!Cee佫T!C2eCee嫆e嫆Te坢郼ee坢沚eeeTT坢坢ee嫆坢佫TT坢狁e坢TC2C22!22T!2C22嫆e2嫆2T2郼2坢T2e坢e2Te2e2e2T2e2ee2e2嫆ee22e2ee呿2T2T2e22e2T2e遨42C22!2e坢T!4C2e嫆ee22e嫆eT2e2郼2e2e坢T22eeee2eTeeeTee坢e22e嫆e坢ee鈃TeT坢2e2e狁Teeee2C2e!e!e靬e!22!ee錚eCe坢e坢eCeeT嫆坢坢e坢嗛委T坢鈃ee坢T12C2!2!2e靬2!22!22親2Cee2鈃22Cee22Te坢ee2e嫆狁e2ee22ee2e2ee2222T222e2沚2e22慢22!2!2呿2!22!2e錚2e2Ce2e2e鈃e2e2坢2eeCe2eTee嫆eee2e坢ee瞠委2T2坢2ee2坢T2ee2e2ee2!!e2e佪v22CeCe坢eeeeT昊eeC委e嫆坢T坢e坢坢e2eeT坢ee坢TT222!!2築22C22eee2ee22T2昊2C2坢2嫆狁e2e狁22Te坢狁e2eee22e2e坢e2e22T2ee22T2T2242!!2佪v222C2坢22e呵22e2e2eT2昊鈃22C2委2ee嫆狁ee坢eTee狁2eeee2eeT坢2e2坢2TeTe!e!eCe!e2e2v邥e2!e沚eT嫆CCCe坢Te錚狁e坢坢錚狁!e昊e狁坢eve!2!eC2!222v22!2T2T2e嫆2C2Cee2C22沚2錚22ee坢e2e2e錚鈃22ee坢狁22e坢e坢2e2e2!2e22怩22ee22e佫ve!2!eC2!2v邥22!2沚2T2e嫆eC2Ce2C2eT2e親2e坢ee錚e狁e2ee坢e2!2e2e昊e2e2坢e2eeeve狁2e!e!e2ee2eeeT澧C狁CeT坢沚e坢佫坢T嫆佫坢佫坢eC呿e坢TveC2422e22!2!222e2T坢澧2C2e坢2Ce2ee2TT22eee2ee2eee2e坢鈃2T2嫆e22eee狁2ee2Ce222eTveC2e224e22!2!22枸22e22T澧eCeeeCeeee22T坢沚2ee坢ee坢e鈃eTe嫆狁ee坢e坢e2坢eeC2坢瞠2eTvCeTe!v22!ee2!e佪T2e听TTe坢TT沚eTeT坢坢坢坢呿eT昊坢坢沚e22ee沚2!ev2!22!2燜2v坢TT2坢2T22T坢T2eeT22T2e狁e2e坢ee22eee2ee22eee2eee2e2e鈃委2昊ee22eTe22eT2!ev22!242!e佪T2治TTee2坢鈃T2eTT2e2T2ee2Teeeee坢ee坢ee昊e坢沚e2ee2e22e2eeeT坢TT嫆C嫆ee坢ee坢坢坢佫坢e坢佫e2e22e2e狁2e2T鈃T2T2嫆22Cee嫆22e2e2e2e2e坢狁2eee2e2坢e2ee2e2222ee22e22e22e22e2eee22eT坢鈃TeT2嫆瞠eCee嫆2e22e坢eeeeeee2e2eee222瞬鈃!杈e委2e2eC邥eCeTTT坢TTT嫆沚ee呿佫坢坢親坢呿諼eee佫eT坢佪Te殺2!eC2222C2C22T坢2T2T狁2T2T坢狁2T2e嫆T2ee22ee嫆e狁e2ee坢鈃e2ee2e2e坢e2ee嫆2e諼2e2T2錚e2eeTe殺2!杈e22424C邥2C22TeT2TeeT2T坢狁2Tee嫆沚ee2ee嫆e坢eee坢e嫆e諼2e2e2eTe佪eT2坢2vveCe2ev狁eT嫆沚TT昊eT嫆eeC坢佫坢坢佫e坢傺e佫e2v2v狁2C2v2T2嫆T2eeT2T2昊狁T2嫆e2e2e坢e2Cee坢e2e2e2e坢ee2ee坢狁e2ee鈃2ee坢ee2eee2佫ee22傺狁e22eee2v2v2C2赳2eeTe嫆Te2eeTeTe昊eTe2e嫆狁e2eeeeCeeeee坢ee狁eee坢ee坢e坢傺e2匐2v沚e鈃e2e2e委CeT坢TTe坢T坢e嫆T嫆佫坢坢狁嗛坢嗛e2v沚2呿2222C22T2T2Te2e2Te2坢狁22ee嫆eT2ee坢e嫆e2e2坢e2坢eee2ee2ee呿e2ee2eee坢2vTe2委C2eT坢鈃TeTee2e2eeTee坢e2e嫆Te坢ee嫆e坢eee坢ee2ee鈃ee嗛e2e嗈eee呿eC2e2ve坢e狁CeT錚e嫆T坢佫坢呿坢坢佫錚嫆Te2嗈2ee2呿2C2ve2鈃2e2e坢2Ce2ee2e2T錚鈃2e2e嫆2Teeee2e坢狁e2eeee2e嫆e2e坢2e2e坢e呿e2錚T2e2eee嗈2ee2呿2C2ve2e2e坢鈃e2eeeC2eeT錚e嫆2Te坢ee坢e嫆eee坢eeee錚嗛Te2C坢TT2郼e2eTeT嫆Ce坢坢沚嫆坢佫佫坢嗛佫呿嗛evC沚T2e呿T2搪e2T2eeee2T2嫆e22Ceee2e2ee2e2T22ee狁e2e嫆ee2e坢狁2eee嫆2ee嫆2e2eevCTT2郼2eeTe2eTe嫆狁2eCe22e2坢ee2ee坢沚ee嫆ee狁eee坢e鈃坢嫆坢ee嫆嗛e2v2送eT嗛2e坢委C2ee委eeT嫆C燜eTC坢親嗛呿eve2e鈃T22邥2C2e2庸e2T2e嫆狁2Ce2燜22eeee22T2e2ee坢鈃e2Ce2e坢鈃2ee鈃2ee坢鈃ee鈃e2e坢呿狁22eev2鈃T嗛22坢2C22e委2eeeeTee嫆狁eCee燜e2eeeT坢ee鈃eC坢e鈃ee瞠ee坢eee呿ev22eeTe嫆2e呿e2TT嫆TT嫆T昊e佫坢佫坢佫佫坢e2T2嗛22e呿2委2T2Te嗛e2eT坢2T22e嫆e2e2e2Te2昊2e坢狁e2eee2ee坢e2e坢eee2e坢e坢坢2e2e2eee2T2嫆2鈃2eeT2Te嫆ee2T坢鈃Te2e嫆eeTee昊eeeee坢eee狁ee坢e坢ee佫e2庸e委嗈2eC昊瞠2ee沚T嫆T坢T嫆Te坢坢親坢佫佫坢嫆嗈佪ee22e2嗈2C怩2T2T2e嫆2T22e2Te2嫆2T2eeee2ee狁22ee坢e2e瞠e2eee2ee坢ee2ee2e2e嫆嗈e2eee瞠2e2e222嗈24C昊2e沚eTee嫆eTeeeeTee嫆鈃Teee坢eee坢eeeee2ee嫆嗈e佪e222Cee!坢ee2eT嫆T坢錚e嫆T佫佫坢坢坢坢坢嗛嗛坢佫TTeeeC22!2呿e2匐2T2ee嫆瞠2eTe2e22錚狁2e22嫆22e2eeeTeee坢eee坢2e2eee坢e坢ee2TeTeeC2e!坢2e22e狁Te嫆eTe錚e2e2e嫆eeTee坢eee坢e坢eee坢嗛eee瞠TeT22e2披eCee昊狁eTTT嫆TT坢e坢嗛坢佫坢eee22披2C22怩22T鈃T2T2嫆eT22eee2Tee2e2e坢鈃e2ee坢22eee﹌鈃e2ee狁e2eeee2e坢e22e坢ee坢ee坢鈃e2ee22披2C2e昊狁2T鈃TeTe嫆狁Tee2eT2坢e2ee坢eee狁ee坢ee坢坢狁坢e222eee!eee諼狁eC坢坢C坢嗛呿錚嗛嗈佫Teev22!e2e2諼22鈃2C2e狁2ee2e2ee22Cee2e坢2e鈃ee嫆e2坢eee2e2錚鈃eee嗈e狁2e2e2Tev22!e2e2e諼2eeCee坢eeeCe坢e坢eee嫆ee狁ee坢e錚坢嗈e2T22vee2eTeCeCeee坢狁坢坢坢坢坢坢eeee2T2C2C2e鈃2狁e2e2鈃e22e坢瞠2e2e2eee2ee坢鈃2eee羋ee2ee坢鈃e2ee2eeee狁嗛ee2e2eee2T2C2C2鈃22e鈃e2eeeeeeee坢eee坢ee鈃ee坢e坢e狁坢ee2ee2eee!e2e邥e錚狁嗛ee坢T嫆e坢坢T佫坢親坢呿eeee22!22錚22e2ee2Tee嫆e2ee2e2ee2e坢狁2Tee坢e瞠e2ee坢ee2eeee2e嫆e坢ee22e2ee22!2邥22e2e錚2ee2eeeTee嫆eeeee坢eeTeee坢ee坢ee嫆狁2e2e2e2ee!e!ee郼嗛坢佫佫呿佫親坢坢嗛呿eee22!2!2e2呿Te22eeee2e2坢鈃e2ee坢e2ee2eeee2ee坢e嫆eeee2e鈃2e2坢eee嫆eee2e2ee22!2!2鈃2e郼嗛e2e坢eee卞e2坢e嫆鈃e瞠ee坢ee嫆ee2ee2Te!e2eve昊e坢C錚嗛嫆親佫佫佫嗛坢親eCeveT2!22v2怩2佫eCe2ee2e錚鈃e2ee嫆狁2e2e瞠2eee2eee坢eee坢狁e2e坢eee坢鈃22e22C2veT2!224v2e2ee昊e坢eCeee錚e嫆e瞠ee坢e坢eeeeeeeee坢坢狁ee2eC22veee!eTee坢evvC呿T坢嫆坢邥嗛嗛佫佫坢嗛佫坢eevvee2!2T22佫2vvC呿e2e2ee2Tee2e嫆狁2e坢ee怩鈃eee2坢e狁e2e坢e2鈃eeee2e2e22evve2!2T22狁2e22vvC呿eeeTe坢e嫆e狁eee昊ee坢eeeeee坢坢e坢e2eevv2e狁eCTeeeCe坢坢坢嗛佫嫆坢佫呿佫坢嗛嫆坢eeee22T22e2C2﹌ee2eee2e2ee2eeee2ee佫e狁e2ee嫆ee嫆e坢ee2ee2eee鈃e2嫆2ee22eee22T2e2C22e22坢eee坢e坢eee嫆e坢ee嫆ee坢eeeee嫆鈃e狁2T22Teeeee坢T坢坢佫佫坢坢佫佫佫佫佫坢CeeT22T22e2e22坢eeTe2eee2ee2e坢e2e2e坢鈃e2eeeeeeee2e坢e2ee坢eee坢e2坢C2eeT22T22狁22ee22eT2eee坢eee坢e狁ee坢狁e坢e坢狁eeee坢C2e22eTC錚嫆坢坢坢〩佫親坢佫坢親佫佫坢eee2e2T坢C2錚ee嫆2e2e坢狁2ee2e2e2eee坢ee2eeeeee2eee坢e坢e坢2eeee2e2TCe錚e嫆e坢ee坢e坢e坢eee坢eeee瞠ee坢e瞠ee坢狁坢eee2e委!eTe坢坢坢坢坢坢佫佫坢坢嗛坢坢佫佫錚鈃vev1!2T22e2佫狁2ee坢e坢2ee2e2eeee2e坢e狁2eee坢e錚e2evev!2T2e坢狁2e坢eeeeee坢e容坢eeeeeee坢ee錚e鈃2v22ve2e!TeeC坢嫆坢嫆佫坢坢呿佫佫佫e哪22!T22e坢Ce呿狁e2eee2e2嫆狁e22ee2eee22e2e坢狁e2e2ee嫆e2e坢狁e2e坢e2eee2e22!T22eCe坢嫆e坢e嫆eee坢eeee坢e嫆eeee坢eeee2e2狁!2Te嫆eT嫆坢坢坢親坢呿嗛佫嫆嫆佫坢Cee2!2T2嫆22T坢嫆鈃e2ee2e坢狁e2ee坢eeee2ee嫆eee2ee嫆e22e嫆eee2Ce佫2!2T2e2嫆22T呿ee坢ee鈃ee瞠eee嫆ee狁e坢ee嫆e2嫆ee佫ee坢eCe22e狁2eCeTe嗛昊坢坢坢佫坢佫佫佫嫆佫佫沚ve222C22T22昊e2ee2e2ee坢ee瞠e2ee狁e2e坢eee22坢ee嫆eeeTevee24C22eeTee嗛昊ee坢eeeeee狁ee坢e坢e坢e瞠e嫆T2v22ee!!e狁e佫坢坢嗛坢佫佫坢佫嗛親坢嫆ee2瞠!!2e22ee2eee2ee坢e坢鈃e2ee坢e2eee2坢ee22ee2ee坢ee嫆2eee瞠!!2eeee2ee坢e坢eeeeeeee坢eeeeee狁e坢e嫆2e22e22e!eee坢嫆坢坢呿佫坢佫坢親佫嗛佫呿佫ve2e2!22e瞠22e嫆e2ee2eeee嫆e2e2e2eeee2e坢e狁22eeeee嫆vee222!22e瞠2ee嫆eeeee坢eee嫆eee坢ee坢eeeee2坢eeee狁嫆狁v2evee2!ee坢坢e坢佫佫佫佫坢佫坢ee2v狁2!22狁e佫eee坢狁2e2eee坢ee22eeee坢e2eee坢eeee2v242!22坢ee佫eeee坢ee坢eee坢e狁e坢eeeeee2TT2e2e坢坢ee佫佫佫佫佫eTTe2佪2eee22e坢eee2eee2ee2ee2e2e坢e2ee22e坢ee坢eee鈃eeTTe2e瞠ee坢e狁eee坢e狁e2eee坢ee坢ee坢e2eee坢eeee鈃2e狁e2eeT沚坢坢佫親坢嫆佫坢佫嗛坢ev22T2Te坢2ee2鈃e2eeeee2e2eee嫆e狁e2eee22e坢ee坢eee鈃ve2222TeTee坢eee坢ee嫆坢狁ee鈃e坢eee坢e22v2鈃2eeTeT坢佫坢嗛坢嗛坢佫佫佫佫e 鈃e2T2eeTe坢ee2eee2ee坢e狁e2e委e2e坢e2e坢ee呿ee2ee坢e鈃22eeee 22T2e2Tee坢ee狁eeee坢eeeeeeeeee2e佫ee坢瞠2e eee2eeTee嫆坢坢坢e佫親佫佫坢佫佫嫆坢e e2T2eee2e嫆e2e2e坢e2ee2e22ee22e2ee2ee坢ee2ee嫆ee 狁22eTe2e2e嫆eeee坢eeeee坢eeeeee嫆ee坢ee狁2怩 鈃2eee嗈e坢佫佫嫆佫錚佫佫e坢佫佫親 2e222嗈22e坢ee坢e嫆e22ee2ee22ee2ee2ee坢ee2e坢e坢eee瞠e 2e22ee22ee嗈e坢ee坢ee嫆eee2e佫ee坢e坢e狁ee瞠e2 e瞠CvTe錚坢嗛e嗛呿ee坢佫嗛佫佫佫 e2C肐T2e22ee錚狁e2eee坢e坢ee2ee2e佫e2鈃222eeee22坢eee坢e ee2CvTe2e狁2e錚eeee坢eee鈃eee2嗛e佫2e呿e2eeee坢ee坢ee 沚Tee沚坢親坢嗛坢eCe嗈杈坢狁ee坢坢嗛坢佫佫沚沚22eT2ee2e2eee2eee2e2C2e2e佫嗈侒eCe22e2ee2坢狁2e鈃e2eeee狁e坢T沚2e2eTee坢ee坢eeeeeCe佫嗈eCe2e2e坢eeee坢e坢e怩C嫆沚昊狁坢坢坢e佫Cee佫嗛坢坢親eC嗛T2昊22eeee2ee坢e2e2e2e2e坢佫e2ee2Cee2eee2ee坢eee坢瞠狁委C嫆T2昊2ee坢e鈃ee坢eeeeeee2ee2eeCe2e2ee坢eeeeee坢瞠2狁瞠錚沚坢呿嗛佫呿嫆e坢坢佫ee沚e嫆佫佫佫嗈狁22錚eTeee嫆ee嗛e嫆e2e22侒e2T2e嫆狁2eeee坢e嗈e2e錚T2ee嫆鈃eee嫆e嫆ee狁2 e22ee沚2e嫆狁e坢eeee狁e嗈eeeC坢呿坢呿嗛坢v佫e坢坢佫佫ee嫆佫坢e委C坢嫆2e2e嫆eee2e坢e瞠2v2e佫e2ee2嫆狁2eeee坢ee邥e22C坢嫆ee嫆鈃eee坢e瞠ev佫22佫eee2ee22ee嫆e坢e狁eee邥2e肐e〩坢嗛坢坢呿靬e坢坢坢佫佫佫呿v2e2eeee2e坢ee坢e嫆e22靬2e侒e佪ee22e狁e22ee鈃e2e嫆v2e2eee坢eee坢eee嫆狁e2靬2eeeeee2eeee坢嫆2ee委e沚佫佫坢TC佫坢佪佫嗛e錚佫嗛e22eTeeee2eee坢2TCe2親鈃2錚22ee坢e佫e222eTeee坢eee坢ee瞠TCeeee錚2錚e坢ee坢e鈃2ee嫆坢坢親諼坢ee佫坢錚嗛坢坢坢22e嫆2eee坢e諼e坢2e2ee錚鈃坢ee坢ee2ee坢ee2ee嫆ee坢eee諼eeeeeee錚坢e坢eee鈃e委e親坢坢親佪呿T佫坢佫佫坢呿e委22eeee2eee錚e嗛e22Te狁eeee2eeee坢呿222eeeee錚e嫆ee2Teeeee坢狁ee坢e狁eee坢坢佫坢e佫坢鈃e22eee2eee2ee佪e22e坢e222e坢ee坢鈃e22eeeee坢eee瞠e2e坢eeeeeeeee狁eee坢ee狁v嗛坢沚e佫 親e坢狁e2ve坢ee坢ee2eT2坢e瞠22e2ee坢e佫e坢佫e22ve坢eeee沚22eeeeeeee瞠2eee坢e狁坢ee嫆坢佫e佫 坢佫ev佫靬ee嫆ee坢eee22e坢ee22ve22eee靬eeee嫆eeee坢eeee狁2eeeeee eeee2e2ve佫eee靬 嗛佫佫坢C坢嗛坢e坢嗛 坢ee坢e坢eeeeCe鈃e22ee2e2ee狁2e嗛鈃e坢eee坢ee狁eCeeee eee2e2e2e坢ee T錚呵親佫嫆嫆親坢親坢親坢坢坢佫ee呿呿佫 狁T坢e錚e瞠e嫆e嫆e瞠e2e瞠e2e222ee鈃22嫆佫 狁Te錚e涓瞠e嫆eee嫆瞠ee2瞠eeeeeeeeee2e2eee嫆 狁嫆昊坢坢坢親e坢 佫eee佫嗛! e嫆e昊e坢eeee2瞠22ee2e22e2e嗛! 2嫆瞠2ee昊e狁eee2eeeeeeeee22e22ee2e 坢佫佫坢佫e坢坢坢坢坢eeT坢呿" 鈃e2eee2eeeee2e坢e2222eeeee22e2Te2e呿" eeeee狁e坢e2eee2eeeeee2eeTe2" 呿e坢呿親坢邥ee佫e狁e嗛# 嫆ee坢e2eee嫆瞠e2e22e侒ee2222e2e嗛# 嗛e2e2e坢ee嫆e222eeeee2e2ee22e#嫆嗛嫆e佫佫佫佫ee佪%嫆嗛ee2eeee2e嫆狁e2e坢e2ee22eeeee2e22親%坢佫嗛坢嗛呿e2e2ee坢e嫆eee2eee2eeee2e22狁2eee$怩邥呿嗛嫆錚佫怩e佫佫eee佫e佫eT%怩怩佫怩e嗈eee嫆e鈃2e2錚ee2委鈃22eee2eee222Te%ee委ee2嗈eee嫆e坢e錚e委22e2ee22e2e2ee22e2eTee2%邥佪親坢坢Te坢坢e佫eC邥e&邥eee鈃2e2Te22eee21ee22C委&ee2eeeeeeTe2e22e2e2e2e22eeee22Ce2e%怩怩eT2TeveeTe呿嫆坢嗛呿eeT坢eee佫佫ee佫&怩怩eTeTeveeTeee呿嗛e呿e嗛ee2e2狁2Teee2eee2eee22&e2T2T2eev22T2e嗛e呿e嗛e2ee2T22e2eeee2ee22e2&邥帘2eCev佫怩錚嗛佫Tee坢坢佫e2e佫狁e'佫怩帘ee2eCevee怩親eee22eT2eeee22ee22'e委帘2C22v22eeee親eeT2e22eeee22eee22e'邥邥邥v佫坢嫆嗛 嫆佫TeeT佫坢坢坢佫e坢佫ee'邥邥邥v坢坢嫆剻佫e2Te22eeeTee eee212eee2'委委委v呿呿 坢佫佫2eeTee2e22T2eee222e22委22e'怩邥嗈呿怩怩帘邥邥嗛佫eeeee坢坢e坢Te'怩嗈呿怩怩帘佫怩披呿佫e22e22e鈃22eeeee221ee2T'委委e嗈呿帘披e呿e22ee2e鈃2ee2eeeee22e22Te2e2'邥邥嫆eeeee佫佫佫Cee坢ee'邥邥佫嫆坢佫e2狁2eee2eeeeeeCe22eeee'委委呿呿佫ee22e狁2ee2e2 e2C2e22e2e'&eeeeeeeeee'!狁2222eeee2e2eeee' 坢佫22e2e2 eee2ee22e2e22e'邥邥嗈嗛嫆嫆親Ce佫e佫坢eeee&邥邥嗈坢呿呿嫆狁2C22eee2eeee2e'委嗈呿e2C2e2eeee 2e2e2&佫怩嗛 坢e佫e佫eeee&佫嫆佫22e22eeeeee2e&ee嗛呿2e2e2e2eee 2ee&怩怩呿坢 嫆eeee佫佫eee&怩怩呿 嫆2e12eeeee2ee&嗛嫆222e2e2 e2e22e&佫 嫆狁ee坢ee& 坢嫆2e22eeeee2ee&e嗛呿佫e2eee 2e2ee%佫怩2ee坢佫佫eve%佫怩2佫鈃2ee2e2eee2e22eeeee21ev%e22ee佫坢坢佫佫呿22e2e2ee2e2v2e%親怩迉嫆嗛嗈嗛嗛嫆坢嫆坢坢嫆嗈嗈嫆嗛e佫佫坢eeCee%親邠剻嫆嗈嫆嫆剻剻坢剻嗈嗈呿嫆坢e2eeee22eee2eeeee2C%瞠委示呿嗛嗛呿呿佫呿嗈呿呿鈃2e2ee2eeee22e2C22e%帘怩坢嫆e坢狁坢佫e2eeee$帘邥邥坢嫆ee2ee22e22eeeee22e$帘eee委委e佫嗛呿佫222e2ee2e2e22e2e$C!!#eee 佫坢坢e22e"C!佫"狁2e2eeee22e佫"eeCee嗛坢坢坢佫坢2e22eee22e22e222222ee!ev 嗛呿坢坢坢嫆坢嫆嫆嫆嫆嫆嫆e呿佫坢e2!eeeeee 佫佫怩ev 嗛呿坢侒坢剻嫆嫆嫆嫆嫆嫆鈃e2eeee2e嫆eeeee22!e 22ev2委 佫嗛嗛嗛呿呿呿呿2ee22e嗛e2e2e22e2!22e2ee 嗈eve怩呿eeeeeeCeee嗈vee怩呿坢e2e2eee2eeeee1C嗈eev2e2ee委委呿佫嗛2ee2e2e2C22e222eC"鈃ee 坢佫佫2eeeeeC!佫"鈃e2eeeeee21e eCe 2ee2e2eeeee22e 2e呿2!v嫆e佫eeeee嗈e!!v佫嫆瞠e1eeeeeeee22侒 嗈e2vee呿呿佫222ee2e ee2ee22e2e嗛邥veCee"e佫eeee嗛邥veCee!狁2e2eeeeeee1e2v2C22e2e2eee22e佫e22坢2!!v%e佫eeeve坢e!!!v侒$狁2eee eeee嫆侒e2ev呿2!!ve 2e2ee2e2e2e2ee嗛e2e2v2e坢嗛Cv$e坢 佫eeee坢嗛C!v#2e2eeeeee2e鈃eCve 2e2e22eeee2e222e佫嗛邥e!2v!鈃e坢佫 eev佫嗛邥e!2v剻 ee坢e侒坢e2v委2!ve佫2eee2ee2eee佫佫ee22eee2v2坢呿ee!!e%ee佫 e狁veee坢呿e!!e佫#e2eee坢佫e ev佫鈃e2!!ee!2ee22eee22e e22e2v2e嗛呿ve!!e佫%鈃佫 佫eeve嗛呿ve!!e#2ee侒e22坢侒v呿v2!2佫 2eee2eeeeee2坢e2v22ee嗛嗈呿呿e!!!v!狁eeeeee嗈呿呿e!v!ee侒2eee嗈ee2!!!ve狁2eeee22eeee2eee22e佫e2e2ee坢呿v!2!2e$狁佫佫 佫e!e坢狁2eev坢呿v!2!2e eeeee2!2e2evev!!22e2eeeee2eeee2ee22!2e佫e2v22e嗈坢ee!!e佫%狁 佫 e!e!eeee嗈e!e侒 2e侒狁 狁e1!!ee!ee呿呿e2!eee22eeeee2e22 e22!22!2eT!e嫆e佫佫坢坢佫C!C!ee坢T2!e呿eeeeeeeeCe狁!!eeeT!2e嗛嗛2eee2ee2 e22C2e2!2e嗛坢佫T2!22e#坢佫e!e2Cee嗛坢邥T2!22e侒eeeee2eeec2!!2e2C呿委T2!2狁e2eee2e22狁2e22e22e2e22!2e2C222e佫eT佫"佫e坢!!Tee!2!e2ee坢e!T侒侒eeeeeeee!!Te2eee22!2!2e2!ee佫e2Te22eeee2ee22e2e!!Te22e2!22e坢呿佫e!!e佫%佫e2!!eee!2C2e侒嗛邥e!!e佫 eeee狁2!!2e2e2!222!!2狁ee2e2ee2e2ee222!!22!22ee呿呿e2e嫆e佫e22eee2eeee呿呿e2e嫆2eeeee222e2e212eeee222ee呿呿佫狁2 e222ee狁2222e佫坢坢呿佫v!e佫%2ee坢佫eeee2!2ee坢呿佫v!!e狁2ee22eee2ee21221e22!eeev!2狁2e222ee 22222!2e22e呿坢v!T佫%C2eeC!e親佫ee2e2ee!22ee呿侒v!T侒 杈22ee2eC!eeee2212.e121!2e佫evTe坢坢eC22e2eC!e瞠22ee2222!2e2e佫ve2Tee坢eeeT2!22佫e2e佫e 2eeee坢veeTee怩嗛2e1T2!22e侒ee2e2c2 2eeeeev22T22e委委 佫 狁e22T2!22e2e222e22 2e嗛嗛呿佫e!e"2!!ee2e ee! !Ce嗛嗛呿佫!ee2!e212122122ee侒eeee21! !Ceee2!2e22!2222eeee2e2e2e2! !C2e坢vT"e!!ee2e2!!4ee侒vT佫 e2!!122e2e2e佫ee2c2!!eeevTee2!2e2ee22!222嗈佫佫v2!22e 嗛狁!!ee2!e 22 eeve嗈佫佫v2!22e嗛1!!12!1ee2 !2ev嗈委v!22e佫!!2222!2e佫呿ee2e2 22v2e坢呿eC2e2222eC!!2ee坢呿C2e2e22221221212e坢坢ee2!!2e呿2C2ee嗛e2222222e佫e2!222e坢e2!e!2!2ee佫佫eC2 2eee坢e!2e佫 e!2ce坢坢侒ee1C2 2ee22e2!222ee嫆佫ee22C 222e呿嗛佫e!!!T嗛e2!2ee佫C22ee呿嗛e!T嫆22!!22e侒 ee22 ee嗈ee2!!!Teee呿嗛坢坢 鈃2!2e坢eee22ee坢veTeev邥T!!ee2!!eeee坢veTeev邥T!!!1e2e坢e22!ee委v2T22ve委eT!!2e佫坢坢佫e2!2222嗛e!!C郼2!!ee佫e!!2ee嗛嫆e!!!C佫郼2!!12ce侒坢ee1!!2eee2!!Ce郼!!22e佫嗛e22!2e嗛eC邥嫆狁2!!2e坢e! !eev嗛e!C嫆狁2!!!2ee佫 侒e2 !eveeCe22!2e坢坢坢e2 !22v2佫呿呿ee2e邥鈅!e佫佫e!2e呿呿e邥鈅!2ceee e21! 2ee委2e委呿鈅22e2e2ee佫ee2!22e坢坢e!!!C嫆22eeee!2!eee坢侒e!!!C佫剻2!!2ee坢ee21!!2!eee!!!Ce佫2e佫ee2!!222e嗈呿e!!2 2!ee 佫ee22!2!ee嗈呿e2佫2!!12eeee2!2!!ee嗈ee22e佫!2e佫佫e2e2222e佫eC2C2e邥杈!2ee2!!!!22ee坢C2Cee呿杈!22_eeeee1!!!!!!22ee2CC22e委呿杈!222e2e佫坢佫e2!!!!!2222ee2e佫坢嫆!!!!2e佫佫e2!2!!!4ee2e22e侒佫嫆!!22ee22!2!!ee2e嫆!!2eeee2!!2e佫vC!Te 佫eC!2!!22Tv坢vCT2!2eeee2!2!2!2Tv佫委vCeT2e2eee2!!Tv2e坢坢e22!2T佫呿22佫 佫ee!2!!2!!!!2evee22!2T邥e!22e午侒e21!2!!2!!!!2eve2!Te嗛e2eee22!!!!2v2e呿eC2eTe嫆C!!!e佫 佫222!!!!Cee呿CeeTe剻C!!!12ee22!!!!!Ce委eC22T2ee嗛C!!2eeee22!!!C2怩佫e!C#!2 佫2!!!!!!2ee佫坢e!C侒坢2e侒侒e22!!!2e佫佫ee2!Cee佫佫2eee2!!!!22e坢佫e!22!2!e佫佫e2!!! !2Ce侒呿e22!!2!2eee2! !!2Cee22ee!!2ee22! 2C22呿坢v2e佫!!!2佫ee2!!2!2!2ev佫嗛ve邥佫e!!!2e佫e2!!2!!2!!2ev呿eev2e委e!!2e2!!2v2佫e!!!C"22!eeee2!!!!!2ee!!!C佫剻!22!!!1eceeee22!!!!!22e2!!!Cee2!!!22e2e2!!!!2e坢e!2"e!!ee!2!!!!22C4e佫侒e!2侒"e!!!2e21!2!!22Cee佫ee22ee2!!! 2!!2C2ee嗛坢e2CeCe邥邥2!!2!22e22!!!!!22eev佪嗛侒eeCeCe邥怩佫2!2!2212e2!!!!!!!!22eev佪ee2CC2e委委2!!222!!!!22ve諼坢e!2C#軥!2!!2!!!!!!!!!!2e呿侒e!2C坢!軥!2!!2!!!!!!!!!!!22ee呿ee2!2Ce佫軥!!!2!!!!!!2e!!2%狁!!!!2!!!!!!!!!!2ee e!!2#2!!!!2!!!!!!!2ee 委e!2ee2!!!!!!!!2e佫e2e 22!!!!!!!!!!!2!!22ev呿 佫e2剻22!!!!!!!!2!22ev呿 e2222ee2!!!!!!22v 嗛eC2C2e$e!!!!!!2!2!2!Cee!嗛eCeCee侒"e!!!!!2!2!!2!Cee!委2C2C22eee!e!!!C22ee!e!2'委2!!!!!2!!22e披#e2'予22!!!!2!!!!!!22ee披#e22ee#2!!!!!!2e披#v2$NCe2!!2!!2!!2Cev呿$坢侒佫v!!2e$NC2!2!2!!!!2!2Cev呿$ev2ee呿#NC2!!!2Cve呿$坢eTe(22!2!22ee佫&侒eTe佫'22!!!!!2!22ee呿&ee2T2e&2!!!!22呿&e!2.!!!2!!!C2ee)e!!2,!!!2!C2e)ee)!!!!!!C22ee)嗛佪e!,e22!!2e諼*嗛e!佫佫,e2!!!2ee諼*委2!ee佫嗛+鈃e2!!!2e諼*嗛e2Te/ee!222呿-嗛eeTe佫.e1!222e呿-ee22T22 e佫-ee2!22呿-e2!24嗈1e2!24嗈e1e!22ee1嗈e1坢e!甹坢e!玔委2!e玓e2ev玓2eviee22v2ei嗛e2C邥玒嗛e2eC侒侒玗委22Cee委佫ilablgl-1.07/Togl/src/Togl/double.c000066400000000000000000000153421437514534100167310ustar00rootroot00000000000000/* $Id: double.c,v 1.14 2005/04/23 07:49:13 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ #include "togl.h" #include #include /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef SUN extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif static GLuint FontBase; static float xAngle = 0.0, yAngle = 0.0, zAngle = 0.0; static GLfloat CornerX, CornerY, CornerZ; /* where to print strings */ /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ void create_cb(Togl *togl) { FontBase = Togl_LoadBitmapFont(togl, TOGL_BITMAP_8_BY_13); if (!FontBase) { printf("Couldn't load font!\n"); exit(1); } } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ void reshape_cb(Togl *togl) { int width = Togl_Width(togl); int height = Togl_Height(togl); float aspect = (float) width / (float) height; glViewport(0, 0, width, height); /* Set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-aspect, aspect, -1.0, 1.0, 1.0, 10.0); CornerX = -aspect; CornerY = -1.0; CornerZ = -1.1; /* Change back to model view transform for rendering */ glMatrixMode(GL_MODELVIEW); } static void print_string(const char *s) { glCallLists(strlen(s), GL_UNSIGNED_BYTE, s); } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ void display_cb(Togl *togl) { static GLuint cubeList = 0; const char *ident; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); /* Reset modelview matrix to the identity * matrix */ glTranslatef(0.0, 0.0, -3.0); /* Move the camera back three units */ glRotatef(xAngle, 1.0, 0.0, 0.0); /* Rotate by X, Y, and Z angles */ glRotatef(yAngle, 0.0, 1.0, 0.0); glRotatef(zAngle, 0.0, 0.0, 1.0); glEnable(GL_DEPTH_TEST); if (!cubeList) { cubeList = glGenLists(1); glNewList(cubeList, GL_COMPILE); /* Front face */ glBegin(GL_QUADS); glColor3f(0.0, 0.7, 0.1); /* Green */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); /* Back face */ glColor3f(0.9, 1.0, 0.0); /* Yellow */ glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); /* Top side face */ glColor3f(0.2, 0.2, 1.0); /* Blue */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); /* Bottom side face */ glColor3f(0.7, 0.0, 0.1); /* Red */ glVertex3f(-1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); glEnd(); glEndList(); } glCallList(cubeList); glDisable(GL_DEPTH_TEST); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); glRasterPos3f(CornerX, CornerY, CornerZ); glListBase(FontBase); ident = Togl_Ident(togl); if (strcmp(ident, "Single") == 0) { print_string("Single buffered"); } else { print_string("Double buffered"); } Togl_SwapBuffers(togl); } int setXrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setXrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } xAngle = atof(argv[2]); /* printf( "before %f ", xAngle ); */ if (xAngle < 0.0) { xAngle += 360.0; } else if (xAngle > 360.0) { xAngle -= 360.0; } /* printf( "after %f \n", xAngle ); */ Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int setYrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setYrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } yAngle = atof(argv[2]); if (yAngle < 0.0) { yAngle += 360.0; } else if (yAngle > 360.0) { yAngle -= 360.0; } Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int getXrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { sprintf(interp->result, "%d", (int) xAngle); return TCL_OK; } int getYrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { sprintf(interp->result, "%d", (int) yAngle); return TCL_OK; } /* * Called by Tk_Main() to let me initialize the modules (Togl) I will need. */ TOGL_EXTERN int Double_Init(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } #ifdef macintosh Togl_MacSetupMainInterp(interp); #endif /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(create_cb); Togl_DisplayFunc(display_cb); Togl_ReshapeFunc(reshape_cb); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ Togl_CreateCommand("setXrot", setXrot_cb); Togl_CreateCommand("setYrot", setYrot_cb); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ Tcl_CreateCommand(interp, "getXrot", (Tcl_CmdProc *) getXrot_cb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "getYrot", (Tcl_CmdProc *) getYrot_cb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } lablgl-1.07/Togl/src/Togl/double.tcl000066400000000000000000000055221437514534100172700ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # $Id: double.tcl,v 1.5 2001/12/20 13:59:31 beskow Exp $ # Togl - a Tk OpenGL widget # Copyright (C) 1996 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # $Log: double.tcl,v $ # Revision 1.5 2001/12/20 13:59:31 beskow # Improved error-handling in togl.c in case of window creation failure # Added pkgIndex target to makefile # Updated documentation to reflect stubs-interface (Togl.html + new README.stubs) # Added tk8.4a3 headers # Removed obsolete Tk internal headers # # Revision 1.4 2001/01/29 18:11:53 brianp # Jonas Beskow's changes to use Tcl/Tk stub interface # # Revision 1.3 1998/03/12 03:52:31 brianp # now sharing display lists between the widgets # # Revision 1.2 1996/10/23 23:31:56 brianp # added -ident options to togl calls # # Revision 1.1 1996/10/23 23:17:22 brianp # Initial revision # # An Tk/OpenGL widget demo with two windows, one single buffered and the # other double buffered. load [file dirname [info script]]/double[info sharedlibextension] proc setup {} { wm title . "Single vs Double Buffering" frame .f1 # create first Togl widget togl .f1.o1 -width 200 -height 200 -rgba true -double false -depth true -ident Single # create second Togl widget, share display lists with first widget togl .f1.o2 -width 200 -height 200 -rgba true -double true -depth true -ident Double -sharelist Single scale .sx -label {X Axis} -from 0 -to 360 -command {setAngle x} -orient horizontal scale .sy -label {Y Axis} -from 0 -to 360 -command {setAngle y} -orient horizontal button .btn -text Quit -command exit bind .f1.o1 { motion_event [lindex [%W config -width] 4] \ [lindex [%W config -height] 4] \ %x %y } bind .f1.o2 { motion_event [lindex [%W config -width] 4] \ [lindex [%W config -height] 4] \ %x %y } pack .f1.o1 .f1.o2 -side left -padx 3 -pady 3 -fill both -expand t pack .f1 -fill both -expand t pack .sx -fill x pack .sy -fill x pack .btn -fill x } # This is called when mouse button 1 is pressed and moved in either of # the OpenGL windows. proc motion_event { width height x y } { .f1.o1 setXrot [expr 360.0 * $y / $height] .f1.o2 setXrot [expr 360.0 * $y / $height] .f1.o1 setYrot [expr 360.0 * ($width - $x) / $width] .f1.o2 setYrot [expr 360.0 * ($width - $x) / $width] # .sx set [expr 360.0 * $y / $height] # .sy set [expr 360.0 * ($width - $x) / $width] .sx set [getXrot] .sy set [getYrot] } # This is called when a slider is changed. proc setAngle {axis value} { global xAngle yAngle zAngle switch -exact $axis { x {.f1.o1 setXrot $value .f1.o2 setXrot $value} y {.f1.o1 setYrot $value .f1.o2 setYrot $value} } } # Execution starts here! setup lablgl-1.07/Togl/src/Togl/gears.c000066400000000000000000000247731437514534100165700ustar00rootroot00000000000000/* gears.c */ /* * 3-D gear wheels. This program is in the public domain. * * Brian Paul * * * Modified to work under Togl as a widget for TK 1997 * * Philip Quaife * */ #include "togl.h" #include #include #include #ifndef M_PI # define M_PI 3.14159265 #endif struct WHIRLYGIZMO { GLint Gear1, Gear2, Gear3; GLfloat Rotx, Roty, Rotz; GLfloat Angle; int Height, Width; }; /* * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth */ static void gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth) { GLint i; GLfloat r0, r1, r2; GLfloat angle, da; GLfloat u, v, len; r0 = inner_radius; r1 = outer_radius - tooth_depth / 2.0; r2 = outer_radius + tooth_depth / 2.0; da = 2.0 * M_PI / teeth / 4.0; glShadeModel(GL_FLAT); glNormal3f(0.0, 0.0, 1.0); /* draw front face */ glBegin(GL_QUAD_STRIP); for (i = 0; i <= teeth; i++) { angle = i * 2.0 * M_PI / teeth; glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); } glEnd(); /* draw front sides of teeth */ glBegin(GL_QUADS); da = 2.0 * M_PI / teeth / 4.0; for (i = 0; i < teeth; i++) { angle = i * 2.0 * M_PI / teeth; glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); } glEnd(); glNormal3f(0.0, 0.0, -1.0); /* draw back face */ glBegin(GL_QUAD_STRIP); for (i = 0; i <= teeth; i++) { angle = i * 2.0 * M_PI / teeth; glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); } glEnd(); /* draw back sides of teeth */ glBegin(GL_QUADS); da = 2.0 * M_PI / teeth / 4.0; for (i = 0; i < teeth; i++) { angle = i * 2.0 * M_PI / teeth; glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); } glEnd(); /* draw outward faces of teeth */ glBegin(GL_QUAD_STRIP); for (i = 0; i < teeth; i++) { angle = i * 2.0 * M_PI / teeth; glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); u = r2 * cos(angle + da) - r1 * cos(angle); v = r2 * sin(angle + da) - r1 * sin(angle); len = sqrt(u * u + v * v); u /= len; v /= len; glNormal3f(v, -u, 0.0); glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); glNormal3f(cos(angle), sin(angle), 0.0); glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); glNormal3f(v, -u, 0.0); glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); glNormal3f(cos(angle), sin(angle), 0.0); } glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); glEnd(); glShadeModel(GL_SMOOTH); /* draw inside radius cylinder */ glBegin(GL_QUAD_STRIP); for (i = 0; i <= teeth; i++) { angle = i * 2.0 * M_PI / teeth; glNormal3f(-cos(angle), -sin(angle), 0.0); glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); } glEnd(); } /* * static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0; static GLint * gear1, gear2, gear3; static GLfloat angle = 0.0; */ static GLuint limit; static GLuint count = 1; static GLubyte polycolor[4] = { 255, 255, 255, 255 }; static void draw(Togl *togl) { struct WHIRLYGIZMO *Wg; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Wg = Togl_GetClientData(togl); glDisable(GL_TEXTURE_2D); glPushMatrix(); glRotatef(Wg->Rotx, 1.0, 0.0, 0.0); glRotatef(Wg->Roty, 0.0, 1.0, 0.0); glRotatef(Wg->Rotz, 0.0, 0.0, 1.0); glPushMatrix(); glTranslatef(-3.0, -2.0, 0.0); glRotatef(Wg->Angle, 0.0, 0.0, 1.0); glEnable(GL_DEPTH_TEST); glCallList(Wg->Gear1); glEnable(GL_DEPTH_TEST); glPopMatrix(); glPushMatrix(); glTranslatef(3.1, -2.0, 0.0); glRotatef(-2.0 * Wg->Angle - 9.0, 0.0, 0.0, 1.0); glCallList(Wg->Gear2); glPopMatrix(); glPushMatrix(); glTranslatef(-3.1, 4.2, 0.0); glRotatef(-2.0 * Wg->Angle - 25.0, 0.0, 0.0, 1.0); glCallList(Wg->Gear3); glPopMatrix(); glPopMatrix(); Togl_SwapBuffers(togl); } static void zap(Togl *togl) { struct WHIRLYGIZMO *Wg; Wg = Togl_GetClientData(togl); free(Wg); } static void idle(Togl *togl) { struct WHIRLYGIZMO *Wg; Wg = Togl_GetClientData(togl); Wg->Angle += 2.0; Togl_PostRedisplay(togl); } /* change view angle, exit upon ESC */ /* * static GLenum key(int k, GLenum mask) { switch (k) { case TK_UP: view_rotx * += 5.0; return GL_TRUE; case TK_DOWN: view_rotx -= 5.0; return GL_TRUE; case * TK_LEFT: view_roty += 5.0; return GL_TRUE; case TK_RIGHT: view_roty -= 5.0; * return GL_TRUE; case TK_z: view_rotz += 5.0; return GL_TRUE; case TK_Z: * view_rotz -= 5.0; return GL_TRUE; } return GL_FALSE; } */ /* new window size or exposure */ static void reshape(Togl *togl) { int width, height; width = Togl_Width(togl); height = Togl_Height(togl); glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (width > height) { GLfloat w = (GLfloat) width / (GLfloat) height; glFrustum(-w, w, -1.0, 1.0, 5.0, 60.0); } else { GLfloat h = (GLfloat) height / (GLfloat) width; glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -40.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } static void init(Togl *togl) { struct WHIRLYGIZMO *Wg; static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; glLightfv(GL_LIGHT0, GL_POSITION, pos); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); /* make the gears */ Wg = malloc(sizeof (*Wg)); if (!Wg) { Tcl_SetResult(Togl_Interp(togl), "\"Cannot allocate client data for widget\"", TCL_STATIC); } Wg->Gear1 = glGenLists(1); glNewList(Wg->Gear1, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); gear(1.0, 4.0, 1.0, 20, 0.7); glEndList(); Wg->Gear2 = glGenLists(1); glNewList(Wg->Gear2, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); gear(0.5, 2.0, 2.0, 10, 0.7); glEndList(); Wg->Gear3 = glGenLists(1); glNewList(Wg->Gear3, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); gear(1.3, 2.0, 0.5, 10, 0.7); glEndList(); glEnable(GL_NORMALIZE); Wg->Height = Togl_Height(togl); Wg->Width = Togl_Width(togl); Wg->Angle = 0.0; Wg->Rotx = 0.0; Wg->Roty = 0.0; Wg->Rotz = 0.0; Togl_SetClientData(togl, (ClientData) Wg); } int position(Togl *togl, int argc, CONST84 char *argv[]) { struct WHIRLYGIZMO *Wg; Tcl_Interp *interp = Togl_Interp(togl); char Result[100]; Wg = Togl_GetClientData(togl); /* error checking */ if (argc != 2) { Tcl_SetResult(interp, "wrong # args: should be \"pathName \"", TCL_STATIC); return TCL_ERROR; } /* Let result string equal value */ sprintf(Result, "%g %g", Wg->Roty, Wg->Rotx); Tcl_SetResult(interp, Result, TCL_VOLATILE); return TCL_OK; } int rotate(Togl *togl, int argc, CONST84 char *argv[]) { struct WHIRLYGIZMO *Wg; Tcl_Interp *interp = Togl_Interp(togl); Wg = Togl_GetClientData(togl); /* error checking */ if (argc != 4) { Tcl_SetResult(interp, "wrong # args: should be \"pathName xrot yrot\"", TCL_STATIC); return TCL_ERROR; } Wg->Roty = atof(argv[2]); Wg->Rotx = atof(argv[3]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } TOGL_EXTERN int Gears_Init(Tcl_Interp *interp) { /* * Initialize Tcl, Tk, and the Togl widget module. */ #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(init); Togl_DestroyFunc(zap); Togl_DisplayFunc(draw); Togl_ReshapeFunc(reshape); Togl_TimerFunc(idle); Togl_CreateCommand("rotate", rotate); Togl_CreateCommand("position", position); return TCL_OK; } lablgl-1.07/Togl/src/Togl/gears.tcl000077500000000000000000000035641437514534100171260ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # Togl - a Tk OpenGL widget # Copyright (C) 1996-1997 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # # Test Togl using GL Gears Demo # # Copyright (C) 1997 Philip Quaife # load [file dirname [info script]]/gears[info sharedlibextension] proc setup {} { global startx starty xangle0 yangle0 xangle yangle RotCnt global vTime set RotCnt 1 set xangle 0.0 set yangle 0.0 set vTime 100 wm title . "Rotating Gear Widget Test" label .t -text "Click and drag to rotate image" pack .t -side top -padx 2 -pady 10 frame .f pack .f -side top button .f.n1 -text " Add " -command AutoRot button .f.r1 -text "Remove" -command DelRot button .f.b1 -text " Quit " -command exit entry .f.t -width 4 -textvariable vTime pack .f.n1 .f.t .f.r1 .f.b1 -side left -anchor w -padx 5 newRot .w0 10 } proc AutoRot {} { global RotCnt vTime newRot .w$RotCnt $vTime set RotCnt [expr $RotCnt + 1] } proc DelRot {} { global RotCnt vTime if { $RotCnt != 0 } { set RotCnt [expr $RotCnt - 1] destroy .w$RotCnt } } proc newRot {win {tick 100} } { togl $win -width 200 -height 200 -rgba true -double true -depth true -privatecmap false -time $tick bind $win {RotStart %x %y %W} bind $win {RotMove %x %y %W} pack $win -expand true -fill both } proc RotStart {x y W } { global startx starty xangle0 yangle0 xangle yangle set startx $x set starty $y set vPos [$W position] set xangle0 [lindex $vPos 0] set yangle0 [lindex $vPos 1] } proc RotMove {x y W} { global startx starty xangle0 yangle0 xangle yangle set xangle [expr $xangle0 + ($x - $startx) ] set yangle [expr $yangle0 + ($y - $starty) ] $W rotate $xangle $yangle } setup lablgl-1.07/Togl/src/Togl/image.c000066400000000000000000000141471437514534100165430ustar00rootroot00000000000000/* * SGI rgb file reader borrowed from gltk library */ #include "togl.h" /* added by GG to include windows.h */ #include #include #include #include "image.h" #ifndef SEEK_SET # define SEEK_SET 0 #endif static void tkQuit(void) { exit(0); } /******************************************************************************/ typedef struct _rawImageRec { unsigned short imagic; unsigned short type; unsigned short dim; unsigned short sizeX, sizeY, sizeZ; unsigned long min, max; unsigned long wasteBytes; char name[80]; unsigned long colorMap; FILE *file; unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA; unsigned long rleEnd; GLuint *rowStart; GLint *rowSize; } rawImageRec; /******************************************************************************/ static void ConvertShort(unsigned short *array, long length) { unsigned long b1, b2; unsigned char *ptr; ptr = (unsigned char *) array; while (length--) { b1 = *ptr++; b2 = *ptr++; *array++ = (b1 << 8) | (b2); } } static void ConvertLong(GLuint *array, long length) { unsigned long b1, b2, b3, b4; unsigned char *ptr; ptr = (unsigned char *) array; while (length--) { b1 = *ptr++; b2 = *ptr++; b3 = *ptr++; b4 = *ptr++; *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); } } static rawImageRec * RawImageOpen(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"); tkQuit(); } if ((raw->file = fopen(fileName, "rb")) == NULL) { perror(fileName); tkQuit(); } 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); raw->tmpA = (unsigned char *) malloc(raw->sizeX * 256); if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL || raw->tmpB == NULL || raw->tmpA == NULL) { fprintf(stderr, "Out of memory!\n"); tkQuit(); } 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"); tkQuit(); } 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->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, raw->rowStart[y + z * raw->sizeY], SEEK_SET); fread(raw->tmp, 1, (unsigned int) raw->rowSize[y + z * raw->sizeY], raw->file); iPtr = raw->tmp; oPtr = buf; while (1) { pixel = *iPtr++; count = (int) (pixel & 0x7F); if (!count) { return; } if (pixel & 0x80) { while (count--) { *oPtr++ = *iPtr++; } } else { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; } } } } else { fseek(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"); tkQuit(); } ptr = final->data; for (i = 0; i < (int) (raw->sizeY); i++) { RawImageGetRow(raw, raw->tmpR, i, 0); RawImageGetRow(raw, raw->tmpG, i, 1); RawImageGetRow(raw, raw->tmpB, i, 2); if (raw->sizeZ == 4) { /* 4 components */ RawImageGetRow(raw, raw->tmpA, i, 3); for (j = 0; j < (int) (raw->sizeX); j++) { *ptr++ = *(raw->tmpR + j); *ptr++ = *(raw->tmpG + j); *ptr++ = *(raw->tmpB + j); *ptr++ = *(raw->tmpA + j); } } else { /* 3 components */ for (j = 0; j < (int) (raw->sizeX); j++) { *ptr++ = *(raw->tmpR + j); *ptr++ = *(raw->tmpG + j); *ptr++ = *(raw->tmpB + j); } } } } TK_RGBImageRec * tkRGBImageLoad(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"); tkQuit(); } final->sizeX = raw->sizeX; final->sizeY = raw->sizeY; final->sizeZ = raw->sizeZ; RawImageGetData(raw, final); RawImageClose(raw); return final; } /******************************************************************************/ lablgl-1.07/Togl/src/Togl/image.h000066400000000000000000000003371437514534100165440ustar00rootroot00000000000000/* image.h */ #ifndef IMAGE_H # define IMAGE_H typedef struct _TK_RGBImageRec { int sizeX, sizeY, sizeZ; unsigned char *data; } TK_RGBImageRec; extern TK_RGBImageRec *tkRGBImageLoad(char *fileName); #endif lablgl-1.07/Togl/src/Togl/index.c000066400000000000000000000102411437514534100165570ustar00rootroot00000000000000/* $Id: index.c,v 1.10 2005/04/23 07:49:13 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ /* * An example Togl program using color-index mode. */ #include "togl.h" #include #include /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef SUN extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif /* Our color indexes: */ static unsigned long black, red, green, blue; /* Rotation angle */ static float Angle = 0.0; /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ void create_cb(Togl *togl) { /* allocate color indexes */ black = Togl_AllocColor(togl, 0.0, 0.0, 0.0); red = Togl_AllocColor(togl, 1.0, 0.0, 0.0); green = Togl_AllocColor(togl, 0.0, 1.0, 0.0); blue = Togl_AllocColor(togl, 0.0, 0.0, 1.0); /* If we were using a private read/write colormap we'd setup our color * table with something like this: */ /* * black = 1; Togl_SetColor( togl, black, 0.0, 0.0, 0.0 ); red = 2; * Togl_SetColor( togl, red, 1.0, 0.0, 0.0 ); green = 3; Togl_SetColor( * togl, green, 0.0, 1.0, 0.0 ); blue = 4; Togl_SetColor( togl, blue, 0.0, * 0.0, 1.0 ); */ glShadeModel(GL_FLAT); glDisable(GL_DITHER); } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ void reshape_cb(Togl *togl) { int width = Togl_Width(togl); int height = Togl_Height(togl); float aspect = (float) width / (float) height; glViewport(0, 0, width, height); /* Set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-aspect, aspect, -1.0, 1.0, -1.0, 1.0); /* Change back to model view transform for rendering */ glMatrixMode(GL_MODELVIEW); } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ void display_cb(Togl *togl) { glClearIndex(black); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(0.3, -0.3, 0.0); glRotatef(Angle, 0.0, 0.0, 1.0); glIndexi(red); glBegin(GL_TRIANGLES); glVertex2f(-0.5, -0.3); glVertex2f(0.5, -0.3); glVertex2f(0.0, 0.6); glEnd(); glPopMatrix(); glPushMatrix(); glRotatef(Angle, 0.0, 0.0, 1.0); glIndexi(green); glBegin(GL_TRIANGLES); glVertex2f(-0.5, -0.3); glVertex2f(0.5, -0.3); glVertex2f(0.0, 0.6); glEnd(); glPopMatrix(); glPushMatrix(); glTranslatef(-0.3, 0.3, 0.0); glRotatef(Angle, 0.0, 0.0, 1.0); glIndexi(blue); glBegin(GL_TRIANGLES); glVertex2f(-0.5, -0.3); glVertex2f(0.5, -0.3); glVertex2f(0.0, 0.6); glEnd(); glPopMatrix(); glFlush(); Togl_SwapBuffers(togl); } void timer_cb(Togl *togl) { Angle += 5.0; Togl_PostRedisplay(togl); } TOGL_EXTERN int Index_Init(Tcl_Interp *interp) { /* * Initialize Tcl, Tk, and the Togl widget module. */ #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(create_cb); Togl_DisplayFunc(display_cb); Togl_ReshapeFunc(reshape_cb); Togl_TimerFunc(timer_cb); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ /* NONE */ /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ return TCL_OK; } lablgl-1.07/Togl/src/Togl/index.tcl000066400000000000000000000024531437514534100171250ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # $Id: index.tcl,v 1.5 2001/12/20 13:59:31 beskow Exp $ # Togl - a Tk OpenGL widget # Copyright (C) 1996 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # $Log: index.tcl,v $ # Revision 1.5 2001/12/20 13:59:31 beskow # Improved error-handling in togl.c in case of window creation failure # Added pkgIndex target to makefile # Updated documentation to reflect stubs-interface (Togl.html + new README.stubs) # Added tk8.4a3 headers # Removed obsolete Tk internal headers # # Revision 1.4 2001/01/29 18:11:53 brianp # Jonas Beskow's changes to use Tcl/Tk stub interface # # Revision 1.3 1998/01/24 14:05:50 brianp # added quit button (Ben Bederson) # # Revision 1.2 1997/04/11 01:37:34 brianp # added a timer to rotate the triangles # # Revision 1.1 1996/10/23 23:18:11 brianp # Initial revision # # A Tk/OpenGL widget demo using color-index mode. load [file dirname [info script]]/index[info sharedlibextension] proc setup {} { wm title . "Color index demo" togl .win -width 200 -height 200 -rgba false -double true -privatecmap false -time 10 button .btn -text Quit -command exit pack .win -expand true -fill both pack .btn -expand true -fill both } # Execution starts here! setup lablgl-1.07/Togl/src/Togl/overlay.c000066400000000000000000000106721437514534100171410ustar00rootroot00000000000000/* $Id: overlay.c,v 1.7 2005/04/23 07:49:13 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ /* * An example Togl program using an overlay. */ #include "togl.h" #include #include /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef SUN extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif /* Overlay color indexes: */ static unsigned long Red, Green; /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ void create_cb(Togl *togl) { /* allocate overlay color indexes */ Red = Togl_AllocColorOverlay(togl, 1.0, 0.0, 0.0); Green = Togl_AllocColorOverlay(togl, 0.0, 1.0, 0.0); /* in this demo we always show the overlay */ if (Togl_ExistsOverlay(togl)) { Togl_ShowOverlay(togl); printf("Red and green lines are in the overlay\n"); } else { printf("Sorry, this display doesn't support overlays\n"); } } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ void reshape_cb(Togl *togl) { int width = Togl_Width(togl); int height = Togl_Height(togl); float aspect = (float) width / (float) height; /* Set up viewing for normal plane's context */ glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-aspect, aspect, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); /* Set up viewing for overlay plane's context */ if (Togl_ExistsOverlay(togl)) { Togl_UseLayer(togl, TOGL_OVERLAY); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); Togl_UseLayer(togl, TOGL_NORMAL); } } /* * Togl widget overlay display callback. This is called by Tcl/Tk when the * overlay has to be redrawn. */ void overlay_display_cb(Togl *togl) { glClear(GL_COLOR_BUFFER_BIT); glIndexi(Red); glBegin(GL_LINES); glVertex2f(-1.0, -1.0); glVertex2f(1.0, 1.0); glVertex2f(-1.0, 1.0); glVertex2f(1.0, -1.0); glEnd(); glIndexi(Green); glBegin(GL_LINE_LOOP); glVertex2f(-0.5, -0.5); glVertex2f(0.5, -0.5); glVertex2f(0.5, 0.5); glVertex2f(-0.5, 0.5); glEnd(); glFlush(); } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ void display_cb(Togl *togl) { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 1.0); glVertex2f(-0.5, -0.3); glVertex2f(0.5, -0.3); glVertex2f(0.0, 0.6); glColor3f(1.0, 1.0, 0.0); glVertex2f(-0.5 + 0.2, -0.3 - 0.2); glVertex2f(0.5 + 0.2, -0.3 - 0.2); glVertex2f(0.0 + 0.2, 0.6 - 0.2); glColor3f(0.0, 1.0, 1.0); glVertex2f(-0.5 + 0.4, -0.3 - 0.4); glVertex2f(0.5 + 0.4, -0.3 - 0.4); glVertex2f(0.0 + 0.4, 0.6 - 0.4); glEnd(); glFlush(); } /* * Called by Tk_Main() to let me initialize the modules (Togl) I will need. */ TOGL_EXTERN int Overlay_Init(Tcl_Interp *interp) { /* * Initialize Tcl, Tk, and the Togl widget module. */ #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(create_cb); Togl_DisplayFunc(display_cb); Togl_ReshapeFunc(reshape_cb); Togl_OverlayDisplayFunc(overlay_display_cb); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ /* NONE */ /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ return TCL_OK; } lablgl-1.07/Togl/src/Togl/overlay.tcl000066400000000000000000000023021437514534100174700ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # $Id: overlay.tcl,v 1.4 2001/12/20 13:59:31 beskow Exp $ # Togl - a Tk OpenGL widget # Copyright (C) 1996 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # $Log: overlay.tcl,v $ # Revision 1.4 2001/12/20 13:59:31 beskow # Improved error-handling in togl.c in case of window creation failure # Added pkgIndex target to makefile # Updated documentation to reflect stubs-interface (Togl.html + new README.stubs) # Added tk8.4a3 headers # Removed obsolete Tk internal headers # # Revision 1.3 2001/01/29 18:11:53 brianp # Jonas Beskow's changes to use Tcl/Tk stub interface # # Revision 1.2 1998/01/24 14:05:50 brianp # added quit button (Ben Bederson) # # Revision 1.1 1997/03/07 01:26:38 brianp # Initial revision # # # A Tk/OpenGL widget demo using an overlay. load [file dirname [info script]]/overlay[info sharedlibextension] proc setup {} { wm title . "Overlay demo" togl .win -width 200 -height 200 -rgba true -double false -overlay true button .btn -text Quit -command exit pack .win -expand true -fill both pack .btn -expand true -fill both } # Execution starts here! setup lablgl-1.07/Togl/src/Togl/stereo.c000066400000000000000000000212161437514534100167550ustar00rootroot00000000000000/* $Id: stereo.c,v 1.6 2005/04/23 07:49:13 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ #include "togl.h" #include #include /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef SUN extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif static GLuint FontBase; static float xAngle = 0.0, yAngle = 0.0, zAngle = 0.0; static GLfloat CornerX, CornerY, CornerZ; /* where to print strings */ static GLfloat scale = 1.0; /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ void create_cb(Togl *togl) { FontBase = Togl_LoadBitmapFont(togl, TOGL_BITMAP_8_BY_13); if (!FontBase) { printf("Couldn't load font!\n"); exit(1); } } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ void reshape_cb(Togl *togl) { int width = Togl_Width(togl); int height = Togl_Height(togl); float aspect = (float) width / (float) height; glViewport(0, 0, width, height); /* Set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-aspect, aspect, -1.0, 1.0, 1.0, 10.0); CornerX = -aspect; CornerY = -1.0; CornerZ = -1.1; /* Change back to model view transform for rendering */ glMatrixMode(GL_MODELVIEW); } static void print_string(const char *s) { glCallLists(strlen(s), GL_UNSIGNED_BYTE, s); } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ void display_cb(Togl *togl) { const char *ident; GLfloat eyeDist = 2.0; GLfloat eyeOffset = 0.05; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); /* Reset modelview matrix to the identity * matrix */ glTranslatef(0.0, 0.0, -3.0); /* Move the camera back three units */ glScalef(scale, scale, scale); /* Zoom in and out */ glRotatef(xAngle, 1.0, 0.0, 0.0); /* Rotate by X, Y, and Z angles */ glRotatef(yAngle, 0.0, 1.0, 0.0); glRotatef(zAngle, 0.0, 0.0, 1.0); glEnable(GL_DEPTH_TEST); /* stereo right eye */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); Togl_StereoFrustum(-1, 1, -1, 1, 1, 10, eyeDist, eyeOffset); glMatrixMode(GL_MODELVIEW); #ifdef OLD_STEREO Togl_OldStereoDrawBuffer(GL_BACK_RIGHT); Togl_OldStereoClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #else glDrawBuffer(GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif /* Front face */ glBegin(GL_QUADS); glColor3f(0.0, 0.7, 0.1); /* Green */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); /* Back face */ glColor3f(0.9, 1.0, 0.0); /* Yellow */ glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); /* Top side face */ glColor3f(0.2, 0.2, 1.0); /* Blue */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); /* Bottom side face */ glColor3f(0.7, 0.0, 0.1); /* Red */ glVertex3f(-1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); glEnd(); /* stereo left eye */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); Togl_StereoFrustum(-1, 1, -1, 1, 1, 10, eyeDist, -eyeOffset); glMatrixMode(GL_MODELVIEW); #ifdef OLD_STEREO Togl_OldStereoDrawBuffer(GL_BACK_LEFT); Togl_OldStereoClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #else glDrawBuffer(GL_BACK_LEFT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif /* Front face */ glBegin(GL_QUADS); glColor3f(0.0, 0.7, 0.1); /* Green */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); /* Back face */ glColor3f(0.9, 1.0, 0.0); /* Yellow */ glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); /* Top side face */ glColor3f(0.2, 0.2, 1.0); /* Blue */ glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); /* Bottom side face */ glColor3f(0.7, 0.0, 0.1); /* Red */ glVertex3f(-1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); glEnd(); glDisable(GL_DEPTH_TEST); glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); glRasterPos3f(CornerX, CornerY, CornerZ); glListBase(FontBase); /* ident = Togl_Ident( togl ); if (strcmp(ident,"Single")==0) { * print_string( "Single buffered" ); } else { print_string( "Double * buffered" ); } */ print_string(Togl_Ident(togl)); Togl_SwapBuffers(togl); } int setXrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setXrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } xAngle = atof(argv[2]); /* printf( "before %f ", xAngle ); */ if (xAngle < 0.0) { xAngle += 360.0; } else if (xAngle > 360.0) { xAngle -= 360.0; } /* printf( "after %f \n", xAngle ); */ Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int setYrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setYrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } yAngle = atof(argv[2]); if (yAngle < 0.0) { yAngle += 360.0; } else if (yAngle > 360.0) { yAngle -= 360.0; } Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int getXrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { sprintf(interp->result, "%d", (int) xAngle); return TCL_OK; } int getYrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { sprintf(interp->result, "%d", (int) yAngle); return TCL_OK; } int scale_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName scale ?value?\"", TCL_STATIC); return TCL_ERROR; } scale = atof(argv[2]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } TOGL_EXTERN int Stereo_Init(Tcl_Interp *interp) { /* * Initialize Tcl, Tk, and the Togl widget module. */ #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(create_cb); Togl_DisplayFunc(display_cb); Togl_ReshapeFunc(reshape_cb); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ Togl_CreateCommand("setXrot", setXrot_cb); Togl_CreateCommand("setYrot", setYrot_cb); Togl_CreateCommand("scale", scale_cb); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ Tcl_CreateCommand(interp, "getXrot", getXrot_cb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "getYrot", getYrot_cb, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } lablgl-1.07/Togl/src/Togl/stereo.tcl000066400000000000000000000055431437514534100173220ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # $Id: stereo.tcl,v 1.4 2004/12/21 05:28:39 gregcouch Exp $ # Togl - a Tk OpenGL widget # Copyright (C) 1996 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # $Log: stereo.tcl,v $ # Revision 1.4 2004/12/21 05:28:39 gregcouch # Apply outstanding patches and Mac OS X support. # # Revision 1.3 2001/12/20 13:59:31 beskow # Improved error-handling in togl.c in case of window creation failure # Added pkgIndex target to makefile # Updated documentation to reflect stubs-interface (Togl.html + new README.stubs) # Added tk8.4a3 headers # Removed obsolete Tk internal headers # # Revision 1.2 2001/01/29 18:11:53 brianp # Jonas Beskow's changes to use Tcl/Tk stub interface # # Revision 1.1 1997/10/01 02:53:12 brianp # Initial revision # # # Revision 1.1 1997/9/28 18:54:46 Ben Evans # Initial revision. Based on double.tcl # # An Tk/OpenGL widget demo with two windows, one single buffered and the # other double buffered. load [file dirname [info script]]/stereo[info sharedlibextension] proc setup {} { global scale set scale 1.0 wm title . "Full Screen Stereo Buffering" frame .f1 togl .f1.o1 -width 200 -height 200 -rgba true -stereo true -double true -depth true -ident "stereo buffer" scale .sx -label {X Axis} -from 0 -to 360 -command {setAngle x} -orient horizontal scale .sy -label {Y Axis} -from 0 -to 360 -command {setAngle y} -orient horizontal button .btn -text Quit -command exit bind .f1.o1 { motion_event [lindex [%W config -width] 4] \ [lindex [%W config -height] 4] \ %x %y } bind .f1.o1 { set startx %x set starty %y set scale0 $scale } bind .f1.o1 { set q [ expr ($starty - %y) / 400.0 ] set scale [expr $scale0 * exp($q)] .f1.o1 scale $scale } pack .f1.o1 -side left -padx 3 -pady 3 -fill both -expand t pack .f1 -fill both -expand t pack .sx -fill x pack .sy -fill x pack .btn -fill x if {[string first $::tcl_platform(os) IRIX] != -1} { puts "use /usr/gfx/setmon -n 60 to reset display and /usr/gfx/setmon -n STR_RECT to put in display in stereo mode" } } # This is called when mouse button 1 is pressed and moved in either of # the OpenGL windows. proc motion_event { width height x y } { .f1.o1 setXrot [expr 360.0 * $y / $height] .f1.o1 setYrot [expr 360.0 * ($width - $x) / $width] # .sx set [expr 360.0 * $y / $height] # .sy set [expr 360.0 * ($width - $x) / $width] .sx set [getXrot] .sy set [getYrot] } # This is called when a slider is changed. proc setAngle {axis value} { global xAngle yAngle zAngle switch -exact $axis { x {.f1.o1 setXrot $value} y {.f1.o1 setYrot $value} } } # Execution starts here! setup lablgl-1.07/Togl/src/Togl/texture.c000066400000000000000000000346711437514534100171650ustar00rootroot00000000000000/* $Id: texture.c,v 1.10 2005/04/23 07:49:14 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ /* * An example Togl program demonstrating texture mapping */ #include "togl.h" #include #include #if defined(TOGL_AGL) || defined(TOGL_AGL_CLASSIC) # include #else # include #endif #include "image.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef SUN extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif #define CHECKER 0 #define FACE 1 #define TREE 2 static GLenum minfilter = GL_NEAREST_MIPMAP_LINEAR; static GLenum magfilter = GL_LINEAR; static GLenum swrap = GL_REPEAT; static GLenum twrap = GL_REPEAT; static GLenum envmode = GL_MODULATE; static GLubyte polycolor[4] = { 255, 255, 255, 255 }; static int image = CHECKER; static GLfloat coord_scale = 1.0; static GLfloat xrot = 0.0; static GLfloat yrot = 0.0; static GLfloat scale = 1.0; static GLint width, height; static GLboolean blend = GL_FALSE; /* * Load a texture image. n is one of CHECKER, FACE or TREE. */ void texture_image(int n) { if (n == CHECKER) { #define WIDTH 64 #define HEIGHT 64 GLubyte teximage[WIDTH * HEIGHT][4]; int i, j; for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { GLubyte value; value = ((i / 4 + j / 4) % 2) ? 0xff : 0x00; teximage[i * WIDTH + j][0] = value; teximage[i * WIDTH + j][1] = value; teximage[i * WIDTH + j][2] = value; teximage[i * WIDTH + j][3] = value; } } glEnable(GL_TEXTURE_2D); gluBuild2DMipmaps(GL_TEXTURE_2D, 4, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, teximage); blend = GL_FALSE; #undef WIDTH #undef HEIGHT } else if (n == FACE) { TK_RGBImageRec *img = tkRGBImageLoad("ben.rgb"); if (img) { glEnable(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); gluBuild2DMipmaps(GL_TEXTURE_2D, img->sizeZ, img->sizeX, img->sizeY, img->sizeZ == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img->data); blend = GL_TRUE; } } else if (n == TREE) { TK_RGBImageRec *img = tkRGBImageLoad("tree2.rgba"); if (img) { glEnable(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); gluBuild2DMipmaps(GL_TEXTURE_2D, img->sizeZ, img->sizeX, img->sizeY, img->sizeZ == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, img->data); blend = GL_TRUE; } } else { abort(); } } /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ void create_cb(Togl *togl) { glEnable(GL_DEPTH_TEST); /* Enable depth buffering */ texture_image(CHECKER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ void reshape_cb(Togl *togl) { width = Togl_Width(togl); height = Togl_Height(togl); glViewport(0, 0, width, height); } static void check_error(char *where) { GLenum error; while (1) { error = glGetError(); if (error == GL_NO_ERROR) { break; } printf("OpenGL error near %s: %s\n", where, gluErrorString(error)); } } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ void display_cb(Togl *togl) { float aspect = (float) width / (float) height; check_error("begin display\n"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Draw background image */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glBegin(GL_POLYGON); glColor3f(0.0, 0.0, 0.3); glVertex2f(-1.0, -1.0); glColor3f(0.0, 0.0, 0.3); glVertex2f(1.0, -1.0); glColor3f(0.0, 0.0, 0.9); glVertex2f(1.0, 1.0); glColor3f(0.0, 0.0, 0.9); glVertex2f(-1.0, 1.0); glEnd(); /* draw textured object */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-aspect, aspect, -1.0, 1.0, 2.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -5.0); glScalef(scale, scale, scale); glRotatef(yrot, 0.0, 1.0, 0.0); glRotatef(xrot, 1.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glColor4ubv(polycolor); if (blend) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } glBegin(GL_POLYGON); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); glTexCoord2f(coord_scale, 0.0); glVertex2f(1.0, -1.0); glTexCoord2f(coord_scale, coord_scale); glVertex2f(1.0, 1.0); glTexCoord2f(0.0, coord_scale); glVertex2f(-1.0, 1.0); glEnd(); glDisable(GL_BLEND); Togl_SwapBuffers(togl); } /* * Called when a magnification filter radio button is pressed. */ int magfilter_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); if (strcmp(argv[2], "GL_NEAREST") == 0) { magfilter = GL_NEAREST; } else if (strcmp(argv[2], "GL_LINEAR") == 0) { magfilter = GL_LINEAR; } else { Tcl_SetResult(interp, "unknown magnification filter type", TCL_STATIC); return TCL_ERROR; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter); Togl_PostRedisplay(togl); return TCL_OK; } /* * Called when a minification filter radio button is pressed. */ int minfilter_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); if (strcmp(argv[2], "GL_NEAREST") == 0) { minfilter = GL_NEAREST; } else if (strcmp(argv[2], "GL_LINEAR") == 0) { minfilter = GL_LINEAR; } else if (strcmp(argv[2], "GL_NEAREST_MIPMAP_NEAREST") == 0) { minfilter = GL_NEAREST_MIPMAP_NEAREST; } else if (strcmp(argv[2], "GL_LINEAR_MIPMAP_NEAREST") == 0) { minfilter = GL_LINEAR_MIPMAP_NEAREST; } else if (strcmp(argv[2], "GL_NEAREST_MIPMAP_LINEAR") == 0) { minfilter = GL_NEAREST_MIPMAP_LINEAR; } else if (strcmp(argv[2], "GL_LINEAR_MIPMAP_LINEAR") == 0) { minfilter = GL_LINEAR_MIPMAP_LINEAR; } else { Tcl_SetResult(interp, "unknown minification filter type", TCL_STATIC); return TCL_ERROR; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); Togl_PostRedisplay(togl); return TCL_OK; } int xrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setXrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } xrot = atof(argv[2]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int yrot_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName setYrot ?angle?\"", TCL_STATIC); return TCL_ERROR; } yrot = atof(argv[2]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } int scale_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName scale ?value?\"", TCL_STATIC); return TCL_ERROR; } scale = atof(argv[2]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when S texture coordinate wrapping is changed. */ int swrap_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName swrap ?mode?\"", TCL_STATIC); return TCL_ERROR; } if (strcmp(argv[2], "GL_CLAMP") == 0) { swrap = GL_CLAMP; } else if (strcmp(argv[2], "GL_REPEAT") == 0) { swrap = GL_REPEAT; } else { Tcl_SetResult(interp, "unknown wrap value", TCL_STATIC); return TCL_ERROR; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, swrap); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when T texture coordinate wrapping is changed. */ int twrap_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName twrap ?mode?\"", TCL_STATIC); return TCL_ERROR; } if (strcmp(argv[2], "GL_CLAMP") == 0) { twrap = GL_CLAMP; } else if (strcmp(argv[2], "GL_REPEAT") == 0) { twrap = GL_REPEAT; } else { Tcl_SetResult(interp, "unknown wrap value", TCL_STATIC); return TCL_ERROR; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, twrap); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when the texture environment mode is changed. */ int envmode_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName envmode ?mode?\"", TCL_STATIC); return TCL_ERROR; } if (strcmp(argv[2], "GL_MODULATE") == 0) { envmode = GL_MODULATE; } else if (strcmp(argv[2], "GL_DECAL") == 0) { envmode = GL_DECAL; } else if (strcmp(argv[2], "GL_BLEND") == 0) { envmode = GL_BLEND; } else { Tcl_SetResult(interp, "unknown texture env mode", TCL_STATIC); return TCL_ERROR; } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envmode); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when the polygon color is changed. */ int polycolor_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 5) { Tcl_SetResult(interp, "wrong # args: should be \"pathName polycolor ?r? ?g? ?b?\"", TCL_STATIC); return TCL_ERROR; } polycolor[0] = atoi(argv[2]); polycolor[1] = atoi(argv[3]); polycolor[2] = atoi(argv[4]); Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when the texture image is to be changed */ int image_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName image ?name?\"", TCL_STATIC); return TCL_ERROR; } if (strcmp(argv[2], "CHECKER") == 0) { texture_image(CHECKER); } else if (strcmp(argv[2], "FACE") == 0) { texture_image(FACE); } else if (strcmp(argv[2], "TREE") == 0) { texture_image(TREE); } else { Tcl_SetResult(interp, "unknown texture image", TCL_STATIC); return TCL_ERROR; } Togl_PostRedisplay(togl); /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } /* * Called when the texture coordinate scale is changed. */ int coord_scale_cb(Togl *togl, int argc, CONST84 char *argv[]) { Tcl_Interp *interp = Togl_Interp(togl); float s; /* error checking */ if (argc != 3) { Tcl_SetResult(interp, "wrong # args: should be \"pathName coord_scale ?scale?\"", TCL_STATIC); return TCL_ERROR; } s = atof(argv[2]); if (s > 0.0 && s < 10.0) { coord_scale = s; Togl_PostRedisplay(togl); } /* Let result string equal value */ strcpy(interp->result, argv[2]); return TCL_OK; } TOGL_EXTERN int Texture_Init(Tcl_Interp *interp) { /* * Initialize Tcl, Tk, and the Togl widget module. */ #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif if (Togl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Togl_CreateFunc(create_cb); Togl_DisplayFunc(display_cb); Togl_ReshapeFunc(reshape_cb); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ Togl_CreateCommand("min_filter", minfilter_cb); Togl_CreateCommand("mag_filter", magfilter_cb); Togl_CreateCommand("xrot", xrot_cb); Togl_CreateCommand("yrot", yrot_cb); Togl_CreateCommand("scale", scale_cb); Togl_CreateCommand("swrap", swrap_cb); Togl_CreateCommand("twrap", twrap_cb); Togl_CreateCommand("envmode", envmode_cb); Togl_CreateCommand("polycolor", polycolor_cb); Togl_CreateCommand("image", image_cb); Togl_CreateCommand("coord_scale", coord_scale_cb); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ return TCL_OK; } lablgl-1.07/Togl/src/Togl/texture.tcl000066400000000000000000000224461437514534100175220ustar00rootroot00000000000000#!/bin/sh # the next line restarts using wish \ exec wish "$0" "$@" # $Id: texture.tcl,v 1.5 2001/12/20 13:59:31 beskow Exp $ # Togl - a Tk OpenGL widget # Copyright (C) 1996 Brian Paul and Ben Bederson # See the LICENSE file for copyright details. # $Log: texture.tcl,v $ # Revision 1.5 2001/12/20 13:59:31 beskow # Improved error-handling in togl.c in case of window creation failure # Added pkgIndex target to makefile # Updated documentation to reflect stubs-interface (Togl.html + new README.stubs) # Added tk8.4a3 headers # Removed obsolete Tk internal headers # # Revision 1.4 2001/01/29 18:11:53 brianp # Jonas Beskow's changes to use Tcl/Tk stub interface # # Revision 1.3 1998/01/24 14:05:50 brianp # added quit button (Ben Bederson) # # Revision 1.2 1997/09/30 23:54:46 brianp # new layout # # Revision 1.1 1996/10/23 23:18:36 brianp # Initial revision # # Togl texture map demo load [file dirname [info script]]/texture[info sharedlibextension] # Called magnification filter changes proc new_magfilter {} { global magfilter .f1.view mag_filter $magfilter } # Called minification filter changes proc new_minfilter {} { global minfilter .f1.view min_filter $minfilter } # Called when texture image radio button changes proc new_image {} { global teximage .f1.view image $teximage } # Called when texture S wrap button changes proc new_swrap {} { global swrap .f1.view swrap $swrap } # Called when texture T wrap button changes proc new_twrap {} { global twrap .f1.view twrap $twrap } # Called when texture environment radio button selected proc new_env {} { global envmode .f1.view envmode $envmode } # Called when polygon color sliders change proc new_color { foo } { global poly_red poly_green poly_blue .f1.view polycolor $poly_red $poly_green $poly_blue } proc new_coord_scale { name element op } { global coord_scale .f1.view coord_scale $coord_scale } # Make the widgets proc setup {} { global magfilter global minfilter global teximage global swrap global twrap global envmode global poly_red global poly_green global poly_blue global coord_scale global startx starty # location of mouse when button pressed global xangle yangle global xangle0 yangle0 global scale scale0 wm title . "Texture Map Options" ### Two frames: top half and bottom half frame .f1 frame .f2 ### The OpenGL window togl .f1.view -width 250 -height 250 -rgba true -double true -depth true ### Filter radio buttons frame .f1.filter -relief ridge -borderwidth 3 frame .f1.filter.mag -relief ridge -borderwidth 2 label .f1.filter.mag.label -text "Magnification Filter" -anchor w radiobutton .f1.filter.mag.nearest -text GL_NEAREST -anchor w -variable magfilter -value GL_NEAREST -command new_magfilter radiobutton .f1.filter.mag.linear -text GL_LINEAR -anchor w -variable magfilter -value GL_LINEAR -command new_magfilter frame .f1.filter.min -relief ridge -borderwidth 2 label .f1.filter.min.label -text "Minification Filter" -anchor w radiobutton .f1.filter.min.nearest -text GL_NEAREST -anchor w -variable minfilter -value GL_NEAREST -command new_minfilter radiobutton .f1.filter.min.linear -text GL_LINEAR -anchor w -variable minfilter -value GL_LINEAR -command new_minfilter radiobutton .f1.filter.min.nearest_mipmap_nearest -text GL_NEAREST_MIPMAP_NEAREST -anchor w -variable minfilter -value GL_NEAREST_MIPMAP_NEAREST -command new_minfilter radiobutton .f1.filter.min.linear_mipmap_nearest -text GL_LINEAR_MIPMAP_NEAREST -anchor w -variable minfilter -value GL_LINEAR_MIPMAP_NEAREST -command new_minfilter radiobutton .f1.filter.min.nearest_mipmap_linear -text GL_NEAREST_MIPMAP_LINEAR -anchor w -variable minfilter -value GL_NEAREST_MIPMAP_LINEAR -command new_minfilter radiobutton .f1.filter.min.linear_mipmap_linear -text GL_LINEAR_MIPMAP_LINEAR -anchor w -variable minfilter -value GL_LINEAR_MIPMAP_LINEAR -command new_minfilter pack .f1.filter.mag -fill x pack .f1.filter.mag.label -fill x pack .f1.filter.mag.nearest -side top -fill x pack .f1.filter.mag.linear -side top -fill x pack .f1.filter.min -fill both -expand true pack .f1.filter.min.label -side top -fill x pack .f1.filter.min.nearest -side top -fill x pack .f1.filter.min.linear -side top -fill x pack .f1.filter.min.nearest_mipmap_nearest -side top -fill x pack .f1.filter.min.linear_mipmap_nearest -side top -fill x pack .f1.filter.min.nearest_mipmap_linear -side top -fill x pack .f1.filter.min.linear_mipmap_linear -side top -fill x ### Texture coordinate scale and wrapping frame .f2.coord -relief ridge -borderwidth 3 frame .f2.coord.scale -relief ridge -borderwidth 2 label .f2.coord.scale.label -text "Max Texture Coord" -anchor w entry .f2.coord.scale.entry -textvariable coord_scale trace variable coord_scale w new_coord_scale frame .f2.coord.s -relief ridge -borderwidth 2 label .f2.coord.s.label -text "GL_TEXTURE_WRAP_S" -anchor w radiobutton .f2.coord.s.repeat -text "GL_REPEAT" -anchor w -variable swrap -value GL_REPEAT -command new_swrap radiobutton .f2.coord.s.clamp -text "GL_CLAMP" -anchor w -variable swrap -value GL_CLAMP -command new_swrap frame .f2.coord.t -relief ridge -borderwidth 2 label .f2.coord.t.label -text "GL_TEXTURE_WRAP_T" -anchor w radiobutton .f2.coord.t.repeat -text "GL_REPEAT" -anchor w -variable twrap -value GL_REPEAT -command new_twrap radiobutton .f2.coord.t.clamp -text "GL_CLAMP" -anchor w -variable twrap -value GL_CLAMP -command new_twrap pack .f2.coord.scale -fill both -expand true pack .f2.coord.scale.label -side top -fill x pack .f2.coord.scale.entry -side top -fill x pack .f2.coord.s -fill x pack .f2.coord.s.label -side top -fill x pack .f2.coord.s.repeat -side top -fill x pack .f2.coord.s.clamp -side top -fill x pack .f2.coord.t -fill x pack .f2.coord.t.label -side top -fill x pack .f2.coord.t.repeat -side top -fill x pack .f2.coord.t.clamp -side top -fill x ### Texture image radio buttons (just happens to fit into the coord frame) frame .f2.env -relief ridge -borderwidth 3 frame .f2.env.image -relief ridge -borderwidth 2 label .f2.env.image.label -text "Texture Image" -anchor w radiobutton .f2.env.image.checker -text "Checker" -anchor w -variable teximage -value CHECKER -command new_image radiobutton .f2.env.image.tree -text "Tree" -anchor w -variable teximage -value TREE -command new_image radiobutton .f2.env.image.face -text "Face" -anchor w -variable teximage -value FACE -command new_image pack .f2.env.image -fill x pack .f2.env.image.label -side top -fill x pack .f2.env.image.checker -side top -fill x pack .f2.env.image.tree -side top -fill x pack .f2.env.image.face -side top -fill x ### Texture Environment label .f2.env.label -text "GL_TEXTURE_ENV_MODE" -anchor w radiobutton .f2.env.modulate -text "GL_MODULATE" -anchor w -variable envmode -value GL_MODULATE -command new_env radiobutton .f2.env.decal -text "GL_DECAL" -anchor w -variable envmode -value GL_DECAL -command new_env radiobutton .f2.env.blend -text "GL_BLEND" -anchor w -variable envmode -value GL_BLEND -command new_env pack .f2.env.label -fill x pack .f2.env.modulate -side top -fill x pack .f2.env.decal -side top -fill x pack .f2.env.blend -side top -fill x ### Polygon color frame .f2.color -relief ridge -borderwidth 3 label .f2.color.label -text "Polygon color" -anchor w scale .f2.color.red -label Red -from 0 -to 255 -orient horizontal -variable poly_red -command new_color scale .f2.color.green -label Green -from 0 -to 255 -orient horizontal -variable poly_green -command new_color scale .f2.color.blue -label Blue -from 0 -to 255 -orient horizontal -variable poly_blue -command new_color pack .f2.color.label -fill x pack .f2.color.red -side top -fill x pack .f2.color.green -side top -fill x pack .f2.color.blue -side top -fill x ### Main widgets pack .f1.view -side left -fill both -expand true pack .f1.filter -side left -fill y pack .f1 -side top -fill both -expand true pack .f2.coord .f2.env -side left -fill both pack .f2.color -fill x pack .f2 -side top -fill x button .btn -text Quit -command exit pack .btn -expand true -fill both bind .f1.view { set startx %x set starty %y set xangle0 $xangle set yangle0 $yangle } bind .f1.view { set xangle [expr $xangle0 + (%x - $startx) / 3.0 ] set yangle [expr $yangle0 + (%y - $starty) / 3.0 ] .f1.view yrot $xangle .f1.view xrot $yangle } bind .f1.view { set startx %x set starty %y set scale0 $scale } bind .f1.view { set q [ expr ($starty - %y) / 400.0 ] set scale [expr $scale0 * exp($q)] .f1.view scale $scale } # set default values: set minfilter GL_NEAREST_MIPMAP_LINEAR set magfilter GL_LINEAR set swrap GL_REPEAT set twrap GL_REPEAT set envmode GL_MODULATE set teximage CHECKER set poly_red 255 set poly_green 255 set poly_blue 255 set coord_scale 1.0 set xangle 0.0 set yangle 0.0 set scale 1.0 } # Execution starts here! setup lablgl-1.07/Togl/src/Togl/tkFont.h000066400000000000000000000174351437514534100167360ustar00rootroot00000000000000/* * tkFont.h -- * * Declarations for interfaces between the generic and platform-specific * parts of the font package. This information is not visible outside of * the font package. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef _TKFONT #define _TKFONT #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* * The following structure keeps track of the attributes of a font. It can be * used to keep track of either the desired attributes or the actual * attributes gotten when the font was instantiated. */ struct TkFontAttributes { Tk_Uid family; /* Font family, or NULL to represent plaform- * specific default system font. */ int size; /* Pointsize of font, 0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ int underline; /* Non-zero for underline font. */ int overstrike; /* Non-zero for overstrike font. */ }; /* * Possible values for the "weight" field in a TkFontAttributes structure. * Weight is a subjective term and depends on what the company that created * the font considers bold. */ #define TK_FW_NORMAL 0 #define TK_FW_BOLD 1 #define TK_FW_UNKNOWN -1 /* Unknown weight. This value is used for * error checking and is never actually stored * in the weight field. */ /* * Possible values for the "slant" field in a TkFontAttributes structure. */ #define TK_FS_ROMAN 0 #define TK_FS_ITALIC 1 #define TK_FS_OBLIQUE 2 /* This value is only used when parsing X font * names to determine the closest match. It is * only stored in the XLFDAttributes * structure, never in the slant field of the * TkFontAttributes. */ #define TK_FS_UNKNOWN -1 /* Unknown slant. This value is used for error * checking and is never actually stored in * the slant field. */ /* * The following structure keeps track of the metrics for an instantiated * font. The metrics are the physical properties of the font itself. */ typedef struct TkFontMetrics { int ascent; /* From baseline to top of font. */ int descent; /* From baseline to bottom of font. */ int maxWidth; /* Width of widest character in font. */ int fixed; /* Non-zero if this is a fixed-width font, * 0 otherwise. */ } TkFontMetrics; /* * The following structure is used to keep track of the generic information * about a font. Each platform-specific font is represented by a structure * with the following structure at its beginning, plus any platform-specific * stuff after that. */ typedef struct TkFont { /* * Fields used and maintained exclusively by generic code. */ int resourceRefCount; /* Number of active uses of this font (each * active use corresponds to a call to * Tk_AllocFontFromTable or Tk_GetFont). If * this count is 0, then this TkFont structure * is no longer valid and it isn't present in * a hash table: it is being kept around only * because there are objects referring to it. * The structure is freed when * resourceRefCount and objRefCount are both * 0. */ int objRefCount; /* The number of Tcl objects that reference * this structure. */ Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure, * used when deleting it. */ Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that * corresponds to the named font that the * tkfont was based on, or NULL if the tkfont * was not based on a named font. */ Screen *screen; /* The screen where this font is valid. */ int tabWidth; /* Width of tabs in this font (pixels). */ int underlinePos; /* Offset from baseline to origin of underline * bar (used for drawing underlines on a * non-underlined font). */ int underlineHeight; /* Height of underline bar (used for drawing * underlines on a non-underlined font). */ /* * Fields used in the generic code that are filled in by * platform-specific code. */ Font fid; /* For backwards compatibility with XGCValues * structures. Remove when TkGCValues is * implemented. */ TkFontAttributes fa; /* Actual font attributes obtained when the * the font was created, as opposed to the * desired attributes passed in to * TkpGetFontFromAttributes(). The desired * metrics can be determined from the string * that was used to create this font. */ TkFontMetrics fm; /* Font metrics determined when font was * created. */ struct TkFont *nextPtr; /* Points to the next TkFont structure with * the same name. All fonts with the same name * (but different displays) are chained * together off a single entry in a hash * table. */ } TkFont; /* * The following structure is used to return attributes when parsing an XLFD. * The extra information is of interest to the Unix-specific code when * attempting to find the closest matching font. */ typedef struct TkXLFDAttributes { Tk_Uid foundry; /* The foundry of the font. */ int slant; /* The tristate value for the slant, which is * significant under X. */ int setwidth; /* The proportionate width, see below for * definition. */ Tk_Uid charset; /* The actual charset string. */ } TkXLFDAttributes; /* * Possible values for the "setwidth" field in a TkXLFDAttributes structure. * The setwidth is whether characters are considered wider or narrower than * normal. */ #define TK_SW_NORMAL 0 #define TK_SW_CONDENSE 1 #define TK_SW_EXPAND 2 #define TK_SW_UNKNOWN 3 /* Unknown setwidth. This value may be stored * in the setwidth field. */ /* * The following defines specify the meaning of the fields in a fully * qualified XLFD. */ #define XLFD_FOUNDRY 0 #define XLFD_FAMILY 1 #define XLFD_WEIGHT 2 #define XLFD_SLANT 3 #define XLFD_SETWIDTH 4 #define XLFD_ADD_STYLE 5 #define XLFD_PIXEL_SIZE 6 #define XLFD_POINT_SIZE 7 #define XLFD_RESOLUTION_X 8 #define XLFD_RESOLUTION_Y 9 #define XLFD_SPACING 10 #define XLFD_AVERAGE_WIDTH 11 #define XLFD_CHARSET 12 #define XLFD_NUMFIELDS 13 /* Number of fields in XLFD. */ /* * Low-level API exported by generic code to platform-specific code. */ #define TkInitFontAttributes(fa) memset((fa), 0, sizeof(TkFontAttributes)); #define TkInitXLFDAttributes(xa) memset((xa), 0, sizeof(TkXLFDAttributes)); MODULE_SCOPE int TkFontParseXLFD(CONST char *string, TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr); MODULE_SCOPE char ** TkFontGetAliasList(CONST char *faceName); MODULE_SCOPE char *** TkFontGetFallbacks(void); MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size); MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size); MODULE_SCOPE char ** TkFontGetGlobalClass(void); MODULE_SCOPE char ** TkFontGetSymbolClass(void); MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin, CONST char *name, TkFontAttributes *faPtr); MODULE_SCOPE int TkDeleteNamedFont(Tcl_Interp *interp, Tk_Window tkwin, CONST char *name); MODULE_SCOPE int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font *font, char *dst); /* * Low-level API exported by platform-specific code to generic code. */ MODULE_SCOPE void TkpDeleteFont(TkFont *tkFontPtr); MODULE_SCOPE void TkpFontPkgInit(TkMainInfo *mainPtr); MODULE_SCOPE TkFont * TkpGetFontFromAttributes(TkFont *tkFontPtr, Tk_Window tkwin, CONST TkFontAttributes *faPtr); MODULE_SCOPE void TkpGetFontFamilies(Tcl_Interp *interp, Tk_Window tkwin); MODULE_SCOPE TkFont * TkpGetNativeFont(Tk_Window tkwin, CONST char *name); #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKFONT */ lablgl-1.07/Togl/src/Togl/togl.c000066400000000000000000003572131437514534100164320ustar00rootroot00000000000000/* $Id: togl.c,v 1.73 2005/10/26 07:40:22 gregcouch Exp $ */ /* vi:set sw=4: */ /* * Togl - a Tk OpenGL widget * * Copyright (C) 1996-2002 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ /* * Currently we support X11, Win32 and Macintosh only */ #include "togl.h" /* Use TCL_STUPID to cast (const char *) to (char *) where the Tcl function * prototype argument should really be const */ #define TCL_STUPID (char *) /* Use WIDGREC to cast widgRec arguments */ #define WIDGREC (char *) /*** Windows headers ***/ #if defined(TOGL_WGL) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN # include /*** X Window System headers ***/ #elif defined(TOGL_X11) # include # include # include /* for XA_RGB_DEFAULT_MAP atom */ # if defined(__vms) # include /* for XmuLookupStandardColormap */ # else # include /* for XmuLookupStandardColormap */ # endif # include /*** Mac headers ***/ #elif defined(TOGL_AGL_CLASSIC) # include # include # include # include #elif defined(TOGL_AGL) # define Cursor QDCursor # include # undef Cursor # define _TKINTXLIBDECLS /* Avoid using tkIntXlibDecls.h */ # include "tkMacOSX.h" # include /* usa MacDrawable */ # include #else /* make sure only one platform defined */ # error Unsupported platform, or confused platform defines... #endif /*** Standard C headers ***/ #include #include #include #ifdef TOGL_WGL # include #endif #if TK_MAJOR_VERSION < 8 # error Sorry Togl requires Tcl/Tk ver 8.0 or higher. #endif #if defined(TOGL_AGL_CLASSIC) # if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 3) # error Sorry Mac classic version requires Tcl/Tk ver 8.3.0 or higher. # endif #endif /* TOGL_AGL_CLASSIC */ #if defined(TOGL_AGL) # if TK_MAJOR_VERSION < 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 4) # error Sorry Mac Aqua version requires Tcl/Tk ver 8.4.0 or higher. # endif #endif /* TOGL_AGL */ /* workaround for bug #123153 in tcl ver8.4a2 (tcl.h) */ #if defined(Tcl_InitHashTable) && defined(USE_TCL_STUBS) # undef Tcl_InitHashTable # define Tcl_InitHashTable (tclStubsPtr->tcl_InitHashTable) #endif #if TK_MAJOR_VERSION > 8 || (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION >= 4) # define HAVE_TK_SETCLASSPROCS /* pointer to Tk_SetClassProcs function in the stub table */ static void (*SetClassProcsPtr) _ANSI_ARGS_((Tk_Window, Tk_ClassProcs *, ClientData)); #endif /* * Copy of TkClassProcs declarations form tkInt.h * (this is needed for Tcl ver =< 8.4a3) */ typedef Window (TkClassCreateProc) _ANSI_ARGS_((Tk_Window tkwin, Window parent, ClientData instanceData)); typedef void (TkClassGeometryProc) _ANSI_ARGS_((ClientData instanceData)); typedef void (TkClassModalProc) _ANSI_ARGS_((Tk_Window tkwin, XEvent *eventPtr)); typedef struct TkClassProcs { TkClassCreateProc *createProc; TkClassGeometryProc *geometryProc; TkClassModalProc *modalProc; } TkClassProcs; /* Defaults */ #define DEFAULT_WIDTH "400" #define DEFAULT_HEIGHT "400" #define DEFAULT_IDENT "" #define DEFAULT_FONTNAME "fixed" #define DEFAULT_TIME "1" #ifdef TOGL_WGL /* Maximum size of a logical palette corresponding to a colormap in color index * mode. */ # define MAX_CI_COLORMAP_SIZE 4096 # if TOGL_USE_FONTS != 1 /* * copy of TkWinColormap from tkWinInt.h */ typedef struct { HPALETTE palette; /* Palette handle used when drawing. */ UINT size; /* Number of entries in the palette. */ int stale; /* 1 if palette needs to be realized, otherwise * 0. If the palette is stale, then an idle * handler is scheduled to realize the palette. */ Tcl_HashTable refCounts; /* Hash table of palette entry reference counts * indexed by pixel value. */ } TkWinColormap; # else # include "tkWinInt.h" # endif static LRESULT(CALLBACK *tkWinChildProc) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) = NULL; # define TK_WIN_CHILD_CLASS_NAME "TkChild" #endif /* TOGL_WGL */ #define MAX(a,b) (((a)>(b))?(a):(b)) #define TCL_ERR(interp, string) \ do { \ Tcl_ResetResult(interp); \ Tcl_AppendResult(interp, string, NULL); \ return TCL_ERROR; \ } while (0) /* The constant DUMMY_WINDOW is used to signal window creation failure from the * Togl_CreateWindow() */ #define DUMMY_WINDOW ((Window) -1) #define ALL_EVENTS_MASK \ (KeyPressMask | \ KeyReleaseMask | \ ButtonPressMask | \ ButtonReleaseMask | \ EnterWindowMask | \ LeaveWindowMask | \ PointerMotionMask | \ ExposureMask | \ VisibilityChangeMask | \ FocusChangeMask | \ PropertyChangeMask | \ ColormapChangeMask) struct Togl { Togl *Next; /* next in linked list */ #if defined(TOGL_WGL) HDC tglGLHdc; /* Device context of device that OpenGL calls * will be drawn on */ HGLRC tglGLHglrc; /* OpenGL rendering context to be made current */ int CiColormapSize; /* (Maximum) size of colormap in color index * mode */ #elif defined(TOGL_X11) GLXContext GlCtx; /* Normal planes GLX context */ #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) AGLContext aglCtx; #endif /* TOGL_WGL */ Display *display; /* X's token for the window's display. */ Tk_Window TkWin; /* Tk window structure */ Tcl_Interp *Interp; /* Tcl interpreter */ Tcl_Command widgetCmd; /* Token for togl's widget command */ #ifndef NO_TK_CURSOR Tk_Cursor Cursor; /* The widget's cursor */ #endif int Width, Height; /* Dimensions of window */ int SetGrid; /* positive is grid size for window manager */ int TimerInterval; /* Time interval for timer in milliseconds */ #if (TCL_MAJOR_VERSION * 100 + TCL_MINOR_VERSION) >= 705 Tcl_TimerToken timerHandler; /* Token for togl's timer handler */ #else Tk_TimerToken timerHandler; /* Token for togl's timer handler */ #endif Bool RgbaFlag; /* configuration flags (ala GLX parameters) */ int RgbaRed; int RgbaGreen; int RgbaBlue; Bool DoubleFlag; Bool DepthFlag; int DepthSize; Bool AccumFlag; int AccumRed; int AccumGreen; int AccumBlue; int AccumAlpha; Bool AlphaFlag; int AlphaSize; Bool StencilFlag; int StencilSize; Bool PrivateCmapFlag; Bool OverlayFlag; Bool StereoFlag; #ifdef __sgi Bool OldStereoFlag; #endif int AuxNumber; Bool Indirect; int PixelFormat; const char *ShareList; /* name (ident) of Togl to share dlists with */ const char *ShareContext; /* name (ident) to share OpenGL context with */ const char *Ident; /* User's identification string */ ClientData Client_Data; /* Pointer to user data */ Bool UpdatePending; /* Should normal planes be redrawn? */ Togl_Callback *CreateProc; /* Callback when widget is created */ Togl_Callback *DisplayProc; /* Callback when widget is rendered */ Togl_Callback *ReshapeProc; /* Callback when window size changes */ Togl_Callback *DestroyProc; /* Callback when widget is destroyed */ Togl_Callback *TimerProc; /* Callback when widget is idle */ /* Overlay stuff */ #if defined(TOGL_X11) GLXContext OverlayCtx; /* Overlay planes OpenGL context */ #elif defined(TOGL_WGL) HGLRC tglGLOverlayHglrc; #endif /* TOGL_X11 */ Window OverlayWindow; /* The overlay window, or 0 */ Togl_Callback *OverlayDisplayProc; /* Overlay redraw proc */ Bool OverlayUpdatePending; /* Should overlay be redrawn? */ Colormap OverlayCmap; /* colormap for overlay is created */ int OverlayTransparentPixel; /* transparent pixel */ Bool OverlayIsMapped; /* for DumpToEpsFile: Added by Miguel A. de Riera Pasenau 10.01.1997 */ XVisualInfo *VisInfo; /* Visual info of the current */ /* context needed for DumpToEpsFile */ GLfloat *EpsRedMap; /* Index2RGB Maps for Color index modes */ GLfloat *EpsGreenMap; GLfloat *EpsBlueMap; GLint EpsMapSize; /* = Number of indices in our Togl */ }; /* NTNTNT need to change to handle Windows Data Types */ /* * Prototypes for functions local to this file */ static int Togl_Cmd(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char **argv); static void Togl_EventProc(ClientData clientData, XEvent *eventPtr); static Window Togl_CreateWindow(Tk_Window, Window, ClientData); static void Togl_WorldChanged(ClientData); #ifdef MESA_COLOR_HACK static int get_free_color_cells(Display *display, int screen, Colormap colormap); static void free_default_color_cells(Display *display, Colormap colormap); #endif static void ToglCmdDeletedProc(ClientData); #if defined(__sgi) /* SGI-only stereo */ static void oldStereoMakeCurrent(Display *dpy, Window win, GLXContext ctx); static void oldStereoInit(Togl *togl, int stereoEnabled); #endif #if defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) static void SetMacBufRect(Togl *togl); #endif /* * Setup Togl widget configuration options: */ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_PIXELS, TCL_STUPID "-height", "height", "Height", DEFAULT_HEIGHT, Tk_Offset(Togl, Height), 0, NULL}, {TK_CONFIG_PIXELS, TCL_STUPID "-width", "width", "Width", DEFAULT_WIDTH, Tk_Offset(Togl, Width), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-setgrid", "setGrid", "SetGrid", "0", Tk_Offset(Togl, SetGrid), 0}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-rgba", "rgba", "Rgba", "true", Tk_Offset(Togl, RgbaFlag), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-redsize", "redsize", "RedSize", "1", Tk_Offset(Togl, RgbaRed), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-greensize", "greensize", "GreenSize", "1", Tk_Offset(Togl, RgbaGreen), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-bluesize", "bluesize", "BlueSize", "1", Tk_Offset(Togl, RgbaBlue), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-double", "double", "Double", "false", Tk_Offset(Togl, DoubleFlag), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-depth", "depth", "Depth", "false", Tk_Offset(Togl, DepthFlag), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-depthsize", "depthsize", "DepthSize", "1", Tk_Offset(Togl, DepthSize), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-accum", "accum", "Accum", "false", Tk_Offset(Togl, AccumFlag), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-accumredsize", "accumredsize", "AccumRedSize", "1", Tk_Offset(Togl, AccumRed), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-accumgreensize", "accumgreensize", "AccumGreenSize", "1", Tk_Offset(Togl, AccumGreen), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-accumbluesize", "accumbluesize", "AccumBlueSize", "1", Tk_Offset(Togl, AccumBlue), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-accumalphasize", "accumalphasize", "AccumAlphaSize", "1", Tk_Offset(Togl, AccumAlpha), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-alpha", "alpha", "Alpha", "false", Tk_Offset(Togl, AlphaFlag), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-alphasize", "alphasize", "AlphaSize", "1", Tk_Offset(Togl, AlphaSize), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-stencil", "stencil", "Stencil", "false", Tk_Offset(Togl, StencilFlag), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-stencilsize", "stencilsize", "StencilSize", "1", Tk_Offset(Togl, StencilSize), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-auxbuffers", "auxbuffers", "AuxBuffers", "0", Tk_Offset(Togl, AuxNumber), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-privatecmap", "privateCmap", "PrivateCmap", "false", Tk_Offset(Togl, PrivateCmapFlag), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-overlay", "overlay", "Overlay", "false", Tk_Offset(Togl, OverlayFlag), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-stereo", "stereo", "Stereo", "false", Tk_Offset(Togl, StereoFlag), 0, NULL}, #ifdef __sgi {TK_CONFIG_BOOLEAN, TCL_STUPID "-oldstereo", "oldstereo", "OldStereo", "false", Tk_Offset(Togl, OldStereoFlag), 0, NULL}, #endif #ifndef NO_TK_CURSOR {TK_CONFIG_ACTIVE_CURSOR, TCL_STUPID "-cursor", "cursor", "Cursor", "", Tk_Offset(Togl, Cursor), TK_CONFIG_NULL_OK}, #endif {TK_CONFIG_INT, TCL_STUPID "-time", "time", "Time", DEFAULT_TIME, Tk_Offset(Togl, TimerInterval), 0, NULL}, {TK_CONFIG_STRING, TCL_STUPID "-sharelist", "sharelist", "ShareList", NULL, Tk_Offset(Togl, ShareList), 0, NULL}, {TK_CONFIG_STRING, TCL_STUPID "-sharecontext", "sharecontext", "ShareContext", NULL, Tk_Offset(Togl, ShareContext), 0, NULL}, {TK_CONFIG_STRING, TCL_STUPID "-ident", "ident", "Ident", DEFAULT_IDENT, Tk_Offset(Togl, Ident), 0, NULL}, {TK_CONFIG_BOOLEAN, TCL_STUPID "-indirect", "indirect", "Indirect", "false", Tk_Offset(Togl, Indirect), 0, NULL}, {TK_CONFIG_INT, TCL_STUPID "-pixelformat", "pixelFormat", "PixelFormat", "0", Tk_Offset(Togl, PixelFormat), 0, NULL}, {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* * Default callback pointers. When a new Togl widget is created it * will be assigned these initial callbacks. */ static Togl_Callback *DefaultCreateProc = NULL; static Togl_Callback *DefaultDisplayProc = NULL; static Togl_Callback *DefaultReshapeProc = NULL; static Togl_Callback *DefaultDestroyProc = NULL; static Togl_Callback *DefaultOverlayDisplayProc = NULL; static Togl_Callback *DefaultTimerProc = NULL; static ClientData DefaultClientData = NULL; static Tcl_HashTable CommandTable; /* * Head of linked list of all Togl widgets */ static Togl *ToglHead = NULL; /* * Add given togl widget to linked list. */ static void AddToList(Togl *t) { t->Next = ToglHead; ToglHead = t; } /* * Remove given togl widget from linked list. */ static void RemoveFromList(Togl *t) { Togl *prev = NULL; Togl *pos = ToglHead; while (pos) { if (pos == t) { if (prev) { prev->Next = pos->Next; } else { ToglHead = pos->Next; } return; } prev = pos; pos = pos->Next; } } /* * Return pointer to togl widget given a user identifier string. */ static Togl * FindTogl(const char *ident) { Togl *t = ToglHead; while (t) { if (strcmp(t->Ident, ident) == 0) return t; t = t->Next; } return NULL; } #if defined(TOGL_X11) /* * Return pointer to another togl widget with same OpenGL context. */ static Togl * FindToglWithSameContext(Togl *togl) { Togl *t; for (t = ToglHead; t != NULL; t = t->Next) { if (t == togl) continue; # if defined(TOGL_WGL) if (t->tglGLHglrc == togl->tglGLHglrc) # elif defined(TOGL_X11) if (t->GlCtx == togl->GlCtx) # elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) if (t->aglCtx == togl->aglCtx) # endif return t; } return NULL; } #endif #ifdef USE_OVERLAY /* * Return pointer to another togl widget with same OpenGL overlay context. */ static Togl * FindToglWithSameOverlayContext(Togl *togl) { Togl *t; for (t = ToglHead; t != NULL; t = t->Next) { if (t == togl) continue; # if defined(TOGL_X11) if (t->OverlayCtx == togl->OverlayCtx) # elif defined(TOGL_WGL) if (t->tglGLOverlayHglrc == togl->tglGLOverlayHglrc) # endif return t; } return NULL; } #endif #if defined(TOGL_X11) /* * Return an X colormap to use for OpenGL RGB-mode rendering. * Input: dpy - the X display * scrnum - the X screen number * visinfo - the XVisualInfo as returned by glXChooseVisual() * Return: an X Colormap or 0 if there's a _serious_ error. */ static Colormap get_rgb_colormap(Display *dpy, int scrnum, const XVisualInfo *visinfo, Tk_Window tkwin) { Atom hp_cr_maps; Status status; int numCmaps; int i; XStandardColormap *standardCmaps; Window root = XRootWindow(dpy, scrnum); Bool using_mesa; /* * First check if visinfo's visual matches the default/root visual. */ if (visinfo->visual == Tk_Visual(tkwin)) { /* use the default/root colormap */ Colormap cmap; cmap = Tk_Colormap(tkwin); # ifdef MESA_COLOR_HACK (void) get_free_color_cells(dpy, scrnum, cmap); # endif return cmap; } /* * Check if we're using Mesa. */ if (strstr(glXQueryServerString(dpy, scrnum, GLX_VERSION), "Mesa")) { using_mesa = True; } else { using_mesa = False; } /* * Next, if we're using Mesa and displaying on an HP with the "Color * Recovery" feature and the visual is 8-bit TrueColor, search for a * special colormap initialized for dithering. Mesa will know how to * dither using this colormap. */ if (using_mesa) { hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True); if (hp_cr_maps # ifdef __cplusplus && visinfo->visual->c_class == TrueColor # else && visinfo->visual->class == TrueColor # endif && visinfo->depth == 8) { status = XGetRGBColormaps(dpy, root, &standardCmaps, &numCmaps, hp_cr_maps); if (status) { for (i = 0; i < numCmaps; i++) { if (standardCmaps[i].visualid == visinfo->visual->visualid) { Colormap cmap = standardCmaps[i].colormap; (void) XFree(standardCmaps); return cmap; } } (void) XFree(standardCmaps); } } } /* * Next, try to find a standard X colormap. */ # if !HP && !SUN # ifndef SOLARIS_BUG status = XmuLookupStandardColormap(dpy, visinfo->screen, visinfo->visualid, visinfo->depth, XA_RGB_DEFAULT_MAP, /* replace */ False, /* retain */ True); if (status == 1) { status = XGetRGBColormaps(dpy, root, &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP); if (status == 1) { for (i = 0; i < numCmaps; i++) { if (standardCmaps[i].visualid == visinfo->visualid) { Colormap cmap = standardCmaps[i].colormap; (void) XFree(standardCmaps); return cmap; } } (void) XFree(standardCmaps); } } # endif # endif /* * If we get here, give up and just allocate a new colormap. */ return XCreateColormap(dpy, root, visinfo->visual, AllocNone); } #elif defined(TOGL_WGL) /* Code to create RGB palette is taken from the GENGL sample program of Win32 * SDK */ static unsigned char threeto8[8] = { 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377 }; static unsigned char twoto8[4] = { 0, 0x55, 0xaa, 0xff }; static unsigned char oneto8[2] = { 0, 255 }; static int defaultOverride[13] = { 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91 }; static PALETTEENTRY defaultPalEntry[20] = { {0, 0, 0, 0}, {0x80, 0, 0, 0}, {0, 0x80, 0, 0}, {0x80, 0x80, 0, 0}, {0, 0, 0x80, 0}, {0x80, 0, 0x80, 0}, {0, 0x80, 0x80, 0}, {0xC0, 0xC0, 0xC0, 0}, {192, 220, 192, 0}, {166, 202, 240, 0}, {255, 251, 240, 0}, {160, 160, 164, 0}, {0x80, 0x80, 0x80, 0}, {0xFF, 0, 0, 0}, {0, 0xFF, 0, 0}, {0xFF, 0xFF, 0, 0}, {0, 0, 0xFF, 0}, {0xFF, 0, 0xFF, 0}, {0, 0xFF, 0xFF, 0}, {0xFF, 0xFF, 0xFF, 0} }; static unsigned char ComponentFromIndex(int i, UINT nbits, UINT shift) { unsigned char val; val = (unsigned char) (i >> shift); switch (nbits) { case 1: val &= 0x1; return oneto8[val]; case 2: val &= 0x3; return twoto8[val]; case 3: val &= 0x7; return threeto8[val]; default: return 0; } } static Colormap Win32CreateRgbColormap(PIXELFORMATDESCRIPTOR pfd) { TkWinColormap *cmap = (TkWinColormap *) ckalloc(sizeof (TkWinColormap)); LOGPALETTE *pPal; int n, i; n = 1 << pfd.cColorBits; pPal = (PLOGPALETTE) LocalAlloc(LMEM_FIXED, sizeof (LOGPALETTE) + n * sizeof (PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = n; for (i = 0; i < n; i++) { pPal->palPalEntry[i].peRed = ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift); pPal->palPalEntry[i].peGreen = ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift); pPal->palPalEntry[i].peBlue = ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift); pPal->palPalEntry[i].peFlags = 0; } /* fix up the palette to include the default GDI palette */ if ((pfd.cColorBits == 8) && (pfd.cRedBits == 3) && (pfd.cRedShift == 0) && (pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) && (pfd.cBlueBits == 2) && (pfd.cBlueShift == 6)) { for (i = 1; i <= 12; i++) pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i]; } cmap->palette = CreatePalette(pPal); LocalFree(pPal); cmap->size = n; cmap->stale = 0; /* Since this is a private colormap of a fix size, we do not need a valid * hash table, but a dummy one */ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS); return (Colormap) cmap; } static Colormap Win32CreateCiColormap(Togl *togl) { /* Create a colormap with size of togl->CiColormapSize and set all entries * to black */ LOGPALETTE logPalette; TkWinColormap *cmap = (TkWinColormap *) ckalloc(sizeof (TkWinColormap)); logPalette.palVersion = 0x300; logPalette.palNumEntries = 1; logPalette.palPalEntry[0].peRed = 0; logPalette.palPalEntry[0].peGreen = 0; logPalette.palPalEntry[0].peBlue = 0; logPalette.palPalEntry[0].peFlags = 0; cmap->palette = CreatePalette(&logPalette); cmap->size = togl->CiColormapSize; ResizePalette(cmap->palette, cmap->size); /* sets new entries to black */ cmap->stale = 0; /* Since this is a private colormap of a fix size, we do not need a valid * hash table, but a dummy one */ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS); return (Colormap) cmap; } #endif /* TOGL_X11 */ /* * Togl_Init * * Called upon system startup to create Togl command. */ int Togl_Init(Tcl_Interp *interp) { int major, minor, patchLevel, releaseType; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif #ifdef USE_TK_STUBS if (Tk_InitStubs(interp, TCL_STUPID "8.1", 0) == NULL) { return TCL_ERROR; } #endif /* Skip all this on Tcl/Tk 8.0 or older. Seems to work */ #if TCL_MAJOR_VERSION * 100 + TCL_MINOR_VERSION > 800 Tcl_GetVersion(&major, &minor, &patchLevel, &releaseType); # ifdef HAVE_TK_SETCLASSPROCS if (major > 8 || (major == 8 && (minor > 4 || (minor == 4 && (releaseType > 0 || patchLevel >= 2))))) { # ifdef USE_TK_STUBS SetClassProcsPtr = tkStubsPtr->tk_SetClassProcs; # else SetClassProcsPtr = Tk_SetClassProcs; # endif } else { SetClassProcsPtr = NULL; } # else if (major > 8 || (major == 8 && (minor > 4 || (minor == 4 && (releaseType > 0 || patchLevel >= 2))))) { TCL_ERR(interp, "Sorry, this instance of Togl was not compiled to work with Tcl/Tk 8.4a2 or higher."); } # endif #endif if (Tcl_PkgProvide(interp, "Togl", TOGL_VERSION) != TCL_OK) { return TCL_ERROR; } if (Tcl_CreateCommand(interp, "togl", Togl_Cmd, (ClientData) Tk_MainWindow(interp), NULL) == NULL) return TCL_ERROR; Tcl_InitHashTable(&CommandTable, TCL_STRING_KEYS); return TCL_OK; } /* * Register a C function to be called when an Togl widget is realized. */ void Togl_CreateFunc(Togl_Callback *proc) { DefaultCreateProc = proc; } /* * Register a C function to be called when an Togl widget must be redrawn. */ void Togl_DisplayFunc(Togl_Callback *proc) { DefaultDisplayProc = proc; } /* * Register a C function to be called when an Togl widget is resized. */ void Togl_ReshapeFunc(Togl_Callback *proc) { DefaultReshapeProc = proc; } /* * Register a C function to be called when an Togl widget is destroyed. */ void Togl_DestroyFunc(Togl_Callback *proc) { DefaultDestroyProc = proc; } /* * Register a C function to be called from TimerEventHandler. */ void Togl_TimerFunc(Togl_Callback *proc) { DefaultTimerProc = proc; } /* * Reset default callback pointers to NULL. */ void Togl_ResetDefaultCallbacks(void) { DefaultCreateProc = NULL; DefaultDisplayProc = NULL; DefaultReshapeProc = NULL; DefaultDestroyProc = NULL; DefaultOverlayDisplayProc = NULL; DefaultTimerProc = NULL; DefaultClientData = NULL; } /* * Chnage the create callback for a specific Togl widget. */ void Togl_SetCreateFunc(Togl *togl, Togl_Callback *proc) { togl->CreateProc = proc; } /* * Change the display/redraw callback for a specific Togl widget. */ void Togl_SetDisplayFunc(Togl *togl, Togl_Callback *proc) { togl->DisplayProc = proc; } /* * Change the reshape callback for a specific Togl widget. */ void Togl_SetReshapeFunc(Togl *togl, Togl_Callback *proc) { togl->ReshapeProc = proc; } /* * Change the destroy callback for a specific Togl widget. */ void Togl_SetDestroyFunc(Togl *togl, Togl_Callback *proc) { togl->DestroyProc = proc; } /* * Togl_Timer * * Gets called from Tk_CreateTimerHandler. */ static void Togl_Timer(ClientData clientData) { Togl *togl = (Togl *) clientData; if (togl->TimerProc) { togl->TimerProc(togl); /* Re-register this callback since Tcl/Tk timers are "one-shot". That * is, after the timer callback is called it not normally called again. * * * * * * * * * That's not the behavior we want for Togl. */ #if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401 togl->timerHandler = Tcl_CreateTimerHandler(togl->TimerInterval, Togl_Timer, (ClientData) togl); #else togl->timerHandler = Tk_CreateTimerHandler(togl->TimeInterval, Togl_Timer, (ClientData) togl); #endif } } /* * Change the timer callback for a specific Togl widget. * Pass NULL to disable the callback. */ void Togl_SetTimerFunc(Togl *togl, Togl_Callback *proc) { togl->TimerProc = proc; if (proc) { #if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401 togl->timerHandler = Tcl_CreateTimerHandler(togl->TimerInterval, Togl_Timer, (ClientData) togl); #else togl->timerHandler = Tk_CreateTimerHandler(togl->TimeInterval, Togl_Timer, (ClientData) togl); #endif } } /* * Togl_CreateCommand * * Declares a new C sub-command of Togl callable from Tcl. * Every time the sub-command is called from Tcl, the * C routine will be called with all the arguments from Tcl. */ void Togl_CreateCommand(char *cmd_name, Togl_CmdProc *cmd_proc) { int new_item; Tcl_HashEntry *entry; entry = Tcl_CreateHashEntry(&CommandTable, cmd_name, &new_item); Tcl_SetHashValue(entry, cmd_proc); } /* * Togl_MakeCurrent * * Bind the OpenGL rendering context to the specified * Togl widget. */ void Togl_MakeCurrent(const Togl *togl) { #if defined(TOGL_WGL) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLHglrc); assert(res == TRUE); #elif defined(TOGL_X11) if (!togl->GlCtx) return; (void) glXMakeCurrent(togl->display, togl->TkWin ? Tk_WindowId(togl->TkWin) : None, togl->GlCtx); # if defined(__sgi) if (togl->OldStereoFlag) oldStereoMakeCurrent(togl->display, togl->TkWin ? Tk_WindowId(togl->TkWin) : None, togl->GlCtx); # endif /*__sgi STEREO */ #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) if (!togl->aglCtx) return; aglSetCurrentContext(togl->aglCtx); #endif } #ifdef TOGL_AGL_CLASSIC /* tell OpenGL which part of the Mac window to render to */ static void SetMacBufRect(Togl *togl) { GLint wrect[4]; /* set wrect[0,1] to lower left corner of widget */ wrect[2] = ((TkWindow *) (togl->TkWin))->changes.width; wrect[3] = ((TkWindow *) (togl->TkWin))->changes.height; wrect[0] = ((TkWindow *) (togl->TkWin))->privatePtr->xOff; wrect[1] = ((TkWindow *) (togl->TkWin))->privatePtr->toplevel->portPtr-> portRect.bottom - wrect[3] - ((TkWindow *) (togl->TkWin))->privatePtr->yOff; aglSetInteger(togl->aglCtx, AGL_BUFFER_RECT, wrect); aglEnable(togl->aglCtx, AGL_BUFFER_RECT); aglUpdateContext(togl->aglCtx); } #elif defined(TOGL_AGL) /* tell OpenGL which part of the Mac window to render to */ static void SetMacBufRect(Togl *togl) { GLint wrect[4]; /* set wrect[0,1] to lower left corner of widget */ wrect[2] = Tk_Width(togl->TkWin); wrect[3] = Tk_Height(togl->TkWin); wrect[0] = ((TkWindow *) (togl->TkWin))->privatePtr->xOff; Rect r; GetPortBounds(((TkWindow *) (togl->TkWin))->privatePtr->toplevel->grafPtr, &r); wrect[1] = r.bottom - wrect[3] - ((TkWindow *) (togl->TkWin))->privatePtr->yOff; aglSetInteger(togl->aglCtx, AGL_BUFFER_RECT, wrect); aglEnable(togl->aglCtx, AGL_BUFFER_RECT); aglUpdateContext(togl->aglCtx); } #endif /* * Called when the widget's contents must be redrawn. Basically, we * just call the user's render callback function. * * Note that the parameter type is ClientData so this function can be * passed to Tk_DoWhenIdle(). */ static void Togl_Render(ClientData clientData) { Togl *togl = (Togl *) clientData; if (togl->DisplayProc) { #ifdef TOGL_AGL_CLASSIC /* Mac is complicated here because OpenGL needs to know what part of * the parent window to render into, and it seems that region need to * be invalidated before drawing, so that QuickDraw will allow OpenGL * to transfer pixels into that part of the window. I'm not even * totally sure how or why this works as it does, since this aspect of * Mac OpenGL seems to be totally undocumented. This was put together * by trial and error! (thiessen) */ MacRegion r; RgnPtr rp = &r; GrafPtr curPort, parentWin; parentWin = (GrafPtr) (((MacDrawable *) (Tk_WindowId(togl->TkWin)))->toplevel-> portPtr); if (!parentWin) return; #endif Togl_MakeCurrent(togl); #ifdef TOGL_AGL_CLASSIC /* Set QuickDraw port and clipping region */ GetPort(&curPort); SetPort(parentWin); r.rgnBBox.left = ((TkWindow *) (togl->TkWin))->privatePtr->xOff; r.rgnBBox.right = r.rgnBBox.left + ((TkWindow *) (togl->TkWin))->changes.width - 1; r.rgnBBox.top = ((TkWindow *) (togl->TkWin))->privatePtr->yOff; r.rgnBBox.bottom = r.rgnBBox.top + ((TkWindow *) (togl->TkWin))->changes.height - 1; r.rgnSize = sizeof (Region); InvalRgn(&rp); SetClip(&rp); /* this may seem an odd place to put this, with possibly redundant * calls to aglSetInteger(AGL_BUFFER_RECT...), but for some reason * performance is actually a lot better if this is called before every * render... */ SetMacBufRect(togl); #endif #ifdef TOGL_AGL SetMacBufRect(togl); #endif togl->DisplayProc(togl); #ifdef TOGL_AGL_CLASSIC SetPort(curPort); /* restore previous port */ #endif } #if defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) else { /* Always need to update on resize */ SetMacBufRect(togl); } #endif togl->UpdatePending = False; } static void RenderOverlay(ClientData clientData) { Togl *togl = (Togl *) clientData; if (togl->OverlayFlag && togl->OverlayDisplayProc) { #if defined(TOGL_WGL) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLHglrc); assert(res == TRUE); #elif defined(TOGL_X11) (void) glXMakeCurrent(Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx); # if defined(__sgi) if (togl->OldStereoFlag) oldStereoMakeCurrent(Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx); # endif /*__sgi STEREO */ #endif /* TOGL_WGL */ togl->OverlayDisplayProc(togl); } togl->OverlayUpdatePending = False; } /* * It's possible to change with this function or in a script some * options like RGBA - ColorIndex ; Z-buffer and so on */ int Togl_Configure(Tcl_Interp *interp, Togl *togl, int argc, const char *argv[], int flags) { Bool oldRgbaFlag = togl->RgbaFlag; int oldRgbaRed = togl->RgbaRed; int oldRgbaGreen = togl->RgbaGreen; int oldRgbaBlue = togl->RgbaBlue; Bool oldDoubleFlag = togl->DoubleFlag; Bool oldDepthFlag = togl->DepthFlag; int oldDepthSize = togl->DepthSize; Bool oldAccumFlag = togl->AccumFlag; int oldAccumRed = togl->AccumRed; int oldAccumGreen = togl->AccumGreen; int oldAccumBlue = togl->AccumBlue; int oldAccumAlpha = togl->AccumAlpha; Bool oldAlphaFlag = togl->AlphaFlag; int oldAlphaSize = togl->AlphaSize; Bool oldStencilFlag = togl->StencilFlag; int oldStencilSize = togl->StencilSize; int oldAuxNumber = togl->AuxNumber; int oldWidth = togl->Width; int oldHeight = togl->Height; int oldSetGrid = togl->SetGrid; if (Tk_ConfigureWidget(interp, togl->TkWin, configSpecs, argc, argv, WIDGREC togl, flags) == TCL_ERROR) { return (TCL_ERROR); } #ifndef USE_OVERLAY if (togl->OverlayFlag) { TCL_ERR(interp, "Sorry, overlay was disabled"); } #endif if (togl->Width != oldWidth || togl->Height != oldHeight || togl->SetGrid != oldSetGrid) { Togl_WorldChanged((ClientData) togl); /* this added per Lou Arata */ Tk_ResizeWindow(togl->TkWin, togl->Width, togl->Height); if (togl->ReshapeProc && #if defined(TOGL_WGL) togl->tglGLHglrc #elif defined(TOGL_X11) togl->GlCtx #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) togl->aglCtx #endif ) { Togl_MakeCurrent(togl); togl->ReshapeProc(togl); } } if (togl->RgbaFlag != oldRgbaFlag || togl->RgbaRed != oldRgbaRed || togl->RgbaGreen != oldRgbaGreen || togl->RgbaBlue != oldRgbaBlue || togl->DoubleFlag != oldDoubleFlag || togl->DepthFlag != oldDepthFlag || togl->DepthSize != oldDepthSize || togl->AccumFlag != oldAccumFlag || togl->AccumRed != oldAccumRed || togl->AccumGreen != oldAccumGreen || togl->AccumBlue != oldAccumBlue || togl->AccumAlpha != oldAccumAlpha || togl->AlphaFlag != oldAlphaFlag || togl->AlphaSize != oldAlphaSize || togl->StencilFlag != oldStencilFlag || togl->StencilSize != oldStencilSize || togl->AuxNumber != oldAuxNumber) { #ifdef MESA_COLOR_HACK free_default_color_cells(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin)); #endif } #if defined(__sgi) oldStereoInit(togl, togl->OldStereoFlag); #endif return TCL_OK; } static int Togl_Widget(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { Togl *togl = (Togl *) clientData; int result = TCL_OK; Tcl_HashEntry *entry; Tcl_HashSearch search; Togl_CmdProc *cmd_proc; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ?options?\"", NULL); return TCL_ERROR; } Tk_Preserve((ClientData) togl); if (!strncmp(argv[1], "configure", MAX(1, strlen(argv[1])))) { if (argc == 2) { /* Return list of all configuration parameters */ result = Tk_ConfigureInfo(interp, togl->TkWin, configSpecs, WIDGREC togl, (char *) NULL, 0); } else if (argc == 3) { if (strcmp(argv[2], "-extensions") == 0) { /* Return a list of OpenGL extensions available */ const char *extensions; extensions = (const char *) glGetString(GL_EXTENSIONS); Tcl_SetResult(interp, TCL_STUPID extensions, TCL_STATIC); result = TCL_OK; } else { /* Return a specific configuration parameter */ result = Tk_ConfigureInfo(interp, togl->TkWin, configSpecs, WIDGREC togl, argv[2], 0); } } else { /* Execute a configuration change */ result = Togl_Configure(interp, togl, argc - 2, argv + 2, TK_CONFIG_ARGV_ONLY); } } else if (!strncmp(argv[1], "render", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_Render((ClientData) togl); } else if (!strncmp(argv[1], "swapbuffers", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_SwapBuffers(togl); } else if (!strncmp(argv[1], "makecurrent", MAX(1, strlen(argv[1])))) { /* force the widget to be redrawn */ Togl_MakeCurrent(togl); } #if TOGL_USE_FONTS == 1 else if (!strncmp(argv[1], "loadbitmapfont", MAX(1, strlen(argv[1])))) { if (argc == 3) { GLuint fontbase; Tcl_Obj *fontbaseAsTclObject; fontbase = Togl_LoadBitmapFont(togl, argv[2]); if (fontbase) { fontbaseAsTclObject = Tcl_NewIntObj(fontbase); Tcl_SetObjResult(interp, fontbaseAsTclObject); result = TCL_OK; } else { Tcl_AppendResult(interp, "Could not allocate font", NULL); result = TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args", NULL); result = TCL_ERROR; } } else if (!strncmp(argv[1], "unloadbitmapfont", MAX(1, strlen(argv[1])))) { if (argc == 3) { Togl_UnloadBitmapFont(togl, atoi(argv[2])); result = TCL_OK; } else { Tcl_AppendResult(interp, "wrong # args", NULL); result = TCL_ERROR; } } #endif /* TOGL_USE_FONTS */ else { /* Probably a user-defined function */ entry = Tcl_FindHashEntry(&CommandTable, argv[1]); if (entry != NULL) { cmd_proc = (Togl_CmdProc *) Tcl_GetHashValue(entry); result = cmd_proc(togl, argc, argv); } else { Tcl_AppendResult(interp, "Togl: Unknown option: ", argv[1], "\n", "Try: configure or render\n", "or one of the user-defined commands:\n", NULL); entry = Tcl_FirstHashEntry(&CommandTable, &search); while (entry) { Tcl_AppendResult(interp, " ", Tcl_GetHashKey(&CommandTable, entry), "\n", NULL); entry = Tcl_NextHashEntry(&search); } result = TCL_ERROR; } } Tk_Release((ClientData) togl); return result; } /* * Togl_Cmd * * Called when Togl is executed - creation of a Togl widget. * * Creates a new window * * Creates an 'Togl' data structure * * Creates an event handler for this window * * Creates a command that handles this object * * Configures this Togl for the given arguments */ static int Togl_Cmd(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char **argv) { const char *name; Tk_Window mainwin = (Tk_Window) clientData; Tk_Window tkwin; Togl *togl; if (argc <= 1) { TCL_ERR(interp, "wrong # args: should be \"pathName read filename\""); } /* Create the window. */ name = argv[1]; tkwin = Tk_CreateWindowFromPath(interp, mainwin, name, (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } Tk_SetClass(tkwin, "Togl"); /* Create Togl data structure */ togl = (Togl *) malloc(sizeof (Togl)); if (!togl) { return TCL_ERROR; } togl->Next = NULL; #if defined(TOGL_WGL) togl->tglGLHdc = NULL; togl->tglGLHglrc = NULL; #elif defined(TOGL_X11) togl->GlCtx = NULL; togl->OverlayCtx = NULL; #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) togl->aglCtx = NULL; #endif /* TOGL_WGL */ togl->display = Tk_Display(tkwin); togl->TkWin = tkwin; togl->Interp = interp; #ifndef NO_TK_CURSOR togl->Cursor = None; #endif togl->Width = 0; togl->Height = 0; togl->SetGrid = 0; togl->TimerInterval = 0; togl->RgbaFlag = True; togl->RgbaRed = 1; togl->RgbaGreen = 1; togl->RgbaBlue = 1; togl->DoubleFlag = False; togl->DepthFlag = False; togl->DepthSize = 1; togl->AccumFlag = False; togl->AccumRed = 1; togl->AccumGreen = 1; togl->AccumBlue = 1; togl->AccumAlpha = 1; togl->AlphaFlag = False; togl->AlphaSize = 1; togl->StencilFlag = False; togl->StencilSize = 1; togl->OverlayFlag = False; togl->StereoFlag = False; #ifdef __sgi togl->OldStereoFlag = False; #endif togl->AuxNumber = 0; togl->Indirect = False; togl->PixelFormat = 0; togl->UpdatePending = False; togl->OverlayUpdatePending = False; togl->CreateProc = DefaultCreateProc; togl->DisplayProc = DefaultDisplayProc; togl->ReshapeProc = DefaultReshapeProc; togl->DestroyProc = DefaultDestroyProc; togl->TimerProc = DefaultTimerProc; togl->OverlayDisplayProc = DefaultOverlayDisplayProc; togl->ShareList = NULL; togl->ShareContext = NULL; togl->Ident = NULL; togl->Client_Data = DefaultClientData; /* for EPS Output */ togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0; /* Create command event handler */ togl->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(tkwin), Togl_Widget, (ClientData) togl, (Tcl_CmdDeleteProc *) ToglCmdDeletedProc); /* * Setup the Tk_ClassProcs callbacks to point at our own window creation * function * * We need to check at runtime if we should use the new Tk_SetClassProcs() * API or if we need to modify the window structure directly */ #ifdef HAVE_TK_SETCLASSPROCS if (SetClassProcsPtr != NULL) { /* use public API (Tk 8.4+) */ Tk_ClassProcs *procsPtr; procsPtr = (Tk_ClassProcs *) Tcl_Alloc(sizeof (Tk_ClassProcs)); procsPtr->size = sizeof (Tk_ClassProcs); procsPtr->createProc = Togl_CreateWindow; procsPtr->worldChangedProc = Togl_WorldChanged; procsPtr->modalProc = NULL; /* Tk_SetClassProcs(togl->TkWin,procsPtr,(ClientData)togl); */ (SetClassProcsPtr) (togl->TkWin, procsPtr, (ClientData) togl); } else #endif { /* use private API */ /* * We need to set these fields in the Tk_FakeWin structure: dummy17 = * classProcsPtr dummy18 = instanceData */ TkClassProcs *procsPtr; Tk_FakeWin *winPtr = (Tk_FakeWin *) (togl->TkWin); procsPtr = (TkClassProcs *) Tcl_Alloc(sizeof (TkClassProcs)); procsPtr->createProc = Togl_CreateWindow; procsPtr->geometryProc = Togl_WorldChanged; procsPtr->modalProc = NULL; winPtr->dummy17 = (char *) procsPtr; winPtr->dummy18 = (ClientData) togl; } Tk_CreateEventHandler(tkwin, ExposureMask | StructureNotifyMask, Togl_EventProc, (ClientData) togl); /* Configure Togl widget */ if (Togl_Configure(interp, togl, argc - 2, argv + 2, 0) == TCL_ERROR) { Tk_DestroyWindow(tkwin); Tcl_AppendResult(interp, "Couldn't configure togl widget\n", NULL); goto error; } /* * If OpenGL window wasn't already created by Togl_Configure() we * create it now. We can tell by checking if the GLX context has * been initialized. */ if (! #if defined(TOGL_WGL) togl->tglGLHdc #elif defined(TOGL_X11) togl->GlCtx #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) togl->aglCtx #endif ) { Tk_MakeWindowExist(togl->TkWin); if (Tk_WindowId(togl->TkWin) == DUMMY_WINDOW) { return TCL_ERROR; } Togl_MakeCurrent(togl); } /* If defined, call create callback */ if (togl->CreateProc) { togl->CreateProc(togl); } /* If defined, call reshape proc */ if (togl->ReshapeProc) { togl->ReshapeProc(togl); } /* If defined, setup timer */ if (togl->TimerProc) { (void) Tk_CreateTimerHandler(togl->TimerInterval, Togl_Timer, (ClientData) togl); } Tcl_AppendResult(interp, Tk_PathName(tkwin), NULL); /* Add to linked list */ AddToList(togl); return TCL_OK; error: (void) Tcl_DeleteCommand(interp, "togl"); /* free(togl); Don't free it, if we do a crash occurs later... */ return TCL_ERROR; } #ifdef USE_OVERLAY /* * Do all the setup for overlay planes * Return: TCL_OK or TCL_ERROR */ static int SetupOverlay(Togl *togl) { # if defined(TOGL_X11) # ifdef GLX_TRANSPARENT_TYPE_EXT static int ovAttributeList[] = { GLX_BUFFER_SIZE, 2, GLX_LEVEL, 1, GLX_TRANSPARENT_TYPE_EXT, GLX_TRANSPARENT_INDEX_EXT, None }; # else static int ovAttributeList[] = { GLX_BUFFER_SIZE, 2, GLX_LEVEL, 1, None }; # endif Display *dpy; XVisualInfo *visinfo; TkWindow *winPtr = (TkWindow *) togl->TkWin; XSetWindowAttributes swa; Tcl_HashEntry *hPtr; int new_flag; dpy = Tk_Display(togl->TkWin); visinfo = glXChooseVisual(dpy, Tk_ScreenNumber(winPtr), ovAttributeList); if (!visinfo) { Tcl_AppendResult(togl->Interp, Tk_PathName(winPtr), ": No suitable overlay index visual available", (char *) NULL); togl->OverlayCtx = 0; togl->OverlayWindow = 0; togl->OverlayCmap = 0; return TCL_ERROR; } # ifdef GLX_TRANSPARENT_INDEX_EXT { int fail = glXGetConfig(dpy, visinfo, GLX_TRANSPARENT_INDEX_VALUE_EXT, &togl->OverlayTransparentPixel); if (fail) togl->OverlayTransparentPixel = 0; /* maybe, maybe ... */ } # else togl->OverlayTransparentPixel = 0; /* maybe, maybe ... */ # endif /* share display lists with normal layer context */ togl->OverlayCtx = glXCreateContext(dpy, visinfo, togl->GlCtx, !togl->Indirect); swa.colormap = XCreateColormap(dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocNone); togl->OverlayCmap = swa.colormap; swa.border_pixel = 0; swa.event_mask = ALL_EVENTS_MASK; togl->OverlayWindow = XCreateWindow(dpy, Tk_WindowId(togl->TkWin), 0, 0, togl->Width, togl->Height, 0, visinfo->depth, InputOutput, visinfo->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable, (char *) togl->OverlayWindow, &new_flag); Tcl_SetHashValue(hPtr, winPtr); /* XMapWindow( dpy, togl->OverlayWindow ); */ togl->OverlayIsMapped = False; /* Make sure window manager installs our colormap */ XSetWMColormapWindows(dpy, togl->OverlayWindow, &togl->OverlayWindow, 1); return TCL_OK; # elif defined(TOGL_WGL) || defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) /* not yet implemented on these */ return TCL_ERROR; # endif } #endif /* USE_OVERLAY */ #ifdef TOGL_WGL # define TOGL_CLASS_NAME "Togl Class" static Bool ToglClassInitialized = False; static LRESULT CALLBACK Win32WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { LONG result; Togl *togl = (Togl *) GetWindowLong(hwnd, 0); WNDCLASS childClass; switch (message) { case WM_WINDOWPOSCHANGED: /* Should be processed by DefWindowProc, otherwise a double buffered * context is not properly resized when the corresponding window is * resized. */ break; case WM_DESTROY: if (togl->tglGLHglrc) { wglDeleteContext(togl->tglGLHglrc); } if (togl->tglGLHdc) { ReleaseDC(hwnd, togl->tglGLHdc); } free(togl); break; default: # if USE_STATIC_LIB return TkWinChildProc(hwnd, message, wParam, lParam); # else /* * OK, since TkWinChildProc is not explicitly exported in the * dynamic libraries, we have to retrieve it from the class info * registered with windows. * */ if (tkWinChildProc == NULL) { GetClassInfo(Tk_GetHINSTANCE(), TK_WIN_CHILD_CLASS_NAME, &childClass); tkWinChildProc = childClass.lpfnWndProc; } return tkWinChildProc(hwnd, message, wParam, lParam); # endif } result = DefWindowProc(hwnd, message, wParam, lParam); Tcl_ServiceAll(); return result; } #endif /* TOGL_WGL */ /* * Togl_CreateWindow * * Window creation function, invoked as a callback from Tk_MakeWindowExist. * Creates an OpenGL window for the Togl widget. */ static Window Togl_CreateWindow(Tk_Window tkwin, Window parent, ClientData instanceData) { Togl *togl = (Togl *) instanceData; XVisualInfo *visinfo = NULL; Display *dpy; Colormap cmap; int scrnum; Window window; #if defined(TOGL_X11) Bool directCtx = True; int attrib_list[1000]; int attrib_count; int dummy; XSetWindowAttributes swa; # define MAX_ATTEMPTS 12 static int ci_depths[MAX_ATTEMPTS] = { 8, 4, 2, 1, 12, 16, 8, 4, 2, 1, 12, 16 }; static int dbl_flags[MAX_ATTEMPTS] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; #elif defined(TOGL_WGL) HWND hwnd, parentWin; int pixelformat; HANDLE hInstance; WNDCLASS ToglClass; PIXELFORMATDESCRIPTOR pfd; XVisualInfo VisInf; #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) GLint attribs[20]; int na; AGLPixelFormat fmt; XVisualInfo VisInf; #endif /* TOGL_X11 */ dpy = Tk_Display(togl->TkWin); #if defined(TOGL_X11) /* Make sure OpenGL's GLX extension supported */ if (!glXQueryExtension(dpy, &dummy, &dummy)) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: X server has no OpenGL GLX extension", TCL_STATIC); return DUMMY_WINDOW; } if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith != NULL); assert(shareWith->GlCtx != NULL); togl->GlCtx = shareWith->GlCtx; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; } else { if (togl->PixelFormat) { XVisualInfo template; int count = 1; template.visualid = togl->PixelFormat; visinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &count); if (visinfo == NULL) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't choose pixel format", TCL_STATIC); return DUMMY_WINDOW; } /* fill in flags normally passed in that affect behavior */ (void) glXGetConfig(dpy, visinfo, GLX_RGBA, &togl->RgbaFlag); (void) glXGetConfig(dpy, visinfo, GLX_DOUBLEBUFFER, &togl->DoubleFlag); (void) glXGetConfig(dpy, visinfo, GLX_STEREO, &togl->StereoFlag); } else { int attempt; /* It may take a few tries to get a visual */ for (attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { attrib_count = 0; attrib_list[attrib_count++] = GLX_USE_GL; if (togl->RgbaFlag) { /* RGB[A] mode */ attrib_list[attrib_count++] = GLX_RGBA; attrib_list[attrib_count++] = GLX_RED_SIZE; attrib_list[attrib_count++] = togl->RgbaRed; attrib_list[attrib_count++] = GLX_GREEN_SIZE; attrib_list[attrib_count++] = togl->RgbaGreen; attrib_list[attrib_count++] = GLX_BLUE_SIZE; attrib_list[attrib_count++] = togl->RgbaBlue; if (togl->AlphaFlag) { attrib_list[attrib_count++] = GLX_ALPHA_SIZE; attrib_list[attrib_count++] = togl->AlphaSize; } /* for EPS Output */ if (togl->EpsRedMap) free(togl->EpsRedMap); if (togl->EpsGreenMap) free(togl->EpsGreenMap); if (togl->EpsBlueMap) free(togl->EpsBlueMap); togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0; } else { /* Color index mode */ int depth; attrib_list[attrib_count++] = GLX_BUFFER_SIZE; depth = ci_depths[attempt]; attrib_list[attrib_count++] = depth; } if (togl->DepthFlag) { attrib_list[attrib_count++] = GLX_DEPTH_SIZE; attrib_list[attrib_count++] = togl->DepthSize; } if (togl->DoubleFlag || dbl_flags[attempt]) { attrib_list[attrib_count++] = GLX_DOUBLEBUFFER; } if (togl->StencilFlag) { attrib_list[attrib_count++] = GLX_STENCIL_SIZE; attrib_list[attrib_count++] = togl->StencilSize; } if (togl->AccumFlag) { attrib_list[attrib_count++] = GLX_ACCUM_RED_SIZE; attrib_list[attrib_count++] = togl->AccumRed; attrib_list[attrib_count++] = GLX_ACCUM_GREEN_SIZE; attrib_list[attrib_count++] = togl->AccumGreen; attrib_list[attrib_count++] = GLX_ACCUM_BLUE_SIZE; attrib_list[attrib_count++] = togl->AccumBlue; if (togl->AlphaFlag) { attrib_list[attrib_count++] = GLX_ACCUM_ALPHA_SIZE; attrib_list[attrib_count++] = togl->AccumAlpha; } } if (togl->AuxNumber != 0) { attrib_list[attrib_count++] = GLX_AUX_BUFFERS; attrib_list[attrib_count++] = togl->AuxNumber; } if (togl->Indirect) { directCtx = False; } if (togl->StereoFlag) { attrib_list[attrib_count++] = GLX_STEREO; } attrib_list[attrib_count++] = None; visinfo = glXChooseVisual(dpy, Tk_ScreenNumber(togl->TkWin), attrib_list); if (visinfo) { /* found a GLX visual! */ break; } } togl->VisInfo = visinfo; if (visinfo == NULL) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't get visual", TCL_STATIC); return DUMMY_WINDOW; } /* * Create a new OpenGL rendering context. */ if (togl->ShareList) { /* share display lists with existing togl widget */ Togl *shareWith = FindTogl(togl->ShareList); GLXContext shareCtx; if (shareWith) shareCtx = shareWith->GlCtx; else shareCtx = None; togl->GlCtx = glXCreateContext(dpy, visinfo, shareCtx, directCtx); } else { /* don't share display lists */ togl->GlCtx = glXCreateContext(dpy, visinfo, None, directCtx); } if (togl->GlCtx == NULL) { Tcl_SetResult(togl->Interp, TCL_STUPID "could not create rendering context", TCL_STATIC); return DUMMY_WINDOW; } } } #endif /* TOGL_X11 */ #ifdef TOGL_WGL parentWin = Tk_GetHWND(parent); hInstance = Tk_GetHINSTANCE(); if (!ToglClassInitialized) { ToglClassInitialized = True; ToglClass.style = CS_HREDRAW | CS_VREDRAW; ToglClass.cbClsExtra = 0; ToglClass.cbWndExtra = 4; /* to save struct Togl* */ ToglClass.hInstance = hInstance; ToglClass.hbrBackground = NULL; ToglClass.lpszMenuName = NULL; ToglClass.lpszClassName = TOGL_CLASS_NAME; ToglClass.lpfnWndProc = Win32WinProc; ToglClass.hIcon = NULL; ToglClass.hCursor = NULL; if (!RegisterClass(&ToglClass)) { Tcl_SetResult(togl->Interp, TCL_STUPID "unable register Togl window class", TCL_STATIC); return DUMMY_WINDOW; } } hwnd = CreateWindow(TOGL_CLASS_NAME, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, togl->Width, togl->Height, parentWin, NULL, hInstance, NULL); SetWindowLong(hwnd, 0, (LONG) togl); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); togl->tglGLHdc = GetDC(hwnd); pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; if (togl->DoubleFlag) { pfd.dwFlags |= PFD_DOUBLEBUFFER; } /* The stereo flag is not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ if (togl->StereoFlag) { pfd.dwFlags |= PFD_STEREO; } if (togl->PixelFormat) { pixelformat = togl->PixelFormat; } else { pfd.cColorBits = togl->RgbaRed + togl->RgbaGreen + togl->RgbaBlue; pfd.iPixelType = togl->RgbaFlag ? PFD_TYPE_RGBA : PFD_TYPE_COLORINDEX; /* Alpha bitplanes are not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ pfd.cAlphaBits = togl->AlphaFlag ? togl->AlphaSize : 0; pfd.cAccumBits = togl->AccumFlag ? (togl->AccumRed + togl->AccumGreen + togl->AccumBlue + togl->AccumAlpha) : 0; pfd.cDepthBits = togl->DepthFlag ? togl->DepthSize : 0; pfd.cStencilBits = togl->StencilFlag ? togl->StencilSize : 0; /* Auxiliary buffers are not supported in the current generic OpenGL * implementation, but may be supported by specific hardware devices. */ pfd.cAuxBuffers = togl->AuxNumber; pfd.iLayerType = PFD_MAIN_PLANE; if ((pixelformat = ChoosePixelFormat(togl->tglGLHdc, &pfd)) == 0) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't choose pixel format", TCL_STATIC); return DUMMY_WINDOW; } } if (SetPixelFormat(togl->tglGLHdc, pixelformat, &pfd) == FALSE) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't choose pixel format", TCL_STATIC); return DUMMY_WINDOW; } /* Get the actual pixel format */ DescribePixelFormat(togl->tglGLHdc, pixelformat, sizeof (pfd), &pfd); if (togl->PixelFormat) { /* fill in flags normally passed in that affect behavior */ togl->RgbaFlag = pfd.iPixelType == PFD_TYPE_RGBA; togl->DoubleFlag = pfd.cDepthBits > 0; togl->StereoFlag = (pfd.dwFlags & PFD_STEREO) != 0; // TODO: set depth flag, and more } else if (togl->StereoFlag && (pfd.dwFlags & PFD_STEREO) == 0) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't choose stereo pixel format", TCL_STATIC); return DUMMY_WINDOW; } if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith); assert(shareWith->tglGLHglrc); togl->tglGLHglrc = shareWith->tglGLHglrc; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; } else { /* * Create a new OpenGL rendering context. And check to share lists. */ togl->tglGLHglrc = wglCreateContext(togl->tglGLHdc); if (togl->ShareList) { /* share display lists with existing togl widget */ Togl *shareWith = FindTogl(togl->ShareList); if (shareWith) wglShareLists(shareWith->tglGLHglrc, togl->tglGLHglrc); } if (!togl->tglGLHglrc) { Tcl_SetResult(togl->Interp, TCL_STUPID "could not create rendering context", TCL_STATIC); return DUMMY_WINDOW; } /* Just for portability, define the simplest visinfo */ visinfo = &VisInf; visinfo->visual = DefaultVisual(dpy, DefaultScreen(dpy)); visinfo->depth = visinfo->visual->bits_per_rgb; togl->VisInfo = visinfo; } #endif /* TOGL_WGL */ /* * find a colormap */ scrnum = Tk_ScreenNumber(togl->TkWin); if (togl->RgbaFlag) { /* Colormap for RGB mode */ #if defined(TOGL_X11) cmap = get_rgb_colormap(dpy, scrnum, visinfo, togl->TkWin); #elif defined(TOGL_WGL) if (pfd.dwFlags & PFD_NEED_PALETTE) { cmap = Win32CreateRgbColormap(pfd); } else { cmap = DefaultColormap(dpy, scrnum); } /* for EPS Output */ if (togl->EpsRedMap) free(togl->EpsRedMap); if (togl->EpsGreenMap) free(togl->EpsGreenMap); if (togl->EpsBlueMap) free(togl->EpsBlueMap); togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0; #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) cmap = DefaultColormap(dpy, scrnum); /* for EPS Output */ if (togl->EpsRedMap) free(togl->EpsRedMap); if (togl->EpsGreenMap) free(togl->EpsGreenMap); if (togl->EpsBlueMap) free(togl->EpsBlueMap); togl->EpsRedMap = togl->EpsGreenMap = togl->EpsBlueMap = NULL; togl->EpsMapSize = 0; #endif /* TOGL_X11 */ } else { /* Colormap for CI mode */ #ifdef TOGL_WGL togl->CiColormapSize = 1 << pfd.cColorBits; togl->CiColormapSize = togl->CiColormapSize < MAX_CI_COLORMAP_SIZE ? togl->CiColormapSize : MAX_CI_COLORMAP_SIZE; #endif /* TOGL_WGL */ if (togl->PrivateCmapFlag) { /* need read/write colormap so user can store own color entries */ #if defined(TOGL_X11) cmap = XCreateColormap(dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocAll); #elif defined(TOGL_WGL) cmap = Win32CreateCiColormap(togl); #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) /* need to figure out how to do this correctly on Mac... */ cmap = DefaultColormap(dpy, scrnum); #endif /* TOGL_X11 */ } else { if (visinfo->visual == DefaultVisual(dpy, scrnum)) { /* share default/root colormap */ cmap = Tk_Colormap(togl->TkWin); } else { /* make a new read-only colormap */ cmap = XCreateColormap(dpy, XRootWindow(dpy, visinfo->screen), visinfo->visual, AllocNone); } } } #if !defined(TOGL_AGL) /* Make sure Tk knows to switch to the new colormap when the cursor is over * this window when running in color index mode. */ (void) Tk_SetWindowVisual(togl->TkWin, visinfo->visual, visinfo->depth, cmap); #endif #ifdef TOGL_WGL /* Install the colormap */ SelectPalette(togl->tglGLHdc, ((TkWinColormap *) cmap)->palette, TRUE); RealizePalette(togl->tglGLHdc); #endif /* TOGL_WGL */ #if defined(TOGL_X11) swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = ALL_EVENTS_MASK; window = XCreateWindow(dpy, parent, 0, 0, togl->Width, togl->Height, 0, visinfo->depth, InputOutput, visinfo->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); /* Make sure window manager installs our colormap */ (void) XSetWMColormapWindows(dpy, window, &window, 1); #elif defined(TOGL_WGL) window = Tk_AttachHWND(togl->TkWin, hwnd); #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) { TkWindow *winPtr = (TkWindow *) togl->TkWin; window = TkpMakeWindow(winPtr, parent); } #endif /* TOGL_X11 */ #ifdef USE_OVERLAY if (togl->OverlayFlag) { if (SetupOverlay(togl) == TCL_ERROR) { fprintf(stderr, "Warning: couldn't setup overlay.\n"); togl->OverlayFlag = False; } } #endif /* USE_OVERLAY */ /* Request the X window to be displayed */ (void) XMapWindow(dpy, window); #if defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) if (togl->ShareContext && FindTogl(togl->ShareContext)) { /* share OpenGL context with existing Togl widget */ Togl *shareWith = FindTogl(togl->ShareContext); assert(shareWith); assert(shareWith->aglCtx); togl->aglCtx = shareWith->aglCtx; togl->VisInfo = shareWith->VisInfo; visinfo = togl->VisInfo; } else { AGLContext shareCtx = NULL; if (togl->PixelFormat) { /* fill in RgbaFlag, DoubleFlag, and StereoFlag */ fmt = (AGLPixelFormat) togl->PixelFormat; GLint has_rgba, has_doublebuf, has_stereo; if (aglDescribePixelFormat(fmt, AGL_RGBA, &has_rgba) && aglDescribePixelFormat(fmt, AGL_DOUBLEBUFFER, &has_doublebuf) && aglDescribePixelFormat(fmt, AGL_STEREO, &has_stereo)) { togl->RgbaFlag = (has_rgba ? True : False); togl->DoubleFlag = (has_doublebuf ? True : False); togl->StereoFlag = (has_stereo ? True : False); } else { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: failed querying pixel format attributes", TCL_STATIC); return DUMMY_WINDOW; } } else { /* Need to do this after mapping window, so MacDrawable structure * is more completely filled in */ na = 0; attribs[na++] = AGL_MINIMUM_POLICY; attribs[na++] = AGL_ROBUST; if (togl->RgbaFlag) { /* RGB[A] mode */ attribs[na++] = AGL_RGBA; attribs[na++] = AGL_RED_SIZE; attribs[na++] = togl->RgbaRed; attribs[na++] = AGL_GREEN_SIZE; attribs[na++] = togl->RgbaGreen; attribs[na++] = AGL_BLUE_SIZE; attribs[na++] = togl->RgbaBlue; if (togl->AlphaFlag) { attribs[na++] = AGL_ALPHA_SIZE; attribs[na++] = togl->AlphaSize; } } else { /* Color index mode */ attribs[na++] = AGL_BUFFER_SIZE; attribs[na++] = 8; } if (togl->DepthFlag) { attribs[na++] = AGL_DEPTH_SIZE; attribs[na++] = togl->DepthSize; } if (togl->DoubleFlag) { attribs[na++] = AGL_DOUBLEBUFFER; } if (togl->StencilFlag) { attribs[na++] = AGL_STENCIL_SIZE; attribs[na++] = togl->StencilSize; } if (togl->AccumFlag) { attribs[na++] = AGL_ACCUM_RED_SIZE; attribs[na++] = togl->AccumRed; attribs[na++] = AGL_ACCUM_GREEN_SIZE; attribs[na++] = togl->AccumGreen; attribs[na++] = AGL_ACCUM_BLUE_SIZE; attribs[na++] = togl->AccumBlue; if (togl->AlphaFlag) { attribs[na++] = AGL_ACCUM_ALPHA_SIZE; attribs[na++] = togl->AccumAlpha; } } if (togl->AuxNumber != 0) { attribs[na++] = AGL_AUX_BUFFERS; attribs[na++] = togl->AuxNumber; } attribs[na++] = AGL_NONE; if ((fmt = aglChoosePixelFormat(NULL, 0, attribs)) == NULL) { Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't choose pixel format", TCL_STATIC); return DUMMY_WINDOW; } } /* * Check whether to share lists. */ if (togl->ShareList) { /* share display lists with existing togl widget */ Togl *shareWith = FindTogl(togl->ShareList); if (shareWith) shareCtx = shareWith->aglCtx; } if ((togl->aglCtx = aglCreateContext(fmt, shareCtx)) == NULL) { GLenum err = aglGetError(); aglDestroyPixelFormat(fmt); if (err == AGL_BAD_MATCH) Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't create context, shared context doesn't match", TCL_STATIC); else if (err == AGL_BAD_CONTEXT) Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't create context, bad shared context", TCL_STATIC); else if (err == AGL_BAD_PIXELFMT) Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't create context, bad pixel format", TCL_STATIC); else Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't create context, unknown reason", TCL_STATIC); return DUMMY_WINDOW; } aglDestroyPixelFormat(fmt); if (!aglSetDrawable(togl->aglCtx, # if defined(TOGL_AGL) ((MacDrawable *) (window))->toplevel->grafPtr # else ((MacDrawable *) (window))->toplevel->portPtr # endif )) { aglDestroyContext(togl->aglCtx); Tcl_SetResult(togl->Interp, TCL_STUPID "Togl: couldn't set drawable", TCL_STATIC); return DUMMY_WINDOW; } /* Just for portability, define the simplest visinfo */ visinfo = &VisInf; visinfo->visual = DefaultVisual(dpy, DefaultScreen(dpy)); visinfo->depth = visinfo->visual->bits_per_rgb; Tk_SetWindowVisual(togl->TkWin, visinfo->visual, visinfo->depth, cmap); } #endif /* TOGL_AGL_CLASSIC || TOGL_AGL */ #if defined(TOGL_X11) /* Check for a single/double buffering snafu */ { int dbl_flag; if (glXGetConfig(dpy, visinfo, GLX_DOUBLEBUFFER, &dbl_flag)) { if (!togl->DoubleFlag && dbl_flag) { /* We requested single buffering but had to accept a */ /* double buffered visual. Set the GL draw buffer to */ /* be the front buffer to simulate single buffering. */ glDrawBuffer(GL_FRONT); } } } #endif /* TOGL_X11 */ /* for EPS Output */ if (!togl->RgbaFlag) { int index_size; #if defined(TOGL_X11) || defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) GLint index_bits; glGetIntegerv(GL_INDEX_BITS, &index_bits); index_size = 1 << index_bits; #elif defined(TOGL_WGL) index_size = togl->CiColormapSize; #endif /* TOGL_X11 */ if (togl->EpsMapSize != index_size) { if (togl->EpsRedMap) free(togl->EpsRedMap); if (togl->EpsGreenMap) free(togl->EpsGreenMap); if (togl->EpsBlueMap) free(togl->EpsBlueMap); togl->EpsMapSize = index_size; togl->EpsRedMap = (GLfloat *) calloc(index_size, sizeof (GLfloat)); togl->EpsGreenMap = (GLfloat *) calloc(index_size, sizeof (GLfloat)); togl->EpsBlueMap = (GLfloat *) calloc(index_size, sizeof (GLfloat)); } } return window; } /* * Togl_WorldChanged * * Add support for setgrid option. */ static void Togl_WorldChanged(ClientData instanceData) { Togl *togl = (Togl *) instanceData; Tk_GeometryRequest(togl->TkWin, togl->Width, togl->Height); Tk_SetInternalBorder(togl->TkWin, 0); if (togl->SetGrid > 0) { Tk_SetGrid(togl->TkWin, togl->Width / togl->SetGrid, togl->Height / togl->SetGrid, togl->SetGrid, togl->SetGrid); } else { Tk_UnsetGrid(togl->TkWin); } } /* * ToglCmdDeletedProc * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */ static void ToglCmdDeletedProc(ClientData clientData) { Togl *togl = (Togl *) clientData; Tk_Window tkwin = togl->TkWin; /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (togl && tkwin) { Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask, Togl_EventProc, (ClientData) togl); } #if defined(TOGL_X11) if (togl->GlCtx) { if (FindToglWithSameContext(togl) == NULL) glXDestroyContext(togl->display, togl->GlCtx); togl->GlCtx = NULL; } # ifdef USE_OVERLAY if (togl->OverlayCtx) { Tcl_HashEntry *entryPtr; TkWindow *winPtr = (TkWindow *) togl->TkWin; if (winPtr) { entryPtr = Tcl_FindHashEntry(&winPtr->dispPtr->winTable, (char *) togl->OverlayWindow); Tcl_DeleteHashEntry(entryPtr); } if (FindToglWithSameOverlayContext(togl) == NULL) glXDestroyContext(togl->display, togl->OverlayCtx); togl->OverlayCtx = NULL; } # endif /* USE_OVERLAY */ #endif /* TODO: delete contexts on other platforms */ if (tkwin != NULL) { if (togl->SetGrid > 0) { Tk_UnsetGrid(tkwin); } togl->TkWin = NULL; Tk_DestroyWindow(tkwin); } } /* * Togl_Destroy * * Gets called when an Togl widget is destroyed. */ static void Togl_Destroy( #if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401 char * #else ClientData #endif clientData) { Togl *togl = (Togl *) clientData; Tk_FreeOptions(configSpecs, WIDGREC togl, togl->display, 0); #ifndef NO_TK_CURSOR if (togl->Cursor != None) { Tk_FreeCursor(togl->display, togl->Cursor); } #endif if (togl->DestroyProc) { togl->DestroyProc(togl); } /* remove from linked list */ RemoveFromList(togl); #if !defined(TOGL_WGL) /* TODO: why not on Windows? */ free(togl); #endif } /* * This gets called to handle Togl window configuration events */ static void Togl_EventProc(ClientData clientData, XEvent *eventPtr) { Togl *togl = (Togl *) clientData; switch (eventPtr->type) { case Expose: if (eventPtr->xexpose.count == 0) { if (!togl->UpdatePending && eventPtr->xexpose.window == Tk_WindowId(togl->TkWin)) { Togl_PostRedisplay(togl); } #if defined(TOGL_X11) if (!togl->OverlayUpdatePending && togl->OverlayFlag && togl->OverlayIsMapped && eventPtr->xexpose.window == togl->OverlayWindow) { Togl_PostOverlayRedisplay(togl); } #endif /* TOGL_X11 */ } break; case ConfigureNotify: if (togl->Width != Tk_Width(togl->TkWin) || togl->Height != Tk_Height(togl->TkWin)) { togl->Width = Tk_Width(togl->TkWin); togl->Height = Tk_Height(togl->TkWin); (void) XResizeWindow(Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin), togl->Width, togl->Height); #if defined(TOGL_X11) if (togl->OverlayFlag) { (void) XResizeWindow(Tk_Display(togl->TkWin), togl->OverlayWindow, togl->Width, togl->Height); (void) XRaiseWindow(Tk_Display(togl->TkWin), togl->OverlayWindow); } #endif /* TOGL_X11 */ Togl_MakeCurrent(togl); if (togl->ReshapeProc) { togl->ReshapeProc(togl); } else { glViewport(0, 0, togl->Width, togl->Height); #if defined(TOGL_X11) if (togl->OverlayFlag) { Togl_UseLayer(togl, TOGL_OVERLAY); glViewport(0, 0, togl->Width, togl->Height); Togl_UseLayer(togl, TOGL_NORMAL); } #endif /* TOGL_X11 */ } #ifndef TOGL_WGL /* causes double redisplay on Win32 platform */ Togl_PostRedisplay(togl); #endif /* TOGL_WGL */ } break; case MapNotify: #if defined(TOGL_AGL) { /* * See comment for the UnmapNotify case below. */ AGLDrawable d = TkMacOSXGetDrawablePort(Tk_WindowId(togl->TkWin)); aglSetDrawable(togl->aglCtx, d); } #endif /* TOGL_AGL */ break; case UnmapNotify: #if defined(TOGL_AGL) { /* * For Mac OS X Aqua, Tk subwindows are not implemented as * separate Aqua windows. They are just different regions of * a single Aqua window. To unmap them they are just not drawn. * Have to disconnect the AGL context otherwise they will continue * to be displayed directly by Aqua. */ aglSetDrawable(togl->aglCtx, NULL); } #endif /* TOGL_AGL */ break; case DestroyNotify: if (togl->TkWin != NULL) { if (togl->SetGrid > 0) { Tk_UnsetGrid(togl->TkWin); } togl->TkWin = NULL; #if (TCL_MAJOR_VERSION * 100 + TCL_MINOR_VERSION) >= 800 /* This function new in Tcl/Tk 8.0 */ (void) Tcl_DeleteCommandFromToken(togl->Interp, togl->widgetCmd); #endif } if (togl->TimerProc != NULL) { #if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401 Tcl_DeleteTimerHandler(togl->timerHandler); #else Tk_DeleteTimerHandler(togl->timerHandler); #endif } if (togl->UpdatePending) { #if (TCL_MAJOR_VERSION * 100 + TCL_MINOR_VERSION) >= 705 Tcl_CancelIdleCall(Togl_Render, (ClientData) togl); #else Tk_CancelIdleCall(Togl_Render, (ClientData) togl); #endif } #if (TK_MAJOR_VERSION * 100 + TK_MINOR_VERSION) >= 401 Tcl_EventuallyFree((ClientData) togl, Togl_Destroy); #else Tk_EventuallyFree((ClientData) togl, Togl_Destroy); #endif break; default: /* nothing */ ; } } void Togl_PostRedisplay(Togl *togl) { if (!togl->UpdatePending) { togl->UpdatePending = True; Tk_DoWhenIdle(Togl_Render, (ClientData) togl); } } void Togl_SwapBuffers(const Togl *togl) { if (togl->DoubleFlag) { #if defined(TOGL_WGL) int res = SwapBuffers(togl->tglGLHdc); assert(res == TRUE); #elif defined(TOGL_X11) glXSwapBuffers(Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin)); #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) aglSwapBuffers(togl->aglCtx); #endif /* TOGL_WGL */ } else { glFlush(); } } const char * Togl_Ident(const Togl *togl) { return togl->Ident; } int Togl_Width(const Togl *togl) { return togl->Width; } int Togl_Height(const Togl *togl) { return togl->Height; } Tcl_Interp * Togl_Interp(const Togl *togl) { return togl->Interp; } Tk_Window Togl_TkWin(const Togl *togl) { return togl->TkWin; } #if defined(TOGL_X11) /* * A replacement for XAllocColor. 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 too efficient; the XQueryColors() could be * done just once. * Written by Michael Pichler, Brian Paul, Mark Kilgard * Input: dpy - X display * cmap - X colormap * cmapSize - size of colormap * In/Out: color - the XColor struct * Output: exact - 1=exact color match, 0=closest match */ static void noFaultXAllocColor(Display *dpy, Colormap cmap, int cmapSize, XColor *color, int *exact) { XColor *ctable, subColor; int i, bestmatch; double mindist; /* 3*2^16^2 exceeds long int precision. */ /* First try just using XAllocColor. */ if (XAllocColor(dpy, cmap, color)) { *exact = 1; return; } /* Retrieve color table entries. */ /* XXX alloca candidate. */ ctable = (XColor *) malloc(cmapSize * sizeof (XColor)); for (i = 0; i < cmapSize; i++) { ctable[i].pixel = i; } (void) XQueryColors(dpy, cmap, ctable, cmapSize); /* Find best match. */ bestmatch = -1; mindist = 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); /* Try to allocate the closest match color. This should only fail if the * cell is read/write. Otherwise, we're incrementing the cell's reference * count. */ if (!XAllocColor(dpy, cmap, &subColor)) { /* do this to work around a problem reported by Frank Ortega */ subColor.pixel = (unsigned long) bestmatch; subColor.red = ctable[bestmatch].red; subColor.green = ctable[bestmatch].green; subColor.blue = ctable[bestmatch].blue; subColor.flags = DoRed | DoGreen | DoBlue; } *color = subColor; } #elif defined(TOGL_WGL) static UINT Win32AllocColor(const Togl *togl, float red, float green, float blue) { /* Modified version of XAllocColor emulation of Tk. - returns index, * instead of color itself - allocates logical palette entry even for * non-palette devices */ TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin); UINT index; COLORREF newColor, closeColor; PALETTEENTRY entry, closeEntry; int new, refCount; Tcl_HashEntry *entryPtr; entry.peRed = (unsigned char) (red * 255 + .5); entry.peGreen = (unsigned char) (green * 255 + .5); entry.peBlue = (unsigned char) (blue * 255 + .5); entry.peFlags = 0; /* * Find the nearest existing palette entry. */ newColor = RGB(entry.peRed, entry.peGreen, entry.peBlue); index = GetNearestPaletteIndex(cmap->palette, newColor); GetPaletteEntries(cmap->palette, index, 1, &closeEntry); closeColor = RGB(closeEntry.peRed, closeEntry.peGreen, closeEntry.peBlue); /* * If this is not a duplicate and colormap is not full, allocate a new entry. */ if (newColor != closeColor) { if (cmap->size == (unsigned int) togl->CiColormapSize) { entry = closeEntry; } else { cmap->size++; ResizePalette(cmap->palette, cmap->size); index = cmap->size - 1; SetPaletteEntries(cmap->palette, index, 1, &entry); SelectPalette(togl->tglGLHdc, cmap->palette, TRUE); RealizePalette(togl->tglGLHdc); } } newColor = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue); entryPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char *) newColor, &new); if (new) { refCount = 1; } else { refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1; } Tcl_SetHashValue(entryPtr, (ClientData) refCount); /* for EPS output */ togl->EpsRedMap[index] = (GLfloat) (entry.peRed / 255.0); togl->EpsGreenMap[index] = (GLfloat) (entry.peGreen / 255.0); togl->EpsBlueMap[index] = (GLfloat) (entry.peBlue / 255.0); return index; } static void Win32FreeColor(const Togl *togl, unsigned long index) { TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin); COLORREF cref; UINT count, refCount; PALETTEENTRY entry, *entries; Tcl_HashEntry *entryPtr; if (index >= cmap->size) { panic("Tried to free a color that isn't allocated."); } GetPaletteEntries(cmap->palette, index, 1, &entry); cref = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue); entryPtr = Tcl_FindHashEntry(&cmap->refCounts, (char *) cref); if (!entryPtr) { panic("Tried to free a color that isn't allocated."); } refCount = (int) Tcl_GetHashValue(entryPtr) - 1; if (refCount == 0) { count = cmap->size - index; entries = (PALETTEENTRY *) ckalloc(sizeof (PALETTEENTRY) * count); GetPaletteEntries(cmap->palette, index + 1, count, entries); SetPaletteEntries(cmap->palette, index, count, entries); SelectPalette(togl->tglGLHdc, cmap->palette, TRUE); RealizePalette(togl->tglGLHdc); ckfree((char *) entries); cmap->size--; Tcl_DeleteHashEntry(entryPtr); } else { Tcl_SetHashValue(entryPtr, (ClientData) refCount); } } static void Win32SetColor(const Togl *togl, unsigned long index, float red, float green, float blue) { TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin); PALETTEENTRY entry; entry.peRed = (unsigned char) (red * 255 + .5); entry.peGreen = (unsigned char) (green * 255 + .5); entry.peBlue = (unsigned char) (blue * 255 + .5); entry.peFlags = 0; SetPaletteEntries(cmap->palette, index, 1, &entry); SelectPalette(togl->tglGLHdc, cmap->palette, TRUE); RealizePalette(togl->tglGLHdc); /* for EPS output */ togl->EpsRedMap[index] = (GLfloat) (entry.peRed / 255.0); togl->EpsGreenMap[index] = (GLfloat) (entry.peGreen / 255.0); togl->EpsBlueMap[index] = (GLfloat) (entry.peBlue / 255.0); } #endif /* TOGL_X11 */ unsigned long Togl_AllocColor(const Togl *togl, float red, float green, float blue) { if (togl->RgbaFlag) { (void) fprintf(stderr, "Error: Togl_AllocColor illegal in RGBA mode.\n"); return 0; } /* TODO: maybe not... */ if (togl->PrivateCmapFlag) { (void) fprintf(stderr, "Error: Togl_FreeColor illegal with private colormap\n"); return 0; } #if defined(TOGL_X11) { XColor xcol; int exact; xcol.red = (short) (red * 65535.0); xcol.green = (short) (green * 65535.0); xcol.blue = (short) (blue * 65535.0); noFaultXAllocColor(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin), Tk_Visual(togl->TkWin)->map_entries, &xcol, &exact); /* for EPS output */ togl->EpsRedMap[xcol.pixel] = (float) xcol.red / 65535.0; togl->EpsGreenMap[xcol.pixel] = (float) xcol.green / 65535.0; togl->EpsBlueMap[xcol.pixel] = (float) xcol.blue / 65535.0; return xcol.pixel; } #elif defined(TOGL_WGL) return Win32AllocColor(togl, red, green, blue); #elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) /* still need to implement this on Mac... */ return 0; #endif /* TOGL_X11 */ } void Togl_FreeColor(const Togl *togl, unsigned long pixel) { if (togl->RgbaFlag) { (void) fprintf(stderr, "Error: Togl_AllocColor illegal in RGBA mode.\n"); return; } /* TODO: maybe not... */ if (togl->PrivateCmapFlag) { (void) fprintf(stderr, "Error: Togl_FreeColor illegal with private colormap\n"); return; } #if defined(TOGL_X11) (void) XFreeColors(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin), &pixel, 1, 0); #elif defined(TOGL_WGL) Win32FreeColor(togl, pixel); #endif /* TOGL_X11 */ } void Togl_SetColor(const Togl *togl, unsigned long index, float red, float green, float blue) { if (togl->RgbaFlag) { (void) fprintf(stderr, "Error: Togl_AllocColor illegal in RGBA mode.\n"); return; } if (!togl->PrivateCmapFlag) { (void) fprintf(stderr, "Error: Togl_SetColor requires a private colormap\n"); return; } #if defined(TOGL_X11) { XColor xcol; xcol.pixel = index; xcol.red = (short) (red * 65535.0); xcol.green = (short) (green * 65535.0); xcol.blue = (short) (blue * 65535.0); xcol.flags = DoRed | DoGreen | DoBlue; (void) XStoreColor(Tk_Display(togl->TkWin), Tk_Colormap(togl->TkWin), &xcol); /* for EPS output */ togl->EpsRedMap[xcol.pixel] = (float) xcol.red / 65535.0; togl->EpsGreenMap[xcol.pixel] = (float) xcol.green / 65535.0; togl->EpsBlueMap[xcol.pixel] = (float) xcol.blue / 65535.0; } #elif defined(TOGL_WGL) Win32SetColor(togl, index, red, green, blue); #endif /* TOGL_X11 */ } #if TOGL_USE_FONTS == 1 # if defined(TOGL_WGL) # include "tkWinInt.h" # include "tkFont.h" /* * The following structure represents Windows' implementation of a font. */ typedef struct WinFont { TkFont font; /* Stuff used by generic font package. Must be * first in structure. */ HFONT hFont; /* Windows information about font. */ HWND hwnd; /* Toplevel window of application that owns * this font, used for getting HDC. */ int widths[256]; /* Widths of first 256 chars in this font. */ } WinFont; # endif /* TOGL_WGL */ # define MAX_FONTS 1000 static GLuint ListBase[MAX_FONTS]; static GLuint ListCount[MAX_FONTS]; /* * Load the named bitmap font as a sequence of bitmaps in a display list. * fontname may be one of the predefined fonts like TOGL_BITMAP_8_BY_13 * or an X font name, or a Windows font name, etc. */ GLuint Togl_LoadBitmapFont(const Togl *togl, const char *fontname) { static Bool FirstTime = True; # if defined(TOGL_X11) XFontStruct *fontinfo; # elif defined(TOGL_WGL) WinFont *winfont; HFONT oldFont; TEXTMETRIC tm; # endif /* TOGL_X11 */ int first, last, count; GLuint fontbase; const char *name; /* Initialize the ListBase and ListCount arrays */ if (FirstTime) { int i; for (i = 0; i < MAX_FONTS; i++) { ListBase[i] = ListCount[i] = 0; } FirstTime = False; } /* * This method of selecting X fonts according to a TOGL_ font name * is a kludge. To be fixed when I find time... */ if (fontname == TOGL_BITMAP_8_BY_13) { name = "8x13"; } else if (fontname == TOGL_BITMAP_9_BY_15) { name = "9x15"; } else if (fontname == TOGL_BITMAP_TIMES_ROMAN_10) { name = "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1"; } else if (fontname == TOGL_BITMAP_TIMES_ROMAN_24) { name = "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1"; } else if (fontname == TOGL_BITMAP_HELVETICA_10) { name = "-adobe-helvetica-medium-r-normal--10-100-75-75-p-57-iso8859-1"; } else if (fontname == TOGL_BITMAP_HELVETICA_12) { name = "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1"; } else if (fontname == TOGL_BITMAP_HELVETICA_18) { name = "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1"; } else if (!fontname) { name = DEFAULT_FONTNAME; } else { name = (const char *) fontname; } assert(name); # if defined(TOGL_X11) fontinfo = (XFontStruct *) XLoadQueryFont(Tk_Display(togl->TkWin), name); if (!fontinfo) { return 0; } first = fontinfo->min_char_or_byte2; last = fontinfo->max_char_or_byte2; # elif defined(TOGL_WGL) winfont = (WinFont *) Tk_GetFont(togl->Interp, togl->TkWin, name); if (!winfont) { return 0; } oldFont = SelectObject(togl->tglGLHdc, winfont->hFont); GetTextMetrics(togl->tglGLHdc, &tm); first = tm.tmFirstChar; last = tm.tmLastChar; # elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) first = 10; /* don't know how to determine font range on * Mac... */ last = 127; # endif /* TOGL_X11 */ count = last - first + 1; fontbase = glGenLists((GLuint) (last + 1)); if (fontbase == 0) { # ifdef TOGL_WGL SelectObject(togl->tglGLHdc, oldFont); Tk_FreeFont((Tk_Font) winfont); # endif /* TOGL_WGL */ return 0; } # if defined(TOGL_WGL) wglUseFontBitmaps(togl->tglGLHdc, first, count, (int) fontbase + first); SelectObject(togl->tglGLHdc, oldFont); Tk_FreeFont((Tk_Font) winfont); # elif defined(TOGL_X11) glXUseXFont(fontinfo->fid, first, count, (int) fontbase + first); # elif defined(TOGL_AGL_CLASSIC) || defined(TOGL_AGL) aglUseFont(togl->aglCtx, 1, 0, 14, /* for now, only app font, regular * 14-point */ 10, 118, fontbase + first); # endif /* Record the list base and number of display lists for * Togl_UnloadBitmapFont(). */ { int i; for (i = 0; i < MAX_FONTS; i++) { if (ListBase[i] == 0) { ListBase[i] = fontbase; ListCount[i] = last + 1; break; } } } return fontbase; } /* * Release the display lists which were generated by Togl_LoadBitmapFont(). */ void Togl_UnloadBitmapFont(const Togl *togl, GLuint fontbase) { int i; (void) togl; for (i = 0; i < MAX_FONTS; i++) { if (ListBase[i] == fontbase) { glDeleteLists(ListBase[i], ListCount[i]); ListBase[i] = ListCount[i] = 0; return; } } } #endif /* TOGL_USE_FONTS */ /* * Overlay functions */ void Togl_UseLayer(Togl *togl, int layer) { if (!togl->OverlayWindow) return; if (layer == TOGL_OVERLAY) { #if defined(TOGL_WGL) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLOverlayHglrc); assert(res == TRUE); #elif defined(TOGL_X11) (void) glXMakeCurrent(Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx); # if defined(__sgi) if (togl->OldStereoFlag) oldStereoMakeCurrent(Tk_Display(togl->TkWin), togl->OverlayWindow, togl->OverlayCtx); # endif /* __sgi STEREO */ #endif /* TOGL_WGL */ } else if (layer == TOGL_NORMAL) { #if defined(TOGL_WGL) int res = wglMakeCurrent(togl->tglGLHdc, togl->tglGLHglrc); assert(res == TRUE); #elif defined(TOGL_X11) (void) glXMakeCurrent(Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin), togl->GlCtx); # if defined(__sgi) if (togl->OldStereoFlag) oldStereoMakeCurrent(Tk_Display(togl->TkWin), Tk_WindowId(togl->TkWin), togl->GlCtx); # endif /* __sgi STEREO */ #endif /* TOGL_WGL */ } else { /* error */ } } void Togl_ShowOverlay(Togl *togl) { #if defined(TOGL_X11) /* not yet implemented on Windows */ if (togl->OverlayWindow) { (void) XMapWindow(Tk_Display(togl->TkWin), togl->OverlayWindow); (void) XInstallColormap(Tk_Display(togl->TkWin), togl->OverlayCmap); togl->OverlayIsMapped = True; } #endif /* TOGL_X11 */ } void Togl_HideOverlay(Togl *togl) { if (togl->OverlayWindow && togl->OverlayIsMapped) { (void) XUnmapWindow(Tk_Display(togl->TkWin), togl->OverlayWindow); togl->OverlayIsMapped = False; } } void Togl_PostOverlayRedisplay(Togl *togl) { if (!togl->OverlayUpdatePending && togl->OverlayWindow && togl->OverlayDisplayProc) { Tk_DoWhenIdle(RenderOverlay, (ClientData) togl); togl->OverlayUpdatePending = True; } } void Togl_OverlayDisplayFunc(Togl_Callback *proc) { DefaultOverlayDisplayProc = proc; } int Togl_ExistsOverlay(const Togl *togl) { return togl->OverlayFlag; } int Togl_GetOverlayTransparentValue(const Togl *togl) { return togl->OverlayTransparentPixel; } int Togl_IsMappedOverlay(const Togl *togl) { return togl->OverlayFlag && togl->OverlayIsMapped; } unsigned long Togl_AllocColorOverlay(const Togl *togl, float red, float green, float blue) { #if defined(TOGL_X11) /* not yet implemented on Windows */ if (togl->OverlayFlag && togl->OverlayCmap) { XColor xcol; xcol.red = (short) (red * 65535.0); xcol.green = (short) (green * 65535.0); xcol.blue = (short) (blue * 65535.0); if (!XAllocColor(Tk_Display(togl->TkWin), togl->OverlayCmap, &xcol)) return (unsigned long) -1; return xcol.pixel; } #endif /* TOGL_X11 */ return (unsigned long) -1; } void Togl_FreeColorOverlay(const Togl *togl, unsigned long pixel) { #if defined(TOGL_X11) /* not yet implemented on Windows */ if (togl->OverlayFlag && togl->OverlayCmap) { (void) XFreeColors(Tk_Display(togl->TkWin), togl->OverlayCmap, &pixel, 1, 0); } #endif /* TOGL_X11 */ } /* * User client data */ void Togl_ClientData(ClientData clientData) { DefaultClientData = clientData; } ClientData Togl_GetClientData(const Togl *togl) { return togl->Client_Data; } void Togl_SetClientData(Togl *togl, ClientData clientData) { togl->Client_Data = clientData; } /* * X11-only functions * Contributed by Miguel A. De Riera Pasenau (miguel@DALILA.UPC.ES) */ Display * Togl_Display(const Togl *togl) { return Tk_Display(togl->TkWin); } Screen * Togl_Screen(const Togl *togl) { return Tk_Screen(togl->TkWin); } int Togl_ScreenNumber(const Togl *togl) { return Tk_ScreenNumber(togl->TkWin); } Colormap Togl_Colormap(const Togl *togl) { return Tk_Colormap(togl->TkWin); } #ifdef MESA_COLOR_HACK /* * Let's know how many free colors do we have */ # if 0 static unsigned char rojo[] = { 4, 39, 74, 110, 145, 181, 216, 251 }, verde[] = { 4, 39, 74, 110, 145, 181, 216, 251}, azul[] = { 4, 39, 74, 110, 145, 181, 216, 251}; unsigned char rojo[] = { 4, 36, 72, 109, 145, 182, 218, 251 }, verde[] = { 4, 36, 72, 109, 145, 182, 218, 251}, azul[] = { 4, 36, 72, 109, 145, 182, 218, 251}; azul[] = { 0, 85, 170, 255}; # endif # define RLEVELS 5 # define GLEVELS 9 # define BLEVELS 5 /* to free dithered_rgb_colormap pixels allocated by Mesa */ static unsigned long *ToglMesaUsedPixelCells = NULL; static int ToglMesaUsedFreeCells = 0; static int get_free_color_cells(Display *display, int screen, Colormap colormap) { if (!ToglMesaUsedPixelCells) { XColor xcol; int i; int colorsfailed, ncolors = XDisplayCells(display, screen); long r, g, b; ToglMesaUsedPixelCells = (unsigned long *) calloc(ncolors, sizeof (unsigned long)); /* Allocate X colors and initialize color_table[], red_table[], etc */ /* de Mesa 2.1: xmesa1.c setup_dithered_(...) */ i = colorsfailed = 0; for (r = 0; r < RLEVELS; r++) for (g = 0; g < GLEVELS; g++) for (b = 0; b < BLEVELS; b++) { int exact; xcol.red = (r * 65535) / (RLEVELS - 1); xcol.green = (g * 65535) / (GLEVELS - 1); xcol.blue = (b * 65535) / (BLEVELS - 1); noFaultXAllocColor(display, colormap, ncolors, &xcol, &exact); ToglMesaUsedPixelCells[i++] = xcol.pixel; if (!exact) { colorsfailed++; } } ToglMesaUsedFreeCells = i; XFreeColors(display, colormap, ToglMesaUsedPixelCells, ToglMesaUsedFreeCells, 0x00000000); } return ToglMesaUsedFreeCells; } static void free_default_color_cells(Display *display, Colormap colormap) { if (ToglMesaUsedPixelCells) { XFreeColors(display, colormap, ToglMesaUsedPixelCells, ToglMesaUsedFreeCells, 0x00000000); free(ToglMesaUsedPixelCells); ToglMesaUsedPixelCells = NULL; ToglMesaUsedFreeCells = 0; } } #endif /* * Generate EPS file. * Contributed by Miguel A. De Riera Pasenau (miguel@DALILA.UPC.ES) */ /* Function that creates a EPS File from a created pixmap on the current * context. Based on the code from Copyright (c) Mark J. Kilgard, 1996. * Parameters: name_file, b&w / Color flag, redraw function. The redraw * function is needed in order to draw things into the new created pixmap. */ /* Copyright (c) Mark J. Kilgard, 1996. */ static GLvoid * grabPixels(int inColor, unsigned int width, unsigned int height) { GLvoid *buffer; GLint swapbytes, lsbfirst, rowlength; GLint skiprows, skippixels, alignment; GLenum format; unsigned int size; if (inColor) { format = GL_RGB; size = width * height * 3; } else { format = GL_LUMINANCE; size = width * height * 1; } buffer = (GLvoid *) malloc(size); if (buffer == NULL) return NULL; /* Save current modes. */ glGetIntegerv(GL_PACK_SWAP_BYTES, &swapbytes); glGetIntegerv(GL_PACK_LSB_FIRST, &lsbfirst); glGetIntegerv(GL_PACK_ROW_LENGTH, &rowlength); glGetIntegerv(GL_PACK_SKIP_ROWS, &skiprows); glGetIntegerv(GL_PACK_SKIP_PIXELS, &skippixels); glGetIntegerv(GL_PACK_ALIGNMENT, &alignment); /* Little endian machines (DEC Alpha for example) could benefit from * setting GL_PACK_LSB_FIRST to GL_TRUE instead of GL_FALSE, but this would * * * * * * * * * require changing the generated bitmaps too. */ glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); /* Actually read the pixels. */ glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, (GLvoid *) buffer); /* Restore saved modes. */ glPixelStorei(GL_PACK_SWAP_BYTES, swapbytes); glPixelStorei(GL_PACK_LSB_FIRST, lsbfirst); glPixelStorei(GL_PACK_ROW_LENGTH, rowlength); glPixelStorei(GL_PACK_SKIP_ROWS, skiprows); glPixelStorei(GL_PACK_SKIP_PIXELS, skippixels); glPixelStorei(GL_PACK_ALIGNMENT, alignment); return buffer; } static int generateEPS(const char *filename, int inColor, unsigned int width, unsigned int height) { FILE *fp; GLvoid *pixels; unsigned char *curpix; unsigned int components, i; int pos; unsigned int bitpixel; pixels = grabPixels(inColor, width, height); if (pixels == NULL) return 1; if (inColor) components = 3; /* Red, green, blue. */ else components = 1; /* Luminance. */ fp = fopen(filename, "w"); if (fp == NULL) { return 2; } (void) fprintf(fp, "%%!PS-Adobe-2.0 EPSF-1.2\n"); (void) fprintf(fp, "%%%%Creator: OpenGL pixmap render output\n"); (void) fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height); (void) fprintf(fp, "%%%%EndComments\n"); i = (((width * height) + 7) / 8) / 40; /* # of lines, 40 bytes per * line */ (void) fprintf(fp, "%%%%BeginPreview: %d %d %d %d\n%%", width, height, 1, i); pos = 0; curpix = (unsigned char *) pixels; for (i = 0; i < width * height * components;) { bitpixel = 0; if (inColor) { double pix = 0; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x80; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x40; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x20; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x10; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x08; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x04; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x02; pix = 0.30 * (double) curpix[i] + 0.59 * (double) curpix[i + 1] + 0.11 * (double) curpix[i + 2]; i += 3; if (pix > 127.0) bitpixel |= 0x01; } else { if (curpix[i++] > 0x7f) bitpixel |= 0x80; if (curpix[i++] > 0x7f) bitpixel |= 0x40; if (curpix[i++] > 0x7f) bitpixel |= 0x20; if (curpix[i++] > 0x7f) bitpixel |= 0x10; if (curpix[i++] > 0x7f) bitpixel |= 0x08; if (curpix[i++] > 0x7f) bitpixel |= 0x04; if (curpix[i++] > 0x7f) bitpixel |= 0x02; if (curpix[i++] > 0x7f) bitpixel |= 0x01; } (void) fprintf(fp, "%02x", bitpixel); if (++pos >= 40) { (void) fprintf(fp, "\n%%"); pos = 0; } } if (pos) (void) fprintf(fp, "\n%%%%EndPreview\n"); else (void) fprintf(fp, "%%EndPreview\n"); (void) fprintf(fp, "gsave\n"); (void) fprintf(fp, "/bwproc {\n"); (void) fprintf(fp, " rgbproc\n"); (void) fprintf(fp, " dup length 3 idiv string 0 3 0\n"); (void) fprintf(fp, " 5 -1 roll {\n"); (void) fprintf(fp, " add 2 1 roll 1 sub dup 0 eq\n"); (void) fprintf(fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n"); (void) fprintf(fp, " 3 1 roll 5 -1 roll put 1 add 3 0 }\n"); (void) fprintf(fp, " { 2 1 roll } ifelse\n"); (void) fprintf(fp, " } forall\n"); (void) fprintf(fp, " pop pop pop\n"); (void) fprintf(fp, "} def\n"); (void) fprintf(fp, "systemdict /colorimage known not {\n"); (void) fprintf(fp, " /colorimage {\n"); (void) fprintf(fp, " pop\n"); (void) fprintf(fp, " pop\n"); (void) fprintf(fp, " /rgbproc exch def\n"); (void) fprintf(fp, " { bwproc } image\n"); (void) fprintf(fp, " } def\n"); (void) fprintf(fp, "} if\n"); (void) fprintf(fp, "/picstr %d string def\n", width * components); (void) fprintf(fp, "%d %d scale\n", width, height); (void) fprintf(fp, "%d %d %d\n", width, height, 8); (void) fprintf(fp, "[%d 0 0 %d 0 0]\n", width, height); (void) fprintf(fp, "{currentfile picstr readhexstring pop}\n"); (void) fprintf(fp, "false %d\n", components); (void) fprintf(fp, "colorimage\n"); curpix = (unsigned char *) pixels; pos = 0; for (i = width * height * components; i != 0; i--) { (void) fprintf(fp, "%02hx", *curpix++); if (++pos >= 40) { (void) fprintf(fp, "\n"); pos = 0; } } if (pos) (void) fprintf(fp, "\n"); (void) fprintf(fp, "grestore\n"); free(pixels); if (fclose(fp) != 0) return 1; return 0; } /* int Togl_DumpToEpsFile( const Togl *togl, const char *filename, int inColor, * void (*user_redraw)(void)) */ /* changed by GG */ int Togl_DumpToEpsFile(const Togl *togl, const char *filename, int inColor, void (*user_redraw) (const Togl *)) { Bool using_mesa = False; #if 0 Pixmap eps_pixmap; GLXPixmap eps_glxpixmap; XVisualInfo *vi = togl->VisInfo; Window win = Tk_WindowId(togl->TkWin); #endif int retval; unsigned int width = togl->Width, height = togl->Height; #if defined(TOGL_X11) Display *dpy = Tk_Display(togl->TkWin); int scrnum = Tk_ScreenNumber(togl->TkWin); if (strstr(glXQueryServerString(dpy, scrnum, GLX_VERSION), "Mesa")) using_mesa = True; else #endif /* TOGL_X11 */ using_mesa = False; /* I don't use Pixmap do drawn into, because the code should link with Mesa * libraries and OpenGL libraries, and the which library we use at run time * should not matter, but the name of the calls differs one from another: * MesaGl: glXCreateGLXPixmapMESA( dpy, vi, eps_pixmap, * Tk_Colormap(togl->TkWin)) OpenGl: glXCreateGLXPixmap( dpy, vi, * eps_pixmap); instead of this I read direct from back buffer of the * screeen. */ #if 0 eps_pixmap = XCreatePixmap(dpy, win, width, height, vi->depth); if (using_mesa) eps_glxpixmap = glXCreateGLXPixmapMESA(dpy, vi, eps_pixmap, Tk_Colormap(togl->TkWin)); else eps_glxpixmap = glXCreateGLXPixmap(dpy, vi, eps_pixmap); glXMakeCurrent(dpy, eps_glxpixmap, togl->GlCtx); user_redraw(); #endif if (!togl->RgbaFlag) { #if defined(TOGL_WGL) /* Due to the lack of a unique inverse mapping from the frame buffer to * the logical palette we need a translation map from the complete * logical palette. */ { int n, i; TkWinColormap *cmap = (TkWinColormap *) Tk_Colormap(togl->TkWin); LPPALETTEENTRY entry = malloc(togl->EpsMapSize * sizeof (PALETTEENTRY)); n = GetPaletteEntries(cmap->palette, 0, togl->EpsMapSize, entry); for (i = 0; i < n; i++) { togl->EpsRedMap[i] = (GLfloat) (entry[i].peRed / 255.0); togl->EpsGreenMap[i] = (GLfloat) (entry[i].peGreen / 255.0); togl->EpsBlueMap[i] = (GLfloat) (entry[i].peBlue / 255.0); } free(entry); } #endif /* TOGL_WGL */ glPixelMapfv(GL_PIXEL_MAP_I_TO_R, togl->EpsMapSize, togl->EpsRedMap); glPixelMapfv(GL_PIXEL_MAP_I_TO_G, togl->EpsMapSize, togl->EpsGreenMap); glPixelMapfv(GL_PIXEL_MAP_I_TO_B, togl->EpsMapSize, togl->EpsBlueMap); } /* user_redraw(); */ user_redraw(togl); /* changed by GG */ /* glReadBuffer( GL_FRONT); */ /* by default it read GL_BACK in double buffer mode */ glFlush(); retval = generateEPS(filename, inColor, width, height); #if 0 glXMakeCurrent(dpy, win, togl->GlCtx); glXDestroyGLXPixmap(dpy, eps_glxpixmap); XFreePixmap(dpy, eps_pixmap); #endif return retval; } /* * Full screen stereo for SGI graphics * Contributed by Ben Evans (Ben.Evans@anusf.anu.edu.au) * This code was based on SGI's /usr/share/src/OpenGL/teach/stereo */ #if defined(__sgi) static struct stereoStateRec { Bool useSGIStereo; Display *currentDisplay; Window currentWindow; GLXContext currentContext; GLenum currentDrawBuffer; int currentStereoBuffer; Bool enabled; char *stereoCommand; char *restoreCommand; } stereo; /* call instead of glDrawBuffer */ void Togl_OldStereoDrawBuffer(GLenum mode) { if (stereo.useSGIStereo) { stereo.currentDrawBuffer = mode; switch (mode) { case GL_FRONT: case GL_BACK: case GL_FRONT_AND_BACK: /* ** Simultaneous drawing to both left and right buffers isn't ** really possible if we don't have a stereo capable visual. ** For now just fall through and use the left buffer. */ case GL_LEFT: case GL_FRONT_LEFT: case GL_BACK_LEFT: stereo.currentStereoBuffer = STEREO_BUFFER_LEFT; break; case GL_RIGHT: case GL_FRONT_RIGHT: stereo.currentStereoBuffer = STEREO_BUFFER_RIGHT; mode = GL_FRONT; break; case GL_BACK_RIGHT: stereo.currentStereoBuffer = STEREO_BUFFER_RIGHT; mode = GL_BACK; break; default: break; } if (stereo.currentDisplay && stereo.currentWindow) { glXWaitGL(); /* sync with GL command stream before calling X */ XSGISetStereoBuffer(stereo.currentDisplay, stereo.currentWindow, stereo.currentStereoBuffer); glXWaitX(); /* sync with X command stream before calling GL */ } } glDrawBuffer(mode); } /* call instead of glClear */ void Togl_OldStereoClear(GLbitfield mask) { GLenum drawBuffer; if (stereo.useSGIStereo) { drawBuffer = stereo.currentDrawBuffer; switch (drawBuffer) { case GL_FRONT: Togl_OldStereoDrawBuffer(GL_FRONT_RIGHT); glClear(mask); Togl_OldStereoDrawBuffer(drawBuffer); break; case GL_BACK: Togl_OldStereoDrawBuffer(GL_BACK_RIGHT); glClear(mask); Togl_OldStereoDrawBuffer(drawBuffer); break; case GL_FRONT_AND_BACK: Togl_OldStereoDrawBuffer(GL_RIGHT); glClear(mask); Togl_OldStereoDrawBuffer(drawBuffer); break; case GL_LEFT: case GL_FRONT_LEFT: case GL_BACK_LEFT: case GL_RIGHT: case GL_FRONT_RIGHT: case GL_BACK_RIGHT: default: break; } } glClear(mask); } static void oldStereoMakeCurrent(Display *dpy, Window win, GLXContext ctx) { if (dpy && (dpy != stereo.currentDisplay)) { int event, error; /* Make sure new Display supports SGIStereo */ if (XSGIStereoQueryExtension(dpy, &event, &error) == False) { dpy = NULL; } } if (dpy && win && (win != stereo.currentWindow)) { /* Make sure new Window supports SGIStereo */ if (XSGIQueryStereoMode(dpy, win) == X_STEREO_UNSUPPORTED) { win = None; } } if (ctx && (ctx != stereo.currentContext)) { GLint drawBuffer; glGetIntegerv(GL_DRAW_BUFFER, &drawBuffer); Togl_OldStereoDrawBuffer((GLenum) drawBuffer); } stereo.currentDisplay = dpy; stereo.currentWindow = win; stereo.currentContext = ctx; } /* call before using stereo */ static void oldStereoInit(Togl *togl, int stereoEnabled) { stereo.useSGIStereo = stereoEnabled; stereo.currentDisplay = NULL; stereo.currentWindow = None; stereo.currentContext = NULL; stereo.currentDrawBuffer = GL_NONE; stereo.currentStereoBuffer = STEREO_BUFFER_NONE; stereo.enabled = False; } #endif /* __sgi STEREO */ void Togl_StereoFrustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat eyeDist, GLfloat eyeOffset) { GLfloat eyeShift = (eyeDist - zNear) * (eyeOffset / eyeDist); glFrustum(left + eyeShift, right + eyeShift, bottom, top, zNear, zFar); glTranslatef(-eyeShift, 0, 0); } #ifdef TOGL_AGL_CLASSIC /* needed to make shared library on Mac with CodeWarrior; should be overridden * by user app */ /* * int main(int argc, char *argv[]) { return -1; } */ /* the following code is borrowed from tkMacAppInit.c */ /* *---------------------------------------------------------------------- * * MacintoshInit -- * * This procedure calls Mac specific initilization calls. Most of * these calls must be made as soon as possible in the startup * process. * * Results: * Returns TCL_OK if everything went fine. If it didn't the * application should probably fail. * * Side effects: * Inits the application. * *---------------------------------------------------------------------- */ int Togl_MacInit(void) { int i; long result, mask = 0x0700; /* mask = system 7.x */ # if GENERATING68K && !GENERATINGCFM SetApplLimit(GetApplLimit() - (TK_MAC_68K_STACK_GROWTH)); # endif MaxApplZone(); for (i = 0; i < 4; i++) { (void) MoreMasters(); } /* * Tk needs us to set the qd pointer it uses. This is needed * so Tk doesn't have to assume the availablity of the qd global * variable. Which in turn allows Tk to be used in code resources. */ tcl_macQdPtr = &qd; /* * If appearance is present, then register Tk as an Appearance client * This means that the mapping from non-Appearance to Appearance cdefs * will be done for Tk regardless of the setting in the Appearance * control panel. */ if (TkMacHaveAppearance()) { RegisterAppearanceClient(); } InitGraf(&tcl_macQdPtr->thePort); InitFonts(); InitWindows(); InitMenus(); InitDialogs((long) NULL); InitCursor(); /* * Make sure we are running on system 7 or higher */ if ((NGetTrapAddress(_Gestalt, ToolTrap) == NGetTrapAddress(_Unimplemented, ToolTrap)) || (((Gestalt(gestaltSystemVersion, &result) != noErr) || (result < mask)))) { panic("Tcl/Tk requires System 7 or higher."); } /* * Make sure we have color quick draw * (this means we can't run on 68000 macs) */ if (((Gestalt(gestaltQuickdrawVersion, &result) != noErr) || (result < gestalt32BitQD13))) { panic("Tk requires Color QuickDraw."); } FlushEvents(everyEvent, 0); SetEventMask(everyEvent); Tcl_MacSetEventProc(TkMacConvertEvent); return TCL_OK; } int Togl_MacSetupMainInterp(Tcl_Interp *interp) { TkMacInitAppleEvents(interp); TkMacInitMenus(interp); return TCL_OK; } #endif /* TOGL_AGL_CLASSIC */ lablgl-1.07/Togl/src/Togl/togl.h000066400000000000000000000142341437514534100164300ustar00rootroot00000000000000/* $Id: togl.h,v 1.28 2005/10/27 07:45:48 gregcouch Exp $ */ /* vi:set sw=4: */ /* * Togl - a Tk OpenGL widget * * Copyright (C) 1996-1998 Brian Paul and Ben Bederson * See the LICENSE file for copyright details. */ #ifndef TOGL_H # define TOGL_H /* Define the window system in Makefile.config */ /* # include "togl_ws.h" */ # ifdef TOGL_WGL # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN # if defined(_MSC_VER) # define DllEntryPoint DllMain # endif # endif # ifdef _WIN32 # define TOGL_EXTERN __declspec(dllexport) extern # else # define TOGL_EXTERN extern # endif /* _WIN32 */ # ifdef TOGL_AGL_CLASSIC # ifndef MAC_TCL # define MAC_TCL 1 # endif # endif # ifdef TOGL_AGL # ifndef MAC_OSX_TCL # define MAC_OSX_TCL 1 # endif # ifndef MAC_OSX_TK # define MAC_OSX_TK 1 # endif # endif # include # include # if defined(TOGL_AGL) || defined(TOGL_AGL_CLASSIC) # include # else # include # endif # ifdef __sgi # include # include # endif # ifndef CONST84 # define CONST84 # endif # ifndef NULL # define NULL 0 # endif # ifndef TOGL_USE_FONTS # define TOGL_USE_FONTS 1 /* needed for demos */ # endif # ifdef __cplusplus /* *INDENT-OFF* */ extern "C" { /* *INDENT-ON* */ # endif # define TOGL_VERSION "1.7" # define TOGL_MAJOR_VERSION 1 # define TOGL_MINOR_VERSION 7 /* * "Standard" fonts which can be specified to Togl_LoadBitmapFont() */ # define TOGL_BITMAP_8_BY_13 ((char *) 1) # define TOGL_BITMAP_9_BY_15 ((char *) 2) # define TOGL_BITMAP_TIMES_ROMAN_10 ((char *) 3) # define TOGL_BITMAP_TIMES_ROMAN_24 ((char *) 4) # define TOGL_BITMAP_HELVETICA_10 ((char *) 5) # define TOGL_BITMAP_HELVETICA_12 ((char *) 6) # define TOGL_BITMAP_HELVETICA_18 ((char *) 7) /* * Normal and overlay plane constants */ # define TOGL_NORMAL 1 # define TOGL_OVERLAY 2 struct Togl; typedef struct Togl Togl; typedef void (Togl_Callback) (Togl *togl); typedef int (Togl_CmdProc) (Togl *togl, int argc, CONST84 char *argv[]); TOGL_EXTERN int Togl_Init(Tcl_Interp *interp); /* * Default/initial callback setup functions */ TOGL_EXTERN void Togl_CreateFunc(Togl_Callback *proc); TOGL_EXTERN void Togl_DisplayFunc(Togl_Callback *proc); TOGL_EXTERN void Togl_ReshapeFunc(Togl_Callback *proc); TOGL_EXTERN void Togl_DestroyFunc(Togl_Callback *proc); TOGL_EXTERN void Togl_TimerFunc(Togl_Callback *proc); TOGL_EXTERN void Togl_ResetDefaultCallbacks(void); /* * Change callbacks for existing widget */ TOGL_EXTERN void Togl_SetCreateFunc(Togl *togl, Togl_Callback *proc); TOGL_EXTERN void Togl_SetDisplayFunc(Togl *togl, Togl_Callback *proc); TOGL_EXTERN void Togl_SetReshapeFunc(Togl *togl, Togl_Callback *proc); TOGL_EXTERN void Togl_SetDestroyFunc(Togl *togl, Togl_Callback *proc); TOGL_EXTERN void Togl_SetTimerFunc(Togl *togl, Togl_Callback *proc); /* * Miscellaneous */ TOGL_EXTERN int Togl_Configure(Tcl_Interp *interp, Togl *togl, int argc, const char *argv[], int flags); TOGL_EXTERN void Togl_MakeCurrent(const Togl *togl); TOGL_EXTERN void Togl_CreateCommand(char *cmd_name, Togl_CmdProc *cmd_proc); TOGL_EXTERN void Togl_PostRedisplay(Togl *togl); TOGL_EXTERN void Togl_SwapBuffers(const Togl *togl); /* * Query functions */ TOGL_EXTERN const char *Togl_Ident(const Togl *togl); TOGL_EXTERN int Togl_Width(const Togl *togl); TOGL_EXTERN int Togl_Height(const Togl *togl); TOGL_EXTERN Tcl_Interp *Togl_Interp(const Togl *togl); TOGL_EXTERN Tk_Window Togl_TkWin(const Togl *togl); /* * Color Index mode */ TOGL_EXTERN unsigned long Togl_AllocColor(const Togl *togl, float red, float green, float blue); TOGL_EXTERN void Togl_FreeColor(const Togl *togl, unsigned long index); TOGL_EXTERN void Togl_SetColor(const Togl *togl, unsigned long index, float red, float green, float blue); # if TOGL_USE_FONTS == 1 /* * Bitmap fonts */ TOGL_EXTERN GLuint Togl_LoadBitmapFont(const Togl *togl, const char *fontname); TOGL_EXTERN void Togl_UnloadBitmapFont(const Togl *togl, GLuint fontbase); # endif /* * Overlay functions */ TOGL_EXTERN void Togl_UseLayer(Togl *togl, int layer); TOGL_EXTERN void Togl_ShowOverlay(Togl *togl); TOGL_EXTERN void Togl_HideOverlay(Togl *togl); TOGL_EXTERN void Togl_PostOverlayRedisplay(Togl *togl); TOGL_EXTERN void Togl_OverlayDisplayFunc(Togl_Callback *proc); TOGL_EXTERN int Togl_ExistsOverlay(const Togl *togl); TOGL_EXTERN int Togl_GetOverlayTransparentValue(const Togl *togl); TOGL_EXTERN int Togl_IsMappedOverlay(const Togl *togl); TOGL_EXTERN unsigned long Togl_AllocColorOverlay(const Togl *togl, float red, float green, float blue); TOGL_EXTERN void Togl_FreeColorOverlay(const Togl *togl, unsigned long index); /* * User client data */ TOGL_EXTERN void Togl_ClientData(ClientData clientData); TOGL_EXTERN ClientData Togl_GetClientData(const Togl *togl); TOGL_EXTERN void Togl_SetClientData(Togl *togl, ClientData clientData); # ifdef TOGL_X11 /* * X11-only commands. * Contributed by Miguel A. De Riera Pasenau (miguel@DALILA.UPC.ES) */ TOGL_EXTERN Display *Togl_Display(const Togl *togl); TOGL_EXTERN Screen *Togl_Screen(const Togl *togl); TOGL_EXTERN int Togl_ScreenNumber(const Togl *togl); TOGL_EXTERN Colormap Togl_Colormap(const Togl *togl); # endif # ifdef __sgi /* * SGI stereo-only commands. * Contributed by Ben Evans (Ben.Evans@anusf.anu.edu.au) */ TOGL_EXTERN void Togl_OldStereoDrawBuffer(GLenum mode); TOGL_EXTERN void Togl_OldStereoClear(GLbitfield mask); # endif TOGL_EXTERN void Togl_StereoFrustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far, GLfloat eyeDist, GLfloat eyeOffset); /* * Generate EPS file. * Contributed by Miguel A. De Riera Pasenau (miguel@DALILA.UPC.ES) */ TOGL_EXTERN int Togl_DumpToEpsFile(const Togl *togl, const char *filename, int inColor, void (*user_redraw) (const Togl *)); # ifdef TOGL_AGL_CLASSIC /* * Mac-specific setup functions */ extern int Togl_MacInit(void); extern int Togl_MacSetupMainInterp(Tcl_Interp *interp); # endif # ifdef __cplusplus /* *INDENT-OFF* */ } /* *INDENT-ON* */ # endif #endif lablgl-1.07/Togl/src/Togl/tree2.rgba000066400000000000000000002010001437514534100171550ustar00rootroot00000000000000no name@@@?0?;?000@0@1@116@@000@0@,)55@?,0000 @0::@600000*@566@45)0000)@1540@4@004@)114@1@004F@1145)000@ 0@0*104)000 ,@0,45@)000 @0156@:@00 @@0*4>@;@0@  ((64,51:@6>,>( (( ($6,*>54@1,16:5$JJ (6C(@E50(((*@@1,54)$*441,, $$ $ T@?*> fa>151:4*((((((( (;))$(*)$1E41,, N@((6?C)(((  L\lF;,*5 65WF>4;4*(450(((((0E$4*5N   ,?((((*(056()0,()0,0$W NJ,1*FcPFI;IZoV>@ 44C50((,?   L,1N@00:440>F>*((((>5,)( *5>Jp0**5?$1$(@(((,:6($,4(140)*,**)6O4* ((5;6456TP``:1F??400((((*6 (N\ $YVpQ;1:>;:*00450500(((0NPF*((*0550())1045) (0((()*(()*)(,,)***5*))*( (((0>0(*:5J:0444>:0((()),4$(E@? ]C;;;;;6NQPFZN551466J0((055*0>4( *>:@()*,,**( ** (5:1($($(*) *)***1*$)* ( ((0**(((*:*00*:5((((**5 FC66((IP51( ;;;;54oJF:4:5;:5T:***44*(:0( (*( )),*$$  ( (:0 ( *( ((((*(((0:(4:((((((()),FI0C66;$L;TY;6I5; ;;;;44;o{Y444:5@:054*(((**(**((( ( (   0( ((  ((((( ( ((((((*(((** *0((((((((()**4>4:,5a?5:bTEC10?L;;;;::r`>@>:00>0(**((((((((( ( (     (4*((( (( (((( ((((((*(())(*((*)*,*0*:@4445>Lz;;;;;5bwY>@55*(**(((((( (      (((550*( ( (((( ( ((*(((((((((((****0**4*04>@YmJ;;;;5Q]|J:40:40(((((((((((( *( ( (   ((4E0((( (( (((( (((( (((((**(((((((((((**(4*400555JN>0;;;;5Yr逆>50*0*(((((((( (((((>:( ( *(  *:0(( ((((*0*((*(( (((((((((( ((((((*(05(000554:@4*;;;;;5qcE:4*(((((((((( ((( 05( (    *((000((( *4*((((( (((((((((((((((***((44*5445>55540;;;;;@?cmTEJ:( ((((( ((((*:0  (((( (( ( (* (  (0>>0(( (0((( ( (((*((((*(((00540(*40*444:F:5440;;;;;ENc|kT>@5( ( ((((( **J4 ((( *4(   (040 (( ( ( (((( *0(((:@0((**00004:@YE444;;;;;?IT|qZfV>40( (( (((EJ*  (   (  ** (*4*( (*( (*( (((( (( ((50((*0:5**0:NNoJ445;;;;;?FNJ`TT@:50(( (((5b*  (   >E>0*0J:( (( (*( (( (0@*(*04PT504:E:>>55;;;;;;;;Y`P60440**( (((((* *0r5    (Vc\F@EJ5* (*(( 0(((((((( ( (0E\:055@@YE:V\E@:5455;;;;;;;;OZo;;;C4**( ((*((4 4\::0    (( *NfbYNVE00((**0(*( (((((((( (0>550>55*4@\mm`@514:54;;;::65WF`PC>C0((( ((( ((((( 0\V>0 (0*    40 *JT>5@*4>4*((*04*( (((( (((*00**(((*FJN>EE>;;>EFE;;;6l1I\rE:;@0(*( ((( (*0( (>F4* 4F* (    :FF50**545* (*50( ( *( (*(( (****(((*5@F504:J@WTVVT:;?;m{rrV>I@F5*@*( (( (45 (40( (5PF4   (  0@0(** *5@* ((054( :@*( *4( ((*(( (((5NE505:E:;LFF>5;Ec~mYELwbY5*@J0( (5(((0J*4*0*(((EEmpT   0  ((  (* ((:TP0((044(( ( ( 5J( 0( ( ((((*(((((((0>>005:::66;YF;;Ycmkf`bY:4@P@0( *( (0VFY@54((0EY{Y4   0J  ((4(  (0JJ0**(* * ( ( ((((0*((04**((0>*0>P:>5;lyE;;vbprqbm`@:450***(((( EbmJ4(*EoY|:( (( (0(  4: (>E44(((   ( (((*(((5\5*))),*4EP@55Nreb;;v|Q\cZI@T:00*0 05((( (@rY::\JE:(  *((( *4 ( 4@>5*(  ( (((**(*4@45,))0E]T>I45Lq@;;:PWmfbLcJ40*0*(>Y0( ( (>TfbbY>*(( 0(  ((((    (*(  ((( ( ((4*0*05>((*))*4`bZ@EFQY{:6;訣\~呂lc>(((*(0FE*(**( *>mTE* ( (  >J(  ((0     *0( (( (***045>4?;((*40@>C6JYZbJ@55;n6尚wbJTmVE((((0:05**(0( (((***( (((( ( FT( (*5(   *4(**( (((((*04:FF5(,@?*0@`@554NfkZWC45565p~?5?apP@50 (:((( 4*(((54(( (((((( (( 4EV* (((*( (   ((*5TP0 ( ((((*0:@>P0(((,,(4;@514:n`x\|J66614ye>>PcP\@50( (*( *5@4*J@ ( *4( (( EV@ (0 4*  (:0(( ((*>TF* (( *@TTF>*((((**F??0*5:IVf\rN:::vY>PN@5:40(((((( (4@T*N> (0*(( ( ((@YN   ((   5N:0( ( (( (4( (* (0>N\T>(((((*5{F>0,1@PI]P{Z445:@◣I1JE:4045(*E@0( ( ( 4J(FE (  ((5J5(   (* (( *>F5* (((( ( ( ( (0>@4JT>0*((**EW464,1;IV]Q@FV55;:N武154040EN4*P\>(4b: ((05(*5(  (:\5 ((((( 04 (( (( (0@E( (( (((( (( ((((0::(4:*50((*,,5050:?:OhF@:ozJ6;:Z蚌504FV`00EJ4(*cV(*0@N*0N0  0F4 4:E4:@(( >@( (:@@( ((*( (((((((**(**00*4***4?4;1*,;EI{E:::;CZ6@YC;44;@F04VN*((NV054:4((V:( (( * (*( PfN**0( *04*( *@0 ( ( ( ((*0*(**((4**05001>J;C?400IO~E>LZ:cZ5稿nJ50*04E5>T50*(mmF:E( ( ( (( (@0 55( 5bN( (((05((*(( (4(  (((  ((*0*(((((***4@106CTN;@>>1>NF;YZVCI6h\qaO5EV>@4:F44**JbWN:( :5 (( (>0( (0VP0( 44(*(((@N4(*****((** ((05( (*(((*(40((:4*0015;QN::?4C:NEO]wq@Lz|6a\aphO0\\FV:0@\E45:cc{>*( (:5((( (( *50(*4\Y4  >:( (( Pb@00(*00500*(( (((04 (((((*::0(***),4>:::OOJ5\F\qVFlVZk;IqQITf(Jc@`E04oP**4PYE4((((( 4:((( ((*04@4VN@(( :E*0 4>:*0*0500*004( *0*( ( ((((((*0:0*4(*),1:;:ECOP:?CEVoT?OL\JqILLIEP05|pfFEJkP*::\T>40((( (>*(:0( (((*4@:TFP*:V(*0 0((**05404*E>5*55J5( ((*00 (4((((((***(0*4J5((0416056CF::>]mECOFZCJ?Ep?]p60(Pk`@5>4:Vk`@:5***((*(( (JF4(((((*0:JEE*Ew4 (5EN@4FE5>cmT5:\pPF* *4**(((4E>*(((0*44(4:E\>0*5F00>50>:55;TV;JNQ:6?L亡r@>(0{mOT0**4N`\c\m\EN**V>(( *40*(((0((*>J4(@*(4 *(>fkJ5445PwyVEFybF5*((00*>>>JF5*(*5:55:(0:V\:**0:>444::>>?>;booOJl;::wTTbT@((wb:555NTb{\F*0@>*(( (***(**4(5c5**4 (4*(0(4YkYJ:>F@fpfTcp`bJ>50*(0*ETYN4****>N\F5(*:N@0555JPE44>FE>JVO@]|lEPJ6:CNeVPrC0(4l~V@TJN\Yk偌迦FN>:5** 40E(((04*4(:rN*04 (5:54 4fykVPTk{yocVPbTF4:504F`54@E:4*0:YcV4(*4::0@F@fcT>40>:?EJPJE;IOEOrk;:11YPC:1*4akY{TY00`w|mw\4 (VN*(((*0*((0Vm0(*:F004* 5o||wwpkYbkF4\pV55:JT`N(*NJ@40*0Nof@54EJE4>F4Ybk`405@bTEFJ>6PZTWO|:;:4?lP;0)*0FrWpbP0(04YNPTJ4(** \` ((((*((*:F* VkJ4(@( (>@V\kopTNN`@0VrF5:PmP****4@55>>JVb\N0F\`>NN:JPY\;:@VTEFE>@PVqqal6;:510J0000:y\pJ:(((((0@:P(04 ** (((((**((0*(45>5(>0 (*ETobVJJ@>05P{yJNY\bJ040>>5@EPVPJ@@4(4Tf@JYJVVbL;F@>O:;@:FFLJV|6;:p11涪a@>0VmzZcJCF4:*0(((0V0(( ((((((0*( (4EJN@:0*(   (0>`rmF:545VkN\{cJ>44>E:0::4@E:000*(>YNP\@PT`C5>JE@;5::JVPaYL{F:;{駐4:V@YFN;,*4>:@40((( 005( (*(*(((0* *T{T@:0(  :PTmfJ@4>VrcyTJ4(*TJF400*4>N@>:4*4YTT:>`VkPEOcf\ZE::YVTZlk`6w炒ㄈ\>;610)*5>`J@4(*0 (0 ((4*0***:0 4pyo`P4((*   (*>b{YT>>fkV>E0*:\VV55:>>>P>5NJ5(54>5PNF`TJcmcNTTE>JNTQN]nk4{\oQ;4*)*(((050>V:04*0 F0(0@((((*(0N>00( (:yb:50*(* (( (0kkJ>N\::::@J@F>4:@NFFV>4FJ5((5E5VYPP\bc\JT\mkF>JTrhevhl1k~w]`TF@4****)**F4:NF(*(( (kF04T0*((**4wT0 :PwT4:45:( (( ((0*fNFbPNPPEJV@4@J>FPF5:P@>N@4((5F>TbPE\aN>EJ\fFCOPwnzF66{@YJTEE55F44::@>F4P4** (*04* J@0(***4J5( (45*:F>5YY0  ( 0N5FT``NP`pcVVP04F`TPN40*4>@NF:4504:E>@E:CFJCJEN@@CIn]`呃6:\NFNTOO`\PFNJYJJ0:05fT(*(0@* *:0(**((4:5@**((*(**05JYw>   4YfJJ\NcfbJNTTE@>4(0@cpVV@>0:PFJb`P@05ETJ\V:J`TVc@::>@Vw1P4逖W:cIJ{P;Coko`EE:P4((FY:(( EJ( ((*(((*((*4f@0((*( 0>54( >N`YJVE>VTPcV0:0*545Nwy\NYPkwcm`@5bo`kP>TcccfP>FFQ4x4pmk]NoqC6>OYCzψE>P>6FTJ(JmE(((4cP5(E:00*(**(*5b{oJN:*(( (0:0 ( 0*PTN`P@`fF4*>T>5PE>JPkyJ>PopEYcokPJrcro|r\oYYqoaW4hOV54]cZ]WC1EpoP>V`5>fF**0:cT0(YV:5*(**0FcPm`ok0 ((*( (((( (Tomc\fN4N\4(@wJ>NNJN>Pm\J\ybTηPb@FVcr\cVVf|rqlTkpOV洍56>6@::?QLCC1:PwWYPP>5NJ500>\Y* >T@54*(05\mN>f{N:@((*(((5( **((((JcJbyrE((4*4ffcfcP5@bkowE>>:00FJJN@VmwpkYVrmlcz:656>L|Z?m\zV>EFTac54>4:4*0>EE* *:>44*(*JT:(:{kFF(0T0( *( ((((( *0(TPV:**5*4crrkfkNETprrm::>:40ETYbNccYTO{n\r?6;:66>l坍ff{NPFCL`Y5@:044040**(:>:(((*04:E*(:myY0(050((((((((((( *005>* (E40EPJ\ob\JNVcwykc@@@:>4@>Nk\Vbro\bPrxxfoooohV5:::;1CYz44NYc\TQ灼``o:@J:*E40*** :V5((((4N:(((4@T>4*40****( (*((*(((0PY\* (@*5\>Jb`cppormpyk|E0J:5@JENbpYTmll|rmolnwlla`::;;NT\{::6OlobY`YT\PΧ:bV:>J>(*TE0((*5f@((((0F@44>50**0((4F*5E400>Yb> (*F\``mF@kpwJNV`Tm@:YFEFFJYpw\Pc|{xqbyry~m肝P6;;o:{`ㄍrY`Y{YTFfP>Tc:0T>*(05Em>5*(*4F:5TF:4(>4*5*>*:N544Py0 0*(5>0@@0>:N>:J?I:>LICC\NNV|mT]lkbefkoyoah枲;;;::;;~b@lYeYerr見ㄒfNycTY:5bN:J0**:JPY44*((*0(:T**0*fN*0(444E540Jb@ ( (*:0(NP@5((0;I??6NT?4>Q\PTko\VfLO~bYeTe]waY]`;;;66;5bVWrn\]ONcwwΓmFT>5NypP>co|P0*>oNF:50((*((*40(0::4*4(4J5Y>05:( ( (**>0*0500**4Fb]L?cP>:CNZcYfcVPP::ZZEJ`λ兝Lb;;;;65:55656Tf]oc?:5Η:Fcr`w|{JF:Fr4(*>5*000(*:*(*54*>N*0*4* 5*EV5@c00*4( (055***005446\`cNPmLCQkbhv\ZVbYCCWqTQWpㄥㄒ針CΛ;;;;;:6:;;NlJlkQLFrΓ\rc~yFEF0P\E4*(4N0****N`:(*0:>PfE0((((**Jc>5>*F>5*((*>5:0*404E5>VcFP`Vh{VFYeWeyWYVppaZoxy`\lzY~f\e\;;;;;;;;;;~fZ劫λeY\mzN]w\P\NJT>Vk:540@JFP@@kT500450>`k4>:*5>5Epf>*@TF*(((0:5:0440**@ye?N\YxZJ\QWekhe]cZOqc{力?ELL\wq;;;;;;;;;;::15OnxqO\rqqw]Qbvpmop\VVcr>>@45kPN|V\:44@5( *5E44>5@555w{E:YoJ0>(*:PF:*040**@mO]{Vb|peV]OWh`lmJV\whal?Wnao~Nq瞥;;;;;;;;;;::Q5LC\zF]rWI;>J>VTTT\k@:J@:@:5V0*4@F4*(*F4*0EEPJE0Jk45pN*4:ENfwr40544005@Nw~rbpnhV`hcYTVZ?CLEJp|e>>4loVZO5;;;;;;;;;;4IFQ\hxQWlOOC50?{xc`I>cJ>JV{rTEo4:@TE4:05*F545kYbff0*0(*FcJ**4>@@V>04440?EETTㄜfknaNOpzZPZ>OLEOkzlFIlfq?555;;;;;;;;;;5kmyn吮?6WLF:5;CWyyry|`>46;>@bmYYm`4>PTV:4*4*(*5*PTPP>(*(((*******00>*0000*;Pwmy`zzYV|PVyOZZmfynO{x55;;;;;;;;;;;;k5nY>6;??FC:QkxkxoNJOC?LCOPTrk\cobF4T\\@E:@5**((0**(((0((054455*04550044445TrYnZh禿r`f]\\OrfffVfWY\::;;;;;;;;;;;;;;;;;;c::CeIr`O\lQZxpFJENJpbk\mycNTN>N@5JofPNE@E0*00(((((*5>50:E>44*55E54Pk@:4@YmVNro|vv`vnVq|QTa听N;;;;;;;;;;;;;;;;;;;::燜@vfWZcpTxponrNYJFYwrpJrVNyE:mrP:>:>54b`(((((*YY::4FPE5:04>45\fN>5bVVO?@P憎~窖rk`TpTEO;?O:;;;;;;;;;;;;;;;;;;;:56~lpYTI>Wna|bJFJFVoNFcoJc{{VE``>F:*05Y@((((0:J:>TE5JE0:>@>**F@JVJbVJJ?TNoko\IJY>N?5J;;;;;;;;;;;;;;;;;;;;51YWpw\EPrr`Fc{YrpOTJETcyNTPNboNY`FJF5>Yb>(*T4 *(0PN>0>TF5>:(4\V>054:JbPw|ECC?m|~z{llk]v~bP\LmLO|`a;;;;;;;;;;;;;;;;;;;;5\JJam``wJ>CIJ`OEac`J`JIZfY`rkoyYmk:40>F\E((@0 *4*>E5:FE5E44**VJEP5@NE5{YYLY~parYEObW]zb\xob;;;;;;;;;;;;;;;;;;;;;Nok|>5Pl`ENQTeoQYTY\Tc{pooJE55::045J*((**0>05>5>@*44*To@:`5FPE55`mlQJO@?>l|~WNEJpΖnnbbZZ;;;;;;;;;;;;;;;;;;;;;;W氳Ffyww徘cCFNPcbbW{pTEZy豕kpw]V5E4@5>J`4**(44F455*045045JkV545TP``p5vnlCIEWICJPoYnQfxb姖]f::;;;;;;;;;;;;;;;;;;;;;;Wa▌PTYEaLJJ\J@FJTbn]rYN?bcw|ooC@O5Y>E5*5PTP@**:F5:5000>554\bf54@Vc::5511\Qff@5FeFP也Lrln6:;;;;;;;;;;;;;;;;;;;;;;;;;5vpnfPIIN\hL>E\|YornP@b`r{ZJcv@?T:>FF5((0ENF540400**4:E5:4FP`>5@Pr]oTYYY{nCEpO\I>E?wvP]{c@J;66;;;;;;;;;;;;;;;;;;;;;;;;;54{lFIh]poV?@?chbfkOYpc{xL54TVPq@J:J5**((0:4*4:0((05F\54>ETV:>@Jp{Tlr`5`|媒zfJpC?;;55;lCW;44;;;;;;;;;;;;;;;;;;;;;;;;;;;qlEV{nx{I`cP`q\hOETCVeJF4;:N]aPPNVV5ET0*4:04>:0*5@@NF@>NTJE>N\TokbqbbT4{r;JJ5\QF;;;;;:6規;66;;;;;;;;;;;;;;;;;;;;;;;;;;;lcwhZZpok\YNb\@;>CLTkoZ>OFeE*:`>*54:Yc@04@J>NYJJVobYJmkaZZhcWO]O4YY``FF;~NF;;;;;;66逖6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;隻帷|ofYQbk|vrf;?`YYkaq{YO:6;:NI:@Nf@44:FP@5@@N`wEPNYpP@QymaL?WcFPYY{{`;`;;|@;;;;;;;:::6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;c嶺\PVVTZlh涎CF\yNqkar\?C;PPmm5F`>44>@@:@FcrcPbLLvI>QcezN;z~r`{`{{Y;;;;5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;r5|煘yLb|qy~~{Iq\`ha~~ll溉ErnwPc\TEJF5:FPfF>@Nb{kmNPlPW]YT]mIl弛`嬋F;;;Fn6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6|crcYwb6C{EPPYVLYWWPO`F>:N\T::5:`bkNEPffywTLo\\hT|OPl玟mrqY]`;;;;F\lEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:56;y佷aT]]J6kbLcWvzqNPhbkz徵xWw`VP@:IT:4>Jk`hfENf`VT`NTcNoQLNY崢WOTf;;;;F\C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65::r淆FLT\E{QQZqPP~Wb|LVbOJP>cfJ6FbrEL`TTbm`rLV?Cb;I`C]緞即Zx;;;;;@I]O;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66:rQqc\|JTToWbyCJ┐NJEw`wpZ@FP`cYPbze?E;JOV\郡mw;;;;;;;;;;;;LYJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66;QP`4忮蒩WLcZ]T::PheF|呃`TLy|e>@m|kOFPTNbewZEF`虺Y尊郢w;;;;;;;;;;;;;;;JJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;l:LZzxwxm66:NkJNovfbVLVpL45x~Y`TL@;?JPTprpofll偽針;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6E?x64~lec;::;;;?@WZeTVopNOJL:4>xWWQ;?LYfcV苯l~f;ww;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6Wzz:4hac;;;;;;;5f;E~VTmTEbP;>6CavfzfJ6{TOraavY;Z;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:65NN篡L;;;;;;>@{Yk`TkYC>`TEPIPF:a\J@bn\Y]lx~vohl;;;pN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:55;::I`]Y;;;;;;Yy`LYwP>Y|YVPW;4>pQFEao\WTbeekYC;;;;;ZfqN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:6:;::`TL;;;;;:Fvev向?]wVVY5@>:bpofQθZm\Vflox?;;;;;;NqN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LYL;;;;6:;F@Wlvo`WWT\yh5?J]PcF`ocW]|r:;;;;;;;;;N;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;>;@amVoV\wCP{O46?wozW逖ObVZoY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;C@Iax炰VVwJPL同JFONqycJoOblcJWW飢Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6@eeoO~VQN\yma\nf@EbmyVCnT`kLN\葷o;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::P刃e]OQYJTwx`oaIN|坊yxkJCwOY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yknlf\QLOhc革WQo~p{{焦wJ>c\Yτ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6?xxx墮QNWwwㄣpf稜Ql`axWYETck]盯;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66|pfYWWl固\h:]Jk崩lfmZC>疵Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Vm魄w~{oYY6`Ck掣eQ]h弦捯Y;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:`薛患mclfl`eavON屝;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Q慮y]OfLLTfmlwoTZmJ@尖C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Qxw{wy帷;@Noa|廚WCPNC@IC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;]|xL;;El圾;>@E:6:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;JzWYL;;;;Nl|L;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      )         $$   ,,  $ 0* ,)$ (JI(0>F$0FE50(((* $  *4$$$ )*(*$ $ PC>4> TV>5;:>4*((((((( ($ $$( ,C (( O>**;?@10),,()(  FWcL?11:  :6F:4,0*((440(((((4C*5*5N  (,?(( (0(1,($ $()554)W(NE044F`PEE>I$VeO;E(54I>0**4@   I45?5*(0*00>J>0(***E:1, (5:Fc40,>@(5)(@((($;;($ ($ $,1440*:P1*$((5?;5:>WOc];5PII5440***4? ),Ya *TPemF:46;::*0*5:4:44**(4PYP0,)*455*,,(4441, (*(((($(($ ($$,144:1,04 (((4@0*0>>V>455;F@4***004;),OIF($$eF$ ]]]]]TJQOEOJ5445:;F0*(0>:44F5*(0@@F,00441,( $$( ** ( 5:1($($$ **,4160)00 ((((000***0@044*@:((**11>$ NN;?,))0OV;:*$ ]]]]NFbfJ@:5:55>:N5**0:>0*>5*( (*(()04*)( (((:0 ( ( (*(** ((((**((4:(:>((((((*),4LJ0F6>@((J?TW>>N>@)(]]]]II]YpV444:45:4540***40(0**(( ( (  *( (( (*((( ( ((((((****** 00( (((***(,0*5@5?5>]?::bTFC66EJ]]]]YYmm`@F@>44E5000*****(((((( ((      *50**(( ((((( ((((( ((((*0*(** (*(*000*0*:>445:>Jp]]]]]Ohop\@@:50*00*(***(((((((( (*(  (  (*:>4*(( (((( (((( (((((0*****((((((****4*04045@>V`E]]]]LWb{N:54>55*((((***(((((0* (*( (((( ( (  ((( **:J0*(( (((*((( **(* ((*((00((*(( ((*(****404445:5EJ>4]]]]L]x吻E:40400*(*(***((((((@>* (( (( (( *(  ( (( ( ( 4@4*( ((*(040((0*( (((***((((((((((***45*0045:5>>40]]]]]NyfF@50***(((((**(((*((4>* ((( ( ((( (( ((   **(540*** *50***(( (((((*((((((*(***(*55*544:>55544]]]]]\JboVNP>*((( ((((*(((***0@4 ((*( ** (( (0 (  ((5EE5*(((0**( (((*((((*((*00440*0540445:E:5544]]]]]ZOe{mY@F>* (( ((((0*(((0*N5 (((((( ( *4(   ((4:4 (((( * ( ((((( *4***>@0****44004>@TE545]]]]]\YWyp]k`E:4*( ( ( (*(((0(FJ* ( (((  (  00 *050( (0* ( (*(((((( ( (*:0((04>5004:NNkF44:]]]]]\YONaVVF@>4** ( ((((((**:`* (((  EJ@404T@( (*( ( (*(( ((( (4@***45NN545:E>>>55]]]]]]]]\`V?4::400*(( (**((*( (*4o5 (  ( *`k`JFJP:0(*0**( ( (( ((0((((*((((( (0EV:05:E@YE:VY@@:55::]]]]]]]VQ`o@@CI500*(((((00**5( 5Y@>4 (( ((   ( *(  (0Pmf\PYF45((004**( (((((*(((( ( (4>550>5:45E`kfY@55:>>5]]]WTOIWJ]QICI50*((*(( (**(*((5c\F5( 040 ( (  ( 50  0PV@>E05E50((0450*(( ( ((((( (((**04*****4JNN>@E>??@FNJ]]QIn@N]oJ?@F500*(**0(((04(( *FP>4( (:J4  (  (@NJ:400>::0 ((4:0((( ( *( ((*( (****(((*5@F:45:JEVQ\YT@]\OovwYCJFN@4F40((**((*5:( *:5*((:VJ5 (   (*  5E4*40(4>F0((*:>4*( :>*( *5* ( ((**(( (((5N@50:>@>@NJJ@>]PknWLOyk]@4NV5*(*>***5P04*40***EJorV  (0  *(*( (*  ((@\T5(*4:5(( *( ( 5F( 4(( (( (*((((((*4@>00:::::;@\J]]]弋{alkkcf`@:F\F4((0*((5bJ\@>5**4F\yY5 4J  *05(   *0PP40000 ( (( ( (((*4**(04**(*0>*4@N>@>@orF]]qanpncmcJE:>500000**( ((NkoN:00Fm\y>((( ( ((  ((*5* 45 ((EJ:50** ( ((((*(((:V50,,0105EN?>>Prb`]]qyT\c]LJY@5545*(4:0**( ((Er{\@E`{NJ:* *(((( (  (*(((( *0 ( 5FE>0* (( ( ((*(0***4>450015F]Q@I;?Qr|a]]FTWlhcOeP55050*EY4(((( *FYfcc\@*0*( (( 5*  ((**   ( (*0*(  *0(   ( (4*0*0::(**),45]]WCJLTawOO]卵ZzflkF0**404NJ4044* (4FmVJ0(((*((( ( EN(  **0    ((( 04*( (((( (0*0045>5??**044?>E;OZZaWVIJ]nLnbIVp\J0((04@5:40*5* (**(*00* ((0***( *( (JV* (*0:(   ( 05***( ((***(*45>JE5*,C@00@\>55:Neh\]NFLOQLpC:Ecr\JE5((*@0*(((50***>4 ((( (*****( ** :FT*  ****(((  ( ( ((0:TP4( (((***4>@@P0**(11*5>C655>k]xY~ZOOP@CyhC@TfTbJ@5*((40( 0:F:0P@ *(0:((**( ( JV> (4 ((5*   *>4(( *(0EVF* (( (0EVPF>**(((*0E@?405:JTfZn`QPTrYCVTF:>:5**(**(( (*4EY0P@(((4*(* * (((*(J\N( (  *( (  :N>4* (*(*4* ** (4@PYT@***(*05rE>016EOJ]Q|YIIPYQJ6PJ@:45:00JE4((*((((5N*JF(((( ( ( ((0*>T@( ( ( *0 ** (0EJ:0(((((*((((( (( (4>@4JT:4**(*0FQ4;54:@LWZWEFYJQ]CO也6>55:5JT:4Y`E*4b>***4:*0:* ( (*@c@( (*((*(44(*( **( (((4EE* (( *(*((*( ((((4::(4:*54***1,5155@E@QeLE?oyYT]J\1N>4:PYb55JP5*0kY(05FN44T0 ( ( ( (4P:( (5@F5:@** (EJ( (((>F@* ((** ( (((((**(*0***00*400*5@5;101CILqE@@?CEkPV`L@:>CJP5>\P40*VV5>:>4((V>( ((**( 4( ( *4* VfN0*0* (445*((( 0E4( ((( ( (**040***(*4**05444?L>F@555JPzE@JW>ckN淫oO:445:N>EV@54*kfPEF( ((*((((( (F0 *(>>* :bN*(*0(4>*(*((( (:((  *** (**040*((((*004>44;EVP?E>?:CNFEYWVCLPk]p{hT:J\EJ;CN:544Nc]V@(( (E:(*((( (J5* 05bV5( (:4(0***EP500004***00(( (*5:( **(***(40((:400046;QP;;C6F>OFP`onEOz|Pa`bnmT4bbP`@5E\F:>>ccr@0*((( (>:***((( 0>5*5:cY5(  E>((*((YfE45*040>450*( ((*44 (*((*0*>:0*0*0*,4>;;;QQO:]L`rTJ|nTYmVYrWNTf0PcFcJ55kN04:VY@5***(( (5>***( (((05>J:bTF** >F04 5F@4404:444445* *40* (( (((***004>404**),1:>?FCQT?EEIQpY@LIaNv\WPOJT4:ofNJPmP5@@`V@:4***(((*@**E:0(*(04:JEbPV*:T(44 4(**05>5450J@:0>>N5( (*044 *5*((((*000*444N:*(4556466FI>>C`hIFQFZJO枉\oIarC5*Tk`F>E:F\m\E@>444*00*((*YP:000*055>TJF0Fo0(( ((>NVJ:JJ>EkoY:@`oPF0( *500*((5F>*((*44:5*5>FY>0*>J04>:4>:::CV|W@QQT㏕L\WcrJC04wlPT544>Tcbmbp`FT00V@**((0:5540000*0EN5(F**4 0*EprT>55>V{{YJPwbJ>0(*440EE@NF5**0>@:>>*4>Y\:000>>445>>@>EC@bloQPmYYYwZ\m\J0*pcC:>@TVf{bP45FE0*( *040*045*>f>4*5 *50(4(5bm\N@FJFmrkVfr`cN@:40(44NV\P4**00ETbN>*0@PE0:::NPE45@FJ@PVPC\xkNWNTYWQe\TwI505lzWFYPV`Yk妒尖NTEE>40(50E***454:*>rT444 *:>:5 :k{m\TTk{wmcVTcVF5>>45Jb:5@E>504@`kY:*0:@:0EFFcbT@54@@ELJPNE>NOITwh~]WE?\QF>:45`ob|\`54br|ryb:(((0\N0((*444*(4`p5**@J5450(>r||yypk\cfF5`oY>>>TVbN*0FJE:445TpfF:5FJF4@F5V`f\54:EaPEJJ>;PYVYP{|T]VEFmW@5445Jy]pn\5*45YNY\J5*00 (\\(((***0**0@J0(\fP:*@( (@EY`op|pTNJbE4Y|pJ:@TmP*0005F::E@JYf`N4F\\>TP>NPVYC>EYQJFE@@PZoo]lP]VI>?O545:@y`vV@*****4@>T*44( *0(((****40**50*55F>*>4( ((0FVofYNPFE4:TypNP\`cN454@@:FJVVPJE@4*4Pc@JYJVV`L@NE@P??@>JFQN~WQ]Wp>>宸aFE:Yoz]cJJN>>05*(*4V50*( (((((****54*((*:FNTE>00* (4EcwpN@>5>YkTbycNE45@F>4@>5EF:444**>YPT\EPTVC;>NFI@:>>NVTb\P~YWYy愣?YYI\OVC50:EEE54*(*(45:( ((*000**0:0((0YyPE:4* (>PTokNE:EVpfwVN5*4\NJ:554:@NE@>5*5\TT:E`YbPEPec`ZI>@YVW\hlk醋ry]E@?;614>EbNJ:*05((04( ((*0505040@4( (5oyo`T50(0( ((0@c{\V@EkkV@J54@b\Y>:>E@@N>:PP:*:5@:VPFYTNbh`PTTF@JPVVQhwnCy\pY@:415,*05@5>YE:>45(*N4*5E((*0004P@450 (>yb@::4(*( (( *5kykN@P\>@>@FNEJ@:>@PJJT>5NN:*0:F:YYPN\``VJV`mfJENTwkozmo?m~ra`WLE;4410,*4T:>NJ04**(*kJ45Y40*004:rT0 ( >TrP5@>>>* (* **40k|NNbTNPTFPYE5@NEJPF:>TE@TF500:J@T`J@YZN@IL`{bFFOVwx{VJPzE\NWIN>@F;:@@JFJ5T:4*((0450*TF4*000:N5( ((((5:0>N>:`\4( (( 5T>{FVbbPP\fc\VT5:NbYYP:40:EETJ>5:45:F@EE:ELNEPJNEEFNwaeλNY\OOPWOO`cVNPV`PJ5@4>fT00(4F0(((4>5*0000:>:@00*(**000:P\w>(( :`fNP\PfkbNTVNEE@5*4Jkp\\F@5@TJNb\T@45FVN\T:F\T\fE>>EEVv;Y>陡kYcNL{QCFpkobNJ>P:*(Pb@**(F|N0***00*000005k{F4***(( (4@:5*(( ( EPb\PYF@YVTmY4@40:5:Tyy\T\Tmwfm`@:`m\bJ>P\\ckT@IFT>y>rkf`]ppJ?ET\Iz{J@YF?JTJ0PwN00*5fP>0N@55**0004>cypNP:**( (*4>0 *( (( *50TYT`PEcfN50EYE>VF@NTmwJEVo{mET`fcNJm`mm|p\kWZqqcYLhTW;;`b\b`F:JrwWEV`>EoN445EkV40c`E@4*005Pr\o`of4( (0*0*(**(((((VrpcbbN5P\5*FrP@PPNP@Vp`Nbr`T`P\@FTb{kY`VVh~wonhWloTW圠PPC;E>?IVQJJ:>Tx`cVYJ@TP>45Ec\0(E`J@:405>frT@kyN>E*(0((*5( (00***(JcNc{oE**54:mmckcT>Ecorr@>@:45NJJPETcombWWwmkey~YPPPCN|ZEney\EJTYfk@>J>@:04EJJ0(4@F550*4NY:*>{oNJ*4T0((4*((*****(04*YPV:44>4:fywof|kNJVpryk>>@:54JVY`PcycYTP{m]p促L]WQTChㄏkh|Y`PNQ``>J@5::44440*@FE0**05::E0*@p{\0*5:400*0*(*(**((4:5>E0(0P55PTTbobYJPVbrwo{fEEE>@4E@Pf\V\mk\`TwyykppppkZIYWW];F\zFFTcmaYY```p@JT@4F54450(Ec>0***:T>0*(5ET@50:54400*(*0(*00*0:V\\0 *E*@kETkbfpomrkr{mF4N:>EFETboVTkek{pmqhkomnckVY]]LV\WYTOlpeZ`ZVb\\@f\@@TE00\J4*04>mE0*((4PJ55@@4004**5N0>N>45F`c@((((00PkkfoJEkp{rNP\aWoE;]FFNFJ\moYQe{yrnazqwzp巾cT]]pW`~qZ`ZYYNcTEVf>4VF40:@Nk@>0*0:P@:TF>:*@54>0J4@T>:>\w0((((400>E5JE4@>PE@NFL>@OJIJ\TPYyfT]k~keffepyqel爐]]]TT]]ykIpZk\mzvfTwk\b@>fVET:40ET``::0(*04*>T0455kP45*::>J>:5Tb@((*(((*0@50TPF>0,5@JE@;TVC;@TYNVkm\YkPTa\fWcfhbfk]]]NN]LbW\wk]bQTewwFkJYE>TyV@kpT40EoPP@@5(*0**05404E@:4:05P>\@5@@*((((((*04E405:54446Ib]NEfTE?EOZb\f`VVT@@]ZLObp`Wq]]]]ONWLJC@JYf`peFC>PEPkyf{PNENp:04>>4454*4@0**>50ET454:0(:4F\>Fc0504*((*5>>44454>::?bbcPTpQFVkblwZZVe\FJZpWTWm听Lh]]]]]YQW]YQlOlm\YP{Tf{l~|{NJP5\bJ:40:T:4440Vb@*05@ETmF40*0004NfE>>0N@:0((0E>>45:55N>F`mJT`Yn{YI]h]hyYZWppb]pyyb]my]~h]op]]]]]]]]]]|h\Vpl]crzVcwbTbTTYE`mE:>5FPNYJEkY@555:0Eck:E@4@FENymE4EYJ0*0*5@>>4>:404J|mETc\z`O`Y\emlkah]WpcxQFJP~O`~]]]]]]]]]]YYE>WozyV`{wppbWex{rwpb`\mrEEF::kYTY\>55F:*(4@J::F@J@@@{{JE\pN5@00@TN@45:444FoQc|ZcymkZ`V\kbnoQZazmcmFZppo|Tq腰]]]]]]]]]]YYY?OEayPb{YOCEPEY\`\bmJ@PF@JE@Y50:EJ50*0T>04JP\VP:Pm5@wP45>JTkyw54>5:55>ETzwcyvlYblhaZ\bILTNPq{eEEFppak`Q]]]]]]]]]]FLNT]hrZ`qQTF;:Izw|kmOEfNEP\y\Fo{5>FYJ5>5>4N>::oboom444*4NfN00:EEFY>45::5@LJV\扛mmnaQQpzbWbFWTNVl{pONlfrNIQQ]]]]]]]]]]IkoynnF@\NJC?EL`yzy{|bF>?CFNor``ob:ETV`>:050(4>0TVTT@*4**0444404455E045550@W{zw|cyy]ZY]xWbbpfynTyIL]]]]]]]]]]]]lNn\F@EFELLCTrzlzyPQWNETNZV`wmcfpmN:YccFN@F>**00400***40*4@::>>4::::44:::5>Yp\wco听vfmeccWqkkkWkY\kYY]]]]]]]]]]]]]]]]]]e?CFhLr`VarY`~rNONYTwfwcp{fV`VF\J@TrkPVFFN5455*(**00>F>5EPF::4@>F:5TpF>:Fbp\V|{xzc|r\qyWVbwZ]]]]]]]]]]]]]]]]]]]TT敲IwfZ]hq\{wwmoYcPPcy{rT|bYPFpwT@E@F:5fb****04b`>@5P\J>@::E:>bfTE>fZ`YJJY汝甜{of\rVJP@I\Y]]]]]]]]]]]]]]]]]]]TLT~npZYNC]mb|bVQVNYpNNmwVp|bPc`EP@05>`E**004ET>@TE>VJ4EFF@44NET\PfZQOJYVpnrcPQ\EPE?T]]]]]]]]]]]]]]]]]]]]PF\\px`JWvp]J`v\{pQ`WN\kyJY`YowPbfPTJ>FbcE*0Y4(00:VPE4E\F5EE0:c\E5>>@PcV|JOLFpz~~kkfbxhYbToOQ{ck]]]]]]]]]]]]]]]]]]]]PbONcoaavLEFJP\OJbf]NkVTekYbwr{boo@::EN`F*(F5*050@J@@PJ:F:>40\PJT@FTF>|bbT]|qcvaLT~eZawccypq]]]]]]]]]]]]]]]]]]]]]Wp{l{E?Wm`IPVYhn]c`beWm|rpwPN>:EE55:N0(*44:E5>E>EF4>:4VrF@b@PVF>>brlVNQJEEl~~Z悴PIPwOqohokk]]]]]]]]]]]]]]]]]]]]]]`逐Levvx呀cIJVVomocyVLa|壯o{{c\>N>F>EPb5040>>N:>>45:>5:>TpY>:>YVbbp>ywnLOL\NJNVoYlWcqf獨blYY]]]]]]]]]]]]]]]]]]]]]]`cqWY\LeONPbPJTVboxcwbVFlkwrwNIT>`EJ>5>T\VE45@P@E>455E@>:fkk>:F`m@@>>;;cZhhJ;LkOQaTqmpPY]]]]]]]]]]]]]]]]]]]]]]]]YLrqvkVNLTcnQENfcryrZFlcw|cQeyJJ]>FJJ>0*4NTN>:5>:440>@J>@:PYcE>J\{`oW]\\w\ZpW]PEVVwxYb||hIP]PP]]]]]]]]]]]]]]]]]]]]]]]]]NE{mJNncvrZJIImrmkmQckyT@:\\VqFV@N:44005@>55@5005@Vb>:@J\`@EFNyYoxb>b~俞zhOpV\]]QQ]rJ]]OO]]]]]]]]]]]]]]]]]]]]]]]]]]]ymIW~rz~Omo\kycnQNYJ]mON;E@YkcV\Y`Y>NY50:>:>FE54>FFYPFEV\PNEVbVrohwhhW;r]ZZPcac]]]]]YV吭]TT]]]]]]]]]]]]]]]]]]]]]]]]]]]mkoeeyym`bQhcF@FINWrq\FTNmJ5EkE0>>EcoJ:>FNFY`TT`yk`Prkb`ale\TcV>\\bbZZ]~\c]]]]]]TTQ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]陝~宸wla\hn~vrn@F`ZZkcqzZTC?@@QN?FVoJ::FNVJ>JJVfyNYVbwVFWypaPEYeLY\\b]b]]W]]]]]]]YYYQ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]e誚aY]]\alk佝JNfyPqlhzcINCYYpm>PmF5:EFFENPoyoYkTVxLCWck|TEz{yvbbZ]]]]O]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]vN喕yPly~{{P~xf`hb~pp埋JypwTf\VFVP>@NYkNJJVfopTWlPZ`]YcpOmzb惑Y]]]cnJ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]Tfyfcrc>LNTPYYPa]aQTcNE@P\T>E>EkkoVPYkmYVwaakYTVm勁qqZ`b]]]]cnp]a]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TLQYz驕fY`fN>phVcYyzqOTqhmz您x]{h]VF>OY?>EVwkpoJTmfcYfQZlTpZQQ]后YQWh]]]]cna]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]PJTTy河LPZaNVT`qQW]e~Q`lYPVLkmQ@Pk{LVf\\mpkxQ`IJhELbZb~扉吭kx]]]]]aVbh]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]NJYwWqkbNTZqZkxIPyQPJ{f{xbIP\km\YkoIJEOV\兙p]]]]]]]]]]]]bee]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]PP]YWcL~憾媥ZQe]]WVVVhcNfkZTy{fFLrkVLY\TfmaJOc甸\沼閃]]]]]]]]]]]]]]]ee]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]oYP]y縊vrwmQTYWkQTlwpm]QYpO>>~bhZQFEEVYYvxrphmm偽]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TPIEyPIzmff]YY]]]\V``e~\`wwVWQO@>F`bZ?FO\ok`邕q~h]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TPZyyVJhbc]]]]]]]FfEN`\r\PkVEFCIlzloT>zYWykhyc]p]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]YPNOOf]]]]]]LIzble\o`LFbVO\TWOChfQJfva`enznhm]]]~h]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TIP]TFLaco]]]]]]h{bPb~ZEbbaY\E?Iw\OPmqaa\kmckmb]]]]]qzh]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TPY]TJa]f]]]]]WWrhw吒Cfyba`?JECkwvmZ多`va\kpoz\]]]]]]hh]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]fof]]]]TJL\NYkwwcaa`fzl@JTe\mJcql]b{qY]]]]]]]]]h]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]QINmlWw`fFZ~T>@Fzra瓶Tf``~p]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\WWhy躑``{NZVVNJWTw~kNoQcnhO]]坐p]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]QWfh~nT`\Ofrb]opJLfp~`NmYbkQQb略~]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]WW`ehbQWaL]|vbxhNPz~xlQFwVp]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]ymznhf\VWnm眾\Trzq{|侷wLEc`]ㄍ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TZyyy淆\Wawwpf跚Tpabwf\NWhlc坑]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]TT|qh`Z\p丸`lFaOk彩wkmeOF◣o]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]bm鈇vrfZCaLkq\em倒o]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]Yo滯軍{ryyp瓶bwmwWP姑]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]m悉waTkh]eypmwzlenQIb]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]mxwzvz咸]\cqm逍h]a\TVab]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]o|yf]]c{]QVbYTY]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]foof]]]]k{f]YY]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]             ** *)),     1)($ II* (     0)()*  ,4>)$  ( 0*   * (0   )   6,,,>1()$*1;0 $ * )  ; *  *   *E$)  $0 $,,54 )$)  $ 14 ?:W`;) $   **($ ( *  $  )$(4)((((($@@?4?5( *  ((  *   () ,0  (((( \kJ00 4   *(   **)$(,$,1$$)$( (((( (JF4  (    ( 6$ 54*,$ *0((((((V@5 (  (0 (((*;\((((($:TE*    ( (04Pb:(((($05]E(  ((( ***:E5 (((($4C{4 *( (  ( ***45* ((((( CP0( (( ( (*4****((((((00PW@50(( (  ( ((  ((*0>00**((((((14Qx>40 4   4:   (04N>*0*(((((*5?lW:4*(00 0( (( (05@`@*00(((((*46:C5* (@ *  (5  (@@*(*0044400((((((((?Jb0  V( (*( ((  5N0 ( *4N50NV5500*00((((((()4:Q$$(*( :((  (*((0( 0** *(((5PcfY:0,,00*((($$$$E4>,((* ::* (*    >@E5>>4544544((($F,>O)((((*(  0(     *4:0(04@5LC:>50(*)FPJJ4()(**(  50  (05 (*E:0*05:4144400(4T6PfC:(*>4, ((( 4 00JN>  0**@ (55**0444,,1>5((?ZwN;>>544* (** 0(@0* 4:V:  >  **  ( (4(*4E4401CF5((Q@EWLE;@5( (4>0 0J:V\*( * ( 0N* $()5@4,*5FEP((\e:;?6,(,  (FP:((@c54*(  (4(*$ $(5LE5>)*:Va)(():?E5P@,0(*> 5@@EE4   ( **  )INL6::EEyN)((;:INY>;:0 0* (E40*4  (*4(10 ( 146,:F;>0*(((L$PT5015*  ( 0: (  (0:*$54 5N4***>OC>>1(($$ L`Q*()4>0(  ( (( 0:** (**4  $$*01)(*0ZE\vC`5(($ $QE$ 45*4( (0(50*5**   ( *04*( ;41$ *,4?N@Qv:((${P@$*0( ( (0>:0((:5((044(*m50($)4;6F;`@(($$0v1**  0* (>:4*(  (  (( 04 :F(,,$(06FJ@4;6((()6o:  ( *05>* @  * (4  (* (( (  ($)),00EW;4,Wc6$((>mhp0( (055 *0 @5 0: (> ( (*4(*0( (((   (*$($ 01;m:00001o@$,]hW60*(((**(5045 * F0>N: (  (,(,*($$:@r:4>F*L~@$WZ>T1(( * *:( NE( 0( (F:    * $(10***)$0>54EC?44f(J>Jwl@:(*@**$,5 5C:4(** 5:  ( * 0 $)(00))0),*>:>Icb5:`\(o>:CWL5 :@05)$4@0 **CCF(** (5> (* *    00   $))))110(606@C>yO?@kO(6rF41>F4>0:* (N5 5:* (* ((* 54*(4   ( ( ()(*)16,116E?11C>J4V0;wf444> (FJN405J: ((:5*( 0  (*(505(E (   *  (  0( ((( ))04044OY541:;04,4xP0FT) 4TmLE0(0(*>F:* (  (*( **05b( ( *  04* (05*(  0(   (*:*  0 **(00004J{C0:06n))*;EPV,, YN1: (5>@>:>:05>*  (0 4  *0(  (44*((:E4(  (((40( ( ( (5:(**(((*004444Y`\:6\(((QVw65>50krJ,(**5:@TcPTT@4 0*  ((E (( (00* *(000*44**((  (040(*50  0( (450((0:40:E>4Ql\4>C((Q05O?6Y1 *Wh>0@45EFNf{{fE*5* (  4 ( *(N4 ((*((0::44000445540*0**   *5 00( (444  ( *0*>@40((4046:>>:4>?>LNCw($ F>1*$ *PvlJ:Y:E( >NbFE:J5 >:  (( 5J *5 4::544400>F4((:54 (005*54* *45* 44* *0(:>>@*(05YI::>:1IPLNIrr$(($,Z4, (5cF;I54 (*:4*00  @F  (*EN4 0 **04:40**0(*555((0:4 *( *(**040 055*04(05:;,0:NcI:5:55FLfJVW$(($ f1 $$ *`L>hF1( **: (  ((( 0( (400(((  (55**4440 (* **040*((  0>005055@40544@0,44:>C>zyFqQ$($L>C0*(EJV>F414(*( >( ( *00((  050( 04(4:4*( ((*( (( ((( *5404*55E0*0:410004>FEL~F:h4$(TT (bb\>4C44*  **0  (*   :kbV:0* *(04*( (0::45*( 0**   (*(((((:54((:>J:4:EF@?444JFIIOJ6\$h`VbbNrF*0,($$ (*@0(   * ( ( (NPNF@ *0:0* 0J@:*  (404 (**(5( 00(( ((405F:4EJE::>55>@FE>5>L pWlELoV:,(  *:(  4  * @0 (VF*( 5>0*((JJ5 (*0(*((((4005( 00((*(::@>@FE@:>ETP:5>CVN:LNF FLwkN:50*($  * 054 P4( 5  (c@ (:`E(* (*5E**40:>*0*(*4* **(*40 (0**40 (0*5::5FI;046JfP::?CY>`ca5$(Tw0O05,e,((4((**0(5(:  0* (( (:*((*50 @E * >@**44**5E4000 *4000  **40( * (*4044*1454;:>55:>>EEWyJ($Z?4;@511:@6055@:: (J:  0*  *0(4  *EE`0*5*(4*454**04*((  (5>00*((400>:50 (455>:0:F>EJ50,1:JY(1(\>$E44q4))Lb@:0*40E((0(4\5 ( (Pk0((5**  (00*4* 00040 *  (0>F@4440:@:>PYP>0(FE>E:4ENNJE>555L(O(PE@C6;k0(*CL,Qb>*(5**:>5*5*(F>(** ( ( (EYV:@0 (0 *0*40*55**:* 40*44:>**0EJEJPFJV\F4E@EE:>\NVOOPET@EQLC6~ Y;J( NOE:04(4JPE5*4:((5* (@: >4** ( (404EfE``  (05405*(*4 *@>*(0000*4>54:E:0EY:0JY@45>EVNEJE@IWVTTF>PP5:4($)$0**15Z:01(*5YL44**((4*  *:: (*(*(( (*@>40P\:** * (**5:>( (>EE555:5(*:>:EPE***( (555:5@JNJF@@PNIFTY]lpq(((()4\:*@5Qc>004:@VV:( ( *( *44 ((((( ::b**P@44(@  004(  55:::@:4*4FF>TP>**40((4>>E5ETN@@>:\TJ;J\fw0(($$(*W{rLkFEZy46114fc`:>(*( ( *0* ((*4 *@EE (* (* * *004>:4045>EF:EE:**40*(405@>>ETNEJ>N@@:>E>>;:4(($$(*6ZZQ$ n4:>:4::::>**4( 0 (4( *:0 (*50( *   >@> ( 0(*4E5:E>>E>PP:EF* 50*054:@J>>QNNVTL>\LNVPC~Z6F((((6;>I$(`$0>NN>;6:64{J44b5(>0(*4*0*  *F5  *0((4   5(0( 0:@0 *444>0*>@JJ0::>6>0,;5455:@ENE@IWYOLFV@ZN`VbFY@:(((haLN$fWI:TTfEI6:6I5Pb@@0*54*:@(0* **5P0*  (0((E>( *( 00 (4(((4VT * (( *((*(400:*4,0:614>5:@TPF>CIZVLJJOP;@E?:;hE>(((((((Y];x,@5@6>@ObbbE0>F:05((:4(0( 05:E(*  *E E5 ((((0(( *5*  0( *05*(14,,,551)0;@>>JN@@J::YI@NCQ:V@656FOhcc((($$( @:4LZF:44@IIb:\45**0F@N4(@FYV0( 0P50**( ( **( ( (4(@0 ** 0 (*(( *6E@;0@5,,4:EJENF@@@,*@@14Elb;C0Ic(((($ $ (()>Q:I@Z***b:*0>J:@@>0**0\P@( 0* * *(*:( ( (05 4N ( *  (* ((((*((,EEF@@TJ60;ICJWJ@@NE11EeC:Icbbe*5(((((($$((q;Y0LET450>b4:>6NYF@@005(4:** :(  5E0(*4:E4 4@**0 400  0*0 (*((0*0@F5@N@FO>1@E>FWE?CEE>>41>@@6IWe4NNF:@((((((((((ZWQF4b;C>@@ZPcP1;F54>44>0:F**( 0c5:0**F5( (* *@J 00(( 0JE* 0>4 (**0 **(((4Y`L1>I>NQ>4C?@EPOLILE?TNkv0,,0|e4F@Q(((((((((((($(:EQF0;J>CLP>;EVE>EE@>>@F00*(*N>:NN:@( (4((0((4(4(((PP0*@N5(4 0>:*((0(((4bP@IY@EPFE>E;@NIPN:CEPNJVy5I?F;f6ZL((((((((((((;*40CY,:P>?;,15,>NFEF5:>>F4050***(EP5 (05(0( (40555 0F((NV: (0:>NY\**0*0**05@bcT]J@JJJ>@LJI@CE55>66WcO0)$OkY@C>((((((((((( 145?Om]:5:Z4F6,(0TNFE@:>1,>44::@E50@F (0@0(*((0( (P@>>J  0E5 *550@4*0*005:5@Ero]hVETFIC66PVE?I5;>6;JZT1;YPYr0((((((((((((( TEe~PW0*:000,40@TJFF@E>*),,005>J5>@> (:>>*( ( :@:0* (((0 (0**(5;Tf\YbYePETFOO>;QW@CW>IlIhcq@ZeY>bY((((((((((((((pbbI(PJ1*1*,150>>YPJ@414104415>F@T:EE4* :::*004(   (((00 ((*0((*0000>kbTEYICEQPZ\fPO`YLOFII@VfOO:::FLE((((((((((((((((((((cI()*?0PL??:45IC15144E>E>NNF440(**(4@@45400  (0( (*0** (*5**EP4405@VN@:FNJPYPP`{]YnLakCQEaY\@@Qla:((((((((((((((((((($$c5*IJ?CPTq;C>:LV4:545TPpT45F50FJ*(EJ5(*(0* JN @E**(4:4(*(*4**PT@54N;::5:>br\kTYmkk{oe>PJEWb?6?,5?(((((((((((((((((((($$(PFN:E6*:YOr~ZFPTVF:115>F544:05@J4*>Y@*0* *E4 *4**:4(45 *054(*@:@J>E:55:F>behZfYIcrZEFwofaaI66E1;4*6((((((((((((((((((((((;:QJJ5;NVL5QhrEEOP>>1,>@J5:54>504:450(*5@( >( >5* (04**0 (>@4*404>N@PJ:544T\TZNZvmbVVT>LqIaF?J;V;>bNI(((((((((((((((((((((@44ENrIJY:141:NC:FII:J515F>>FE>T@>FNE*( *0:**  (04(*0**5(*( >\:5F4:@:4cTE?;IeZPZ:4>hhLE{r;a]@WPmF`Zp{I(((((((((((((((((((((Yz0F\Wkp0,FNE:?C;EW>@>:56:JEJVPNfPN40*(**((*:  (4((*(55(0*(@T54J4>E:44JPVqlY@@E1,4V]a;f@*6If4EpWJICC((((((((((((((((((((((`6|Q5P]\e\VE65>5E@>6J@41:JJVTckF@F\?>(* *(05F* ((4 ( ((0***5N@404E>JJ`1Y>pzQ;?4C656EZ>YEOcI0?Pe:((((((((((((((((((((((((`6EqF6:;5L40:E:45::>F@J:5,:FVJPJT@YN0,:*@*4* *:E@4 *4(**(*(40*(:EJ00:EJ5541*,wmkN5LzW1):n@5;qE;ZT>((((((((((((((((((((((((((($]OmI@:51>E?:,4EPN:VVQ;1>@NJ\]60@L1,@0*05*  055(( ( *0500*5:E54:>NIN@FCCb>af01T?J100*JI1@OmhL,0(((((((((((((((((((((((((((($ ]Na15F@NJ6144JZC@NN\;:@JkE\Z5,$656\40*5*  *( (* (*5F4045>>4:::PYCPQmJ4J\h0P\Pn,],*(((((;ZT4;((((((((((((((((((((((((((((((@NZ1CPJTY5EE@EN@C::@16?mp45),,6?NI>55:@*4: *0((0*( *445555::5:5@EEVfNFQII@*WTqc(::(:l1*(((((((C((((((((((((((((((((((((((((((TTpm`IbkTNC:?JEVZP@>0;T@1,*,04?E@*55@1(>0 **0>F0*(4:0:F>:>FEF@N\VLCCQI>6E;,EEJJ55(T`,*((((((((O$((((((((((((((((((((((((((((((TpzZQFp`PE;6>FWQTV>)*:66FCNT6Y5((**41(04@4**45:4*44:FVY5>>@N4,>YTJ60?F6>rEEYYJ(J((TF)((((((((($V$((((((((((((((((((((((((((((((p`F弋@cy|c?@;;?NNh1,1EbQ0ZNJ6bC:01,>:>@*0>4**445045EPbE>N?>O0*>JOZ5,hbcTJYJYYqF((((T$(((((((((((((((((((((((((((((((((((((((((bT F?rVcb>JYVNTVZJ4`@E:FC\]b>>10COT>:>:445*05:N:45:EbJFJ>:?4;FC?IJ:LfmcJJ5(((*TP$((((((((((((((((((((((((((((((((((((((((((($FFEhQNJ\wpQI)1J1:1Z5:6y:51|]15P@54*5@@0004@@J>5@NJY\PP?>J@@Oq?Q>CNTaW~FIJ((((*5?n*)(((((((((((((((((((((((((((((((((((((((($ (@qcJCEE5(?;6>>CQN5:L>OQJJ:J@@>40;:,,5:N?NJ:>FE@cffEJ:>J;Vc1,;Cp>@55EcT((((*Nph5)((((((((((((((((((((((((((((((((((((((($$$(LYhehE4>CC1NP44?O]60]Lz4FcZW4;@65:1FE6,;NT16E@@FVJYkV>E11N16ElV,FhYCCEEE((((()*?`0((((((((((((((((((((((((((((((((((((((( (L6bob`Nf\:5NI*?1Y>@:Np])*`c4]b;5P@NNTJ\cm?45>>FE@FOC041:h?E,pQT@(((((((EEE(((((,5v,((((((((((((((((((((((((((((((((((((((( (:;5(kf5,zE?E0((bNo4QL*PP@PL>:PLC,0ETolZT>55>@PPO\@5:OYE4cp>@(((((((((E((((((,,(((((((((((((((((((((((((((((((((((((((((((Fw(,IbQLZZ\PnN$((bN:W50VJhF@\V@;;I5**NWIN@;,*1>EF]`Z\\`\LNNccppp@c((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((($$0,x?$ aNJLmT((((((*16ENba@>FJ>>61,)0N`C@>(06FTTJywEF`pmLccc(Ecc@@((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((($$;QkT($N\ENT(((((((T**TWEEJ>:J@11*4@TL]T;(afb??\]EFY{@TTTT(@ccT((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((bbh(((E**Y4(((((()0c4JEENF;5JC;@6>5,JcE40@N`E?NYZcWVPNcTT(((QqcT5(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((b(($ $($))6E?((((((>Z~L>F`ZC5JbF@CC0(1VcC64LZNFEENYOVV@,(T((((@LTT5(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((bb(($$(($(n6;4((((($0r\>FkoyJ6IVF@E,11,JTQN>fwJFP4CFV`h*((cb((((5Tc5(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((b(((((((((4?4(((($()00IVFNpoT@@FJZW*16I>kcT,|kJW64Epla$(((((((((5E(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((**,IYCrbyykVJE\*;]>(**aTVo\c@P;Q,CyP?(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0,1IlJ\qe??\0;6e44\,??WkZT0W4?CN*05~p?((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((($,NOOhoO4N??5E\PLJPN01FTZc?0W;@vN)1>~P((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((($$>I@>14T{E6@`ocEVkI46fmaZbycC44a4e妳?((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((TOPON`E>:>WVccrq{E?]mc\Z6Q6,PI0|O((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((*@@EE>:@WWbcVOE?WPQr`Y`z@>4:@Q1P(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\PEEEE淆WZEc>>Y,?>W?PIWC10~hr?((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((bZ?TeP]`▅]\TCL*?0VYJY>CN幀?(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((EvZWpkNJOL{Wk;hIEI;6vZ;(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;fcbx:1:E46?LYJcYT>@C50Yb,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;EObTp]I(0:bnZI\W@,:60,1,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((EElb\@EE4((0Oalbb()*,$$(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((4\cc??4((((5aaN\fc4(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((lablgl-1.07/Togl/src/lablgl.bat000077500000000000000000000002011437514534100163220ustar00rootroot00000000000000@rem toplevel for lablgl with Togl support ocaml -I +labltk -I +lablGL labltk.cma lablgl.cma togl.cma %1 %2 %3 %4 %5 %6 %7 %8 %9 lablgl-1.07/Togl/src/ml_togl.c000066400000000000000000000107441437514534100162100ustar00rootroot00000000000000/* $Id: ml_togl.c,v 1.16 2006-03-23 06:01:55 garrigue Exp $ */ #define CAML_NAME_SPACE #ifdef _WIN32 #include #endif #include #ifdef __APPLE__ #include #else #include #endif #include #include #include #include #include #include #include #include "togl.h" #include "ml_gl.h" #include "togl_tags.h" /* extern Tcl_Interp *cltclinterp; */ /* The Tcl interpretor */ /* extern void tk_error (char *message); */ /* Raise TKerror */ int TOGLenum_val(value tag) { switch(tag) { #include "togl_tags.c" } invalid_argument ("Unknown Togl tag"); } /* Avoid direct use of stderr */ void togl_prerr(const char *msg) { value ml_msg = copy_string(msg); value *prerr = caml_named_value("togl_prerr"); if (!prerr) caml_failwith(msg); caml_callback_exn(*prerr, ml_msg); } CAMLprim value ml_Togl_Init (value unit) /* ML */ { value *interp = caml_named_value("cltclinterp"); Tcl_Interp *cltclinterp = (interp ? (Tcl_Interp *) Nativeint_val(Field(*interp,0)) : NULL); if (cltclinterp == NULL || Togl_Init(cltclinterp) == TCL_ERROR) raise_with_string(*caml_named_value("tkerror"), "Togl_Init failed"); return Val_unit; } /* Does not register the structure with Caml ! static value Val_togl (struct Togl *togl) { value wrapper = alloc(1,No_scan_tag); Field(wrapper,0) = (value) togl; return wrapper; } */ enum { CreateFunc = 0, DisplayFunc, ReshapeFunc, DestroyFunc, TimerFunc, OverlayDisplayFunc, RenderFunc, LastFunc }; static value *callbacks = NULL; #define CALLBACK(func) \ static void callback_##func (struct Togl *togl) \ { callback (Field(*callbacks, func), Val_addr(togl)); } #define CALLBACK_const(func) \ static void callback_##func (const struct Togl *togl) \ { callback (Field(*callbacks, func), Val_addr(togl)); } #define ENABLER(func) \ CAMLprim value ml_Togl_##func (value unit) \ { if (callbacks == NULL) callbacks = caml_named_value ("togl_callbacks"); \ Togl_##func (callback_##func); \ return Val_unit; } CALLBACK (CreateFunc) CALLBACK (DisplayFunc) CALLBACK (ReshapeFunc) CALLBACK (DestroyFunc) CALLBACK (TimerFunc) CALLBACK (OverlayDisplayFunc) CALLBACK_const (RenderFunc) ENABLER (CreateFunc) ENABLER (DisplayFunc) ENABLER (ReshapeFunc) ENABLER (DestroyFunc) ENABLER (TimerFunc) ENABLER (OverlayDisplayFunc) ML_0 (Togl_ResetDefaultCallbacks) ML_1 (Togl_PostRedisplay, Addr_val) ML_1 (Togl_SwapBuffers, Addr_val) ML_1_ (Togl_Ident, Addr_val, copy_string) ML_1_ (Togl_Width, Addr_val, Val_int) ML_1_ (Togl_Height, Addr_val, Val_int) CAMLprim value ml_Togl_LoadBitmapFont (value togl, value font) /* ML */ { char *fontname = NULL; if (Is_block(font)) fontname = String_val (Field(font,0)); else switch (font) { case MLTAG_Fixed_8x13: fontname = TOGL_BITMAP_8_BY_13; break; case MLTAG_Fixed_9x15: fontname = TOGL_BITMAP_9_BY_15; break; case MLTAG_Times_10: fontname = TOGL_BITMAP_TIMES_ROMAN_10; break; case MLTAG_Times_24: fontname = TOGL_BITMAP_TIMES_ROMAN_24; break; case MLTAG_Helvetica_10: fontname = TOGL_BITMAP_HELVETICA_10; break; case MLTAG_Helvetica_12: fontname = TOGL_BITMAP_HELVETICA_12; break; case MLTAG_Helvetica_18: fontname = TOGL_BITMAP_HELVETICA_18; break; } return Val_int (Togl_LoadBitmapFont (Addr_val(togl), fontname)); } ML_2 (Togl_UnloadBitmapFont, Addr_val, Int_val) ML_2 (Togl_UseLayer, Addr_val, TOGLenum_val) #ifdef _WIN32 CAMLprim value ml_Togl_ShowOverlay(value v) { invalid_argument("Togl_ShowOverlay: not implemented"); return Val_unit; } #else ML_1 (Togl_ShowOverlay, Addr_val) #endif ML_1 (Togl_HideOverlay, Addr_val) ML_1 (Togl_PostOverlayRedisplay, Addr_val) ML_1_ (Togl_ExistsOverlay, Addr_val, Val_int) ML_1_ (Togl_GetOverlayTransparentValue, Addr_val, Val_int) CAMLprim value ml_Togl_DumpToEpsFile (value togl, value filename, value rgb) { if (callbacks == NULL) callbacks = caml_named_value ("togl_callbacks"); if (Togl_DumpToEpsFile(Addr_val(togl), String_val(filename), Int_val(rgb), callback_RenderFunc) == TCL_ERROR) raise_with_string(*caml_named_value("tkerror"), "Dump to EPS file failed"); return Val_unit; } #if 0 && defined(_WIN32) && !defined(CAML_DLL) && (WINVER < 0x0500) /* VC7 or later, building with pre-VC7 runtime libraries */ long _ftol( double ); /* defined by VC6 C libs */ long _ftol2( double dblSource ) { return _ftol( dblSource ); } #endif lablgl-1.07/Togl/src/togl.ml000066400000000000000000000174321437514534100157070ustar00rootroot00000000000000(* $Id: togl.ml,v 1.23 2006-03-23 00:39:27 garrigue Exp $ *) open StdLabels open Tk open Protocol let may x name f = match x with None -> [] | Some a -> [TkToken name; TkToken (f a)] let cbool x = if x then "1" else "0" let cint = string_of_int let id x = x let togl_options_optionals f = fun ?accum ?accumalphasize ?accumbluesize ?accumgreensize ?accumredsize ?alpha ?alphasize ?auxbuffers ?bluesize ?depth ?depthsize ?double ?greensize ?height (* ?ident *) ?overlay ?privatecmap ?redsize ?rgba ?stencil ?stencilsize ?stereo (* ?time *) ?width -> f (may accum "-accum" cbool @ may accumalphasize "-accumalphasize" cint @ may accumbluesize "-accumbluesize" cint @ may accumgreensize "-accumgreensize" cint @ may accumredsize "-accumredsize" cint @ may alpha "-alpha" cbool @ may alphasize "-alphasize" cint @ may auxbuffers "-auxbuffers" cint @ may bluesize "-bluesize" cint @ may depth "-depth" cbool @ may depthsize "-depthsize" cint @ may double "-double" cbool @ may greensize "-greensize" cint @ may height "-height" cint (* @ may ident "-ident" id *) @ may overlay "-overlay" cbool @ may privatecmap "-privatecmap" cbool @ may redsize "-redsize" cint @ may rgba "-rgba" cbool @ may stencil "-stencil" cbool @ may stencilsize "-stencilsize" cint @ may stereo "-stereo" cbool (* @ may time "-time" cint *) @ may width "-width" cint) type t external init : unit -> unit = "ml_Togl_Init" external _create_func : unit -> unit = "ml_Togl_CreateFunc" external _display_func : unit -> unit = "ml_Togl_DisplayFunc" external _reshape_func : unit -> unit = "ml_Togl_ReshapeFunc" external _destroy_func : unit -> unit = "ml_Togl_DestroyFunc" external _timer_func : unit -> unit = "ml_Togl_TimerFunc" external _overlay_display_func : unit -> unit = "ml_Togl_OverlayDisplayFunc" external _reset_default_callbacks : unit -> unit = "ml_Togl_ResetDefaultCallbacks" external _post_redisplay : t -> unit = "ml_Togl_PostRedisplay" external _swap_buffers : t -> unit = "ml_Togl_SwapBuffers" external _ident : t -> string = "ml_Togl_Ident" external _height : t -> int = "ml_Togl_Height" external _width : t -> int = "ml_Togl_Width" type font = [ `Fixed_8x13 | `Fixed_9x15 | `Times_10 | `Times_24 | `Helvetica_10 | `Helvetica_12 | `Helvetica_18 | `Xfont of string ] external _load_bitmap_font : t -> font:font -> GlList.base = "ml_Togl_LoadBitmapFont" external _unload_bitmap_font : t -> base:GlList.base -> unit = "ml_Togl_UnloadBitmapFont" external _use_layer : t -> num:int -> unit = "ml_Togl_UseLayer" external _show_overlay : t -> unit = "ml_Togl_ShowOverlay" external _hide_overlay : t -> unit = "ml_Togl_HideOverlay" external _post_overlay_redisplay : t -> unit = "ml_Togl_PostOverlayRedisplay" external _exists_overlay : t -> bool = "ml_Togl_ExistsOverlay" external _get_overlay_transparent_value : t -> int = "ml_Togl_GetOverlayTransparentValue" external _dump_to_eps_file : t -> string -> bool -> unit = "ml_Togl_DumpToEpsFile" type w type widget = w Widget.widget let togl_table = Hashtbl.create 7 let wrap f (w : widget) = let togl = try Hashtbl.find togl_table w with Not_found -> raise (TkError "Unreferenced togl widget") in f togl let render = wrap _post_redisplay let swap_buffers = wrap _swap_buffers let height = wrap _height let width = wrap _width let load_bitmap_font = wrap _load_bitmap_font let unload_bitmap_font = wrap _unload_bitmap_font let use_layer = wrap _use_layer let show_overlay = wrap _show_overlay let hide_overlay = wrap _hide_overlay let overlay_redisplay = wrap _post_overlay_redisplay let exists_overlay = wrap _exists_overlay let get_overlay_transparent_value = wrap _get_overlay_transparent_value let make_current togl = ignore (tkEval [|TkToken (Widget.name togl); TkToken "makecurrent"|]) let null_func _ = () let display_table = Hashtbl.create 7 and reshape_table = Hashtbl.create 7 and overlay_table = Hashtbl.create 7 let cb_of_togl table togl = try let key = _ident togl in let cb = Hashtbl.find table key in ignore (tkEval [|TkToken key; TkToken "makecurrent"|]); cb () with Not_found -> () let create_id = 0 and display_id = 1 and reshape_id = 2 and destroy_id = 3 and timer_id = 4 and overlay_display_id = 5 and render_id = 6 let callback_table = [|null_func; cb_of_togl display_table; cb_of_togl reshape_table; null_func; null_func; cb_of_togl overlay_table; null_func|] let () = Callback.register "togl_callbacks" callback_table; (* Also export an error-reporting function *) Callback.register "togl_prerr" (fun msg -> prerr_string msg; flush stderr) let callback_func table (w : widget) ~cb = let key = Widget.name w in (try Hashtbl.remove table key with Not_found -> ()); Hashtbl.add table key cb let display_func = callback_func display_table let reshape_func w ~cb = make_current w; cb (); callback_func reshape_table w ~cb let overlay_display_func = callback_func overlay_table let dump_to_eps_file ~filename ?(rgba=false) ?render togl = let render = match render with Some f -> f | None -> try Hashtbl.find display_table (_ident togl) with Not_found -> raise (TkError "Togl.dump_to_eps_file : no render function") in callback_table.(render_id) <- (fun _ -> render()); _dump_to_eps_file togl filename rgba let dump_to_eps_file ~filename ?rgba ?render = wrap (dump_to_eps_file ~filename ?rgba ?render) let rec timer_func ~ms ~cb = ignore (Timer.add ~ms ~callback:(fun () -> cb (); timer_func ~ms ~cb)) let configure ?height ?width w = let options = may height "-height" cint @ may width "-width" cint in tkEval [|TkToken (Widget.name w); TkTokenList options|] (* class widget w t = val w : widget = w val t = t method widget = w method name = coe w method configure = configure ?w method bind = bind w method redisplay = post_redisplay t method swap_buffers = swap_buffers t method width = width t method height = height t method load_font = load_bitmap_font t method unload_font = unload_bitmap_font t method use_layer = use_layer t method show_overlay = show_overlay t method hide_overlay = hide_overlay t method overlay_redisplay = post_overlay_redisplay t method exist_overlay = exists_overlay t method overlay_transparent_value = get_overlay_transparent_value t method dump_to_eps_file = dump_to_eps_file t method make_current = tkEval [|TkToken (Widget.name w); TkToken "makecurrent"|]; () end *) let ready = ref false let init_togl () = init (); _create_func (); _display_func (); _reshape_func (); _overlay_display_func (); _destroy_func (); ready := true let create ?name = togl_options_optionals (fun options parent -> prerr_endline "Before init"; if not !ready then init_togl (); prerr_endline "After init"; let w : widget = Widget.new_atom "togl" ~parent ?name in let togl = ref None in callback_table.(create_id) <- (fun t -> togl := Some t; Hashtbl.add togl_table w t); callback_table.(destroy_id) <- (fun t -> begin try Hashtbl.remove togl_table w with Not_found -> () end; List.iter [display_table; reshape_table; overlay_table] ~f: begin fun tbl -> try Hashtbl.remove tbl (Widget.name w) with Not_found -> () end); prerr_endline "Before create"; let command = [|TkToken "togl"; TkToken (Widget.name w); TkToken "-ident"; TkToken (Widget.name w); TkTokenList options|] in let _res : string = try tkEval command with TkError "invalid command name \"togl\"" -> raise (TkError "Togl initialization failed") in prerr_endline "After create"; match !togl with None -> raise (TkError "Togl widget creation failed") | Some t -> w) lablgl-1.07/Togl/src/togl.mli000066400000000000000000000031431437514534100160520ustar00rootroot00000000000000(* $Id: togl.mli,v 1.6 2000-04-03 02:57:44 garrigue Exp $ *) type w type widget = w Widget.widget val render : widget -> unit val swap_buffers : widget -> unit val height : widget -> int val width : widget -> int type font = [ `Fixed_8x13 | `Fixed_9x15 | `Times_10 | `Times_24 | `Helvetica_10 | `Helvetica_12 | `Helvetica_18 | `Xfont of string ] val load_bitmap_font : widget -> font:font -> GlList.base val unload_bitmap_font : widget -> base:GlList.base -> unit val use_layer : widget -> num:int -> unit val show_overlay : widget -> unit val hide_overlay : widget -> unit val overlay_redisplay : widget -> unit val exists_overlay : widget -> bool val get_overlay_transparent_value : widget -> int val make_current : widget -> unit val display_func : widget -> cb:(unit -> unit) -> unit val reshape_func : widget -> cb:(unit -> unit) -> unit val overlay_display_func : widget -> cb:(unit -> unit) -> unit val dump_to_eps_file : filename:string -> ?rgba:bool -> ?render:(unit -> unit) -> widget -> unit val timer_func : ms:int -> cb:(unit -> unit) -> unit val configure : ?height:int -> ?width:int -> widget -> string val create : ?name:string -> ?accum:bool -> ?accumalphasize:int -> ?accumbluesize:int -> ?accumgreensize:int -> ?accumredsize:int -> ?alpha:bool -> ?alphasize:int -> ?auxbuffers:int -> ?bluesize:int -> ?depth:bool -> ?depthsize:int -> ?double:bool -> ?greensize:int -> ?height:int -> ?overlay:bool -> ?privatecmap:bool -> ?redsize:int -> ?rgba:bool -> ?stencil:bool -> ?stencilsize:int -> ?stereo:bool -> ?width:int -> 'a Widget.widget -> widget lablgl-1.07/Togl/src/togl_tags.var000066400000000000000000000004451437514534100171010ustar00rootroot00000000000000overlay normal $$ Fixed_8x13 -> TOGL_BITMAP_8_BY_13 Fixed_9x15 -> TOGL_BITMAP_9_BY_15 Times_10 -> TOGL_BITMAP_TIMES_ROMAN_10 Times_24 -> TOGL_BITMAP_TIMES_ROMAN_24 Helvetica_10 -> TOGL_BITMAP_HELVETICA_10 Helvetica_12 -> TOGL_BITMAP_HELVETICA_12 Helvetica_18 -> TOGL_BITMAP_HELVETICA_18 Xfont lablgl-1.07/src/000077500000000000000000000000001437514534100134745ustar00rootroot00000000000000lablgl-1.07/src/.cvsignore000066400000000000000000000002441437514534100154740ustar00rootroot00000000000000var2def var2switch gl_tags.c gl_tags.h glu_tags.c glu_tags.h raw_tags.c raw_tags.h togl_tags.c togl_tags.h build.ml lablgltop lablgl *.dll *.so *.exp *.lib .depend lablgl-1.07/src/.depend000066400000000000000000000034071437514534100147400ustar00rootroot00000000000000build.cmo: build.cmx: gl.cmo: gl.cmi gl.cmx: gl.cmi glArray.cmo: raw.cmi glDraw.cmi gl.cmi glArray.cmi glArray.cmx: raw.cmx glDraw.cmx gl.cmx glArray.cmi glClear.cmo: gl.cmi glClear.cmi glClear.cmx: gl.cmx glClear.cmi glDraw.cmo: raw.cmi glPix.cmi gl.cmi glDraw.cmi glDraw.cmx: raw.cmx glPix.cmx gl.cmx glDraw.cmi glFunc.cmo: gl.cmi glFunc.cmi glFunc.cmx: gl.cmx glFunc.cmi glLight.cmo: gl.cmi glLight.cmi glLight.cmx: gl.cmx glLight.cmi glList.cmo: glList.cmi glList.cmx: glList.cmi glMap.cmo: raw.cmi glMap.cmi glMap.cmx: raw.cmx glMap.cmi glMat.cmo: raw.cmi glMat.cmi glMat.cmx: raw.cmx glMat.cmi glMisc.cmo: raw.cmi glMisc.cmi glMisc.cmx: raw.cmx glMisc.cmi glPix.cmo: raw.cmi gl.cmi glPix.cmi glPix.cmx: raw.cmx gl.cmx glPix.cmi glShader.cmo: glShader.cmi glShader.cmx: glShader.cmi glTex.cmo: raw.cmi glPix.cmi glMisc.cmi gl.cmi glTex.cmi glTex.cmx: raw.cmx glPix.cmx glMisc.cmx gl.cmx glTex.cmi gluMat.cmo: gl.cmi gluMat.cmi gluMat.cmx: gl.cmx gluMat.cmi gluMisc.cmo: raw.cmi glTex.cmi glPix.cmi gl.cmi gluMisc.cmi gluMisc.cmx: raw.cmx glTex.cmx glPix.cmx gl.cmx gluMisc.cmi gluNurbs.cmo: raw.cmi glMap.cmi gl.cmi gluNurbs.cmi gluNurbs.cmx: raw.cmx glMap.cmx gl.cmx gluNurbs.cmi gluQuadric.cmo: gluQuadric.cmi gluQuadric.cmx: gluQuadric.cmi gluTess.cmo: gluTess.cmi gluTess.cmx: gluTess.cmi raw.cmo: raw.cmi raw.cmx: raw.cmi var2def.cmo: var2def.cmx: var2switch.cmo: var2switch.cmx: gl.cmi: glArray.cmi: raw.cmi glDraw.cmi glClear.cmi: gl.cmi glDraw.cmi: glPix.cmi gl.cmi glFunc.cmi: gl.cmi glLight.cmi: gl.cmi glList.cmi: glMap.cmi: raw.cmi glMat.cmi: raw.cmi gl.cmi glMisc.cmi: raw.cmi glPix.cmi: raw.cmi gl.cmi glShader.cmi: glTex.cmi: glPix.cmi gl.cmi gluMat.cmi: gl.cmi gluMisc.cmi: glTex.cmi glPix.cmi gl.cmi gluNurbs.cmi: raw.cmi glMap.cmi gl.cmi gluQuadric.cmi: gluTess.cmi: raw.cmi: lablgl-1.07/src/Makefile000066400000000000000000000062171437514534100151420ustar00rootroot00000000000000# Include shared parts TOPDIR = .. include ../Makefile.common # Composite options INCLUDES = $(GLINCLUDES) $(XINCLUDES) LIBS = $(GLLIBS) $(XLIBS) LIBDIRS = OCAMLINC=-I +labltk # Files LIBOBJS = raw.cmo \ gl.cmo glLight.cmo glList.cmo glMap.cmo \ glMat.cmo glMisc.cmo glPix.cmo glClear.cmo \ glTex.cmo glDraw.cmo glFunc.cmo gluMisc.cmo \ gluNurbs.cmo gluQuadric.cmo gluTess.cmo gluMat.cmo \ glArray.cmo glShader.cmo MLOBJS = $(LIBOBJS) togl.cmo OPTOBJS = $(LIBOBJS:.cmo=.cmx) COBJS = ml_gl$(XO) ml_glu$(XO) ml_raw$(XO) ml_glarray$(XO) \ ml_glutess$(XO) ml_shader$(XO) TOGLOBJS = ml_togl$(XO) $(TOGLDIR)/togl$(XO) CAMLP4GEN = var2def.ml var2switch.ml all: tools $(MAKE) lablgl.cma opt: lablgl.cmxa tools: var2def$(XE) var2switch$(XE) var2def.cmo: var2def.ml $(OCAMLFIND) $(COMPILER) -package camlp-streams $< var2def$(XE): var2def.cmo $(OCAMLFIND) $(LINKER) -package camlp-streams -linkpkg $< -o $@ var2switch.cmo: var2switch.ml $(OCAMLFIND) $(COMPILER) -package camlp-streams $< var2switch$(XE): var2switch.cmo $(OCAMLFIND) $(LINKER) -package camlp-streams -linkpkg $< -o $@ ifeq ($(TOOLCHAIN), msvc) liblablgl$(XA): $(COBJS) $(MKLIB)$@ $(COBJS) dlllablgl.dll: $(COBJS:$(XO)=.d$(XO)) $(MKDLL)$@ $(COBJS:$(XO)=.d$(XO)) $(GLLIBS) $(OCAMLDLL) lablgl.cma: liblablgl$(XA) dlllablgl.dll $(LIBOBJS) $(CONFIG) $(LINKER) -a -o $@ $(LIBOBJS) \ -cclib -llablgl -dllib -llablgl \ -cclib "$(GLLIBS)" lablgl.cmxa: liblablgl$(XA) $(OPTOBJS) $(CONFIG) $(OPTLINK) -a -o $@ $(OPTOBJS) -cclib -llablgl \ -cclib "$(GLLIBS)" else liblablgl$(XA): lablgl.cma lablgl.cma: $(COBJS) $(LIBOBJS) $(CONFIG) $(LIBRARIAN) -o lablgl $(COBJS) $(LIBOBJS) $(GLLIBS) $(XLIBS) lablgl.cmxa: $(COBJS) $(OPTOBJS) $(CONFIG) $(LIBRARIAN) -o lablgl $(COBJS) $(OPTOBJS) $(GLLIBS) $(XLIBS) endif gl_tags.c: gl_tags.var $(VAR2SWITCH) -table GL_ < gl_tags.var > $@ glu_tags.c: glu_tags.var $(VAR2SWITCH) GLU_ < glu_tags.var > $@ build.ml: build.ml.in ../Makefile.config sed -e "s|@LABLGL_MLS@|$(LIBOBJS:.cmo=)|" \ -e "s|@TOGL_MLS@|togl|" \ -e "s|@GLUT_MLS@|glut|" \ -e "s|@GLLIBS@|$(GLLIBS0)|" \ -e "s|@TKLIBS@|$(TKLIBS0)|" \ -e "s|@GLUTLIBS@|$(GLUTLIBS0)|" < build.ml.in > $@ preinstall: build.ml if test -d "$(INSTALLDIR)"; then : ; else mkdir -p "$(INSTALLDIR)"; fi cp build.ml $(LIBOBJS:.cmo=.ml) $(LIBOBJS:.cmo=.mli) "$(INSTALLDIR)" cp liblablgl$(XA) "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) liblablgl$(XA) if test -f dlllablgl$(XS); then cp dlllablgl$(XS) "$(DLLDIR)"; fi install: preinstall cp $(LIBOBJS:.cmo=.cmi) lablgl.cma "$(INSTALLDIR)" @if test -f lablgl.cmxa; then $(MAKE) installopt; fi installopt: cp lablgl.cmxa lablgl$(XA) $(LIBOBJS:.cmo=.cmx) "$(INSTALLDIR)" cd "$(INSTALLDIR)" && $(RANLIB) lablgl$(XA) clean: rm -f *.cm* *.a *.o *.so *.lib *.obj *.exe *.opt *_tags.c *_tags.h *~ \ *.dll var2def$(XE) var2switch$(XE) lablgltop$(XE) lablgl$(XB) make-camlp4: $(CAMLP4GEN) clean-camlp4: rm -f $(CAMLP4GEN) depend: ocamldep -pp $(CAMLP4O) *.ml *.mli > .depend #dependencies ml_gl$(XO): ml_gl.h gl_tags.h gl_tags.c ml_raw.h ml_glu$(XO) ml_glutess$(XO) : ml_gl.h ml_glu.h glu_tags.h glu_tags.c ml_raw$(XO): raw_tags.h ml_raw.h include .depend lablgl-1.07/src/build.ml.in000077500000000000000000000105531437514534100155410ustar00rootroot00000000000000(* $Id: build.ml.in,v 1.5 2008-12-26 07:13:21 garrigue Exp $ *) (* A script to build lablGL libraries *) open StdLabels let ocamlc = ref "ocamlc.opt" let ocamlopt = ref "ocamlopt.opt" let flags = ref "-w s -I +labltk" let ccomp_type = ref "msvc" (* "msvc" for MSVC++, "cc" for Mingw. Attempt to autodetect *) let split ?(sep = [' ';'\t';'\r';'\n']) s = let len = String.length s in let rec loop last cur acc = if cur > len then acc else let next = cur+1 in if cur = len || List.mem s.[cur] sep then if cur > last then loop next next (String.sub s ~pos:last ~len:(cur-last) :: acc) else loop next next acc else loop last next acc in List.rev (loop 0 0 []) let lablgl_mls = split "@LABLGL_MLS@" let togl_mls = split "@TOGL_MLS@" let glut_mls = split "@GLUT_MLS@" let gl_libs = "@GLLIBS@" let tk_libs = "@TKLIBS@ " let glut_libs = "@GLUTLIBS@ " (* Hack to check for mingw *) let () = try let ic = open_in "../Makefile.config" in while true do let s = input_line ic in match split ~sep:[' ';'\t';'='] s with "CCOMPTYPE" :: cc :: _ -> ccomp_type := cc | _ -> () done with _ -> () let has_mingw_import nm = (* sufficient for now... *) Filename.check_suffix nm "32.lib" let norm_libs libs = if !ccomp_type = "msvc" then libs else let libs = List.map (split libs) ~f: (fun nm -> if has_mingw_import nm then "-l" ^ Filename.chop_extension nm else nm) in String.concat " " libs let gl_libs = norm_libs gl_libs let tk_libs = norm_libs tk_libs let glut_libs = norm_libs glut_libs let exe cmd args = let cmd = String.concat " " (cmd :: !flags :: args) in print_endline cmd; flush stdout; let err = Sys.command cmd in if err > 0 then failwith ("error "^string_of_int err) let may_remove f = if Sys.file_exists f then Sys.remove f let byte () = List.iter (lablgl_mls @ togl_mls @ glut_mls) ~f: begin fun file -> if Sys.file_exists (file ^ ".mli") then exe !ocamlc ["-c"; file^".mli"]; exe !ocamlc ["-c"; file^".ml"] end; List.iter ["lablgl", lablgl_mls, gl_libs; "togl", togl_mls, tk_libs; "lablglut", glut_mls, glut_libs] ~f:begin fun (lib, mls,libs) -> let cmos = List.map mls ~f:(fun nm -> nm ^".cmo") in exe !ocamlc (["-a -o"; lib^".cma"; "-cclib -l"^lib; "-dllib -l"^lib; "-cclib \""^libs^"\""] @ cmos); List.iter cmos ~f:may_remove end let native () = List.iter (lablgl_mls @ togl_mls @ glut_mls) ~f: (fun file -> exe !ocamlopt ["-c"; file^".ml"]); List.iter ["lablgl", lablgl_mls, gl_libs; "togl", togl_mls, tk_libs; "lablglut", glut_mls, glut_libs] ~f:begin fun (lib, mls,libs) -> let cmxs = List.map mls ~f:(fun nm -> nm ^".cmx") in exe !ocamlopt (["-a -o"; lib^".cmxa"; "-cclib -l"^lib; "-cclib \""^libs^"\""] @ cmxs); List.iter mls ~f:(fun nm -> may_remove (nm ^ ".obj"); may_remove (nm ^ ".o")) end let rename ~ext1 ~ext2 file = if Sys.file_exists (file^ext1) && not (Sys.file_exists (file^ext2)) then begin prerr_endline ("Renaming "^file^ext1^" to "^file^ext2); Sys.rename (file^ext1) (file^ext2) end let () = try let arg = if Array.length Sys.argv > 1 then Sys.argv.(1) else "" in if arg <> "" && arg <> "byte" && arg <> "opt" then begin prerr_endline "ocaml build.ml [ byte | opt ]"; prerr_endline " byte build bytecode library only"; prerr_endline " opt build both bytecode and native (default)"; exit 2 end; byte (); if arg = "opt" || arg <> "byte" then begin try native () with Failure err -> prerr_endline ("Native build failed: " ^ err); prerr_endline "You can still use the bytecode version" end; if !ccomp_type = "msvc" then begin List.iter ["liblablgl"; "libtogl"; "liblablglut"] ~f:(rename ~ext1:".a" ~ext2:".noa"); List.iter ["liblablgl"; "libtogl"; "liblablglut"] ~f:(rename ~ext1:".nolib" ~ext2:".lib"); prerr_endline "Now ready to use on an OCaml MSVC port" end else begin List.iter ["liblablgl"; "libtogl"; "liblablglut"] ~f:(rename ~ext1:".noa" ~ext2:".a"); List.iter ["liblablgl"; "libtogl"; "liblablglut"] ~f:(rename ~ext1:".lib" ~ext2:".nolib"); prerr_endline "Now ready to use on an OCaml Mingw port" end with Failure err -> prerr_endline ("Bytecode failed: " ^ err) lablgl-1.07/src/gl.ml000066400000000000000000000061631437514534100144360ustar00rootroot00000000000000(* $Id: gl.ml,v 1.31 2012-03-06 03:31:02 garrigue Exp $ *) (* Register an exception *) exception GLerror of string let _ = Callback.register_exception "glerror" (GLerror "") (* Types common to all modules *) type rgb = float * float * float type rgba = float * float * float * float type point2 = float * float type point3 = float * float * float type point4 = float * float * float * float type vect3 = float * float *float type clampf = float type short = int type kind = [`bitmap|`byte|`float|`int|`short|`ubyte|`uint|`ushort] type real_kind = [`byte|`float|`int|`short|`ubyte|`uint|`ushort] type format = [`alpha|`bgr|`bgra|`blue|`color_index|`depth_component|`green|`luminance |`luminance_alpha|`red|`rgb|`rgba|`stencil_index] let format_size (#format as f) = match f with `rgba | `bgra -> 4 | `rgb | `bgr -> 3 | `luminance_alpha -> 2 | _ -> 1 type target = [`color_4|`index|`normal|`texture_coord_1|`texture_coord_2|`texture_coord_3 |`texture_coord_4|`trim_2|`trim_3|`vertex_3|`vertex_4] let target_size = function `index|`normal|`texture_coord_1 -> 1 | `texture_coord_2|`trim_2 -> 2 | `vertex_3|`texture_coord_3|`trim_3 -> 3 | `vertex_4|`color_4|`texture_coord_4 -> 4 type cmp_func = [`always|`equal|`gequal|`greater|`lequal|`less|`never|`notequal] type face = [`back|`both|`front] (* Basic functions *) external flush : unit -> unit = "ml_glFlush" external finish : unit -> unit = "ml_glFinish" type cap = [`alpha_test|`auto_normal|`blend|`clip_plane0|`clip_plane1|`clip_plane2 |`clip_plane3|`clip_plane4|`clip_plane5|`color_material|`cull_face |`depth_test|`dither|`fog|`light0|`light1|`light2|`light3|`light4|`light5 |`light6|`light7|`lighting|`line_smooth|`line_stipple |`index_logic_op |`color_logic_op |`map1_color_4|`map1_index|`map1_normal|`map1_texture_coord_1 |`map1_texture_coord_2|`map1_texture_coord_3|`map1_texture_coord_4 |`map1_vertex_3|`map1_vertex_4|`map2_color_4|`map2_index|`map2_normal |`map2_texture_coord_1|`map2_texture_coord_2|`map2_texture_coord_3 |`map2_texture_coord_4|`map2_vertex_3|`map2_vertex_4|`normalize|`point_smooth |`polygon_offset_fill|`polygon_offset_line|`polygon_offset_point |`polygon_smooth|`polygon_stipple|`scissor_test|`stencil_test|`texture_1d |`texture_2d|`texture_gen_q|`texture_gen_r|`texture_gen_s|`texture_gen_t] external enable : cap -> unit = "ml_glEnable" external disable : cap -> unit = "ml_glDisable" external is_enabled : cap -> bool = "ml_glIsEnabled" type error = [`no_error|`invalid_enum|`invalid_value|`invalid_operation |`stack_overflow|`stack_underflow|`out_of_memory|`table_too_large] external get_error : unit -> error = "ml_glGetError" let raise_error name = let err = get_error () in if err = `no_error then () else let s = List.assoc err [ `invalid_enum, "Invalid Enum"; `invalid_value, "Invalid Value"; `invalid_operation, "Invalid Operation"; `stack_overflow, "Stack Overflow"; `stack_underflow, "Stack Underflow"; `out_of_memory, "Out of Memory"; `table_too_large, "Table Too Large" ] in let s = if name = "" then s else (name ^ ": " ^ s) in raise (GLerror s) lablgl-1.07/src/gl.mli000066400000000000000000000044471437514534100146120ustar00rootroot00000000000000(* $Id: gl.mli,v 1.23 2012-03-06 03:31:02 garrigue Exp $ *) (* Exceptions *) exception GLerror of string (* Types common to all modules *) type rgb = float * float * float type rgba = float * float * float * float type point2 = float * float type point3 = float * float * float type point4 = float * float * float * float type vect3 = float * float *float type clampf = float type short = int type kind = [`bitmap|`byte|`float|`int|`short|`ubyte|`uint|`ushort] type real_kind = [`byte|`float|`int|`short|`ubyte|`uint|`ushort] type format = [`alpha|`bgr|`bgra|`blue|`color_index|`depth_component|`green|`luminance |`luminance_alpha|`red|`rgb|`rgba|`stencil_index] val format_size : [< format] -> int type target = [`color_4|`index|`normal|`texture_coord_1|`texture_coord_2|`texture_coord_3 |`texture_coord_4|`trim_2|`trim_3|`vertex_3|`vertex_4] val target_size : [< target] -> int type cmp_func = [`always|`equal|`gequal|`greater|`lequal|`less|`never|`notequal] type face = [`back|`both|`front] (* Basic functions *) val flush : unit -> unit val finish : unit -> unit type cap = [`alpha_test|`auto_normal|`blend|`clip_plane0|`clip_plane1|`clip_plane2 |`clip_plane3|`clip_plane4|`clip_plane5|`color_material|`cull_face |`depth_test|`dither|`fog|`light0|`light1|`light2|`light3|`light4|`light5 |`light6|`light7|`lighting|`line_smooth|`line_stipple |`index_logic_op |`color_logic_op |`map1_color_4|`map1_index|`map1_normal|`map1_texture_coord_1 |`map1_texture_coord_2|`map1_texture_coord_3|`map1_texture_coord_4 |`map1_vertex_3|`map1_vertex_4|`map2_color_4|`map2_index|`map2_normal |`map2_texture_coord_1|`map2_texture_coord_2|`map2_texture_coord_3 |`map2_texture_coord_4|`map2_vertex_3|`map2_vertex_4|`normalize|`point_smooth |`polygon_offset_fill|`polygon_offset_line|`polygon_offset_point |`polygon_smooth|`polygon_stipple|`scissor_test|`stencil_test|`texture_1d |`texture_2d|`texture_gen_q|`texture_gen_r|`texture_gen_s|`texture_gen_t] val enable : cap -> unit val disable : cap -> unit val is_enabled : cap -> bool type error = [`no_error|`invalid_enum|`invalid_value|`invalid_operation |`stack_overflow|`stack_underflow|`out_of_memory|`table_too_large] val get_error : unit -> error val raise_error : string -> unit (* raise GLerror if there is a current error, otherwise do nothing *) lablgl-1.07/src/glArray.ml000066400000000000000000000032701437514534100154310ustar00rootroot00000000000000(* $Id: glArray.ml,v 1.6 2008-10-30 07:51:33 garrigue Exp $ *) open Gl open Raw type kind = [`edge_flag | `texture_coord | `color | `index | `normal | `vertex ] let check_static func f raw = if not (Raw.static raw) then invalid_arg ("GlArray." ^ func ^ " : buffer must be static"); f raw external _edge_flag : [< `bitmap] Raw.t -> unit = "ml_glEdgeFlagPointer" let edge_flag raw = check_static "edge_flag" _edge_flag raw external _tex_coord : [< `one | `two | `three | `four] -> [< `short | `int | `float | `double] Raw.t -> unit = "ml_glTexCoordPointer" let tex_coord n = check_static "tex_coord" (_tex_coord n) external _color : [< `three | `four] -> [< `byte | `ubyte | `short | `ushort | `int | `uint | `float | `double] Raw.t -> unit = "ml_glColorPointer" let color n = check_static "color" (_color n) external _index : [< `ubyte | `short | `int | `float | `double] Raw.t -> unit = "ml_glIndexPointer" let index raw = check_static "index" _index raw external _normal : [< `byte | `short | `int | `float | `double] Raw.t -> unit = "ml_glNormalPointer" let normal raw = check_static "normal" _normal raw external _vertex : [< `two | `three | `four] -> [< `short | `int | `float | `double] Raw.t -> unit = "ml_glVertexPointer" let vertex n = check_static "vertex" (_vertex n) external enable : kind -> unit= "ml_glEnableClientState" external disable : kind -> unit = "ml_glDisableClientState" external element : int -> unit = "ml_glArrayElement" external draw_arrays : GlDraw.shape -> first:int -> count:int -> unit = "ml_glDrawArrays" external draw_elements : GlDraw.shape -> count:int -> [< `ubyte | `ushort | `uint] Raw.t -> unit = "ml_glDrawElements" lablgl-1.07/src/glArray.mli000066400000000000000000000043251437514534100156040ustar00rootroot00000000000000(** Vertex array manipulation functions *) (* $Id: glArray.mli,v 1.7 2008-10-25 02:22:58 garrigue Exp $ *) (** The six different kinds for array *) type kind = [ `color | `edge_flag | `index | `normal | `texture_coord | `vertex ] (** Tell openGL the address of the edgeFlag array. Raw array must be static. *) val edge_flag : [ `bitmap ] Raw.t -> unit (** Tell openGL the address of the texCoor array Raw array must be static. *) val tex_coord : [< `one | `two | `three | `four] -> [< `double | `float | `int | `short ] Raw.t -> unit (** Tell openGL the address of the color array Raw array must be static. *) val color : [< `three | `four] -> [< `byte | `double | `float | `int | `short | `ubyte | `uint | `ushort ] Raw.t -> unit (** Tell openGL the address of the index array Raw array must be static. *) val index : [< `double | `float | `int | `short | `ubyte ] Raw.t -> unit (** Tell openGL the address of the normal array Raw array must be static. *) val normal : [< `byte | `double | `float | `int | `short ] Raw.t -> unit (** Tell openGL the address of the vertex array Raw array must be static. *) val vertex : [< `two | `three | `four] -> [< `double | `float | `int | `short ] Raw.t -> unit (** Tell openGL the address of to use the specified array Raw array must be static. *) external enable : kind -> unit = "ml_glEnableClientState" (** Tell openGL the address of not to use the specified array Raw array must be static. *) external disable : kind -> unit = "ml_glDisableClientState" (* GlArray.element i sends to openGL the element i of all enabled arrays *) external element : int -> unit = "ml_glArrayElement" (* GlArray.draw_arrays shape i c sends to openGL a GlDraw.begins shape and all the element from i to i+c-1 of all enabled arrays and finally do a GlDraw.ends () *) external draw_arrays : GlDraw.shape -> first:int -> count:int -> unit = "ml_glDrawArrays" (* GlArray.draw_elements shape c tbl sends to openGL a GlDraw.begins shape and all the element from tbl[0] to tbl[c-1] of all enabled arrays and finally do a GlDraw.ends () *) external draw_elements : GlDraw.shape -> count:int -> [< `ubyte | `uint | `ushort ] Raw.t -> unit = "ml_glDrawElements" lablgl-1.07/src/glClear.ml000066400000000000000000000012221437514534100153740ustar00rootroot00000000000000(* $Id: glClear.ml,v 1.5 2000-04-12 07:40:23 garrigue Exp $ *) open Gl external accum : float -> float -> float -> float -> unit = "ml_glClearAccum" let accum ?(alpha=1.) (r,g,b : rgb) = accum r g b alpha type buffer = [`color|`depth|`accum|`stencil] external clear : buffer list -> unit = "ml_glClear" external color : red:float -> green:float -> blue:float -> alpha:float -> unit = "ml_glClearColor" let color ?(alpha=1.) (red, green, blue : rgb) = color ~red ~green ~blue ~alpha external depth : clampf -> unit = "ml_glClearDepth" external index : float -> unit = "ml_glClearIndex" external stencil : int -> unit = "ml_glClearStencil" lablgl-1.07/src/glClear.mli000066400000000000000000000006471437514534100155570ustar00rootroot00000000000000(* $Id: glClear.mli,v 1.3 1999-11-15 09:55:05 garrigue Exp $ *) type buffer = [`accum|`color|`depth|`stencil] val clear : buffer list -> unit (* glClear: clear the specified buffers *) val accum : ?alpha:float -> Gl.rgb -> unit val color : ?alpha:float -> Gl.rgb -> unit val depth : Gl.clampf -> unit val index : float -> unit val stencil : int -> unit (* Set the clear value for each buffer: glClearAccum etc *) lablgl-1.07/src/glDraw.ml000066400000000000000000000037721437514534100152570ustar00rootroot00000000000000(* $Id: glDraw.ml,v 1.6 2007-04-13 01:17:50 garrigue Exp $ *) open Gl external color : red:float -> green:float -> blue:float -> alpha:float -> unit = "ml_glColor4d" let color ?(alpha=1.) (red, green, blue : rgb) = color ~red ~green ~blue ~alpha external index : float -> unit = "ml_glIndexd" external cull_face : face -> unit = "ml_glCullFace" external edge_flag : bool -> unit = "ml_glEdgeFlag" external front_face : [`cw|`ccw] -> unit = "ml_glFrontFace" external line_width : float -> unit = "ml_glLineWidth" external line_stipple : factor:int -> pattern:short -> unit = "ml_glLineStipple" let line_stipple ?(factor=1) pattern = line_stipple ~factor ~pattern external point_size : float -> unit = "ml_glPointSize" external polygon_offset : factor:float -> units:float -> unit = "ml_glPolygonOffset" external polygon_mode : face:face -> [`point|`line|`fill] -> unit = "ml_glPolygonMode" external polygon_stipple : [`bitmap] Raw.t -> unit = "ml_glPolygonStipple" let polygon_stipple (img : GlPix.bitmap) = if GlPix.height img <> 32 || GlPix.width img <> 32 then invalid_arg "GlDraw.polygon_stipple"; polygon_stipple (GlPix.to_raw img) external shade_model : [`flat|`smooth] -> unit = "ml_glShadeModel" type shape = [ `points | `lines | `polygon | `triangles | `quads | `line_strip | `line_loop | `triangle_strip | `triangle_fan | `quad_strip ] external begins : shape -> unit = "ml_glBegin" external ends : unit -> unit = "ml_glEnd" external normal : x:float -> y:float -> z:float -> unit = "ml_glNormal3d" let normal ?(x=0.) ?(y=0.) ?(z=0.) () = normal ~x ~y ~z and normal3 (x,y,z) = normal ~x ~y ~z external rect : point2 -> point2 -> unit = "ml_glRectd" external vertex : x:float -> y:float -> ?z:float -> ?w:float -> unit -> unit = "ml_glVertex" let vertex2 (x,y : point2) = vertex ~x ~y () and vertex3 (x,y,z : point3) = vertex ~x ~y ~z () and vertex4 (x,y,z,w : point4) = vertex ~x ~y ~z ~w () external viewport : x:int -> y:int -> w:int -> h:int -> unit = "ml_glViewport" lablgl-1.07/src/glDraw.mli000066400000000000000000000026041437514534100154210ustar00rootroot00000000000000(* $Id: glDraw.mli,v 1.3 2007-04-13 01:17:50 garrigue Exp $ *) open Gl val color : ?alpha:float -> rgb -> unit (* Sets the current color *) val index : float -> unit (* Sets the current index *) val cull_face : face -> unit (* Specifies which faces are candidates for culling *) val front_face : [`ccw|`cw] -> unit (* Specifies wether front faces are clockwise or not *) val edge_flag : bool -> unit val line_width : float -> unit val line_stipple : ?factor:int -> short -> unit (* [line_stipple :factor pattern] sets the line stipple to the 16-bit integer [pattern]. Each bit is used [factor] times *) val point_size : float -> unit val polygon_offset : factor:float -> units:float -> unit val polygon_mode : face:face -> [`fill|`line|`point] -> unit val polygon_stipple : GlPix.bitmap -> unit val shade_model : [`flat|`smooth] -> unit val normal : ?x:float -> ?y:float -> ?z:float -> unit -> unit val normal3 : vect3 -> unit (* [glNormal] *) val rect : point2 -> point2 -> unit type shape = [`line_loop|`line_strip|`lines|`points|`polygon|`quad_strip|`quads |`triangle_fan|`triangle_strip|`triangles] val begins : shape -> unit val ends : unit -> unit val vertex : x:float -> y:float -> ?z:float -> ?w:float -> unit -> unit val vertex2 : point2 -> unit val vertex3 : point3 -> unit val vertex4 : point4 -> unit val viewport : x:int -> y:int -> w:int -> h:int -> unit lablgl-1.07/src/glFunc.ml000066400000000000000000000040631437514534100152470ustar00rootroot00000000000000(* $Id: glFunc.ml,v 1.7 2000-04-12 07:40:23 garrigue Exp $ *) open Gl external accum : op:[`accum|`load|`add|`mult|`return] -> float -> unit = "ml_glAccum" external alpha_func : cmp_func -> ref:clampf -> unit = "ml_glAlphaFunc" type sfactor = [ `zero | `one | `dst_color | `one_minus_dst_color | `src_alpha | `one_minus_src_alpha | `dst_alpha | `one_minus_dst_alpha | `src_alpha_saturate ] type dfactor = [ `zero | `one | `src_color | `one_minus_src_color | `src_alpha | `one_minus_src_alpha | `dst_alpha | `one_minus_dst_alpha ] external blend_func : src:sfactor -> dst:dfactor -> unit = "ml_glBlendFunc" external color_mask : bool -> bool -> bool -> bool -> unit = "ml_glColorMask" let color_mask ?(red=false) ?(green=false) ?(blue=false) ?(alpha=false) ()= color_mask red green blue alpha external depth_func : cmp_func -> unit = "ml_glDepthFunc" external depth_mask : bool -> unit = "ml_glDepthMask" external depth_range : near:float -> far:float -> unit = "ml_glDepthRange" type draw_buffer = [`none|`front_left|`front_right|`back_left|`back_right |`front|`back|`left|`right|`front_and_back|`aux of int] external draw_buffer : draw_buffer -> unit = "ml_glDrawBuffer" external index_mask : int -> unit = "ml_glIndexMask" type logic_op = [`clear|`set|`copy|`copy_inverted|`noop|`invert|`And|`nand|`Or|`nor |`xor|`equiv|`and_reverse|`and_inverted|`or_reverse|`or_inverted] external logic_op : logic_op -> unit = "ml_glLogicOp" type read_buffer = [`front_left|`front_right|`back_left|`back_right|`front|`back |`left|`right|`aux of int] external read_buffer : read_buffer -> unit = "ml_glReadBuffer" external stencil_func : cmp_func -> ref:int -> mask:int -> unit = "ml_glStencilFunc" external stencil_mask : int -> unit = "ml_glStencilMask" type stencil_op = [`keep|`zero|`replace|`incr|`decr|`invert] external stencil_op : fail:stencil_op -> zfail:stencil_op -> zpass:stencil_op -> unit = "ml_glStencilOp" let stencil_op ?(fail=`keep) ?(zfail=`keep) ?(zpass=`keep) () = stencil_op ~fail ~zfail ~zpass lablgl-1.07/src/glFunc.mli000066400000000000000000000027521437514534100154230ustar00rootroot00000000000000(* $Id: glFunc.mli,v 1.4 2000-04-03 02:57:41 garrigue Exp $ *) val accum : op:[`accum|`add|`load|`mult|`return] -> float -> unit val alpha_func : Gl.cmp_func -> ref:Gl.clampf -> unit type sfactor = [`dst_alpha|`dst_color|`one|`one_minus_dst_alpha|`one_minus_dst_color |`one_minus_src_alpha|`src_alpha|`src_alpha_saturate|`zero] type dfactor = [`dst_alpha|`one|`one_minus_dst_alpha|`one_minus_src_alpha |`one_minus_src_color|`src_alpha|`src_color|`zero] val blend_func : src:sfactor -> dst:dfactor -> unit val color_mask : ?red:bool -> ?green:bool -> ?blue:bool -> ?alpha:bool -> unit -> unit val depth_func : Gl.cmp_func -> unit val depth_mask : bool -> unit val depth_range : near:float -> far:float -> unit val index_mask : int -> unit val stencil_func : Gl.cmp_func -> ref:int -> mask:int -> unit val stencil_mask : int -> unit type stencil_op = [`decr|`incr|`invert|`keep|`replace|`zero] val stencil_op : ?fail:stencil_op -> ?zfail:stencil_op -> ?zpass:stencil_op -> unit -> unit type logic_op = [`And|`Or|`and_inverted|`and_reverse|`clear|`copy|`copy_inverted|`equiv |`invert|`nand|`noop|`nor|`or_inverted|`or_reverse|`set|`xor] val logic_op : logic_op -> unit type draw_buffer = [`aux of int|`back|`back_left|`back_right|`front|`front_and_back|`front_left |`front_right|`left|`none|`right] val draw_buffer : draw_buffer -> unit type read_buffer = [`aux of int|`back|`back_left|`back_right|`front|`front_left|`front_right |`left|`right] val read_buffer : read_buffer -> unit lablgl-1.07/src/glLight.ml000066400000000000000000000025051437514534100154220ustar00rootroot00000000000000(* $Id: glLight.ml,v 1.7 2003-04-24 16:42:59 erickt Exp $ *) open Gl type color_material = [`emission|`ambient|`diffuse|`specular|`ambient_and_diffuse] external color_material : face:face -> color_material -> unit = "ml_glColorMaterial" type fog_param = [ `mode of [`linear|`exp|`exp2] | `density of float | `start of float | `End of float | `index of float | `color of rgba ] external fog : fog_param -> unit = "ml_glFog" type light_param = [ `ambient of rgba | `diffuse of rgba | `specular of rgba | `position of point4 | `spot_direction of point3 | `spot_exponent of float | `spot_cutoff of float | `constant_attenuation of float | `linear_attenuation of float | `quadratic_attenuation of float ] external light : num:int -> light_param -> unit = "ml_glLight" type light_model_param = [ `ambient of rgba | `local_viewer of bool | `two_side of bool | `color_control of [`separate_specular_color | `single_color] ] external light_model : light_model_param -> unit = "ml_glLightModel" type material_param = [ `ambient of rgba | `diffuse of rgba | `specular of rgba | `emission of rgba | `shininess of float | `ambient_and_diffuse of rgba | `color_indexes of (float * float * float) ] external material : face:face -> material_param -> unit = "ml_glMaterial" lablgl-1.07/src/glLight.mli000066400000000000000000000022241437514534100155710ustar00rootroot00000000000000(* $Id: glLight.mli,v 1.7 2003-04-24 16:42:59 erickt Exp $ *) open Gl type color_material = [`emission|`ambient|`diffuse|`specular|`ambient_and_diffuse] val color_material : face:face -> color_material -> unit type fog_param = [ `mode of [`linear|`exp|`exp2] | `density of float | `start of float | `End of float | `index of float | `color of rgba ] val fog : fog_param -> unit type light_param = [ `ambient of rgba | `diffuse of rgba | `specular of rgba | `position of point4 | `spot_direction of point3 | `spot_exponent of float | `spot_cutoff of float | `constant_attenuation of float | `linear_attenuation of float | `quadratic_attenuation of float ] val light : num:int -> light_param -> unit val light_model : [ `ambient of rgba | `local_viewer of bool | `two_side of bool | `color_control of [`separate_specular_color|`single_color] ] -> unit type material_param = [ `ambient of rgba | `diffuse of rgba | `specular of rgba | `emission of rgba | `shininess of float | `ambient_and_diffuse of rgba | `color_indexes of (float * float * float) ] val material : face:face -> material_param -> unit lablgl-1.07/src/glList.ml000066400000000000000000000015171437514534100152700ustar00rootroot00000000000000(* $Id: glList.ml,v 1.4 2000-04-12 07:40:24 garrigue Exp $ *) type t = int type base = int external is_list : t -> bool = "ml_glIsList" external gen_lists : len:int -> base = "ml_glGenLists" external delete_lists : base -> len:int -> unit = "ml_glDeleteLists" external begins : t -> mode:[`compile|`compile_and_execute] -> unit = "ml_glNewList" external ends : unit -> unit = "ml_glEndList" external call : t -> unit = "ml_glCallList" external call_lists : [ `byte of string | `int of int array] -> unit = "ml_glCallLists" external list_base : base -> unit = "ml_glListBase" let nth base ~pos = base + pos let create mode = let l = gen_lists ~len:1 in begins l ~mode; l let delete l = delete_lists l ~len:1 let call_lists ?base lists = begin match base with None -> () | Some base -> list_base base end; call_lists lists lablgl-1.07/src/glList.mli000066400000000000000000000023311437514534100154340ustar00rootroot00000000000000(* $Id: glList.mli,v 1.4 2000-04-03 02:57:41 garrigue Exp $ *) type t val create : [`compile|`compile_and_execute] -> t (* [create mode] creates a new display list in given mode. It is equivalent to [let base = gen_lists len:1 in begins (nth base pos:0)] *) val ends : unit -> unit (* glEndList: end a display list started by create or begins *) val call : t -> unit val delete : t -> unit type base val nth : base -> pos:int -> t (* [nth base :pos] returns the index of the list at base+pos *) val is_list : t -> bool (* [is_list l] is true if l indexes a display list *) val gen_lists : len:int -> base (* Generate len new display lists. They are indexed by [nth base pos:0] to [nth base pos:(len-1)] *) val begins : t -> mode:[`compile|`compile_and_execute] -> unit (* glNewList: start the definition of a display list in given mode *) val delete_lists : base -> len:int -> unit (* Delete len lists starting at base *) val call_lists : ?base:base -> [ `byte of string | `int of int array] -> unit (* Call the lists whose indexes are given either by a string (code of each character) or an array. If the base is omited, the base given in a previous call is assumed *) lablgl-1.07/src/glMap.ml000066400000000000000000000024101437514534100150630ustar00rootroot00000000000000(* $Id: glMap.ml,v 1.4 2008-01-10 05:50:37 garrigue Exp $ *) external eval_coord1 : float -> unit = "ml_glEvalCoord1d" external eval_coord2 : float -> float -> unit = "ml_glEvalCoord2d" external eval_mesh1 : mode:[`point|`line] -> int -> int -> unit = "ml_glEvalMesh1" let eval_mesh1 ~mode ~range:(u1,u2) = eval_mesh1 ~mode u1 u2 external eval_mesh2 : mode:[`point|`line|`fill] -> int -> int -> int -> int -> unit = "ml_glEvalMesh2" let eval_mesh2 ~mode ~range1:(u1,u2) ~range2:(v1,v2) = eval_mesh2 ~mode u1 u2 v1 v2 external eval_point1 : int -> unit = "ml_glEvalPoint1" external eval_point2 : int -> int -> unit = "ml_glEvalPoint2" type target = [ `vertex_3 | `vertex_4 | `index | `color_4 | `normal | `texture_coord_1 | `texture_coord_2 | `texture_coord_3 | `texture_coord_4 ] external map1 : target:target -> (float*float) -> order:int -> [`double] Raw.t -> unit = "ml_glMap1d" external map2 : target:target -> (float*float) -> order:int -> (float*float) -> order:int -> [`double] Raw.t -> unit = "ml_glMap2d_bc" "ml_glMap2d" external grid1 : n:int -> range:(float * float) -> unit = "ml_glMapGrid1d" external grid2 : n1:int -> range1:(float * float) -> n2:int -> range2:(float * float) -> unit = "ml_glMapGrid2d" lablgl-1.07/src/glMap.mli000066400000000000000000000024701437514534100152420ustar00rootroot00000000000000(* $Id: glMap.mli,v 1.3 2000-04-12 07:40:24 garrigue Exp $ *) type target = [ `vertex_3 | `vertex_4 | `index | `color_4 | `normal | `texture_coord_1 | `texture_coord_2 | `texture_coord_3 | `texture_coord_4 ] val map1 : target:target -> float * float -> order:int -> [`double] Raw.t -> unit (* [map1 :target (u1,u2) :order points] defines a 1-dimensional map. [order] is the number of control points in [points] *) val map2 : target:target -> float * float -> order:int -> float * float -> order:int -> [`double] Raw.t -> unit (* [map1 :target (u1,u2) order:uorder (v1,v2) order:vorder points] defines a 2-dimensional map. The number of control points in [points] is [uorder*vorder] *) val eval_coord1 : float -> unit val eval_coord2 : float -> float -> unit (* Evaluate the maps at given coordinates *) val grid1 : n:int -> range:float * float -> unit val grid2 : n1:int -> range1:float * float -> n2:int -> range2:float * float -> unit (* Define 1- and 2-dimensional meshes to the maps *) val eval_mesh1 : mode:[`line|`point] -> range:(int * int) -> unit val eval_mesh2 : mode:[`fill|`line|`point] -> range1:(int * int) -> range2:(int * int) -> unit val eval_point1 : int -> unit val eval_point2 : int -> int -> unit (* Evaluate meshes at given coordinates *) lablgl-1.07/src/glMat.ml000066400000000000000000000047351437514534100151030ustar00rootroot00000000000000(* $Id: glMat.ml,v 1.11 2005-10-28 02:49:09 garrigue Exp $ *) type t = [`double] Raw.t external frustum : x:(float * float) -> y:(float * float) -> z:(float * float) -> unit = "ml_glFrustum" external load_identity : unit -> unit = "ml_glLoadIdentity" external load : t -> unit = "ml_glLoadMatrixd" let load m = if Raw.length m <> 16 then invalid_arg "Gl.load_matrix"; load m external load_transpose : t -> unit = "ml_glLoadTransposeMatrixd" let load_transpose m = if Raw.length m <> 16 then invalid_arg "Gl.load_transpose_matrix"; load_transpose m external get_matrix : [`modelview_matrix|`projection_matrix|`texture_matrix] -> t -> unit = "ml_glGetDoublev" let get_matrix mode = let model = Raw.create `double ~len:16 in get_matrix mode model; model external mode : [`modelview|`projection|`texture] -> unit = "ml_glMatrixMode" external mult : t -> unit = "ml_glMultMatrixd" let mult m = if Raw.length m <> 16 then invalid_arg "Gl.mult_matrix"; mult m external mult_transpose : t -> unit = "ml_glMultTransposeMatrixd" let mult_transpose m = if Raw.length m <> 16 then invalid_arg "Gl.mult_matrix"; mult_transpose m external ortho : x:(float * float) -> y:(float * float) -> z:(float * float) -> unit = "ml_glOrtho" external pop : unit -> unit = "ml_glPopMatrix" external push : unit -> unit = "ml_glPushMatrix" external rotate : angle:float -> x:float -> y:float -> z:float -> unit = "ml_glRotated" let rotate3 ~angle (x,y,z) = rotate ~angle ~x ~y ~z let rotate ~angle ?(x=0.) ?(y=0.) ?(z=0.) () = rotate ~angle ~x ~y ~z external scale : x:float -> y:float -> z:float -> unit = "ml_glScaled" let scale3 (x,y,z) = scale ~x ~y ~z let scale ?(x=0.) ?(y=0.) ?(z=0.) () = scale ~x ~y ~z external translate : x:float -> y:float -> z:float -> unit = "ml_glTranslated" let translate3 (x,y,z) = translate ~x ~y ~z let translate ?(x=0.) ?(y=0.) ?(z=0.) () = translate ~x ~y ~z let of_raw mat = if Raw.length mat <> 16 then invalid_arg "GlMatrix.of_array"; mat external to_raw : t -> [`double] Raw.t = "%identity" let of_array m : t = if Array.length m <> 4 then invalid_arg "GlMatrix.of_array"; let mat = Raw.create `double ~len:16 in for i = 0 to 3 do let arr = Array.unsafe_get m i in if Array.length arr <> 4 then invalid_arg "GlMatrix.of_array"; Raw.sets_float mat ~pos:(i*4) arr done; mat let to_array (mat : t) = let m = Array.make 4 [||] in for i = 0 to 3 do Array.unsafe_set m i (Raw.gets_float mat ~pos:(i*4) ~len:4) done; m lablgl-1.07/src/glMat.mli000066400000000000000000000023221437514534100152420ustar00rootroot00000000000000(* $Id: glMat.mli,v 1.6 2003-04-22 03:24:02 erickt Exp $ *) open Gl type t val of_raw : [`double] Raw.t -> t external to_raw : t -> [`double] Raw.t = "%identity" (* Those two functions are just the identity, and keep sharing. [double] Raw.t is a raw array of 16 floating point values representing as 4x4 matrix *) val of_array : float array array -> t val to_array : t -> float array array val load : t -> unit val load_transpose : t -> unit val mult : t -> unit val mult_transpose : t -> unit val load_identity : unit -> unit val push : unit -> unit val pop : unit -> unit (* Push and pop the matrix on the stack *) val mode : [`modelview|`projection|`texture] -> unit val get_matrix : [`modelview_matrix|`projection_matrix|`texture_matrix] -> t val rotate : angle:float -> ?x:float -> ?y:float -> ?z:float -> unit -> unit val scale : ?x:float -> ?y:float -> ?z:float -> unit -> unit val translate : ?x:float -> ?y:float -> ?z:float -> unit -> unit val rotate3 : angle:float -> vect3 -> unit val scale3 : point3 -> unit val translate3 : point3 -> unit val ortho : x:float * float -> y:float * float -> z:float * float -> unit val frustum : x:float * float -> y:float * float -> z:float * float -> unit lablgl-1.07/src/glMisc.ml000066400000000000000000000046671437514534100152610ustar00rootroot00000000000000(* $Id: glMisc.ml,v 1.8 2008-10-25 02:22:58 garrigue Exp $ *) open StdLabels external get_string : [`vendor|`renderer|`version|`extensions] -> string = "ml_glGetString" let rec check_substring ~sep ~start ~buf s = let len = String.length s in if String.length buf < len + start then false else if String.sub buf ~pos:start ~len = s && (String.length buf = len + start || buf.[len+start] = sep) then true else match try Some (String.index_from buf start sep) with Not_found -> None with | None -> false | Some n -> check_substring ~sep ~start:(n+1) ~buf s let check_extension s = check_substring ~sep:' ' ~start:0 ~buf:(get_string `extensions) s type equation = float * float * float * float external clip_plane : plane:int -> equation -> unit = "ml_glClipPlane" let clip_plane ~plane equation = if plane < 0 || plane > 5 then invalid_arg "Gl.clip_plane"; clip_plane ~plane equation type hint_target = [`fog|`line_smooth|`perspective_correction|`point_smooth|`polygon_smooth] external hint : hint_target -> [`fastest|`nicest|`dont_care] -> unit = "ml_glHint" external init_names : unit -> unit = "ml_glInitNames" external load_name : int -> unit = "ml_glLoadName" external pop_name : unit -> unit = "ml_glPopName" external push_name : int -> unit = "ml_glPushName" external pop_attrib : unit -> unit = "ml_glPopAttrib" type attrib = [ `accum_buffer|`color_buffer|`current|`depth_buffer|`enable|`eval|`fog | `hint|`lighting|`line|`list|`pixel_mode|`point|`polygon|`polygon_stipple | `scissor|`stencil_buffer|`texture|`transform|`viewport ] external push_attrib : attrib list -> unit = "ml_glPushAttrib" external pass_through : float -> unit = "ml_glPassThrough" external render_mode : [`render|`select|`feedback] -> int = "ml_glRenderMode" external select_buffer : int -> [`uint] Raw.t -> unit = "ml_glSelectBuffer" let select_buffer raw = if not (Raw.static raw) then invalid_arg "GlMisc.select_buffer : buffer must be static"; select_buffer (Raw.length raw) raw type feedback_mode = [`_2d |`_3d |`_3d_color |`_3d_color_texture |`_4d_color_texture] external feedback_buffer : int -> feedback_mode -> [`float] Raw.t -> unit = "ml_glFeedbackBuffer" let feedback_buffer ~mode buf = if not (Raw.static buf) then invalid_arg "GlMisc.feedback_buffer : buffer must be static"; feedback_buffer (Raw.length buf) mode buf external scissor : x:int -> y:int -> width:int -> height:int -> unit = "ml_glScissor" lablgl-1.07/src/glMisc.mli000066400000000000000000000025051437514534100154170ustar00rootroot00000000000000(* $Id: glMisc.mli,v 1.6 2008-10-25 02:22:58 garrigue Exp $ *) (* Getting information *) val get_string : [`vendor|`renderer|`version|`extensions] -> string val check_extension : string -> bool (* Clipping planes *) type equation = float * float * float * float val clip_plane : plane:int -> equation -> unit (* Speed hint *) type hint_target = [`fog|`line_smooth|`perspective_correction|`point_smooth|`polygon_smooth] val hint : hint_target -> [`fastest|`nicest|`dont_care] -> unit (* Names *) val init_names : unit -> unit val load_name : int -> unit val push_name : int -> unit val pop_name : unit -> unit type attrib = [ `accum_buffer|`color_buffer|`current|`depth_buffer|`enable|`eval|`fog | `hint|`lighting|`line|`list|`pixel_mode|`point|`polygon|`polygon_stipple | `scissor|`stencil_buffer|`texture|`transform|`viewport ] val push_attrib : attrib list -> unit val pop_attrib : unit -> unit val render_mode : [`feedback|`render|`select] -> int val pass_through : float -> unit val select_buffer : [`uint] Raw.t -> unit (* argument must be a static Raw.t *) type feedback_mode = [`_2d |`_3d |`_3d_color |`_3d_color_texture |`_4d_color_texture] val feedback_buffer : mode:feedback_mode -> [`float] Raw.t -> unit (* argument must be a static Raw.t *) val scissor : x:int -> y:int -> width:int -> height:int -> unit lablgl-1.07/src/glPix.ml000066400000000000000000000063111437514534100151120ustar00rootroot00000000000000(* $Id: glPix.ml,v 1.10 2005-10-14 13:35:32 garrigue Exp $ *) open Gl type ('a,'b) t = { format: 'a ; width: int ; height:int ; raw: 'b Raw.t } let create k ~format ~width ~height = let size = format_size format * width * height in let len = match k with `bitmap -> (size-1)/8+1 | #Gl.real_kind -> size in let raw = Raw.create k ~len in { format = format; width = width; height = height; raw = raw } let of_raw raw ~format ~width ~height = let size = format_size format * width * height and len = Raw.length raw in let len = match Raw.kind raw with `bitmap -> len * 8 | #Gl.real_kind -> len in if size > len then invalid_arg "GlPix.of_raw"; { format = format; width = width; height = height; raw = raw } let to_raw img = img.raw let format img = img.format let width img = img.width let height img = img.height let raw_pos img = let width = match Raw.kind img.raw with `bitmap -> (img.width-1)/8+1 | #Gl.real_kind -> img.width in let stride = format_size img.format in let line = stride * width in fun ~x ~y -> x * stride + y * line external bitmap : width:int -> height:int -> orig:point2 -> move:point2 -> [`bitmap] Raw.t -> unit = "ml_glBitmap" type bitmap = ([`color_index], [`bitmap]) t let bitmap (img : bitmap) = bitmap ~width:img.width ~height:img.height img.raw external copy : x:int -> y:int -> width:int -> height:int -> buffer:[`color|`depth|`stencil] -> unit = "ml_glCopyPixels" external draw : width:int -> height:int -> format:[< format] -> [< Gl.kind] Raw.t -> unit = "ml_glDrawPixels" let draw img = draw img.raw ~width:img.width ~height:img.height ~format:img.format type map = [`i_to_i|`i_to_r|`i_to_g|`i_to_b|`i_to_a |`s_to_s|`r_to_r|`g_to_g|`b_to_b|`a_to_a] external map : map -> [`float] Raw.t -> unit = "ml_glPixelMapfv" type store_param = [ `pack_swap_bytes of bool | `pack_lsb_first of bool | `pack_row_length of int | `pack_skip_pixels of int | `pack_skip_rows of int | `pack_alignment of int | `unpack_swap_bytes of bool | `unpack_lsb_first of bool | `unpack_row_length of int | `unpack_skip_pixels of int | `unpack_skip_rows of int | `unpack_alignment of int ] external store : store_param -> unit = "ml_glPixelStorei" type transfer_param = [ `map_color of bool | `map_stencil of bool | `index_shift of int | `index_offset of int | `red_scale of float | `red_bias of float | `green_scale of float | `green_bias of float | `blue_scale of float | `blue_bias of float | `alpha_scale of float | `alpha_bias of float | `depth_scale of float | `depth_bias of float ] external transfer : transfer_param -> unit = "ml_glPixelTransfer" external zoom : x:float -> y:float -> unit = "ml_glPixelZoom" external raster_pos : x:float -> y:float -> ?z:float -> ?w:float -> unit -> unit = "ml_glRasterPos" external read : x:int -> y:int -> width:int -> height:int -> format:[< format] -> [< Gl.kind] Raw.t -> unit = "ml_glReadPixels_bc" "ml_glReadPixels" let read ~x ~y ~width ~height ~format ~kind = let raw = Raw.create kind ~len:(width * height * format_size format) in read ~x ~y ~width ~height ~format raw; { raw = raw; width = width; height = height; format = format } lablgl-1.07/src/glPix.mli000066400000000000000000000040621437514534100152640ustar00rootroot00000000000000(* $Id: glPix.mli,v 1.9 2004-12-02 02:01:16 garrigue Exp $ *) (* An abstract type for pixmaps *) type (+'a,+'b) t val create : ([< Gl.kind] as 'a) -> format:([< Gl.format] as 'b) -> width:int -> height:int -> ('b, 'a) t val of_raw : ([< Gl.kind] as 'a) Raw.t -> format:([< Gl.format] as 'b) -> width:int -> height:int -> ('b, 'a) t val to_raw : ('a, 'b) t -> 'b Raw.t val format : ('a, 'b) t -> 'a val width : ('a, 'b) t -> int val height : ('a, 'b) t -> int val raw_pos : ([< Gl.format], [< Gl.kind]) t -> x:int -> y:int -> int (* [raw_pos image :x :y] partially evaluates on [image] *) (* openGL functions *) val read : x:int -> y:int -> width:int -> height:int -> format:([< Gl.format] as 'a) -> kind:([< Gl.kind] as 'b) -> ('a, 'b) t type bitmap = ([`color_index], [`bitmap]) t val bitmap : bitmap -> orig:Gl.point2 -> move:Gl.point2 -> unit val draw : ([< Gl.format], [< Gl.kind]) t -> unit type map = [`a_to_a|`b_to_b|`g_to_g|`i_to_a|`i_to_b |`i_to_g|`i_to_i|`i_to_r|`r_to_r|`s_to_s] val map : map -> [`float] Raw.t -> unit type store_param = [ `pack_swap_bytes of bool | `pack_lsb_first of bool | `pack_row_length of int | `pack_skip_pixels of int | `pack_skip_rows of int | `pack_alignment of int | `unpack_swap_bytes of bool | `unpack_lsb_first of bool | `unpack_row_length of int | `unpack_skip_pixels of int | `unpack_skip_rows of int | `unpack_alignment of int ] val store : store_param -> unit type transfer_param = [ `map_color of bool | `map_stencil of bool | `index_shift of int | `index_offset of int | `red_scale of float | `red_bias of float | `green_scale of float | `green_bias of float | `blue_scale of float | `blue_bias of float | `alpha_scale of float | `alpha_bias of float | `depth_scale of float | `depth_bias of float ] val transfer : transfer_param -> unit val zoom : x:float -> y:float -> unit val raster_pos : x:float -> y:float -> ?z:float -> ?w:float -> unit -> unit val copy : x:int -> y:int -> width:int -> height:int -> buffer:[`color|`depth|`stencil] -> unit lablgl-1.07/src/glShader.ml000066400000000000000000000152621437514534100155650ustar00rootroot00000000000000(* $Id: glShader.ml,v 1.1 2010-03-11 08:30:02 garrigue Exp $ *) (* Code contributed by Florent Monnier *) (** GLSL Shaders *) type shader_object type shader_program external create: shader_type:[`vertex_shader|`fragment_shader] -> shader_object = "ml_glcreateshader" external delete: shader:shader_object -> unit = "ml_gldeleteshader" external is_shader: shader:shader_object -> bool = "ml_glisshader" external source: shader:shader_object -> string -> unit = "ml_glshadersource" external compile: shader:shader_object -> unit = "ml_glcompileshader" external create_program: unit -> shader_program = "ml_glcreateprogram" external delete_program: program:shader_program -> unit = "ml_gldeleteprogram" external attach: program:shader_program -> shader:shader_object -> unit = "ml_glattachshader" external detach: program:shader_program -> shader:shader_object -> unit = "ml_gldetachshader" external link_program: program:shader_program -> unit = "ml_gllinkprogram" external use_program: program:shader_program -> unit = "ml_gluseprogram" external unuse_program: unit -> unit = "ml_glunuseprogram" external shader_compile_status: shader:shader_object -> bool = "ml_glgetshadercompilestatus" external shader_compile_status_exn: shader:shader_object -> unit = "ml_glgetshadercompilestatus_exn" external get_uniform_location: program:shader_program -> name:string -> int = "ml_glgetuniformlocation" external get_program_attached_shaders: program:shader_program -> int = "ml_glgetprogram_attached_shaders" external get_program_active_uniforms: program:shader_program -> int = "ml_glgetprogram_active_uniforms" external get_program_active_attributes: program:shader_program -> int = "ml_glgetprogram_active_attributes" external get_program_validate_status: program:shader_program -> bool = "ml_glgetprogram_validate_status" external get_program_link_status: program:shader_program -> bool = "ml_glgetprogram_link_status" external get_program_delete_status: program:shader_program -> bool = "ml_glgetprogram_delete_status" external uniform1f: location:int -> v0:float -> unit = "ml_gluniform1f" external uniform2f: location:int -> v0:float -> v1:float -> unit = "ml_gluniform2f" external uniform3f: location:int -> v0:float -> v1:float -> v2:float -> unit = "ml_gluniform3f" external uniform4f: location:int -> v0:float -> v1:float -> v2:float -> v3:float -> unit = "ml_gluniform4f" external uniform1i: location:int -> v0:int -> unit = "ml_gluniform1i" external uniform2i: location:int -> v0:int -> v1:int -> unit = "ml_gluniform2i" external uniform3i: location:int -> v0:int -> v1:int -> v2:int -> unit = "ml_gluniform3i" external uniform4i: location:int -> v0:int -> v1:int -> v2:int -> v3:int -> unit = "ml_gluniform4i" external uniform1fv: location:int -> value:float array -> unit = "ml_gluniform1fv" external uniform2fv: location:int -> count:int -> value:float array -> unit = "ml_gluniform2fv" external uniform3fv: location:int -> count:int -> value:float array -> unit = "ml_gluniform3fv" external uniform4fv: location:int -> count:int -> value:float array -> unit = "ml_gluniform4fv" external uniform1iv: location:int -> value:int array -> unit = "ml_gluniform1iv" external uniform2iv: location:int -> count:int -> value:int array -> unit = "ml_gluniform2iv" external uniform3iv: location:int -> count:int -> value:int array -> unit = "ml_gluniform3iv" external uniform4iv: location:int -> count:int -> value:int array -> unit = "ml_gluniform4iv" external uniform_matrix2f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2f" external uniform_matrix3f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3f" external uniform_matrix4f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4f" external uniform_matrix2x3f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2x3f" external uniform_matrix3x2f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3x2f" external uniform_matrix2x4f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2x4f" external uniform_matrix4x2f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4x2f" external uniform_matrix3x4f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3x4f" external uniform_matrix4x3f: location:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4x3f" external uniform_matrix2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2fv" external uniform_matrix3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3fv" external uniform_matrix4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4fv" external uniform_matrix2x3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2x3fv" external uniform_matrix3x2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3x2fv" external uniform_matrix2x4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix2x4fv" external uniform_matrix4x2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4x2fv" external uniform_matrix3x4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix3x4fv" external uniform_matrix4x3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit = "ml_gluniformmatrix4x3fv" external get_attrib_location: program:shader_program -> name:string -> int = "ml_glgetattriblocation" external bind_attrib_location: program:shader_program -> index:int -> name:string -> unit = "ml_glbindattriblocation" external vertex_attrib1s: index:int -> v:int -> unit = "ml_glvertexattrib1s" external vertex_attrib1d: index:int -> v:float -> unit = "ml_glvertexattrib1d" external vertex_attrib2s: index:int -> v0:int -> v1:int -> unit = "ml_glvertexattrib2s" external vertex_attrib2d: index:int -> v0:float -> v1:float -> unit = "ml_glvertexattrib2d" external vertex_attrib3s: index:int -> v0:int -> v1:int -> v2:int -> unit = "ml_glvertexattrib3s" external vertex_attrib3d: index:int -> v0:float -> v1:float -> v2:float -> unit = "ml_glvertexattrib3d" external vertex_attrib4s: index:int -> v0:int -> v1:int -> v2:int -> v3:int -> unit = "ml_glvertexattrib4s" external vertex_attrib4d: index:int -> v0:float -> v1:float -> v2:float -> v3:float -> unit = "ml_glvertexattrib4d" external get_shader_infolog: shader:shader_object -> string = "ml_glgetshaderinfolog" external get_program_infolog: program:shader_program -> string = "ml_glgetprograminfolog" lablgl-1.07/src/glShader.mli000066400000000000000000000077021437514534100157360ustar00rootroot00000000000000(* $Id: glShader.mli,v 1.1 2010-03-11 08:30:02 garrigue Exp $ *) (* Code contributed by Florent Monnier *) (** GLSL Shaders *) type shader_object type shader_program val create: shader_type:[`vertex_shader|`fragment_shader] -> shader_object val delete: shader:shader_object -> unit val source: shader:shader_object -> string -> unit val compile: shader:shader_object -> unit val create_program: unit -> shader_program val delete_program: program:shader_program -> unit val attach: program:shader_program -> shader:shader_object -> unit val detach: program:shader_program -> shader:shader_object -> unit val link_program: program:shader_program -> unit val use_program: program:shader_program -> unit val unuse_program: unit -> unit val shader_compile_status: shader:shader_object -> bool val shader_compile_status_exn: shader:shader_object -> unit val get_uniform_location: program:shader_program -> name:string -> int val get_program_attached_shaders: program:shader_program -> int val get_program_active_uniforms: program:shader_program -> int val get_program_active_attributes: program:shader_program -> int val get_program_validate_status: program:shader_program -> bool val get_program_link_status: program:shader_program -> bool val get_program_delete_status: program:shader_program -> bool val uniform1f: location:int -> v0:float -> unit val uniform2f: location:int -> v0:float -> v1:float -> unit val uniform3f: location:int -> v0:float -> v1:float -> v2:float -> unit val uniform4f: location:int -> v0:float -> v1:float -> v2:float -> v3:float -> unit val uniform1i: location:int -> v0:int -> unit val uniform2i: location:int -> v0:int -> v1:int -> unit val uniform3i: location:int -> v0:int -> v1:int -> v2:int -> unit val uniform4i: location:int -> v0:int -> v1:int -> v2:int -> v3:int -> unit val uniform1fv: location:int -> value:float array -> unit val uniform2fv: location:int -> count:int -> value:float array -> unit val uniform3fv: location:int -> count:int -> value:float array -> unit val uniform4fv: location:int -> count:int -> value:float array -> unit val uniform1iv: location:int -> value:int array -> unit val uniform2iv: location:int -> count:int -> value:int array -> unit val uniform3iv: location:int -> count:int -> value:int array -> unit val uniform4iv: location:int -> count:int -> value:int array -> unit val uniform_matrix2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix2x3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix3x2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix2x4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix4x2fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix3x4fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val uniform_matrix4x3fv: location:int -> count:int -> transpose:bool -> value:float array -> unit val get_attrib_location: program:shader_program -> name:string -> int val bind_attrib_location: program:shader_program -> index:int -> name:string -> unit val vertex_attrib1s: index:int -> v:int -> unit val vertex_attrib1d: index:int -> v:float -> unit val vertex_attrib2s: index:int -> v0:int -> v1:int -> unit val vertex_attrib2d: index:int -> v0:float -> v1:float -> unit val vertex_attrib3s: index:int -> v0:int -> v1:int -> v2:int -> unit val vertex_attrib3d: index:int -> v0:float -> v1:float -> v2:float -> unit val vertex_attrib4s: index:int -> v0:int -> v1:int -> v2:int -> v3:int -> unit val vertex_attrib4d: index:int -> v0:float -> v1:float -> v2:float -> v3:float -> unit val get_shader_infolog: shader:shader_object -> string val get_program_infolog: program:shader_program -> string lablgl-1.07/src/glTex.ml000066400000000000000000000075061437514534100151210ustar00rootroot00000000000000(* $Id: glTex.ml,v 1.14 2012-03-06 03:31:02 garrigue Exp $ *) open Gl open GlPix external coord1 : float -> unit = "ml_glTexCoord1d" external coord2 : float -> float -> unit = "ml_glTexCoord2d" external coord3 : float -> float -> float -> unit = "ml_glTexCoord3d" external coord4 : float -> float -> float -> float -> unit = "ml_glTexCoord4d" (*external multi_coord2 : *) let default x = function Some x -> x | None -> x let coord ~s ?t ?r ?q () = match q with Some q -> coord4 s (default 0.0 t) (default 0.0 r) q | None -> match r with Some r -> coord3 s (default 0.0 t) r | None -> match t with Some t -> coord2 s t | None -> coord1 s let coord2 (s,t) = coord2 s t let coord3 (s,t,r) = coord3 s t r let coord4 (s,t,r,q) = coord4 s t r q type env_param = [ `mode of [`modulate|`decal|`blend|`replace] | `color of rgba ] external env : env_param -> unit = "ml_glTexEnv" type coord = [`s|`t|`r|`q] type gen_param = [ `mode of [`object_linear|`eye_linear|`sphere_map] | `object_plane of point4 | `eye_plane of point4 ] external gen : coord:coord -> gen_param -> unit = "ml_glTexGen" let npot = ref None let check_pow2 n = if !npot = None then npot := Some (GlMisc.check_extension "GL_ARB_texture_non_power_of_two"); (!npot = Some true) || (n land (n - 1) = 0) type format = [ `color_index | `red | `green | `blue | `alpha | `rgb | `bgr | `rgba | `bgra | `luminance | `luminance_alpha ] external image1d : proxy:bool -> level:int -> internal:int -> width:int -> border:int -> format:[< format] -> [< kind] Raw.t -> unit = "ml_glTexImage1D_bc""ml_glTexImage1D" let image1d ?(proxy=false) ?(level=0) ?internal:i ?(border=false) img = let internal = match i with None -> format_size (format img) | Some i -> i in let border = if border then 1 else 0 in if not (check_pow2 (width img - 2 * border)) then raise (GLerror "Gl.image1d : bad width"); if height img < 1 then raise (GLerror "Gl.image1d : bad height"); image1d ~proxy ~level ~internal ~width:(width img) ~border ~format:(format img) (to_raw img) external image2d : proxy:bool -> level:int -> internal:int -> width:int -> height:int -> border:int -> format:[< format] -> [< kind] Raw.t -> unit = "ml_glTexImage2D_bc""ml_glTexImage2D" let image2d ?(proxy=false) ?(level=0) ?internal:i ?(border=false) img = let internal = match i with None -> format_size (format img) | Some i -> i in let border = if border then 1 else 0 in if not (check_pow2 (width img - 2 * border)) then raise (GLerror "Gl.image2d : bad width"); if not (check_pow2 (height img - 2 * border)) then raise (GLerror "Gl.image2d : bad height"); image2d ~proxy ~level ~internal ~border ~width:(width img) ~height:(height img) ~format:(format img) (to_raw img) type filter = [ `nearest | `linear | `nearest_mipmap_nearest | `linear_mipmap_nearest | `nearest_mipmap_linear | `linear_mipmap_linear ] type wrap = [`clamp|`repeat] type parameter = [ `min_filter of filter | `mag_filter of [`nearest|`linear] | `wrap_s of wrap | `wrap_t of wrap | `border_color of rgba | `priority of clampf | `generate_mipmap of bool ] external parameter : target:[`texture_1d|`texture_2d] -> parameter -> unit = "ml_glTexParameter" type texture_id = nativeint external _gen_textures : int -> [`uint] Raw.t -> unit = "ml_glGenTextures" let gen_textures ~len = let raw = Raw.create `uint ~len in _gen_textures len raw; let arr = Array.make len Nativeint.zero in for i = 0 to len - 1 do arr.(i) <- Raw.get_long raw ~pos:i done; arr let gen_texture () = (gen_textures 1).(0) external bind_texture : target:[`texture_1d|`texture_2d] -> texture_id -> unit = "ml_glBindTexture" external delete_texture : texture_id -> unit = "ml_glDeleteTexture" let delete_textures a = Array.iter (fun id -> delete_texture id) a lablgl-1.07/src/glTex.mli000066400000000000000000000031521437514534100152630ustar00rootroot00000000000000(* $Id: glTex.mli,v 1.8 2012-03-06 03:31:02 garrigue Exp $ *) open Gl val coord : s:float -> ?t:float -> ?r:float -> ?q:float -> unit -> unit val coord2 : float * float -> unit val coord3 : float * float * float -> unit val coord4 : float * float * float * float -> unit type env_param = [ `mode of [`modulate|`decal|`blend|`replace] | `color of rgba] val env : env_param -> unit type coord = [`s|`t|`r|`q] type gen_param = [ `mode of [`object_linear|`eye_linear|`sphere_map] | `object_plane of point4 | `eye_plane of point4 ] val gen : coord:coord -> gen_param -> unit type format = [`color_index|`red|`green|`blue|`alpha|`rgb|`bgr|`rgba|`bgra |`luminance|`luminance_alpha] val image1d : ?proxy:bool -> ?level:int -> ?internal:int -> ?border:bool -> ([< format], [< kind]) GlPix.t -> unit val image2d : ?proxy:bool -> ?level:int -> ?internal:int -> ?border:bool -> ([< format], [< kind]) GlPix.t -> unit type filter = [`nearest|`linear|`nearest_mipmap_nearest|`linear_mipmap_nearest |`nearest_mipmap_linear|`linear_mipmap_linear] type wrap = [`clamp|`repeat] type parameter = [ `min_filter of filter | `mag_filter of [`nearest|`linear] | `wrap_s of wrap | `wrap_t of wrap | `border_color of rgba | `priority of clampf | `generate_mipmap of bool ] val parameter : target:[`texture_1d|`texture_2d] -> parameter -> unit type texture_id val gen_texture : unit -> texture_id val gen_textures : len:int -> texture_id array val bind_texture : target:[`texture_1d|`texture_2d] -> texture_id -> unit val delete_texture : texture_id -> unit val delete_textures : texture_id array -> unit lablgl-1.07/src/gl_tags.var000066400000000000000000000106161437514534100156320ustar00rootroot00000000000000(* GLenum *) color depth accum stencil points lines polygon triangles quads line_strip line_loop triangle_strip triangle_fan quad_strip front back both -> GL_FRONT_AND_BACK point line fill cw ccw modelview projection texture modelview_matrix projection_matrix texture_matrix (* glEnable *) alpha_test auto_normal blend clip_plane0 clip_plane1 clip_plane2 clip_plane3 clip_plane4 clip_plane5 (* color_logic_op *) color_material cull_face depth_test dither fog (* index_logic_op *) light0 light1 light2 light3 light4 light5 light6 light7 lighting line_smooth line_stipple logic_op index_logic_op color_logic_op map1_color_4 map1_index map1_normal map1_texture_coord_1 map1_texture_coord_2 map1_texture_coord_3 map1_texture_coord_4 map1_vertex_3 map1_vertex_4 map2_color_4 map2_index map2_normal map2_texture_coord_1 map2_texture_coord_2 map2_texture_coord_3 map2_texture_coord_4 map2_vertex_3 map2_vertex_4 normalize point_smooth polygon_offset_fill polygon_offset_line polygon_offset_point polygon_smooth polygon_stipple scissor_test stencil_test texture_1d texture_2d texture_gen_q texture_gen_r texture_gen_s texture_gen_t (* glShadeModel *) flat smooth (* glLight *) ambient diffuse specular position spot_direction spot_exponent spot_cutoff constant_attenuation linear_attenuation quadratic_attenuation (* glMaterial *) (* ambient *) (* diffuse *) (* specular *) emission shininess ambient_and_diffuse color_indexes (* glDepthFunc, glAlphaFunc *) never less equal lequal greater notequal gequal always (* glBlendFunc *) zero one dst_color one_minus_dst_color src_alpha one_minus_src_alpha dst_alpha one_minus_dst_alpha src_alpha_saturate src_color one_minus_src_color (* glFog *) linear exp exp2 (* glNewList *) compile compile_and_execute (* data types *) bitmap byte short int float double ubyte -> GL_UNSIGNED_BYTE ushort -> GL_UNSIGNED_SHORT uint -> GL_UNSIGNED_INT (* glAccum *) load add mult return (* glDrawPixels *) color_index stencil_index depth_component rgb bgr rgba bgra red green blue alpha luminance luminance_alpha (* glHint *) dont_care fastest nicest (* glLogicOp *) clear set copy copy_inverted noop invert And nand Or nor xor equiv and_reverse and_inverted or_reverse or_inverted (* glPixelTransfer *) alpha_bias alpha_scale blue_bias blue_scale depth_bias depth_scale green_bias green_scale index_offset index_shift map_color map_stencil red_bias red_scale (* glPixelMap *) i_to_i -> GL_PIXEL_MAP_I_TO_I i_to_r -> GL_PIXEL_MAP_I_TO_R i_to_g -> GL_PIXEL_MAP_I_TO_G i_to_b -> GL_PIXEL_MAP_I_TO_B i_to_a -> GL_PIXEL_MAP_I_TO_A s_to_s -> GL_PIXEL_MAP_S_TO_S r_to_r -> GL_PIXEL_MAP_R_TO_R g_to_g -> GL_PIXEL_MAP_G_TO_G b_to_b -> GL_PIXEL_MAP_B_TO_B a_to_a -> GL_PIXEL_MAP_A_TO_A (* glPixelStore *) pack_swap_bytes pack_lsb_first pack_row_length pack_skip_pixels pack_skip_rows pack_alignment unpack_swap_bytes unpack_lsb_first unpack_row_length unpack_skip_pixels unpack_skip_rows unpack_alignment (* glReadBuffer *) front_left front_right back_left back_right left right (* glDrawBuffer *) none (* glStencilOp *) keep replace incr decr (* glTexEnv *) modulate decal (* glTexGen *) s t r q object_plane eye_plane eye_linear object_linear sphere_map (* glTexParameter *) min_filter -> GL_TEXTURE_MIN_FILTER mag_filter -> GL_TEXTURE_MAG_FILTER wrap_s -> GL_TEXTURE_WRAP_S wrap_t -> GL_TEXTURE_WRAP_T border_color -> GL_TEXTURE_BORDER_COLOR priority -> GL_TEXTURE_PRIORITY nearest nearest_mipmap_nearest linear_mipmap_nearest nearest_mipmap_linear linear_mipmap_linear generate_mipmap clamp repeat (* glGetString *) vendor renderer version extensions (* glRenderMode *) render select feedback (* glFeedBackBuffer *) _2d -> GL_2D _3d -> GL_3D _3d_color -> GL_3D_COLOR _3d_color_texture -> GL_3D_COLOR_TEXTURE _4d_color_texture -> GL_4D_COLOR_TEXTURE $$ (* glLightModel *) local_viewer two_side mode density start index End color_control separate_specular_color single_color (* glHint *) perspective_correction (* glMap1, glMap2 *) vertex_3 vertex_4 color_4 normal texture_coord_1 texture_coord_2 texture_coord_3 texture_coord_4 (* glPushAttrib *) accum_buffer color_buffer current depth_buffer enable eval hint list pixel_mode scissor stencil_buffer transform viewport (* glReadBuffer *) aux (* glArray *) edge_flag texture_coord vertex two three four (* glGetError *) no_error invalid_enum invalid_value invalid_operation stack_overflow stack_underflow out_of_memory table_too_large (* glCreateShader *) vertex_shader fragment_shader lablgl-1.07/src/gluMat.ml000066400000000000000000000015161437514534100152620ustar00rootroot00000000000000(* $Id: gluMat.ml,v 1.2 2000-04-12 07:40:25 garrigue Exp $ *) open Gl external look_at : eye:(float * float * float) -> center:(float * float * float) -> up:(float * float * float) -> unit = "ml_gluLookAt" external ortho2d : left:float -> right:float -> bottom:float -> top:float -> unit = "ml_gluOrtho2D" let ortho2d ~x:(left,right) ~y:(bottom,top) = ortho2d ~left ~right ~bottom ~top external perspective : fovy:float -> aspect:float -> znear:float -> zfar:float -> unit = "ml_gluPerspective" let perspective ~fovy ~aspect ~z:(znear,zfar) = perspective ~fovy ~aspect ~znear ~zfar external pick_matrix : x:float -> y:float -> width:float -> height:float -> unit = "ml_gluPickMatrix" external project : point3 -> point3 = "ml_gluProject" external unproject : point3 -> point3 = "ml_gluUnProject" lablgl-1.07/src/gluMat.mli000066400000000000000000000006341437514534100154330ustar00rootroot00000000000000(* $Id: gluMat.mli,v 1.1 1998-01-29 11:46:06 garrigue Exp $ *) open Gl val look_at : eye:point3 -> center:point3 -> up:vect3 -> unit val ortho2d : x:float * float -> y:float * float -> unit val perspective : fovy:float -> aspect:float -> z:float * float -> unit val pick_matrix : x:float -> y:float -> width:float -> height:float -> unit val project : point3 -> point3 val unproject : point3 -> point3 lablgl-1.07/src/gluMisc.ml000066400000000000000000000026721437514534100154400ustar00rootroot00000000000000(* $Id: gluMisc.ml,v 1.6 2003-02-06 18:19:12 furuse Exp $ *) open Gl open GlPix external build_1d_mipmaps : internal:int -> width:int -> format:[< GlTex.format] -> [< kind] Raw.t -> unit = "ml_gluBuild1DMipmaps" let build_1d_mipmaps ?internal:i img = let internal = match i with None -> format_size (format img) | Some i -> i in if height img < 1 then raise (GLerror "GluMisc.build_1d_mipmaps : bad height"); build_1d_mipmaps ~internal ~width:(width img) ~format:(format img) (to_raw img) external build_2d_mipmaps : internal:int -> width:int -> height:int -> format:[< GlTex.format] -> [< kind] Raw.t -> unit = "ml_gluBuild2DMipmaps" let build_2d_mipmaps ?internal:i img = let internal = match i with None -> format_size (format img) | Some i -> i in build_2d_mipmaps ~internal ~width:(width img) ~height:(height img) ~format:(format img) (to_raw img) external get_string : [`version|`extensions] -> string = "ml_gluGetString" external scale_image : format:[< Gl.format] -> w:int -> h:int -> data:[< kind] Raw.t -> w:int -> h:int -> data:[< kind] Raw.t -> unit = "ml_gluScaleImage_bc" "ml_gluScaleImage" let scale_image ~width ~height img = let k = Raw.kind (to_raw img) and format = format img in let new_img = GlPix.create k ~format ~height ~width in scale_image ~format ~w:(GlPix.width img) ~h:(GlPix.height img) ~data:(to_raw img) ~w:width ~h:height ~data:(to_raw new_img); new_img lablgl-1.07/src/gluMisc.mli000066400000000000000000000006351437514534100156060ustar00rootroot00000000000000(* $Id: gluMisc.mli,v 1.3 2001-10-01 02:59:13 garrigue Exp $ *) open Gl val get_string : [`extensions|`version] -> string val build_1d_mipmaps : ?internal:int -> ([< GlTex.format], [< kind]) GlPix.t -> unit val build_2d_mipmaps : ?internal:int -> ([< GlTex.format], [< kind]) GlPix.t -> unit val scale_image : width:int -> height:int -> ([< format] as 'a, [< kind] as 'b) GlPix.t -> ('a, 'b) GlPix.t lablgl-1.07/src/gluNurbs.ml000066400000000000000000000054561437514534100156410ustar00rootroot00000000000000(* $Id: gluNurbs.ml,v 1.6 2001-10-01 02:59:13 garrigue Exp $ *) open Gl type t external begin_curve : t -> unit = "ml_gluBeginCurve" external begin_surface : t -> unit = "ml_gluBeginSurface" external begin_trim : t -> unit = "ml_gluBeginTrim" external end_curve : t -> unit = "ml_gluEndCurve" external end_surface : t -> unit = "ml_gluEndSurface" external end_trim : t -> unit = "ml_gluEndTrim" external load_sampling_matrices : t -> model:[`float] Raw.t -> persp:[`float] Raw.t -> view:[`int] Raw.t -> unit = "ml_gluLoadSamplingMatrices" external create : unit -> t = "ml_gluNewNurbsRenderer" external curve : t -> knots:[`float] Raw.t -> control:[`float] Raw.t -> order:int -> kind:[< GlMap.target] -> unit = "ml_gluNurbsCurve" let curve nurb ~knots ~control ~order ~kind:t = let arity = target_size t in if (Array.length knots - order) * arity <> Array.length control then invalid_arg "GluNurbs.curve"; let knots = Raw.of_float_array ~kind:`float knots and control = Raw.of_float_array ~kind:`float control in curve nurb ~knots ~control ~order ~kind:t type property = [ `sampling_method of [`path_length|`parametric_error|`domain_distance] | `sampling_tolerance of int | `parametric_tolerance of float | `u_step of int | `v_step of int | `display_mode of [`fill|`polygon|`patch] | `culling of bool | `auto_load_matrix of bool ] external property : t -> property -> unit = "ml_gluNurbsProperty" external surface : t -> sknots:[`float] Raw.t -> tknots:[`float] Raw.t -> tstride:int -> control:[`float] Raw.t -> sorder:int -> torder:int -> target:[< target] -> unit = "ml_gluNurbsSurface_bc" "ml_gluNurbsSurface" let surface t ~sknots ~tknots ~control ~sorder ~torder ~target = let cl = Array.length control in if cl = 0 then invalid_arg "GluNurb.curve"; let tstride = Array.length control.(0) in let sl = Array.length sknots and tl = Array.length tknots in if tl <> cl + torder || (sl - sorder) * target_size target <> tstride then invalid_arg "GluNurb.curve"; let sknots = Raw.of_float_array ~kind:`float sknots in let tknots = Raw.of_float_array ~kind:`float tknots in let co = Raw.create `float ~len:(cl * tstride) in for i = 0 to cl - 1 do if Array.length control.(i) <> tstride then invalid_arg "GluNurb.curve"; Raw.sets_float co ~pos:(i*tstride) control.(i) done; surface t ~sknots ~tknots ~tstride ~control:co ~sorder ~torder ~target external pwl_curve : t -> count:int -> [`float] Raw.t -> kind:[`trim_2|`trim_3] -> unit = "ml_gluPwlCurve" let pwl_curve nurb ~kind:t data = let len = Array.length data and raw = Raw.of_float_array ~kind:`float data and stride = match t with `trim_2 -> 2 | `trim_3 -> 3 in if len mod stride <> 0 then invalid_arg "GluNurb.pwl_curve"; pwl_curve nurb ~count:(len/stride) raw ~kind:t lablgl-1.07/src/gluNurbs.mli000066400000000000000000000020251437514534100157770ustar00rootroot00000000000000(* $Id: gluNurbs.mli,v 1.5 2001-10-01 02:59:13 garrigue Exp $ *) type t val create : unit -> t val begin_curve : t -> unit val begin_surface : t -> unit val begin_trim : t -> unit val end_curve : t -> unit val end_surface : t -> unit val end_trim : t -> unit val load_sampling_matrices : t -> model:[`float] Raw.t -> persp:[`float] Raw.t -> view:[`int] Raw.t -> unit val curve : t -> knots:float array -> control:float array -> order:int -> kind:[< GlMap.target] -> unit val pwl_curve : t -> kind:[`trim_2|`trim_3] -> float array -> unit val surface : t -> sknots:float array -> tknots:float array -> control:float array array -> sorder:int -> torder:int -> target:[< Gl.target] -> unit type property = [ `sampling_method of [`path_length|`parametric_error|`domain_distance] | `sampling_tolerance of int | `parametric_tolerance of float | `u_step of int | `v_step of int | `display_mode of [`fill|`polygon|`patch] | `culling of bool | `auto_load_matrix of bool ] val property : t -> property -> unit lablgl-1.07/src/gluQuadric.ml000066400000000000000000000027001437514534100161250ustar00rootroot00000000000000(* $Id: gluQuadric.ml,v 1.5 2000-04-12 07:40:26 garrigue Exp $ *) type t external create : unit -> t = "ml_gluNewQuadric" external cylinder : t -> base:float -> top:float -> height:float -> slices:int -> stacks:int -> unit = "ml_gluCylinder_bc" "ml_gluCylinder" let cylinder ~base ~top ~height ~slices ~stacks ?(quad = create ()) () = cylinder ~base ~top ~height ~slices ~stacks quad external disk : t -> inner:float -> outer:float -> slices:int -> loops:int -> unit = "ml_gluDisk" let disk ~inner ~outer ~slices ~loops ?(quad = create ()) () = disk ~inner ~outer ~slices ~loops quad external partial_disk : t -> inner:float -> outer:float -> slices:int -> loops:int -> start:float -> sweep:float -> unit = "ml_gluPartialDisk_bc" "ml_gluPartialDisk" let partial_disk ~inner ~outer ~slices ~loops ~start ~sweep ?(quad = create ()) () = partial_disk ~inner ~outer ~slices ~loops ~start ~sweep quad external draw_style : t -> [`fill|`line|`silhouette|`point] -> unit = "ml_gluQuadricDrawStyle" external normals : t -> [`none|`flat|`smooth] -> unit = "ml_gluQuadricNormals" external orientation : t -> [`inside|`outside] -> unit = "ml_gluQuadricOrientation" external texture : t -> bool -> unit = "ml_gluQuadricTexture" external sphere : t -> radius:float -> slices:int -> stacks:int -> unit = "ml_gluSphere" let sphere ~radius ~slices ~stacks ?(quad = create ()) () = sphere ~radius ~slices ~stacks quad lablgl-1.07/src/gluQuadric.mli000066400000000000000000000014241437514534100163000ustar00rootroot00000000000000(* $Id: gluQuadric.mli,v 1.2 1999-11-15 14:32:14 garrigue Exp $ *) type t val create : unit -> t (* If you omit the quadric, a new one will be created *) val cylinder : base:float -> top:float -> height:float -> slices:int -> stacks:int -> ?quad:t -> unit -> unit val disk : inner:float -> outer:float -> slices:int -> loops:int -> ?quad:t -> unit -> unit val partial_disk : inner:float -> outer:float -> slices:int -> loops:int -> start:float -> sweep:float -> ?quad:t -> unit -> unit val sphere : radius:float -> slices:int -> stacks:int -> ?quad:t -> unit -> unit val draw_style : t -> [`fill|`line|`point|`silhouette] -> unit val normals : t -> [`flat|`none|`smooth] -> unit val orientation : t -> [`inside|`outside] -> unit val texture : t -> bool -> unit lablgl-1.07/src/gluTess.ml000066400000000000000000000011261437514534100154540ustar00rootroot00000000000000(* $Id: gluTess.ml,v 1.7 2004-07-13 07:55:18 garrigue Exp $ *) (* Code contributed by Jon Harrop *) type winding_rule = [`odd|`nonzero|`positive|`negative|`abs_geq_two] type vertices = (float * float * float) list external tesselate : ?winding:winding_rule -> ?boundary_only:bool -> ?tolerance:float -> vertices list -> unit = "ml_gluTesselate" type triangles = { singles: vertices list; strips: vertices list; fans: vertices list } external tesselate_and_return : ?winding:winding_rule -> ?tolerance:float -> vertices list -> triangles = "ml_gluTesselateAndReturn" lablgl-1.07/src/gluTess.mli000066400000000000000000000013411437514534100156240ustar00rootroot00000000000000(* $Id: gluTess.mli,v 1.8 2004-07-13 09:44:03 garrigue Exp $ *) (* Code contributed by Jon Harrop *) type winding_rule = [`odd|`nonzero|`positive|`negative|`abs_geq_two] type vertices = (float * float * float) list val tesselate : ?winding:winding_rule -> ?boundary_only:bool -> ?tolerance:float -> vertices list -> unit (** Render directly to current screen. Each [vertices] in the input is a contour in the single polygon represented by [vertices list]. *) type triangles = { singles: vertices list; strips: vertices list; fans: vertices list } val tesselate_and_return : ?winding:winding_rule -> ?tolerance:float -> vertices list -> triangles (** Return 3 lists of triangles instead of rendering directly *) lablgl-1.07/src/glu_tags.var000066400000000000000000000016151437514534100160160ustar00rootroot00000000000000(* $Id: glu_tags.var,v 1.5 2002-05-01 03:35:00 garrigue Exp $: tags for GLU library *) (* gluGetString *) version extensions (* gluNextContour *) exterior interior unknown ccw cw (* gluNurbsProperty *) sampling_method path_length parametric_error domain_distance sampling_tolerance parametric_tolerance u_step v_step display_mode fill culling auto_load_matrix polygon -> GLU_OUTLINE_POLYGON patch -> GLU_OUTLINE_PATCH (* gluQuadricDrawStyle *) line silhouette point (* gluQuadricNormals *) none flat smooth (* gluQuadricOrientation *) inside outside (* gluTessProperty *) winding_rule -> GLU_TESS_WINDING_RULE odd -> GLU_TESS_WINDING_ODD nonzero -> GLU_TESS_WINDING_NONZERO positive -> GLU_TESS_WINDING_POSITIVE negative -> GLU_TESS_WINDING_NEGATIVE abs_geq_two -> GLU_TESS_WINDING_ABS_GEQ_TWO boundary_only -> GLU_TESS_BOUNDARY_ONLY tolerance -> GLU_TESS_TOLERANCE $$ (* gluNurbsCurve *) trim_2 trim_3 lablgl-1.07/src/ml_gl.c000066400000000000000000000475321437514534100147450ustar00rootroot00000000000000/* $Id: ml_gl.c,v 1.51 2007-04-13 02:48:43 garrigue Exp $ */ #define CAML_NAME_SPACE #ifdef _WIN32 #include #endif #include #ifdef __APPLE__ #include #else #include #endif #ifdef HAS_GLEXT_H #include #undef GL_VERSION_1_3 #endif #include #include #include #include #include #include #include "ml_raw.h" #include "gl_tags.h" #include "ml_gl.h" #if !defined(GL_VERSION_1_4) #define GL_GENERATE_MIPMAP 0x8191 #endif /* #include */ void ml_raise_gl(const char *errmsg) { const static value * gl_exn = NULL; if (gl_exn == NULL) gl_exn = caml_named_value("glerror"); caml_raise_with_string(*gl_exn, (char*)errmsg); } value copy_string_check (const char *str) { if (!str) ml_raise_gl("Null string"); return caml_copy_string ((char*) str); } struct record { value key; GLenum data; }; static struct record input_table[] = { #include "gl_tags.c" }; static struct record *tag_table = NULL; #define TABLE_SIZE (TAG_NUMBER*2+1) CAMLprim value ml_gl_make_table (value unit) { int i; unsigned int hash; tag_table = caml_stat_alloc (TABLE_SIZE * sizeof(struct record)); memset ((char *) tag_table, 0, TABLE_SIZE * sizeof(struct record)); for (i = 0; i < TAG_NUMBER; i++) { hash = (unsigned long) input_table[i].key % TABLE_SIZE; while (tag_table[hash].key != 0) { hash ++; if (hash == TABLE_SIZE) hash = 0; } tag_table[hash].key = input_table[i].key; tag_table[hash].data = input_table[i].data; } return Val_unit; } GLenum GLenum_val(value tag) { unsigned int hash = (unsigned long) tag % TABLE_SIZE; if (!tag_table) ml_gl_make_table (Val_unit); while (tag_table[hash].key != tag) { if (tag_table[hash].key == 0) ml_raise_gl ("Unknown tag"); hash++; if (hash == TABLE_SIZE) hash = 0; } /* fprintf(stderr, "Converted %ld to %d", Int_val(tag), tag_table[hash].data); */ return tag_table[hash].data; } /* GLenum GLenum_val(value tag) { switch(tag) { #include "gl_tags.c" } ml_raise_gl("Unknown tag"); } */ ML_2 (glAccum, GLenum_val, Float_val) ML_2 (glAlphaFunc, GLenum_val, Float_val) ML_1 (glBegin, GLenum_val) ML_5 (glBitmap, Int_val, Int_val, Pair(arg3,Float_val,Float_val), Pair(arg4,Float_val,Float_val), Void_raw) ML_2 (glBlendFunc, GLenum_val, GLenum_val) CAMLprim value ml_glClipPlane(value plane, value equation) /* ML */ { double eq[4]; int i; for (i = 0; i < 4; i++) eq[i] = Double_val (Field(equation,i)); glClipPlane (GL_CLIP_PLANE0 + Int_val(plane), eq); return Val_unit; } CAMLprim value ml_glClear(value bit_list) /* ML */ { GLbitfield accu = 0; while (bit_list != Val_int(0)) { switch (Field (bit_list, 0)) { case MLTAG_color: accu |= GL_COLOR_BUFFER_BIT; break; case MLTAG_depth: accu |= GL_DEPTH_BUFFER_BIT; break; case MLTAG_accum: accu |= GL_ACCUM_BUFFER_BIT; break; case MLTAG_stencil: accu |= GL_STENCIL_BUFFER_BIT; break; } bit_list = Field (bit_list, 1); } glClear (accu); return Val_unit; } ML_4 (glClearAccum, Float_val, Float_val, Float_val, Float_val) ML_4 (glClearColor, Double_val, Double_val, Double_val, Double_val) ML_1 (glClearDepth, Double_val) ML_1 (glClearIndex, Float_val) ML_1 (glClearStencil, Int_val) ML_4 (glColor4d, Double_val, Double_val, Double_val, Double_val) ML_4 (glColorMask, Int_val, Int_val, Int_val, Int_val) ML_2 (glColorMaterial, GLenum_val, GLenum_val) ML_5 (glCopyPixels, Int_val, Int_val, Int_val, Int_val, GLenum_val) ML_1 (glCullFace, GLenum_val) ML_1 (glDisable, GLenum_val) ML_1 (glDepthFunc, GLenum_val) ML_1 (glDepthMask, Int_val) ML_2 (glDepthRange, Double_val, Double_val) CAMLprim value ml_glDrawBuffer (value buffer) { if (Is_block(buffer)) { int n = Int_val (Field(buffer,1)); if (n >= GL_AUX_BUFFERS) ml_raise_gl ("GlFunc.draw_buffer : no such auxiliary buffer"); glDrawBuffer (GL_AUX0 + n); } else glDrawBuffer (GLenum_val(buffer)); return Val_unit; } ML_4 (glDrawPixels, Int_val, Int_val, GLenum_val, Type_void_raw) ML_1 (glEdgeFlag, Int_val) ML_1 (glEnable, GLenum_val) ML_0 (glEnd) ML_1 (glEvalCoord1d, Double_val) ML_2 (glEvalCoord2d, Double_val, Double_val) ML_3 (glEvalMesh1, GLenum_val, Int_val, Int_val) ML_5 (glEvalMesh2, GLenum_val, Int_val, Int_val, Int_val, Int_val) ML_1 (glEvalPoint1, Int_val) ML_2 (glEvalPoint2, Int_val, Int_val) ML_3 (glFeedbackBuffer, Int_val, GLenum_val, (GLfloat*)Addr_raw) CAMLprim value ml_glFog (value param) /* ML */ { float params[4]; int i; switch (Field(param,0)) { case MLTAG_mode: glFogi(GL_FOG_MODE, GLenum_val(Field(param,1))); break; case MLTAG_density: glFogf(GL_FOG_DENSITY, Float_val(Field(param,1))); break; case MLTAG_start: glFogf(GL_FOG_START, Float_val(Field(param,1))); break; case MLTAG_End: glFogf(GL_FOG_END, Float_val(Field(param,1))); break; case MLTAG_index: glFogf(GL_FOG_INDEX, Float_val(Field(param,1))); break; case MLTAG_color: for (i = 0; i < 4; i++) params[i] = Float_val(Field(Field(param,1),i)); glFogfv(GL_FOG_COLOR, params); break; } return Val_unit; } ML_0 (glFlush) ML_0 (glFinish) ML_1 (glFrontFace, GLenum_val) ML_3 (glFrustum, Pair(arg1,Double_val,Double_val), Pair(arg2,Double_val,Double_val), Pair(arg3,Double_val,Double_val)) ML_1_ (glGetString, GLenum_val, copy_string_check) ML_2 (glGetDoublev, GLenum_val, Double_raw) CAMLprim value ml_glGetError(value unit) { switch (glGetError()) { case GL_NO_ERROR: return MLTAG_no_error; case GL_INVALID_ENUM: return MLTAG_invalid_enum; case GL_INVALID_VALUE: return MLTAG_invalid_value; case GL_INVALID_OPERATION: return MLTAG_invalid_operation; case GL_STACK_OVERFLOW: return MLTAG_stack_overflow; case GL_STACK_UNDERFLOW: return MLTAG_stack_underflow; case GL_OUT_OF_MEMORY: return MLTAG_out_of_memory; #if defined(GL_VERSION_1_2) || defined(GL_TABLE_TOO_LARGE) case GL_TABLE_TOO_LARGE: return MLTAG_table_too_large; #endif default: ml_raise_gl("glGetError: unknown error"); } } CAMLprim value ml_glHint (value target, value hint) { GLenum targ = 0U; switch (target) { case MLTAG_fog: targ = GL_FOG_HINT; break; case MLTAG_line_smooth: targ = GL_LINE_SMOOTH_HINT; break; case MLTAG_perspective_correction: targ = GL_PERSPECTIVE_CORRECTION_HINT; break; case MLTAG_point_smooth: targ = GL_POINT_SMOOTH_HINT; break; case MLTAG_polygon_smooth: targ = GL_POLYGON_SMOOTH_HINT; break; } glHint (targ, GLenum_val(hint)); return Val_unit; } ML_1 (glIndexMask, Int_val) ML_1 (glIndexd, Double_val) ML_0 (glInitNames) ML_1_ (glIsEnabled, GLenum_val, Val_int) CAMLprim value ml_glLight (value n, value param) /* ML */ { float params[4]; int i; if (Int_val(n) >= GL_MAX_LIGHTS) caml_invalid_argument ("Gl.light"); switch (Field(param,0)) { case MLTAG_ambient: case MLTAG_diffuse: case MLTAG_specular: case MLTAG_position: for (i = 0; i < 4; i++) params[i] = Float_val (Field(Field(param, 1), i)); break; case MLTAG_spot_direction: for (i = 0; i < 3; i++) params[i] = Float_val (Field(Field(param, 1), i)); break; default: params[0] = Float_val (Field(param, 1)); } glLightfv (GL_LIGHT0 + Int_val(n), GLenum_val(Field(param,0)), params); return Val_unit; } CAMLprim value ml_glLightModel (value param) /* ML */ { float params[4]; int i; switch (Field(param,0)) { case MLTAG_ambient: for (i = 0; i < 4; i++) params[i] = Float_val (Field(Field(param,1),i)); glLightModelfv (GL_LIGHT_MODEL_AMBIENT, params); break; case MLTAG_local_viewer: glLightModelf (GL_LIGHT_MODEL_LOCAL_VIEWER, Int_val(Field(param,1))); break; case MLTAG_two_side: glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, Int_val(Field(param,1))); break; case MLTAG_color_control: #ifdef GL_VERSION_1_2 switch (Field(param,1)) { case MLTAG_separate_specular_color: glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); break; case MLTAG_single_color: glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); break; } #else ml_raise_gl ("Parameter: GL_LIGHT_MODEL_COLOR_CONTROL not available"); #endif break; } return Val_unit; } ML_1 (glLineWidth, Float_val) ML_2 (glLineStipple, Int_val, Int_val) ML_1 (glLoadName, Int_val) ML_0 (glLoadIdentity) ML_1 (glLoadMatrixd, Double_raw) #ifdef GL_VERSION_1_3 ML_1 (glLoadTransposeMatrixd, Double_raw) #else CAMLprim void ml_glLoadTransposeMatrixd (value raw) { ml_raise_gl ("Function: glLoadTransposeMatrixd not available"); } #endif ML_1 (glLogicOp, GLenum_val) CAMLprim value ml_glMap1d (value target, value *u, value order, value raw) { int ustride = 0; GLenum targ = 0U; switch (target) { case MLTAG_vertex_3: targ = GL_MAP1_VERTEX_3; ustride = 3; break; case MLTAG_vertex_4: targ = GL_MAP1_VERTEX_4; ustride = 4; break; case MLTAG_index: targ = GL_MAP1_INDEX; ustride = 1; break; case MLTAG_color_4: targ = GL_MAP1_COLOR_4; ustride = 4; break; case MLTAG_normal: targ = GL_MAP1_NORMAL; ustride = 3; break; case MLTAG_texture_coord_1: targ = GL_MAP1_TEXTURE_COORD_1; ustride = 1; break; case MLTAG_texture_coord_2: targ = GL_MAP1_TEXTURE_COORD_2; ustride = 2; break; case MLTAG_texture_coord_3: targ = GL_MAP1_TEXTURE_COORD_3; ustride = 3; break; case MLTAG_texture_coord_4: targ = GL_MAP1_TEXTURE_COORD_4; ustride = 4; break; } glMap1d (targ, Double_val(u[0]), Double_val(u[1]), ustride, Int_val(order), Double_raw(raw)); return Val_unit; } CAMLprim value ml_glMap2d (value target, value u, value uorder, value v, value vorder, value raw) { int ustride = 0; GLenum targ = 0U; switch (target) { case MLTAG_vertex_3: targ = GL_MAP2_VERTEX_3; ustride = 3; break; case MLTAG_vertex_4: targ = GL_MAP2_VERTEX_4; ustride = 4; break; case MLTAG_index: targ = GL_MAP2_INDEX; ustride = 1; break; case MLTAG_color_4: targ = GL_MAP2_COLOR_4; ustride = 4; break; case MLTAG_normal: targ = GL_MAP2_NORMAL; ustride = 3; break; case MLTAG_texture_coord_1: targ = GL_MAP2_TEXTURE_COORD_1; ustride = 1; break; case MLTAG_texture_coord_2: targ = GL_MAP2_TEXTURE_COORD_2; ustride = 2; break; case MLTAG_texture_coord_3: targ = GL_MAP2_TEXTURE_COORD_3; ustride = 3; break; case MLTAG_texture_coord_4: targ = GL_MAP2_TEXTURE_COORD_4; ustride = 4; break; } glMap2d (targ, Double_val(Field(u,0)), Double_val(Field(u,1)), ustride, Int_val(uorder), Double_val(Field(v,0)), Double_val(Field(v,1)), Int_val(uorder)*ustride, Int_val(vorder), Double_raw(raw)); return Val_unit; } ML_bc6 (ml_glMap2d) ML_2 (glMapGrid1d, Int_val, Pair(arg2,Double_val,Double_val)) ML_4 (glMapGrid2d, Int_val, Pair(arg2,Double_val,Double_val), Int_val, Pair(arg4,Double_val,Double_val)) CAMLprim value ml_glMaterial (value face, value param) /* ML */ { float params[4]; int i; switch (Field(param,0)) { case MLTAG_shininess: params[0] = Float_val (Field(param, 1)); break; case MLTAG_color_indexes: for (i = 0; i < 3; i++) params[i] = Float_val (Field(Field(param, 1), i)); break; default: for (i = 0; i < 4; i++) params[i] = Float_val (Field(Field(param, 1), i)); break; } glMaterialfv (GLenum_val(face), GLenum_val(Field(param,0)), params); return Val_unit; } ML_1 (glMatrixMode, GLenum_val) ML_1 (glMultMatrixd, Double_raw) #ifdef GL_VERSION_1_3 ML_1 (glMultTransposeMatrixd, Double_raw) #else CAMLprim void ml_glMultTransposeMatrixd (value raw) { ml_raise_gl ("Function: glMultTransposeMatrixd not available"); } #endif ML_3 (glNormal3d, Double_val, Double_val, Double_val) ML_1 (glPassThrough, Float_val) CAMLprim value ml_glPixelMapfv (value map, value raw) { glPixelMapfv (GLenum_val(map), Int_val(Size_raw(raw))/sizeof(GLfloat), Float_raw(raw)); return Val_unit; } ML_3 (glOrtho, Pair(arg1,Double_val,Double_val), Pair(arg2,Double_val,Double_val), Pair(arg3,Double_val,Double_val)) ML_1 (glPixelStorei, Pair(arg1,GLenum_val,Int_val)) CAMLprim value ml_glPixelTransfer (value param) { GLenum pname = GLenum_val (Field(param,0)); switch (pname) { case GL_MAP_COLOR: case GL_MAP_STENCIL: case GL_INDEX_SHIFT: case GL_INDEX_OFFSET: glPixelTransferi (pname, Int_val (Field(param,1))); break; default: glPixelTransferf (pname, Float_val (Field(param,1))); } return Val_unit; } ML_2 (glPixelZoom, Float_val, Float_val) ML_1 (glPointSize, Float_val) ML_2 (glPolygonOffset, Float_val, Float_val) ML_2 (glPolygonMode, GLenum_val, GLenum_val) ML_1 (glPolygonStipple, (unsigned char *)Byte_raw) ML_0 (glPopAttrib) ML_0 (glPopMatrix) ML_0 (glPopName) CAMLprim value ml_glPushAttrib (value list) { GLbitfield mask = 0; while (list != Val_int(0)) { switch (Field(list,0)) { case MLTAG_accum_buffer:mask |= GL_ACCUM_BUFFER_BIT; break; case MLTAG_color_buffer:mask |= GL_COLOR_BUFFER_BIT; break; case MLTAG_current: mask |= GL_CURRENT_BIT; break; case MLTAG_depth_buffer:mask |= GL_DEPTH_BUFFER_BIT; break; case MLTAG_enable: mask |= GL_ENABLE_BIT; break; case MLTAG_eval: mask |= GL_EVAL_BIT; break; case MLTAG_fog: mask |= GL_FOG_BIT; break; case MLTAG_hint: mask |= GL_HINT_BIT; break; case MLTAG_lighting: mask |= GL_LIGHTING_BIT; break; case MLTAG_line: mask |= GL_LINE_BIT; break; case MLTAG_list: mask |= GL_LIST_BIT; break; case MLTAG_pixel_mode: mask |= GL_PIXEL_MODE_BIT; break; case MLTAG_point: mask |= GL_POINT_BIT; break; case MLTAG_polygon: mask |= GL_POLYGON_BIT; break; case MLTAG_polygon_stipple:mask |= GL_POLYGON_STIPPLE_BIT; break; case MLTAG_scissor: mask |= GL_SCISSOR_BIT; break; case MLTAG_stencil_buffer:mask |= GL_STENCIL_BUFFER_BIT; break; case MLTAG_texture: mask |= GL_TEXTURE_BIT; break; case MLTAG_transform: mask |= GL_TRANSFORM_BIT; break; case MLTAG_viewport: mask |= GL_VIEWPORT_BIT; break; } list = Field(list,1); } glPushAttrib (mask); return Val_unit; } ML_0 (glPushMatrix) ML_1 (glPushName, Int_val) CAMLprim value ml_glRasterPos(value x, value y, value z, value w) /* ML */ { if (z == Val_int(0)) glRasterPos2d (Double_val(x), Double_val(y)); else if (w == Val_int(0)) glRasterPos3d (Double_val(x), Double_val(y), Double_val(Field(z, 0))); else glRasterPos4d (Double_val(x), Double_val(y), Double_val(Field(z, 0)), Double_val(Field(w, 0))); return Val_unit; } CAMLprim value ml_glReadBuffer (value buffer) { if (Is_block(buffer)) { int n = Int_val (Field(buffer,1)); if (n >= GL_AUX_BUFFERS) ml_raise_gl ("GlFunc.read_buffer : no such auxiliary buffer"); glReadBuffer (GL_AUX0 + n); } else glReadBuffer (GLenum_val(buffer)); return Val_unit; } CAMLprim value ml_glReadPixels(value x, value y, value w, value h, value format , value raw) /* ML */ { glPixelStorei(GL_PACK_SWAP_BYTES, 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(Int_val(x),Int_val(y),Int_val(w),Int_val(h),GLenum_val(format), Type_void_raw(raw)); return Val_unit; } ML_bc6 (ml_glReadPixels) ML_2 (glRectd, Pair(arg1,Double_val,Double_val), Pair(arg2,Double_val,Double_val)) ML_1_ (glRenderMode, GLenum_val, Val_int) ML_4 (glRotated, Double_val, Double_val, Double_val, Double_val) ML_3 (glScaled, Double_val, Double_val, Double_val) ML_4 (glScissor, Int_val, Int_val, Int_val, Int_val) ML_2 (glSelectBuffer, Int_val, (GLuint*)Addr_raw) ML_1 (glShadeModel, GLenum_val) ML_3 (glStencilFunc, GLenum_val, Int_val, Int_val) ML_1 (glStencilMask, Int_val) ML_3 (glStencilOp, GLenum_val, GLenum_val, GLenum_val) ML_1 (glTexCoord1d, Double_val) ML_2 (glTexCoord2d, Double_val, Double_val) ML_3 (glTexCoord3d, Double_val, Double_val, Double_val) ML_4 (glTexCoord4d, Double_val, Double_val, Double_val, Double_val) CAMLprim value ml_glTexEnv (value param) { value params = Field(param,1); GLfloat color[4]; int i; switch (Field(param,0)) { case MLTAG_mode: glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLenum_val(params)); break; case MLTAG_color: for (i = 0; i < 4; i++) color[i] = Float_val(Field(params,i)); glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); break; } return Val_unit; } CAMLprim value ml_glTexGen (value coord, value param) { value params = Field(param,1); GLdouble point[4]; int i; if (Field(param,0) == MLTAG_mode) glTexGeni (GLenum_val(coord), GL_TEXTURE_GEN_MODE, GLenum_val(params)); else { for (i = 0; i < 4; i++) point[i] = Double_val(Field(params,i)); glTexGendv (GLenum_val(coord), GLenum_val(Field(param,0)), point); } return Val_unit; } CAMLprim value ml_glTexImage1D (value proxy, value level, value internal, value width, value border, value format, value data) { glTexImage1D (proxy == Val_int(1) ? GL_PROXY_TEXTURE_1D : GL_TEXTURE_1D, Int_val(level), Int_val(internal), Int_val(width), Int_val(border), GLenum_val(format), Type_raw(data), Void_raw(data)); return Val_unit; } ML_bc7 (ml_glTexImage1D) CAMLprim value ml_glTexImage2D (value proxy, value level, value internal, value width, value height, value border, value format, value data) { /* printf("p=%x,l=%d,i=%d,w=%d,h=%d,b=%d,f=%x,t=%x,d=%x\n", */ glTexImage2D (proxy == Val_int(1) ? GL_PROXY_TEXTURE_2D : GL_TEXTURE_2D, Int_val(level), Int_val(internal), Int_val(width), Int_val(height), Int_val(border), GLenum_val(format), Type_raw(data), Void_raw(data)); /* flush(stdout); */ return Val_unit; } ML_bc8 (ml_glTexImage2D) CAMLprim value ml_glTexParameter (value target, value param) { GLenum targ = GLenum_val(target); GLenum pname = GLenum_val(Field(param,0)); value params = Field(param,1); GLfloat color[4]; int i; switch (pname) { case GL_TEXTURE_BORDER_COLOR: for (i = 0; i < 4; i++) color[i] = Float_val(Field(params,i)); glTexParameterfv (targ, pname, color); break; case GL_TEXTURE_PRIORITY: glTexParameterf (targ, pname, Float_val(params)); break; case GL_GENERATE_MIPMAP: #ifdef GL_VERSION_1_4 glTexParameteri (targ, pname, Int_val(params)); #else ml_raise_gl ("Parameter: GL_GENERATE_MIPMAP not available"); #endif break; default: glTexParameteri (targ, pname, GLenum_val(params)); break; } return Val_unit; } ML_2 (glGenTextures, Int_val, Int_raw) ML_2 (glBindTexture, GLenum_val, Nativeint_val) CAMLprim value ml_glDeleteTexture (value texture_id) { GLuint id = Nativeint_val(texture_id); glDeleteTextures(1,&id); return Val_unit; } ML_3 (glTranslated, Double_val, Double_val, Double_val) CAMLprim value ml_glVertex(value x, value y, value z, value w) /* ML */ { if (z == Val_int(0)) glVertex2d (Double_val(x), Double_val(y)); else if (w == Val_int(0)) glVertex3d (Double_val(x), Double_val(y), Double_val(Field(z, 0))); else glVertex4d (Double_val(x), Double_val(y), Double_val(Field(z, 0)), Double_val(Field(w, 0))); return Val_unit; } ML_4 (glViewport, Int_val, Int_val, Int_val, Int_val) /* List functions */ ML_1_ (glIsList, Int_val, Val_int) ML_2 (glDeleteLists, Int_val, Int_val) ML_1_ (glGenLists, Int_val, Val_int) ML_2 (glNewList, Int_val, GLenum_val) ML_0 (glEndList) ML_1 (glCallList, Int_val) ML_1 (glListBase, Int_val) CAMLprim value ml_glCallLists (value indexes) /* ML */ { int len,i; int * table; switch (Field(indexes,0)) { case MLTAG_byte: glCallLists (caml_string_length(Field(indexes,1)), GL_UNSIGNED_BYTE, String_val(Field(indexes,1))); break; case MLTAG_int: len = Wosize_val (indexes); table = calloc (len, sizeof (GLint)); for (i = 0; i < len; i++) table[i] = Int_val (Field(indexes,i)); glCallLists (len, GL_INT, table); free (table); break; } return Val_unit; } lablgl-1.07/src/ml_gl.h000066400000000000000000000136321437514534100147440ustar00rootroot00000000000000/* $Id: ml_gl.h,v 1.21 2003-10-03 04:27:19 garrigue Exp $ */ #ifndef _ml_gl_ #define _ml_gl_ #include "ml_raw.h" void ml_raise_gl (const char *errmsg) Noreturn; #define copy_string_check lablgl_copy_string_check value copy_string_check (const char *str); GLenum GLenum_val (value); #define Float_val(dbl) ((GLfloat) Double_val(dbl)) #define Addr_val(addr) ((GLvoid *) addr) #define Val_addr(addr) ((value) addr) #define Type_raw(raw) (GLenum_val(Kind_raw(raw))) #define Type_void_raw(raw) Type_raw(raw), Void_raw(raw) #define ML_0(cname) \ CAMLprim value ml_##cname (value unit) \ { cname (); return Val_unit; } #define ML_1(cname, conv1) \ CAMLprim value ml_##cname (value arg1) \ { cname (conv1(arg1)); return Val_unit; } #define ML_2(cname, conv1, conv2) \ CAMLprim value ml_##cname (value arg1, value arg2) \ { cname (conv1(arg1), conv2(arg2)); return Val_unit; } #define ML_3(cname, conv1, conv2, conv3) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3)); return Val_unit; } #define ML_4(cname, conv1, conv2, conv3, conv4) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4)); \ return Val_unit; } #define ML_5(cname, conv1, conv2, conv3, conv4, conv5) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5)); \ return Val_unit; } #define ML_6(cname, conv1, conv2, conv3, conv4, conv5, conv6) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6)); \ return Val_unit; } #define ML_7(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6), conv7(arg7)); \ return Val_unit; } #define ML_8(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7, value arg8) \ { cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), conv5(arg5), \ conv6(arg6), conv7(arg7), conv8(arg8)); \ return Val_unit; } #define ML_0_(cname, conv) \ CAMLprim value ml_##cname (value unit) \ { return conv (cname ()); } #define ML_1_(cname, conv1, conv) \ CAMLprim value ml_##cname (value arg1) \ { return conv (cname (conv1(arg1))); } #define ML_2_(cname, conv1, conv2, conv) \ CAMLprim value ml_##cname (value arg1, value arg2) \ { return conv (cname (conv1(arg1), conv2(arg2))); } #define ML_3_(cname, conv1, conv2, conv3, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3))); } #define ML_4_(cname, conv1, conv2, conv3, conv4, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4))); } #define ML_5_(cname, conv1, conv2, conv3, conv4, conv5, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5))); } #define ML_6_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6))); } #define ML_7_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6), conv7(arg7))); } #define ML_8_(cname, conv1, conv2, conv3, conv4, conv5, conv6, conv7, conv8, \ conv) \ CAMLprim value ml_##cname (value arg1, value arg2, value arg3, value arg4, \ value arg5, value arg6, value arg7, value arg8) \ { return conv (cname (conv1(arg1), conv2(arg2), conv3(arg3), conv4(arg4), \ conv5(arg5), conv6(arg6), conv7(arg7), conv8(arg8))); } /* Use with care: needs the argument index */ #define Ignore(x) #define Split(x,f,g) f(x), g(x) Ignore #define Split3(x,f,g,h) f(x), g(x), h(x) Ignore #define Pair(x,f,g) f(Field(x,0)), g(Field(x,1)) Ignore #define Triple(x,f,g,h) f(Field(x,0)), g(Field(x,1)), h(Field(x,2)) Ignore /* For more than 5 arguments */ #define ML_bc6(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5]); } #define ML_bc7(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5],argv[6]); } #define ML_bc8(cname) \ CAMLprim value cname##_bc (value *argv, int argn) \ { return cname(argv[0],argv[1],argv[2],argv[3],argv[4],argv[5],argv[6], \ argv[7]); } /* subtleties of openGL 1.1 vs 1.2 */ #if !defined(GL_DOUBLE) && defined(GL_DOUBLE_EXT) #define GL_DOUBLE GL_DOUBLE_EXT #endif #if !defined(GL_TEXTURE_PRIORITY) && defined(GL_TEXTURE_PRIORITY_EXT) #define GL_TEXTURE_PRIORITY GL_TEXTURE_PRIORITY_EXT #endif #if !defined(GL_PROXY_TEXTURE_1D) && defined(GL_PROXY_TEXTURE_1D_EXT) #define GL_PROXY_TEXTURE_1D GL_PROXY_TEXTURE_1D_EXT #endif #if !defined(GL_PROXY_TEXTURE_2D) && defined(GL_PROXY_TEXTURE_2D_EXT) #define GL_PROXY_TEXTURE_2D GL_PROXY_TEXTURE_2D_EXT #endif #endif lablgl-1.07/src/ml_glarray.c000066400000000000000000000054421437514534100157760ustar00rootroot00000000000000 #define CAML_NAME_SPACE #ifdef _WIN32 #include #endif #include #include #include #include #include #include #ifdef __APPLE__ #include #else #include #endif #include "ml_gl.h" #include "gl_tags.h" #include "raw_tags.h" #include "ml_raw.h" int ml_glSizeOfValue(value v) { switch(v) { case MLTAG_one: return(1); case MLTAG_two: return(2); case MLTAG_three: return(3); case MLTAG_four: return(4); default: ml_raise_gl("ml_glSizeOfValue: invalid size"); } } CAMLprim value ml_glEdgeFlagPointer(value raw) { glEdgeFlagPointer(0, (GLboolean*)Addr_raw(raw)); return Val_unit; } CAMLprim value ml_glTexCoordPointer(value size, value raw) { glTexCoordPointer (ml_glSizeOfValue(size), GLenum_val(Kind_raw(raw)), 0, Void_raw(raw)); return Val_unit; } CAMLprim value ml_glColorPointer(value size, value raw) { glColorPointer (ml_glSizeOfValue(size), GLenum_val(Kind_raw(raw)), 0, Void_raw(raw)); return Val_unit; } CAMLprim value ml_glIndexPointer(value raw) { glIndexPointer (GLenum_val(Kind_raw(raw)), 0, Void_raw(raw)); return Val_unit; } CAMLprim value ml_glNormalPointer(value raw) { glNormalPointer (GLenum_val(Kind_raw(raw)), 0, Void_raw(raw)); return Val_unit; } CAMLprim value ml_glVertexPointer(value size, value raw) { glVertexPointer (ml_glSizeOfValue(size), GLenum_val(Kind_raw(raw)), 0, Void_raw(raw)); return Val_unit; } CAMLprim value ml_glEnableClientState(value kl) { GLenum a; switch(kl) { case MLTAG_edge_flag: a = GL_EDGE_FLAG_ARRAY; break; case MLTAG_texture_coord: a = GL_TEXTURE_COORD_ARRAY; break; case MLTAG_color: a = GL_COLOR_ARRAY; break; case MLTAG_index: a = GL_INDEX_ARRAY; break; case MLTAG_normal: a = GL_NORMAL_ARRAY; break; case MLTAG_vertex: a = GL_VERTEX_ARRAY; break; default: ml_raise_gl("ml_glEnableClientState: invalid array"); } glEnableClientState(a); return Val_unit; } CAMLprim value ml_glDisableClientState(value kl) { GLenum a; switch(kl) { case MLTAG_edge_flag: a = GL_EDGE_FLAG_ARRAY; break; case MLTAG_texture_coord: a = GL_TEXTURE_COORD_ARRAY; break; case MLTAG_color: a = GL_COLOR_ARRAY; break; case MLTAG_index: a = GL_INDEX_ARRAY; break; case MLTAG_normal: a = GL_NORMAL_ARRAY; break; case MLTAG_vertex: a = GL_VERTEX_ARRAY; break; default: ml_raise_gl("ml_glDisableClientState: invalid array"); } glDisableClientState(a); return Val_unit; } ML_1 (glArrayElement, Int_val); ML_3 (glDrawArrays, GLenum_val, Int_val, Int_val); CAMLprim value ml_glDrawElements(value mode, value count, value raw) { glDrawElements (GLenum_val(mode), Int_val(count), GLenum_val(Kind_raw(raw)), Void_raw(raw)); return Val_unit; } lablgl-1.07/src/ml_glu.c000066400000000000000000000212371437514534100151240ustar00rootroot00000000000000/* $Id: ml_glu.c,v 1.28 2004-11-02 07:03:34 garrigue Exp $ */ #define CAML_NAME_SPACE #ifdef _WIN32 #include #endif #ifdef __APPLE__ #include #include #else #include #include #endif #include #include #include #include #include "gl_tags.h" #include "glu_tags.h" #include "ml_gl.h" #include "ml_glu.h" GLenum GLUenum_val(value tag) { switch(tag) { #include "glu_tags.c" } ml_raise_gl ("Unknown GLU tag"); } /* Does not register the structure with Caml ! static value Val_addr (void *addr) { value wrapper; if (!addr) ml_raise_gl ("Bad address"); wrapper = alloc(1,No_scan_tag); Field(wrapper,0) = (value) addr; return wrapper; } */ #define Nurb_val(struc) ((GLUnurbsObj *) Field(struc,1)) #define Quad_val(struc) ((GLUquadricObj *) Field(struc,1)) #define Store_addr(struc, addr) Field(struc,1) = (value) addr #define ML_final(cname) \ static void ml_##cname (value struc) \ { cname ((GLvoid *) Field(struc,1)); } ML_final (gluDeleteNurbsRenderer) ML_final (gluDeleteQuadric) /* Called from ML */ ML_1 (gluBeginCurve, Nurb_val) ML_1 (gluBeginSurface, Nurb_val) ML_1 (gluBeginTrim, Nurb_val) CAMLprim value ml_gluBuild1DMipmaps (value internal, value width, value format, value data) { GLenum error; error = gluBuild1DMipmaps (GL_TEXTURE_1D, Int_val(internal), Int_val(width), GLenum_val(format), Type_raw(data), Void_raw(data)); if (error) ml_raise_gl((char*)gluErrorString(error)); return Val_unit; } CAMLprim value ml_gluBuild2DMipmaps (value internal, value width, value height, value format, value data) { GLint error; error = gluBuild2DMipmaps (GL_TEXTURE_2D, Int_val(internal), Int_val(width), Int_val(height), GLenum_val(format), Type_raw(data), Void_raw(data)); if (error) ml_raise_gl((char*)gluErrorString(error)); return Val_unit; } ML_6 (gluCylinder, Quad_val, Double_val, Double_val, Double_val, Int_val, Int_val) ML_bc6 (ml_gluCylinder) ML_5 (gluDisk, Quad_val, Double_val, Double_val, Int_val, Int_val) ML_1 (gluEndCurve, Nurb_val) ML_1 (gluEndSurface, Nurb_val) ML_1 (gluEndTrim, Nurb_val) ML_1_ (gluGetString, GLUenum_val, copy_string_check) ML_4 (gluLoadSamplingMatrices, Nurb_val, Float_raw, Float_raw, (GLint*)Int_raw) ML_3 (gluLookAt, Triple(arg1,Double_val,Double_val,Double_val), Triple(arg2,Double_val,Double_val,Double_val), Triple(arg3,Double_val,Double_val,Double_val)) CAMLprim value ml_gluNewNurbsRenderer (void) { value struc = caml_alloc_final (2, ml_gluDeleteNurbsRenderer, 1, 32); Store_addr(struc, gluNewNurbsRenderer()); return struc; } CAMLprim value ml_gluNewQuadric (void) { value struc = caml_alloc_final (2, ml_gluDeleteQuadric, 1, 32); Store_addr(struc, gluNewQuadric()); return struc; } #define Fsize_raw(raw) (Int_val(Size_raw(raw))/sizeof(GLfloat)) CAMLprim value ml_gluNurbsCurve (value nurb, value knots, value control, value order, value type) { GLenum targ = 0U; int ustride = 0; switch (type) { case MLTAG_vertex_3: targ = GL_MAP1_VERTEX_3; ustride = 3; break; case MLTAG_vertex_4: targ = GL_MAP1_VERTEX_4; ustride = 4; break; case MLTAG_index: targ = GL_MAP1_INDEX; ustride = 1; break; case MLTAG_color_4: targ = GL_MAP1_COLOR_4; ustride = 4; break; case MLTAG_normal: targ = GL_MAP1_NORMAL; ustride = 3; break; case MLTAG_texture_coord_1: targ = GL_MAP1_TEXTURE_COORD_1; ustride = 1; break; case MLTAG_texture_coord_2: targ = GL_MAP1_TEXTURE_COORD_2; ustride = 2; break; case MLTAG_texture_coord_3: targ = GL_MAP1_TEXTURE_COORD_3; ustride = 3; break; case MLTAG_texture_coord_4: targ = GL_MAP1_TEXTURE_COORD_4; ustride = 4; break; case MLTAG_trim_2: targ = GLU_MAP1_TRIM_2; ustride = 2; break; case MLTAG_trim_3: targ = GLU_MAP1_TRIM_3; ustride = 3; break; } gluNurbsCurve (Nurb_val(nurb), Fsize_raw(knots), Float_raw(knots), ustride, Float_raw(control), Int_val(order), targ); return Val_unit; } CAMLprim value ml_gluNurbsProperty (value nurb, value prop) { GLfloat val; GLenum property = GLUenum_val (Field(prop,0)); switch (property) { case GLU_SAMPLING_METHOD: case GLU_DISPLAY_MODE: val = GLUenum_val (Field(prop,1)); break; case GLU_PARAMETRIC_TOLERANCE: val = Float_val (Field(prop,1)); break; default: val = Int_val (Field(prop,1)); break; } gluNurbsProperty (Nurb_val(nurb), property, val); return Val_unit; } CAMLprim value ml_gluNurbsSurface (value nurb, value sKnots, value tKnots, value tStride, value control, value sOrder, value tOrder, value tag) { GLenum type = 0U; GLint sStride = 0; switch (tag) { case MLTAG_vertex_3: type = GL_MAP2_VERTEX_3; sStride = 3; break; case MLTAG_vertex_4: type = GL_MAP2_VERTEX_4; sStride = 4; break; case MLTAG_index: type = GL_MAP2_INDEX; sStride = 1; break; case MLTAG_color_4: type = GL_MAP2_COLOR_4; sStride = 4; break; case MLTAG_normal: type = GL_MAP2_NORMAL; sStride = 3; break; case MLTAG_texture_coord_1: type = GL_MAP2_TEXTURE_COORD_1; sStride = 1; break; case MLTAG_texture_coord_2: type = GL_MAP2_TEXTURE_COORD_2; sStride = 2; break; case MLTAG_texture_coord_3: type = GL_MAP2_TEXTURE_COORD_3; sStride = 3; break; case MLTAG_texture_coord_4: type = GL_MAP2_TEXTURE_COORD_4; sStride = 4; break; } gluNurbsSurface (Nurb_val(nurb), Fsize_raw(sKnots), Float_raw(sKnots), Fsize_raw(tKnots), Float_raw(tKnots), sStride, Int_val(tStride), Float_raw(control), Int_val(sOrder), Int_val(tOrder), type); return Val_unit; } ML_bc8 (ml_gluNurbsSurface) ML_4 (gluOrtho2D, Double_val, Double_val, Double_val, Double_val) ML_7 (gluPartialDisk, Quad_val, Double_val, Double_val, Int_val, Int_val, Double_val, Double_val) ML_bc7 (ml_gluPartialDisk) ML_4 (gluPerspective, Double_val, Double_val, Double_val, Double_val) CAMLprim value ml_gluPickMatrix (value x, value y, value delX, value delY) { GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport); gluPickMatrix (Double_val(x), Double_val(y), Double_val(delX), Double_val(delY), viewport); return Val_unit; } CAMLprim value ml_gluProject (value object) { CAMLparam0(); GLdouble model[16]; GLdouble proj[16]; GLint viewport[4]; GLdouble winX, winY, winZ; CAMLlocal3(win0, win1, win2); value win; glGetDoublev (GL_MODELVIEW_MATRIX, model); glGetDoublev (GL_PROJECTION_MATRIX, proj); glGetIntegerv (GL_VIEWPORT, viewport); gluProject (Double_val(Field(object,0)), Double_val(Field(object,1)), Double_val(Field(object,2)), model, proj, viewport, &winX, &winY, &winZ); win0 = caml_copy_double(winX); win1 = caml_copy_double(winY); win2 = caml_copy_double(winZ); win = caml_alloc_small(3, 0); Field(win,0) = win0; Field(win,1) = win1; Field(win,2) = win2; CAMLreturn(win); } CAMLprim value ml_gluPwlCurve (value nurbs, value count, value data, value tag) { GLenum type = 0U; GLint stride = 0; switch (tag) { case MLTAG_trim_2: type = GLU_MAP1_TRIM_2; stride = 2; break; case MLTAG_trim_3: type = GLU_MAP1_TRIM_3; stride = 3; break; } gluPwlCurve (Nurb_val(nurbs), Int_val(count), Float_raw(data), stride, type); return Val_unit; } ML_2 (gluQuadricDrawStyle, Quad_val, GLUenum_val) ML_2 (gluQuadricNormals, Quad_val, GLUenum_val) ML_2 (gluQuadricOrientation, Quad_val, GLUenum_val) ML_2 (gluQuadricTexture, Quad_val, Int_val) ML_7 (gluScaleImage, GLenum_val, Int_val, Int_val, Split(arg4,Type_raw,Void_raw), Int_val, Int_val, Split(arg7,Type_raw,Void_raw)) ML_bc7 (ml_gluScaleImage) ML_4 (gluSphere, Quad_val, Double_val, Int_val, Int_val) CAMLprim value ml_gluUnProject (value win) { CAMLparam0(); GLdouble model[16]; GLdouble proj[16]; GLint viewport[4]; GLdouble objX, objY, objZ; GLint ok; CAMLlocal3(obj0,obj1,obj2); value obj; glGetDoublev (GL_MODELVIEW_MATRIX, model); glGetDoublev (GL_PROJECTION_MATRIX, proj); glGetIntegerv (GL_VIEWPORT, viewport); ok = gluUnProject (Double_val(Field(win,0)), Double_val(Field(win,1)), Double_val(Field(win,2)), model, proj, viewport, &objX, &objY, &objZ); if (!ok) ml_raise_gl ("Glu.unproject : point out of window"); obj0 = caml_copy_double(objX); obj1 = caml_copy_double(objY); obj2 = caml_copy_double(objZ); obj = caml_alloc_small (3, 0); Field(obj,0) = obj0; Field(obj,1) = obj1; Field(obj,2) = obj2; CAMLreturn(obj); } lablgl-1.07/src/ml_glu.h000066400000000000000000000006221437514534100151240ustar00rootroot00000000000000#ifndef _ml_glu_ #define _ml_glu_ GLenum GLUenum_val(value tag); #if !defined(GLU_VERSION_1_2) && !defined(GLU_TESS_WINDING_RULE) #define GLU_TESS_WINDING_RULE #define GLU_TESS_WINDING_ODD #define GLU_TESS_WINDING_NONZERO #define GLU_TESS_WINDING_POSITIVE #define GLU_TESS_WINDING_NEGATIVE #define GLU_TESS_WINDING_ABS_GEQ_TWO #define GLU_TESS_BOUNDARY_ONLY #define GLU_TESS_TOLERANCE #endif #endif lablgl-1.07/src/ml_glutess.c000066400000000000000000000131751437514534100160250ustar00rootroot00000000000000/* $Id: ml_glutess.c,v 1.7 2008-02-25 01:52:20 garrigue Exp $ */ /* Code contributed by Jon Harrop */ #define CAML_NAME_SPACE #include #include #ifdef _WIN32 #include #endif #ifdef __APPLE__ #include #include #else #include #include #endif #include #include #include #include #include "gl_tags.h" #include "glu_tags.h" #include "ml_gl.h" #include "ml_glu.h" #ifndef GLU_VERSION_1_2 #define ML_fail(cname) \ CAMLprim value ml_##cname (value any) \ { ml_raise_gl ("Function not available: "#cname); } ML_fail (gluTesselate) ML_fail (gluTesselateAndReturn) #else /* Apparently this is used under Windows, according to the Red Book. */ #ifndef CALLBACK #define CALLBACK #endif #define AS_CB (GLvoid(CALLBACK *)()) static void CALLBACK errorCallback(GLenum error) { ml_raise_gl((char*)gluErrorString(error)); } typedef struct chunklist { struct chunklist *next; int current; int size; GLdouble data[32][3]; } chunklist; static chunklist *rootchunk=NULL; static GLdouble *new_vertex(GLdouble x, GLdouble y, GLdouble z) { GLdouble *vert; if (rootchunk == NULL || rootchunk->current >= rootchunk->size) { chunklist *tmp = rootchunk; rootchunk = (chunklist*)malloc(sizeof(chunklist)); rootchunk->next = tmp; rootchunk->current = 0; rootchunk->size = 32; } vert = rootchunk->data[rootchunk->current++]; vert[0] = x; vert[1] = y; vert[2] = z; return vert; } static void free_chunks() { while (rootchunk != NULL) { chunklist *next = rootchunk->next; free(rootchunk); rootchunk = next; } } static void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **data) { *data = new_vertex(coords[0],coords[1],coords[2]); } /* prim is only valid during callbacks */ static value *prim; static int kind = 0; static void push_vert(value root, double x, double y, double z) { CAMLparam1(root); CAMLlocal4(vert, xx, yy, zz); value cons; xx = caml_copy_double(x); yy = caml_copy_double(y); zz = caml_copy_double(z); vert = caml_alloc_tuple(3); Field(vert,0) = xx; Field(vert,1) = yy; Field(vert,2) = zz; cons = caml_alloc_tuple(2); Field(cons, 0) = vert; Field(cons, 1) = Field(root,0); caml_modify(&Field(root,0), cons); CAMLreturn0; } static void push_list() { value cons = caml_alloc_tuple(2); Field(cons,0) = Val_unit; Field(cons,1) = Field(*prim,kind); caml_modify(&Field(*prim,kind), cons); } static void CALLBACK beginCallback(GLenum type) { switch (type) { case GL_TRIANGLES : kind = 0; break; case GL_TRIANGLE_FAN : kind = 1; break; case GL_TRIANGLE_STRIP : kind = 2; break; default: { char msg[80]; sprintf(msg, "Unknown primitive format %d in tesselation.\n", (int)type); ml_raise_gl(msg); } } push_list(); } static void CALLBACK vertexCallback(void *vertex_data) { GLdouble *verts=(GLdouble *)vertex_data; push_vert(Field(*prim,kind), verts[0], verts[1], verts[2]); } static void CALLBACK endCallback() { kind = 0; } static GLUtesselator *tobj=NULL; static void iniTesselator(value winding, value by_only, value tolerance) { if (!tobj) { tobj=gluNewTess(); if (!tobj) ml_raise_gl("Failed to initialise the GLU tesselator."); } gluTessNormal(tobj, 0.0, 0.0, 1.0); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, (winding != Val_unit ? GLUenum_val(Field(winding,0)) : GLU_TESS_WINDING_ODD)); gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, (by_only != Val_unit && Field(by_only,0) != Val_unit)); gluTessProperty(tobj, GLU_TESS_TOLERANCE, (tolerance != Val_unit ? Float_val(Field(by_only,0)) : 0)); } static void runTesselator(value contours) { CAMLparam1(contours); gluTessBeginPolygon(tobj, NULL); while (contours != Val_int(0)) { value contour=Field(contours, 0); gluTessBeginContour(tobj); while (contour != Val_int(0)) { value v=Field(contour, 0); GLdouble *r = new_vertex(Double_val(Field(v, 0)), Double_val(Field(v, 1)), Double_val(Field(v, 2))); gluTessVertex(tobj, r, (void *)r); contour = Field(contour, 1); } contours = Field(contours, 1); gluTessEndContour(tobj); } gluTessEndPolygon(tobj); gluDeleteTess(tobj); tobj = NULL; free_chunks(); CAMLreturn0; } CAMLprim value ml_gluTesselateAndReturn(value winding, value tolerance, value contours) { CAMLparam1(contours); CAMLlocal1(res); res = caml_alloc_tuple(3); Field(res,0) = Field(res,1) = Field(res,2) = Val_unit; prim = &res; iniTesselator(winding, Val_unit, tolerance); gluTessCallback(tobj, GLU_TESS_BEGIN, AS_CB beginCallback); gluTessCallback(tobj, GLU_TESS_VERTEX, AS_CB vertexCallback); gluTessCallback(tobj, GLU_TESS_END, AS_CB endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, AS_CB errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, AS_CB combineCallback); runTesselator(contours); CAMLreturn (res); } CAMLprim value ml_gluTesselate (value winding, value by_only, value tolerance, value contours) { iniTesselator(winding, by_only, tolerance); gluTessCallback(tobj, GLU_TESS_BEGIN, AS_CB glBegin); gluTessCallback(tobj, GLU_TESS_VERTEX, AS_CB glVertex3dv); gluTessCallback(tobj, GLU_TESS_END, AS_CB glEnd); gluTessCallback(tobj, GLU_TESS_ERROR, AS_CB errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, AS_CB combineCallback); runTesselator(contours); return Val_unit; } #endif lablgl-1.07/src/ml_raw.c000066400000000000000000000302621437514534100151240ustar00rootroot00000000000000/* $Id: ml_raw.c,v 1.16 2007-04-13 02:48:43 garrigue Exp $ */ #define CAML_NAME_SPACE #include #include #include #include #include #include #include #include "raw_tags.h" #include "ml_raw.h" #define SIZE_BYTE sizeof(char) #define SIZE_SHORT sizeof(short) #define SIZE_INT sizeof(int) #define SIZE_LONG sizeof(long) #define SIZE_FLOAT sizeof(float) #define SIZE_DOUBLE sizeof(double) static int raw_sizeof (value kind) { switch (kind) { case MLTAG_bitmap: case MLTAG_byte: case MLTAG_ubyte: return SIZE_BYTE; case MLTAG_short: case MLTAG_ushort: return SIZE_SHORT; case MLTAG_int: case MLTAG_uint: return SIZE_INT; case MLTAG_long: case MLTAG_ulong: return SIZE_LONG; case MLTAG_float: return SIZE_FLOAT; case MLTAG_double: return SIZE_DOUBLE; } return 0; } CAMLprim value ml_raw_sizeof (value kind) /* ML */ { return Val_int(raw_sizeof(kind)); } static void check_size (value raw, long pos, char *msg) { if (pos < 0 || (pos+1) * raw_sizeof(Kind_raw(raw)) > Int_val(Size_raw(raw))) caml_invalid_argument (msg); } CAMLprim value ml_raw_get (value raw, value pos) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.get"); switch (Kind_raw(raw)) { case MLTAG_bitmap: case MLTAG_ubyte: return Val_long ((unsigned char) Byte_raw(raw)[i]); case MLTAG_byte: return Val_long (Byte_raw(raw)[i]); case MLTAG_short: return Val_long (Short_raw(raw)[i]); case MLTAG_ushort: return Val_long ((unsigned short) Short_raw(raw)[i]); case MLTAG_int: return Val_long (Int_raw(raw)[i]); case MLTAG_uint: return Val_long ((unsigned int) Int_raw(raw)[i]); case MLTAG_long: return Val_long (Long_raw(raw)[i]); case MLTAG_ulong: return Val_long ((unsigned long) Long_raw(raw)[i]); } return Val_unit; } CAMLprim value ml_raw_read (value raw, value pos, value len) /* ML */ { int s = Int_val(pos); int i, l = Int_val(len); value ret; check_size (raw,s+l-1,"Raw.read"); if (l<0 || s<0) caml_invalid_argument("Raw.read"); ret = caml_alloc_shr (l, 0); switch (Kind_raw(raw)) { case MLTAG_bitmap: case MLTAG_ubyte: { unsigned char *byte_raw = (unsigned char *)Byte_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*byte_raw++); break; } case MLTAG_byte: { char *byte_raw = Byte_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*byte_raw++); break; } case MLTAG_short: { short *short_raw = Short_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*short_raw++); break; } case MLTAG_ushort: { unsigned short *short_raw = (unsigned short *)Short_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*short_raw++); break; } case MLTAG_int: { int *int_raw = Int_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*int_raw++); break; } case MLTAG_uint: { unsigned int *int_raw = (unsigned int *)Int_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*int_raw++); break; } case MLTAG_long: { long *long_raw = Long_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*long_raw++); break; } case MLTAG_ulong: { unsigned long *long_raw = (unsigned long *)Long_raw(raw)+s; for (i = 0; i < l; i++) Field(ret,i) = Val_long (*long_raw++); break; } } return ret; } CAMLprim value ml_raw_read_string (value raw, value pos, value len) /* ML */ { CAMLparam1(raw); int s = Int_val(pos); int l = Int_val(len); value ret; if (l<0 || s<0 || s+l > Int_val(Size_raw(raw))) caml_invalid_argument("Raw.read_string"); ret = caml_alloc_string (l); memcpy (Bytes_val(ret), Bp_val(Addr_raw(raw))+s, l); CAMLreturn(ret); } CAMLprim value ml_raw_write_string (value raw, value pos, value data) /* ML */ { int s = Int_val(pos); int l = caml_string_length(data); if (s<0 || s+l > Int_val(Size_raw(raw))) caml_invalid_argument("Raw.write_string"); memcpy (Bp_val(Addr_raw(raw))+s, String_val(data), l); return Val_unit; } CAMLprim value ml_raw_set (value raw, value pos, value data) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.set"); switch (Kind_raw(raw)) { case MLTAG_bitmap: case MLTAG_ubyte: case MLTAG_byte: Byte_raw(raw)[i] = Long_val(data); break; case MLTAG_short: case MLTAG_ushort: Short_raw(raw)[i] = Long_val(data); break; case MLTAG_int: Int_raw(raw)[i] = Long_val(data); break; case MLTAG_uint: Int_raw(raw)[i] = Long_val((unsigned long) data); break; case MLTAG_long: Long_raw(raw)[i] = Long_val(data); break; case MLTAG_ulong: Long_raw(raw)[i] = Long_val((unsigned long) data); break; } return Val_unit; } CAMLprim value ml_raw_write (value raw, value pos, value data) /* ML */ { int s = Int_val(pos); int i, l = Wosize_val(data); check_size (raw,s+l-1,"Raw.write"); if (s<0) caml_invalid_argument("Raw.write"); switch (Kind_raw(raw)) { case MLTAG_bitmap: case MLTAG_ubyte: case MLTAG_byte: { char *byte_raw = Byte_raw(raw)+s; for (i = 0; i < l; i++) *byte_raw++ = Long_val(Field(data,i)); break; } case MLTAG_short: case MLTAG_ushort: { short *short_raw = Short_raw(raw)+s; for (i = 0; i < l; i++) *short_raw++ = Long_val(Field(data,i)); break; } case MLTAG_int: { int *int_raw = Int_raw(raw)+s; for (i = 0; i < l; i++) *int_raw++ = Long_val(Field(data,i)); break; } case MLTAG_uint: { int *int_raw = Int_raw(raw)+s; for (i = 0; i < l; i++) *int_raw++ = Long_val((unsigned long) Field(data,i)); break; } case MLTAG_long: { long *long_raw = Long_raw(raw)+s; for (i = 0; i < l; i++) *long_raw++ = Long_val(Field(data,i)); break; } case MLTAG_ulong: { long *long_raw = Long_raw(raw)+s; for (i = 0; i < l; i++) *long_raw++ = Long_val((unsigned long) Field(data,i)); break; } } return Val_unit; } CAMLprim value ml_raw_get_float (value raw, value pos) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.get_float"); if (Kind_raw(raw) == MLTAG_float) return caml_copy_double ((double) Float_raw(raw)[i]); else return caml_copy_double (Double_raw(raw)[i]); } CAMLprim value ml_raw_read_float (value raw, value pos, value len) /* ML */ { int s = Int_val(pos); int i, l = Int_val(len); value ret = Val_unit; check_size (raw,s+l-1,"Raw.read_float"); if (l<0 || s<0) caml_invalid_argument("Raw.read_float"); ret = caml_alloc_shr (l*sizeof(double)/sizeof(value), Double_array_tag); if (Kind_raw(raw) == MLTAG_float) { float *float_raw = Float_raw(raw)+s; for (i = 0; i < l; i++) Store_double_field(ret, i, (double) *float_raw++); } else { double *double_raw = Double_raw(raw)+s; for (i = 0; i < l; i++) Store_double_field(ret, i, *double_raw++); } return ret; } CAMLprim value ml_raw_set_float (value raw, value pos, value data) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.set_float"); if (Kind_raw(raw) == MLTAG_float) Float_raw(raw)[i] = (float) Double_val(data); else Double_raw(raw)[i] = Double_val(data); return Val_unit; } CAMLprim value ml_raw_write_float (value raw, value pos, value data) /* ML */ { int s = Int_val(pos); int i, l = Wosize_val(data)*sizeof(value)/sizeof(double); check_size (raw,s+l-1,"Raw.write_float"); if (s<0) caml_invalid_argument("Raw.write_float"); if (Kind_raw(raw) == MLTAG_float) { float *float_raw = Float_raw(raw)+s; for (i = 0; i < l; i++) *float_raw++ = (float) Double_field(data,i); } else { double *double_raw = Double_raw(raw)+s; for (i = 0; i < l; i++) *double_raw++ = Double_field(data,i); } return Val_unit; } #ifdef ARCH_BIG_ENDIAN #define HI_OFFSET 1 #define LO_OFFSET 0 #else #define HI_OFFSET 0 #define LO_OFFSET 1 #endif /* Here we suppose that: * sizeof(int) == 2*sizeof(short) * sizeof(long) == 2*sizeof(int) (64-bit architectures) * sizeof(long) == 2*sizeof(short) (otherwise) */ #define Hint_raw(raw) ((unsigned short *) Short_raw(raw)) #ifdef ARCH_SIXTYFOUR #define Hlong_raw(raw) ((unsigned int *) Int_raw(raw)) #else #define Hlong_raw(raw) ((unsigned short *) Short_raw(raw)) #endif CAMLprim value ml_raw_get_hi (value raw, value pos) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.get_hi"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: return Val_long (Hint_raw(raw)[2*i+HI_OFFSET]); case MLTAG_long: case MLTAG_ulong: return Val_long (Hlong_raw(raw)[2*i+HI_OFFSET]); } return Val_unit; } CAMLprim value ml_raw_get_lo (value raw, value pos) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.get_lo"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: return Val_long ((unsigned long) Hint_raw(raw)[2*i+LO_OFFSET]); case MLTAG_long: case MLTAG_ulong: return Val_long ((unsigned long) Hlong_raw(raw)[2*i+LO_OFFSET]); } return Val_unit; } CAMLprim value ml_raw_set_hi (value raw, value pos, value data) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.set_hi"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: Hint_raw(raw)[2*i+HI_OFFSET] = Long_val(data); break; case MLTAG_long: case MLTAG_ulong: Hlong_raw(raw)[2*i+HI_OFFSET] = Long_val(data); break; } return Val_unit; } CAMLprim value ml_raw_set_lo (value raw, value pos, value data) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.set_lo"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: Hint_raw(raw)[2*i+LO_OFFSET] = Long_val(data); break; case MLTAG_long: case MLTAG_ulong: Hlong_raw(raw)[2*i+LO_OFFSET] = Long_val(data); break; } return Val_unit; } CAMLprim value ml_raw_get_long (value raw, value pos) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.get_long"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: return caml_copy_nativeint (Int_raw(raw)[i]); case MLTAG_long: case MLTAG_ulong: return caml_copy_nativeint (Long_raw(raw)[i]); } return Val_unit; } CAMLprim value ml_raw_set_long (value raw, value pos, value data) /* ML */ { long i = Long_val(pos); check_size (raw,i,"Raw.set_long"); switch (Kind_raw(raw)) { case MLTAG_int: case MLTAG_uint: Int_raw(raw)[i] = Nativeint_val(data); break; case MLTAG_long: case MLTAG_ulong: Long_raw(raw)[i] = Nativeint_val(data); break; } return Val_unit; } CAMLprim value ml_raw_alloc (value kind, value len) /* ML */ { CAMLparam0(); CAMLlocal1(data); value raw; int size = raw_sizeof(kind) * Int_val(len); int offset = 0; if (kind == MLTAG_double && sizeof(double) > sizeof(value)) { data = caml_alloc_shr ((size-1)/sizeof(value)+2, Abstract_tag); offset = (data % sizeof(double) ? sizeof(value) : 0); } else data = caml_alloc_shr ((size-1)/sizeof(value)+1, Abstract_tag); raw = caml_alloc_small (SIZE_RAW,0); Kind_raw(raw) = kind; Size_raw(raw) = Val_int(size); Base_raw(raw) = data; Offset_raw(raw) = Val_int(offset); Static_raw(raw) = Val_false; CAMLreturn(raw); } CAMLprim value ml_raw_alloc_static (value kind, value len) /* ML */ { value raw; void *data; int size = raw_sizeof(kind) * Int_val(len); int offset = 0; if (kind == MLTAG_double && sizeof(double) > sizeof(long)) { data = caml_stat_alloc (size+sizeof(long)); offset = ((long)data % sizeof(double) ? sizeof(value) : 0); } else data = caml_stat_alloc (size); raw = caml_alloc_small (SIZE_RAW, 0); Kind_raw(raw) = kind; Size_raw(raw) = Val_int(size); Base_raw(raw) = (value) data; Offset_raw(raw) = Val_int(offset); Static_raw(raw) = Val_true; return raw; } CAMLprim value ml_raw_free_static (value raw) /* ML */ { if (Static_raw(raw) != Val_int(1)) caml_invalid_argument ("Raw.free_static"); caml_stat_free (Void_raw(raw)); Base_raw(raw) = Val_unit; Size_raw(raw) = Val_unit; Offset_raw(raw) = Val_unit; Static_raw(raw) = Val_false; return Val_unit; } lablgl-1.07/src/ml_raw.h000066400000000000000000000013121437514534100151230ustar00rootroot00000000000000/* $Id: ml_raw.h,v 1.3 1999-04-14 14:05:52 garrigue Exp $ */ #ifndef _ml_raw_ #define _ml_raw_ #define SIZE_RAW 5 #define Kind_raw(raw) (Field(raw,0)) #define Base_raw(raw) (Field(raw,1)) #define Offset_raw(raw) (Field(raw,2)) #define Size_raw(raw) (Field(raw,3)) #define Static_raw(raw) (Field(raw,4)) #define Addr_raw(raw) (Base_raw(raw)+Long_val(Offset_raw(raw))) #define Void_raw(raw) ((void *) Addr_raw(raw)) #define Byte_raw(raw) ((char *) Addr_raw(raw)) #define Short_raw(raw) ((short *) Addr_raw(raw)) #define Int_raw(raw) ((int *) Addr_raw(raw)) #define Long_raw(raw) ((long *) Addr_raw(raw)) #define Float_raw(raw) ((float *) Addr_raw(raw)) #define Double_raw(raw) ((double *) Addr_raw(raw)) #endif lablgl-1.07/src/ml_shader.c000066400000000000000000001264001437514534100156010ustar00rootroot00000000000000/* $Id: ml_shader.c,v 1.1 2010-03-11 08:30:02 garrigue Exp $ */ /* Code contributed by Florent Monnier */ #define GL_GLEXT_PROTOTYPES #define CAML_NAME_SPACE #ifdef _WIN32 #include #endif #include #ifdef __APPLE__ #include #include #else #include #include #endif #include #include #include #include #include #include #include "gl_tags.h" #include "ml_gl.h" #ifdef _WIN32 #include // if the PFNGL*PROC types are not defined in gl.h or glext.h add these lines: #if 0 typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); #endif #define LOAD_FUNC(func, f_type) \ static f_type func = NULL; \ static unsigned int func##_is_loaded = 0; \ if (!func##_is_loaded) { \ func = (f_type) wglGetProcAddress(#func); \ if (func == NULL) caml_failwith("Unable to load " #func); \ else func##_is_loaded = 1; \ } #else #define LOAD_FUNC(func, f_type) #endif /* end of ifdef _WIN32 */ /* GLSL Shaders */ #ifdef GL_VERSION_2_0 /* wrap as abstract */ //define Val_shader_object(v) ((value)(v)) //define Shader_object_val(v) ((GLuint)(v)) //define Val_shader_program(v) ((value)(v)) //define Shader_program_val(v) ((GLuint)(v)) /* wrap as ints */ #define Val_shader_object Val_long #define Shader_object_val Long_val #define Val_shader_program Val_long #define Shader_program_val Long_val CAMLprim value ml_glcreateshader( value shaderType ) { GLuint s = 0; LOAD_FUNC(glCreateShader, PFNGLCREATESHADERPROC) switch (shaderType) { case MLTAG_vertex_shader: s = glCreateShader(GL_VERTEX_SHADER); break; case MLTAG_fragment_shader: s = glCreateShader(GL_FRAGMENT_SHADER); break; default: caml_failwith("glShader.create"); } if (s == 0) caml_failwith("glShader.create"); return Val_shader_object(s); } CAMLprim value ml_gldeleteshader( value shader ) { LOAD_FUNC(glDeleteShader, PFNGLDELETESHADERPROC) glDeleteShader( Shader_object_val(shader) ); return Val_unit; } CAMLprim value ml_glisshader( value shader ) { LOAD_FUNC(glIsShader, PFNGLISSHADERPROC) return (glIsShader( Shader_object_val(shader) ) == GL_TRUE ? Val_true : Val_false); } CAMLprim value ml_glshadersource( value shader, value str ) { const char * vp = String_val(str); LOAD_FUNC(glShaderSource, PFNGLSHADERSOURCEPROC) glShaderSource(Shader_object_val(shader), 1, &vp, NULL); return Val_unit; } CAMLprim value ml_glcompileshader( value shader ) { LOAD_FUNC(glCompileShader, PFNGLCOMPILESHADERPROC) glCompileShader( Shader_object_val(shader) ); return Val_unit; } CAMLprim value ml_glcreateprogram( value unit ) { LOAD_FUNC(glCreateProgram, PFNGLCREATEPROGRAMPROC) GLuint p = glCreateProgram(); if (p == 0) caml_failwith("glShader.create_program"); return Val_shader_program(p); } CAMLprim value ml_gldeleteprogram( value program ) { LOAD_FUNC(glDeleteProgram, PFNGLDELETEPROGRAMPROC) glDeleteProgram( Shader_program_val(program) ); return Val_unit; } CAMLprim value ml_glattachshader( value program, value shader ) { LOAD_FUNC(glAttachShader, PFNGLATTACHSHADERPROC) glAttachShader( Shader_program_val(program), Shader_object_val(shader) ); return Val_unit; } CAMLprim value ml_gldetachshader( value program, value shader ) { LOAD_FUNC(glDetachShader, PFNGLDETACHSHADERPROC) glDetachShader( Shader_program_val(program), Shader_object_val(shader) ); return Val_unit; } CAMLprim value ml_gllinkprogram( value program ) { LOAD_FUNC(glLinkProgram, PFNGLLINKPROGRAMPROC) glLinkProgram( Shader_program_val(program) ); return Val_unit; } CAMLprim value ml_gluseprogram( value program ) { LOAD_FUNC(glUseProgram, PFNGLUSEPROGRAMPROC) glUseProgram( Shader_program_val(program) ); return Val_unit; } CAMLprim value ml_glunuseprogram( value unit ) { /* desactivate */ LOAD_FUNC(glUseProgram, PFNGLUSEPROGRAMPROC) glUseProgram(0); return Val_unit; } CAMLprim value ml_glgetshadercompilestatus( value shader ) { GLint error; LOAD_FUNC(glGetShaderiv, PFNGLGETSHADERIVPROC) glGetShaderiv( Shader_object_val(shader), GL_COMPILE_STATUS, &error); if (error == GL_TRUE) return Val_true; else return Val_false; } CAMLprim value ml_glgetshadercompilestatus_exn( value shader ) { GLint error; LOAD_FUNC(glGetShaderiv, PFNGLGETSHADERIVPROC) glGetShaderiv( Shader_object_val(shader), GL_COMPILE_STATUS, &error); if (error != GL_TRUE) caml_failwith("Shader compile status: error"); return Val_unit; } CAMLprim value ml_glgetuniformlocation( value program, value name ) { LOAD_FUNC(glGetUniformLocation, PFNGLGETUNIFORMLOCATIONPROC) return Val_int( glGetUniformLocation( Shader_program_val(program), String_val(name) )); } #else CAMLprim value ml_glcreateshader( value shaderType ) { caml_failwith("glCreateShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gldeleteshader( value shader ) { caml_failwith("glDeleteShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glisshader( value shader ) { caml_failwith("glIsShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glshadersource( value shader, value str ) { caml_failwith("glShaderSource function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glcompileshader( value shader ) { caml_failwith("glCompileShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glcreateprogram( value unit ) { caml_failwith("glCreateProgram function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gldeleteprogram( value program ) { caml_failwith("glDeleteProgram function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glattachshader( value program, value shader ) { caml_failwith("glAttachShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gldetachshader( value program, value shader ) { caml_failwith("glDetachShader function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gllinkprogram( value program ) { caml_failwith("glLinkProgram function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluseprogram( value program ) { caml_failwith("glUseProgram function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glunuseprogram( value unit ) { caml_failwith("glUseProgram function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_glgetuniformlocation( value program, value name ) { caml_failwith("glGetUniformLocation function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } #endif #ifdef GL_VERSION_2_0 CAMLprim value ml_gluniform1f( value location, value v0) { LOAD_FUNC(glUniform1f, PFNGLUNIFORM1FPROC) glUniform1f( Int_val(location), Double_val(v0)); return Val_unit; } CAMLprim value ml_gluniform2f( value location, value v0, value v1) { LOAD_FUNC(glUniform2f, PFNGLUNIFORM2FPROC) glUniform2f( Int_val(location), Double_val(v0), Double_val(v1)); return Val_unit; } CAMLprim value ml_gluniform3f( value location, value v0, value v1, value v2) { LOAD_FUNC(glUniform3f, PFNGLUNIFORM3FPROC) glUniform3f( Int_val(location), Double_val(v0), Double_val(v1), Double_val(v2)); return Val_unit; } CAMLprim value ml_gluniform4f( value location, value v0, value v1, value v2, value v3) { LOAD_FUNC(glUniform4f, PFNGLUNIFORM4FPROC) glUniform4f( Int_val(location), Double_val(v0), Double_val(v1), Double_val(v2), Double_val(v3)); return Val_unit; } CAMLprim value ml_gluniform1i( value location, value v0) { LOAD_FUNC(glUniform1i, PFNGLUNIFORM1IPROC) glUniform1i( Int_val(location), Int_val(v0)); return Val_unit; } CAMLprim value ml_gluniform2i( value location, value v0, value v1) { LOAD_FUNC(glUniform2i, PFNGLUNIFORM2IPROC) glUniform2i( Int_val(location), Int_val(v0), Int_val(v1)); return Val_unit; } CAMLprim value ml_gluniform3i( value location, value v0, value v1, value v2) { LOAD_FUNC(glUniform3i, PFNGLUNIFORM3IPROC) glUniform3i( Int_val(location), Int_val(v0), Int_val(v1), Int_val(v2)); return Val_unit; } CAMLprim value ml_gluniform4i( value location, value v0, value v1, value v2, value v3) { LOAD_FUNC(glUniform4i, PFNGLUNIFORM4IPROC) glUniform4i( Int_val(location), Int_val(v0), Int_val(v1), Int_val(v2), Int_val(v3)); return Val_unit; } #else CAMLprim value ml_gluniform1f( value location, value v0) { caml_failwith("glUniform1f function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform2f( value location, value v0, value v1) { caml_failwith("glUniform2f function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform3f( value location, value v0, value v1, value v2) { caml_failwith("glUniform3f function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform4f( value location, value v0, value v1, value v2, value v3) { caml_failwith("glUniform4f function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform1i( value location, value v0) { caml_failwith("glUniform1i function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform2i( value location, value v0, value v1) { caml_failwith("glUniform2i function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform3i( value location, value v0, value v1, value v2) { caml_failwith("glUniform3i function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } CAMLprim value ml_gluniform4i( value location, value v0, value v1, value v2, value v3) { caml_failwith("glUniform4i function is available only if the OpenGL version is 2.0 or greater"); return Val_unit; } #endif #ifdef GL_VERSION_2_0 CAMLprim value ml_gluniform1fv( value location, value vars ) { int i, len = Wosize_val(vars) / Double_wosize; GLfloat val[len]; for (i=0; i 0) { LOAD_FUNC(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC) value infoLog = caml_alloc_string(infologLength); glGetShaderInfoLog(Shader_object_val(shader), infologLength, &charsWritten, Bytes_val(infoLog)); return infoLog; } else { return caml_copy_string(""); } #else caml_failwith("glGetShaderInfoLog is available only if the OpenGL version is 2.0 or greater"); return Val_unit; #endif } CAMLprim value ml_glgetprograminfolog(value program) { #ifdef GL_VERSION_2_0 int infologLength = 0; int charsWritten = 0; LOAD_FUNC(glGetProgramiv, PFNGLGETPROGRAMIVPROC) glGetProgramiv( Shader_program_val(program), GL_INFO_LOG_LENGTH, &infologLength); if (infologLength > 0) { LOAD_FUNC(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC) value infoLog = caml_alloc_string(infologLength); glGetProgramInfoLog(Shader_program_val(program), infologLength, &charsWritten, Bytes_val(infoLog)); return infoLog; } else { return caml_copy_string(""); } #else caml_failwith("glGetProgramInfoLog is available only if the OpenGL version is 2.0 or greater"); return Val_unit; #endif } lablgl-1.07/src/raw.ml000066400000000000000000000061531437514534100146240ustar00rootroot00000000000000(* $Id: raw.ml,v 1.9 2007-04-13 02:48:43 garrigue Exp $ *) type addr type kind = [`bitmap|`byte|`double|`float|`int|`long|`short |`ubyte|`uint|`ulong|`ushort] type fkind = [`double|`float] type ikind = [`bitmap|`byte|`int|`long|`short|`ubyte|`uint|`ulong|`ushort] type lkind = [`int|`long|`uint|`ulong] type 'a t = { kind: 'a; base: addr; offset: int; size: int; static: bool} let kind raw = raw.kind let byte_size raw = raw.size let static raw = raw.static let cast raw ~kind = { kind = kind; size = raw.size; base = raw.base; offset = raw.offset; static = raw.static } external sizeof : [< kind] -> int = "ml_raw_sizeof" let length raw = raw.size / sizeof raw.kind let sub raw ~pos ~len = let size = sizeof raw.kind in if pos < 0 || (pos+len) * size > raw.size then invalid_arg "Raw.sub"; { raw with offset = raw.offset + pos * size; size = len * size } external get : [< ikind] t -> pos:int -> int = "ml_raw_get" external set : [< ikind] t -> pos:int -> int -> unit = "ml_raw_set" external get_float : [< fkind] t -> pos:int -> float = "ml_raw_get_float" external set_float : [< fkind] t -> pos:int -> float -> unit = "ml_raw_set_float" external get_hi : [< lkind] t -> pos:int -> int = "ml_raw_get_hi" external set_hi : [< lkind] t -> pos:int -> int -> unit = "ml_raw_set_hi" external get_lo : [< lkind] t -> pos:int -> int = "ml_raw_get_lo" external set_lo : [< lkind] t -> pos:int -> int -> unit = "ml_raw_set_lo" external get_long : [< lkind] t -> pos:int -> nativeint = "ml_raw_get_long" external set_long : [< lkind] t -> pos:int -> nativeint -> unit = "ml_raw_set_long" external gets : [< ikind] t -> pos:int -> len:int -> int array = "ml_raw_read" external gets_string : 'a t -> pos:int -> len:int -> string = "ml_raw_read_string" external gets_float : [< fkind] t -> pos:int -> len:int -> float array = "ml_raw_read_float" external sets : [< ikind] t -> pos:int -> int array -> unit = "ml_raw_write" external sets_string : 'a t -> pos:int -> string -> unit = "ml_raw_write_string" external sets_float : [< fkind] t -> pos:int -> float array -> unit = "ml_raw_write_float" (* external fill : [< ikind] t -> pos:int -> len:int -> unit = "ml_raw_fill" external fill_float : [< fkind] t -> pos:int -> len:int -> unit = "ml_raw_fill_float" *) external create : ([< kind] as 'a) -> len:int -> 'a t = "ml_raw_alloc" external create_static : ([< kind] as 'a) -> len:int -> 'a t = "ml_raw_alloc_static" external free_static : 'a t -> unit = "ml_raw_free_static" let of_array arr ~kind = let raw = create kind ~len:(Array.length arr) in sets raw ~pos:0 arr; raw let of_float_array arr ~kind = let raw = create kind ~len:(Array.length arr) in sets_float raw ~pos:0 arr; raw let of_string s ~kind = let raw = create kind ~len:(String.length s) in sets_string raw ~pos:0 s; raw let of_matrix mat ~kind = let h = Array.length mat in if h = 0 then invalid_arg "Raw.of_matrix"; let w = Array.length mat.(0) in let raw = create kind ~len:(h*w) in for i = 0 to h - 1 do if Array.length mat.(i) <> w then invalid_arg "Raw.of_matrix"; sets_float raw ~pos:(i*w) mat.(i) done; raw lablgl-1.07/src/raw.mli000066400000000000000000000072041437514534100147730ustar00rootroot00000000000000(* $Id: raw.mli,v 1.10 2007-04-13 02:48:43 garrigue Exp $ *) (* This module provides a direct way to access C arrays of basic types. This is particularly useful when one wants to avoid costly conversions between ML and C representations. *) type (+'a) t type kind = [`bitmap|`byte|`double|`float|`int|`long|`short |`ubyte|`uint|`ulong|`ushort] (* Supported element types. [bitmap] is equivalent to [ubyte] but allows user modules to distinguish between them *) type fkind = [`double|`float] type ikind = [`bitmap|`byte|`int|`long|`short|`ubyte|`uint|`ulong|`ushort] type lkind = [`int|`long|`uint|`ulong] val create : ([< kind] as 'a) -> len:int -> 'a t (* [create t :len] returns a new raw array of C type t and length len. This array is managed by the GC *) val create_static : ([< kind] as 'a) -> len:int -> 'a t (* [create_static t :len] returns a new raw array of C type t and length len. This array is created through malloc. You must free it explicitely *) val free_static : 'a t -> unit (* Free a raw array created through create_static *) val kind : 'a t -> 'a (* Returns the type of a free array. Beware of the influence on the type system: you probably want to write [(kind raw :> kind)] *) val byte_size : 'a t -> int (* The size of the array in bytes. That is (sizeof t * len) where t and len are the parameters to create *) val static : 'a t -> bool (* Wether this array was statically allocated or not *) val cast : 'a t -> kind:([< kind] as 'b) -> 'b t (* Change the type of a raw array *) external sizeof : [< kind] -> int = "ml_raw_sizeof" (* [sizeof t] returns the physical size of t in bytes *) val length : [< kind] t -> int (* [length raw] returns the length of raw array according to its contents type *) val sub : ([< kind] t as 'a) -> pos:int -> len:int -> 'a (* returns the slice of length len starting at position pos *) (* The following functions access raw arrays in the intuitive way. They raise [Invalid_argument] when access is attempted out of bounds *) external get : [< ikind] t -> pos:int -> int = "ml_raw_get" external set : [< ikind] t -> pos:int -> int -> unit = "ml_raw_set" external get_float : [< fkind] t -> pos:int -> float = "ml_raw_get_float" external set_float : [< fkind] t -> pos:int -> float -> unit = "ml_raw_set_float" external get_hi : [< lkind] t -> pos:int -> int = "ml_raw_get_hi" external set_hi : [< lkind] t -> pos:int -> int -> unit = "ml_raw_set_hi" external get_lo : [< lkind] t -> pos:int -> int = "ml_raw_get_lo" external set_lo : [< lkind] t -> pos:int -> int -> unit = "ml_raw_set_lo" external get_long : [< lkind] t -> pos:int -> nativeint = "ml_raw_get_long" external set_long : [< lkind] t -> pos:int -> nativeint -> unit = "ml_raw_set_long" (* Simultaneous access versions are much more efficient than individual access, the overhead being paid only once *) val gets : [< ikind] t -> pos:int -> len:int -> int array val sets : [< ikind] t -> pos:int -> int array -> unit val gets_float : [< fkind] t -> pos:int -> len:int -> float array val sets_float : [< fkind] t -> pos:int -> float array -> unit (* Fastest version: simply copy the contents of the array to and from a string *) val gets_string : 'a t -> pos:int -> len:int -> string val sets_string : 'a t -> pos:int -> string -> unit (* Abbreviations to create raw arrays from ML arrays and strings *) val of_array : int array -> kind:([< ikind] as 'a) -> 'a t val of_float_array : float array -> kind:([< fkind] as 'a) -> 'a t val of_string : string -> kind:([< kind] as 'a) -> 'a t val of_matrix : float array array -> kind:([< fkind] as 'a) -> 'a t lablgl-1.07/src/raw_tags.var000066400000000000000000000001021437514534100160060ustar00rootroot00000000000000$$ bitmap byte ubyte short ushort int uint long ulong float doublelablgl-1.07/src/var2def.ml000066400000000000000000000027201437514534100153600ustar00rootroot00000000000000open StdLabels (* Compile a list of variant tags into CPP defines *) (* hash_variant, from ctype.ml *) let hash_variant s = let accu = ref 0 in for i = 0 to String.length s - 1 do accu := 223 * !accu + Char.code s.[i] done; (* reduce to 31 bits *) accu := !accu land (1 lsl 31 - 1); (* make it signed for 64 bits architectures *) if !accu > 0x3FFFFFFF then !accu - 1 lsl 31 else !accu open Genlex let lexer = make_lexer ["->"; "$$"] let main () = let s = lexer (Stream.of_channel stdin) in let tags = Hashtbl.create 57 in try while true do let (strm__ : _ Stream.t) = s in match Stream.peek strm__ with Some (Ident tag) -> Stream.junk strm__; print_string "#define MLTAG_"; print_string tag; print_string "\tVal_int("; let hash = hash_variant tag in begin try failwith (String.concat ~sep:" " ["Doublon ~tag:"; tag; "and"; Hashtbl.find tags hash]) with Not_found -> Hashtbl.add tags hash tag end; print_int hash; print_string ")\n" | Some (Kwd "->") -> Stream.junk strm__; begin match Stream.peek strm__ with Some (Ident _) -> Stream.junk strm__; () | _ -> raise (Stream.Error "") end | Some (Kwd "$$") -> Stream.junk strm__; () | _ -> raise End_of_file done with End_of_file -> () let _ = Printexc.print main () lablgl-1.07/src/var2def.ml4000066400000000000000000000021071437514534100154430ustar00rootroot00000000000000open StdLabels (* Compile a list of variant tags into CPP defines *) (* hash_variant, from ctype.ml *) let hash_variant s = let accu = ref 0 in for i = 0 to String.length s - 1 do accu := 223 * !accu + Char.code s.[i] done; (* reduce to 31 bits *) accu := !accu land (1 lsl 31 - 1); (* make it signed for 64 bits architectures *) if !accu > 0x3FFFFFFF then !accu - (1 lsl 31) else !accu open Genlex let lexer = make_lexer ["->"; "$$"] let main () = let s = lexer (Stream.of_channel stdin) in let tags = Hashtbl.create 57 in try while true do match s with parser [< ' Ident tag >] -> print_string "#define MLTAG_"; print_string tag; print_string "\tVal_int("; let hash = hash_variant tag in begin try failwith (String.concat ~sep:" " ["Doublon ~tag:";tag;"and";Hashtbl.find tags hash]) with Not_found -> Hashtbl.add tags hash tag end; print_int hash; print_string ")\n" | [< ' Kwd "->"; ' Ident _ >] -> () | [< ' Kwd "$$" >] -> () | [< >] -> raise End_of_file done with End_of_file -> () let _ = Printexc.print main () lablgl-1.07/src/var2switch.ml000066400000000000000000000026031437514534100161230ustar00rootroot00000000000000(* Build a switch statement translating variants to C tags *) open Genlex let lexer = make_lexer ["->"; "$$"] let main () = let table = ref false and prefix = ref "" and tag_number = ref 0 in Arg.parse ["-table", Arg.Set table, " Produce table output"] (fun s -> prefix := s) ""; let s = lexer (Stream.of_channel stdin) in try while true do let (strm__ : _ Stream.t) = s in match Stream.peek strm__ with Some (Ident tag) -> Stream.junk strm__; incr tag_number; print_string (if !table then " {MLTAG_" else " case MLTAG_"); print_string tag; print_string (if !table then ", " else ":\treturn "); let name = let (strm__ : _ Stream.t) = s in match Stream.peek strm__ with Some (Kwd "->") -> Stream.junk strm__; begin match Stream.peek strm__ with Some (Ident name) -> Stream.junk strm__; name | _ -> raise (Stream.Error "") end | _ -> !prefix ^ String.uppercase_ascii tag in print_string name; print_string (if !table then "},\n" else ";\n") | Some (Kwd "$$") -> Stream.junk strm__; raise End_of_file | _ -> raise End_of_file done with End_of_file -> Printf.printf "#define TAG_NUMBER %d\n" !tag_number let _ = Printexc.print main () lablgl-1.07/src/var2switch.ml4000066400000000000000000000017131437514534100162100ustar00rootroot00000000000000(* Build a switch statement translating variants to C tags *) open Genlex let lexer = make_lexer ["->"; "$$"] let main () = let table = ref false and prefix = ref "" and tag_number = ref 0 in Arg.parse ["-table", Arg.Set table, " Produce table output"] (fun s -> prefix := s) ""; let s = lexer (Stream.of_channel stdin) in try while true do match s with parser [< ' Ident tag >] -> incr tag_number; print_string (if !table then " {MLTAG_" else " case MLTAG_"); print_string tag; print_string (if !table then ", " else ":\treturn "); let name = match s with parser [< ' Kwd "->" ; ' Ident name >] -> name | [< >] -> !prefix ^ String.uppercase_ascii tag in print_string name; print_string (if !table then "},\n" else ";\n") | [< ' Kwd "$$" >] -> raise End_of_file | [< >] -> raise End_of_file done with End_of_file -> Printf.printf "#define TAG_NUMBER %d\n" !tag_number let _ = Printexc.print main ()