{-# LANGUAGE Arrows #-}
import Control.Arrow
import Data.Monoid
import Data.VectorSpace
import Graphics.UI.GLUT
import FRP.Yampa.GLUT.Adapter
import FRP.Yampa (SF, integral, delay, initially)
import FRP.Yampa.Event
import FRP.Yampa.Utilities
main = do
simpleInit "Simple"
adapt leaveMainLoop simple
simple :: Reaction
simple = proc ev -> do
pos <- ball -< ev
displayAction <- arr (tagWith (actionIO . display)) <<< redisplay -< ev
reshapedAction <- arr (fmap (actionIO . reshape)) <<< reshaped -< ev
returnA -< mconcat [fmap (\f -> f pos) displayAction, reshapedAction]
display (x, y) = do
clear [ ColorBuffer, DepthBuffer ]
preservingMatrix $ do
translate (Vector3 (realToFrac x) (realToFrac y) (0 :: GLfloat))
renderObject Solid (Teapot 0.1)
swapBuffers
reshape sz@(Size w h) = do
let b = fromIntegral (w `min` h) * 2
w' = fromIntegral w / b
h' = fromIntegral h / b
viewport $= (Position 0 0, sz)
matrixMode $= Projection
loadIdentity
frustum (-w') w' (-h') h' 2 100
matrixMode $= Modelview 0
loadIdentity
translate (Vector3 0 0 (-4 :: GLfloat))
ball :: SF (Event UI) (Float, Float)
ball = proc ev -> do
rec
(Vector2 tx ty) <- simpleMousePosition -< ev
let mpos = (tx, ty)
dpos = mpos ^-^ pos
speed = normalized dpos ^* 0.5
pos <- integral <<< delay 0.2 zeroV -< speed
returnA -< pos