vinyl-gl 0.1.0.1 → 0.1.2
raw patch · 3 files changed
+53/−7 lines, 3 files
Files
- src/Data/Vinyl/Reflect.hs +11/−2
- src/Graphics/VinylGL/Vertex.hs +41/−4
- vinyl-gl.cabal +1/−1
src/Data/Vinyl/Reflect.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE DataKinds, TypeOperators, FlexibleContexts, FlexibleInstances, - ScopedTypeVariables #-}+ ScopedTypeVariables, CPP #-} -- | Reflection utilities for vinyl records. module Data.Vinyl.Reflect where import Data.Foldable (Foldable, foldMap)@@ -7,7 +7,10 @@ import Data.Monoid (Sum(..)) import Data.Vinyl (Rec, PlainRec, (:::)) import Foreign.Storable (Storable(sizeOf))-import GHC.TypeLits (SingI(..), fromSing, Sing)+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+import Data.Proxy+#endif+import GHC.TypeLits -- | List all field names in a record. class HasFieldNames a where@@ -16,9 +19,15 @@ instance HasFieldNames (Rec '[] f) where fieldNames _ = [] +#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+instance (KnownSymbol sy, HasFieldNames (Rec ts Identity))+ => HasFieldNames (Rec ((sy:::t) ': ts) Identity) where+ fieldNames _ = symbolVal (Proxy::Proxy sy) : fieldNames (undefined::PlainRec ts)+#else instance (SingI sy, HasFieldNames (Rec ts Identity)) => HasFieldNames (Rec ((sy:::t) ': ts) Identity) where fieldNames _ = fromSing (sing::Sing sy) : fieldNames (undefined::PlainRec ts)+#endif -- | Compute the size in bytes of of each field in a record. class HasFieldSizes a where
src/Graphics/VinylGL/Vertex.hs view
@@ -1,10 +1,11 @@ {-# LANGUAGE DataKinds, ScopedTypeVariables, TypeOperators, GADTs, BangPatterns, FlexibleInstances, FlexibleContexts, KindSignatures, RankNTypes,- ConstraintKinds #-}+ ConstraintKinds, CPP #-} -- | Utilities for working with vertex buffer objects (VBOs) filled -- with vertices represented as vinyl records. module Graphics.VinylGL.Vertex (bufferVertices, bindVertices, reloadVertices, deleteVertices, enableVertices, enableVertices',+ enableVertexFields, BufferedVertices(..), fieldToVAD) where import Control.Applicative import Control.Arrow (second)@@ -17,8 +18,8 @@ import Data.Vinyl ((:::)(..), PlainRec, Implicit(..), Elem) import Foreign.Ptr (plusPtr) import Foreign.Storable-import GHC.TypeLits (Sing, SingI(..), fromSing)-import Graphics.GLUtil hiding (Elem)+import GHC.TypeLits+import Graphics.GLUtil hiding (Elem, throwError) import Graphics.Rendering.OpenGL (VertexArrayDescriptor(..), bindBuffer, ($=), BufferTarget(..)) import qualified Graphics.Rendering.OpenGL as GL@@ -69,7 +70,13 @@ fieldToVAD :: forall sy v a r rs. (r ~ (sy ::: v a), HasFieldNames (PlainRec rs), HasFieldSizes (PlainRec rs), HasGLType a, Storable (PlainRec rs),- Num (v a), SingI sy, Foldable v, Implicit (Elem r rs)) =>+ Num (v a),+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+ KnownSymbol sy,+#else+ SingI sy,+#endif+ Foldable v, Implicit (Elem r rs)) => r -> Proxy (PlainRec rs) -> GL.VertexArrayDescriptor a fieldToVAD _ _ = GL.VertexArrayDescriptor dim (glType (undefined::a))@@ -78,11 +85,41 @@ (offset0 `plusPtr` offset) where dim = getSum $ foldMap (const (Sum 1)) (0::v a) Just offset = lookup n $ namesAndOffsets (undefined::PlainRec rs)+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+ n = symbolVal (Proxy::Proxy sy)+#else n = fromSing (sing::Sing sy)+#endif -- Constraint alias capturing the requirements of a vertex type. type ViableVertex t = (HasFieldNames t, HasFieldSizes t, HasFieldDims t, HasFieldGLTypes t, Storable t)++-- | Bind some of a shader's attribute inputs to a vertex record. This+-- is useful when the inputs of a shader are split across multiple+-- arrays.+enableVertexFields :: forall p rs. (ViableVertex (PlainRec rs))+ => ShaderProgram -> p rs -> IO ()+enableVertexFields s _ = enableSomeAttribs s (Proxy::Proxy (PlainRec rs)) >>=+ maybe (return ()) error++-- | Do not raise an error is some of a shader's inputs are not bound+-- by a vertex record.+enableSomeAttribs :: forall v. ViableVertex v+ => ShaderProgram -> Proxy v -> IO (Maybe String)+enableSomeAttribs s p = go $ fieldDescriptors (undefined::v)+ where go [] = return Nothing+ go (fd:fds) = + let n = fieldName fd+ shaderAttribs = attribs s+ in case M.lookup n shaderAttribs of+ Nothing -> return (Just $ "Unexpected attribute " ++ n)+ Just (_,t)+ | fieldType fd == t -> do enableAttrib s n+ setAttrib s n GL.ToFloat $+ descriptorVAD p fd+ go fds+ | otherwise -> return . Just $ "Type mismatch in " ++ n enableAttribs :: forall v. ViableVertex v => ShaderProgram -> Proxy v -> IO (Maybe String)
vinyl-gl.cabal view
@@ -1,5 +1,5 @@ name: vinyl-gl-version: 0.1.0.1+version: 0.1.2 synopsis: Utilities for working with OpenGL's GLSL shading language and vinyl records. description: Using "Data.Vinyl" records (similar in spirit to @HList@) to carry GLSL uniform parameters and vertex data enables