File: planet.ml

package info (click to toggle)
lablgl 1%3A1.05-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,444 kB
  • ctags: 2,438
  • sloc: ansic: 8,270; ml: 6,118; tcl: 342; makefile: 294; xml: 84; perl: 12
file content (120 lines) | stat: -rw-r--r-- 3,675 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
(* $Id: planet.ml,v 1.17 2001-09-07 06:50:01 garrigue Exp $ *)

open Unix

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 ()