summaryrefslogtreecommitdiff
path: root/backendtest
diff options
context:
space:
mode:
authorCsaba Hruska <csaba.hruska@gmail.com>2016-02-13 12:57:24 +0100
committerCsaba Hruska <csaba.hruska@gmail.com>2016-02-13 12:58:19 +0100
commit203b47f9f54090cecb8624d7d2fb2a4e10de2c9b (patch)
tree4b03ddaaca9695cfae47db7477972db489583e36 /backendtest
parent7ea1b33b2ec58fe08070dc7762ffcfa6b71c07d0 (diff)
add editor examples to backend test system
Diffstat (limited to 'backendtest')
-rw-r--r--backendtest/EditorExamplesTest.hs227
-rw-r--r--backendtest/TestData.hs33
-rw-r--r--backendtest/hello.json1
-rw-r--r--backendtest/logo.pngbin126891 -> 0 bytes
-rw-r--r--backendtest/logo256x256.pngbin0 -> 35777 bytes
-rw-r--r--backendtest/server.hs65
6 files changed, 271 insertions, 55 deletions
diff --git a/backendtest/EditorExamplesTest.hs b/backendtest/EditorExamplesTest.hs
new file mode 100644
index 00000000..2fe861c2
--- /dev/null
+++ b/backendtest/EditorExamplesTest.hs
@@ -0,0 +1,227 @@
1{-# LANGUAGE LambdaCase #-}
2module EditorExamplesTest (getRenderJob) where
3
4import Control.Monad
5import qualified Data.Vector as V
6import qualified Data.Map as Map
7import qualified Data.ByteString as BS
8import qualified Data.ByteString.Base64 as B64
9import Data.ByteString.Char8 (unpack)
10import System.FilePath
11import System.Directory
12
13import Data.Aeson
14import Data.Vect
15
16import TestData as TD
17import LambdaCube.Linear
18import LambdaCube.IR
19import LambdaCube.PipelineSchema
20import LambdaCube.PipelineSchemaUtil
21import LambdaCube.Mesh
22
23import LambdaCube.Compiler as LambdaCube -- compiler
24
25{-
26 ../test-data/editor-examples
27
28 let inputSchema =
29 { slots : fromArray [ Tuple "stream4" {primitive: Triangles, attributes: fromArray [Tuple "position4" TV4F, Tuple "vertexUV" TV2F]}
30 ]
31 , uniforms : fromArray
32 +[ Tuple "MVP" M44F
33 +, Tuple "Time" Float
34 +, Tuple "Diffuse" FTexture2D
35 ]
36 }
37-}
38
39inputSchema = makeSchema $ do
40 defObjectArray "stream4" Triangles $ do
41 "position4" @: Attribute_V4F
42 "vertexUV" @: Attribute_V2F
43 defUniforms $ do
44 "Time" @: Float
45 "MVP" @: M44F
46 "Diffuse" @: FTexture2D
47
48frame t m = Frame
49 { renderCount = 10
50 , frameUniforms = Map.fromList [("Time",VFloat t), ("MVP",VM44F m)]
51 , frameTextures = Map.fromList [("Diffuse",0)]
52 }
53
54scene wh = Scene
55 { TD.objectArrays = Map.fromList [("stream4", V.fromList [0])]
56 , renderTargetWidth = wh
57 , renderTargetHeight = wh
58 , frames = V.fromList [frame t (mvp t) | t <- [0..10]]
59 }
60 where
61 mvp t =
62 let camPos = Vec3 3.0 1.3 0.3
63 camTarget = Vec3 0.0 0.0 0.0
64 camUp = Vec3 0.0 1.0 0.0
65 near = 0.1
66 far = 100.0
67 fovDeg = 30.0
68
69 angle = pi / 24.0 * t
70
71 cm = fromProjective $ lookat camPos camTarget camUp
72 mm = fromProjective $ orthogonal $ toOrthoUnsafe $ rotMatrixY angle
73 pm = perspective near far (fovDeg / 180 * pi) (fromIntegral wh / fromIntegral wh)
74 in mat4ToM44F $ mm .*. cm .*. pm
75
76getRenderJob = do
77 let path = "../testdata/editor-examples"
78 tests <- filter ((".lc" ==) . takeExtension) <$> getDirectoryContents path
79 print tests
80 ppls <- forM tests $ \name -> do
81 putStrLn $ "compile: " ++ name
82 LambdaCube.compileMain [path] OpenGL33 (dropExtension name) >>= \case
83 Left err -> fail $ "compile error:\n" ++ err
84 Right ppl -> return $ PipelineInfo
85 { pipelineName = path </> name
86 , pipeline = ppl
87 }
88
89 img <- unpack . B64.encode <$> BS.readFile "logo256x256.png"
90
91 return $ RenderJob
92 { meshes = V.fromList [cubeMesh]
93 , TD.textures = V.fromList [img]
94 , schema = inputSchema
95 , scenes = V.fromList [scene 64]
96 , pipelines = V.fromList ppls
97 }
98
99g_vertex_buffer_data =
100 [ V4 1.0 1.0 (-1.0) 1.0
101 , V4 1.0 (-1.0) (-1.0) 1.0
102 , V4 (-1.0) (-1.0) (-1.0) 1.0
103
104 , V4 1.0 1.0 (-1.0) 1.0
105 , V4 (-1.0) (-1.0) (-1.0) 1.0
106 , V4 (-1.0) 1.0 (-1.0) 1.0
107
108 , V4 1.0 1.0 (-1.0) 1.0
109 , V4 1.0 1.0 1.0 1.0
110 , V4 1.0 (-1.0) 1.0 1.0
111
112 , V4 1.0 1.0 (-1.0) 1.0
113 , V4 1.0 (-1.0) 1.0 1.0
114 , V4 1.0 (-1.0) (-1.0) 1.0
115
116 , V4 1.0 1.0 1.0 1.0
117 , V4 (-1.0) (-1.0) 1.0 1.0
118 , V4 1.0 (-1.0) 1.0 1.0
119
120 , V4 1.0 1.0 1.0 1.0
121 , V4 (-1.0) 1.0 1.0 1.0
122 , V4 (-1.0) (-1.0) 1.0 1.0
123
124 , V4 (-1.0) 1.0 1.0 1.0
125 , V4 (-1.0) (-1.0) (-1.0) 1.0
126 , V4 (-1.0) (-1.0) 1.0 1.0
127
128 , V4 (-1.0) 1.0 1.0 1.0
129 , V4 (-1.0) 1.0 (-1.0) 1.0
130 , V4 (-1.0) (-1.0) (-1.0) 1.0
131
132 , V4 1.0 1.0 (-1.0) 1.0
133 , V4 (-1.0) 1.0 (-1.0) 1.0
134 , V4 (-1.0) 1.0 1.0 1.0
135
136 , V4 1.0 1.0 (-1.0) 1.0
137 , V4 (-1.0) 1.0 1.0 1.0
138 , V4 1.0 1.0 1.0 1.0
139
140 , V4 1.0 (-1.0) (-1.0) 1.0
141 , V4 1.0 (-1.0) 1.0 1.0
142 , V4 (-1.0) (-1.0) 1.0 1.0
143
144 , V4 1.0 (-1.0) (-1.0) 1.0
145 , V4 (-1.0) (-1.0) 1.0 1.0
146 , V4 (-1.0) (-1.0) (-1.0) 1.0
147 ]
148
149-- Two UV coordinatesfor each vertex. They were created with Blender.
150g_uv_buffer_data =
151 [ V2 0.0 1.0
152 , V2 0.0 0.0
153 , V2 1.0 0.0
154 , V2 0.0 1.0
155 , V2 1.0 0.0
156 , V2 1.0 1.0
157 , V2 0.0 1.0
158 , V2 1.0 1.0
159 , V2 1.0 0.0
160 , V2 0.0 1.0
161 , V2 1.0 0.0
162 , V2 0.0 0.0
163 , V2 1.0 1.0
164 , V2 0.0 0.0
165 , V2 1.0 0.0
166 , V2 1.0 1.0
167 , V2 0.0 1.0
168 , V2 0.0 0.0
169 , V2 0.0 1.0
170 , V2 1.0 0.0
171 , V2 0.0 0.0
172 , V2 0.0 1.0
173 , V2 1.0 1.0
174 , V2 1.0 0.0
175 , V2 0.0 1.0
176 , V2 1.0 1.0
177 , V2 1.0 0.0
178 , V2 0.0 1.0
179 , V2 1.0 0.0
180 , V2 0.0 0.0
181 , V2 0.0 1.0
182 , V2 0.0 0.0
183 , V2 1.0 0.0
184 , V2 0.0 1.0
185 , V2 1.0 0.0
186 , V2 1.0 1.0
187 ]
188
189cubeMesh = Mesh
190 { mAttributes = Map.fromList
191 [ ("position4", A_V4F $ V.fromList g_vertex_buffer_data)
192 , ("vertexUV", A_V2F $ V.fromList g_uv_buffer_data)
193 ]
194 , mPrimitive = P_Triangles
195 }
196
197vec4ToV4F (Vec4 x y z w) = V4 x y z w
198mat4ToM44F (Mat4 a b c d) = V4 (vec4ToV4F a) (vec4ToV4F b) (vec4ToV4F c) (vec4ToV4F d)
199
200-- | Camera transformation matrix.
201lookat :: Vec3 -- ^ Camera position.
202 -> Vec3 -- ^ Target position.
203 -> Vec3 -- ^ Upward direction.
204 -> Proj4
205lookat pos target up = translateBefore4 (neg pos) (orthogonal $ toOrthoUnsafe r)
206 where
207 w = normalize $ pos &- target
208 u = normalize $ up &^ w
209 v = w &^ u
210 r = transpose $ Mat3 u v w
211
212-- | Perspective transformation matrix in row major order.
213perspective :: Float -- ^ Near plane clipping distance (always positive).
214 -> Float -- ^ Far plane clipping distance (always positive).
215 -> Float -- ^ Field of view of the y axis, in radians.
216 -> Float -- ^ Aspect ratio, i.e. screen's width\/height.
217 -> Mat4
218perspective n f fovy aspect = transpose $
219 Mat4 (Vec4 (2*n/(r-l)) 0 (-(r+l)/(r-l)) 0)
220 (Vec4 0 (2*n/(t-b)) ((t+b)/(t-b)) 0)
221 (Vec4 0 0 (-(f+n)/(f-n)) (-2*f*n/(f-n)))
222 (Vec4 0 0 (-1) 0)
223 where
224 t = n*tan(fovy/2)
225 b = -t
226 r = aspect*t
227 l = -r
diff --git a/backendtest/TestData.hs b/backendtest/TestData.hs
index a48dc42b..d6d8e381 100644
--- a/backendtest/TestData.hs
+++ b/backendtest/TestData.hs
@@ -1,5 +1,5 @@
1-- generated file, do not modify! 1-- generated file, do not modify!
2-- 2016-01-28T13:15:31.27456Z 2-- 2016-02-12T16:05:13.383716000000Z
3 3
4{-# LANGUAGE OverloadedStrings, RecordWildCards #-} 4{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
5module TestData where 5module TestData where
@@ -46,13 +46,21 @@ data Scene
46 46
47 deriving (Show, Eq, Ord) 47 deriving (Show, Eq, Ord)
48 48
49data PipelineInfo
50 = PipelineInfo
51 { pipelineName :: String
52 , pipeline :: Pipeline
53 }
54
55 deriving (Show, Eq, Ord)
56
49data RenderJob 57data RenderJob
50 = RenderJob 58 = RenderJob
51 { meshes :: Vector Mesh 59 { meshes :: Vector Mesh
52 , textures :: Vector String 60 , textures :: Vector String
53 , schema :: PipelineSchema 61 , schema :: PipelineSchema
54 , scenes :: Vector Scene 62 , scenes :: Vector Scene
55 , pipelines :: Vector Pipeline 63 , pipelines :: Vector PipelineInfo
56 } 64 }
57 65
58 deriving (Show, Eq, Ord) 66 deriving (Show, Eq, Ord)
@@ -144,6 +152,27 @@ instance FromJSON Scene where
144 } 152 }
145 parseJSON _ = mzero 153 parseJSON _ = mzero
146 154
155instance ToJSON PipelineInfo where
156 toJSON v = case v of
157 PipelineInfo{..} -> object
158 [ "tag" .= ("PipelineInfo" :: Text)
159 , "pipelineName" .= pipelineName
160 , "pipeline" .= pipeline
161 ]
162
163instance FromJSON PipelineInfo where
164 parseJSON (Object obj) = do
165 tag <- obj .: "tag"
166 case tag :: Text of
167 "PipelineInfo" -> do
168 pipelineName <- obj .: "pipelineName"
169 pipeline <- obj .: "pipeline"
170 pure $ PipelineInfo
171 { pipelineName = pipelineName
172 , pipeline = pipeline
173 }
174 parseJSON _ = mzero
175
147instance ToJSON RenderJob where 176instance ToJSON RenderJob where
148 toJSON v = case v of 177 toJSON v = case v of
149 RenderJob{..} -> object 178 RenderJob{..} -> object
diff --git a/backendtest/hello.json b/backendtest/hello.json
deleted file mode 100644
index 56de2470..00000000
--- a/backendtest/hello.json
+++ /dev/null
@@ -1 +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":{"z1":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"position"},"a2":{"tag":"Parameter","ty":{"tag":"V2F"},"name":"uv"}},"fragmentShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform sampler2D diffuseTexture ;\nsmooth in vec2 v0 ;\nout vec4 f0 ;\nvoid main() {\nf0 = texture2D ( diffuseTexture,v0 );\n}\n","vertexShader":"#version 330 core\nvec4 texture2D(sampler2D s, vec2 uv){return texture(s,uv);}\nuniform float time ;\nin vec2 z1 ;\nin vec2 a2 ;\nsmooth out vec2 v0 ;\nvoid main() {\nv0 = a2;\ngl_Position = ( mat4 ( vec4 ( cos ( time ),sin ( time ),0.0,0.0 ),vec4 ( ( 0.0 ) - ( sin ( time ) ),cos ( time ),0.0,0.0 ),vec4 ( 0.0,0.0,1.0,0.0 ),vec4 ( 0.0,0.0,0.0,1.0 ) ) ) * ( vec4 ( ( z1 ).x,( z1 ).y,-1.0,1.0 ) );\ngl_PointSize = 1.0;\n}\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"}}}]}]} \ No newline at end of file
diff --git a/backendtest/logo.png b/backendtest/logo.png
deleted file mode 100644
index 44716763..00000000
--- a/backendtest/logo.png
+++ /dev/null
Binary files differ
diff --git a/backendtest/logo256x256.png b/backendtest/logo256x256.png
new file mode 100644
index 00000000..2c0c985c
--- /dev/null
+++ b/backendtest/logo256x256.png
Binary files differ
diff --git a/backendtest/server.hs b/backendtest/server.hs
index 79d873f5..c2d13555 100644
--- a/backendtest/server.hs
+++ b/backendtest/server.hs
@@ -13,6 +13,7 @@ import qualified Data.Vector.Storable as SV
13import qualified Network.WebSockets as WS 13import qualified Network.WebSockets as WS
14import qualified Data.Map as Map 14import qualified Data.Map as Map
15import Text.Printf 15import Text.Printf
16import System.FilePath
16import System.Directory 17import System.Directory
17 18
18import TestData 19import TestData
@@ -22,6 +23,8 @@ import LambdaCube.PipelineSchema
22import LambdaCube.PipelineSchemaUtil 23import LambdaCube.PipelineSchemaUtil
23import LambdaCube.Mesh 24import LambdaCube.Mesh
24 25
26import qualified EditorExamplesTest
27
25main :: IO () 28main :: IO ()
26main = do 29main = do
27 putStrLn "listening" 30 putStrLn "listening"
@@ -31,23 +34,27 @@ application pending = do
31 conn <- WS.acceptRequest pending 34 conn <- WS.acceptRequest pending
32 WS.forkPingThread conn 30 35 WS.forkPingThread conn 30
33 let disconnect = return () 36 let disconnect = return ()
37 one = 1 :: Int
34 flip finally disconnect $ do 38 flip finally disconnect $ do
35 -- receive client info 39 -- receive client info
36 decodeStrict <$> WS.receiveData conn >>= \case 40 decodeStrict <$> WS.receiveData conn >>= \case
37 Nothing -> putStrLn "invalid client info" 41 Nothing -> putStrLn "invalid client info"
38 Just ci@ClientInfo{..} -> print ci 42 Just ci@ClientInfo{..} -> print ci
39 -- send pipeline 43 -- send pipeline
40 renderJob@RenderJob{..} <- testRenderJob 44 --renderJob@RenderJob{..} <- testRenderJob
45 renderJob@RenderJob{..} <- EditorExamplesTest.getRenderJob -- TODO
41 WS.sendTextData conn . encode $ renderJob 46 WS.sendTextData conn . encode $ renderJob
42 -- TODO: get render result: pipeline x scene x frame 47 -- TODO: get render result: pipeline x scene x frame
43 forM_ [1..length pipelines] $ \pIdx -> 48 forM_ [one..length pipelines] $ \pIdx -> do
44 forM_ (zip [1..] $ V.toList scenes) $ \(sIdx,Scene{..}) -> 49 putStrLn $ "pipeline: " ++ pipelineName (pipelines V.! (pIdx - 1))
45 forM_ [1..length frames] $ \fIdx -> do 50 forM_ (zip [one..] $ V.toList scenes) $ \(sIdx,Scene{..}) ->
51 forM_ [one..length frames] $ \fIdx -> do
46 decodeStrict <$> WS.receiveData conn >>= \case 52 decodeStrict <$> WS.receiveData conn >>= \case
47 Nothing -> putStrLn "invalid RenderJobResult" 53 Nothing -> putStrLn "invalid RenderJobResult"
48 Just (RenderJobError e) -> putStrLn $ "render error: " ++ e -- TODO: test failed 54 Just (RenderJobError e) -> fail $ "render error:\n" ++ e -- TODO: test failed
49 Just (RenderJobResult FrameResult{..}) -> do 55 Just (RenderJobResult FrameResult{..}) -> do
50 let name = "out/output_ppl" ++ show pIdx ++ "_scn" ++ show sIdx ++ "_" ++ show fIdx ++ ".png" 56 let name = "out/output_ppl" ++ printf "%02d" pIdx ++ "_scn" ++ printf "%02d" sIdx ++ "_" ++ printf "%02d" fIdx ++ ".png"
57 createDirectoryIfMissing True (takeDirectory name)
51 compareOrSaveImage name =<< toImage frImageWidth frImageHeight . either error id . B64.decode =<< WS.receiveData conn 58 compareOrSaveImage name =<< toImage frImageWidth frImageHeight . either error id . B64.decode =<< WS.receiveData conn
52 putStrLn $ name ++ "\t" ++ unwords (map showTime . V.toList $ frRenderTimes) 59 putStrLn $ name ++ "\t" ++ unwords (map showTime . V.toList $ frRenderTimes)
53 putStrLn "render job done" 60 putStrLn "render job done"
@@ -114,49 +121,3 @@ showTime delta
114 collect pipelines 121 collect pipelines
115 - create render job list 122 - create render job list
116-} 123-}
117testRenderJob = do
118 let triangleA = Mesh
119 { mAttributes = Map.fromList
120 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 1 (-1), V2 (-1) (-1)])
121 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 1, V2 0 0])
122 ]
123 , mPrimitive = P_Triangles
124 }
125
126 triangleB = Mesh
127 { mAttributes = Map.fromList
128 [ ("position", A_V2F $ V.fromList [V2 1 1, V2 (-1) (-1), V2 (-1) 1])
129 , ("uv", A_V2F $ V.fromList [V2 1 1, V2 0 0, V2 1 0])
130 ]
131 , mPrimitive = P_Triangles
132 }
133 inputSchema = makeSchema $ do
134 defObjectArray "objects" Triangles $ do
135 "position" @: Attribute_V2F
136 "uv" @: Attribute_V2F
137 defUniforms $ do
138 "time" @: Float
139 "diffuseTexture" @: FTexture2D
140 frame t = Frame
141 { renderCount = 10
142 , frameUniforms = Map.fromList [("time",VFloat t)]
143 , frameTextures = Map.fromList [("diffuseTexture",0)]
144 }
145
146 scene wh = Scene
147 { objectArrays = Map.fromList [("objects", V.fromList [0,1])]
148 , renderTargetWidth = wh
149 , renderTargetHeight = wh
150 , frames = V.fromList [frame t | t <- [0,0.3..6]]
151 }
152
153 img <- unpack . B64.encode <$> BS.readFile "logo.png"
154 Just ppl <- decodeStrict <$> BS.readFile "hello.json"
155
156 return $ RenderJob
157 { meshes = V.fromList [triangleA,triangleB]
158 , textures = V.fromList [img]
159 , schema = inputSchema
160 , scenes = V.fromList [scene (2^s) | s <- [1..9]]
161 , pipelines = V.fromList [ppl]
162 }