diff options
-rw-r--r-- | examples/Hello.hs | 43 | ||||
-rw-r--r-- | examples/Panels_Diffuse.png | bin | 0 -> 490310 bytes | |||
-rw-r--r-- | examples/hello.lc | 12 | ||||
-rw-r--r-- | src/LambdaCube/GL.hs | 13 | ||||
-rw-r--r-- | src/LambdaCube/GL/Backend.hs | 10 | ||||
-rw-r--r-- | src/LambdaCube/GL/Input.hs | 33 |
6 files changed, 65 insertions, 46 deletions
diff --git a/examples/Hello.hs b/examples/Hello.hs index cfe1053..5918d88 100644 --- a/examples/Hello.hs +++ b/examples/Hello.hs | |||
@@ -1,4 +1,4 @@ | |||
1 | {-# LANGUAGE PackageImports, LambdaCase #-} | 1 | {-# LANGUAGE PackageImports, LambdaCase, OverloadedStrings #-} |
2 | {-# LANGUAGE FlexibleContexts #-} | 2 | {-# LANGUAGE FlexibleContexts #-} |
3 | import "GLFW-b" Graphics.UI.GLFW as GLFW | 3 | import "GLFW-b" Graphics.UI.GLFW as GLFW |
4 | import qualified Data.Map as Map | 4 | import qualified Data.Map as Map |
@@ -11,39 +11,6 @@ import Codec.Picture as Juicy | |||
11 | 11 | ||
12 | import LambdaCube.Compiler.Driver as LambdaCube -- compiler | 12 | import LambdaCube.Compiler.Driver as LambdaCube -- compiler |
13 | 13 | ||
14 | ---- | ||
15 | import Control.Monad.Writer | ||
16 | |||
17 | {- | ||
18 | data ObjectArraySchema | ||
19 | = ObjectArraySchema | ||
20 | { primitive :: FetchPrimitive | ||
21 | , attributes :: Map String StreamType | ||
22 | } | ||
23 | deriving Show | ||
24 | |||
25 | data PipelineSchema | ||
26 | = PipelineSchema | ||
27 | { objectArrays :: Map String ObjectArraySchema | ||
28 | , uniforms :: Map String InputType | ||
29 | } | ||
30 | -} | ||
31 | |||
32 | |||
33 | a @: b = tell [(a,b)] | ||
34 | defObjectArray n p m = tell [PipelineSchema (Map.singleton n $ ObjectArraySchema p $ Map.fromList $ execWriter m) mempty] | ||
35 | defUniforms m = tell [PipelineSchema mempty $ Map.fromList $ execWriter m] | ||
36 | makeSchema a = head $ execWriter a :: PipelineSchema | ||
37 | |||
38 | sch = makeSchema $ do | ||
39 | defObjectArray "objects" Triangles $ do | ||
40 | "position" @: Attribute_V4F | ||
41 | "uv" @: Attribute_V2F | ||
42 | defUniforms $ do | ||
43 | "time" @: Float | ||
44 | "diffuseTexture" @: FTexture2D | ||
45 | |||
46 | ----- | ||
47 | main :: IO () | 14 | main :: IO () |
48 | main = do | 15 | main = do |
49 | -- compile hello.lc to graphics pipeline description | 16 | -- compile hello.lc to graphics pipeline description |
@@ -56,7 +23,7 @@ main = do | |||
56 | -- setup render data | 23 | -- setup render data |
57 | let inputSchema = makeSchema $ do | 24 | let inputSchema = makeSchema $ do |
58 | defObjectArray "objects" Triangles $ do | 25 | defObjectArray "objects" Triangles $ do |
59 | "position" @: Attribute_V4F | 26 | "position" @: Attribute_V2F |
60 | "uv" @: Attribute_V2F | 27 | "uv" @: Attribute_V2F |
61 | defUniforms $ do | 28 | defUniforms $ do |
62 | "time" @: Float | 29 | "time" @: Float |
@@ -80,11 +47,11 @@ main = do | |||
80 | where loop = do | 47 | where loop = do |
81 | -- update graphics input | 48 | -- update graphics input |
82 | GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h) | 49 | GLFW.getWindowSize win >>= \(w,h) -> LambdaCubeGL.setScreenSize storage (fromIntegral w) (fromIntegral h) |
83 | {- | ||
84 | LambdaCubeGL.updateUniforms storage $ do | 50 | LambdaCubeGL.updateUniforms storage $ do |
85 | "time" @= fromJust <$> GLFW.getTime | ||
86 | "diffuseTexture" @= return textureData | 51 | "diffuseTexture" @= return textureData |
87 | -} | 52 | "time" @= do |
53 | Just t <- GLFW.getTime | ||
54 | return (realToFrac t :: Float) | ||
88 | -- render | 55 | -- render |
89 | LambdaCubeGL.renderFrame renderer | 56 | LambdaCubeGL.renderFrame renderer |
90 | GLFW.swapBuffers win | 57 | GLFW.swapBuffers win |
diff --git a/examples/Panels_Diffuse.png b/examples/Panels_Diffuse.png new file mode 100644 index 0000000..15b242c --- /dev/null +++ b/examples/Panels_Diffuse.png | |||
Binary files differ | |||
diff --git a/examples/hello.lc b/examples/hello.lc new file mode 100644 index 0000000..1087fbe --- /dev/null +++ b/examples/hello.lc | |||
@@ -0,0 +1,12 @@ | |||
1 | sampler = Sampler PointFilter MirroredRepeat (Texture2DSlot "diffuseTexture") | ||
2 | main = let | ||
3 | emptyFB = FrameBuffer (colorImage1 (V4 0.0 0.0 0.4 1.0)) | ||
4 | rasterCtx = TriangleCtx CullNone PolygonFill NoOffset LastVertex | ||
5 | fragmentCtx = AccumulationContext (ColorOp NoBlending (V4 True True True True)) | ||
6 | vertexShader (p,uv) = VertexOut (V4 p%x p%y (-1) 1) 1.0 () (Smooth uv) | ||
7 | vertexStream = Fetch "objects" Triangles (Attribute "position" :: Vec 2 Float, Attribute "uv" :: Vec 2 Float) | ||
8 | primitiveStream = Transform vertexShader vertexStream | ||
9 | fragmentStream = Rasterize rasterCtx primitiveStream | ||
10 | fragmentShader uv = FragmentOut $ texture2D sampler uv | ||
11 | frame = Accumulate fragmentCtx PassAll fragmentShader fragmentStream emptyFB | ||
12 | in ScreenOut frame | ||
diff --git a/src/LambdaCube/GL.hs b/src/LambdaCube/GL.hs index 3e11be1..258d2ba 100644 --- a/src/LambdaCube/GL.hs +++ b/src/LambdaCube/GL.hs | |||
@@ -28,6 +28,7 @@ module LambdaCube.GL ( | |||
28 | uploadTexture2DToGPU', | 28 | uploadTexture2DToGPU', |
29 | 29 | ||
30 | -- GL: Renderer, Storage, Object | 30 | -- GL: Renderer, Storage, Object |
31 | GLUniformName, | ||
31 | GLRenderer, | 32 | GLRenderer, |
32 | GLStorage, | 33 | GLStorage, |
33 | Object, | 34 | Object, |
@@ -48,7 +49,6 @@ module LambdaCube.GL ( | |||
48 | setObjectOrder, | 49 | setObjectOrder, |
49 | objectUniformSetter, | 50 | objectUniformSetter, |
50 | setScreenSize, | 51 | setScreenSize, |
51 | sortSlotObjects, | ||
52 | 52 | ||
53 | uniformBool, | 53 | uniformBool, |
54 | uniformV2B, | 54 | uniformV2B, |
@@ -80,7 +80,16 @@ module LambdaCube.GL ( | |||
80 | uniformM43F, | 80 | uniformM43F, |
81 | uniformM44F, | 81 | uniformM44F, |
82 | 82 | ||
83 | uniformFTexture2D | 83 | uniformFTexture2D, |
84 | |||
85 | -- schema builder utility functions | ||
86 | (@:), | ||
87 | defObjectArray, | ||
88 | defUniforms, | ||
89 | makeSchema, | ||
90 | |||
91 | (@=), | ||
92 | updateUniforms | ||
84 | ) where | 93 | ) where |
85 | 94 | ||
86 | import LambdaCube.GL.Type | 95 | import LambdaCube.GL.Type |
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs index 2753ac3..677e925 100644 --- a/src/LambdaCube/GL/Backend.hs +++ b/src/LambdaCube/GL/Backend.hs | |||
@@ -696,12 +696,12 @@ renderSlot cmds = forM_ cmds $ \cmd -> do | |||
696 | texUnit <- readIORef tuRef | 696 | texUnit <- readIORef tuRef |
697 | glActiveTexture $ GL_TEXTURE0 + fromIntegral texUnit | 697 | glActiveTexture $ GL_TEXTURE0 + fromIntegral texUnit |
698 | glBindTexture txTarget txObj | 698 | glBindTexture txTarget txObj |
699 | putStrLn $ "to texture unit " ++ show texUnit ++ " texture object " ++ show txObj | 699 | --putStrLn $ "to texture unit " ++ show texUnit ++ " texture object " ++ show txObj |
700 | GLSetVertexAttrib idx val -> do | 700 | GLSetVertexAttrib idx val -> do |
701 | glDisableVertexAttribArray idx | 701 | glDisableVertexAttribArray idx |
702 | setVertexAttrib idx val | 702 | setVertexAttrib idx val |
703 | isOk <- checkGL | 703 | --isOk <- checkGL |
704 | putStrLn $ isOk ++ " - " ++ show cmd | 704 | --putStrLn $ isOk ++ " - " ++ show cmd |
705 | 705 | ||
706 | renderFrame :: GLRenderer -> IO () | 706 | renderFrame :: GLRenderer -> IO () |
707 | renderFrame glp = do | 707 | renderFrame glp = do |
@@ -750,8 +750,8 @@ renderFrame glp = do | |||
750 | GLSaveImage | 750 | GLSaveImage |
751 | GLLoadImage | 751 | GLLoadImage |
752 | -} | 752 | -} |
753 | isOk <- checkGL | 753 | --isOk <- checkGL |
754 | putStrLn $ isOk ++ " - " ++ show cmd | 754 | --putStrLn $ isOk ++ " - " ++ show cmd |
755 | 755 | ||
756 | data CGState | 756 | data CGState |
757 | = CGState | 757 | = CGState |
diff --git a/src/LambdaCube/GL/Input.hs b/src/LambdaCube/GL/Input.hs index 742fc35..7e4ba74 100644 --- a/src/LambdaCube/GL/Input.hs +++ b/src/LambdaCube/GL/Input.hs | |||
@@ -1,8 +1,10 @@ | |||
1 | {-# LANGUAGE FlexibleContexts #-} | ||
1 | module LambdaCube.GL.Input where | 2 | module LambdaCube.GL.Input where |
2 | 3 | ||
3 | import Control.Applicative | 4 | import Control.Applicative |
4 | import Control.Exception | 5 | import Control.Exception |
5 | import Control.Monad | 6 | import Control.Monad |
7 | import Control.Monad.Writer | ||
6 | import Data.IORef | 8 | import Data.IORef |
7 | import Data.Map (Map) | 9 | import Data.Map (Map) |
8 | import Data.IntMap (IntMap) | 10 | import Data.IntMap (IntMap) |
@@ -68,7 +70,7 @@ allocStorage sch = do | |||
68 | } | 70 | } |
69 | 71 | ||
70 | disposeStorage :: GLStorage -> IO () | 72 | disposeStorage :: GLStorage -> IO () |
71 | disposeStorage = error "not implemented: disposeStorage" | 73 | disposeStorage _ = putStrLn "not implemented: disposeStorage" |
72 | 74 | ||
73 | -- object | 75 | -- object |
74 | addObject :: GLStorage -> String -> Primitive -> Maybe (IndexStream Buffer) -> Map String (Stream Buffer) -> [String] -> IO Object | 76 | addObject :: GLStorage -> String -> Primitive -> Maybe (IndexStream Buffer) -> Map String (Stream Buffer) -> [String] -> IO Object |
@@ -137,6 +139,7 @@ addObject input slotName prim indices attribs uniformNames = do | |||
137 | let emptyV = V.replicate (V.length $ glPrograms p) [] | 139 | let emptyV = V.replicate (V.length $ glPrograms p) [] |
138 | return $ emptyV // [(prgIdx,createObjectCommands (glTexUnitMapping p) topUnis obj (glPrograms p ! prgIdx))| prgIdx <- glSlotPrograms p ! pSlotIdx] | 140 | return $ emptyV // [(prgIdx,createObjectCommands (glTexUnitMapping p) topUnis obj (glPrograms p ! prgIdx))| prgIdx <- glSlotPrograms p ! pSlotIdx] |
139 | writeIORef cmdsRef cmds | 141 | writeIORef cmdsRef cmds |
142 | sortSlotObjects input | ||
140 | return obj | 143 | return obj |
141 | 144 | ||
142 | removeObject :: GLStorage -> Object -> IO () | 145 | removeObject :: GLStorage -> Object -> IO () |
@@ -149,6 +152,7 @@ setObjectOrder :: GLStorage -> Object -> Int -> IO () | |||
149 | setObjectOrder p obj i = do | 152 | setObjectOrder p obj i = do |
150 | writeIORef (objOrder obj) i | 153 | writeIORef (objOrder obj) i |
151 | modifyIORef (slotVector p ! objSlot obj) $ \(GLSlot objs sorted _) -> GLSlot objs sorted Reorder | 154 | modifyIORef (slotVector p ! objSlot obj) $ \(GLSlot objs sorted _) -> GLSlot objs sorted Reorder |
155 | sortSlotObjects p | ||
152 | 156 | ||
153 | objectUniformSetter :: Object -> Map GLUniformName InputSetter | 157 | objectUniformSetter :: Object -> Map GLUniformName InputSetter |
154 | objectUniformSetter = objUniSetter | 158 | objectUniformSetter = objUniSetter |
@@ -387,3 +391,30 @@ uniformM44F n is = case Map.lookup n is of | |||
387 | uniformFTexture2D n is = case Map.lookup n is of | 391 | uniformFTexture2D n is = case Map.lookup n is of |
388 | Just (SFTexture2D fun) -> fun | 392 | Just (SFTexture2D fun) -> fun |
389 | _ -> nullSetter n "FTexture2D" | 393 | _ -> nullSetter n "FTexture2D" |
394 | |||
395 | a @: b = tell [(a,b)] | ||
396 | defObjectArray n p m = mapM_ tell [PipelineSchema (Map.singleton n $ ObjectArraySchema p $ Map.singleton a t) mempty | (a,t) <- execWriter m] | ||
397 | defUniforms m = tell $ PipelineSchema mempty $ Map.fromList $ execWriter m | ||
398 | makeSchema a = execWriter a :: PipelineSchema | ||
399 | |||
400 | unionObjectArraySchema (ObjectArraySchema a1 b1) (ObjectArraySchema a2 b2) = | ||
401 | ObjectArraySchema (if a1 == a2 then a1 else error $ "object array schema primitive mismatch " ++ show (a1,a2)) | ||
402 | (Map.unionWith (\a b -> if a == b then a else error $ "object array schema attribute type mismatch " ++ show (a,b)) b1 b2) | ||
403 | |||
404 | instance Monoid PipelineSchema where | ||
405 | mempty = PipelineSchema mempty mempty | ||
406 | mappend (PipelineSchema a1 b1) (PipelineSchema a2 b2) = | ||
407 | PipelineSchema (Map.unionWith unionObjectArraySchema a1 a2) (Map.unionWith (\a b -> if a == b then a else error $ "schema type mismatch " ++ show (a,b)) b1 b2) | ||
408 | |||
409 | type UniM = Writer [GLStorage -> IO ()] | ||
410 | |||
411 | class UniformSetter a where | ||
412 | (@=) :: GLUniformName -> IO a -> UniM () | ||
413 | |||
414 | instance UniformSetter Float where | ||
415 | n @= act = tell [\s -> let f = uniformFloat n (uniformSetter s) in f =<< act] | ||
416 | |||
417 | instance UniformSetter TextureData where | ||
418 | n @= act = tell [\s -> let f = uniformFTexture2D n (uniformSetter s) in f =<< act] | ||
419 | |||
420 | updateUniforms storage m = sequence_ $ let l = map ($ storage) $ execWriter m in l | ||