summaryrefslogtreecommitdiff
path: root/examples/HelloEmbedded.hs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/HelloEmbedded.hs')
-rw-r--r--examples/HelloEmbedded.hs99
1 files changed, 99 insertions, 0 deletions
diff --git a/examples/HelloEmbedded.hs b/examples/HelloEmbedded.hs
new file mode 100644
index 0000000..fbddb20
--- /dev/null
+++ b/examples/HelloEmbedded.hs
@@ -0,0 +1,99 @@
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 LambdaCube.Compiler as LambdaCube -- compiler
12
13main :: IO ()
14main = do
15 -- compile hello.lc to graphics pipeline description
16 pipelineDesc <- LambdaCube.compileMain ["."] OpenGL33 "hello" >>= \case
17 Left err -> fail $ "compile error:\n" ++ err
18 Right pd -> return pd
19
20 win <- initWindow "LambdaCube 3D DSL Hello World" 640 640
21
22 -- setup render data
23 let inputSchema = makeSchema $ do
24 defObjectArray "objects" Triangles $ do
25 "position" @: Attribute_V2F
26 "uv" @: Attribute_V2F
27 defUniforms $ do
28 "time" @: Float
29 "diffuseTexture" @: FTexture2D
30
31 storage <- LambdaCubeGL.allocStorage inputSchema
32
33 -- upload geometry to GPU and add to pipeline input
34 LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
35 LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
36
37 -- load image and upload texture
38 Right img <- Juicy.readImage "logo.png"
39 textureData <- LambdaCubeGL.uploadTexture2DToGPU img
40
41 -- allocate GL pipeline
42 renderer <- LambdaCubeGL.allocRenderer pipelineDesc
43 LambdaCubeGL.setStorage renderer storage >>= \case -- check schema compatibility
44 Just err -> putStrLn err
45 Nothing -> loop
46 where loop = do
47 -- update graphics input
48 GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h)
49 LambdaCubeGL.updateUniforms storage $ do
50 "diffuseTexture" @= return textureData
51 "time" @= do
52 Just t <- GLFW.getTime
53 return (realToFrac t :: Float)
54 -- render
55 LambdaCubeGL.renderFrame renderer
56 GLFW.swapBuffers win
57 GLFW.pollEvents
58
59 let keyIsPressed k = fmap (==KeyState'Pressed) $ GLFW.getKey win k
60 escape <- keyIsPressed Key'Escape
61 if escape then return () else loop
62
63 LambdaCubeGL.disposeRenderer renderer
64 LambdaCubeGL.disposeStorage storage
65 GLFW.destroyWindow win
66 GLFW.terminate
67
68-- geometry data: triangles
69triangleA :: LambdaCubeGL.Mesh
70triangleA = Mesh
71 { mAttributes = Map.fromList
72 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
73 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
74 ]
75 , mPrimitive = P_Triangles
76 }
77
78triangleB :: LambdaCubeGL.Mesh
79triangleB = Mesh
80 { mAttributes = Map.fromList
81 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
82 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
83 ]
84 , mPrimitive = P_Triangles
85 }
86
87initWindow :: String -> Int -> Int -> IO Window
88initWindow title width height = do
89 GLFW.init
90 GLFW.defaultWindowHints
91 mapM_ GLFW.windowHint
92 [ WindowHint'ContextVersionMajor 3
93 , WindowHint'ContextVersionMinor 3
94 , WindowHint'OpenGLProfile OpenGLProfile'Core
95 , WindowHint'OpenGLForwardCompat True
96 ]
97 Just win <- GLFW.createWindow width height title Nothing Nothing
98 GLFW.makeContextCurrent $ Just win
99 return win