(************************************************************************************) (* * To prepare an Ocaml graphics window for use with OpenGL the following hack is used. * The method is similar, but not identical, on both Windows and X11. * After opening the window with Graphics.open_graph (), the function init_opengl () * has to be called. This function gives the window a (hopefully) unique name. Then * some C code is called which searches through all available windows for a window * with that particular name, gets pointers to its internal structure (both Win32 and * Xlib allow this) and sets it up for use as an OpenGL surface. * * Compiling: * You need the file win_stub.c and the ML code contained in this section, specifically * the function init_opengl () and the external functions init_gl'(), find_window() and swap_buffers (). * Link the resultant executable with libGL.a on X11, opengl32.lib and gdi32.lib on Windows * * Usage: * First set up your caml window with Graphics.open_graph () * Next, call the function init_gl () defined here below. * After this you can (re)set the window title (if you set it previously it will be empty) * Feel free to call any OpenGL calls you wish. lablgl, glcaml and camlgl may all be used. * You may mix the Ocaml graphics functions with OpenGL. * Call swap_buffers () any time you need to flip the contents of your back buffer to the screen. *) external find_window : string -> int = "stub_find_window""stub_find_window" external init_gl' : string -> unit = "stub_init_gl" "stub_init_gl" external swap_buffers : unit -> unit = "stub_swap_buffers" "stub_swap_buffers" let init_opengl () = let _ = Random.self_init () in let title = Printf.sprintf "%d.%d" (Random.int 1000000) (Random.int 1000000) in Graphics.set_window_title title; init_gl' title; Graphics.set_window_title "";; (************************************************************************************) (* --------------------------------------------------------------------------------- *) open Glcaml (* Replacement for GluPerspective() *) let perspective fov aspect zNear zFar = let pi = 4.0 *. (atan 1.0) in let fH = (tan (fov /. 360.0 *. pi )) *. zNear in let fW = fH *. aspect in glFrustum (-.fW) fW (-.fH) fH zNear zFar;; (* A general OpenGL initialization function. Sets all of the initial parameters. *) let init_gl width height = glViewport 0 0 width height; glClearColor 0.0 0.0 0.0 0.0; glClearDepth 1.0; glDepthFunc GL_LESS; glEnable GL_DEPTH_TEST; glShadeModel GL_SMOOTH; glMatrixMode GL_PROJECTION; glLoadIdentity (); let aspect = (float_of_int width) /. (float_of_int height) in perspective 45.0 aspect 1.0 100.0; glMatrixMode GL_MODELVIEW ;; (* The main drawing function. *) let draw_gl_scene () = glClear [GL_COLOR_BUFFER_BIT; GL_DEPTH_BUFFER_BIT]; glLoadIdentity (); glTranslatef (-.1.5) 0.0 (-.6.0); (* draw a triangle *) glBegin GL_TRIANGLES; glColor3f 1.0 0.0 0.0; glVertex3f 0.0 1.0 0.0; glColor3f 0.0 1.0 0.0; glVertex3f 1.0 (-.1.0) 0.0; glColor3f 0.0 0.0 1.0; glVertex3f (-.1.0) (-.1.0) 0.0; glEnd (); glTranslatef 3.0 0.0 0.0; (* Move Right 3 Units *) (* draw a square (quadrilateral) *) glColor3f 0.5 0.5 1.0; glBegin GL_QUADS; glVertex3f (-.1.0) 1.0 0.0; glVertex3f 1.0 1.0 0.0; glVertex3f 1.0 (-.1.0) 0.0; glVertex3f (-.1.0)(-.1.0) 0.0; glEnd () ;; (************ main ***********) let width = 640 let height =480 let topx = 50 let topy = 50 let init_graphics () = let init_string = (Printf.sprintf " %dx%d" width height) in Graphics.open_graph init_string; init_opengl (); init_gl width height; Graphics.set_window_title "Test OpenGL with native Ocaml graphics" ;; let show_img img = Graphics.draw_image (Graphics.make_image img) 0 0;; let _ = init_graphics ();; let main () = draw_gl_scene (); swap_buffers (); Graphics.set_color Graphics.white; Graphics.moveto 50 50; Graphics.draw_string "Hello OpenGL world, from Ocaml Graphics"; (* Mix in Ocaml Graphics primitives *) let _ = Graphics.read_key () in ();; main ()