gloss-1.3.3.1: Graphics/Gloss/Internals/Render/Bitmap.hs
{-# OPTIONS -fwarn-incomplete-patterns #-}
-- | Helper functions for rendering bitmaps
module Graphics.Gloss.Internals.Render.Bitmap
( reverseRGBA
, bitmapPath
, freeBitmapData
)
where
import Foreign
import qualified Data.ByteString as B
-- | Generates the point path to display the bitmap centred
bitmapPath :: Float -> Float -> [(Float, Float)]
bitmapPath width height
= [(-width', -height'), (width', -height'), (width', height'), (-width', height')]
where width' = width / 2
height' = height / 2
-- | This is necessary as OpenGL reads pixel data as ABGR, rather than RGBA
reverseRGBA :: B.ByteString -> IO (Ptr Word8)
reverseRGBA orig
= do ptr <- newArray $ B.unpack orig
reverseRGBA' (B.length orig `div` 4) (castPtr ptr) 0
return ptr
-- | Parses through pixel values, shifting the bytes into OpenGL ABGR order
reverseRGBA' :: Int -> Ptr Word32 -> Int -> IO ()
reverseRGBA' len ptr count
| count < len
= do curr <- peekElemOff ptr count
let byte0 = shift (isolateByte0 curr) 24
let byte1 = shift (isolateByte1 curr) 8
let byte2 = shift (isolateByte2 curr) (-8)
let byte3 = shift (isolateByte3 curr) (-24)
pokeElemOff ptr count (byte0 .|. byte1 .|. byte2 .|. byte3)
reverseRGBA' len ptr (count + 1)
| otherwise
= return ()
-- | Frees the allocated memory given to OpenGL to avoid a memory leak
freeBitmapData :: Ptr Word8 -> IO ()
{-# INLINE freeBitmapData #-}
freeBitmapData p = free p
-- | These functions work as bit masks to isolate the Word8 components
isolateByte0 :: Word32 -> Word32
isolateByte0 word =
word .&. (255 :: Word32)
isolateByte1 :: Word32 -> Word32
isolateByte1 word =
word .&. (65280 :: Word32)
isolateByte2 :: Word32 -> Word32
isolateByte2 word =
word .&. (16711680 :: Word32)
isolateByte3 :: Word32 -> Word32
isolateByte3 word =
word .&. (4278190080 :: Word32)