summaryrefslogtreecommitdiff
path: root/TextureBufferRing.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-05-14 17:52:40 -0400
committerJoe Crayne <joe@jerkface.net>2019-05-14 17:52:40 -0400
commitf5d4a74e9a4b23917b97f48bde529cb21e3ec152 (patch)
treee46037115608c455b738b864ab2f70cc4162f14c /TextureBufferRing.hs
parentb24d6672ff055208f6c0a85a01c43d17d8de9226 (diff)
Factor TEXTURE_BUFFER-based ring buffer into module.
Diffstat (limited to 'TextureBufferRing.hs')
-rw-r--r--TextureBufferRing.hs61
1 files changed, 61 insertions, 0 deletions
diff --git a/TextureBufferRing.hs b/TextureBufferRing.hs
new file mode 100644
index 0000000..2edf86f
--- /dev/null
+++ b/TextureBufferRing.hs
@@ -0,0 +1,61 @@
1module TextureBufferRing where
2
3import Control.Monad
4import Data.Int
5import Data.IORef
6import qualified Data.Map.Strict as Map
7import qualified Data.Vector as V
8import Foreign.Marshal.Array
9import Foreign.Storable
10
11import LambdaCube.GL as LC
12import LambdaCube.GL.Data (uploadCubeMapToGPU,uploadTextureBufferToGPU,updateTextureBuffer)
13import LambdaCube.GL.Mesh as LC
14import LambdaCube.IR as LC
15
16data Ring = Ring
17 { ringMax :: Int
18 , ringTexture :: TextureBufferData
19 , ringStart :: IO Int
20 , ringSize :: IO Int
21 , pushBack :: Float -> Float -> Float -> IO ()
22 , popFront :: IO ()
23 }
24
25newRing :: GLStorage -> Int -> IO Ring
26newRing storage cnt = do
27 let ringCapacity = cnt * 3
28 tbo <- uploadTextureBufferToGPU ringCapacity
29 p <- uploadMeshToGPU Mesh
30 { mAttributes = Map.singleton "position" $ A_Float $ V.fromList
31 $ replicate ringCapacity 0.0
32 , mPrimitive = P_Points
33 }
34 obj <- addMeshToObjectArray storage "Points" [] p
35 LC.updateUniforms storage $ do
36 "PointBuffer" @= return tbo
37 rstart <- newIORef 0
38 rsize <- newIORef 0
39 return Ring
40 { ringMax = cnt * 3
41 , ringTexture = tbo
42 , ringStart = readIORef rstart
43 , ringSize = readIORef rsize
44 , pushBack = \x y z -> do
45 start <- readIORef rstart
46 allocaArray 3 $ \ptr -> do
47 pokeElemOff ptr 0 x
48 pokeElemOff ptr 1 y
49 pokeElemOff ptr 2 z
50 updateTextureBuffer tbo start 3 ptr
51 writeIORef rstart (mod (start + 3) ringCapacity)
52 sz <- readIORef rsize
53 putStrLn $ "pushBack "++show (sz,start,(x,y,z))
54 when (sz < ringCapacity) $ do
55 writeIORef rsize (sz + 3)
56 , popFront = modifyIORef' rsize $ \s -> if s > 3 then s - 3 else 0
57 }
58
59updateRingUniforms storage ring = LC.updateUniforms storage $ do
60 "PointsStart" @= fmap (fromIntegral :: Int -> Int32) (ringStart ring)
61 "PointsMax" @= return (fromIntegral (ringMax ring) :: Int32)