File: graphics_demo.ml

package info (click to toggle)
ocaml-cairo2 0.6.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 716 kB
  • sloc: ml: 2,955; ansic: 2,132; makefile: 24; sh: 17
file content (70 lines) | stat: -rw-r--r-- 2,119 bytes parent folder | download | duplicates (3)
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
(* Demo to show how one could achieve cairo drawing on a Graphics
   window. Note that using XLib or GTK would be *much* faster. *)

open Printf
open Bigarray
open Cairo

let pi2 = 8. *. atan 1.

let lastfps = ref (Unix.gettimeofday ())
let frames = ref 0
let fps = ref 0.

let update_fps () =
  let t = Unix.gettimeofday () in
  let dt = t -. !lastfps in
  if dt > 0.5 then (
    fps := float !frames /. dt;
    frames := 0;
    lastfps := t
  );
  incr frames

let draw cr width height x y =
  let x = x -. width *. 0.5 and y = y -. height *. 0.5 in
  let r = 0.5 *. sqrt (x *. x +. y *. y) in
  set_source_rgba cr 0. 1. 0. 0.5;
  arc cr (0.5 *. width) (0.35 *. height) r 0. pi2;
  fill cr;
  set_source_rgba cr 1. 0. 0. 0.5;
  arc cr (0.35 *. width) (0.65 *. height) r 0. pi2;
  fill cr;
  set_source_rgba cr 0. 0. 1. 0.5;
  arc cr (0.65 *. width) (0.65 *. height) r 0. pi2;
  fill cr;
  set_source_rgba cr 1. 1. 0. 1.;
  move_to cr (0.05 *. width) (0.95 *. height);
  show_text cr (sprintf "%gx%g -- %.0f fps" width height !fps)

let expose () =
  let sx = Graphics.size_x ()
  and sy = Graphics.size_y ()
  and mx, my = Graphics.mouse_pos () in
  (* Create a cairo context from a cairo surface and do our drawings
     on it. Note: we may cache it between expose events for
     incremental drawings but its creation and initialization is not
     the time bottleneck here. *)
  let cr_img = Image.create Image.RGB24 sx sy in
  let cr = create cr_img in
  draw cr (float sx) (float sy) (float mx) (float my);
  (* Don't forget to flush the surface before using its content. *)
  Surface.flush cr_img;
  (* Now, access the surface data and convert it to a Graphics.image
     that can be drawn on the Graphics window. *)
  let data32 = Image.get_data32 cr_img in
  let data_img =
    Array.init sy
      (fun y -> Array.init sx (fun x -> Int32.to_int (data32.{y, x})))
  in
  Graphics.draw_image (Graphics.make_image data_img) 0 0;
  Graphics.synchronize ();
  (* Update our fps counter. *)
  update_fps ()

let () =
  Graphics.open_graph "";
  Graphics.auto_synchronize false;
  while true do
    expose ()
  done