{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeFamilies, TypeSynonymInstances, FlexibleContexts, FlexibleInstances, ScopedTypeVariables, Arrows, GeneralizedNewtypeDeriving, PatternSynonyms #-}
module Graphics.GPipe.Internal.PrimitiveStream where
import Control.Arrow
import Control.Monad.Trans.Class
import Control.Monad.Trans.State.Strict
import Control.Monad.Trans.Reader
import Prelude hiding (length, id, (.))
import Graphics.GPipe.Internal.Buffer
import Graphics.GPipe.Internal.Expr
import Graphics.GPipe.Internal.Shader
import Graphics.GPipe.Internal.Compiler
import Graphics.GPipe.Internal.PrimitiveArray
import Graphics.GPipe.Internal.Context
import Graphics.GPipe.Internal.Uniform
import Control.Category
import Control.Arrow
import Control.Monad (void, when)
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup (Semigroup(..))
#endif
import Data.IntMap.Lazy (insert)
import Data.Word
import Data.Int
import Foreign.Marshal (alloca)
import Foreign.Storable
import Foreign.Ptr
import qualified Data.IntMap as Map
import Graphics.GL.Core45
import Graphics.GL.Types
import Foreign.Marshal.Utils
import Data.IORef
import Linear.V4
import Linear.V3
import Linear.V2
import Linear.V1
import Linear.V0
import Linear.Plucker (Plucker(..))
import Linear.Quaternion (Quaternion(..))
import Linear.Affine (Point(..))
import Data.Maybe (fromMaybe)
import System.IO
import Control.Monad.IO.Class
import Graphics.GPipe.Internal.Debug
type PrimitiveName = Int
type USize = Int
data PrimitiveStreamData = PrimitiveStreamData PrimitiveName USize
newtype PrimitiveStream t a = PrimitiveStream [(a, (Maybe PointSize, PrimitiveStreamData))] deriving (Semigroup, Monoid)
instance Functor (PrimitiveStream t) where
fmap f (PrimitiveStream xs) = PrimitiveStream $ map (first f) xs
class VertexInput a where
type VertexFormat a
toVertex :: ToVertex a (VertexFormat a)
type UniOffset = Int
data ToVertex a b = ToVertex
!( Kleisli
( StateT (Ptr ()) IO
) a b)
!( Kleisli
( StateT
( Int
, UniOffset
, OffsetToSType
)
( Reader
( Int -> ExprM String
)
)
) a b)
!( Kleisli
( State
[ Binding -> (IO VAOKey, IO ())
]
) a b)
instance Category ToVertex where
{-# INLINE id #-}
id = ToVertex id id id
{-# INLINE (.) #-}
ToVertex a b c . ToVertex x y z = ToVertex (a.x) (b.y) (c.z)
instance Arrow ToVertex where
{-# INLINE arr #-}
arr f = ToVertex (arr f) (arr f) (arr f)
{-# INLINE first #-}
first (ToVertex a b c) = ToVertex (first a) (first b) (first c)
toPrimitiveStream :: forall os f s a p. (PrimitiveTopology p, VertexInput a) => (s -> PrimitiveArray p a) -> Shader os s (PrimitiveStream p (VertexFormat a))
toPrimitiveStream = toPrimitiveStream' Nothing
toPrimitiveStream' :: forall os f s a b p. (PrimitiveTopology p, VertexInput a) => Maybe (s -> Buffer os b) -> (s -> PrimitiveArray p a) -> Shader os s (PrimitiveStream p (VertexFormat a))
toPrimitiveStream' getFeedbackBuffer sf = Shader $ do
n <- getNewName
uniAl <- askUniformAlignment
let
err = error "toPrimitiveStream is creating values that are dependant on the actual HostFormat values, this is not allowed since it doesn't allow static creation of shaders"
(x, (_, uSize, offToStype)) = runReader
(runStateT (makeV err) (0, 0, mempty))
(useUniform (buildUDecl offToStype) 0)
doForInputArray n $ \s ->
let
fb = getFeedbackBuffer >>= \g -> return (g s)
ps = getPrimitiveArray (sf s)
in
map drawcall (map (\p -> (fb, p)) ps)
return $ PrimitiveStream [(x, (Nothing, PrimitiveStreamData n uSize))]
where
ToVertex
(Kleisli uWriter)
(Kleisli makeV)
(Kleisli makeBind)
= toVertex :: ToVertex a (VertexFormat a)
drawcall (Just feedbackBuffer, PrimitiveArraySimple p l s a) binds = (attribs a binds, do
Just (tfName, tfqName) <- readIORef (bufTransformFeedback feedbackBuffer)
if False
then glDrawTransformFeedback (toGLtopology p) tfName
else do
l' <- (fromIntegral (toPrimitiveSize p) *) <$> (alloca $ \ptr -> do
glGetQueryObjectiv tfqName GL_QUERY_RESULT ptr
peek ptr)
when (l' > 0) $ do
glDrawArrays (toGLtopology p) (fromIntegral s) l'
)
drawcall (Just feedbackBuffer, PrimitiveArrayInstanced p il l s a) binds = (attribs a binds, do
Just (tfName, _) <- readIORef (bufTransformFeedback feedbackBuffer)
glDrawTransformFeedbackInstanced (toGLtopology p) tfName (fromIntegral il))
drawcall (Nothing, PrimitiveArraySimple p l s a) binds = (attribs a binds, do
glDrawArrays (toGLtopology p) (fromIntegral s) (fromIntegral l))
drawcall (Nothing, PrimitiveArrayIndexed p i s a) binds = (attribs a binds, do
bindIndexBuffer i
glDrawElementsBaseVertex (toGLtopology p) (fromIntegral $ indexArrayLength i) (indexType i) (intPtrToPtr $ fromIntegral $ offset i * glSizeOf (indexType i)) (fromIntegral s))
drawcall (Nothing, PrimitiveArrayInstanced p il l s a) binds = (attribs a binds, do
glDrawArraysInstanced (toGLtopology p) (fromIntegral s) (fromIntegral l) (fromIntegral il))
drawcall (Nothing, PrimitiveArrayIndexedInstanced p i il s a) binds = (attribs a binds, do
bindIndexBuffer i
glDrawElementsInstancedBaseVertex (toGLtopology p) (fromIntegral $ indexArrayLength i) (indexType i) (intPtrToPtr $ fromIntegral $ offset i * glSizeOf (indexType i)) (fromIntegral il) (fromIntegral s))
bindIndexBuffer i = do
case restart i of
Just x -> do
glEnable GL_PRIMITIVE_RESTART
glPrimitiveRestartIndex (fromIntegral x)
Nothing ->
glDisable GL_PRIMITIVE_RESTART
bname <- readIORef (iArrName i)
glBindBuffer GL_ELEMENT_ARRAY_BUFFER bname
glSizeOf GL_UNSIGNED_INT = 4
glSizeOf GL_UNSIGNED_SHORT = 2
glSizeOf GL_UNSIGNED_BYTE = 1
glSizeOf _ = error "toPrimitiveStream: Unknown indexArray type"
assignIxs :: Int -> Binding -> [Int] -> [Binding -> (IO VAOKey, IO ())] -> [(IO VAOKey, IO ())]
assignIxs n ix xxs@(x:xs) (f:fs) | x == n = f ix : assignIxs (n+1) (ix+1) xs fs
| otherwise = assignIxs (n+1) ix xxs fs
assignIxs _ _ [] _ = []
assignIxs _ _ _ _ = error "Too few attributes generated in toPrimitiveStream"
attribs a (binds, uBname, uSize) = let
bindsAssoc = execState (makeBind a) []
(ioVaokeys, ios) = unzip $ assignIxs 0 0 binds $ reverse bindsAssoc
in (writeUBuffer uBname uSize a >> sequence ioVaokeys, sequence_ ios)
doForInputArray :: Int -> (s -> [([Binding], GLuint, Int) -> ((IO [VAOKey], IO ()), IO ())]) -> ShaderM s ()
doForInputArray n io = modifyRenderIO (\s -> s { inputArrayToRenderIO = insert n io (inputArrayToRenderIO s) } )
writeUBuffer _ 0 _ = return ()
writeUBuffer bname size a = do
error "Cannot happen!"
glBindBuffer GL_COPY_WRITE_BUFFER bname
ptr <- glMapBufferRange GL_COPY_WRITE_BUFFER 0 (fromIntegral size) (GL_MAP_WRITE_BIT + GL_MAP_INVALIDATE_BUFFER_BIT)
void $ runStateT (uWriter a) ptr
void $ glUnmapBuffer GL_COPY_WRITE_BUFFER
data InputIndices = InputIndices {
inputVertexID :: VInt,
inputInstanceID :: VInt
}
withInputIndices :: (a -> InputIndices -> b) -> PrimitiveStream p a -> PrimitiveStream p b
withInputIndices f = fmap (\a -> f a (InputIndices (scalarS' "gl_VertexID") (scalarS' "gl_InstanceID")))
type PointSize = VFloat
withPointSize :: (a -> PointSize -> (b, PointSize)) -> PrimitiveStream Points a -> PrimitiveStream Points b
withPointSize f (PrimitiveStream xs) = PrimitiveStream $ map (\(a, (ps, d)) -> let (b, ps') = f a (fromMaybe (scalarS' "1") ps) in (b, (Just ps', d))) xs
append :: Monad m => a -> StateT [a] m ()
append x = modify (x:)
makeVertexF x f styp _ = do
(n, uoffset, m) <- get
put (n + 1, uoffset, m)
return (f styp $ useVInput styp n)
makeBindVertexFx norm x typ b = do
let combOffset = bStride b * bSkipElems b + bOffset b
append (\ix ->
( do bn <- readIORef $ bName b
return $ VAOKey bn combOffset x norm (bInstanceDiv b)
, do bn <- readIORef $ bName b
let ix' = fromIntegral ix
glEnableVertexAttribArray ix'
glBindBuffer GL_ARRAY_BUFFER bn
glVertexAttribDivisor ix' (fromIntegral $ bInstanceDiv b)
glVertexAttribPointer ix' x typ (fromBool norm) (fromIntegral $ bStride b) (intPtrToPtr $ fromIntegral combOffset))
)
return undefined
makeBindVertexFnorm = makeBindVertexFx True
makeBindVertexF = makeBindVertexFx False
makeVertexI x f styp _ = do
(n, uoffset,m) <- get
put (n + 1, uoffset,m)
return (f styp $ useVInput styp n)
makeBindVertexI x typ b = do
let combOffset = bStride b * bSkipElems b + bOffset b
append (\ix ->
( do bn <- readIORef $ bName b
return $ VAOKey bn combOffset x False (bInstanceDiv b)
, do bn <- readIORef $ bName b
let ix' = fromIntegral ix
glEnableVertexAttribArray ix'
glBindBuffer GL_ARRAY_BUFFER bn
glVertexAttribDivisor ix' (fromIntegral $ bInstanceDiv b)
glVertexAttribIPointer ix' x typ (fromIntegral $ bStride b) (intPtrToPtr $ fromIntegral combOffset))
)
return undefined
noWriter = Kleisli (const $ return undefined)
toUniformVertex :: forall a b. Storable a => SType -> ToVertex a (S V b)
toUniformVertex styp = ToVertex (Kleisli uWriter) (Kleisli makeV) (Kleisli makeBind)
where
size = sizeOf (undefined :: a)
uWriter a = do
ptr <- get
put (ptr `plusPtr` size)
lift $ poke (castPtr ptr) a
return undefined
makeV a = do
(n, uoffset,m) <- get
put (n, uoffset + size, Map.insert uoffset styp m)
useF <- lift ask
return $ S $ useF uoffset
makeBind a =
return undefined
instance VertexInput Float where
type VertexFormat Float = VFloat
toVertex = toUniformVertex STypeFloat
instance VertexInput Int32 where
type VertexFormat Int32 = VInt
toVertex = toUniformVertex STypeInt
instance VertexInput Word32 where
type VertexFormat Word32 = VWord
toVertex = toUniformVertex STypeUInt
unBnorm :: Normalized t -> t
unBnorm (Normalized a) = a
instance VertexInput (B Float) where
type VertexFormat (B Float) = VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 1 (const S) STypeFloat) (Kleisli $ makeBindVertexF 1 GL_FLOAT)
instance VertexInput (Normalized (B Int32)) where
type VertexFormat (Normalized (B Int32)) = VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 1 (const S) STypeFloat . unBnorm) (Kleisli $ makeBindVertexFnorm 1 GL_INT . unBnorm)
instance VertexInput (Normalized (B Word32)) where
type VertexFormat (Normalized (B Word32)) = VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 1 (const S) STypeFloat . unBnorm) (Kleisli $ makeBindVertexFnorm 1 GL_UNSIGNED_INT . unBnorm)
instance VertexInput (B Int32) where
type VertexFormat (B Int32) = VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 1 (const S) STypeInt) (Kleisli $ makeBindVertexI 1 GL_INT)
instance VertexInput (B Word32) where
type VertexFormat (B Word32) = VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 1 (const S) STypeUInt) (Kleisli $ makeBindVertexI 1 GL_UNSIGNED_INT)
instance VertexInput (B2 Float) where
type VertexFormat (B2 Float) = V2 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 2 vec2S (STypeVec 2) . unB2) (Kleisli $ makeBindVertexF 2 GL_FLOAT . unB2)
instance VertexInput (Normalized (B2 Int32)) where
type VertexFormat (Normalized (B2 Int32)) = V2 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 2 vec2S (STypeVec 2) . unB2 . unBnorm) (Kleisli $ makeBindVertexFnorm 2 GL_INT . unB2 . unBnorm)
instance VertexInput (Normalized (B2 Int16)) where
type VertexFormat (Normalized (B2 Int16)) = V2 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 2 vec2S (STypeVec 2) . unB2 . unBnorm) (Kleisli $ makeBindVertexFnorm 2 GL_SHORT . unB2 . unBnorm)
instance VertexInput (Normalized (B2 Word32)) where
type VertexFormat (Normalized (B2 Word32)) = V2 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 2 vec2S (STypeVec 2) . unB2 . unBnorm) (Kleisli $ makeBindVertexFnorm 2 GL_UNSIGNED_INT . unB2 . unBnorm)
instance VertexInput (Normalized (B2 Word16)) where
type VertexFormat (Normalized (B2 Word16)) = V2 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 2 vec2S (STypeVec 2) . unB2 . unBnorm) (Kleisli $ makeBindVertexFnorm 2 GL_UNSIGNED_SHORT . unB2 . unBnorm)
instance VertexInput (B2 Int32) where
type VertexFormat (B2 Int32) = V2 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 2 vec2S (STypeIVec 2) . unB2) (Kleisli $ makeBindVertexI 2 GL_INT . unB2)
instance VertexInput (B2 Int16) where
type VertexFormat (B2 Int16) = V2 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 2 vec2S (STypeIVec 2) . unB2) (Kleisli $ makeBindVertexI 2 GL_SHORT . unB2)
instance VertexInput (B2 Word32) where
type VertexFormat (B2 Word32) = V2 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 2 vec2S (STypeUVec 2) . unB2) (Kleisli $ makeBindVertexI 2 GL_UNSIGNED_INT . unB2)
instance VertexInput (B2 Word16) where
type VertexFormat (B2 Word16) = V2 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 2 vec2S (STypeUVec 2) . unB2) (Kleisli $ makeBindVertexI 2 GL_UNSIGNED_SHORT . unB2)
instance VertexInput (B3 Float) where
type VertexFormat (B3 Float) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3) (Kleisli $ makeBindVertexF 3 GL_FLOAT . unB3)
instance VertexInput (Normalized (B3 Int32)) where
type VertexFormat (Normalized (B3 Int32)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_INT . unB3 . unBnorm)
instance VertexInput (Normalized (B3 Int16)) where
type VertexFormat (Normalized (B3 Int16)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_SHORT . unB3 . unBnorm)
instance VertexInput (Normalized (B3 Int8)) where
type VertexFormat (Normalized (B3 Int8)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_BYTE . unB3 . unBnorm)
instance VertexInput (Normalized (B3 Word32)) where
type VertexFormat (Normalized (B3 Word32)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_UNSIGNED_INT . unB3 . unBnorm)
instance VertexInput (Normalized (B3 Word16)) where
type VertexFormat (Normalized (B3 Word16)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_UNSIGNED_SHORT . unB3 . unBnorm)
instance VertexInput (Normalized (B3 Word8)) where
type VertexFormat (Normalized (B3 Word8)) = V3 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 3 vec3S (STypeVec 3) . unB3 . unBnorm) (Kleisli $ makeBindVertexFnorm 3 GL_UNSIGNED_BYTE . unB3 . unBnorm)
instance VertexInput (B3 Int32) where
type VertexFormat (B3 Int32) = V3 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeIVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_INT . unB3)
instance VertexInput (B3 Int16) where
type VertexFormat (B3 Int16) = V3 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeIVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_SHORT . unB3)
instance VertexInput (B3 Int8) where
type VertexFormat (B3 Int8) = V3 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeIVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_BYTE . unB3)
instance VertexInput (B3 Word32) where
type VertexFormat (B3 Word32) = V3 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeUVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_UNSIGNED_INT . unB3)
instance VertexInput (B3 Word16) where
type VertexFormat (B3 Word16) = V3 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeUVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_UNSIGNED_SHORT . unB3)
instance VertexInput (B3 Word8) where
type VertexFormat (B3 Word8) = V3 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 3 vec3S (STypeUVec 3) . unB3) (Kleisli $ makeBindVertexI 3 GL_UNSIGNED_BYTE . unB3)
instance VertexInput (B4 Float) where
type VertexFormat (B4 Float) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4) (Kleisli $ makeBindVertexF 4 GL_FLOAT . unB4)
instance VertexInput (Normalized (B4 Int32)) where
type VertexFormat (Normalized (B4 Int32)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_INT . unB4 . unBnorm)
instance VertexInput (Normalized (B4 Int16)) where
type VertexFormat (Normalized (B4 Int16)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_SHORT . unB4 . unBnorm)
instance VertexInput (Normalized (B4 Int8)) where
type VertexFormat (Normalized (B4 Int8)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_BYTE . unB4 . unBnorm)
instance VertexInput (Normalized (B4 Word32)) where
type VertexFormat (Normalized (B4 Word32)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_UNSIGNED_INT . unB4 . unBnorm)
instance VertexInput (Normalized (B4 Word16)) where
type VertexFormat (Normalized (B4 Word16)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_UNSIGNED_SHORT . unB4 . unBnorm)
instance VertexInput (Normalized (B4 Word8)) where
type VertexFormat (Normalized (B4 Word8)) = V4 VFloat
toVertex = ToVertex noWriter (Kleisli $ makeVertexF 4 vec4S (STypeVec 4) . unB4 . unBnorm) (Kleisli $ makeBindVertexFnorm 4 GL_UNSIGNED_BYTE . unB4 . unBnorm)
instance VertexInput (B4 Int32) where
type VertexFormat (B4 Int32) = V4 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeIVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_INT . unB4)
instance VertexInput (B4 Int16) where
type VertexFormat (B4 Int16) = V4 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeIVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_SHORT . unB4)
instance VertexInput (B4 Int8) where
type VertexFormat (B4 Int8) = V4 VInt
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeIVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_BYTE . unB4)
instance VertexInput (B4 Word32) where
type VertexFormat (B4 Word32) = V4 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeUVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_UNSIGNED_INT . unB4)
instance VertexInput (B4 Word16) where
type VertexFormat (B4 Word16) = V4 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeUVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_UNSIGNED_SHORT . unB4)
instance VertexInput (B4 Word8) where
type VertexFormat (B4 Word8) = V4 VWord
toVertex = ToVertex noWriter (Kleisli $ makeVertexI 4 vec4S (STypeUVec 4) . unB4) (Kleisli $ makeBindVertexI 4 GL_UNSIGNED_BYTE . unB4)
instance VertexInput () where
type VertexFormat () = ()
toVertex = arr (const ())
instance (VertexInput a, VertexInput b) => VertexInput (a,b) where
type VertexFormat (a,b) = (VertexFormat a, VertexFormat b)
toVertex = proc ~(a,b) -> do a' <- toVertex -< a
b' <- toVertex -< b
returnA -< (a', b')
instance (VertexInput a, VertexInput b, VertexInput c) => VertexInput (a,b,c) where
type VertexFormat (a,b,c) = (VertexFormat a, VertexFormat b, VertexFormat c)
toVertex = proc ~(a,b,c) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
returnA -< (a', b', c')
instance (VertexInput a, VertexInput b, VertexInput c, VertexInput d) => VertexInput (a,b,c,d) where
type VertexFormat (a,b,c,d) = (VertexFormat a, VertexFormat b, VertexFormat c, VertexFormat d)
toVertex = proc ~(a,b,c,d) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
returnA -< (a', b', c', d')
instance (VertexInput a, VertexInput b, VertexInput c, VertexInput d, VertexInput e) => VertexInput (a,b,c,d,e) where
type VertexFormat (a,b,c,d,e) = (VertexFormat a, VertexFormat b, VertexFormat c, VertexFormat d, VertexFormat e)
toVertex = proc ~(a,b,c,d,e) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
e' <- toVertex -< e
returnA -< (a', b', c', d', e')
instance (VertexInput a, VertexInput b, VertexInput c, VertexInput d, VertexInput e, VertexInput f) => VertexInput (a,b,c,d,e,f) where
type VertexFormat (a,b,c,d,e,f) = (VertexFormat a, VertexFormat b, VertexFormat c, VertexFormat d, VertexFormat e, VertexFormat f)
toVertex = proc ~(a,b,c,d,e,f) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
e' <- toVertex -< e
f' <- toVertex -< f
returnA -< (a', b', c', d', e', f')
instance (VertexInput a, VertexInput b, VertexInput c, VertexInput d, VertexInput e, VertexInput f, VertexInput g) => VertexInput (a,b,c,d,e,f,g) where
type VertexFormat (a,b,c,d,e,f,g) = (VertexFormat a, VertexFormat b, VertexFormat c, VertexFormat d, VertexFormat e, VertexFormat f, VertexFormat g)
toVertex = proc ~(a,b,c,d,e,f,g) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
e' <- toVertex -< e
f' <- toVertex -< f
g' <- toVertex -< g
returnA -< (a', b', c', d', e', f', g')
instance VertexInput a => VertexInput (V0 a) where
type VertexFormat (V0 a) = V0 (VertexFormat a)
toVertex = arr (const V0)
instance VertexInput a => VertexInput (V1 a) where
type VertexFormat (V1 a) = V1 (VertexFormat a)
toVertex = proc ~(V1 a) -> do a' <- toVertex -< a
returnA -< V1 a'
instance VertexInput a => VertexInput (V2 a) where
type VertexFormat (V2 a) = V2 (VertexFormat a)
toVertex = proc ~(V2 a b) -> do a' <- toVertex -< a
b' <- toVertex -< b
returnA -< V2 a' b'
instance VertexInput a => VertexInput (V3 a) where
type VertexFormat (V3 a) = V3 (VertexFormat a)
toVertex = proc ~(V3 a b c) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
returnA -< V3 a' b' c'
instance VertexInput a => VertexInput (V4 a) where
type VertexFormat (V4 a) = V4 (VertexFormat a)
toVertex = proc ~(V4 a b c d) -> do a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
returnA -< V4 a' b' c' d'
instance VertexInput a => VertexInput (Quaternion a) where
type VertexFormat (Quaternion a) = Quaternion (VertexFormat a)
toVertex = proc ~(Quaternion a v) -> do
a' <- toVertex -< a
v' <- toVertex -< v
returnA -< Quaternion a' v'
instance (VertexInput (f a), VertexInput a, HostFormat (f a) ~ f (HostFormat a), VertexFormat (f a) ~ f (VertexFormat a)) => VertexInput (Point f a) where
type VertexFormat (Point f a) = Point f (VertexFormat a)
toVertex = proc ~(P a) -> do
a' <- toVertex -< a
returnA -< P a'
instance VertexInput a => VertexInput (Plucker a) where
type VertexFormat (Plucker a) = Plucker (VertexFormat a)
toVertex = proc ~(Plucker a b c d e f) -> do
a' <- toVertex -< a
b' <- toVertex -< b
c' <- toVertex -< c
d' <- toVertex -< d
e' <- toVertex -< e
f' <- toVertex -< f
returnA -< Plucker a' b' c' d' e' f'