module Graphics.Rendering.Ombra.Shader.CPU (
CPUSetterType(..),
CPU,
CPUBase,
CPUMirror,
BaseUniform(..),
BaseAttribute(..),
Uniform(..),
Attribute(..),
toGPUBool
) where
import Data.Int
import Data.Typeable
import Graphics.Rendering.Ombra.Shader.Language.Types
import Graphics.Rendering.Ombra.Internal.GL
import Graphics.Rendering.Ombra.Vector
import GHC.Generics hiding (S)
import qualified GHC.Generics as G
import Prelude as CPU
data CPUSetterType k
= S
| M
type family CPU (s :: CPUSetterType *) g where
CPU 'S x = CPUSingle x
CPU 'M x = CPUMirror x
type family CPUBase g
type family CPUMirror g
class BaseUniform g where
setUniform :: UniformLocation -> proxy g -> CPUBase g -> GL ()
class ShaderType g => BaseAttribute g where
encodeAttribute :: proxy g -> [CPUBase g] -> GL AnyArray
setAttribute :: proxy g -> GLUInt -> GL ()
class Generic g => Uniform (s :: CPUSetterType *) g where
withUniforms :: Applicative f
=> proxy s
-> g
-> CPU s g
-> (forall g. BaseUniform g => Int -> Proxy g
-> CPUBase g -> f ())
-> f ()
class Generic g => Attribute (s :: CPUSetterType *) g where
withAttributes :: Applicative f
=> proxy s
-> g
-> [CPU s g]
-> (forall g. BaseAttribute g => Int -> Proxy g
-> [CPUBase g] -> f ())
-> f ()
instance (BaseUniform (GGPUValue (Rep g)), Generic g) => Uniform S g where
withUniforms _ (_ :: g) c f =
f 0 (Proxy :: Proxy (GGPUValue (Rep g))) c
instance (BaseAttribute (GGPUValue (Rep g)), Generic g) => Attribute S g where
withAttributes _ (_ :: g) c f =
f 0 (Proxy :: Proxy (GGPUValue (Rep g))) c
instance ( GUniformMirror (Rep g) (Rep (CPUMirror g))
(TData (Rep (CPUMirror g)))
(TCons (Rep (CPUMirror g)))
, Generic g, Generic (CPUMirror g) )
=> Uniform M g where
withUniforms _ (g :: g) c f =
fst $ gWithUniformMirror
(Proxy :: Proxy (MTuple (TData (Rep (CPUMirror g)))
(TCons (Rep (CPUMirror g)))) )
0 (from g) (from c) f
type family TData (g :: * -> *) :: Meta where
TData (M1 D d a) = d
type family TCons (g :: * -> *) :: Meta where
TCons (M1 D d a) = TCons a
TCons (M1 C c a) = c
type family GGPUValue (g :: * -> *) where
GGPUValue (M1 i c a) = GGPUValue a
GGPUValue (K1 i a) = a
type CPUSingle g = GCPUSingle (Rep g)
type GCPUSingle g = CPUBase (GGPUValue g)
type family GCPUMirror (g :: * -> *) d c :: * -> * where
GCPUMirror (a :*: b) d c = GCPUMirror a d c :*: GCPUMirror b d c
GCPUMirror (M1 D gd a) d c = M1 D d (GCPUMirror a d c)
GCPUMirror (M1 C gc a) d c = M1 C c (GCPUMirror a d c)
GCPUMirror (M1 G.S s a) d c = M1 G.S s (GCPUMirror a d c)
GCPUMirror (K1 i a) d c = K1 i (CPUBase a)
data MTuple (d :: k) (c :: k)
class GUniformMirror (g :: * -> *) (m :: * -> *) (d :: Meta) (c :: Meta) where
gWithUniformMirror :: Applicative f
=> proxy (MTuple d c)
-> Int
-> g a
-> m b
-> (forall u. BaseUniform u => Int -> Proxy u
-> CPUBase u -> f ())
-> (f (), Int)
instance ( GUniformMirror a (GCPUMirror a d c) d c
, GUniformMirror b (GCPUMirror b d c) d c
, m ~ GCPUMirror (a :*: b) d c )
=> GUniformMirror (a :*: b) m d c where
gWithUniformMirror p i (x :*: y) (mx :*: my) f =
let (a1, i') = gWithUniformMirror p i x mx f
(a2, i'') = gWithUniformMirror p i' y my f
in (a1 *> a2, i'')
instance ( GUniformMirror a ma d c
, M1 mi mv ma ~ GCPUMirror (M1 i v a) d c )
=> GUniformMirror (M1 i v a) (M1 mi mv ma) d c where
gWithUniformMirror p i (M1 x) (M1 mx) = gWithUniformMirror p i x mx
instance (BaseUniform a, m ~ GCPUMirror (K1 i a) d c)
=> GUniformMirror (K1 i a) m d c where
gWithUniformMirror _ i (K1 (_ :: t)) (K1 mx) f =
(f i (Proxy :: Proxy t) mx, i + 1)
type instance CPUBase GFloat = Float
type instance CPUBase (GArray n GFloat) = [Float]
instance GLES => BaseUniform GFloat where
setUniform l _ = uniform1f l
instance GLES => BaseUniform (GArray n GFloat) where
setUniform l _ v = liftIO (encodeFloats v) >>= uniform1fv l
instance GLES => BaseAttribute GFloat where
encodeAttribute _ a = liftIO . fmap fromFloat32Array $ encodeFloats a
setAttribute _ i = attr gl_FLOAT i 1
type instance CPUBase GBool = Int32
type instance CPUBase (GArray n GBool) = [Int32]
instance GLES => BaseUniform GBool where
setUniform l _ = uniform1i l
instance GLES => BaseUniform (GArray n GBool) where
setUniform l _ v = liftIO (encodeInts v) >>= uniform1iv l
instance GLES => BaseAttribute GBool where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeInts a
setAttribute _ i = attr gl_INT i 1
type instance CPUBase GInt = Int32
type instance CPUBase (GArray n GInt) = [Int32]
instance GLES => BaseUniform GInt where
setUniform l _ = uniform1i l
instance GLES => BaseUniform (GArray n GInt) where
setUniform l _ v = liftIO (encodeInts v) >>= uniform1iv l
instance GLES => BaseAttribute GInt where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeInts a
setAttribute _ i = attr gl_INT i 1
type instance CPUBase GSampler2D = ActiveTexture
type instance CPUBase GSamplerCube = ActiveTexture
instance GLES => BaseUniform GSampler2D where
setUniform l _ (ActiveTexture v) = uniform1i l $ fromIntegral v
instance GLES => BaseUniform GSamplerCube where
setUniform l _ (ActiveTexture v) = uniform1i l $ fromIntegral v
type instance CPUBase GVec2 = Vec2
type instance CPUBase (GArray n GVec2) = [Vec2]
instance GLES => BaseUniform GVec2 where
setUniform l _ (Vec2 x y) = uniform2f l x y
instance GLES => BaseUniform (GArray n GVec2) where
setUniform l _ v = liftIO (encodeVec2s v) >>= uniform2fv l
instance GLES => BaseAttribute GVec2 where
encodeAttribute _ a = liftIO . fmap fromFloat32Array $ encodeVec2s a
setAttribute _ i = attr gl_FLOAT i 2
type instance CPUBase GVec3 = Vec3
type instance CPUBase (GArray n GVec3) = [Vec3]
instance GLES => BaseUniform GVec3 where
setUniform l _ (Vec3 x y z) = uniform3f l x y z
instance GLES => BaseUniform (GArray n GVec3) where
setUniform l _ v = liftIO (encodeVec3s v) >>= uniform3fv l
instance GLES => BaseAttribute GVec3 where
encodeAttribute _ a = liftIO . fmap fromFloat32Array $ encodeVec3s a
setAttribute _ i = attr gl_FLOAT i 3
type instance CPUBase GVec4 = Vec4
type instance CPUBase (GArray n GVec4) = [Vec4]
instance GLES => BaseUniform GVec4 where
setUniform l _ (Vec4 x y z w) = uniform4f l x y z w
instance GLES => BaseUniform (GArray n GVec4) where
setUniform l _ v = liftIO (encodeVec4s v) >>= uniform4fv l
instance GLES => BaseAttribute GVec4 where
encodeAttribute _ a = liftIO . fmap fromFloat32Array $ encodeVec4s a
setAttribute _ i = attr gl_FLOAT i 4
type instance CPUBase GIVec2 = IVec2
type instance CPUBase (GArray n GIVec2) = [IVec2]
instance GLES => BaseUniform GIVec2 where
setUniform l _ (IVec2 x y) = uniform2i l x y
instance GLES => BaseUniform (GArray n GIVec2) where
setUniform l _ v = liftIO (encodeIVec2s v) >>= uniform2iv l
instance GLES => BaseAttribute GIVec2 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec2s a
setAttribute _ i = attr gl_INT i 2
type instance CPUBase GIVec3 = IVec3
type instance CPUBase (GArray n GIVec3) = [IVec3]
instance GLES => BaseUniform GIVec3 where
setUniform l _ (IVec3 x y z) = uniform3i l x y z
instance GLES => BaseUniform (GArray n GIVec3) where
setUniform l _ v = liftIO (encodeIVec3s v) >>= uniform3iv l
instance GLES => BaseAttribute GIVec3 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec3s a
setAttribute _ i = attr gl_INT i 3
type instance CPUBase GIVec4 = IVec4
type instance CPUBase (GArray n GIVec4) = [IVec4]
instance GLES => BaseUniform GIVec4 where
setUniform l _ (IVec4 x y z w) = uniform4i l x y z w
instance GLES => BaseUniform (GArray n GIVec4) where
setUniform l _ v = liftIO (encodeIVec4s v) >>= uniform4iv l
instance GLES => BaseAttribute GIVec4 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec4s a
setAttribute _ i = attr gl_INT i 4
type instance CPUBase GBVec2 = IVec2
type instance CPUBase (GArray n GBVec2) = [IVec2]
instance GLES => BaseUniform GBVec2 where
setUniform l _ (IVec2 x y) = uniform2i l x y
instance GLES => BaseUniform (GArray n GBVec2) where
setUniform l _ v = liftIO (encodeIVec2s v) >>= uniform2iv l
instance GLES => BaseAttribute GBVec2 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec2s a
setAttribute _ i = attr gl_INT i 2
type instance CPUBase GBVec3 = IVec3
type instance CPUBase (GArray n GBVec3) = [IVec3]
instance GLES => BaseUniform GBVec3 where
setUniform l _ (IVec3 x y z) = uniform3i l x y z
instance GLES => BaseUniform (GArray n GBVec3) where
setUniform l _ v = liftIO (encodeIVec3s v) >>= uniform3iv l
instance GLES => BaseAttribute GBVec3 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec3s a
setAttribute _ i = attr gl_INT i 3
type instance CPUBase GBVec4 = IVec4
type instance CPUBase (GArray n GBVec4) = [IVec4]
instance GLES => BaseUniform GBVec4 where
setUniform l _ (IVec4 x y z w) = uniform4i l x y z w
instance GLES => BaseUniform (GArray n GBVec4) where
setUniform l _ v = liftIO (encodeIVec4s v) >>= uniform4iv l
instance GLES => BaseAttribute GBVec4 where
encodeAttribute _ a = liftIO . fmap fromInt32Array $ encodeIVec4s a
setAttribute _ i = attr gl_INT i 4
type instance CPUBase GMat2 = Mat2
type instance CPUBase GMat3 = Mat3
type instance CPUBase GMat4 = Mat4
instance GLES => BaseUniform GMat2 where
setUniform l _ m = liftIO (encodeMat2 m) >>= uniformMatrix2fv l false
instance GLES => BaseUniform GMat3 where
setUniform l _ m = liftIO (encodeMat3 m) >>= uniformMatrix3fv l false
instance GLES => BaseUniform GMat4 where
setUniform l _ m = liftIO (encodeMat4 m) >>= uniformMatrix4fv l false
class BaseUniforms (xs :: [*])
instance BaseUniform x => BaseUniforms (x ': '[])
instance (BaseUniform x, BaseUniforms (y ': xs)) =>
BaseUniforms (x ': y ': xs)
class BaseAttributes (xs :: [*])
instance BaseAttribute x => BaseAttributes (x ': '[])
instance (BaseAttribute x, BaseAttributes (y ': xs)) =>
BaseAttributes (x ': y ': xs)
attr :: GLES => GLEnum -> GLUInt -> GLInt -> GL ()
attr t i s = vertexAttribPointer i s t false 0 nullGLPtr
toGPUBool :: Bool -> Int32
toGPUBool True = 1
toGPUBool False = 0