SML3d
3d graphics for Standard ML

Introduction

The GLFW Library is a C Library for managing windows and input devices in an OpenGL applications in an operating system independent way.

Basic concepts

Callbacks

GLFW uses per-window callback functions for most input handling (joysticks are the one exception to this policy).

A simple example

The following example is the SML3d version of the simple example in the GLFW manual.

structure Simple =
  struct

    fun errorCallback (_, msg) = (
	  TextIO.output(TextIO.stdErr, msg);
	  OS.Process.exit OS.Process.failure)
    fun keyCallback (win, key, scanCode, act, mode) =
	  if (key = GLFW.Key.KEY_ESCAPE andalso act = GLFW.Kbd.PRESS)
	    then GLFW.Window.setShouldClose(win, true)
	    else ()

    fun render win = let
	  val {w, h} = GLFW.Window.framebufferSize win
	  in
	    (* render code *)
	  end

    fun main () = let
	  val () = GLFW.setErrorAction errorCallback;
	  val () = if not GLFW.init()
		then OS.Process.exit OS.Process.failure
		else ();
	  val win = GLFW.Window.create {
		size = {w = 640, h = 480},
		title = "Simple example",
		share = NONE
	      }
	  val () = GLFW.makeCurrent win
	  val () = GLFW.Kbd.setKeyCallback (win, SOME keyCallback)
	  fun loop () = if GLFW.Window.shouldClose win
		then ()
		else (
		    render win;
		    GLFW.swapBuffers win;
		    GLFW.pollEvents ();
		    loop ())
	  in
	    loop ();
	    GLFW.Window.destroy win;
	    GLFW.terminate();
	    OS.Process.exit OS.Process.success
	  end

    val _ = main ()

  end

We also need to specify a MLB file that will include the SML3d and GLFW library code.

local

  $(SML_LIB)/basis/basis.mlb

  $(SML3D_LIB)/sml3d.mlb
  $(SML3D_LIB)/glfw.mlb

  simple.sml

in

  structure Simple

end

Lastly, we specify a makefile for building the program. The makefile uses the config-sml3d.sh script to configure the command-line options to the MLton compiler.

# path to MLton compiler
#
MLTON =         /usr/local/mlton/bin/mlton

# path to SML3d configuration script
#
CONFIG_SML3D    = /Users/jhr/Work/sml3d/sml3d/bin/config-sml3d.sh

MLTON_FLAGS     += $(shell $(CONFIG_SML3D) glfw)
C_OBJS          += $(shell $(CONFIG_SML3D) objs glfw)

simple: simple.mlb simple.sml
        $(MLTON) $(MLTON_FLAGS) -output simple main.mlb $(C_OBJS)

The GLFW structure

signature GLFW =
  sig

  (*** common types ***)
    type int = CInt.int
    type word = CUInt.word
    type float = Float.t
    type double = Double.t
    type size2i = {w : int, h : int}
    type pos2i = {x : int, y : int}
    type pos2d = {x : double, y : double}

  (*** GLFW types ***)
    type monitor
    type window

  (*** Errors ***)
    structure Error : sig
      (* GLFW error codes *)
	eqtype error_code
	val NOT_INITIALIZED : error_code
	val NO_CURRENT_CONTEXT : error_code
	val INVALID_ENUM : error_code
	val INVALID_VALUE : error_code
	val OUT_OF_MEMORY : error_code
	val API_UNAVAILABLE : error_code
	val VERSION_UNAVAILABLE : error_code
	val PLATFORM_ERROR : error_code
	val FORMAT_UNAVAILABLE : error_code

      (* the GLFW_ERROR exception is raised by the default error action *)
	exception GLFW_ERROR of (error_code * string)

      (* override the default error action *)
	val setErrorAction : ((error_code * string) -> unit) -> unit

      end

  (*** Monitors ***)
    structure Monitor : sig
      (* equality operation on monitors *)
	val same : monitor * monitor -> bool
      (* return the primary monitor [glfwGetPrimaryMonitor] *)
	val primary : unit -> monitor
      (* return a list of the available monitors [glfwGetMonitors] *)
	val monitors : unit -> monitor list
      (* return the name of the monitor [glfwGetMonitorName] *)
	val name : monitor -> string
      (* return the size of the monitor in millimeters [glfwGetMonitorPhysicalSize] *)
	val physicalSize : monitor -> {width : int, height : int}
      (* return the position of the monitor's viewport on the virtual screen [glfwGetMonitorPos] *)
	val position : monitor -> pos2i

      (* monitor status events *)
	datatype config_event = CONNECTED | DISCONNECTED

      (* register a callback function to track changes in the active monitors. [glfwSetMonitorCallback] *)
	val setMonitorCallback : ((monitor * config_event) -> unit) option -> unit

      (* video modes *)
	type video_mode = {
	    size : size2i,
	    redBits : int,
	    greenBits : int,
	    blueBits : int,
	    refreshRate : int
	  }

      (* return a list of the video modes supported by the monitor.  The list
       * is sorted in ascending order, first by color bit depth (the sum of all
       * channel depths) and then by resolution area (the product of width and height).
       *)
	val videoModes : monitor -> video_mode list
      (* return the current video mode of the monitor; NONE is returned on error *)
	val videoMode : monitor -> video_mode option

      (* Gamma ramp; each channel is described by its own vector of values.  All vectors must
       * have the same length (256 is standard, other sizes may not be supported).
       *)
	type gamma_ramp = {
	    red : Word16.word vector,	(* values describing the response of the red channel *)
	    green : Word16.word vector, (* values describing the response of the green channel *)
	    blue : Word16.word vector	(* values describing the response of the blue channel *)
	  }

	exception InvalidRamp	(* raised by setGammaRamp when the ramp is not well formed *)

      (* get/set/reset the gamma ramp for a given monitor *)
	val gammaRamp : monitor -> gamma_ramp option
	val setGammaRamp : monitor * gamma_ramp -> unit
	val resetGammaRamp : monitor -> unit

      end

  (*** Windows ***)
    structure Window : sig

      (* equality operation on windows *)
	val same : window * window -> bool

      (* buffer access robustness as described in
       *    http://www.opengl.org/registry/specs/ARB/robustness.txt
       *)
	eqtype robustness
	val NO_ROBUSTNESS : robustness
	val NO_RESET_NOTIFICATION : robustness
	val LOSE_CONTEXT_ON_RESET : robustness

      (* hints for window creation; these are set before creating a window.  There are
       * two hints that we do not support:
       *    GLFW_CLIENT_API	-- we only support OpenGL at this time (not OpenGL ES).
       *    GLFW_OPENGL_PROFILE	-- we are only supporting the Core Profile in SML3d, so
       *			   we set this hint to GLFW_OPENGL_CORE_PROFILE.
       *)
	structure Hint : sig
	  (* reset hints to default values *)
	    val reset : unit -> unit
	  (* can the user resize the window? (default: true) *)
	    val resizable : bool -> unit
	  (* is the window initially visible? (default: true) *)
	    val visible : bool -> unit
	  (* does the window have decorations such as a border, etc? (default: true) *)
	    val decorated : bool -> unit
	  (* desired number of bits/channel (default: 8) *)
	    val redBits : int -> unit
	    val greenBits : int -> unit
	    val blueBits : int -> unit
	    val alphaBits : int -> unit
	    val depthBits : int -> unit
	    val stencilBits : int -> unit
	  (* desired number of bits/channel for the accumulator buffer (default: 0) *)
	    val accumRedBits : int -> unit
	    val accumGreenBits : int -> unit
	    val accumBlueBits : int -> unit
	    val accumAlphaBits : int -> unit
	  (* desired number of auxiliary buffers (default: 0) *)
	    val auxBuffers : int -> unit
	  (* desired number of multisamples per pixel (default: 0) *)
	    val samples : int -> unit
	  (* desired refresh rate for full screen windows; 0 means highest available (default: 0) *)
	    val refreshRate : int -> unit
	  (* stereoscopic rendering support (default: false) *)
	    val stereo : bool -> unit
	  (* sRGB color space support (default: false) *)
	    val srgbCapable : bool -> unit
	    (* val client_api : int -> unit *)
	  (* desired context API version; e.g., OpenGL 3.2 (default: 1.0.0) *)
	    val contextVersionMajor : int -> unit
	    val contextVersionMinor : int -> unit
	    val contexRevision : int -> unit
	  (* desired robustness of the window's rendering context (default: NO_ROBUSTNESS) *)
	    val contextRobustness : robustness -> unit
	  (* is an OpenGL forward-compatible context is desired? (default: false) *)
	    val openglForwardCompat : bool -> unit
	  (* is an OpenGL debug context is desired? (default: false) *)
	    val openglDebugContext : bool -> unit
	    (* val openglProfile : gl_profile -> unit *)
	  end

      (* window creation [glfwCreateWindow] *)
        val window : {
		sz : size2i,		(* desired window size *)
		title : string,		(* window title (UTF8) *)
		share : window option	(* optional widow to share context with *)
	      } -> window option
      (* fullscreen window creation [glfwCreateWindow] *)
        val fullscreen : {
		sz : size2i,		(* desired window size *)
		title : string,		(* window title (UTF8) *)
		monitor : monitor,	(* monitor to use as the screen *)
		share : window option	(* optional widow to share context with *)
	      } -> window option
      (* destroy a window [glfwDestroyWindow] *)
	val destroy : window -> unit

      (* return the monitor that the specified window is in full screen on; NONE if the
       * window is not full screen or has been destroyed.
       *)
	val monitor : window -> monitor option

      (* signal that the window should close [glfwSetWindowShouldClose] *)
	val setShouldClose : window * bool -> unit
      (* check the value of the window's close flag [glfwWindowShouldClose] *)
	val shouldClose : window -> bool

      (*  iconify/restore the specified window [glfwIconifyWindow, glfwRestoreWindow] *)
	val iconify : window * bool -> unit

      (* hide/reveal the specified window [glfwHideWindow, glfwShowWindow] *)
	val hide : window * bool -> unit

      (* set the window's title [glfwSetWindowTitle] *)
	val setTitle : window * string -> unit

      (* get/set the window's position [glfwGetWindowPos, glfwSetWindowPos] *)
	val position : window -> pos2i
	val setPosition : window * pos2i -> unit

      (* get/set the window's size [glfwGetWindowSize, glfwSetWindowSize] *)
	val size : window -> size2i
	val setSize : window * size2i -> unit

      (* get the size of the window's framebuffer [glfwGetFramebufferSize] *)
	val framebufferSize : window -> size2i

      (* window state callbacks *)
	val setPositionCallback : (window * (window * pos2i -> unit) option) -> unit
	val setSizeCallback : (window * (window * size2i -> unit) option) -> unit
	val setRefreshCallback : (window * (window -> unit) option) -> unit
	val setCloseCallback : (window * (window -> unit) option) -> unit
	val setFocusCallback : (window * (window * bool -> unit) option) -> unit
	val setIconifyCallback : (window * (window * bool -> unit) option) -> unit
	val setFramebufferSizeCallback : (window * (window * size2i -> unit) option) -> unit

      (* functions for querying window attributes (this are set using the hint mechanism) *)
	structure Attrib : sig
	  (* can user resize the window? *)
	    val resizable : window -> bool
	  (* is the window initially visible? *)
	    val visible : window -> bool
	  (* does the window have decorations such as a border, etc? *)
	    val decorated : window -> bool
	  (* the number of bits/channel *)
	    val redBits : window -> int
	    val greenBits : window -> int
	    val blueBits : window -> int
	    val alphaBits : window -> int
	    val depthBits : window -> int
	    val stencilBits : window -> int
	  (* the number of bits/channel for the accumulator buffer *)
	    val accumRedBits : window -> int
	    val accumGreenBits : window -> int
	    val accumBlueBits : window -> int
	    val accumAlphaBits : window -> int
	  (* the number of auxiliary buffers *)
	    val auxBuffers : window -> int
	  (* the number of multisamples per pixel *)
	    val samples : window -> int
	  (* refresh rate for full screen windows *)
	    val refreshRate : window -> int
	  (* is stereoscopic rendering supported? *)
	    val stereo : window -> bool
	  (* sRGB color space support *)
	    val srgbCapable : window -> bool
	    (* val client_api : window -> int *)
	  (* desired context API version; e.g., OpenGL 3.2 *)
	    val contextVersionMajor : window -> int
	    val contextVersionMinor : window -> int
	    val contexRevision : window -> int
	  (* desired robustness of the window's rendering context *)
	    val contextRobustness : window -> robustness
	  (* is an OpenGL forward-compatible context is desired? *)
	    val openglForwardCompat : window -> bool
	  (* is an OpenGL debug context is desired? *)
	    val openglDebugContext : window -> bool
	    (* val openglProfile : window -> gl_profile *)
	  end

      end (* Window *)

  (*** Physical key definitions based on standard 105 key keyboard.  The values are named
   * according to the values they would have using the standard US layout, but this is only a
   * convenience, as most programmers are assumed to know that layout. This means that (for
   * example) LEFT_BRACKET is always a single key and is the same key in the same place
   * regardless of what keyboard layouts the users of your program has.
   ****)
    structure Key : sig
	eqtype key

      (* map a key to its integer ID.  For the keys that correspond to ASCII characters, the
       * ID is the ASCII code (letters are uppercase).
       *)
	val id : key -> int

      (* Printable keys *)
	val KEY_SPACE : key
	val KEY_APOSTROPHE : key  (* ' *)
	val KEY_COMMA : key  (* , *)
	val KEY_MINUS : key  (* - *)
	val KEY_PERIOD : key  (* . *)
	val KEY_SLASH : key  (* / *)
	val KEY_0 : key  (* 0 *)
	val KEY_1 : key
	val KEY_2 : key
	val KEY_3 : key
	val KEY_4 : key
	val KEY_5 : key
	val KEY_6 : key
	val KEY_7 : key
	val KEY_8 : key
	val KEY_9 : key
	val KEY_SEMICOLON : key  (* ; *)
	val KEY_EQUAL : key  (* = *)
	val KEY_A : key
	val KEY_B : key
	val KEY_C : key
	val KEY_D : key
	val KEY_E : key
	val KEY_F : key
	val KEY_G : key
	val KEY_H : key
	val KEY_I : key
	val KEY_J : key
	val KEY_K : key
	val KEY_L : key
	val KEY_M : key
	val KEY_N : key
	val KEY_O : key
	val KEY_P : key
	val KEY_Q : key
	val KEY_R : key
	val KEY_S : key
	val KEY_T : key
	val KEY_U : key
	val KEY_V : key
	val KEY_W : key
	val KEY_X : key
	val KEY_Y : key
	val KEY_Z : key
	val KEY_LEFT_BRACKET : key  (* [ *)
	val KEY_BACKSLASH : key  (* \ *)
	val KEY_RIGHT_BRACKET : key  (* ] *)
	val KEY_GRAVE_ACCENT : key  (* ` *)
	val KEY_WORLD_1 : key (* non-US #1 *)
	val KEY_WORLD_2 : key (* non-US #2 *)

      (* Function keys *)
	val KEY_ESCAPE : key
	val KEY_ENTER : key
	val KEY_TAB : key
	val KEY_BACKSPACE : key
	val KEY_INSERT : key
	val KEY_DELETE : key
	val KEY_RIGHT : key
	val KEY_LEFT : key
	val KEY_DOWN : key
	val KEY_UP : key
	val KEY_PAGE_UP : key
	val KEY_PAGE_DOWN : key
	val KEY_HOME : key
	val KEY_END : key
	val KEY_CAPS_LOCK : key
	val KEY_SCROLL_LOCK : key
	val KEY_NUM_LOCK : key
	val KEY_PRINT_SCREEN : key
	val KEY_PAUSE : key
	val KEY_F1 : key
	val KEY_F2 : key
	val KEY_F3 : key
	val KEY_F4 : key
	val KEY_F5 : key
	val KEY_F6 : key
	val KEY_F7 : key
	val KEY_F8 : key
	val KEY_F9 : key
	val KEY_F10 : key
	val KEY_F11 : key
	val KEY_F12 : key
	val KEY_F13 : key
	val KEY_F14 : key
	val KEY_F15 : key
	val KEY_F16 : key
	val KEY_F17 : key
	val KEY_F18 : key
	val KEY_F19 : key
	val KEY_F20 : key
	val KEY_F21 : key
	val KEY_F22 : key
	val KEY_F23 : key
	val KEY_F24 : key
	val KEY_F25 : key
	val KEY_KP_0 : key
	val KEY_KP_1 : key
	val KEY_KP_2 : key
	val KEY_KP_3 : key
	val KEY_KP_4 : key
	val KEY_KP_5 : key
	val KEY_KP_6 : key
	val KEY_KP_7 : key
	val KEY_KP_8 : key
	val KEY_KP_9 : key
	val KEY_KP_DECIMAL : key
	val KEY_KP_DIVIDE : key
	val KEY_KP_MULTIPLY : key
	val KEY_KP_SUBTRACT : key
	val KEY_KP_ADD : key
	val KEY_KP_ENTER : key
	val KEY_KP_EQUAL : key
	val KEY_LEFT_SHIFT : key
	val KEY_LEFT_CONTROL : key
	val KEY_LEFT_ALT : key
	val KEY_LEFT_SUPER : key
	val KEY_RIGHT_SHIFT : key
	val KEY_RIGHT_CONTROL : key
	val KEY_RIGHT_ALT : key
	val KEY_RIGHT_SUPER : key
	val KEY_MENU : key
	val KEY_UNKNOWN : key	(* represents unknown keys (ID = ~1) *)
	val KEY_FIRST : key	(* Key with lowest ID (not counting UNKNOWN) *)
	val KEY_LAST : key	(* Key with highest ID *)
      end

  (*** Modifier keys ***)
    structure ModKey : sig
	eqtype mod_key
	eqtype mod_keys
	val SHIFT : mod_key
	val CONTROL : mod_key
	val ALT : mod_key
	val SUPER : mod_key
	val modKeys : mod_key list -> mod_keys
	val isSet : mod_key -> mod_keys -> bool
      end

  (*** Keyboard input ***)
    structure Kbd : sig
      (* get the current state of the given key.  If the input mode is sticky, then the function
       * returns true the first this function is called after a key has been pressed, even if the
       * key has already been released. [glfwGetKey]
       *)
	val key : window * Key.key -> bool

      (* Get/set the stickyness of the keyboard keys. [glfwGetInputMode, glfwSetInputMode] *)
	val sticky : window -> bool
	val setSticky : window * bool -> unit

      (* Keyboard callbacks *)
	datatype action = PRESS | RELEASE | REPEAT
	val setKeyCallback : (window * (window * Key.key * int * action * ModKey.mod_keys -> unit) option) -> unit
	val setCharCallback : (window * (window * string -> unit) option) -> unit
      end

  (*** Mouse input ***)
    structure Mouse : sig
	val cursorPos : window -> pos2d
	val setCursorPos : window * pos2d -> unit

      (* [glfwGetInputMode, glfwSetInputMode] *)
	datatype cursor_mode = NORMAL | HIDDEN | DISABLED
	val cursorMode : window -> cursor_mode
	val setCursorMode : window * cursor_mode -> unit

      (* [glfwGetInputMode, glfwSetInputMode] *)
	val stickyButtons : window -> bool
	val setStickyButtons : window * bool -> unit

      (* Mouse cursor and button callbacks *)
	val setCursorEnterCallback : (window * (window * bool -> unit) option) -> unit
	val setCursorPosCallback : (window * (window * pos2d -> unit) option) -> unit
	val setButtonCallback : (window * (window * int * bool * ModKey.mod_keys -> unit) option) -> unit
	val setScrollCallback : (window * (window * {xOffset : double, yOffset : double} -> unit) option) -> unit
      end

  (*** Joysticks ***)
    structure Joystick : sig
	eqtype joystick
      (* "joystick i" returns the i'th joystick (if it exists) or else NONE [glfwJoystickPresent] *)
	val joystick : int -> joystick option
      (* return the ID of the joystick *)
	val id : joystick -> int
      (* return the name of the joystick [glfwGetJoystickName] *)
	val name : joystick -> string
      (* return the current axes values of the joystick [glfwGetJoystickAxes] *)
	val axes : joystick -> float vector
      (* return the current button values of the joystick (true = down, false = up) [glfwGetJoystickButtons] *)
	val buttons : joystick -> bool vector
      end

  (*** Various other functions ***)

  (* initialize the GLFW library; returns false if an error occurred. [glfwInit] *)
    val init : unit -> bool

  (* destroy all remaining windows, free any allocated resources, and reset the GLFW
   * library to an uninitialized state. [glfwTerminate]
   *)
    val terminate : unit -> unit

  (* return the version of the GLFW library being used. [glfwGetVersion] *)
    val version : unit -> {major : int, minor : int, rev : int}

  (* return a version string that was generated at compile-time according to which
   * configuration macros were defined. [glfwGetVersionString]
   *)
    val versionString : unit -> string

  (* get/set the window's context be the current rendering context; NONE means no
    * current context.
    *)
    val current : unit -> window option
    val makeCurrent : window option -> unit

  (* Swap the front and back buffers of the specified window. *)
    val swapBuffers : window -> unit

  (* Set the swap interval for the current context.  The interval is measured in
   * refresh cycles.
   *)
    val swapInterval : int -> unit

  (* process any pending events by calling the appropriate callback functions and then return.
   * Note: do not call this function from a callback! [glfwPollEvents]
   *)
    val pollEvents : unit -> unit

  (* sleep until at least one event has been received.  Then process any pending events
   * by calling the appropriate callback functions and return.
   * Note: do not call this function from a callback! [glfwWaitEvents]
   *)
    val waitEvents : unit -> unit

  (* get the current contents of the clipboard as a UTF8 string (if it is convertable) *)
    val clipboard : window -> string

  (* set the current contents of the clipboard to the specified UTF8 string *)
    val setClipboard : window * string -> unit

  end

Substructures

Most of the GLFW structure is organized into a number of substructures

Types

  • monitor

    an abstract type representing a monitor. GLFW assumes that the monitors of a system are organized into a virtual desktop.

  • window

    an abstract type representing a window.

Values

  • init ()

    initialize the GLFW library; returns false if an error occurred. (see glfwInit).

  • terminate ()

    terminates the GLFW session by destroying all remaining windows, freeing any allocated resources, and reset the GLFW library to an uninitialized state. (see glfwTerminate)

  • version ()

    returns a record {major, minor, rev} that specifies the version of the GLFW library that is being used. (see glfwGetVersion)

  • versionString ()

    returns a version string that was generated at compile-time according to which configuration macros were defined. (see glfwGetVersionString)

  • current ()

    returns the current rendering context (NONE means that there is no current context).

  • makeCurrent NONE

    sets the current rendering context to be no context.

  • makeCurrent (SOME win)

    sets the current rendering context to be the window win.

  • swapBuffers ()

    swaps the front and back buffers of the specified window.

  • swapInterval n

    sets the swap interval for the current context to be n refresh cycles.

  • pollEvents ()

    process any pending events by calling the appropriate callback functions and then return.

    Note: do not call this function from a callback!

  • waitEvents ()

    sleeps until at least one event has been received. Then process any pending events by calling the appropriate callback functions and return.

    Note: do not call this function from a callback!

  • clipboard win

    returns the current contents of the clipboard as a UTF8 string (if it is convertable).

  • setClipboard (win, txt)

    sets the current contents of the clipboard to the UTF8 string txt.

The Monitor structure

structure Monitor : sig

    val same : window * window -> bool

    val primary : unit -> monitor
    val monitors : unit -> monitor list
    val name : monitor -> string
    val physicalSize : monitor -> {width : int, height : int}
    val position : monitor -> pos2i

    type video_mode = {
        size : size2i,
        redBits : int,
        greenBits : int,
        blueBits : int,
        refreshRate : int
      }

    val videoModes : monitor -> video_mode list
    val videoode : monitor -> video_mode

    type gamma_ramp = {
        red : Word16.word vector,
        green : Word16.word vector,
        blue : Word16.word vector
      }

    exception InvalidRamp

    val gammaRamp : monitor -> gamma_ramp option
    val setGammaRamp : monitor * gamma_ramp -> unit
    val resetGammaRamp : monitor -> unit

    datatype config_event = CONNECTED | DISCONNECTED

    val setMonitorCallback : ((monitor * config_event) -> unit) option -> unit

  end

Types

  • video_mode

    specifies properties of a video mode, including the monitor’s screen size in pixels (size), the red channel bit depth (redBits), green channel bit depth (greeBits), blue channel bit depth (blueBits), and refresh rate (refreshRate).

  • gamma_ramp

    specifies a gamma ramp as a record of three vectors (one per channel). All three vectors must have the same length (256 is standard, other sizes may not be supported).

  • config_status

    specifies the change in state of a monitor (either CONNECTED or DISCONNECTED).

Exceptions

  • InvalidRamp

    is raised by setGammaRamp when the an invalid gamma ramp is specified.

Values

  • same (mon1, mon2)

    returns true if mon1 and mon2 are the same, false otherwise.

  • primary ()

    returns the system’s primary monitor.

  • monitors ()

    returns a list of the available monitors.

  • name mon

    returns the name of the monitor mon.

  • physicalSize mon

    returns the size of the monitor in millimeters.

  • position mon

    returns the position of the monitor’s viewport on the virtual screen.

  • videoModes mon

    returns a list of the video modes supported by the monitor. The list is sorted in ascending order, first by color bit depth (the sum of all channel depths) and then by resolution area (the product of width and height).

  • videoode mon

    returns the current video mode of the monitor.

  • gammaRamp mon

    returns the monitor mon's gamma ramp.

  • setGammaRamp (mon, ramp)

    sets the monitor mon's gamma ramp o+ramp+. If ramp is not well formed, then the InvalidRamp exception is raised.

  • resetGammaRamp mon

    restores the monitor mon's ramp to its default value.

  • setMonitorCallback (SOME cb)

    register a callback function cb to track changes in the active monitors. The function cb will be called with the monitor whose connection state has changed and the new status of the monitor (either CONNECTED or DISCONNECTED).

  • setMonitorCallback NONE

    remove any registered callback function that was set by a prior call to setMonitorCallback.

The Window structure

structure Window : sig
    eqtype robustness
    val NO_ROBUSTNESS : robustness
    val NO_RESET_NOTIFICATION : robustness
    val LOSE_CONTEXT_ON_RESET : robustness

    structure Hint : sig ... end
    structure Attrib : sig ... end

    val same : window * window -> bool

    val window : {
            sz : size2i,                (* desired window size *)
            title : string,             (* window title (UTF8) *)
            share : window option       (* optional widow to share context with *)
          } -> window option
    val fullscreen : {
            sz : size2i,                (* desired window size *)
            title : string,             (* window title (UTF8) *)
            monitor : monitor,  (* monitor to use as the screen *)
            share : window option       (* optional widow to share context with *)
          } -> window option
    val destroy : window -> unit

    val monitor : window -> monitor option

    val setShouldClose : window * bool -> unit
    val shouldClose : window -> bool

    val iconify : window * bool -> unit
    val hide : window * bool -> unit
    val setTitle : window * string -> unit

    val position : window -> pos2i
    val setPosition : window * pos2i -> unit

    val size : window -> size2i
    val setSize : window * size2i -> unit

    val framebufferSize : window -> size2i

    val setPositionCallback : (window * (window * pos2i -> unit) option) -> unit
    val setSizeCallback : (window * (window * size2i -> unit) option) -> unit
    val setRefreshCallback : (window * (window -> unit) option) -> unit
    val setCloseCallback : (window * (window -> unit) option) -> unit
    val setFocusCallback : (window * (window * bool -> unit) option) -> unit
    val setIconifyCallback : (window * (window * bool -> unit) option) -> unit
    val setFramebufferSizeCallback : (window * (window * size2i -> unit) option) -> unit

  end (* Window *)

The Window.Hint structure

structure Hint : sig
    val reset : unit -> unit
    val resizable : bool -> unit
    val visible : bool -> unit
    val decorated : bool -> unit
    val redBits : int -> unit
    val greenBits : int -> unit
    val blueBits : int -> unit
    val alphaBits : int -> unit
    val depthBits : int -> unit
    val stencilBits : int -> unit
    val accumRedBits : int -> unit
    val accumGreenBits : int -> unit
    val accumBlueBits : int -> unit
    val accumAlphaBits : int -> unit
    val auxBuffers : int -> unit
    val samples : int -> unit
    val refreshRate : int -> unit
    val stereo : bool -> unit
    val srgbCapable : bool -> unit
    val contextVersionMajor : int -> unit
    val contextVersionMinor : int -> unit
    val contexRevision : int -> unit
    val contextRobustness : robustness -> unit
    val openglForwardCompat : bool -> unit
    val openglDebugContext : bool -> unit
  end

The Window.Attrib structure

The Window.Attrib structure provides functions for querying the various properties of a window.

    structure Attrib : sig
      (* can user resize the window? *)
        val resizable : window -> bool
      (* is the window initially visible? *)
        val visible : window -> bool
      (* does the window have decorations such as a border, etc? *)
        val decorated : window -> bool
      (* the number of bits/channel *)
        val redBits : window -> int
        val greenBits : window -> int
        val blueBits : window -> int
        val alphaBits : window -> int
        val depthBits : window -> int
        val stencilBits : window -> int
      (* the number of bits/channel for the accumulator buffer *)
        val accumRedBits : window -> int
        val accumGreenBits : window -> int
        val accumBlueBits : window -> int
        val accumAlphaBits : window -> int
      (* the number of auxiliary buffers *)
        val auxBuffers : window -> int
      (* the number of multisamples per pixel *)
        val samples : window -> int
      (* refresh rate for full screen windows *)
        val refreshRate : window -> int
      (* is stereoscopic rendering supported? *)
        val stereo : window -> bool
      (* sRGB color space support *)
        val srgbCapable : window -> bool
        (* val client_api : window -> int *)
      (* desired context API version; e.g., OpenGL 3.2 *)
        val contextVersionMajor : window -> int
        val contextVersionMinor : window -> int
        val contexRevision : window -> int
      (* desired robustness of the window's rendering context *)
        val contextRobustness : window -> robustness
      (* is an OpenGL forward-compatible context is desired? *)
        val openglForwardCompat : window -> bool
      (* is an OpenGL debug context is desired? *)
        val openglDebugContext : window -> bool
        (* val openglProfile : window -> gl_profile *)
      end

The Key structure

The Key structure defines physical key definitions based on standard 105 key keyboard. The values are named according to the values they would have using the standard US layout, but this is only a convenience, as most programmers are assumed to know that layout. This convention means that, for example LEFT_BRACKET is always a single key and is the same key in the same place regardless of what keyboard layout the user has.

    structure Key : sig
        eqtype key

        val id : key -> int

        val KEY_SPACE : key
        val KEY_APOSTROPHE : key
        val KEY_COMMA : key
        val KEY_MINUS : key
        val KEY_PERIOD : key
        val KEY_SLASH : key
        val KEY_0 : key
        val KEY_1 : key
        val KEY_2 : key
        val KEY_3 : key
        val KEY_4 : key
        val KEY_5 : key
        val KEY_6 : key
        val KEY_7 : key
        val KEY_8 : key
        val KEY_9 : key
        val KEY_SEMICOLON : key
        val KEY_EQUAL : key
        val KEY_A : key
        val KEY_B : key
        val KEY_C : key
        val KEY_D : key
        val KEY_E : key
        val KEY_F : key
        val KEY_G : key
        val KEY_H : key
        val KEY_I : key
        val KEY_J : key
        val KEY_K : key
        val KEY_L : key
        val KEY_M : key
        val KEY_N : key
        val KEY_O : key
        val KEY_P : key
        val KEY_Q : key
        val KEY_R : key
        val KEY_S : key
        val KEY_T : key
        val KEY_U : key
        val KEY_V : key
        val KEY_W : key
        val KEY_X : key
        val KEY_Y : key
        val KEY_Z : key
        val KEY_LEFT_BRACKET : key
        val KEY_BACKSLASH : key
        val KEY_RIGHT_BRACKET : key
        val KEY_GRAVE_ACCENT : key
        val KEY_WORLD_1 : key
        val KEY_WORLD_2 : key
        val KEY_ESCAPE : key
        val KEY_ENTER : key
        val KEY_TAB : key
        val KEY_BACKSPACE : key
        val KEY_INSERT : key
        val KEY_DELETE : key
        val KEY_RIGHT : key
        val KEY_LEFT : key
        val KEY_DOWN : key
        val KEY_UP : key
        val KEY_PAGE_UP : key
        val KEY_PAGE_DOWN : key
        val KEY_HOME : key
        val KEY_END : key
        val KEY_CAPS_LOCK : key
        val KEY_SCROLL_LOCK : key
        val KEY_NUM_LOCK : key
        val KEY_PRINT_SCREEN : key
        val KEY_PAUSE : key
        val KEY_F1 : key
        val KEY_F2 : key
        val KEY_F3 : key
        val KEY_F4 : key
        val KEY_F5 : key
        val KEY_F6 : key
        val KEY_F7 : key
        val KEY_F8 : key
        val KEY_F9 : key
        val KEY_F10 : key
        val KEY_F11 : key
        val KEY_F12 : key
        val KEY_F13 : key
        val KEY_F14 : key
        val KEY_F15 : key
        val KEY_F16 : key
        val KEY_F17 : key
        val KEY_F18 : key
        val KEY_F19 : key
        val KEY_F20 : key
        val KEY_F21 : key
        val KEY_F22 : key
        val KEY_F23 : key
        val KEY_F24 : key
        val KEY_F25 : key
        val KEY_KP_0 : key
        val KEY_KP_1 : key
        val KEY_KP_2 : key
        val KEY_KP_3 : key
        val KEY_KP_4 : key
        val KEY_KP_5 : key
        val KEY_KP_6 : key
        val KEY_KP_7 : key
        val KEY_KP_8 : key
        val KEY_KP_9 : key
        val KEY_KP_DECIMAL : key
        val KEY_KP_DIVIDE : key
        val KEY_KP_MULTIPLY : key
        val KEY_KP_SUBTRACT : key
        val KEY_KP_ADD : key
        val KEY_KP_ENTER : key
        val KEY_KP_EQUAL : key
        val KEY_LEFT_SHIFT : key
        val KEY_LEFT_CONTROL : key
        val KEY_LEFT_ALT : key
        val KEY_LEFT_SUPER : key
        val KEY_RIGHT_SHIFT : key
        val KEY_RIGHT_CONTROL : key
        val KEY_RIGHT_ALT : key
        val KEY_RIGHT_SUPER : key
        val KEY_MENU : key
        val KEY_UNKNOWN : key
        val KEY_FIRST : key
        val KEY_LAST : key
      end

Types

  • key specifies a physical key.

Values

  • id k

    returns the integer ID of the key value k. This value matches the value specified in the glfh3.h header file.

  • For each GLFW constant GLFW_KEY_XXX, the Key structure defines a key value KEY_XXX.

  • KEY_UNKNOWN

    represents unknown keys with id(KEY_UNKNOWN) = ~1.

  • KEY_FIRST

    the key with the lowest ID value.

  • KEY_LAST

    the key with the highest ID value.

The ModKey structure

The ModKey structure defines types and operations for tracking the state of the modifier keys when handling keyboard or mouse input.

structure ModKey : sig
    eqtype mod_key
    eqtype mod_keys
    val SHIFT : mod_key
    val CONTROL : mod_key
    val ALT : mod_key
    val SUPER : mod_key
    val modKeys : mod_key list -> mod_keys
    val isSet : mod_key -> mod_keys -> bool
  end

TYPES

  • mod_key

    represents an individual modifier key.

  • mod_keys

    represents a set of modifier keys.

VALUES

  • SHIFT

    specifies the shift modifier key.

  • CONTROL

    specifies the control modifier key.

  • ALT

    specifies the alt or option modifier key.

  • SUPER

    specifies the super or command modifier key.

  • modKeys keys

    returns the set representation of the list keys of modifier keys.

  • isSet key keySet

    returns true if key is in the set keySet.

The Kbd structure

structure Kbd : sig
    val key : window * Key.key -> bool

    val sticky : window -> bool
    val setSticky : window * bool -> unit

    datatype action = PRESS | RELEASE | REPEAT
    val setKeyCallback : (window * (window * Key.key * int * action * ModKey.mod_keys -> unit) option) -> unit
    val setCharCallback : (window * (window * string -> unit) option) -> unit
  end

Types

  • action

    represents the key action (PRESS, RELEASE, or REPEAT) in a key event.

Values

  • key (win, key)

    returns the current state of the given key. If the input mode is sticky, then this function returns true the first time that this function is called after key has been pressed, even if it has already been released.

  • sticky win

    returns the keyboard stickiness input mode for the window win.

  • setSticky (win, mode)

    sets the keyboard stickiness for the window win.

  • setKeyCallback (win, NONE)

    clears the current keyboard key callback function.

  • setKeyCallback (win, SOME kb)

    sets the current current keyboard key callback function to the function kb. The callback function has the type

    window * Key.key * int * action * ModKey.mod_keys -> unit
    

    where the callback arguments are

    • the window that has the keyboard focus

    • the key that was pressed

    • a system-specific scan code

    • one of PRESS, RELEASE, or REPEAT

    • the state of the modifier keys when the event happened.

  • setCharCallback (win, NONE)

    clears the current Unicode character callback function.

  • setCharCallback (win, SOME kb)

    sets the current current keyboard key callback function to the function kb. The callback function has the type

    window * string -> unit
    

    where the callback arguments are

    • the window that has the keyboard focus

    • a UTF8 encoding of the Unicode code point of the character. A single-character string is used for this value to support readable pattern matching in the callback function (as opposed to matching against the numeric Unicode code points).

The Mouse structure

structure Mouse : sig
    val cursorPos : window -> pos2d
    val setCursorPos : window * pos2d -> unit

  (* [glfwGetInputMode, glfwSetInputMode] *)
    datatype cursor_mode = NORMAL | HIDDEN | DISABLED
    val cursorMode : window -> cursor_mode
    val setCursorMode : window * cursor_mode -> unit

  (* [glfwGetInputMode, glfwSetInputMode] *)
    val stickyButtons : window -> bool
    val setStickyButtons : window * bool -> unit

  (* Mouse cursor and button callbacks *)
    val setCursorEnterCallback : (window * (window * bool -> unit) option) -> unit
    val setCursorPosCallback : (window * (window * pos2d -> unit) option) -> unit
    val setButtonCallback : (window * (window * int * bool * ModKey.mod_keys -> unit) option) -> unit
    val setScrollCallback : (window * (window * {xOffset : double, yOffset : double} -> unit) option) -> unit
  end

The Joystick structure

structure Joystick : sig
    eqtype joystick
  (* "joystick i" returns the i'th joystick (if it exists) or else NONE [glfwJoystickPresent] *)
    val joystick : int -> joystick option
  (* return the ID of the joystick *)
    val id : joystick -> int
  (* return the name of the joystick [glfwGetJoystickName] *)
    val name : joystick -> string
  (* return the current axes values of the joystick [glfwGetJoystickAxes] *)
    val axes : joystick -> float vector
  (* return the current button values of the joystick (true = down, false = up) [glfwGetJoystickButtons] *)
    val buttons : joystick -> bool vector
  end

The Error structure

GLFW uses a callback mechanism to report errors to the client program. Since it is common in SML programs to signal errors using exceptions, we postpone the error callback until after the GLFW function that encountered the error returns. We supply a default error callback (or action function) that raises the GLFW_ERROR exception, but it is also possible for an application to define its own error action.

structure Error : sig
    eqtype error_code
    val NOT_INITIALIZED : error_code
    val NO_CURRENT_CONTEXT : error_code
    val INVALID_ENUM : error_code
    val INVALID_VALUE : error_code
    val OUT_OF_MEMORY : error_code
    val API_UNAVAILABLE : error_code
    val VERSION_UNAVAILABLE : error_code
    val PLATFORM_ERROR : error_code
    val FORMAT_UNAVAILABLE : error_code

    exception GLFW_ERROR of (error_code * string)

    val setErrorAction : ((error_code * string) -> unit) -> unit

  end

Types

  • error_code

    specifies a GLFW error.

Exceptions

  • GLFW_ERROR(code, msg)

    is an exception value that is raised by the default error action, where code is the GLFW error code and msg is a UTF8 encoded error message.

Values

  • NOT_INITIALIZED

    signals that GLFW has not been initialized.

  • NO_CURRENT_CONTEXT

    signals that no context is current for this thread.

  • INVALID_ENUM

    signals that one of the enum parameters for the function was given an invalid enum.

  • INVALID_VALUE

    signals that one of the parameters for the function was given an invalid value.

  • OUT_OF_MEMORY

    signals that a memory allocation failed.

  • API_UNAVAILABLE

    signals that GLFW could not find support for the requested client API on the system.

  • VERSION_UNAVAILABLE

    signals that GLFW could not find the requested client API version on the system.

  • PLATFORM_ERROR

    signals that a platform-specific error occurred that does not match any of the more specific categories.

  • FORMAT_UNAVAILABLE

    signals that the clipboard did not contain data in the requested format.

  • setErrorAction act

    sets the error action to be the function act.

Correspondence between SML3d and the GLFW APIs

TODO: a table that maps GLFW functions to SML3d.