-- |Allocate and fill a 'BufferObject' from a list of 'Storable's
-- whose length is explicitly given. This is useful when the list is
-- of known length, as it avoids a traversal to find the length.
makeBufferLen :: forall a. Storable a => 
                 BufferTarget -> Int -> [a] -> IO BufferObject
makeBufferLen target len elems = 
    do [buffer] <- genObjectNames 1
       bindBuffer target $= Just buffer
       let n = fromIntegral $ len * sizeOf (undefined::a)
       arr <- newListArray (0, len - 1) elems
       withStorableArray arr $ \ptr -> 
         bufferData target $= (n, ptr, StaticDraw)
       return buffer

-- |@replaceBuffer target elements@ replaces the buffer data attached
-- to the buffer object currently bound to @target@ with the supplied
-- list. Any previous data is deleted.
makeBufferLen :: forall a. Storable a => 
                 BufferTarget -> Int -> [a] -> IO BufferObject
makeBufferLen target len elems = 
    do [buffer] <- genObjectNames 1
       bindBuffer target $= Just buffer
       let n = fromIntegral $ len * sizeOf (undefined::a)
       arr <- newListArray (0, len - 1) elems
       withStorableArray arr $ \ptr -> 
         bufferData target $= (n, ptr, StaticDraw)
       return buffer

-- |@replaceBuffer target elements@ replaces the buffer data attached
-- to the buffer object currently bound to @target@ with the supplied
-- list. Any previous data is deleted.
makeBufferLen target len elems = 
    do [buffer] <- genObjectNames 1
       bindBuffer target $= Just buffer
       let n = fromIntegral $ len * sizeOf (undefined::a)
       arr <- newListArray (0, len - 1) elems
       withStorableArray arr $ \ptr -> 
         bufferData target $= (n, ptr, StaticDraw)
       return buffer

-- |@replaceBuffer target elements@ replaces the buffer data attached
-- to the buffer object currently bound to @target@ with the supplied
-- list. Any previous data is deleted.