summaryrefslogtreecommitdiff
path: root/Hello-glfw.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-07 02:53:16 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-07 02:53:16 -0400
commit483ffac7da055342598b44800e69ee5217cb47cd (patch)
treef2c5780ea4bbcbfd443a3c77cd789d34905e2d90 /Hello-glfw.hs
initial commit
Diffstat (limited to 'Hello-glfw.hs')
-rw-r--r--Hello-glfw.hs101
1 files changed, 101 insertions, 0 deletions
diff --git a/Hello-glfw.hs b/Hello-glfw.hs
new file mode 100644
index 0000000..c93136b
--- /dev/null
+++ b/Hello-glfw.hs
@@ -0,0 +1,101 @@
1{-# LANGUAGE PackageImports, LambdaCase, OverloadedStrings #-}
2import "GLFW-b" Graphics.UI.GLFW as GLFW
3import qualified Data.Map as Map
4import qualified Data.Vector as V
5
6import LambdaCube.GL as LambdaCubeGL -- renderer
7import LambdaCube.GL.Mesh as LambdaCubeGL
8
9import Codec.Picture as Juicy
10
11import Data.Aeson
12import qualified Data.ByteString as SB
13
14----------------------------------------------------
15-- See: http://lambdacube3d.com/getting-started
16----------------------------------------------------
17
18main :: IO ()
19main = do
20 Just pipelineDesc <- decodeStrict <$> SB.readFile "hello.json"
21
22 win <- initWindow "LambdaCube 3D DSL Hello World" 640 640
23
24 -- setup render data
25 let inputSchema = makeSchema $ do
26 defObjectArray "objects" Triangles $ do
27 "position" @: Attribute_V2F
28 "uv" @: Attribute_V2F
29 defUniforms $ do
30 "time" @: Float
31 "diffuseTexture" @: FTexture2D
32
33 storage <- LambdaCubeGL.allocStorage inputSchema
34
35 -- upload geometry to GPU and add to pipeline input
36 LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
37 LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
38
39 -- load image and upload texture
40 Right img <- Juicy.readImage "logo.png"
41 textureData <- LambdaCubeGL.uploadTexture2DToGPU img
42
43 -- allocate GL pipeline
44 renderer <- LambdaCubeGL.allocRenderer pipelineDesc
45 LambdaCubeGL.setStorage renderer storage >>= \case -- check schema compatibility
46 Just err -> putStrLn err
47 Nothing -> loop
48 where loop = do
49 -- update graphics input
50 GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h)
51 LambdaCubeGL.updateUniforms storage $ do
52 "diffuseTexture" @= return textureData
53 "time" @= do
54 Just t <- GLFW.getTime
55 return (realToFrac t :: Float)
56 -- render
57 LambdaCubeGL.renderFrame renderer
58 GLFW.swapBuffers win
59 GLFW.pollEvents
60
61 let keyIsPressed k = fmap (==KeyState'Pressed) $ GLFW.getKey win k
62 escape <- keyIsPressed Key'Escape
63 if escape then return () else loop
64
65 LambdaCubeGL.disposeRenderer renderer
66 LambdaCubeGL.disposeStorage storage
67 GLFW.destroyWindow win
68 GLFW.terminate
69
70-- geometry data: triangles
71triangleA :: LambdaCubeGL.Mesh
72triangleA = Mesh
73 { mAttributes = Map.fromList
74 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
75 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
76 ]
77 , mPrimitive = P_Triangles
78 }
79
80triangleB :: LambdaCubeGL.Mesh
81triangleB = Mesh
82 { mAttributes = Map.fromList
83 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
84 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
85 ]
86 , mPrimitive = P_Triangles
87 }
88
89initWindow :: String -> Int -> Int -> IO Window
90initWindow title width height = do
91 GLFW.init
92 GLFW.defaultWindowHints
93 mapM_ GLFW.windowHint
94 [ WindowHint'ContextVersionMajor 3
95 , WindowHint'ContextVersionMinor 3
96 , WindowHint'OpenGLProfile OpenGLProfile'Core
97 , WindowHint'OpenGLForwardCompat True
98 ]
99 Just win <- GLFW.createWindow width height title Nothing Nothing
100 GLFW.makeContextCurrent $ Just win
101 return win