292 lines
10 KiB
Haskell
292 lines
10 KiB
Haskell
{-# LANGUAGE TupleSections
|
|
, BangPatterns
|
|
#-}
|
|
module Shader.Poke
|
|
( pokeArrayOff
|
|
, pokePoint3s
|
|
, pokePoint33s
|
|
, pokeVerxs
|
|
, pokeLayVerxsFold
|
|
, poke224s
|
|
) where
|
|
import Shader.Data
|
|
import Shader.Parameters
|
|
import Picture.Data
|
|
import Geometry.Data
|
|
--import Layers
|
|
|
|
--import qualified Streaming.Prelude as SP
|
|
--import Data.Maybe
|
|
--import Data.List
|
|
import Foreign
|
|
import Control.Monad
|
|
import qualified Control.Foldl as F
|
|
import qualified Data.IntMap.Strict as IM
|
|
import Control.Lens
|
|
import qualified Data.Vector.Unboxed.Mutable as MV
|
|
import Control.Monad.Primitive
|
|
|
|
pokeVerxs'' :: PicShads VBO -> [Verx] -> IO (PicShads Int)
|
|
pokeVerxs'' vbos = F.foldM $ F.FoldM
|
|
(\count vx -> pokeVerx vbos count vx >> return (addCountVerx count vx))
|
|
(pure $ pure 0)
|
|
return
|
|
|
|
pokeVerxs' :: PicShads VBO -> [Verx] -> IO (MV.MVector (PrimState IO) Int)
|
|
pokeVerxs' vbos = F.foldM $ F.FoldM
|
|
(\count vx -> pokeVerx' vbos count vx >> addCountVerx' count vx >> return count)
|
|
(MV.replicate 6 0)
|
|
return
|
|
|
|
pokeVerxs :: PicShads VBO -> [Verx] -> IO (PicShads Int)
|
|
pokeVerxs vbos = F.foldM $ F.FoldM
|
|
(\count vx -> pokeVerx' vbos count vx >> addCountVerx' count vx >> return count)
|
|
(MV.replicate 6 0)
|
|
vToPicShad
|
|
|
|
vToPicShad :: MV.MVector (PrimState IO) Int -> IO (PicShads Int)
|
|
vToPicShad mv = do
|
|
mapM (MV.read mv) $ PicShads 0 1 2 3 4 5
|
|
|
|
--pokeVerxs vbos vxs0 = go vxs0 (pure 0)
|
|
-- where
|
|
-- go [] !count = return count
|
|
-- go (!vx:vxs) !count = pokeVerx vbos count vx >> (go vxs $! addCountVerx count vx)
|
|
|
|
-- this is very brittle, but want to optimise speed if possible here
|
|
pokeVerx :: PicShads VBO -> PicShads Int -> Verx -> IO ()
|
|
{-# INLINE pokeVerx #-}
|
|
pokeVerx vbos offsets Verx{_vxPos=thePos,_vxCol=theCol,_vxType=theType} = case theType of
|
|
PolyV -> poke34 (plusPtr (_vboPtr $ _psPoly vbos) (_psPoly offsets * 7 * floatSize)) thePos theCol
|
|
PolyzV x -> poke34 thePtr thePos theCol
|
|
>> pokeElemOff thePtr 7 x
|
|
where
|
|
thePtr = plusPtr (_vboPtr $ _psPolyz vbos) (_psPolyz offsets * 8 * floatSize)
|
|
BezV (V4 x y z w) -> poke34 thePtr thePos theCol
|
|
>> pokeElemOff thePtr 7 x
|
|
>> pokeElemOff thePtr 8 y
|
|
>> pokeElemOff thePtr 9 z
|
|
>> pokeElemOff thePtr 10 w
|
|
where
|
|
thePtr = plusPtr (_vboPtr $ _psBez vbos) (_psBez offsets * 11 * floatSize)
|
|
TextV (V2 x y) -> poke34 thePtr thePos theCol
|
|
>> pokeElemOff thePtr 7 x
|
|
>> pokeElemOff thePtr 8 y
|
|
where
|
|
thePtr = plusPtr (_vboPtr $ _psText vbos) (_psText offsets * 9 * floatSize)
|
|
ArcV (V3 x y z) -> poke34 thePtr thePos theCol
|
|
>> pokeElemOff thePtr 7 x
|
|
>> pokeElemOff thePtr 8 y
|
|
>> pokeElemOff thePtr 9 z
|
|
where
|
|
thePtr = plusPtr (_vboPtr $ _psArc vbos) (_psArc offsets * 10 * floatSize)
|
|
EllV -> poke34 (plusPtr (_vboPtr $ _psEll vbos) (_psEll offsets * 7 * floatSize)) thePos theCol
|
|
|
|
pokeVerx' :: PicShads VBO -> MV.MVector (PrimState IO) Int -> Verx -> IO ()
|
|
{-# INLINE pokeVerx' #-}
|
|
pokeVerx' vbos offsets Verx{_vxPos=thePos,_vxCol=theCol,_vxType=theType} = case theType of
|
|
PolyV -> do
|
|
typeOff <- MV.read offsets 0
|
|
poke34 (plusPtr (_vboPtr $ _psPoly vbos) (typeOff * 7 * floatSize)) thePos theCol
|
|
PolyzV x -> do
|
|
typeOff <- MV.read offsets 1
|
|
let thePtr = plusPtr (_vboPtr $ _psPolyz vbos) (typeOff * 8 * floatSize)
|
|
poke34 thePtr thePos theCol
|
|
pokeElemOff thePtr 7 x
|
|
BezV (V4 x y z w) -> do
|
|
typeOff <- MV.read offsets 2
|
|
let thePtr = plusPtr (_vboPtr $ _psBez vbos) (typeOff * 11 * floatSize)
|
|
poke34 thePtr thePos theCol
|
|
pokeElemOff thePtr 7 x
|
|
pokeElemOff thePtr 8 y
|
|
pokeElemOff thePtr 9 z
|
|
pokeElemOff thePtr 10 w
|
|
TextV (V2 x y) -> do
|
|
typeOff <- MV.read offsets 3
|
|
let thePtr = plusPtr (_vboPtr $ _psText vbos) (typeOff * 9 * floatSize)
|
|
poke34 thePtr thePos theCol
|
|
pokeElemOff thePtr 7 x
|
|
pokeElemOff thePtr 8 y
|
|
ArcV (V3 x y z) -> do
|
|
typeOff <- MV.read offsets 4
|
|
let thePtr = plusPtr (_vboPtr $ _psArc vbos) (typeOff * 10 * floatSize)
|
|
poke34 thePtr thePos theCol
|
|
pokeElemOff thePtr 7 x
|
|
pokeElemOff thePtr 8 y
|
|
pokeElemOff thePtr 9 z
|
|
EllV -> do
|
|
typeOff <- MV.read offsets 5
|
|
poke34 (plusPtr (_vboPtr $ _psEll vbos) (typeOff * 7 * floatSize)) thePos theCol
|
|
|
|
poke34 :: Ptr Float -> Point3 -> Point4 -> IO ()
|
|
{-# INLINE poke34 #-}
|
|
poke34 ptr (V3 a b c) (V4 d e f g) = do
|
|
pokeElemOff ptr 0 a
|
|
pokeElemOff ptr 1 b
|
|
pokeElemOff ptr 2 c
|
|
pokeElemOff ptr 3 d
|
|
pokeElemOff ptr 4 e
|
|
pokeElemOff ptr 5 f
|
|
pokeElemOff ptr 6 g
|
|
|
|
addCountVerx :: PicShads Int -> Verx -> PicShads Int
|
|
{-# INLINE addCountVerx #-}
|
|
addCountVerx !ps@PicShads
|
|
{ _psPoly = sPoly
|
|
, _psPolyz = sPolyz
|
|
, _psBez = sBez
|
|
, _psText = sText
|
|
, _psArc = sArc
|
|
, _psEll = sEll
|
|
} !Verx{_vxType=theType} = case theType of
|
|
PolyV -> ps {_psPoly = sPoly + 1}
|
|
PolyzV _ -> ps {_psPolyz = sPolyz + 1}
|
|
BezV _ -> ps {_psBez = sBez + 1}
|
|
TextV _ -> ps {_psText = sText + 1}
|
|
ArcV _ -> ps {_psArc = sArc + 1}
|
|
EllV -> ps {_psEll = sEll + 1}
|
|
|
|
addCountVerx' :: MV.MVector (PrimState IO) Int -> Verx -> IO ()
|
|
{-# INLINE addCountVerx' #-}
|
|
addCountVerx' v !Verx{_vxType=theType} = case theType of
|
|
PolyV -> MV.unsafeModify v (+ 1) 0
|
|
PolyzV _ -> MV.unsafeModify v (+ 1) 1
|
|
BezV _ -> MV.unsafeModify v (+ 1) 2
|
|
TextV _ -> MV.unsafeModify v (+ 1) 3
|
|
ArcV _ -> MV.unsafeModify v (+ 1) 4
|
|
EllV -> MV.unsafeModify v (+ 1) 5
|
|
|
|
pokeArrayOff :: Storable a => Ptr a -> Int -> [a] -> IO ()
|
|
--{-# INLINE pokeArrayOff #-}
|
|
--pokeArrayOff ptr i = zipWithM_ (pokeElemOff ptr) [i..]
|
|
pokeArrayOff ptr i = pokeArray (plusPtr ptr (floatSize * i))
|
|
|
|
pokePoint33s :: Ptr Float -> [(Point3,Point3)] -> IO Int
|
|
pokePoint33s ptr vals0 = go vals0 0
|
|
where
|
|
go [] n = return n
|
|
go ( !(!(V3 a b c),!(V3 d e f)):vals) !n = do
|
|
pokeElemOff ptr (off 0) a
|
|
pokeElemOff ptr (off 1) b
|
|
pokeElemOff ptr (off 2) c
|
|
pokeElemOff ptr (off 3) d
|
|
pokeElemOff ptr (off 4) e
|
|
pokeElemOff ptr (off 5) f
|
|
go vals (n+1)
|
|
where
|
|
off i = n*6 + i
|
|
|
|
pokePoint3s :: Ptr Float -> [Point3] -> IO Int
|
|
pokePoint3s ptr vals0 = go vals0 0
|
|
where
|
|
go [] n = return n
|
|
go ( !(V3 a b c):vals) !n = do
|
|
pokeElemOff ptr (off 0) a
|
|
pokeElemOff ptr (off 1) b
|
|
pokeElemOff ptr (off 2) c
|
|
go vals (n+1)
|
|
where
|
|
off i = n*3 + i
|
|
|
|
comLayVerx :: PicShads VBO -> IM.IntMap (PicShads Int) -> Verx -> IO (IM.IntMap (PicShads Int))
|
|
--{-# INLINE comLayVerx #-}
|
|
comLayVerx vbos counts vx = do
|
|
poke34 thePtr thePos theCol
|
|
pokeVerxType thePtr theType
|
|
return $ addLayCountVerx counts theLayer theType
|
|
where
|
|
theLayer = _vxLayer vx
|
|
layCounts = counts IM.! theLayer
|
|
theType = _vxType vx
|
|
thePos = _vxPos vx
|
|
theCol = _vxCol vx
|
|
basePtr = _vboPtr $ vboFromType vbos theType
|
|
layOff = theLayer * numSubElements
|
|
thePtr = plusPtr basePtr ((intFromType layCounts theType + layOff) * theStride * floatSize)
|
|
theStride = pokeStride theType
|
|
|
|
pokeVerxType :: Ptr Float -> VertexType -> IO ()
|
|
{-# INLINE pokeVerxType #-}
|
|
pokeVerxType thePtr vt = case vt of
|
|
PolyzV x -> pokeElemOff thePtr 7 x
|
|
BezV (V4 x y z w) -> pokeElemOff thePtr 7 x >> pokeElemOff thePtr 8 y
|
|
>> pokeElemOff thePtr 9 z >> pokeElemOff thePtr 10 w
|
|
TextV (V2 x y) -> pokeElemOff thePtr 7 x >> pokeElemOff thePtr 8 y
|
|
ArcV (V3 x y z) -> pokeElemOff thePtr 7 x >> pokeElemOff thePtr 8 y
|
|
>> pokeElemOff thePtr 9 z
|
|
_ -> return ()
|
|
|
|
intFromType :: PicShads Int -> VertexType -> Int
|
|
{-# INLINE intFromType #-}
|
|
intFromType ps vt = case vt of
|
|
PolyV -> _psPoly ps
|
|
PolyzV{} -> _psPolyz ps
|
|
BezV{} -> _psBez ps
|
|
TextV{} -> _psText ps
|
|
ArcV{} -> _psArc ps
|
|
EllV -> _psEll ps
|
|
|
|
vboFromType :: PicShads VBO -> VertexType -> VBO
|
|
{-# INLINE vboFromType #-}
|
|
vboFromType ps vt = case vt of
|
|
PolyV -> _psPoly ps
|
|
PolyzV{} -> _psPolyz ps
|
|
BezV{} -> _psBez ps
|
|
TextV{} -> _psText ps
|
|
ArcV{} -> _psArc ps
|
|
EllV -> _psEll ps
|
|
|
|
pokeLayVerxsFold :: PicShads VBO -> [Verx] -> IO (IM.IntMap (PicShads Int))
|
|
pokeLayVerxsFold vbos = F.foldM $ F.FoldM
|
|
(comLayVerx vbos)
|
|
(return $ imLayers 0)
|
|
return
|
|
|
|
imLayers :: a -> IM.IntMap (PicShads a)
|
|
{-# INLINE imLayers #-}
|
|
imLayers x = IM.fromList $ zip [0..5] $ repeat ps
|
|
where
|
|
ps = pure x
|
|
|
|
pokeStride :: VertexType -> Int
|
|
{-# INLINE pokeStride #-}
|
|
pokeStride PolyV = 7
|
|
pokeStride PolyzV{} = 8
|
|
pokeStride BezV{} = 11
|
|
pokeStride TextV{} = 9
|
|
pokeStride ArcV{} = 10
|
|
pokeStride EllV = 7
|
|
|
|
addLayCountVerx :: IM.IntMap (PicShads Int) -> Int -> VertexType -> IM.IntMap (PicShads Int)
|
|
{-# INLINE addLayCountVerx #-}
|
|
addLayCountVerx m lay vt = case vt of
|
|
PolyV -> m & ix lay . psPoly +~ 1
|
|
PolyzV _ -> m & ix lay . psPolyz +~ 1
|
|
BezV _ -> m & ix lay . psBez +~ 1
|
|
TextV _ -> m & ix lay . psText +~ 1
|
|
ArcV _ -> m & ix lay . psArc +~ 1
|
|
EllV -> m & ix lay . psEll +~ 1
|
|
--PolyV -> IM.adjust (psPoly +~ 1) lay m
|
|
--PolyzV _ -> IM.adjust (psPolyz +~ 1) lay m
|
|
--BezV _ -> IM.adjust (psBez +~ 1) lay m
|
|
--TextV _ -> IM.adjust (psText +~ 1) lay m
|
|
--ArcV _ -> IM.adjust (psArc +~ 1) lay m
|
|
--EllV -> IM.adjust (psEll +~ 1) lay m
|
|
|
|
poke224s :: Ptr Float -> [((Point2,Point2),Point4)] -> IO Int
|
|
poke224s ptr vals0 = go vals0 0
|
|
where
|
|
go [] n = return n
|
|
go ((((V2 a b),(V2 c d)),(V4 e f g h)):vals) !n = do
|
|
pokeElemOff ptr (off 0) a
|
|
pokeElemOff ptr (off 1) b
|
|
pokeElemOff ptr (off 2) c
|
|
pokeElemOff ptr (off 3) d
|
|
pokeElemOff ptr (off 4) e
|
|
pokeElemOff ptr (off 5) f
|
|
pokeElemOff ptr (off 6) g
|
|
pokeElemOff ptr (off 7) h
|
|
go vals (n+1)
|
|
where
|
|
off i = n*8 + i
|