-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathGLFWHelpers.hs
124 lines (107 loc) · 4.76 KB
/
GLFWHelpers.hs
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
121
122
123
module GLFWHelpers ( withWindow
, GLFWEvent(..)
, highDPIScaleFactor
) where
import Control.Exception
import Control.Monad
import Control.Concurrent.STM
import qualified Graphics.UI.GLFW as GLFW
import qualified Graphics.GL as GLR
-- Various utility functions related to GLFW
withWindow :: Int -> Int -> Bool -> String -> TQueue GLFWEvent -> (GLFW.Window -> IO ()) -> IO ()
withWindow w h srgb title tq =
bracket
( do GLFW.setErrorCallback . Just $ errorCallback tq
True <- GLFW.init
-- GLFW.windowHint $ GLFW.WindowHint'Samples 4
-- GLFW.windowHint $ GLFW.WindowHint'Decorated False
GLFW.windowHint $ GLFW.WindowHint'Resizable True
when srgb . GLFW.windowHint $ GLFW.WindowHint'sRGBCapable True
modernOpenGL
Just window <- GLFW.createWindow w h title Nothing Nothing
registerCallbacks window tq
GLFW.makeContextCurrent $ Just window
when srgb $ GLR.glEnable GLR.GL_FRAMEBUFFER_SRGB
return window
)
( \window -> do GLFW.destroyWindow window
GLFW.terminate
)
-- >2.1, no backwards compatibility on OS X
-- http://www.glfw.org/faq.html#how-do-i-create-an-opengl-30-context
modernOpenGL :: IO ()
modernOpenGL = do
GLFW.windowHint $ GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core
GLFW.windowHint $ GLFW.WindowHint'OpenGLForwardCompat True
GLFW.windowHint $ GLFW.WindowHint'ContextVersionMajor 3
GLFW.windowHint $ GLFW.WindowHint'ContextVersionMinor 3
highDPIScaleFactor :: GLFW.Window -> IO Double
highDPIScaleFactor win = do
(scWdh, _) <- GLFW.getWindowSize win
(pxWdh, _) <- GLFW.getFramebufferSize win
return $ fromIntegral pxWdh / fromIntegral scWdh
-- Convert GLFW callbacks into events delivered to a queue
data GLFWEvent = GLFWEventError
!GLFW.Error
!String
| GLFWEventKey
!GLFW.Window
!GLFW.Key
!Int
!GLFW.KeyState
!GLFW.ModifierKeys
| GLFWEventWindowSize
!GLFW.Window
!Int
!Int
| GLFWEventFramebufferSize
!GLFW.Window
!Int
!Int
| GLFWEventMouseButton
!GLFW.Window
!GLFW.MouseButton
!GLFW.MouseButtonState
!GLFW.ModifierKeys
| GLFWEventCursorPos
!GLFW.Window
!Double
!Double
| GLFWEventScroll
!GLFW.Window
!Double
!Double
errorCallback :: TQueue GLFWEvent -> GLFW.Error -> String -> IO ()
errorCallback tq e s = atomically . writeTQueue tq $ GLFWEventError e s
keyCallback :: TQueue GLFWEvent
-> GLFW.Window
-> GLFW.Key
-> Int
-> GLFW.KeyState
-> GLFW.ModifierKeys -> IO ()
keyCallback tq win k sc ka mk = atomically . writeTQueue tq $ GLFWEventKey win k sc ka mk
windowSizeCallback :: TQueue GLFWEvent -> GLFW.Window -> Int -> Int -> IO ()
windowSizeCallback tq win w h = atomically . writeTQueue tq $ GLFWEventWindowSize win w h
framebufferSizeCallback :: TQueue GLFWEvent -> GLFW.Window -> Int -> Int -> IO ()
framebufferSizeCallback tq win w h =
atomically . writeTQueue tq $ GLFWEventFramebufferSize win w h
mouseButtonCallback :: TQueue GLFWEvent
-> GLFW.Window
-> GLFW.MouseButton
-> GLFW.MouseButtonState
-> GLFW.ModifierKeys
-> IO ()
mouseButtonCallback tq win bttn st mk =
atomically . writeTQueue tq $ GLFWEventMouseButton win bttn st mk
cursorPosCallback :: TQueue GLFWEvent -> GLFW.Window -> Double -> Double -> IO ()
cursorPosCallback tq win x y = atomically . writeTQueue tq $ GLFWEventCursorPos win x y
scrollCallback :: TQueue GLFWEvent -> GLFW.Window -> Double -> Double -> IO ()
scrollCallback tq win x y = atomically . writeTQueue tq $ GLFWEventScroll win x y
registerCallbacks :: GLFW.Window -> TQueue GLFWEvent -> IO ()
registerCallbacks window tq = do
GLFW.setKeyCallback window . Just $ keyCallback tq
GLFW.setWindowSizeCallback window . Just $ windowSizeCallback tq
GLFW.setFramebufferSizeCallback window . Just $ framebufferSizeCallback tq
GLFW.setMouseButtonCallback window . Just $ mouseButtonCallback tq
GLFW.setCursorPosCallback window . Just $ cursorPosCallback tq
GLFW.setScrollCallback window . Just $ scrollCallback tq