To make this work with SDL surfaces & Haskell bindings use surfaceGetPixels
it returns Pixels
which is a type alias for Ptr PixelData
and PixelData
is an empty data declaration. The reason why this is, is because SDL surface pixel format & number of bits per pixel could be almost anything. So basically if you have 32bpp format you would cast the pointer to say Ptr Word32
using castPtr
.
Here is an example of getting/putting a pixel:
getPixel32 :: MonadIO m => Surface -> Int -> Int -> m Pixel
getPixel32 s x y = liftIO $ do
ps <- surfaceGetPixels s
assert (x >= 0 && x < surfaceGetWidth s && y >= 0 && y < surfaceGetHeight s) $
Pixel `liftM` peekElemOff (castPtr ps :: Ptr Word32) offset
where offset = y * (fromIntegral $ surfaceGetPitch s `div` 4) + x
setPixel32 :: MonadIO m => Surface -> Int -> Int -> Pixel -> m ()
setPixel32 s x y (Pixel pixel) = liftIO $ do
ps <- surfaceGetPixels s
assert (x >= 0 && x < surfaceGetWidth s && y >= 0 && y < surfaceGetHeight s) $
pokeElemOff (castPtr ps :: Ptr Word32) offset pixel
where offset = y * (fromIntegral $ surfaceGetPitch s `div` 4) + x
So similarly you can cast the pointer to a particular pointer type and give that to glTexImage2D to upload the texture.