-- | A thin layer over OpenGL 3.1+ vertex array objects. module Graphics.GLUtil.VertexArrayObjects (VertexArrayObject(..), VAO, makeVAO, deleteVAO, bindVertexArray) where import Foreign.Marshal.Array (allocaArray) import Foreign.Marshal.Utils (with) import Foreign.Storable (peek) import Graphics.Rendering.OpenGL.Raw.Core31 -- |A vertex array object captures OpenGL state needed for drawing a -- vertex array. It encapsulates the binding of an array buffer and an -- element buffer, as well as vertex attribute setup. newtype VertexArrayObject = VertexArrayObject GLuint -- |Short alias. type VAO = VertexArrayObject -- |Allocate a 'VertexArrayObject', and initialize it with the -- provided action. This action should bind the buffer data, index -- data (if necessary), and setup vertex attributes. makeVAO :: IO () -> IO VertexArrayObject makeVAO m = do vao <- allocaArray 1 $ \ptr -> glGenVertexArrays 1 ptr >> peek ptr glBindVertexArray vao m glBindVertexArray 0 return $ VertexArrayObject vao -- |Delete a 'VertexArrayObject'. Do not use the VAO after running -- this action! deleteVAO :: VertexArrayObject -> IO () deleteVAO (VertexArrayObject i) = with i $ glDeleteVertexArrays 1 -- |Bind a 'VertexArrayObject', or ensure that no VAO is bound. bindVertexArray :: Maybe VertexArrayObject -> IO () bindVertexArray (Just (VertexArrayObject i)) = glBindVertexArray i bindVertexArray Nothing = glBindVertexArray 0