module FWGL (
module FWGL.Audio,
module FWGL.Input,
module FWGL.Utils,
module FRP.Yampa,
draw,
run,
run',
loadOBJ,
loadOBJAsync,
Output,
(.>),
io,
freeGeometry,
freeTexture,
freeProgram
) where
import Control.Concurrent
import Control.Monad.IO.Class
import FWGL.Audio
import FWGL.Backend hiding (Texture, Program)
import FWGL.Input
import FWGL.Internal.GL (evalGL)
import FWGL.Geometry (Geometry3)
import FWGL.Geometry.OBJ
import FWGL.Graphics.Draw
import FWGL.Graphics.Types
import FWGL.Shader.Program (Program)
import FWGL.Utils
import FRP.Yampa
newtype Output = Output { drawOutput :: Draw () }
(.>) :: Output -> Output -> Output
Output a .> Output b = Output $ a >> b
draw :: BackendIO => [Layer] -> Output
draw layers = Output $ mapM_ drawLayer layers
io :: IO () -> Output
io = Output . liftIO
freeGeometry :: BackendIO => Geometry i -> Output
freeGeometry = Output . removeGeometry
freeTexture :: BackendIO => Texture -> Output
freeTexture = Output . removeTexture
freeProgram :: BackendIO => Program g i -> Output
freeProgram = Output . removeProgram
run :: BackendIO
=> SF (Input ()) Output
-> IO ()
run = run' $ return ()
run' :: BackendIO
=> IO inp
-> SF (Input inp) Output
-> IO ()
run' customInput sigf = setup initState loop customInput sigf
where initState w h = evalGL $ drawInit w h
loop (Output act) ctx drawState =
flip evalGL ctx . flip execDraw drawState $ do
drawBegin
act
drawEnd
loadOBJAsync :: BackendIO
=> FilePath
-> (Either String (Geometry Geometry3) -> IO ())
-> IO ()
loadOBJAsync fp k = loadTextFile fp $
\e -> case e of
Left err -> k $ Left err
Right str -> k . Right . geometryOBJ
. parseOBJ $ str
loadOBJ :: BackendIO => FilePath -> IO (Either String (Geometry Geometry3))
loadOBJ fp = do var <- newEmptyMVar
loadOBJAsync fp $ putMVar var
takeMVar var