diff options
author | Joe Crayne <joe@jerkface.net> | 2019-05-06 00:30:38 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-05-06 02:03:02 -0400 |
commit | 154b25e0ad8a8ecedb02876215d29c12e87e6c93 (patch) | |
tree | 993a82722d7f046a5df4c1972b8b7b3ce2452c98 /src/LambdaCube/GL/Input.hs | |
parent | 98b19d6d4076f4f19bdaa3dd8ba795637718bf12 (diff) |
Representation-agnostic matrix/vector pipeline inputs.
Diffstat (limited to 'src/LambdaCube/GL/Input.hs')
-rw-r--r-- | src/LambdaCube/GL/Input.hs | 388 |
1 files changed, 196 insertions, 192 deletions
diff --git a/src/LambdaCube/GL/Input.hs b/src/LambdaCube/GL/Input.hs index 5d2a49e..bd46fe0 100644 --- a/src/LambdaCube/GL/Input.hs +++ b/src/LambdaCube/GL/Input.hs | |||
@@ -1,9 +1,16 @@ | |||
1 | {-# LANGUAGE BangPatterns, FlexibleContexts, TypeSynonymInstances, FlexibleInstances #-} | 1 | {-# LANGUAGE BangPatterns, FlexibleContexts, TypeSynonymInstances, FlexibleInstances #-} |
2 | {-# LANGUAGE DataKinds #-} | ||
3 | {-# LANGUAGE GADTs #-} | ||
4 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
5 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
6 | {-# LANGUAGE RankNTypes #-} | ||
7 | {-# LANGUAGE StandaloneDeriving #-} | ||
2 | module LambdaCube.GL.Input where | 8 | module LambdaCube.GL.Input where |
3 | 9 | ||
4 | import Control.Applicative | 10 | import Control.Applicative |
5 | import Control.Exception | 11 | import Control.Exception |
6 | import Control.Monad | 12 | import Control.Monad |
13 | import Control.Monad.Reader | ||
7 | import Control.Monad.Writer | 14 | import Control.Monad.Writer |
8 | import Data.Maybe | 15 | import Data.Maybe |
9 | import Data.IORef | 16 | import Data.IORef |
@@ -12,7 +19,9 @@ import Data.IntMap (IntMap) | |||
12 | import Data.Vector (Vector,(//),(!)) | 19 | import Data.Vector (Vector,(//),(!)) |
13 | import Data.Word | 20 | import Data.Word |
14 | import Data.String | 21 | import Data.String |
22 | import Data.Typeable | ||
15 | import Foreign | 23 | import Foreign |
24 | import qualified Data.Dependent.Map as DMap | ||
16 | import qualified Data.IntMap as IM | 25 | import qualified Data.IntMap as IM |
17 | import qualified Data.Set as S | 26 | import qualified Data.Set as S |
18 | import qualified Data.Map as Map | 27 | import qualified Data.Map as Map |
@@ -23,11 +32,12 @@ import qualified Data.ByteString.Char8 as SB | |||
23 | 32 | ||
24 | import Graphics.GL.Core33 | 33 | import Graphics.GL.Core33 |
25 | 34 | ||
35 | import LambdaCube.GL.Input.Type | ||
36 | import LambdaCube.GL.Type as T | ||
37 | import LambdaCube.GL.Util | ||
26 | import LambdaCube.IR as IR | 38 | import LambdaCube.IR as IR |
27 | import LambdaCube.Linear as IR | 39 | import LambdaCube.Linear as IR |
28 | import LambdaCube.PipelineSchema | 40 | import LambdaCube.PipelineSchema |
29 | import LambdaCube.GL.Type as T | ||
30 | import LambdaCube.GL.Util | ||
31 | 41 | ||
32 | import qualified LambdaCube.IR as IR | 42 | import qualified LambdaCube.IR as IR |
33 | 43 | ||
@@ -43,19 +53,19 @@ schemaFromPipeline a = PipelineSchema (Map.fromList sl) (foldl Map.union Map.emp | |||
43 | Just v -> v | 53 | Just v -> v |
44 | Nothing -> error "internal error (schemaFromPipeline)" | 54 | Nothing -> error "internal error (schemaFromPipeline)" |
45 | 55 | ||
46 | mkUniform :: [(String,InputType)] -> IO (Map GLUniformName InputSetter, Map String GLUniform) | 56 | mkUniform :: [(String,InputType)] -> IO (Map String GLUniform) |
47 | mkUniform l = do | 57 | mkUniform l = do |
48 | unisAndSetters <- forM l $ \(n,t) -> do | 58 | unis <- forM l $ \(n,t) -> do |
49 | (uni, setter) <- mkUniformSetter t | 59 | uni <- initializeUniform t |
50 | return ((n,uni),(fromString n,setter)) | 60 | return (n,uni) |
51 | let (unis,setters) = unzip unisAndSetters | 61 | return (Map.fromList unis) |
52 | return (Map.fromList setters, Map.fromList unis) | 62 | |
53 | 63 | ||
54 | allocStorage :: PipelineSchema -> IO GLStorage | 64 | allocStorage :: PipelineSchema -> IO GLStorage |
55 | allocStorage sch = do | 65 | allocStorage sch = do |
56 | let sm = Map.fromList $ zip (Map.keys $ objectArrays sch) [0..] | 66 | let sm = Map.fromList $ zip (Map.keys $ objectArrays sch) [0..] |
57 | len = Map.size sm | 67 | len = Map.size sm |
58 | (setters,unis) <- mkUniform $ Map.toList $ uniforms sch | 68 | unis <- mkUniform $ Map.toList $ uniforms sch |
59 | seed <- newIORef 0 | 69 | seed <- newIORef 0 |
60 | slotV <- V.replicateM len $ newIORef (GLSlot IM.empty V.empty Ordered) | 70 | slotV <- V.replicateM len $ newIORef (GLSlot IM.empty V.empty Ordered) |
61 | size <- newIORef (0,0) | 71 | size <- newIORef (0,0) |
@@ -65,7 +75,6 @@ allocStorage sch = do | |||
65 | , slotMap = sm | 75 | , slotMap = sm |
66 | , slotVector = slotV | 76 | , slotVector = slotV |
67 | , objSeed = seed | 77 | , objSeed = seed |
68 | , uniformSetter = setters | ||
69 | , uniformSetup = unis | 78 | , uniformSetup = unis |
70 | , screenSize = size | 79 | , screenSize = size |
71 | , pipelines = ppls | 80 | , pipelines = ppls |
@@ -102,14 +111,15 @@ addObject input slotName prim indices attribs uniformNames = do | |||
102 | enabled <- newIORef True | 111 | enabled <- newIORef True |
103 | index <- readIORef seed | 112 | index <- readIORef seed |
104 | modifyIORef seed (1+) | 113 | modifyIORef seed (1+) |
105 | (setters,unis) <- mkUniform [(n,t) | n <- uniformNames, let t = fromMaybe (error $ "missing uniform: " ++ n) $ Map.lookup n (uniforms sch)] | 114 | unis <- mkUniform [(n,t) | n <- uniformNames, |
115 | let t = fromMaybe (error $ "missing uniform: " ++ n) | ||
116 | $ Map.lookup n (uniforms sch)] | ||
106 | cmdsRef <- newIORef (V.singleton V.empty) | 117 | cmdsRef <- newIORef (V.singleton V.empty) |
107 | let obj = Object | 118 | let obj = Object |
108 | { objSlot = slotIdx | 119 | { objSlot = slotIdx |
109 | , objPrimitive = prim | 120 | , objPrimitive = prim |
110 | , objIndices = indices | 121 | , objIndices = indices |
111 | , objAttributes = attribs | 122 | , objAttributes = attribs |
112 | , objUniSetter = setters | ||
113 | , objUniSetup = unis | 123 | , objUniSetup = unis |
114 | , objOrder = order | 124 | , objOrder = order |
115 | , objEnabled = enabled | 125 | , objEnabled = enabled |
@@ -154,8 +164,11 @@ setObjectOrder p obj i = do | |||
154 | writeIORef (objOrder obj) i | 164 | writeIORef (objOrder obj) i |
155 | modifyIORef (slotVector p ! objSlot obj) $ \(GLSlot objs sorted _) -> GLSlot objs sorted Reorder | 165 | modifyIORef (slotVector p ! objSlot obj) $ \(GLSlot objs sorted _) -> GLSlot objs sorted Reorder |
156 | 166 | ||
167 | uniformSetter :: GLStorage -> Map String InputSetter | ||
168 | uniformSetter = uniformSetup | ||
169 | |||
157 | objectUniformSetter :: Object -> Map GLUniformName InputSetter | 170 | objectUniformSetter :: Object -> Map GLUniformName InputSetter |
158 | objectUniformSetter = objUniSetter | 171 | objectUniformSetter = objUniSetup |
159 | 172 | ||
160 | setScreenSize :: GLStorage -> Word -> Word -> IO () | 173 | setScreenSize :: GLStorage -> Word -> Word -> IO () |
161 | setScreenSize p w h = writeIORef (screenSize p) (w,h) | 174 | setScreenSize p w h = writeIORef (screenSize p) (w,h) |
@@ -212,7 +225,8 @@ createObjectCommands texUnitMap topUnis obj prg = objUniCmds ++ objStreamCmds ++ | |||
212 | , let u = Map.findWithDefault (topUni n) n objUnis | 225 | , let u = Map.findWithDefault (topUni n) n objUnis |
213 | , let texUnit = Map.findWithDefault (error $ "internal error (createObjectCommands - Texture Unit): " ++ show n) n texUnitMap | 226 | , let texUnit = Map.findWithDefault (error $ "internal error (createObjectCommands - Texture Unit): " ++ show n) n texUnitMap |
214 | ] | 227 | ] |
215 | uniInputType (GLUniform ty _) = ty | 228 | uniInputType (GLTypedUniform ty _) = unwitnessType ty |
229 | uniInputType (GLUniform ty _) = ty | ||
216 | 230 | ||
217 | -- object attribute stream commands | 231 | -- object attribute stream commands |
218 | objStreamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name objAttrs] | 232 | objStreamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name objAttrs] |
@@ -252,187 +266,177 @@ createObjectCommands texUnitMap topUnis obj prg = objUniCmds ++ objStreamCmds ++ | |||
252 | -- constant generic attribute | 266 | -- constant generic attribute |
253 | constAttr -> GLSetVertexAttrib i constAttr | 267 | constAttr -> GLSetVertexAttrib i constAttr |
254 | 268 | ||
255 | nullSetter :: GLUniformName -> String -> a -> IO () | 269 | newtype UniM a = UniM (ReaderT (Map GLUniformName GLUniform) (Writer [IO ()]) a) |
256 | nullSetter n t _ = return () | 270 | deriving instance Functor UniM |
257 | --nullSetter n t _ = Prelude.putStrLn $ "WARNING: unknown uniform: " ++ show n ++ " :: " ++ t | 271 | deriving instance Applicative UniM |
258 | 272 | deriving instance Monad UniM | |
259 | uniformBool :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun Bool | 273 | deriving instance MonadReader (Map String GLUniform) UniM |
260 | uniformV2B :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V2B | 274 | deriving instance MonadWriter [IO ()] UniM |
261 | uniformV3B :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V3B | 275 | |
262 | uniformV4B :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V4B | 276 | |
263 | 277 | (@=) :: (Typeable a, Uniformable a) => String -> IO a -> UniM () | |
264 | uniformWord :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun Word32 | 278 | name @= val = do |
265 | uniformV2U :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V2U | 279 | u <- do |
266 | uniformV3U :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V3U | 280 | us <- ask |
267 | uniformV4U :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V4U | 281 | return $ us Map.! name |
268 | 282 | case u of | |
269 | uniformInt :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun Int32 | 283 | |
270 | uniformV2I :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V2I | 284 | GLTypedUniform ty ref -> do |
271 | uniformV3I :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V3I | 285 | case DMap.lookup ty (uniformContexts val) of |
272 | uniformV4I :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V4I | 286 | Just UniformContext -> do |
273 | 287 | tell [val >>= writeIORef ref . GLUniformValue] | |
274 | uniformFloat :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun Float | 288 | Nothing -> do |
275 | uniformV2F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V2F | 289 | tell [throwIO $ typeMismatch ty ref] |
276 | uniformV3F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V3F | 290 | |
277 | uniformV4F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun V4F | 291 | GLUniform FTexture2D ref -> case withTypes val ref <$> eqT of |
278 | 292 | Just Refl -> tell [val >>= writeIORef ref] | |
279 | uniformM22F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M22F | 293 | Nothing -> tell [ Prelude.putStrLn $ "WARNING: Texture2D variable " |
280 | uniformM23F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M23F | 294 | ++ show name |
281 | uniformM24F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M24F | 295 | ++ " cannot recieve value " ++ show (typeRep val) |
282 | uniformM32F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M32F | 296 | , throwIO $ typeMismatch ref val |
283 | uniformM33F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M33F | 297 | ] |
284 | uniformM34F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M34F | 298 | |
285 | uniformM42F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M42F | 299 | GLUniform ty _ -> tell [Prelude.putStrLn $ "WARNING: unknown uniform: " ++ show name ++ " :: " ++ show ty] |
286 | uniformM43F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M43F | ||
287 | uniformM44F :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun M44F | ||
288 | |||
289 | uniformFTexture2D :: GLUniformName -> Map GLUniformName InputSetter -> SetterFun TextureData | ||
290 | |||
291 | uniformBool n is = case Map.lookup n is of | ||
292 | Just (SBool fun) -> fun | ||
293 | _ -> nullSetter n "Bool" | ||
294 | |||
295 | uniformV2B n is = case Map.lookup n is of | ||
296 | Just (SV2B fun) -> fun | ||
297 | _ -> nullSetter n "V2B" | ||
298 | |||
299 | uniformV3B n is = case Map.lookup n is of | ||
300 | Just (SV3B fun) -> fun | ||
301 | _ -> nullSetter n "V3B" | ||
302 | 300 | ||
303 | uniformV4B n is = case Map.lookup n is of | ||
304 | Just (SV4B fun) -> fun | ||
305 | _ -> nullSetter n "V4B" | ||
306 | |||
307 | uniformWord n is = case Map.lookup n is of | ||
308 | Just (SWord fun) -> fun | ||
309 | _ -> nullSetter n "Word" | ||
310 | |||
311 | uniformV2U n is = case Map.lookup n is of | ||
312 | Just (SV2U fun) -> fun | ||
313 | _ -> nullSetter n "V2U" | ||
314 | |||
315 | uniformV3U n is = case Map.lookup n is of | ||
316 | Just (SV3U fun) -> fun | ||
317 | _ -> nullSetter n "V3U" | ||
318 | |||
319 | uniformV4U n is = case Map.lookup n is of | ||
320 | Just (SV4U fun) -> fun | ||
321 | _ -> nullSetter n "V4U" | ||
322 | |||
323 | uniformInt n is = case Map.lookup n is of | ||
324 | Just (SInt fun) -> fun | ||
325 | _ -> nullSetter n "Int" | ||
326 | |||
327 | uniformV2I n is = case Map.lookup n is of | ||
328 | Just (SV2I fun) -> fun | ||
329 | _ -> nullSetter n "V2I" | ||
330 | |||
331 | uniformV3I n is = case Map.lookup n is of | ||
332 | Just (SV3I fun) -> fun | ||
333 | _ -> nullSetter n "V3I" | ||
334 | |||
335 | uniformV4I n is = case Map.lookup n is of | ||
336 | Just (SV4I fun) -> fun | ||
337 | _ -> nullSetter n "V4I" | ||
338 | |||
339 | uniformFloat n is = case Map.lookup n is of | ||
340 | Just (SFloat fun) -> fun | ||
341 | _ -> nullSetter n "Float" | ||
342 | |||
343 | uniformV2F n is = case Map.lookup n is of | ||
344 | Just (SV2F fun) -> fun | ||
345 | _ -> nullSetter n "V2F" | ||
346 | |||
347 | uniformV3F n is = case Map.lookup n is of | ||
348 | Just (SV3F fun) -> fun | ||
349 | _ -> nullSetter n "V3F" | ||
350 | |||
351 | uniformV4F n is = case Map.lookup n is of | ||
352 | Just (SV4F fun) -> fun | ||
353 | _ -> nullSetter n "V4F" | ||
354 | |||
355 | uniformM22F n is = case Map.lookup n is of | ||
356 | Just (SM22F fun) -> fun | ||
357 | _ -> nullSetter n "M22F" | ||
358 | |||
359 | uniformM23F n is = case Map.lookup n is of | ||
360 | Just (SM23F fun) -> fun | ||
361 | _ -> nullSetter n "M23F" | ||
362 | |||
363 | uniformM24F n is = case Map.lookup n is of | ||
364 | Just (SM24F fun) -> fun | ||
365 | _ -> nullSetter n "M24F" | ||
366 | |||
367 | uniformM32F n is = case Map.lookup n is of | ||
368 | Just (SM32F fun) -> fun | ||
369 | _ -> nullSetter n "M32F" | ||
370 | |||
371 | uniformM33F n is = case Map.lookup n is of | ||
372 | Just (SM33F fun) -> fun | ||
373 | _ -> nullSetter n "M33F" | ||
374 | |||
375 | uniformM34F n is = case Map.lookup n is of | ||
376 | Just (SM34F fun) -> fun | ||
377 | _ -> nullSetter n "M34F" | ||
378 | |||
379 | uniformM42F n is = case Map.lookup n is of | ||
380 | Just (SM42F fun) -> fun | ||
381 | _ -> nullSetter n "M42F" | ||
382 | |||
383 | uniformM43F n is = case Map.lookup n is of | ||
384 | Just (SM43F fun) -> fun | ||
385 | _ -> nullSetter n "M43F" | ||
386 | |||
387 | uniformM44F n is = case Map.lookup n is of | ||
388 | Just (SM44F fun) -> fun | ||
389 | _ -> nullSetter n "M44F" | ||
390 | |||
391 | uniformFTexture2D n is = case Map.lookup n is of | ||
392 | Just (SFTexture2D fun) -> fun | ||
393 | _ -> nullSetter n "FTexture2D" | ||
394 | |||
395 | type UniM = Writer [Map GLUniformName InputSetter -> IO ()] | ||
396 | |||
397 | class UniformSetter a where | ||
398 | (@=) :: GLUniformName -> IO a -> UniM () | ||
399 | |||
400 | setUniM :: (n -> Map GLUniformName InputSetter -> a -> IO ()) -> n -> IO a -> UniM () | ||
401 | setUniM setUni n act = tell [\s -> let f = setUni n s in f =<< act] | ||
402 | |||
403 | instance UniformSetter Bool where (@=) = setUniM uniformBool | ||
404 | instance UniformSetter V2B where (@=) = setUniM uniformV2B | ||
405 | instance UniformSetter V3B where (@=) = setUniM uniformV3B | ||
406 | instance UniformSetter V4B where (@=) = setUniM uniformV4B | ||
407 | instance UniformSetter Word32 where (@=) = setUniM uniformWord | ||
408 | instance UniformSetter V2U where (@=) = setUniM uniformV2U | ||
409 | instance UniformSetter V3U where (@=) = setUniM uniformV3U | ||
410 | instance UniformSetter V4U where (@=) = setUniM uniformV4U | ||
411 | instance UniformSetter Int32 where (@=) = setUniM uniformInt | ||
412 | instance UniformSetter V2I where (@=) = setUniM uniformV2I | ||
413 | instance UniformSetter V3I where (@=) = setUniM uniformV3I | ||
414 | instance UniformSetter V4I where (@=) = setUniM uniformV4I | ||
415 | instance UniformSetter Float where (@=) = setUniM uniformFloat | ||
416 | instance UniformSetter V2F where (@=) = setUniM uniformV2F | ||
417 | instance UniformSetter V3F where (@=) = setUniM uniformV3F | ||
418 | instance UniformSetter V4F where (@=) = setUniM uniformV4F | ||
419 | instance UniformSetter M22F where (@=) = setUniM uniformM22F | ||
420 | instance UniformSetter M23F where (@=) = setUniM uniformM23F | ||
421 | instance UniformSetter M24F where (@=) = setUniM uniformM24F | ||
422 | instance UniformSetter M32F where (@=) = setUniM uniformM32F | ||
423 | instance UniformSetter M33F where (@=) = setUniM uniformM33F | ||
424 | instance UniformSetter M34F where (@=) = setUniM uniformM34F | ||
425 | instance UniformSetter M42F where (@=) = setUniM uniformM42F | ||
426 | instance UniformSetter M43F where (@=) = setUniM uniformM43F | ||
427 | instance UniformSetter M44F where (@=) = setUniM uniformM44F | ||
428 | instance UniformSetter TextureData where (@=) = setUniM uniformFTexture2D | ||
429 | 301 | ||
430 | updateUniforms :: GLStorage -> UniM a -> IO () | 302 | updateUniforms :: GLStorage -> UniM a -> IO () |
431 | updateUniforms storage m = sequence_ l where | 303 | updateUniforms storage (UniM m) = sequence_ l where |
432 | setters = uniformSetter storage | 304 | setters = uniformSetup storage |
433 | l = map ($ setters) $ execWriter m | 305 | l = execWriter $ runReaderT m setters |
434 | 306 | ||
435 | updateObjectUniforms :: Object -> UniM a -> IO () | 307 | updateObjectUniforms :: Object -> UniM a -> IO () |
436 | updateObjectUniforms object m = sequence_ l where | 308 | updateObjectUniforms object (UniM m) = sequence_ l where |
437 | setters = objectUniformSetter object | 309 | setters = objectUniformSetter object |
438 | l = map ($ setters) $ execWriter m | 310 | l = execWriter $ runReaderT m setters |
311 | |||
312 | -- | Set a uniform ref. | ||
313 | setGLUniform :: Typeable a => | ||
314 | (forall v. Typeable v => TypeTag v -> Maybe (UniformContext a v)) | ||
315 | -> String -- ^ For warning messages, name of uniform. | ||
316 | -> GLUniform -- ^ Uniform ref to set. | ||
317 | -> a -- ^ Value to store. | ||
318 | -> IO () | ||
319 | setGLUniform resolv name u val = case u of | ||
320 | GLTypedUniform ty ref -> do | ||
321 | case resolv ty of | ||
322 | Just UniformContext -> writeIORef ref $ GLUniformValue val | ||
323 | Nothing -> warn $ unwords [ "Cannot set", show $ unwitnessType ty | ||
324 | , "uniform", name | ||
325 | , "to", show (typeOf val) | ||
326 | , "value." ] | ||
327 | |||
328 | GLUniform textureType ref -> case withTypes (Just val) ref <$> eqT of | ||
329 | Just Refl -> writeIORef ref val | ||
330 | Nothing -> warn $ unwords [ show textureType | ||
331 | , "uniform", name | ||
332 | , "only accepts values of type TextureData." ] | ||
333 | where warn s = putStrLn $ "WARNING: " ++ s | ||
334 | |||
335 | -- | Lookup and set a Uniform ref. | ||
336 | setUniformRef :: ( Typeable a | ||
337 | , Show name, Ord name | ||
338 | ) => (forall v. Typeable v => TypeTag v -> Maybe (UniformContext a v)) | ||
339 | -> name | ||
340 | -> Map name GLUniform | ||
341 | -> a | ||
342 | -> IO () | ||
343 | setUniformRef resolv name us val = case Map.lookup name us of | ||
344 | Nothing -> warn $ "unknown uniform: " ++ show name | ||
345 | Just u -> setGLUniform resolv (show name) u val | ||
346 | where warn s = putStrLn $ "WARNING: " ++ s | ||
347 | |||
348 | uniformOf :: (Show name, Ord name, GLData a have) => | ||
349 | TypeTag have | ||
350 | -> name | ||
351 | -> Map name GLUniform | ||
352 | -> a | ||
353 | -> IO () | ||
354 | uniformOf have = setUniformRef $ knownContext have | ||
355 | |||
356 | uniform :: (Typeable a, Show name, Ord name, Uniformable a) => | ||
357 | name -> Map name GLUniform -> a -> IO () | ||
358 | uniform n o a = setUniformRef (resolveContext a) n o a | ||
359 | |||
360 | |||
361 | uniformFTexture2D :: SB.ByteString -> Map GLUniformName GLUniform -> TextureData -> IO () | ||
362 | uniformFTexture2D = | ||
363 | -- TODO: Check that the uniform is of the expected FTexture2D type. | ||
364 | uniform . SB.unpack | ||
365 | |||
366 | uniformBool :: (Show name, Ord name) => name -> Map name GLUniform -> Bool -> IO () | ||
367 | uniformV2B :: (Show name, Ord name, GLData a (GLVector 2 Word32)) => name -> Map name GLUniform -> a -> IO () | ||
368 | uniformV3B :: (Show name, Ord name, GLData a (GLVector 3 Word32)) => name -> Map name GLUniform -> a -> IO () | ||
369 | uniformV4B :: (Show name, Ord name, GLData a (GLVector 4 Word32)) => name -> Map name GLUniform -> a -> IO () | ||
370 | uniformBool = uniformOf TypeBool | ||
371 | uniformV2B = uniformOf TypeV2B | ||
372 | uniformV3B = uniformOf TypeV3B | ||
373 | uniformV4B = uniformOf TypeV4B | ||
374 | |||
375 | uniformWord :: (Show name, Ord name) => name -> Map name GLUniform -> Word32 -> IO () | ||
376 | uniformV2U :: (Typeable f, GLData (f Word32) (GLVector 2 Word32)) => | ||
377 | String -> Map GLUniformName GLUniform -> f Word32 -> IO () | ||
378 | uniformV3U :: (Typeable f, GLData (f Word32) (GLVector 3 Word32)) => | ||
379 | String -> Map GLUniformName GLUniform -> f Word32 -> IO () | ||
380 | uniformV4U :: (Typeable f, GLData (f Word32) (GLVector 4 Word32)) => | ||
381 | String -> Map GLUniformName GLUniform -> f Word32 -> IO () | ||
382 | uniformWord = uniformOf TypeWord | ||
383 | uniformV2U = uniformOf TypeV2U | ||
384 | uniformV3U = uniformOf TypeV3U | ||
385 | uniformV4U = uniformOf TypeV4U | ||
386 | |||
387 | uniformFloat :: (Show name, Ord name) => name -> Map name GLUniform -> Float -> IO () | ||
388 | uniformV2F :: (Typeable f, GLData (f Float) (GLVector 2 Float)) => | ||
389 | String -> Map GLUniformName GLUniform -> f Float -> IO () | ||
390 | uniformV3F :: (Typeable f, GLData (f Float) (GLVector 3 Float)) => | ||
391 | String -> Map GLUniformName GLUniform -> f Float -> IO () | ||
392 | uniformV4F :: (Typeable f, GLData (f Float) (GLVector 4 Float)) => | ||
393 | String -> Map GLUniformName GLUniform -> f Float -> IO () | ||
394 | uniformFloat = uniformOf TypeFloat | ||
395 | uniformV2F = setUniformRef (knownContext TypeV2F) | ||
396 | uniformV3F = setUniformRef (knownContext TypeV3F) | ||
397 | uniformV4F = setUniformRef (knownContext TypeV4F) | ||
398 | |||
399 | uniformInt :: (Show name, Ord name) => name -> Map name GLUniform -> Int32 -> IO () | ||
400 | uniformV2I :: (Typeable f, GLData (f Int32) (GLVector 2 Int32)) => | ||
401 | String -> Map GLUniformName GLUniform -> f Int32 -> IO () | ||
402 | uniformV3I :: (Typeable f, GLData (f Int32) (GLVector 3 Int32)) => | ||
403 | String -> Map GLUniformName GLUniform -> f Int32 -> IO () | ||
404 | uniformV4I :: (Typeable f, GLData (f Int32) (GLVector 4 Int32)) => | ||
405 | String -> Map GLUniformName GLUniform -> f Int32 -> IO () | ||
406 | uniformInt = uniformOf TypeInt | ||
407 | uniformV2I = uniformOf TypeV2I | ||
408 | uniformV3I = uniformOf TypeV3I | ||
409 | uniformV4I = uniformOf TypeV4I | ||
410 | |||
411 | {- | ||
412 | Note: This works to infer the type Float for literals without fixing the matrix type: | ||
413 | |||
414 | type family MatrixComponent m where | ||
415 | MatrixComponent (f (g c)) = c | ||
416 | MatrixComponent (f c) = c | ||
417 | |||
418 | uniformM44F :: ( MatrixComponent a ~ Float , GLData a (GLMatrix 4 4 Float)) | ||
419 | => String -> Map String GLUniform -> a -> IO () | ||
420 | |||
421 | However, it breaks the ability to partially apply without a type signature. | ||
422 | Therefore, I'm forcing LambdaCube's internal matrix types for uniformM* | ||
423 | functions. | ||
424 | -} | ||
425 | uniformM22F :: (Show name, Ord name) => name -> Map name GLUniform -> M22F -> IO () | ||
426 | uniformM23F :: (Show name, Ord name) => name -> Map name GLUniform -> M23F -> IO () | ||
427 | uniformM24F :: (Show name, Ord name) => name -> Map name GLUniform -> M24F -> IO () | ||
428 | uniformM32F :: (Show name, Ord name) => name -> Map name GLUniform -> M32F -> IO () | ||
429 | uniformM33F :: (Show name, Ord name) => name -> Map name GLUniform -> M33F -> IO () | ||
430 | uniformM34F :: (Show name, Ord name) => name -> Map name GLUniform -> M34F -> IO () | ||
431 | uniformM42F :: (Show name, Ord name) => name -> Map name GLUniform -> M42F -> IO () | ||
432 | uniformM43F :: (Show name, Ord name) => name -> Map name GLUniform -> M43F -> IO () | ||
433 | uniformM44F :: (Show name, Ord name) => name -> Map name GLUniform -> M44F -> IO () | ||
434 | uniformM22F = uniformOf TypeM22F | ||
435 | uniformM23F = uniformOf TypeM23F | ||
436 | uniformM24F = uniformOf TypeM24F | ||
437 | uniformM32F = uniformOf TypeM32F | ||
438 | uniformM33F = uniformOf TypeM33F | ||
439 | uniformM34F = uniformOf TypeM34F | ||
440 | uniformM42F = uniformOf TypeM42F | ||
441 | uniformM43F = uniformOf TypeM43F | ||
442 | uniformM44F = uniformOf TypeM44F | ||