summaryrefslogtreecommitdiff
path: root/LambdaHello.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-08 07:09:40 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-08 07:09:40 -0400
commita3e6b1b9b9b5a45fee5b71d7a3ef81c7111f8d48 (patch)
tree410dd05dd0eaa3327efda3d9413c9c4bf1314e72 /LambdaHello.hs
parent42c7f6bd91165816dd10a20d0571057c286265b7 (diff)
LambdaHello
Diffstat (limited to 'LambdaHello.hs')
-rw-r--r--LambdaHello.hs139
1 files changed, 139 insertions, 0 deletions
diff --git a/LambdaHello.hs b/LambdaHello.hs
new file mode 100644
index 0000000..ed04598
--- /dev/null
+++ b/LambdaHello.hs
@@ -0,0 +1,139 @@
1{-# LANGUAGE OverloadedStrings #-}
2module LambdaHello where
3
4import GI.Gtk as Gtk
5import GI.Gdk.Objects
6
7-- import qualified Graphics.Rendering.OpenGL as GL
8import Data.Function
9import Control.Concurrent
10import LambdaCube.GL as LambdaCubeGL
11import LambdaCube.GL.Mesh as LambdaCubeGL
12import LambdaCube.IR
13import Codec.Picture as Juicy
14import Data.Aeson as JSON
15import qualified Data.ByteString as SB
16import System.IO.Error
17import qualified Data.Map as Map
18import qualified Data.Vector as V
19
20import qualified Backend as RF
21
22data State = State
23 { stConfig :: Config
24 , stRealized :: MVar Realized
25 }
26
27initState :: IO State
28initState = do
29 cfg <- either fail return =<< loadConfig
30 r <- newEmptyMVar
31 return State
32 { stConfig = cfg
33 , stRealized = r
34 }
35
36
37render :: State -> GLArea -> GLContext -> IO Bool
38render st w _ = do -- gLAreaMakeCurrent w >> gLAreaGetError w >>= \me -> maybe id (\e _ -> print e >> return False) me $ do
39 mr <- tryTakeMVar (stRealized st)
40 maybe (\_ -> putStrLn "Not realized!") (&) mr $ \r -> do
41 -- Load input to pipeline.
42 -- GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h)
43 return (500,500) >>= \(w,h) -> LambdaCubeGL.setScreenSize (rStorage r) (fromIntegral w) (fromIntegral h)
44 LambdaCubeGL.updateUniforms (rStorage r) $ do
45 "diffuseTexture" @= return (rTexture r)
46 "time" @= do
47 -- Just t <- GLFW.getTime
48 let t = 1.0 :: Double
49 return (realToFrac t :: Float)
50
51 putStrLn "render!"
52 -- GL.clearColor GL.$= GL.Color4 0 255 0 1
53 -- GL.clear [GL.ColorBuffer]
54 RF.renderFrame (rRenderer r)
55 -- GL.flush
56 putMVar (stRealized st) r
57 return True
58
59data Realized = Realized
60 { rStorage :: GLStorage
61 , rTexture :: TextureData
62 , rRenderer :: GLRenderer
63 }
64
65realize :: State -> GLArea -> IO ()
66realize st w = gLAreaMakeCurrent w >> gLAreaGetError w >>= \me -> maybe id (\e _ -> print e) me $ do
67 let cfg = stConfig st
68
69 _ <- tryTakeMVar (stRealized st)
70
71 storage <- LambdaCubeGL.allocStorage (cfgSchema cfg)
72
73 -- upload geometry to GPU and add to pipeline input
74 LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
75 LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
76
77 -- load image and upload texture
78 texture <- LambdaCubeGL.uploadTexture2DToGPU (cfgLogo cfg)
79
80 renderer <- LambdaCubeGL.allocRenderer (cfgPipeline cfg)
81
82 compat <- LambdaCubeGL.setStorage renderer storage -- check schema compatibility
83
84 putMVar (stRealized st) $ Realized storage texture renderer
85 -- GL.flush
86 putStrLn "realize!"
87 maybe id (\e _ -> putStrLn e) compat $ return ()
88
89unrealize :: State -> GLArea -> IO ()
90unrealize _ _ = return ()
91
92data Config = Config
93 { cfgSchema :: PipelineSchema
94 , cfgPipeline :: Pipeline
95 , cfgLogo :: DynamicImage
96 }
97
98loadConfig :: IO (Either String Config)
99loadConfig = do
100 pipelineDesc <- do
101 maybe (Left "Unable to parse hello.json") Right . JSON.decodeStrict <$> SB.readFile "hello.json"
102 `catchIOError` \e -> return $ Left (show e)
103 -- setup render data
104 let inputSchema = makeSchema $ do
105 defObjectArray "objects" Triangles $ do
106 "position" @: Attribute_V2F
107 "uv" @: Attribute_V2F
108 defUniforms $ do
109 "time" @: Float
110 "diffuseTexture" @: FTexture2D
111 -- load image and upload texture
112 img <- Juicy.readImage "logo.png"
113 `catchIOError` \e -> return $ Left (show e)
114 return $ Config inputSchema <$> pipelineDesc <*> img
115
116-- geometry data: triangles
117triangleA :: LambdaCubeGL.Mesh
118triangleA = Mesh
119 { mAttributes = Map.fromList
120 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
121 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
122 ]
123 , mPrimitive = P_Triangles
124 }
125
126triangleB :: LambdaCubeGL.Mesh
127triangleB = Mesh
128 { mAttributes = Map.fromList
129 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
130 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
131 ]
132 , mPrimitive = P_Triangles
133 }
134
135createContext :: State -> GLArea -> IO GLContext
136createContext st glarea = do
137 Just win <- widgetGetWindow glarea
138 gl <- windowCreateGlContext win
139 return gl