packages feed

gelatin-sdl2-0.1.0.0: app/Main.hs

{-# LANGUAGE LambdaCase #-}
import           Control.Arrow
import           Control.Concurrent         (threadDelay)
import           Control.Monad              (forM_, forever, when)
import           Control.Monad.Trans.Either (runEitherT)
import           Gelatin.SDL2
import           Paths_gelatin_sdl2
import           SDL
import           System.Exit                (exitFailure, exitSuccess)
import           System.FilePath            ((</>))

--------------------------------------------------------------------------------
-- Regular pure pictures
--------------------------------------------------------------------------------
colorGeometry :: Geometry (V2 Float, V4 Float)
colorGeometry = do
  triangles tris
  beziers $ mapVertices (first (+ V2 100 0)) tris
  line $ mapVertices (first (+V2 200 0)) tris
  line $ mapVertices (first (+V2 300 0)) bcurve
  line $ mapVertices (first ((+V2 300 100) . (*V2 1 (-1)))) bcurve
  line $ mapVertices (first (+V2 350 50)) circle
  where tris = do tri (0, red) (V2 100 0, green) (100, blue)
                  tri (0, magenta) (V2 0 100, canary) (100, cyan)
        bcurve = mapVertices (\v -> (v,white)) $
                   curve (V2 0 100) (V2 50 (-50)) 100
        circle = mapVertices (\v -> (v,white)) $ arc 50 50 0 (2*pi)

colorPicture :: ColorPicture ()
colorPicture = do
  setStroke [StrokeWidth 3, StrokeFeather 1]
  setGeometry colorGeometry

bezierPicture :: ColorPicture ()
bezierPicture = setGeometry $ beziers $ do
  bez (V2 0   0,   white) (V2 200 0, blue) (V2 200 200, green)
  bez (V2 400 200, white) (V2 400 0, blue) (V2 200 0,   green)

texturePicture :: GLuint -> V2 Int -> TexturePicture ()
texturePicture tex (V2 w h) = do
  setStroke [StrokeWidth 3, StrokeFeather 1]
  setTextures [tex]
  setGeometry $ mapGeometry toUV colorGeometry
    where toUV (V2 x y, _) = (V2 x y, V2 (x/fromIntegral w) (y/fromIntegral h))

isQuit :: Event -> Bool
isQuit (Event _ payload) = isKeyQ payload || payload == QuitEvent
  where
    isKeyQ (KeyboardEvent (KeyboardEventData _ _ _ (Keysym _ KeycodeQ _))) = True
    isKeyQ _ = False

-- Start up our backend(s) and go!
main :: IO ()
main =
  runEitherT (startupSDL2Backends 920 420 "gelatin-sdl2-example" True) >>= \case
    Left err -> putStrLn err >> exitFailure
    Right (SDL2Backends glv2v4 glv2v2) -> do
      -- Load up a texture. This can be done with either backend, as they both
      -- share the same OpenGL context.
      imgName <- getDataFileName $ "img" </> "lava.png"
      Just (tex, sz) <- allocTexture glv2v2 imgName
      -- Compiler our picture descriptions, sending their geometry to the GPU and
      -- returning a renderable resource and a cleanup action. The result of the
      -- picture computation is discarded.
      (_, colorRender)     <- compilePicture glv2v4 colorPicture
      (_, bezierRenderer)  <- compilePicture glv2v4 bezierPicture
      (_, texRender)       <- compilePicture glv2v2 $ texturePicture tex sz
      -- Forever run the main loop, which polls for SDL events, clear the window,
      -- render our resources at different places with different transforms, and
      -- update the window with the new frame.
      forever $ do
        threadDelay 1
        events <- getEvents glv2v4
        when (any isQuit events) exitSuccess
        clearWindow glv2v4
        let indices = [0..10]
        forM_ indices $ \i -> do
          let txy  = move (100 - 10 * i) (100 - 10 * i)
              a    = alpha $ i/10
              rs   = [txy, a]
          snd colorRender rs
          snd bezierRenderer $ move 400 0 : rs
          snd texRender $ move 0 200 : rs
        updateWindow glv2v4