sig
  external glutInit : argv:string array -> string array = "ml_glutinit"
  external glutInitWindowPosition : x:int -> y:int -> unit
    = "ml_glutinitwindowposition"
  external glutInitWindowSize : width:int -> height:int -> unit
    = "ml_glutinitwindowsize"
  type init_mode =
      GLUT_RGBA
    | GLUT_RGB
    | GLUT_INDEX
    | GLUT_SINGLE
    | GLUT_DOUBLE
    | GLUT_ACCUM
    | GLUT_ALPHA
    | GLUT_DEPTH
    | GLUT_STENCIL
    | GLUT_MULTISAMPLE
    | GLUT_STEREO
    | GLUT_LUMINANCE
  external glutInitDisplayMode : mode:Glut.init_mode list -> unit
    = "ml_glutinitdisplaymode"
  external glutInitDisplayString : string -> unit
    = "ml_glutinitdisplaystring"
  external glutInitContextVersion : major:int -> minor:int -> unit
    = "ml_glutinitcontextversion"
  type context_profile = GLUT_CORE_PROFILE | GLUT_COMPATIBILITY_PROFILE
  external glutInitContextProfile : profile:Glut.context_profile -> unit
    = "ml_glutinitcontextprofile"
  external glutMainLoop : unit -> unit = "ml_glutmainloop"
  external glutLeaveMainLoop : unit -> unit = "ml_glutleavemainloop"
  type window_id
  external glutCreateWindow : title:string -> Glut.window_id
    = "ml_glutcreatewindow"
  external glutSetWindow : win:Glut.window_id -> unit = "ml_glutsetwindow"
  external glutGetWindow : unit -> Glut.window_id = "ml_glutgetwindow"
  external glutCreateSubWindow :
    win:Glut.window_id ->
    x:int -> y:int -> width:int -> height:int -> Glut.window_id
    = "ml_glutcreatesubwindow"
  external glutDestroyWindow : win:Glut.window_id -> unit
    = "ml_glutdestroywindow"
  external glutPostRedisplay : unit -> unit = "ml_glutpostredisplay"
  external glutSwapBuffers : unit -> unit = "ml_glutswapbuffers"
  external glutPositionWindow : x:int -> y:int -> unit
    = "ml_glutpositionwindow"
  external glutReshapeWindow : width:int -> height:int -> unit
    = "ml_glutreshapewindow"
  external glutFullScreen : unit -> unit = "ml_glutfullscreen"
  external glutPopWindow : unit -> unit = "ml_glutpopwindow"
  external glutPushWindow : unit -> unit = "ml_glutpushwindow"
  external glutShowWindow : unit -> unit = "ml_glutshowwindow"
  external glutHideWindow : unit -> unit = "ml_gluthidewindow"
  external glutIconifyWindow : unit -> unit = "ml_gluticonifywindow"
  external glutSetWindowTitle : name:string -> unit = "ml_glutsetwindowtitle"
  external glutSetIconTitle : name:string -> unit = "ml_glutseticontitle"
  type cursor_type =
      GLUT_CURSOR_RIGHT_ARROW
    | GLUT_CURSOR_LEFT_ARROW
    | GLUT_CURSOR_INFO
    | GLUT_CURSOR_DESTROY
    | GLUT_CURSOR_HELP
    | GLUT_CURSOR_CYCLE
    | GLUT_CURSOR_SPRAY
    | GLUT_CURSOR_WAIT
    | GLUT_CURSOR_TEXT
    | GLUT_CURSOR_CROSSHAIR
    | GLUT_CURSOR_UP_DOWN
    | GLUT_CURSOR_LEFT_RIGHT
    | GLUT_CURSOR_TOP_SIDE
    | GLUT_CURSOR_BOTTOM_SIDE
    | GLUT_CURSOR_LEFT_SIDE
    | GLUT_CURSOR_RIGHT_SIDE
    | GLUT_CURSOR_TOP_LEFT_CORNER
    | GLUT_CURSOR_TOP_RIGHT_CORNER
    | GLUT_CURSOR_BOTTOM_RIGHT_CORNER
    | GLUT_CURSOR_BOTTOM_LEFT_CORNER
    | GLUT_CURSOR_FULL_CROSSHAIR
    | GLUT_CURSOR_NONE
    | GLUT_CURSOR_INHERIT
  external glutSetCursor : cursor:Glut.cursor_type -> unit
    = "ml_glutsetcursor"
  external glutWarpPointer : x:int -> y:int -> unit = "ml_glutwarppointer"
  external glutIgnoreKeyRepeat : ignore:bool -> unit
    = "ml_glutignorekeyrepeat"
  type menu_id
  val glutCreateMenu : menu:(value:int -> unit) -> Glut.menu_id
  external glutGetMenu : unit -> Glut.menu_id = "ml_glutgetmenu"
  external glutSetMenu : menu:Glut.menu_id -> unit = "ml_glutsetmenu"
  external glutDestroyMenu : menu:Glut.menu_id -> unit = "ml_glutdestroymenu"
  external glutAddMenuEntry : name:string -> value:int -> unit
    = "ml_glutaddmenuentry"
  external glutAddSubMenu : name:string -> menu:Glut.menu_id -> unit
    = "ml_glutaddsubmenu"
  external glutChangeToMenuEntry :
    entry:int -> name:string -> value:int -> unit
    = "ml_glutchangetomenuentry"
  external glutChangeToSubMenu :
    entry:int -> name:string -> menu:Glut.menu_id -> unit
    = "ml_glutchangetosubmenu"
  external glutRemoveMenuItem : entry:int -> unit = "ml_glutremovemenuitem"
  type mouse_button =
      GLUT_LEFT_BUTTON
    | GLUT_MIDDLE_BUTTON
    | GLUT_RIGHT_BUTTON
    | GLUT_WHEEL_UP
    | GLUT_WHEEL_DOWN
  external glutAttachMenu : button:Glut.mouse_button -> unit
    = "ml_glutattachmenu"
  external glutDetachMenu : button:Glut.mouse_button -> unit
    = "ml_glutdetachmenu"
  val glutDisplayFunc : display:(unit -> unit) -> unit
  val glutReshapeFunc : reshape:(width:int -> height:int -> unit) -> unit
  val glutKeyboardFunc :
    keyboard:(key:char -> x:int -> y:int -> unit) -> unit
  val glutKeyboardUpFunc :
    keyboard_up:(key:char -> x:int -> y:int -> unit) -> unit
  type mouse_button_state = GLUT_DOWN | GLUT_UP
  val glutMouseFunc :
    mouse:(button:Glut.mouse_button ->
           state:Glut.mouse_button_state -> x:int -> y:int -> unit) ->
    unit
  val glutMotionFunc : motion:(x:int -> y:int -> unit) -> unit
  val glutPassiveMotionFunc : passive:(x:int -> y:int -> unit) -> unit
  type visibility_state = GLUT_NOT_VISIBLE | GLUT_VISIBLE
  val glutVisibilityFunc :
    visibility:(state:Glut.visibility_state -> unit) -> unit
  type entry_state = GLUT_LEFT | GLUT_ENTERED
  val glutEntryFunc : entry:(state:Glut.entry_state -> unit) -> unit
  type special_key =
      GLUT_KEY_F1
    | GLUT_KEY_F2
    | GLUT_KEY_F3
    | GLUT_KEY_F4
    | GLUT_KEY_F5
    | GLUT_KEY_F6
    | GLUT_KEY_F7
    | GLUT_KEY_F8
    | GLUT_KEY_F9
    | GLUT_KEY_F10
    | GLUT_KEY_F11
    | GLUT_KEY_F12
    | GLUT_KEY_LEFT
    | GLUT_KEY_UP
    | GLUT_KEY_RIGHT
    | GLUT_KEY_DOWN
    | GLUT_KEY_PAGE_UP
    | GLUT_KEY_PAGE_DOWN
    | GLUT_KEY_HOME
    | GLUT_KEY_END
    | GLUT_KEY_INSERT
  val glutSpecialFunc :
    special:(key:Glut.special_key -> x:int -> y:int -> unit) -> unit
  val glutSpecialUpFunc :
    special_up:(key:Glut.special_key -> x:int -> y:int -> unit) -> unit
  val glutIdleFunc : idle:(unit -> unit) -> unit
  external glutRemoveIdleFunc : unit -> unit = "ml_glutremoveidlefunc"
  val glutTimerFunc :
    msecs:int -> timer:(value:'-> unit) -> value:'-> unit
  external glutSetColor : cell:int -> r:float -> g:float -> b:float -> unit
    = "ml_glutsetcolor"
  external glutGetColor : cell:int -> float * float * float
    = "ml_glutgetcolor"
  type get_state =
      GLUT_WINDOW_X
    | GLUT_WINDOW_Y
    | GLUT_WINDOW_WIDTH
    | GLUT_WINDOW_HEIGHT
    | GLUT_WINDOW_BUFFER_SIZE
    | GLUT_WINDOW_STENCIL_SIZE
    | GLUT_WINDOW_DEPTH_SIZE
    | GLUT_WINDOW_RED_SIZE
    | GLUT_WINDOW_GREEN_SIZE
    | GLUT_WINDOW_BLUE_SIZE
    | GLUT_WINDOW_ALPHA_SIZE
    | GLUT_WINDOW_ACCUM_RED_SIZE
    | GLUT_WINDOW_ACCUM_GREEN_SIZE
    | GLUT_WINDOW_ACCUM_BLUE_SIZE
    | GLUT_WINDOW_ACCUM_ALPHA_SIZE
    | GLUT_WINDOW_DOUBLEBUFFER
    | GLUT_WINDOW_RGBA
    | GLUT_WINDOW_PARENT
    | GLUT_WINDOW_NUM_CHILDREN
    | GLUT_WINDOW_COLORMAP_SIZE
    | GLUT_WINDOW_NUM_SAMPLES
    | GLUT_WINDOW_STEREO
    | GLUT_WINDOW_CURSOR
    | GLUT_SCREEN_WIDTH
    | GLUT_SCREEN_HEIGHT
    | GLUT_SCREEN_WIDTH_MM
    | GLUT_SCREEN_HEIGHT_MM
    | GLUT_MENU_NUM_ITEMS
    | GLUT_DISPLAY_MODE_POSSIBLE
    | GLUT_INIT_DISPLAY_MODE
    | GLUT_INIT_WINDOW_X
    | GLUT_INIT_WINDOW_Y
    | GLUT_INIT_WINDOW_WIDTH
    | GLUT_INIT_WINDOW_HEIGHT
    | GLUT_ELAPSED_TIME
  external glutGet : state:Glut.get_state -> int = "ml_glutget"
  type glut_device =
      GLUT_HAS_KEYBOARD
    | GLUT_HAS_MOUSE
    | GLUT_HAS_SPACEBALL
    | GLUT_HAS_DIAL_AND_BUTTON_BOX
    | GLUT_HAS_TABLET
    | GLUT_NUM_MOUSE_BUTTONS
    | GLUT_NUM_SPACEBALL_BUTTONS
    | GLUT_NUM_BUTTON_BOX_BUTTONS
    | GLUT_NUM_DIALS
    | GLUT_NUM_TABLET_BUTTONS
  external glutDeviceGet : device:Glut.glut_device -> int
    = "ml_glutdeviceget"
  type active_modifier =
      GLUT_ACTIVE_SHIFT
    | GLUT_ACTIVE_CTRL
    | GLUT_ACTIVE_ALT
  external glutGetModifiers : unit -> Glut.active_modifier list
    = "ml_glutgetmodifiers"
  external glutGetModifiersB : unit -> bool * bool * bool
    = "ml_glutgetmodifiers_t"
  external glutExtensionSupported : extension:string -> bool
    = "ml_glutextensionsupported"
  type stroke_font = GLUT_STROKE_ROMAN | GLUT_STROKE_MONO_ROMAN
  type bitmap_font =
      GLUT_BITMAP_9_BY_15
    | GLUT_BITMAP_8_BY_13
    | GLUT_BITMAP_TIMES_ROMAN_10
    | GLUT_BITMAP_TIMES_ROMAN_24
    | GLUT_BITMAP_HELVETICA_10
    | GLUT_BITMAP_HELVETICA_12
    | GLUT_BITMAP_HELVETICA_18
  external glutBitmapCharacter : font:Glut.bitmap_font -> c:char -> unit
    = "ml_glutbitmapcharacter"
  external glutBitmapWidth : font:Glut.bitmap_font -> c:char -> int
    = "ml_glutbitmapwidth"
  external glutStrokeCharacter : font:Glut.stroke_font -> c:char -> unit
    = "ml_glutstrokecharacter"
  external glutStrokeWidth : font:Glut.stroke_font -> c:char -> int
    = "ml_glutstrokewidth"
  external glutBitmapHeight : font:Glut.bitmap_font -> int
    = "ml_glutbitmapheight"
  external glutStrokeHeight : font:Glut.stroke_font -> float
    = "ml_glutstrokeheight"
  external glutBitmapLength : font:Glut.bitmap_font -> str:string -> int
    = "ml_glutbitmaplength"
  external glutStrokeLength : font:Glut.stroke_font -> str:string -> int
    = "ml_glutstrokelength"
  external glutWireSphere : radius:float -> slices:int -> stacks:int -> unit
    = "ml_glutwiresphere"
  external glutSolidSphere : radius:float -> slices:int -> stacks:int -> unit
    = "ml_glutsolidsphere"
  external glutWireCone :
    base:float -> height:float -> slices:int -> stacks:int -> unit
    = "ml_glutwirecone"
  external glutSolidCone :
    base:float -> height:float -> slices:int -> stacks:int -> unit
    = "ml_glutsolidcone"
  external glutWireCube : size:float -> unit = "ml_glutwirecube"
  external glutSolidCube : size:float -> unit = "ml_glutsolidcube"
  external glutWireTorus :
    innerRadius:float -> outerRadius:float -> sides:int -> rings:int -> unit
    = "ml_glutwiretorus"
  external glutSolidTorus :
    innerRadius:float -> outerRadius:float -> sides:int -> rings:int -> unit
    = "ml_glutsolidtorus"
  external glutWireDodecahedron : unit -> unit = "ml_glutwiredodecahedron"
  external glutSolidDodecahedron : unit -> unit = "ml_glutsoliddodecahedron"
  external glutWireTeapot : size:float -> unit = "ml_glutwireteapot"
  external glutSolidTeapot : size:float -> unit = "ml_glutsolidteapot"
  external glutWireOctahedron : unit -> unit = "ml_glutwireoctahedron"
  external glutSolidOctahedron : unit -> unit = "ml_glutsolidoctahedron"
  external glutWireTetrahedron : unit -> unit = "ml_glutwiretetrahedron"
  external glutSolidTetrahedron : unit -> unit = "ml_glutsolidtetrahedron"
  external glutWireIcosahedron : unit -> unit = "ml_glutwireicosahedron"
  external glutSolidIcosahedron : unit -> unit = "ml_glutsolidicosahedron"
  external glutWireRhombicDodecahedron : unit -> unit
    = "ml_glutwirerhombicdodecahedron"
  external glutSolidRhombicDodecahedron : unit -> unit
    = "ml_glutsolidrhombicdodecahedron"
  external glutGameModeString : mode:string -> unit = "ml_glutgamemodestring"
  external glutEnterGameMode : unit -> unit = "ml_glutentergamemode"
  external glutLeaveGameMode : unit -> unit = "ml_glutleavegamemode"
  type game_mode =
      GLUT_GAME_MODE_ACTIVE
    | GLUT_GAME_MODE_POSSIBLE
    | GLUT_GAME_MODE_WIDTH
    | GLUT_GAME_MODE_HEIGHT
    | GLUT_GAME_MODE_PIXEL_DEPTH
    | GLUT_GAME_MODE_REFRESH_RATE
    | GLUT_GAME_MODE_DISPLAY_CHANGED
  external glutGameModeGet : game_mode:Glut.game_mode -> int
    = "ml_glutgamemodeget"
end