summaryrefslogtreecommitdiff
path: root/MaskableStream.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-05-19 04:56:51 -0400
committerJoe Crayne <joe@jerkface.net>2019-05-19 04:56:51 -0400
commitab43ecb77e381b83448a0ea324dd5377333538a0 (patch)
treecd56c0eda401ee1536758217f69b9e2c100bd95c /MaskableStream.hs
parent04fc039177d49e1f5f57ce0f61216870d4f723ab (diff)
Type-safe incremental attribute update.
Diffstat (limited to 'MaskableStream.hs')
-rw-r--r--MaskableStream.hs49
1 files changed, 46 insertions, 3 deletions
diff --git a/MaskableStream.hs b/MaskableStream.hs
index 831a6e2..5ef5b28 100644
--- a/MaskableStream.hs
+++ b/MaskableStream.hs
@@ -6,7 +6,9 @@ module MaskableStream where
6 6
7import Control.Monad 7import Control.Monad
8import Control.Monad.IO.Class 8import Control.Monad.IO.Class
9import Control.Monad.Writer
9import Data.Foldable 10import Data.Foldable
11import Data.Function
10import Data.Int 12import Data.Int
11import Data.IORef 13import Data.IORef
12import Data.Maybe 14import Data.Maybe
@@ -22,6 +24,7 @@ import Data.Dependent.Sum
22import Data.Some 24import Data.Some
23import Data.GADT.Show 25import Data.GADT.Show
24import GHC.TypeLits 26import GHC.TypeLits
27import System.IO
25 28
26import LambdaCube.GL as LC 29import LambdaCube.GL as LC
27import LambdaCube.GL.Data -- (uploadCubeMapToGPU,uploadTextureBufferToGPU,updateTextureBuffer) 30import LambdaCube.GL.Data -- (uploadCubeMapToGPU,uploadTextureBufferToGPU,updateTextureBuffer)
@@ -195,9 +198,6 @@ componentCount x@(IsGLVector _) = fromIntegral $ natVal $ vectorLength x
195componentCount x@(IsGLMatrix _) = let (r,c) = matrixDimensions x 198componentCount x@(IsGLMatrix _) = let (r,c) = matrixDimensions x
196 in fromIntegral (natVal r) * fromIntegral (natVal c) 199 in fromIntegral (natVal r) * fromIntegral (natVal c)
197 200
198-- TODO: Add flexibility.
199-- Currently this allocates a buffer consisting of a single named vertex attribute that
200-- must be of type V3F.
201uploadDynamicBuffer :: Int -> [Parameter] -> IO GPUData 201uploadDynamicBuffer :: Int -> [Parameter] -> IO GPUData
202uploadDynamicBuffer sz params = do 202uploadDynamicBuffer sz params = do
203 bo <- alloca $! \pbo -> glGenBuffers 1 pbo >> peek pbo 203 bo <- alloca $! \pbo -> glGenBuffers 1 pbo >> peek pbo
@@ -231,3 +231,46 @@ incrementalUpdateBuffer b byteoffset bytecount ptr = do
231 glBindBuffer GL_ARRAY_BUFFER (bufGLObj b) 231 glBindBuffer GL_ARRAY_BUFFER (bufGLObj b)
232 glBufferSubData GL_ARRAY_BUFFER byteoffset bytecount ptr 232 glBufferSubData GL_ARRAY_BUFFER byteoffset bytecount ptr
233 glBindBuffer GL_ARRAY_BUFFER 0 233 glBindBuffer GL_ARRAY_BUFFER 0
234
235data AttributeKey c = AttributeKey (TypeTag c) Buffer CPtrdiff
236
237attributeKey :: TypeTagable c => GPUData -> String -> Maybe (AttributeKey c)
238attributeKey dta name = do
239 stream <- Map.lookup name (dStreams dta)
240 fix $ \mp -> let typ = typeTag (fromJust mp) in case stream of
241 Stream t b i _ _ -> do
242 let a = bufArrays b ! i
243 -- arrType :: ArrayType
244 -- arrLength :: Int -- number of 32 bit values
245 -- arrOffset :: Int -- byte offset into buffer
246 -- arrSize :: Int -- byte count
247 off = arrOffset a
248 guard (fromStreamType t == unwitnessType typ)
249 Just $ AttributeKey typ b (fromIntegral off)
250 _ -> Nothing
251
252(@<-) :: GLData a c => AttributeKey c -> a -> Writer [DSum AttributeKey GLUniformValue] ()
253k @<- v = tell [k :=> GLUniformValue v]
254
255updateAttributes :: Int -> Writer [DSum AttributeKey GLUniformValue] a -> IO ()
256updateAttributes i writer = forM_ (execWriter writer) $ \case
257 AttributeKey typ b base :=> GLUniformValue a -> do
258 glBindBuffer GL_ARRAY_BUFFER (bufGLObj b)
259 let abi = glABI typ
260 attribSize = 4 * componentCount abi
261 case marshalUniform abi a of
262
263 Just (MarshalGLVector with) -> with $ \sz ptr -> do
264 let sz' = fromIntegral $ attribSize * (fromIntegral sz)
265 putStrLn $ "vector sz = " ++ show sz
266 glBufferSubData GL_ARRAY_BUFFER (base + fromIntegral i * sz') sz' ptr
267
268 Just (MarshalGLMatrix with) -> with $ \sz isrowcol ptr -> do
269 if isrowcol then
270 hPutStrLn stderr $ "WARNING: (TODO) row-major matrix attribute update unimplemented."
271 else do
272 let sz' = fromIntegral $ attribSize * (fromIntegral sz)
273 glBufferSubData GL_ARRAY_BUFFER (base + fromIntegral i * sz') sz' ptr
274
275 Nothing -> hPutStrLn stderr $ "Warning: dimension mismatch updating " ++ show (unwitnessType typ) ++ " attribute."
276 glBindBuffer GL_ARRAY_BUFFER 0