1
- {-# LANGUAGE FlexibleInstances,
2
- ScopedTypeVariables,
3
- FlexibleContexts,
4
- DataKinds,
5
- TypeFamilies,
6
- MultiParamTypeClasses,
7
- ExistentialQuantification #-}
8
- module GLUtils where
9
- import Var
10
- import Graphics.GL.Core33
1
+ {-# LANGUAGE DataKinds #-}
2
+ {-# LANGUAGE ExistentialQuantification #-}
3
+ {-# LANGUAGE FlexibleContexts #-}
4
+ {-# LANGUAGE FlexibleInstances #-}
5
+ {-# LANGUAGE MultiParamTypeClasses #-}
6
+ {-# LANGUAGE ScopedTypeVariables #-}
7
+ {-# LANGUAGE TypeFamilies #-}
8
+ {-# LANGUAGE TypeOperators #-}
9
+
10
+ module Graphics.Binding where
11
+ import Control.Monad
11
12
import Control.Monad.IO.Class
12
- import Foreign.C.String
13
+ import Data.Proxy
14
+ import Data.Var
13
15
import Foreign
16
+ import Foreign.C.String
17
+ import GHC.TypeLits
18
+ import Graphics.GL
19
+ import Graphics.Program
20
+ import Graphics.Shader
14
21
import Linear
15
- import Control.Monad
16
22
17
- type ProgId = GLuint
23
+ data Bindable (k :: [(Symbol , GLSLType )]) a = Bindable [a ]
24
+
25
+ bindVertexData :: forall a i u m .
26
+ (Storable a , GLTypeable a , TypeInfo i , MonadIO m ) =>
27
+ Program i u -> Bindable i a -> m ()
28
+ bindVertexData (Program progId) (Bindable bdata) = liftIO $ do
29
+ withArrayLen bdata $ \ len vertices ->
30
+ glBufferData GL_ARRAY_BUFFER
31
+ (fromIntegral $ len * dataSize)
32
+ (vertices :: Ptr a )
33
+ GL_STATIC_DRAW
34
+ foldM_ (\ offset (name, size) -> do
35
+ attrib <- get $ AttribLocation progId name
36
+ glEnableVertexAttribArray attrib
37
+ glVertexAttribPointer attrib
38
+ size
39
+ (glType proxy)
40
+ (fromBool False )
41
+ (fromIntegral $ totalSize * dataSize)
42
+ offset
43
+ return (offset `plusPtr` fromIntegral (size * fromIntegral dataSize))
44
+ ) nullPtr (map (fmap (fromIntegral . glslTypeSize)) extracted)
45
+ where extracted = extract (Proxy :: Proxy i )
46
+ totalSize = fromIntegral $ sum . map (glslTypeSize . snd ) $ extracted
47
+ dataSize = sizeOf proxy
48
+ proxy = undefined :: a
18
49
19
50
-- Attribute location
20
51
data AttribLocation a = AttribLocation ProgId String
@@ -26,37 +57,37 @@ instance (MonadIO m, Num a) => HasGetter m (AttribLocation a) a where
26
57
-- Uniform binding
27
58
data Uniform a = Uniform ProgId String
28
59
29
- instance (MonadIO m , UniformBinding a , Storable a ) => HasSetter m (Uniform a ) a where
60
+ instance (MonadIO m , HasBinder a ) => HasSetter m (Uniform a ) a where
30
61
(Uniform progId name) $= uniData = liftIO $ do
31
62
uniId <- withCString name $ glGetUniformLocation progId
32
63
bindUniform uniData (fromIntegral uniId) 1
33
64
34
- class Storable v => UniformBinding v where
65
+ class Storable v => HasBinder v where
35
66
bindFunc :: v -> GLint -> GLsizei -> Ptr a -> IO ()
36
67
bindUniform :: MonadIO m => v -> GLint -> GLsizei -> m ()
37
68
bindUniform val loc count = liftIO $
38
69
with val $ \ trans -> bindFunc val loc count trans
39
70
40
- instance UniformBinding (M44 GLfloat ) where
71
+ instance HasBinder (M44 GLfloat ) where
41
72
bindFunc _ = matrixBinder glUniformMatrix4fv
42
73
43
- instance UniformBinding (M33 GLfloat ) where
74
+ instance HasBinder (M33 GLfloat ) where
44
75
bindFunc _ = matrixBinder glUniformMatrix3fv
45
76
46
- instance UniformBinding (M23 GLfloat ) where
77
+ instance HasBinder (M23 GLfloat ) where
47
78
bindFunc _ = matrixBinder glUniformMatrix2x3fv
48
79
-- TODO: add other matrices
49
80
50
- instance UniformBinding (V4 GLfloat ) where
81
+ instance HasBinder (V4 GLfloat ) where
51
82
bindFunc _ = vectorBinder glUniform4fv
52
83
53
- instance UniformBinding (V3 GLfloat ) where
84
+ instance HasBinder (V3 GLfloat ) where
54
85
bindFunc _ = vectorBinder glUniform3fv
55
86
56
- instance UniformBinding (V2 GLfloat ) where
87
+ instance HasBinder (V2 GLfloat ) where
57
88
bindFunc _ = vectorBinder glUniform2fv
58
89
59
- instance UniformBinding (V1 GLfloat ) where
90
+ instance HasBinder (V1 GLfloat ) where
60
91
bindFunc _ = vectorBinder glUniform1fv
61
92
-- TODO: add other vectors (GLint)
62
93
@@ -72,31 +103,7 @@ vectorBinder :: MonadIO m =>
72
103
vectorBinder f loc count val
73
104
= liftIO $ f loc count (castPtr val)
74
105
75
- -- Misc aux. functions
76
- offsetPtr :: Storable a => Int -> a -> Ptr GLvoid
77
- offsetPtr x s = plusPtr nullPtr (fromIntegral $ x * sizeOf s)
78
-
79
- withNewPtr :: Storable a => (Ptr a -> IO b ) -> IO a
80
- withNewPtr f = alloca (\ p -> f p >> get p)
81
-
82
- loadShader :: GLenum -> FilePath -> IO GLuint
83
- loadShader shaderTypeFlag filePath = do
84
- code <- readFile filePath
85
- shader <- glCreateShader shaderTypeFlag
86
- withCString code $ \ codePtr ->
87
- with codePtr $ \ codePtrPtr ->
88
- glShaderSource shader 1 codePtrPtr nullPtr
89
- glCompileShader shader
90
- status <- toBool <$> withNewPtr (glGetShaderiv shader GL_COMPILE_STATUS )
91
- unless status $
92
- alloca $ \ err -> do
93
- glGetShaderInfoLog shader 512 nullPtr err
94
- err' <- peekCString err
95
- error err'
96
- return shader
97
-
98
106
-- Fragment shader
99
-
100
107
data FragmentShaderField
101
108
= FragDiffuseColor -- 0
102
109
| FragMaterialID -- 1
@@ -112,14 +119,3 @@ instance MonadIO m => HasSetter m FragShaderLocation FragmentShaderField where
112
119
= liftIO . withCString name $
113
120
glBindFragDataLocation progId (fromIntegral $ fromEnum loc)
114
121
115
- -- GL typeable stuff
116
- class GLTypeable a where
117
- glType :: a -> Word32
118
-
119
- instance GLTypeable GLfloat where
120
- glType _ = GL_FLOAT
121
-
122
- instance GLTypeable GLint where
123
- glType _ = GL_INT
124
-
125
- -- TODO: etc
0 commit comments