diff options
author | 3gg <3gg@shellblade.net> | 2023-10-04 09:03:50 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2023-10-04 09:03:58 -0700 |
commit | c3fdc1fa310dbfe35e3457561a1c6198954b825a (patch) | |
tree | a7fbbfcdffecb3968489a7743545b91aa9317b67 | |
parent | 9209a05d5d61458bf63af1f4b14c03dee934112a (diff) |
Allow creation of Geometry from literal arrays. Simplify Buffer.
-rw-r--r-- | Spear/Render/Core/Buffer.hs | 54 | ||||
-rw-r--r-- | Spear/Render/Core/Geometry.hs | 197 | ||||
-rw-r--r-- | Spear/Render/Core/State.hs | 65 | ||||
-rw-r--r-- | Spear/Render/Immediate.hs | 7 |
4 files changed, 222 insertions, 101 deletions
diff --git a/Spear/Render/Core/Buffer.hs b/Spear/Render/Core/Buffer.hs index 6f1e355..a4e98a4 100644 --- a/Spear/Render/Core/Buffer.hs +++ b/Spear/Render/Core/Buffer.hs | |||
@@ -13,8 +13,8 @@ import Spear.Game | |||
13 | import Spear.Math.Vector | 13 | import Spear.Math.Vector |
14 | import Spear.Render.Core.State | 14 | import Spear.Render.Core.State |
15 | 15 | ||
16 | import Control.Monad (void) | 16 | import Control.Monad (unless, void) |
17 | import Data.HashMap as HashMap | 17 | import qualified Data.HashMap as HashMap |
18 | import Data.Word | 18 | import Data.Word |
19 | import Foreign.C.Types | 19 | import Foreign.C.Types |
20 | import Foreign.Marshal.Alloc | 20 | import Foreign.Marshal.Alloc |
@@ -29,6 +29,7 @@ data BufferData | |||
29 | = BufferDataUntyped (Ptr Word8) GLuint | 29 | = BufferDataUntyped (Ptr Word8) GLuint |
30 | | BufferDataVec2 [Vector2] | 30 | | BufferDataVec2 [Vector2] |
31 | | BufferDataVec3 [Vector3] | 31 | | BufferDataVec3 [Vector3] |
32 | | BufferDataVec4 [Vector4] | ||
32 | | BufferDataFloat [Float] | 33 | | BufferDataFloat [Float] |
33 | | BufferDataU8 [Word8] | 34 | | BufferDataU8 [Word8] |
34 | | BufferDataU16 [Word16] | 35 | | BufferDataU16 [Word16] |
@@ -36,7 +37,6 @@ data BufferData | |||
36 | 37 | ||
37 | data BufferDesc = BufferDesc | 38 | data BufferDesc = BufferDesc |
38 | { bufferDescUsage :: BufferUsage | 39 | { bufferDescUsage :: BufferUsage |
39 | , bufferDescType :: BufferType | ||
40 | , bufferDescData :: BufferData | 40 | , bufferDescData :: BufferData |
41 | } | 41 | } |
42 | 42 | ||
@@ -52,10 +52,10 @@ makeBufferAndView desc = do | |||
52 | } | 52 | } |
53 | 53 | ||
54 | makeBuffer :: BufferDesc -> Game RenderCoreState Buffer | 54 | makeBuffer :: BufferDesc -> Game RenderCoreState Buffer |
55 | makeBuffer (BufferDesc usage bufferType bufferData) = do | 55 | makeBuffer (BufferDesc usage bufferData) = do |
56 | handle <- gameIO $ alloca $ \ptr -> glGenBuffers 1 ptr >> peek ptr | 56 | handle <- gameIO $ alloca $ \ptr -> glGenBuffers 1 ptr >> peek ptr |
57 | resourceKey <- register $ deleteBuffer' handle | 57 | resourceKey <- register $ deleteBuffer' handle |
58 | let buffer = Buffer handle resourceKey bufferType usage | 58 | let buffer = Buffer handle resourceKey usage |
59 | gameIO $ updateBuffer buffer bufferData | 59 | gameIO $ updateBuffer buffer bufferData |
60 | modifyGameState (\state -> state { | 60 | modifyGameState (\state -> state { |
61 | buffers = HashMap.insert handle buffer (buffers state) }) | 61 | buffers = HashMap.insert handle buffer (buffers state) }) |
@@ -71,12 +71,10 @@ deleteBuffer buffer = do | |||
71 | -- TODO: use glBufferSubData for updates. | 71 | -- TODO: use glBufferSubData for updates. |
72 | updateBuffer :: Buffer -> BufferData -> IO () | 72 | updateBuffer :: Buffer -> BufferData -> IO () |
73 | updateBuffer buffer bufferData = | 73 | updateBuffer buffer bufferData = |
74 | case bufferData of | 74 | unless (bufferEmpty bufferData) $ do |
75 | BufferUninitialized -> return () | 75 | glBindBuffer GL_ARRAY_BUFFER (bufferHandle buffer) |
76 | _ -> do | 76 | uploadData (bufferUsage buffer) bufferData |
77 | glBindBuffer GL_ARRAY_BUFFER (bufferHandle buffer) | 77 | glBindBuffer GL_ARRAY_BUFFER 0 |
78 | uploadData (bufferUsage buffer) bufferData | ||
79 | glBindBuffer GL_ARRAY_BUFFER 0 | ||
80 | 78 | ||
81 | -- Private | 79 | -- Private |
82 | 80 | ||
@@ -87,26 +85,35 @@ deleteBuffer' handle = alloca $ \ptr -> do | |||
87 | 85 | ||
88 | uploadData :: BufferUsage -> BufferData -> IO () | 86 | uploadData :: BufferUsage -> BufferData -> IO () |
89 | uploadData usage bufferData = case bufferData of | 87 | uploadData usage bufferData = case bufferData of |
90 | BufferDataUntyped ptr sizeBytes -> do | 88 | BufferDataUntyped ptr sizeBytes -> |
91 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) (unsafeCoerce ptr) usage' | 89 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) (unsafeCoerce ptr) usage' |
92 | BufferDataVec2 vec2s -> withArrayLen vec2s $ \numElems ptr -> do | 90 | BufferDataVec2 vec2s -> withArrayLen vec2s $ \numElems ptr -> |
93 | let sizeBytes = numElems * sizeOf (undefined :: Vector2) | ||
94 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' | 91 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
95 | BufferDataVec3 vec3s -> withArrayLen vec3s $ \numElems ptr -> do | 92 | BufferDataVec3 vec3s -> withArrayLen vec3s $ \numElems ptr -> |
96 | let sizeBytes = numElems * sizeOf (undefined :: Vector3) | ||
97 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' | 93 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
98 | BufferDataFloat floats -> withArrayLen floats $ \numElems ptr -> do | 94 | BufferDataVec4 vec4s -> withArrayLen vec4s $ \numElems ptr -> |
99 | let sizeBytes = numElems * sizeOf (undefined :: CFloat) | ||
100 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' | 95 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
101 | BufferDataU8 ints -> withArrayLen ints $ \numElems ptr -> do | 96 | BufferDataFloat floats -> withArrayLen floats $ \numElems ptr -> |
102 | let sizeBytes = numElems * sizeOf (undefined :: Word8) | ||
103 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' | 97 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
104 | BufferDataU16 ints -> withArrayLen ints $ \numElems ptr -> do | 98 | BufferDataU8 ints -> withArrayLen ints $ \numElems ptr -> |
105 | let sizeBytes = numElems * sizeOf (undefined :: Word16) | 99 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
100 | BufferDataU16 ints -> withArrayLen ints $ \numElems ptr -> | ||
106 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' | 101 | glBufferData GL_ARRAY_BUFFER (fromIntegral sizeBytes) ptr usage' |
107 | BufferUninitialized -> | 102 | BufferUninitialized -> |
108 | return () | 103 | return () |
109 | where usage' = toGLUsage usage | 104 | where |
105 | usage' = toGLUsage usage | ||
106 | sizeBytes = bufferDataSizeBytes bufferData | ||
107 | |||
108 | bufferEmpty :: BufferData -> Bool | ||
109 | bufferEmpty (BufferDataUntyped ptr sizeBytes) = sizeBytes /= 0 | ||
110 | bufferEmpty (BufferDataVec2 list) = null list | ||
111 | bufferEmpty (BufferDataVec3 list) = null list | ||
112 | bufferEmpty (BufferDataVec4 list) = null list | ||
113 | bufferEmpty (BufferDataFloat list) = null list | ||
114 | bufferEmpty (BufferDataU8 list) = null list | ||
115 | bufferEmpty (BufferDataU16 list) = null list | ||
116 | bufferEmpty BufferUninitialized = True | ||
110 | 117 | ||
111 | toGLUsage :: BufferUsage -> GLenum | 118 | toGLUsage :: BufferUsage -> GLenum |
112 | toGLUsage BufferStatic = GL_STATIC_DRAW | 119 | toGLUsage BufferStatic = GL_STATIC_DRAW |
@@ -117,6 +124,7 @@ bufferDataSizeBytes bufferData = case bufferData of | |||
117 | BufferDataUntyped ptr sizeBytes -> sizeBytes | 124 | BufferDataUntyped ptr sizeBytes -> sizeBytes |
118 | BufferDataVec2 vec2s -> fromIntegral $ length vec2s * sizeOf (undefined :: Vector2) | 125 | BufferDataVec2 vec2s -> fromIntegral $ length vec2s * sizeOf (undefined :: Vector2) |
119 | BufferDataVec3 vec3s -> fromIntegral $ length vec3s * sizeOf (undefined :: Vector3) | 126 | BufferDataVec3 vec3s -> fromIntegral $ length vec3s * sizeOf (undefined :: Vector3) |
127 | BufferDataVec4 vec4s -> fromIntegral $ length vec4s * sizeOf (undefined :: Vector4) | ||
120 | BufferDataFloat floats -> fromIntegral $ length floats * 4 | 128 | BufferDataFloat floats -> fromIntegral $ length floats * 4 |
121 | BufferDataU8 bytes -> fromIntegral $ length bytes | 129 | BufferDataU8 bytes -> fromIntegral $ length bytes |
122 | BufferDataU16 words -> fromIntegral $ length words * 2 | 130 | BufferDataU16 words -> fromIntegral $ length words * 2 |
diff --git a/Spear/Render/Core/Geometry.hs b/Spear/Render/Core/Geometry.hs index aa0dfe5..6c05b38 100644 --- a/Spear/Render/Core/Geometry.hs +++ b/Spear/Render/Core/Geometry.hs | |||
@@ -1,6 +1,12 @@ | |||
1 | module Spear.Render.Core.Geometry | 1 | module Spear.Render.Core.Geometry |
2 | ( | 2 | ( |
3 | newGeometryDesc | 3 | GeometryDesc(..) |
4 | , VertexData(..) | ||
5 | , Positions(..) | ||
6 | , Indices(..) | ||
7 | , Weights(..) | ||
8 | , GeometryUsage(..) | ||
9 | , newGeometryDesc | ||
4 | , makeGeometry | 10 | , makeGeometry |
5 | , deleteGeometry | 11 | , deleteGeometry |
6 | , renderGeometry | 12 | , renderGeometry |
@@ -10,19 +16,58 @@ where | |||
10 | 16 | ||
11 | 17 | ||
12 | import Spear.Game | 18 | import Spear.Game |
13 | import Spear.Math.Vector.Vector3 | 19 | import Spear.Math.Vector |
14 | import Spear.Render.Core.Buffer | 20 | import Spear.Render.Core.Buffer |
15 | import Spear.Render.Core.Constants | 21 | import Spear.Render.Core.Constants |
16 | import Spear.Render.Core.State | 22 | import Spear.Render.Core.State |
17 | 23 | ||
18 | import Data.HashMap as HashMap | 24 | import Data.HashMap as HashMap |
19 | import Data.IORef | 25 | import Data.IORef |
26 | import Data.Maybe (fromJust) | ||
27 | import Data.Word | ||
20 | import Foreign.Marshal.Alloc | 28 | import Foreign.Marshal.Alloc |
21 | import Foreign.Storable | 29 | import Foreign.Storable |
22 | import Graphics.GL.Core46 | 30 | import Graphics.GL.Core46 |
23 | import Unsafe.Coerce | 31 | import Unsafe.Coerce |
24 | 32 | ||
25 | 33 | ||
34 | data VertexData v | ||
35 | = FromView (BufferView v) | ||
36 | | FromList [v] | ||
37 | |||
38 | data Positions | ||
39 | = Positions2d (VertexData Vector2) | ||
40 | | Positions3d (VertexData Vector3) | ||
41 | |||
42 | data Indices | ||
43 | = IndicesU8 (VertexData Word8) | ||
44 | | IndicesU16 (VertexData Word16) | ||
45 | |||
46 | data Weights | ||
47 | = WeightsU8 (VertexData Word8) | ||
48 | | WeightsU16 (VertexData Word16) | ||
49 | | WeightsFloat (VertexData Float) | ||
50 | |||
51 | data GeometryUsage | ||
52 | = GeometryStatic | ||
53 | | GeometryDynamic | ||
54 | |||
55 | -- | A geometry descriptor. | ||
56 | data GeometryDesc = GeometryDesc | ||
57 | { positions :: Maybe Positions -- Convenient for the empty descriptor. | ||
58 | , normals :: Maybe (VertexData Vector3) | ||
59 | , tangents :: Maybe (VertexData Vector4) | ||
60 | , texcoords :: Maybe (VertexData Vector4) | ||
61 | , joints :: Maybe Indices | ||
62 | , weights :: Maybe Weights | ||
63 | , indices :: Maybe Indices | ||
64 | , numVerts :: GLsizei | ||
65 | , numIndices :: GLsizei | ||
66 | , primitiveType :: PrimitiveType | ||
67 | , geometryUsage :: GeometryUsage | ||
68 | } | ||
69 | |||
70 | |||
26 | newGeometryDesc :: GeometryDesc | 71 | newGeometryDesc :: GeometryDesc |
27 | newGeometryDesc = GeometryDesc | 72 | newGeometryDesc = GeometryDesc |
28 | { positions = Nothing | 73 | { positions = Nothing |
@@ -35,19 +80,21 @@ newGeometryDesc = GeometryDesc | |||
35 | , numVerts = 0 | 80 | , numVerts = 0 |
36 | , numIndices = 0 | 81 | , numIndices = 0 |
37 | , primitiveType = Triangles | 82 | , primitiveType = Triangles |
83 | , geometryUsage = GeometryStatic | ||
38 | } | 84 | } |
39 | 85 | ||
40 | 86 | ||
41 | makeGeometry :: GeometryDesc -> Game RenderCoreState Geometry | 87 | makeGeometry :: GeometryDesc -> Game RenderCoreState Geometry |
42 | makeGeometry desc = do | 88 | makeGeometry desc = do |
89 | gdata <- geometryDescToData desc | ||
43 | handle <- gameIO $ alloca $ \ptr -> glGenVertexArrays 1 ptr >> peek ptr | 90 | handle <- gameIO $ alloca $ \ptr -> glGenVertexArrays 1 ptr >> peek ptr |
44 | gameIO $ do | 91 | gameIO $ do |
45 | glBindVertexArray handle | 92 | glBindVertexArray handle |
46 | configureVertexAttributes desc | 93 | configureVertexAttributes gdata |
47 | glBindVertexArray 0 | 94 | glBindVertexArray 0 |
48 | descRef <- gameIO $ newIORef desc | 95 | gdataRef <- gameIO $ newIORef gdata |
49 | resourceKey <- register $ deleteGeometry' handle | 96 | resourceKey <- register $ deleteGeometry' handle |
50 | let geometry = Geometry handle resourceKey descRef | 97 | let geometry = Geometry handle resourceKey gdataRef |
51 | modifyGameState (\state -> state { | 98 | modifyGameState (\state -> state { |
52 | geometries = HashMap.insert handle geometry (geometries state) }) | 99 | geometries = HashMap.insert handle geometry (geometries state) }) |
53 | return geometry | 100 | return geometry |
@@ -60,39 +107,120 @@ deleteGeometry geometry = do | |||
60 | 107 | ||
61 | renderGeometry :: Geometry -> IO () | 108 | renderGeometry :: Geometry -> IO () |
62 | renderGeometry geometry = do | 109 | renderGeometry geometry = do |
63 | desc <- readIORef (geometryDesc geometry) | 110 | gdata <- readIORef (geometryData geometry) |
64 | let mode = toGLPrimitiveType $ primitiveType desc | 111 | let mode = toGLPrimitiveType $ geometryPrimitiveType gdata |
65 | glBindVertexArray (geometryVao geometry) | 112 | glBindVertexArray (geometryVao geometry) |
66 | case indices desc of | 113 | case vertexIndices gdata of |
67 | (Just (IndicesU8 view)) -> renderIndexed view mode (numIndices desc) GL_UNSIGNED_BYTE | 114 | (Just (VertexIndicesU8 view)) -> |
68 | (Just (IndicesU16 view)) -> renderIndexed view mode (numIndices desc) GL_UNSIGNED_SHORT | 115 | renderIndexed view mode (geometryNumIndices gdata) GL_UNSIGNED_BYTE |
69 | Nothing -> glDrawArrays mode 0 (numVerts desc) | 116 | (Just (VertexIndicesU16 view)) -> |
117 | renderIndexed view mode (geometryNumIndices gdata) GL_UNSIGNED_SHORT | ||
118 | Nothing -> | ||
119 | glDrawArrays mode 0 (geometryNumVerts gdata) | ||
70 | glBindVertexArray 0 | 120 | glBindVertexArray 0 |
71 | 121 | ||
72 | -- Functions for updating dynamic geometry. | 122 | -- Functions for updating dynamic geometry. |
73 | 123 | ||
74 | setPositions :: Geometry -> [Vector3] -> IO () | 124 | setPositions :: Geometry -> [Vector3] -> IO () |
75 | setPositions geometry vectors = do | 125 | setPositions geometry vectors = do |
76 | desc <- readIORef $ geometryDesc geometry | 126 | gdata <- readIORef $ geometryData geometry |
77 | case positions desc of | 127 | case vertexPositions gdata of |
78 | Just (Positions3d view) -> do | 128 | VertexPositions3d view -> do |
79 | updateBuffer (bufferViewBuffer view) (BufferDataVec3 vectors) | 129 | updateBuffer (bufferViewBuffer view) (BufferDataVec3 vectors) |
80 | updateGeometry geometry $ \desc -> desc { | 130 | updateGeometry geometry $ \gdata -> gdata { |
81 | numVerts = fromIntegral . length $ vectors | 131 | geometryNumVerts = fromIntegral . length $ vectors |
82 | } | 132 | } |
83 | _ -> putStrLn "setPositions ERROR" -- TODO: handle gracefully | 133 | _ -> putStrLn "setPositions ERROR" -- TODO: handle gracefully |
84 | 134 | ||
85 | -- Private | 135 | -- Private |
86 | 136 | ||
137 | geometryDescToData :: GeometryDesc -> Game RenderCoreState GeometryData | ||
138 | geometryDescToData desc = | ||
139 | let | ||
140 | bufferUsage = toBufferUsage (geometryUsage desc) | ||
141 | toBufferUsage GeometryStatic = BufferStatic | ||
142 | toBufferUsage GeometryDynamic = BufferDynamic | ||
143 | -- Maybe handling. | ||
144 | convert :: (a -> Game RenderCoreState b) -> Maybe a -> Game RenderCoreState (Maybe b) | ||
145 | convert f value = case value of | ||
146 | Nothing -> return Nothing | ||
147 | Just x -> Just <$> f x | ||
148 | -- 2d vectors | ||
149 | convert2d :: VertexData Vector2 -> Game RenderCoreState (BufferView Vector2) | ||
150 | convert2d (FromView view) = return view | ||
151 | convert2d (FromList vec2s) = makeBufferAndView $ | ||
152 | BufferDesc bufferUsage (BufferDataVec2 vec2s) | ||
153 | -- 3d vectors | ||
154 | convert3d :: VertexData Vector3 -> Game RenderCoreState (BufferView Vector3) | ||
155 | convert3d (FromView view) = return view | ||
156 | convert3d (FromList vec3s) = makeBufferAndView $ | ||
157 | BufferDesc bufferUsage (BufferDataVec3 vec3s) | ||
158 | -- 4d vectors | ||
159 | convert4d :: VertexData Vector4 -> Game RenderCoreState (BufferView Vector4) | ||
160 | convert4d (FromView view) = return view | ||
161 | convert4d (FromList vec4s) = makeBufferAndView $ | ||
162 | BufferDesc bufferUsage (BufferDataVec4 vec4s) | ||
163 | -- U8 | ||
164 | convertU8 :: VertexData Word8 -> Game RenderCoreState (BufferView Word8) | ||
165 | convertU8 (FromView view) = return view | ||
166 | convertU8 (FromList list) = makeBufferAndView | ||
167 | (BufferDesc BufferStatic (BufferDataU8 $ fromIntegral <$> list)) | ||
168 | -- U16 | ||
169 | convertU16 :: VertexData Word16 -> Game RenderCoreState (BufferView Word16) | ||
170 | convertU16 (FromView view) = return view | ||
171 | convertU16 (FromList list) = makeBufferAndView | ||
172 | (BufferDesc BufferStatic (BufferDataU16 $ fromIntegral <$> list)) | ||
173 | -- Floats | ||
174 | convertFloat :: VertexData Float -> Game RenderCoreState (BufferView Float) | ||
175 | convertFloat (FromView view) = return view | ||
176 | convertFloat (FromList list) = makeBufferAndView | ||
177 | (BufferDesc BufferStatic (BufferDataFloat list)) | ||
178 | -- Positions | ||
179 | convertPositions :: Positions -> Game RenderCoreState VertexPositions | ||
180 | convertPositions (Positions2d positions) = VertexPositions2d <$> convert2d positions | ||
181 | convertPositions (Positions3d positions) = VertexPositions3d <$> convert3d positions | ||
182 | -- Joints | ||
183 | convertJoints :: Indices -> Game RenderCoreState VertexJoints | ||
184 | convertJoints (IndicesU8 joints) = VertexJointsU8 <$> convertU8 joints | ||
185 | convertJoints (IndicesU16 joints) = VertexJointsU16 <$> convertU16 joints | ||
186 | -- Weights | ||
187 | convertWeights :: Weights -> Game RenderCoreState VertexWeights | ||
188 | convertWeights (WeightsU8 weights) = VertexWeightsU8 <$> convertU8 weights | ||
189 | convertWeights (WeightsU16 weights) = VertexWeightsU16 <$> convertU16 weights | ||
190 | convertWeights (WeightsFloat weights) = VertexWeightsFloat <$> convertFloat weights | ||
191 | -- Indices | ||
192 | convertIndices :: Indices -> Game RenderCoreState VertexIndices | ||
193 | convertIndices (IndicesU8 indices) = VertexIndicesU8 <$> convertU8 indices | ||
194 | convertIndices (IndicesU16 indices) = VertexIndicesU16 <$> convertU16 indices | ||
195 | in do | ||
196 | vertexPositions <- convertPositions (fromJust $ positions desc) | ||
197 | vertexNormals <- convert convert3d (normals desc) | ||
198 | vertexTangents <- convert convert4d (tangents desc) | ||
199 | vertexTexcoords <- convert convert4d (texcoords desc) | ||
200 | vertexJoints <- convert convertJoints (joints desc) | ||
201 | vertexWeights <- convert convertWeights (weights desc) | ||
202 | vertexIndices <- convert convertIndices (indices desc) | ||
203 | return $ GeometryData | ||
204 | vertexPositions | ||
205 | vertexNormals | ||
206 | vertexTangents | ||
207 | vertexTexcoords | ||
208 | vertexJoints | ||
209 | vertexWeights | ||
210 | vertexIndices | ||
211 | (numVerts desc) | ||
212 | (numIndices desc) | ||
213 | (primitiveType desc) | ||
214 | |||
87 | deleteGeometry' :: GLenum -> IO () | 215 | deleteGeometry' :: GLenum -> IO () |
88 | deleteGeometry' handle = alloca $ \ptr -> do | 216 | deleteGeometry' handle = alloca $ \ptr -> do |
89 | poke ptr handle | 217 | poke ptr handle |
90 | glDeleteVertexArrays 1 ptr | 218 | glDeleteVertexArrays 1 ptr |
91 | 219 | ||
92 | updateGeometry :: Geometry -> (GeometryDesc -> GeometryDesc) -> IO () | 220 | updateGeometry :: Geometry -> (GeometryData -> GeometryData) -> IO () |
93 | updateGeometry geometry update = do | 221 | updateGeometry geometry update = do |
94 | desc <- readIORef $ geometryDesc geometry | 222 | gdata <- readIORef $ geometryData geometry |
95 | writeIORef (geometryDesc geometry) (update desc) | 223 | writeIORef (geometryData geometry) (update gdata) |
96 | 224 | ||
97 | renderIndexed :: BufferView a -> GLenum -> GLsizei -> GLenum -> IO () | 225 | renderIndexed :: BufferView a -> GLenum -> GLsizei -> GLenum -> IO () |
98 | renderIndexed view mode numIndices indexElemSize = do | 226 | renderIndexed view mode numIndices indexElemSize = do |
@@ -100,29 +228,28 @@ renderIndexed view mode numIndices indexElemSize = do | |||
100 | glDrawElements mode numIndices GL_UNSIGNED_SHORT (unsafeCoerce $ bufferViewOffsetBytes view) | 228 | glDrawElements mode numIndices GL_UNSIGNED_SHORT (unsafeCoerce $ bufferViewOffsetBytes view) |
101 | glBindBuffer GL_ELEMENT_ARRAY_BUFFER 0 | 229 | glBindBuffer GL_ELEMENT_ARRAY_BUFFER 0 |
102 | 230 | ||
103 | configureVertexAttributes :: GeometryDesc -> IO () | 231 | configureVertexAttributes :: GeometryData -> IO () |
104 | configureVertexAttributes desc = do | 232 | configureVertexAttributes gdata = do |
105 | case positions desc of | 233 | case vertexPositions gdata of |
106 | Just (Positions2d view) -> configureView view positionChannel 2 GL_FLOAT GL_FALSE | 234 | VertexPositions2d view -> configureView view positionChannel 2 GL_FLOAT GL_FALSE |
107 | Just (Positions3d view) -> configureView view positionChannel 3 GL_FLOAT GL_FALSE | 235 | VertexPositions3d view -> configureView view positionChannel 3 GL_FLOAT GL_FALSE |
108 | Nothing -> return () | 236 | case vertexNormals gdata of |
109 | case normals desc of | ||
110 | Just view -> configureView view normalChannel 3 GL_FLOAT GL_FALSE | 237 | Just view -> configureView view normalChannel 3 GL_FLOAT GL_FALSE |
111 | Nothing -> return () | 238 | Nothing -> return () |
112 | case tangents desc of | 239 | case vertexTangents gdata of |
113 | Just view -> configureView view tangentChannel 4 GL_FLOAT GL_FALSE | 240 | Just view -> configureView view tangentChannel 4 GL_FLOAT GL_FALSE |
114 | Nothing -> return () | 241 | Nothing -> return () |
115 | case texcoords desc of | 242 | case vertexTexcoords gdata of |
116 | Just view -> configureView view texcoordsChannel 2 GL_FLOAT GL_FALSE | 243 | Just view -> configureView view texcoordsChannel 2 GL_FLOAT GL_FALSE |
117 | Nothing -> return () | 244 | Nothing -> return () |
118 | case joints desc of | 245 | case vertexJoints gdata of |
119 | Just (JointsU8 view) -> configureView view jointsChannel 4 GL_UNSIGNED_BYTE GL_FALSE | 246 | Just (VertexJointsU8 view) -> configureView view jointsChannel 4 GL_UNSIGNED_BYTE GL_FALSE |
120 | Just (JointsU16 view) -> configureView view jointsChannel 4 GL_UNSIGNED_SHORT GL_FALSE | 247 | Just (VertexJointsU16 view) -> configureView view jointsChannel 4 GL_UNSIGNED_SHORT GL_FALSE |
121 | Nothing -> return () | 248 | Nothing -> return () |
122 | case weights desc of | 249 | case vertexWeights gdata of |
123 | Just (WeightsU8 view) -> configureView view weightsChannel 4 GL_UNSIGNED_BYTE GL_TRUE | 250 | Just (VertexWeightsU8 view) -> configureView view weightsChannel 4 GL_UNSIGNED_BYTE GL_TRUE |
124 | Just (WeightsU16 view) -> configureView view weightsChannel 4 GL_UNSIGNED_SHORT GL_TRUE | 251 | Just (VertexWeightsU16 view) -> configureView view weightsChannel 4 GL_UNSIGNED_SHORT GL_TRUE |
125 | Just (WeightsFloat view) -> configureView view weightsChannel 4 GL_FLOAT GL_FALSE | 252 | Just (VertexWeightsFloat view) -> configureView view weightsChannel 4 GL_FLOAT GL_FALSE |
126 | Nothing -> return () | 253 | Nothing -> return () |
127 | 254 | ||
128 | -- TODO: Add the assertion: | 255 | -- TODO: Add the assertion: |
diff --git a/Spear/Render/Core/State.hs b/Spear/Render/Core/State.hs index 34b0732..f7e5627 100644 --- a/Spear/Render/Core/State.hs +++ b/Spear/Render/Core/State.hs | |||
@@ -11,15 +11,6 @@ import Graphics.GL.Core46 | |||
11 | 11 | ||
12 | 12 | ||
13 | 13 | ||
14 | data BufferType | ||
15 | = BufferUntyped | ||
16 | | Buffer2d | ||
17 | | Buffer3d | ||
18 | | Buffer4d | ||
19 | | BufferFloat | ||
20 | | BufferU8 | ||
21 | | BufferU16 | ||
22 | |||
23 | data BufferUsage | 14 | data BufferUsage |
24 | = BufferStatic | 15 | = BufferStatic |
25 | | BufferDynamic | 16 | | BufferDynamic |
@@ -28,7 +19,6 @@ data BufferUsage | |||
28 | data Buffer = Buffer | 19 | data Buffer = Buffer |
29 | { bufferHandle :: GLuint | 20 | { bufferHandle :: GLuint |
30 | , bufferResource :: Resource | 21 | , bufferResource :: Resource |
31 | , bufferType :: BufferType | ||
32 | , bufferUsage :: BufferUsage | 22 | , bufferUsage :: BufferUsage |
33 | } | 23 | } |
34 | 24 | ||
@@ -41,50 +31,49 @@ data BufferView a = BufferView | |||
41 | } | 31 | } |
42 | 32 | ||
43 | 33 | ||
44 | data Positions | 34 | data VertexPositions |
45 | = Positions2d (BufferView Vector2) | 35 | = VertexPositions2d (BufferView Vector2) |
46 | | Positions3d (BufferView Vector3) | 36 | | VertexPositions3d (BufferView Vector3) |
47 | 37 | ||
48 | data Joints | 38 | data VertexJoints |
49 | = JointsU8 (BufferView Word8) | 39 | = VertexJointsU8 (BufferView Word8) |
50 | | JointsU16 (BufferView Word16) | 40 | | VertexJointsU16 (BufferView Word16) |
51 | 41 | ||
52 | data Weights | 42 | data VertexWeights |
53 | = WeightsU8 (BufferView Word8) | 43 | = VertexWeightsU8 (BufferView Word8) |
54 | | WeightsU16 (BufferView Word16) | 44 | | VertexWeightsU16 (BufferView Word16) |
55 | | WeightsFloat (BufferView Float) | 45 | | VertexWeightsFloat (BufferView Float) |
56 | 46 | ||
57 | data Indices | 47 | data VertexIndices |
58 | = IndicesU8 (BufferView Word8) | 48 | = VertexIndicesU8 (BufferView Word8) |
59 | | IndicesU16 (BufferView Word16) | 49 | | VertexIndicesU16 (BufferView Word16) |
60 | 50 | ||
61 | data PrimitiveType | 51 | data PrimitiveType |
62 | = Triangles | 52 | = Triangles |
63 | | TriangleFan | 53 | | TriangleFan |
64 | | TriangleStrip | 54 | | TriangleStrip |
65 | 55 | ||
66 | -- | A geometry descriptor. | 56 | data GeometryData = GeometryData |
67 | data GeometryDesc = GeometryDesc | 57 | { vertexPositions :: VertexPositions |
68 | { positions :: Maybe Positions -- Convenient for the empty descriptor. | 58 | , vertexNormals :: Maybe (BufferView Vector3) |
69 | , normals :: Maybe (BufferView Vector3) | 59 | , vertexTangents :: Maybe (BufferView Vector4) |
70 | , tangents :: Maybe (BufferView Vector4) | 60 | , vertexTexcoords :: Maybe (BufferView Vector4) |
71 | , texcoords :: Maybe (BufferView Vector4) | 61 | , vertexJoints :: Maybe VertexJoints |
72 | , joints :: Maybe Joints | 62 | , vertexWeights :: Maybe VertexWeights |
73 | , weights :: Maybe Weights | 63 | , vertexIndices :: Maybe VertexIndices |
74 | , indices :: Maybe Indices | 64 | , geometryNumVerts :: GLsizei |
75 | , numVerts :: GLsizei | 65 | , geometryNumIndices :: GLsizei |
76 | , numIndices :: GLsizei | 66 | , geometryPrimitiveType :: PrimitiveType |
77 | , primitiveType :: PrimitiveType | ||
78 | } | 67 | } |
79 | 68 | ||
80 | -- | A piece of renderable geometry. | 69 | -- | A piece of renderable geometry. |
81 | -- | 70 | -- |
82 | -- Since dynamic geometry can be mutated, the descriptor is stored as an IORef | 71 | -- Since dynamic geometry can be mutated, the data is stored as an IORef so that |
83 | -- so that its state cannot become stale after an update. | 72 | -- its state cannot become stale after an update. |
84 | data Geometry = Geometry | 73 | data Geometry = Geometry |
85 | { geometryVao :: GLuint | 74 | { geometryVao :: GLuint |
86 | , geometryResource :: Resource | 75 | , geometryResource :: Resource |
87 | , geometryDesc :: IORef GeometryDesc | 76 | , geometryData :: IORef GeometryData |
88 | } | 77 | } |
89 | 78 | ||
90 | 79 | ||
diff --git a/Spear/Render/Immediate.hs b/Spear/Render/Immediate.hs index ca5d5c5..44fe7a6 100644 --- a/Spear/Render/Immediate.hs +++ b/Spear/Render/Immediate.hs | |||
@@ -54,13 +54,10 @@ newImmRenderer = do | |||
54 | (ShaderFromFile "/home/jeanne/src/gfx/gfx/shaders/immediate_mode.frag") [] | 54 | (ShaderFromFile "/home/jeanne/src/gfx/gfx/shaders/immediate_mode.frag") [] |
55 | shader <- compileShaderProgram [vs, ps] | 55 | shader <- compileShaderProgram [vs, ps] |
56 | 56 | ||
57 | -- TODO: Make 'makeGeometry' easier to use. GeometryDesc should be able to | ||
58 | -- take (possibly empty) lists as inputs. | ||
59 | positions <- makeBufferAndView $ | ||
60 | BufferDesc BufferDynamic Buffer3d BufferUninitialized | ||
61 | triangles <- makeGeometry $ newGeometryDesc | 57 | triangles <- makeGeometry $ newGeometryDesc |
62 | { positions = Just (Positions3d positions) | 58 | { positions = Just (Positions3d (FromList [])) |
63 | , primitiveType = Triangles | 59 | , primitiveType = Triangles |
60 | , geometryUsage = GeometryDynamic | ||
64 | } | 61 | } |
65 | 62 | ||
66 | return ImmRenderState | 63 | return ImmRenderState |