-- | Initialize an OpenGL window using the GLFW-b library module GL where -------------------------------------------------------------------------------- import Data.Char hiding ( Space ) import Control.Monad import Control.Concurrent import Data.IORef import System.Exit import System.IO.Unsafe as Unsafe import Graphics.UI.GLFW as GLFW import Graphics.Rendering.OpenGL as GL -------------------------------------------------------------------------------- theWindowSize :: IORef (Int,Int) theWindowSize = Unsafe.unsafePerformIO $ newIORef $ error "window size not set" setWindowCoordSystem :: IO () setWindowCoordSystem = do matrixMode $=! Projection loadIdentity (w,h) <- readIORef theWindowSize GL.ortho 0 (fromIntegral w) (fromIntegral h) 0 (-1) (1::Double) matrixMode $=! Modelview 0 loadIdentity -------------------------------------------------------------------------------- myErrorCallback :: GLFW.Error -> String -> IO () myErrorCallback err msg = do putStrLn $ msg ++ "(" ++ show err ++ ")" myExit myKeyCallback :: Window -> Key -> Int -> KeyState -> ModifierKeys -> IO () myKeyCallback _ key nrepeat keyState modif = case key of Key'Escape -> myExit _ -> return () myCharCallback :: Window -> Char -> IO () myCharCallback _ char = do return () myWinCloseCallback :: Window -> IO () myWinCloseCallback window = myExit myFrBufSizeCallback :: Window -> Int -> Int -> IO () myFrBufSizeCallback window xsiz ysiz = do writeIORef theWindowSize (xsiz,ysiz) putStrLn $ "framebuffer resized to " ++ show (xsiz,ysiz) myRefreshCallback :: Window -> IO () myRefreshCallback window = do return () myExit :: IO () myExit = do -- terminate exitWith ExitSuccess -------------------------------------------------------------------------------- {- frac :: Double -> Double frac x = x - fromIntegral (floor x :: Int) fmod :: Double -> Double -> Double fmod x s = frac (x/s) * s -} -------------------------------------------------------------------------------- renderLoop :: (Window -> Double -> IO ()) -> Window -> IO () renderLoop display window = loop where loop = do Just time <- getTime -- print time display window time swapBuffers window threadDelay 50 loop -------------------------------------------------------------------------------- initGL :: IO precalc -> (precalc -> Window -> Double -> IO ()) -> IO () initGL userPrecalc userDisplay = do setErrorCallback (Just myErrorCallback) GLFW.init Just window <- createWindow 800 500 "window title" Nothing Nothing (xsiz,ysiz) <- getFramebufferSize window putStrLn $ "initial framebuffer size = " ++ show (xsiz,ysiz) writeIORef theWindowSize (xsiz,ysiz) major <- getWindowContextVersionMajor window minor <- getWindowContextVersionMinor window rev <- getWindowContextVersionRevision window putStrLn $ "OpenGL context version = " ++ show major ++ "." ++ show minor ++ "." ++ show rev setWindowCloseCallback window (Just myWinCloseCallback ) setKeyCallback window (Just myKeyCallback ) setCharCallback window (Just myCharCallback ) setFramebufferSizeCallback window (Just myFrBufSizeCallback) setWindowRefreshCallback window (Just myRefreshCallback ) forkOS $ do makeContextCurrent (Just window) swapInterval 1 precalc <- userPrecalc renderLoop (userDisplay precalc) window forever waitEvents --------------------------------------------------------------------------------