diff options
author | Joe Crayne <joe@jerkface.net> | 2019-05-19 22:16:55 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-05-19 22:16:55 -0400 |
commit | dc5aecfffbe071e9b8714988b9824c4f445f8dfc (patch) | |
tree | d3cc59ca11d2e4183d7eb2757b6aa723d5510398 | |
parent | eb02d7ac3e47cba80a1701fc4d755073941e02dd (diff) |
Use Data.Data to specify ring buffer attributes.
-rw-r--r-- | AttributeData.hs | 12 | ||||
-rw-r--r-- | MeshSketch.hs | 33 | ||||
-rw-r--r-- | PointPrimitiveRing.hs | 44 |
3 files changed, 58 insertions, 31 deletions
diff --git a/AttributeData.hs b/AttributeData.hs index 8e149af..59b9e6d 100644 --- a/AttributeData.hs +++ b/AttributeData.hs | |||
@@ -104,8 +104,12 @@ reflectPrim r = case () of | |||
104 | 104 | ||
105 | 105 | ||
106 | reflectVectorType :: Typeable a => proxy a -> Maybe (Some TypeTag) | 106 | reflectVectorType :: Typeable a => proxy a -> Maybe (Some TypeTag) |
107 | reflectVectorType proxy = case R.someTypeRep proxy of | 107 | reflectVectorType proxy = go (R.someTypeRep proxy) |
108 | where | ||
109 | go :: R.SomeTypeRep -> Maybe (Some TypeTag) | ||
110 | go rep = case rep of | ||
108 | R.SomeTypeRep r -> case R.splitApps r of | 111 | R.SomeTypeRep r -> case R.splitApps r of |
112 | |||
109 | (v,[c,a]) -> do | 113 | (v,[c,a]) -> do |
110 | cols <- reflectDim c | 114 | cols <- reflectDim c |
111 | This p <- reflectPrim a | 115 | This p <- reflectPrim a |
@@ -125,6 +129,7 @@ reflectVectorType proxy = case R.someTypeRep proxy of | |||
125 | 2 -> This TypeV2F | 129 | 2 -> This TypeV2F |
126 | 3 -> This TypeV3F | 130 | 3 -> This TypeV3F |
127 | 4 -> This TypeV4F | 131 | 4 -> This TypeV4F |
132 | |||
128 | (m,[r,c,a]) -> do | 133 | (m,[r,c,a]) -> do |
129 | rows <- reflectDim r | 134 | rows <- reflectDim r |
130 | cols <- reflectDim c | 135 | cols <- reflectDim c |
@@ -147,6 +152,9 @@ reflectVectorType proxy = case R.someTypeRep proxy of | |||
147 | 4 -> Just $ This TypeM44F | 152 | 4 -> Just $ This TypeM44F |
148 | _ -> Nothing | 153 | _ -> Nothing |
149 | _ -> Nothing | 154 | _ -> Nothing |
155 | |||
156 | (p,[x]) -> go x | ||
157 | |||
150 | _ -> Nothing | 158 | _ -> Nothing |
151 | 159 | ||
152 | fieldParameters :: forall attrkeys proxy. Data attrkeys => proxy attrkeys -> (String -> String) -> [Parameter] | 160 | fieldParameters :: forall attrkeys proxy. Data attrkeys => proxy attrkeys -> (String -> String) -> [Parameter] |
@@ -156,7 +164,7 @@ fieldParameters proxy toAttrName = do | |||
156 | AlgRep (c:_) -> do | 164 | AlgRep (c:_) -> do |
157 | let fields = constrFields c | 165 | let fields = constrFields c |
158 | mkb :: (MonadPlus m, Data k) => p k -> String -> m InputType | 166 | mkb :: (MonadPlus m, Data k) => p k -> String -> m InputType |
159 | mkb pxy n = case reflectVectorType proxy of | 167 | mkb pxy n = case reflectVectorType pxy of |
160 | Just (This tt) -> return $ unwitnessType tt | 168 | Just (This tt) -> return $ unwitnessType tt |
161 | _ -> mzero | 169 | _ -> mzero |
162 | go :: Data c => StateT ([String],[Parameter]) Maybe c | 170 | go :: Data c => StateT ([String],[Parameter]) Maybe c |
diff --git a/MeshSketch.hs b/MeshSketch.hs index d06e905..cca9524 100644 --- a/MeshSketch.hs +++ b/MeshSketch.hs | |||
@@ -1,14 +1,17 @@ | |||
1 | {-# LANGUAGE CPP #-} | 1 | {-# LANGUAGE CPP #-} |
2 | {-# LANGUAGE FlexibleContexts #-} | 2 | {-# LANGUAGE DataKinds #-} |
3 | {-# LANGUAGE LambdaCase #-} | 3 | {-# LANGUAGE DeriveDataTypeable #-} |
4 | {-# LANGUAGE OverloadedLabels #-} | 4 | {-# LANGUAGE FlexibleContexts #-} |
5 | {-# LANGUAGE OverloadedStrings #-} | 5 | {-# LANGUAGE LambdaCase #-} |
6 | {-# LANGUAGE RecordWildCards #-} | 6 | {-# LANGUAGE OverloadedLabels #-} |
7 | {-# LANGUAGE OverloadedStrings #-} | ||
8 | {-# LANGUAGE RecordWildCards #-} | ||
7 | module MeshSketch where | 9 | module MeshSketch where |
8 | 10 | ||
9 | import Codec.Picture as Juicy | 11 | import Codec.Picture as Juicy |
10 | import Control.Concurrent | 12 | import Control.Concurrent |
11 | import Control.Monad | 13 | import Control.Monad |
14 | import Data.Data | ||
12 | import Data.Word | 15 | import Data.Word |
13 | import Data.Function ((&)) | 16 | import Data.Function ((&)) |
14 | import Data.Functor ((<&>)) | 17 | import Data.Functor ((<&>)) |
@@ -44,6 +47,7 @@ import Text.Printf | |||
44 | 47 | ||
45 | import CubeMap | 48 | import CubeMap |
46 | import GLWidget (nullableContext, withCurrentGL) | 49 | import GLWidget (nullableContext, withCurrentGL) |
50 | import LambdaCube.GL.Input.Type | ||
47 | import LambdaCube.GL.HMatrix | 51 | import LambdaCube.GL.HMatrix |
48 | import LambdaCubeWidget (loadPipeline,DynamicPipeline(..)) | 52 | import LambdaCubeWidget (loadPipeline,DynamicPipeline(..)) |
49 | import Animator | 53 | import Animator |
@@ -52,6 +56,7 @@ import InfinitePlane | |||
52 | import MtlParser (ObjMaterial(..)) | 56 | import MtlParser (ObjMaterial(..)) |
53 | import Matrix | 57 | import Matrix |
54 | import PointPrimitiveRing | 58 | import PointPrimitiveRing |
59 | import MaskableStream (AttributeKey,(@<-)) | ||
55 | 60 | ||
56 | 61 | ||
57 | prettyDebug :: GL.DebugMessage -> String | 62 | prettyDebug :: GL.DebugMessage -> String |
@@ -75,6 +80,14 @@ setupGLDebugging = do | |||
75 | 80 | ||
76 | type Plane = Vector Float | 81 | type Plane = Vector Float |
77 | 82 | ||
83 | data RingPoint = RingPoint | ||
84 | { rpPosition :: AttributeKey (GLVector 3 Float) | ||
85 | } | ||
86 | deriving Data | ||
87 | |||
88 | ringPointAttr :: String -> String | ||
89 | ringPointAttr ('r':'p':c:cs) = toLower c : cs | ||
90 | |||
78 | -- State created by uploadState. | 91 | -- State created by uploadState. |
79 | data State = State | 92 | data State = State |
80 | { stAnimator :: Animator | 93 | { stAnimator :: Animator |
@@ -84,7 +97,7 @@ data State = State | |||
84 | , stSkybox :: IORef Int | 97 | , stSkybox :: IORef Int |
85 | , stSkyTexture :: IORef TextureCubeData | 98 | , stSkyTexture :: IORef TextureCubeData |
86 | , stDragFrom :: IORef (Maybe (Vector Float,Camera)) | 99 | , stDragFrom :: IORef (Maybe (Vector Float,Camera)) |
87 | , stRingBuffer :: Ring | 100 | , stRingBuffer :: Ring RingPoint |
88 | , stPenDown :: IORef Bool | 101 | , stPenDown :: IORef Bool |
89 | , stPlane :: IORef (Maybe Plane) | 102 | , stPlane :: IORef (Maybe Plane) |
90 | , stDragPlane :: IORef (Maybe (Vector Float,Plane)) | 103 | , stDragPlane :: IORef (Maybe (Vector Float,Plane)) |
@@ -183,7 +196,7 @@ uploadState obj glarea storage = do | |||
183 | -- grid plane | 196 | -- grid plane |
184 | uploadMeshToGPU xzplane >>= addMeshToObjectArray storage "plane" [] | 197 | uploadMeshToGPU xzplane >>= addMeshToObjectArray storage "plane" [] |
185 | 198 | ||
186 | ring <- newRing storage 100 | 199 | ring <- newRing storage 100 ringPointAttr |
187 | 200 | ||
188 | -- setup FrameClock | 201 | -- setup FrameClock |
189 | w <- toWidget glarea | 202 | w <- toWidget glarea |
@@ -560,7 +573,9 @@ pushRing w st h k = do | |||
560 | plane <- readIORef (stPlane st) | 573 | plane <- readIORef (stPlane st) |
561 | d <- worldCoordinates st h k plane | 574 | d <- worldCoordinates st h k plane |
562 | Just win <- getWidgetWindow w | 575 | Just win <- getWidgetWindow w |
563 | pushBack (stRingBuffer st) (d!0) (d!1) (d!2) | 576 | pushBack (stRingBuffer st) $ do |
577 | RingPoint{..} <- return $ rKeys (stRingBuffer st) | ||
578 | rpPosition @<- d | ||
564 | windowInvalidateRect win Nothing False | 579 | windowInvalidateRect win Nothing False |
565 | return d | 580 | return d |
566 | 581 | ||
diff --git a/PointPrimitiveRing.hs b/PointPrimitiveRing.hs index f55e08e..47819e3 100644 --- a/PointPrimitiveRing.hs +++ b/PointPrimitiveRing.hs | |||
@@ -2,7 +2,9 @@ | |||
2 | module PointPrimitiveRing where | 2 | module PointPrimitiveRing where |
3 | 3 | ||
4 | import Control.Monad | 4 | import Control.Monad |
5 | import Control.Monad.Writer | ||
5 | import Data.Data | 6 | import Data.Data |
7 | import Data.Dependent.Sum | ||
6 | import Data.Foldable | 8 | import Data.Foldable |
7 | import Data.Function | 9 | import Data.Function |
8 | import Data.Int | 10 | import Data.Int |
@@ -27,43 +29,48 @@ import LambdaCube.GL.Util | |||
27 | import LambdaCube.GL.Input.Type | 29 | import LambdaCube.GL.Input.Type |
28 | import LambdaCube.GL.Input hiding (createObjectCommands) | 30 | import LambdaCube.GL.Input hiding (createObjectCommands) |
29 | 31 | ||
32 | import AttributeData | ||
33 | |||
30 | -- import Graphics.GL.Core33 | 34 | -- import Graphics.GL.Core33 |
31 | 35 | ||
32 | import MaskableStream | 36 | import MaskableStream |
33 | 37 | ||
34 | data Ring = Ring | 38 | data Ring keys = Ring |
35 | { rBufferObject :: Buffer | 39 | { rBufferObject :: Buffer |
36 | , rStorage :: GLStorage | 40 | , rStorage :: GLStorage |
37 | , rObject :: Object | 41 | , rObject :: Object |
38 | , rSize :: IORef Int -- Current count of vertices in the ring buffer. | 42 | , rSize :: IORef Int -- Current count of vertices in the ring buffer. |
39 | , rBack :: IORef Int -- Where next vertex will be added. | 43 | , rBack :: IORef Int -- Where next vertex will be added. |
40 | , ringCapacity :: Int -- Maximum number of vertices in buffer. | 44 | , ringCapacity :: Int -- Maximum number of vertices in buffer. |
41 | , rPosition :: AttributeKey (GLVector 3 Float) | 45 | , rKeys :: keys |
42 | } | 46 | } |
43 | 47 | ||
44 | newRing :: GLStorage -> Int -> IO Ring | 48 | newRing :: Data keys => GLStorage -> Int -> (String -> String) -> IO (Ring keys) |
45 | newRing storage sz = do | 49 | newRing storage sz toAttr = fix $ \retProxy -> do |
50 | let paramProxy = paramProxy' retProxy | ||
51 | where paramProxy' :: io (ring keys) -> Proxy keys | ||
52 | paramProxy' _ = Proxy | ||
46 | startRef <- newIORef 0 | 53 | startRef <- newIORef 0 |
47 | sizeRef <- newIORef 0 | 54 | sizeRef <- newIORef 0 |
48 | gd <- uploadDynamicBuffer sz [Parameter "position" V3F] | 55 | let ps = fieldParameters paramProxy toAttr |
49 | let Just k = attributeKey gd "position" | 56 | putStrLn $ "Ring params: " ++ show ps |
57 | gd <- uploadDynamicBuffer sz ps | ||
58 | Just keys <- return $ lookupAttrKeys (lookupAttributeKey gd . toAttr) | ||
50 | obj <- addToObjectArray storage "Points" [] gd | 59 | obj <- addToObjectArray storage "Points" [] gd |
51 | readIORef (objCommands obj) >>= mapM_ print | 60 | readIORef (objCommands obj) >>= mapM_ print |
52 | -- [[GLSetUniform 0 GLUniform M44F,GLSetVertexAttribArray 0 5 3 5126 0x0000000000000000,GLDrawArrays 0 0 1],[],[],[]] | 61 | let r = Ring |
53 | let bo = streamBuffer $ dStreams gd Map.! "position" | 62 | { rBufferObject = streamBuffer $ head $ Map.elems (dStreams gd) |
54 | r = Ring | ||
55 | { rBufferObject = bo | ||
56 | , rStorage = storage | 63 | , rStorage = storage |
57 | , rObject = obj | 64 | , rObject = obj |
58 | , rSize = sizeRef | 65 | , rSize = sizeRef |
59 | , rBack = startRef | 66 | , rBack = startRef |
60 | , ringCapacity = sz | 67 | , ringCapacity = sz |
61 | , rPosition = k | 68 | , rKeys = keys |
62 | } | 69 | } |
63 | updateRingCommands r | 70 | updateRingCommands r |
64 | return r | 71 | return r |
65 | 72 | ||
66 | updateRingCommands :: Ring -> IO () | 73 | updateRingCommands :: Ring keys -> IO () |
67 | updateRingCommands r = do | 74 | updateRingCommands r = do |
68 | back <- fromIntegral <$> readIORef (rBack r) | 75 | back <- fromIntegral <$> readIORef (rBack r) |
69 | size <- fromIntegral <$> readIORef (rSize r) | 76 | size <- fromIntegral <$> readIORef (rSize r) |
@@ -77,17 +84,14 @@ updateRingCommands r = do | |||
77 | readIORef (objCommands $ rObject r) >>= mapM_ print | 84 | readIORef (objCommands $ rObject r) >>= mapM_ print |
78 | return () | 85 | return () |
79 | 86 | ||
80 | pushBack :: Ring -> Float -> Float -> Float -> IO () | 87 | pushBack :: Ring keys -> Writer [DSum AttributeKey GLUniformValue] a -> IO () |
81 | pushBack r x y z = do | 88 | pushBack r attrs = do |
82 | back <- readIORef $ rBack r | 89 | back <- readIORef $ rBack r |
83 | writeIORef (rBack r) (mod (back + 1) (ringCapacity r)) | 90 | writeIORef (rBack r) (mod (back + 1) (ringCapacity r)) |
84 | updateAttributes back $ do | 91 | updateAttributes back attrs |
85 | rPosition r @<- V3 x y z -- (fromList [x,y,z] :: Vector Float) | ||
86 | sz <- readIORef (rSize r) | 92 | sz <- readIORef (rSize r) |
87 | putStrLn $ "pushBack "++show (sz,back,(x,y,z)) | 93 | when (sz < ringCapacity r) $ writeIORef (rSize r) (sz + 1) |
88 | when (sz < ringCapacity r) $ do | ||
89 | writeIORef (rSize r) (sz + 1) | ||
90 | updateRingCommands r | 94 | updateRingCommands r |
91 | 95 | ||
92 | updateRingUniforms :: GLStorage -> Ring -> IO () | 96 | updateRingUniforms :: GLStorage -> Ring keys -> IO () |
93 | updateRingUniforms _ _ = return () | 97 | updateRingUniforms _ _ = return () |