X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FDEVEL%2Flablgtk%2Flablgtk_20001129-0.1.0%2Fexamples%2FGL%2Fmorph3d.ml;fp=helm%2FDEVEL%2Flablgtk%2Flablgtk_20001129-0.1.0%2Fexamples%2FGL%2Fmorph3d.ml;h=0000000000000000000000000000000000000000;hb=c7514aaa249a96c5fdd39b1123fbdb38d92f20b6;hp=a08726e05794ad4edc1fe6f87fd3fea86f0db219;hpb=1c7fb836e2af4f2f3d18afd0396701f2094265ff;p=helm.git diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml deleted file mode 100644 index a08726e05..000000000 --- a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml +++ /dev/null @@ -1,607 +0,0 @@ -(* $Id$ *) - -(*- - * 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 area = object (self) - val area : GlGtk.area = area - val mutable smooth = true - val mutable step = 0. - val mutable obj = 1 - val mutable draw_object = fun ~amp -> () - val mutable magnitude = 0. - - method width = area#misc#allocation.Gtk.width - method height = area#misc#allocation.Gtk.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(); - area#swap_buffers (); - step <- step +. 0.05 - - method reshape ~width ~height = - GlDraw.viewport ~x:0 ~y:0 ~w:width ~h: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 - | "\r" -> smooth <- not smooth - | "\027" -> area#misc#toplevel#destroy (); 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) - initializer - area#connect#display ~callback:self#draw; - area#connect#reshape ~callback:self#reshape; - () -end - -open GMain - -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 window = - GWindow.window ~title:"Morph 3D - Shows morphing platonic polyhedra" () - in - window#connect#destroy ~callback:Main.quit; - window#set_resize_mode `IMMEDIATE; - - let area = GlGtk.area [`DEPTH_SIZE 1;`RGBA;`DOUBLEBUFFER] - ~width:640 ~height:480 ~packing:window#add () in - - let view = new view area in - - area#connect#realize ~callback: - begin fun () -> - view#pinit; - 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(); - - 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 - end; - - window#event#connect#key_press - ~callback:(fun ev -> view#key (GdkEvent.Key.string ev); true); - - Timeout.add ~ms:20 - ~callback:(fun _ -> if area#misc#visible then view#draw (); true); - window#show (); - Main.main () - -let _ = main ()