summaryrefslogtreecommitdiff
path: root/main.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-17 14:18:12 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-17 18:36:53 -0400
commit64f1a100fc887fb2a8bc87e2ac6975e872010ef5 (patch)
tree71e96856bf8a0ebcd14f7ab87124184cb15d868b /main.hs
parent3899b660b11bf1d3179965ac92a039b8d449306f (diff)
Refactored spinning-logo demo.
Diffstat (limited to 'main.hs')
-rw-r--r--main.hs92
1 files changed, 92 insertions, 0 deletions
diff --git a/main.hs b/main.hs
new file mode 100644
index 0000000..dff8263
--- /dev/null
+++ b/main.hs
@@ -0,0 +1,92 @@
1{-# LANGUAGE OverloadedLabels #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE LambdaCase #-}
4module Main where
5
6import Codec.Picture as Juicy
7import Control.Concurrent
8import Data.Word
9import Data.Function
10import qualified Data.Map.Strict as Map
11import qualified Data.Vector as V
12import GI.Gdk.Objects
13import GI.GLib.Constants
14import GI.Gtk as Gtk hiding (main)
15import LambdaCube.GL as LC
16import LambdaCube.GL.Mesh as LC
17import System.IO
18import System.IO.Error
19
20import GLWidget
21import LambdaCubeWidget
22import TimeKeeper
23
24type State = (TextureData, TimeKeeper, TickCallbackHandle)
25
26uploadState :: IsWidget glarea => DynamicImage -> glarea -> GLStorage -> IO State
27uploadState img glarea storage = do
28 -- upload geometry to GPU and add to pipeline input
29 LC.uploadMeshToGPU triangleA >>= LC.addMeshToObjectArray storage "objects" []
30 LC.uploadMeshToGPU triangleB >>= LC.addMeshToObjectArray storage "objects" []
31 -- load image and upload texture
32 texture <- LC.uploadTexture2DToGPU img
33 -- setup FrameClock
34 tm <- newTimeKeeper
35 tickcb <- widgetAddTickCallback glarea (tick tm)
36 return (texture,tm,tickcb)
37
38destroyState :: GLArea -> State -> IO ()
39destroyState glarea (texture,tm,tickcb) = do
40 widgetRemoveTickCallback glarea tickcb
41
42setUniforms :: glctx -> GLStorage -> State -> IO ()
43setUniforms gl storage (texture,tm,_) = do
44 t <- withMVar (tmSeconds tm) return
45 LC.updateUniforms storage $ do
46 "diffuseTexture" @= return texture
47 "time" @= return (realToFrac t :: Float)
48
49main :: IO ()
50main = do
51 m <- do
52 mimg <- Juicy.readImage "logo.png" `catchIOError` \e -> return $ Left (show e)
53 mpipeline <- loadPipeline "hello.json" $ do
54 defObjectArray "objects" Triangles $ do
55 "position" @: Attribute_V2F
56 "uv" @: Attribute_V2F
57 defUniforms $ do
58 "time" @: Float
59 "diffuseTexture" @: FTexture2D
60 return $ (,) <$> mimg <*> mpipeline
61 either (\e _ -> hPutStrLn stderr e) (&) m $ \(logo,pipeline) -> do
62 app <- do
63 mvar <- newEmptyMVar
64 return $ \glarea -> LCMethods
65 { lcRealized = mvar
66 , lcUploadState = uploadState logo glarea
67 , lcDestroyState = destroyState glarea
68 , lcSetUniforms = setUniforms
69 , lcPipeline = pipeline
70 }
71
72 runGLApp return (lambdaRender app glmethods)
73
74-- geometry data: triangles
75triangleA :: LC.Mesh
76triangleA = Mesh
77 { mAttributes = Map.fromList
78 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
79 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
80 ]
81 , mPrimitive = P_Triangles
82 }
83
84triangleB :: LC.Mesh
85triangleB = Mesh
86 { mAttributes = Map.fromList
87 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
88 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
89 ]
90 , mPrimitive = P_Triangles
91 }
92