summaryrefslogtreecommitdiff
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
initial commit
-rw-r--r--GtkHello.hs46
-rw-r--r--Hello-glfw.hs101
-rw-r--r--Hello-glut.hs129
-rw-r--r--Tut.hs32
-rw-r--r--hello.json1
-rw-r--r--hello.lc16
6 files changed, 325 insertions, 0 deletions
diff --git a/GtkHello.hs b/GtkHello.hs
new file mode 100644
index 0000000..9b29ba7
--- /dev/null
+++ b/GtkHello.hs
@@ -0,0 +1,46 @@
1{-# LANGUAGE OverloadedLabels #-}
2{-# LANGUAGE OverloadedLists #-}
3{-# LANGUAGE OverloadedStrings #-}
4module Main where
5
6import qualified GI.Gtk as Gtk
7import GI.Gtk.Declarative
8import GI.Gtk.Declarative.App.Simple
9
10import qualified Data.Map as Map
11import qualified Data.Vector as V
12
13import LambdaCube.GL as LambdaCubeGL -- renderer
14import LambdaCube.GL.Mesh as LambdaCubeGL
15
16import Codec.Picture as Juicy
17
18import Data.Aeson
19import qualified Data.ByteString as SB
20
21type State = ()
22
23data Event = Closed
24
25view' :: State -> AppView Gtk.Window Event
26view' _ = bin
27 Gtk.Window
28 [ #title := "LambdaCube 3D DSL Hello World"
29 , on #deleteEvent $ {- GI.Gdk.Unions.Event.Event -> (Bool, Event) -} \_ -> (True,Closed)
30 ]
31 $ widget Gtk.Label [#label := "Hello, World!"]
32
33update' :: State -> Event -> Transition State Event
34update' _ Closed = Exit
35
36main :: IO ()
37main = do
38 Just pipelineDesc <- decodeStrict <$> SB.readFile "hello.json"
39
40 run App
41 -- :: App Gtk.Window State Event
42 { view = view'
43 , update = update'
44 , inputs = []
45 , initialState = ()
46 }
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
diff --git a/Hello-glut.hs b/Hello-glut.hs
new file mode 100644
index 0000000..9ffa92c
--- /dev/null
+++ b/Hello-glut.hs
@@ -0,0 +1,129 @@
1{-# LANGUAGE PackageImports, LambdaCase, OverloadedStrings #-}
2import Control.Concurrent
3
4-- import "GLFW-b" Graphics.UI.GLFW as GLFW
5import qualified Graphics.UI.GLUT as GLFW -- lie
6import qualified Graphics.UI.GLUT as GLUT -- truth
7import Graphics.UI.GLUT (Window)
8import qualified Data.Map as Map
9import qualified Data.Vector as V
10
11import LambdaCube.GL as LambdaCubeGL -- renderer
12import LambdaCube.GL.Mesh as LambdaCubeGL
13
14import Codec.Picture as Juicy
15
16import Data.Aeson
17import qualified Data.ByteString as SB
18
19----------------------------------------------------
20-- See: http://lambdacube3d.com/getting-started
21----------------------------------------------------
22
23main :: IO ()
24main = do
25 Just pipelineDesc <- decodeStrict <$> SB.readFile "hello.json"
26
27 win <- initWindow "LambdaCube 3D DSL Hello World" 640 640
28
29 -- setup render data
30 let inputSchema = makeSchema $ do
31 defObjectArray "objects" Triangles $ do
32 "position" @: Attribute_V2F
33 "uv" @: Attribute_V2F
34 defUniforms $ do
35 "time" @: Float
36 "diffuseTexture" @: FTexture2D
37
38 storage <- LambdaCubeGL.allocStorage inputSchema
39
40 -- upload geometry to GPU and add to pipeline input
41 LambdaCubeGL.uploadMeshToGPU triangleA >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
42 LambdaCubeGL.uploadMeshToGPU triangleB >>= LambdaCubeGL.addMeshToObjectArray storage "objects" []
43
44 -- load image and upload texture
45 Right img <- Juicy.readImage "logo.png"
46 textureData <- LambdaCubeGL.uploadTexture2DToGPU img
47
48 -- allocate GL pipeline
49 renderer <- LambdaCubeGL.allocRenderer pipelineDesc
50 LambdaCubeGL.setStorage renderer storage >>= \case -- check schema compatibility
51 Just err -> putStrLn err
52 Nothing -> do qsig <- newMVar False
53 GLUT.keyboardMouseCallback GLUT.$= Just (keyCB qsig)
54 loop qsig
55 where loop qsig = do
56 -- update graphics input
57 -- GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h)
58 GLUT.get GLUT.windowSize >>= \(GLUT.Size w h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h)
59 LambdaCubeGL.updateUniforms storage $ do
60 "diffuseTexture" @= return textureData
61 "time" @= do
62 -- Just t <- GLFW.getTime
63 Just t <- Just . (* (1000.0 :: Double)) . fromIntegral <$> GLUT.elapsedTime
64 return (realToFrac t :: Float)
65 -- render
66 LambdaCubeGL.renderFrame renderer
67 -- GLFW.swapBuffers win
68 GLUT.swapBuffers
69 -- GLFW.pollEvents
70 GLUT.mainLoopEvent
71
72 -- let keyIsPressed k = fmap (==KeyState'Pressed) $ GLFW.getKey win k
73 -- escape <- keyIsPressed Key'Escape
74 escape <- withMVar qsig return
75 if escape then return () else loop qsig
76
77 keyCB :: MVar Bool -> GLUT.KeyboardMouseCallback
78 keyCB qsig key keyState mods pos= do
79 cw <- GLUT.get GLUT.currentWindow
80 case (keyState,key,cw) of
81 (GLUT.Down,GLUT.Char 'q',Just cw) -> do
82 modifyMVar_ qsig (const $ return True)
83 GLUT.destroyWindow cw
84 (GLUT.Down,_,_)-> GLUT.postRedisplay Nothing
85 _ -> return ()
86
87 LambdaCubeGL.disposeRenderer renderer
88 LambdaCubeGL.disposeStorage storage
89 GLFW.destroyWindow win
90 -- GLFW.terminate
91
92-- geometry data: triangles
93triangleA :: LambdaCubeGL.Mesh
94triangleA = Mesh
95 { mAttributes = Map.fromList
96 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
97 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
98 ]
99 , mPrimitive = P_Triangles
100 }
101
102triangleB :: LambdaCubeGL.Mesh
103triangleB = Mesh
104 { mAttributes = Map.fromList
105 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
106 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
107 ]
108 , mPrimitive = P_Triangles
109 }
110
111initWindow :: String -> Int -> Int -> IO Window
112initWindow title width height = do
113 {-
114 GLFW.init
115 GLFW.defaultWindowHints
116 mapM_ GLFW.windowHint
117 [ WindowHint'ContextVersionMajor 3
118 , WindowHint'ContextVersionMinor 3
119 , WindowHint'OpenGLProfile OpenGLProfile'Core
120 , WindowHint'OpenGLForwardCompat True
121 ]
122 Just win <- GLFW.createWindow width height title Nothing Nothing
123 GLFW.makeContextCurrent $ Just win
124 -}
125 (progname,args) <- GLUT.getArgsAndInitialize
126 win <- GLUT.createWindow title
127 GLUT.actionOnWindowClose GLUT.$=! GLUT.MainLoopReturns
128 return win
129
diff --git a/Tut.hs b/Tut.hs
new file mode 100644
index 0000000..0ae5494
--- /dev/null
+++ b/Tut.hs
@@ -0,0 +1,32 @@
1{-# LANGUAGE OverloadedLabels #-}
2{-# LANGUAGE OverloadedLists #-}
3{-# LANGUAGE OverloadedStrings #-}
4module Main where
5
6import qualified GI.Gtk as Gtk
7import GI.Gtk.Declarative
8import GI.Gtk.Declarative.App.Simple
9
10type State = ()
11
12data Event = Closed
13
14view' :: State -> AppView Gtk.Window Event
15view' _ = bin
16 Gtk.Window
17 [ #title := "Demo"
18 , on #deleteEvent $ {- GI.Gdk.Unions.Event.Event -> (Bool, Event) -} \_ -> (True,Closed)
19 ]
20 $ widget Gtk.Label [#label := "Hello, World!"]
21
22update' :: State -> Event -> Transition State Event
23update' _ Closed = Exit
24
25main :: IO ()
26main = run App
27 -- :: App Gtk.Window State Event
28 { view = view'
29 , update = update'
30 , inputs = []
31 , initialState = ()
32 }
diff --git a/hello.json b/hello.json
new file mode 100644
index 0000000..22f3ff1
--- /dev/null
+++ b/hello.json
@@ -0,0 +1 @@
{"textures":[],"commands":[{"tag":"SetRenderTarget","arg0":0},{"tag":"ClearRenderTarget","arg0":[{"tag":"ClearImage","clearValue":{"tag":"VV4F","arg0":{"w":1,"z":0.4,"x":0.0,"y":0.0}},"imageSemantic":{"tag":"Color"}}]},{"tag":"SetProgram","arg0":0},{"tag":"SetSamplerUniform","arg0":"diffuseTexture","arg1":0},{"tag":"SetRasterContext","arg0":{"arg3":{"tag":"LastVertex"},"tag":"TriangleCtx","arg0":{"tag":"CullNone"},"arg1":{"tag":"PolygonFill"},"arg2":{"tag":"NoOffset"}}},{"tag":"SetAccumulationContext","arg0":{"accViewportName":null,"tag":"AccumulationContext","accOperations":[{"tag":"ColorOp","arg0":{"tag":"NoBlending"},"arg1":{"tag":"VV4B","arg0":{"w":true,"z":true,"x":true,"y":true}}}]}},{"tag":"RenderSlot","arg0":0}],"slots":[{"tag":"Slot","slotPrimitive":{"tag":"Triangles"},"slotStreams":{"uv":{"tag":"V2F"},"position":{"tag":"V2F"}},"slotName":"objects","slotUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}},"slotPrograms":[0]}],"programs":[{"programInTextures":{"diffuseTexture":{"tag":"FTexture2D"}},"tag":"Program","programOutput":[{"tag":"Parameter","ty":{"tag":"V4F"},"name":"f0"}],"programStreams":{"vi2":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"uv"},"vi1":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"position"}},"fragmentShader":"#version 330 core\nvec4 texture2D(sampler2D s\n ,vec2 uv) {\n return texture(s,uv);\n}\nuniform sampler2D diffuseTexture;\nsmooth in vec2 vo1;\nout vec4 f0;\nvoid main() {\n f0 = texture2D (diffuseTexture\n ,vo1);\n}","vertexShader":"#version 330 core\nvec4 texture2D(sampler2D s\n ,vec2 uv) {\n return texture(s,uv);\n}\nuniform float time;\nin vec2 vi1;\nin vec2 vi2;\nsmooth out vec2 vo1;\nmat4 rotMatrixZ(float z0) {\n return mat4 (vec4 (cos (z0)\n ,sin (z0)\n ,0.0\n ,0.0)\n ,vec4 ((0.0) - (sin (z0))\n ,cos (z0)\n ,0.0\n ,0.0)\n ,vec4 (0.0,0.0,1.0,0.0)\n ,vec4 (0.0,0.0,0.0,1.0));\n}\nvoid main() {\n gl_Position = (rotMatrixZ\n (time)) * (vec4 ((vi1).x\n ,(vi1).y\n ,-1.0\n ,1.0));\n vo1 = vi2;\n}","geometryShader":null,"programUniforms":{"time":{"tag":"Float"},"diffuseTexture":{"tag":"FTexture2D"}}}],"samplers":[],"tag":"Pipeline","backend":{"tag":"OpenGL33"},"streams":[],"targets":[{"tag":"RenderTarget","renderTargets":[{"tag":"TargetItem","targetSemantic":{"tag":"Color"},"targetRef":{"tag":"Framebuffer","arg0":{"tag":"Color"}}}]}],"info":"generated by lambdacube-compiler 0.5.0.0"} \ No newline at end of file
diff --git a/hello.lc b/hello.lc
new file mode 100644
index 0000000..5837a82
--- /dev/null
+++ b/hello.lc
@@ -0,0 +1,16 @@
1makeFrame (time :: Float)
2 (texture :: Texture)
3 (prims :: PrimitiveStream Triangle (Vec 2 Float, Vec 2 Float))
4
5 = imageFrame ((emptyColorImage (V4 0 0 0.4 1)))
6 `overlay`
7 prims
8 & mapPrimitives (\(p,uv) -> (rotMatrixZ time *. (V4 p%x p%y (-1) 1), uv))
9 & rasterizePrimitives (TriangleCtx CullNone PolygonFill NoOffset LastVertex) ((Smooth))
10 & mapFragments (\((uv)) -> ((texture2D (Sampler PointFilter MirroredRepeat texture) uv)))
11 & accumulateWith ((ColorOp NoBlending (V4 True True True True)))
12
13main = renderFrame $
14 makeFrame (Uniform "time")
15 (Texture2DSlot "diffuseTexture")
16 (fetch "objects" (Attribute "position", Attribute "uv"))