diff options
Diffstat (limited to 'src/LambdaCube/GL/Util.hs')
-rw-r--r-- | src/LambdaCube/GL/Util.hs | 205 |
1 files changed, 144 insertions, 61 deletions
diff --git a/src/LambdaCube/GL/Util.hs b/src/LambdaCube/GL/Util.hs index fbc0f50..071e86b 100644 --- a/src/LambdaCube/GL/Util.hs +++ b/src/LambdaCube/GL/Util.hs | |||
@@ -1,8 +1,12 @@ | |||
1 | {-# LANGUAGE RecordWildCards #-} | 1 | {-# LANGUAGE DataKinds #-} |
2 | {-# LANGUAGE FlexibleInstances #-} | ||
3 | {-# LANGUAGE GADTs #-} | ||
4 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
5 | {-# LANGUAGE RecordWildCards #-} | ||
2 | module LambdaCube.GL.Util ( | 6 | module LambdaCube.GL.Util ( |
3 | queryUniforms, | 7 | queryUniforms, |
4 | queryStreams, | 8 | queryStreams, |
5 | mkUniformSetter, | 9 | initializeUniform, |
6 | setUniform, | 10 | setUniform, |
7 | setVertexAttrib, | 11 | setVertexAttrib, |
8 | compileShader, | 12 | compileShader, |
@@ -28,7 +32,9 @@ module LambdaCube.GL.Util ( | |||
28 | compileTexture, | 32 | compileTexture, |
29 | primitiveToFetchPrimitive, | 33 | primitiveToFetchPrimitive, |
30 | primitiveToGLType, | 34 | primitiveToGLType, |
31 | inputTypeToTextureTarget | 35 | inputTypeToTextureTarget, |
36 | TypeMismatch(..), | ||
37 | typeMismatch | ||
32 | ) where | 38 | ) where |
33 | 39 | ||
34 | import Control.Applicative | 40 | import Control.Applicative |
@@ -43,12 +49,17 @@ import Data.Vector.Unboxed.Mutable (IOVector) | |||
43 | import qualified Data.Vector.Unboxed.Mutable as MV | 49 | import qualified Data.Vector.Unboxed.Mutable as MV |
44 | import Data.Map (Map) | 50 | import Data.Map (Map) |
45 | import qualified Data.Map as Map | 51 | import qualified Data.Map as Map |
52 | import Data.Typeable | ||
53 | import Data.Dependent.Sum | ||
54 | import qualified Data.Dependent.Map as DMap | ||
55 | import Data.Some | ||
46 | 56 | ||
47 | import Graphics.GL.Core33 | 57 | import Graphics.GL.Core33 |
48 | import LambdaCube.Linear | 58 | import LambdaCube.Linear |
49 | import LambdaCube.IR | 59 | import LambdaCube.IR |
50 | import LambdaCube.PipelineSchema | 60 | import LambdaCube.PipelineSchema |
51 | import LambdaCube.GL.Type | 61 | import LambdaCube.GL.Type |
62 | import LambdaCube.GL.Input.Type | ||
52 | 63 | ||
53 | setSampler :: GLint -> Int32 -> IO () | 64 | setSampler :: GLint -> Int32 -> IO () |
54 | setSampler i v = glUniform1i i $ fromIntegral v | 65 | setSampler i v = glUniform1i i $ fromIntegral v |
@@ -70,67 +81,138 @@ b2w :: Bool -> GLuint | |||
70 | b2w True = 1 | 81 | b2w True = 1 |
71 | b2w False = 0 | 82 | b2w False = 0 |
72 | 83 | ||
73 | mkUniformSetter :: InputType -> IO (GLUniform, InputSetter) | 84 | instance GLData Bool (GLVector 1 GLuint) where |
74 | mkUniformSetter t@Bool = do {r <- newIORef 0; return $! (GLUniform t r, SBool $! writeIORef r . b2w)} | 85 | marshalUniform _ b = Just $ MarshalGLVector $ \f -> with (b2w b) (f 1) |
75 | mkUniformSetter t@V2B = do {r <- newIORef (V2 0 0); return $! (GLUniform t r, SV2B $! writeIORef r . fmap b2w)} | 86 | instance GLData (V2 Bool) (GLVector 2 GLuint) where |
76 | mkUniformSetter t@V3B = do {r <- newIORef (V3 0 0 0); return $! (GLUniform t r, SV3B $! writeIORef r . fmap b2w)} | 87 | marshalUniform _ b = Just $ MarshalGLVector $ \f -> with (b2w <$> b) (f 1 . castPtr) |
77 | mkUniformSetter t@V4B = do {r <- newIORef (V4 0 0 0 0); return $! (GLUniform t r, SV4B $! writeIORef r . fmap b2w)} | 88 | instance GLData (V3 Bool) (GLVector 3 GLuint) where |
78 | mkUniformSetter t@Word = do {r <- newIORef 0; return $! (GLUniform t r, SWord $! writeIORef r)} | 89 | marshalUniform _ b = Just $ MarshalGLVector $ \f -> with (b2w <$> b) (f 1 . castPtr) |
79 | mkUniformSetter t@V2U = do {r <- newIORef (V2 0 0); return $! (GLUniform t r, SV2U $! writeIORef r)} | 90 | instance GLData (V4 Bool) (GLVector 4 GLuint) where |
80 | mkUniformSetter t@V3U = do {r <- newIORef (V3 0 0 0); return $! (GLUniform t r, SV3U $! writeIORef r)} | 91 | marshalUniform _ b = Just $ MarshalGLVector $ \f -> with (b2w <$> b) (f 1 . castPtr) |
81 | mkUniformSetter t@V4U = do {r <- newIORef (V4 0 0 0 0); return $! (GLUniform t r, SV4U $! writeIORef r)} | 92 | instance Uniformable Bool where uniformContexts _ = contexts $ supports TypeBool |
82 | mkUniformSetter t@Int = do {r <- newIORef 0; return $! (GLUniform t r, SInt $! writeIORef r)} | 93 | instance Uniformable (V2 Bool) where uniformContexts _ = contexts $ supports TypeV2B |
83 | mkUniformSetter t@V2I = do {r <- newIORef (V2 0 0); return $! (GLUniform t r, SV2I $! writeIORef r)} | 94 | instance Uniformable (V3 Bool) where uniformContexts _ = contexts $ supports TypeV3B |
84 | mkUniformSetter t@V3I = do {r <- newIORef (V3 0 0 0); return $! (GLUniform t r, SV3I $! writeIORef r)} | 95 | instance Uniformable (V4 Bool) where uniformContexts _ = contexts $ supports TypeV4B |
85 | mkUniformSetter t@V4I = do {r <- newIORef (V4 0 0 0 0); return $! (GLUniform t r, SV4I $! writeIORef r)} | 96 | |
86 | mkUniformSetter t@Float = do {r <- newIORef 0; return $! (GLUniform t r, SFloat $! writeIORef r)} | 97 | instance GLData Word32 (GLVector 1 GLuint) |
87 | mkUniformSetter t@V2F = do {r <- newIORef (V2 0 0); return $! (GLUniform t r, SV2F $! writeIORef r)} | 98 | instance GLData (V2 Word32) (GLVector 2 GLuint) |
88 | mkUniformSetter t@V3F = do {r <- newIORef (V3 0 0 0); return $! (GLUniform t r, SV3F $! writeIORef r)} | 99 | instance GLData (V3 Word32) (GLVector 3 GLuint) |
89 | mkUniformSetter t@V4F = do {r <- newIORef (V4 0 0 0 0); return $! (GLUniform t r, SV4F $! writeIORef r)} | 100 | instance GLData (V4 Word32) (GLVector 4 GLuint) |
90 | mkUniformSetter t@M22F = do {r <- newIORef (V2 z2 z2); return $! (GLUniform t r, SM22F $! writeIORef r)} | 101 | instance Uniformable Word32 where uniformContexts _ = contexts $ supports TypeWord |
91 | mkUniformSetter t@M23F = do {r <- newIORef (V3 z2 z2 z2); return $! (GLUniform t r, SM23F $! writeIORef r)} | 102 | instance Uniformable (V2 Word32) where uniformContexts _ = contexts $ supports TypeV2U |
92 | mkUniformSetter t@M24F = do {r <- newIORef (V4 z2 z2 z2 z2); return $! (GLUniform t r, SM24F $! writeIORef r)} | 103 | instance Uniformable (V3 Word32) where uniformContexts _ = contexts $ supports TypeV3U |
93 | mkUniformSetter t@M32F = do {r <- newIORef (V2 z3 z3); return $! (GLUniform t r, SM32F $! writeIORef r)} | 104 | instance Uniformable (V4 Word32) where uniformContexts _ = contexts $ supports TypeV4U |
94 | mkUniformSetter t@M33F = do {r <- newIORef (V3 z3 z3 z3); return $! (GLUniform t r, SM33F $! writeIORef r)} | 105 | |
95 | mkUniformSetter t@M34F = do {r <- newIORef (V4 z3 z3 z3 z3); return $! (GLUniform t r, SM34F $! writeIORef r)} | 106 | instance GLData Int32 (GLVector 1 GLint) |
96 | mkUniformSetter t@M42F = do {r <- newIORef (V2 z4 z4); return $! (GLUniform t r, SM42F $! writeIORef r)} | 107 | instance GLData (V2 Int32) (GLVector 2 GLint) |
97 | mkUniformSetter t@M43F = do {r <- newIORef (V3 z4 z4 z4); return $! (GLUniform t r, SM43F $! writeIORef r)} | 108 | instance GLData (V3 Int32) (GLVector 3 GLint) |
98 | mkUniformSetter t@M44F = do {r <- newIORef (V4 z4 z4 z4 z4); return $! (GLUniform t r, SM44F $! writeIORef r)} | 109 | instance GLData (V4 Int32) (GLVector 4 GLint) |
99 | mkUniformSetter t@FTexture2D = do {r <- newIORef (TextureData 0); return $! (GLUniform t r, SFTexture2D $! writeIORef r)} | 110 | instance Uniformable Int32 where uniformContexts _ = contexts $ supports TypeInt |
111 | instance Uniformable (V2 Int32) where uniformContexts _ = contexts $ supports TypeV2I | ||
112 | instance Uniformable (V3 Int32) where uniformContexts _ = contexts $ supports TypeV3I | ||
113 | instance Uniformable (V4 Int32) where uniformContexts _ = contexts $ supports TypeV4I | ||
114 | |||
115 | instance GLData Float (GLVector 1 GLfloat) | ||
116 | instance GLData (V2 Float) (GLVector 2 GLfloat) | ||
117 | instance GLData (V3 Float) (GLVector 3 GLfloat) | ||
118 | instance GLData (V4 Float) (GLVector 4 GLfloat) | ||
119 | instance Uniformable Float where uniformContexts _ = contexts $ supports TypeFloat | ||
120 | instance Uniformable (V2 Float) where uniformContexts _ = contexts $ supports TypeV2F | ||
121 | instance Uniformable (V3 Float) where uniformContexts _ = contexts $ supports TypeV3F | ||
122 | instance Uniformable (V4 Float) where uniformContexts _ = contexts $ supports TypeV4F | ||
123 | |||
124 | instance GLData (V2 V2F) (GLMatrix 2 2 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
125 | instance GLData (V3 V2F) (GLMatrix 3 2 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
126 | instance GLData (V4 V2F) (GLMatrix 4 2 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
127 | instance GLData (V2 V3F) (GLMatrix 2 3 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
128 | instance GLData (V3 V3F) (GLMatrix 3 3 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
129 | instance GLData (V4 V3F) (GLMatrix 4 3 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
130 | instance GLData (V2 V4F) (GLMatrix 2 4 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
131 | instance GLData (V3 V4F) (GLMatrix 3 4 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
132 | instance GLData (V4 V4F) (GLMatrix 4 4 GLfloat) where marshalUniform _ = Just . marshalColumnMajor | ||
133 | instance Uniformable (V2 V2F) where uniformContexts _ = contexts $ supports TypeM22F | ||
134 | instance Uniformable (V3 V2F) where uniformContexts _ = contexts $ supports TypeM23F | ||
135 | instance Uniformable (V4 V2F) where uniformContexts _ = contexts $ supports TypeM24F | ||
136 | instance Uniformable (V2 V3F) where uniformContexts _ = contexts $ supports TypeM32F | ||
137 | instance Uniformable (V3 V3F) where uniformContexts _ = contexts $ supports TypeM33F | ||
138 | instance Uniformable (V4 V3F) where uniformContexts _ = contexts $ supports TypeM34F | ||
139 | instance Uniformable (V2 V4F) where uniformContexts _ = contexts $ supports TypeM42F | ||
140 | instance Uniformable (V3 V4F) where uniformContexts _ = contexts $ supports TypeM43F | ||
141 | instance Uniformable (V4 V4F) where uniformContexts _ = contexts $ supports TypeM44F | ||
142 | |||
143 | |||
144 | instance Uniformable TextureData where uniformContexts _ = DMap.empty -- TODO | ||
145 | |||
146 | mkU :: GLData a c => TypeTag c -> a -> IO GLUniform | ||
147 | mkU ty a = GLTypedUniform ty <$> newIORef (GLUniformValue a) | ||
148 | |||
149 | initializeUniform :: InputType -> IO GLUniform | ||
150 | initializeUniform t = case witnessType t of | ||
151 | |||
152 | Just (This ty) -> case ty of | ||
153 | TypeBool -> mkU ty False | ||
154 | TypeV2B -> mkU ty (V2 False False) | ||
155 | TypeV3B -> mkU ty (V3 False False False) | ||
156 | TypeV4B -> mkU ty (V4 False False False False) | ||
157 | TypeWord -> mkU ty (0::Word32) | ||
158 | TypeV2U -> mkU ty (V2 0 0 :: V2 Word32) | ||
159 | TypeV3U -> mkU ty (V3 0 0 0 :: V3 Word32) | ||
160 | TypeV4U -> mkU ty (V4 0 0 0 0 :: V4 Word32) | ||
161 | TypeInt -> mkU ty (0::Int32) | ||
162 | TypeV2I -> mkU ty (V2 0 0 :: V2 Int32) | ||
163 | TypeV3I -> mkU ty (V3 0 0 0 :: V3 Int32) | ||
164 | TypeV4I -> mkU ty (V4 0 0 0 0 :: V4 Int32) | ||
165 | TypeFloat -> mkU ty (0::Float) | ||
166 | TypeV2F -> mkU ty (V2 0 0 :: V2 Float) | ||
167 | TypeV3F -> mkU ty (V3 0 0 0 :: V3 Float) | ||
168 | TypeV4F -> mkU ty (V4 0 0 0 0 :: V4 Float) | ||
169 | TypeM22F -> mkU ty (V2 z2 z2) | ||
170 | TypeM23F -> mkU ty (V3 z2 z2 z2) | ||
171 | TypeM24F -> mkU ty (V4 z2 z2 z2 z2) | ||
172 | TypeM32F -> mkU ty (V2 z3 z3) | ||
173 | TypeM33F -> mkU ty (V3 z3 z3 z3) | ||
174 | TypeM34F -> mkU ty (V4 z3 z3 z3 z3) | ||
175 | TypeM42F -> mkU ty (V2 z4 z4) | ||
176 | TypeM43F -> mkU ty (V3 z4 z4 z4) | ||
177 | TypeM44F -> mkU ty (V4 z4 z4 z4 z4) | ||
178 | |||
179 | Nothing -> case t of | ||
180 | FTexture2D -> GLUniform t <$> newIORef (TextureData 0) | ||
181 | _ -> fail $ "initializeUniform: " ++ show t | ||
182 | |||
183 | |||
184 | data TypeMismatch c a = TypeMismatch | ||
185 | |||
186 | instance (Typeable c, Typeable a) => Show (TypeMismatch c a) where | ||
187 | showsPrec d ty = | ||
188 | paren '(' | ||
189 | . mappend "TypeMismatch @" | ||
190 | . showsPrec 11 (typeRep $ ctx ty) | ||
191 | . mappend " @" | ||
192 | . showsPrec 0 (typeRep ty) | ||
193 | . paren ')' | ||
194 | where | ||
195 | ctx :: ty c a -> Proxy c | ||
196 | ctx _ = Proxy | ||
197 | paren | d<=10 = (:) | ||
198 | | otherwise = \_ -> id | ||
199 | |||
200 | instance (Typeable c, Typeable a) => Exception (TypeMismatch c a) | ||
201 | |||
202 | typeMismatch :: ctx c -> ref a -> TypeMismatch c a | ||
203 | typeMismatch _ _ = TypeMismatch | ||
100 | 204 | ||
101 | -- sets value based uniforms only (does not handle textures) | 205 | -- sets value based uniforms only (does not handle textures) |
102 | setUniform :: Storable a => GLint -> InputType -> IORef a -> IO () | 206 | setUniform :: GLint -> TypeTag c -> IO (GLUniformValue c) -> IO () |
103 | setUniform i ty ref = do | 207 | setUniform i ty ref = do |
104 | v <- readIORef ref | 208 | GLUniformValue v <- ref |
105 | let false = fromIntegral GL_FALSE | 209 | let false = GL_FALSE |
106 | with v $ \p -> case ty of | 210 | case marshalUniform (glABI ty) v of |
107 | Bool -> glUniform1uiv i 1 (castPtr p) | 211 | Just (MarshalGLVector withU) -> withU $ \n ptr -> |
108 | V2B -> glUniform2uiv i 1 (castPtr p) | 212 | case glUniform ty of GLVector f -> f i n ptr |
109 | V3B -> glUniform3uiv i 1 (castPtr p) | 213 | Just (MarshalGLMatrix withU) -> withU $ \n isRowMajor ptr -> |
110 | V4B -> glUniform4uiv i 1 (castPtr p) | 214 | case glUniform ty of GLMatrix f -> f i n isRowMajor ptr |
111 | Word -> glUniform1uiv i 1 (castPtr p) | 215 | Nothing -> throwIO (typeMismatch ty ref) |
112 | V2U -> glUniform2uiv i 1 (castPtr p) | ||
113 | V3U -> glUniform3uiv i 1 (castPtr p) | ||
114 | V4U -> glUniform4uiv i 1 (castPtr p) | ||
115 | Int -> glUniform1iv i 1 (castPtr p) | ||
116 | V2I -> glUniform2iv i 1 (castPtr p) | ||
117 | V3I -> glUniform3iv i 1 (castPtr p) | ||
118 | V4I -> glUniform4iv i 1 (castPtr p) | ||
119 | Float -> glUniform1fv i 1 (castPtr p) | ||
120 | V2F -> glUniform2fv i 1 (castPtr p) | ||
121 | V3F -> glUniform3fv i 1 (castPtr p) | ||
122 | V4F -> glUniform4fv i 1 (castPtr p) | ||
123 | M22F -> glUniformMatrix2fv i 1 false (castPtr p) | ||
124 | M23F -> glUniformMatrix2x3fv i 1 false (castPtr p) | ||
125 | M24F -> glUniformMatrix2x4fv i 1 false (castPtr p) | ||
126 | M32F -> glUniformMatrix3x2fv i 1 false (castPtr p) | ||
127 | M33F -> glUniformMatrix3fv i 1 false (castPtr p) | ||
128 | M34F -> glUniformMatrix3x4fv i 1 false (castPtr p) | ||
129 | M42F -> glUniformMatrix4x2fv i 1 false (castPtr p) | ||
130 | M43F -> glUniformMatrix4x3fv i 1 false (castPtr p) | ||
131 | M44F -> glUniformMatrix4fv i 1 false (castPtr p) | ||
132 | FTexture2D -> return () --putStrLn $ "TODO: setUniform FTexture2D" | ||
133 | _ -> fail $ "internal error (setUniform)! - " ++ show ty | ||
134 | 216 | ||
135 | -- attribute functions | 217 | -- attribute functions |
136 | queryStreams :: GLuint -> IO (Map String GLuint, Map String InputType) | 218 | queryStreams :: GLuint -> IO (Map String GLuint, Map String InputType) |
@@ -605,6 +687,7 @@ compileTexture txDescriptor = do | |||
605 | , textureMaxLevel = txMaxLevel | 687 | , textureMaxLevel = txMaxLevel |
606 | } = txDescriptor | 688 | } = txDescriptor |
607 | 689 | ||
690 | txSetup :: Num a => GLenum -> TextureDataType -> IO (a,GLenum) | ||
608 | txSetup txTarget dTy = do | 691 | txSetup txTarget dTy = do |
609 | let internalFormat = fromIntegral $ textureDataTypeToGLType txSemantic dTy | 692 | let internalFormat = fromIntegral $ textureDataTypeToGLType txSemantic dTy |
610 | dataFormat = fromIntegral $ textureDataTypeToGLArityType txSemantic dTy | 693 | dataFormat = fromIntegral $ textureDataTypeToGLArityType txSemantic dTy |