module Graphics.GL.Low.BufferObject (
VBO,
ElementArray,
UsageHint(..),
newVBO,
updateVBO,
bindVBO,
newElementArray,
updateElementArray,
bindElementArray,
deleteBufferObject
) where
import Foreign.Ptr
import Foreign.Marshal
import Foreign.Storable
import qualified Data.Vector.Storable as V
import Data.Vector.Storable (Vector)
import Data.Word
import Graphics.GL
import Graphics.GL.Low.Classes
data VBO = VBO GLuint deriving Show
data ElementArray = ElementArray GLuint deriving Show
data UsageHint = StaticDraw
| DynamicDraw
| StreamDraw
deriving Show
instance ToGL UsageHint where
toGL StaticDraw = GL_STATIC_DRAW
toGL DynamicDraw = GL_DYNAMIC_DRAW
toGL StreamDraw = GL_STREAM_DRAW
instance GLObject VBO where
glObjectName (VBO n) = fromIntegral n
instance GLObject ElementArray where
glObjectName (ElementArray n) = fromIntegral n
instance BufferObject VBO
instance BufferObject ElementArray
newVBO :: Vector Word8 -> UsageHint -> IO VBO
newVBO src usage = do
n <- alloca (\ptr -> glGenBuffers 1 ptr >> peek ptr)
let len = V.length src
glBindBuffer GL_ARRAY_BUFFER n
V.unsafeWith src $ \ptr -> glBufferData
GL_ARRAY_BUFFER
(fromIntegral len)
(castPtr ptr)
(toGL usage)
return (VBO n)
deleteBufferObject :: BufferObject a => a -> IO ()
deleteBufferObject bo = withArray [glObjectName bo] (\ptr -> glDeleteBuffers 1 ptr)
updateVBO :: Vector Word8 -> Int -> IO ()
updateVBO src offset = do
let len = V.length src
V.unsafeWith src $ \ptr -> glBufferSubData
GL_ARRAY_BUFFER
(fromIntegral offset)
(fromIntegral len)
(castPtr ptr)
bindVBO :: VBO -> IO ()
bindVBO (VBO n) = glBindBuffer GL_ARRAY_BUFFER n
newElementArray :: Vector Word8 -> UsageHint -> IO ElementArray
newElementArray bytes usage = do
n <- alloca (\ptr -> glGenBuffers 1 ptr >> peek ptr)
glBindBuffer GL_ELEMENT_ARRAY_BUFFER n
let len = V.length bytes
V.unsafeWith bytes $ \ptr -> do
glBufferData
GL_ELEMENT_ARRAY_BUFFER
(fromIntegral len)
(castPtr ptr)
(toGL usage)
return (ElementArray n)
updateElementArray :: Vector Word8 -> Int -> IO ()
updateElementArray bytes offset = V.unsafeWith bytes $ \ptr -> do
glBufferSubData
GL_ELEMENT_ARRAY_BUFFER
(fromIntegral offset)
(fromIntegral (V.length bytes))
(castPtr ptr)
bindElementArray :: ElementArray -> IO ()
bindElementArray (ElementArray n) = glBindBuffer GL_ELEMENT_ARRAY_BUFFER n