diff --git a/src/Shader.hs b/src/Shader.hs index 3fee66050..3cecb6b18 100644 --- a/src/Shader.hs +++ b/src/Shader.hs @@ -146,9 +146,45 @@ setupVAO :: [(GLuint,Int)] -> IO VAO setupVAO ps = do theVAO <- genObjectName bindVertexArrayObject $= Just theVAO + theVBO <- setupVBO $ map snd ps vbos <- forM ps setupArrayBuffer ptrs <- forM (zip vbos $ map snd ps) setupVBOPointers - return $ VAO theVAO ptrs + return $ VAO + { _vao = theVAO + , _vaoBufferTargets = ptrs + , _vaoVBO = theVBO + } + +setupVBO :: [Int] -> IO VBO +setupVBO sizes = do + vboName <- genObjectName + bindBuffer ArrayBuffer $= Just vboName + forM_ (zip3 [0..] sizes offs) $ \(loc,siz,off) -> do + setupVertexAttribPointer loc siz strd off + thePtr <- mallocArray (strd * numDrawableElements) + return $ VBO + { _vbo = vboName + , _vboPoint = thePtr + , _vboAttribSizes = sizes + } + where + strd = sum sizes + offs = scanl (+) 0 sizes + +{- | Assumes the correct VBO is bound -} +setupVertexAttribPointer + :: Int -- ^ Atrib location + -> Int -- ^ Size + -> Int -- ^ Stride + -> Int -- ^ Offset + -> IO () +setupVertexAttribPointer loc siz strd off = do + vertexAttribPointer (AttribLocation (fi loc)) $= + (ToFloat, VertexArrayDescriptor (fi' siz) Float (fi'' $ floatSize * strd) (bufferOffset off)) + where + fi = fromIntegral + fi' = fromIntegral + fi'' = fromIntegral setupVBOPointers :: (BufferObject,Int) -> IO (BufferObject,Ptr Float,Int) setupVBOPointers (vbo,vsize) = do diff --git a/src/Shader/Data.hs b/src/Shader/Data.hs index 919bfe0af..c6557a155 100644 --- a/src/Shader/Data.hs +++ b/src/Shader/Data.hs @@ -4,6 +4,7 @@ Datatypes used to setup and pass data to shaders. -} module Shader.Data ( VAO (..) + , VBO (..) , FullShader (..) , ShaderTexture (..) -- | Lens functions @@ -28,7 +29,18 @@ and its buffer targets. -} data VAO = VAO { _vao :: VertexArrayObject , _vaoBufferTargets :: [(BufferObject,Ptr Float,Int)] + , _vaoVBO :: VBO } +{- | Vertex buffer object: contains the reference to the object, +a pointer to a location with space that can be written to the buffer, +and a list of attribute pointer sizes. +Vertex attributes are interleaved within the vbo. -} +data VBO = VBO + { _vbo :: BufferObject + , _vboPoint :: Ptr Float + , _vboAttribSizes :: [Int] -- ^ It is not clear to me if this is necessary to store or not + } + {- | Datatype containing the necessary information for a single shader. -} data FullShader a = FullShader { _shaderProgram :: Program