aboutsummaryrefslogtreecommitdiff
path: root/Graphics/SDL/SDLHelp.hs
diff options
context:
space:
mode:
authorJoshua Rahm <joshua.rahm@colorado.edu>2014-04-04 19:38:15 -0600
committerJoshua Rahm <joshua.rahm@colorado.edu>2014-04-04 19:38:15 -0600
commite083553a455d30374f21aa0c34d9ae827470d490 (patch)
tree0313b29e5ff36efa76a53dbe63169c9d18b4433f /Graphics/SDL/SDLHelp.hs
downloadterralloc-e083553a455d30374f21aa0c34d9ae827470d490.tar.gz
terralloc-e083553a455d30374f21aa0c34d9ae827470d490.tar.bz2
terralloc-e083553a455d30374f21aa0c34d9ae827470d490.zip
intiial commit
Diffstat (limited to 'Graphics/SDL/SDLHelp.hs')
-rw-r--r--Graphics/SDL/SDLHelp.hs126
1 files changed, 126 insertions, 0 deletions
diff --git a/Graphics/SDL/SDLHelp.hs b/Graphics/SDL/SDLHelp.hs
new file mode 100644
index 0000000..8b09484
--- /dev/null
+++ b/Graphics/SDL/SDLHelp.hs
@@ -0,0 +1,126 @@
+module Graphics.SDL.SDLHelp where
+
+import Graphics.UI.SDL.Image as SDLImg
+import Graphics.UI.SDL as SDL
+import Data.Word
+import Control.Monad
+import Graphics.Glyph.Util
+
+import Graphics.Rendering.OpenGL as GL
+import Graphics.Rendering.OpenGL.Raw.Core31
+
+import Foreign.Storable
+import Foreign.Ptr
+import Data.Bits
+
+import System.IO.Unsafe
+import System.Endian
+import System.Exit
+
+data TextureData = TextureData {
+ textureSize :: (Int,Int),
+ textureObject :: TextureObject } deriving Show
+
+bindSurfaceToTexture :: SDL.Surface -> TextureObject -> IO TextureData
+bindSurfaceToTexture surf to = do
+ textureBinding Texture2D $= Just to
+ bbp <- liftM fromIntegral (pixelFormatGetBytesPerPixel $ surfaceGetPixelFormat surf)
+ putStrLn $ "bpp: " ++! bbp
+ ptr <- surfaceGetPixels surf
+ glTexImage2D gl_TEXTURE_2D 0 bbp (w surf) (h surf) 0 (if bbp == 3 then gl_RGB else gl_RGBA) gl_UNSIGNED_BYTE ptr
+ return $ TextureData (w surf, h surf) to
+ where
+ w :: (Integral a) => SDL.Surface -> a
+ w = fromIntegral . surfaceGetWidth
+ h :: (Integral a) => SDL.Surface -> a
+ h = fromIntegral . surfaceGetHeight
+
+textureFromSurface :: SDL.Surface -> IO TextureData
+textureFromSurface surf = makeTexture >>= (bindSurfaceToTexture surf >=> return)
+
+makeTexture :: IO TextureObject
+makeTexture = do
+ texobj <- liftM head $ genObjectNames 1
+ textureBinding Texture2D $= Just texobj
+ textureFilter Texture2D $= ((Linear', Nothing), Linear')
+ return texobj
+
+getPixel :: Int -> Int -> SDL.Surface -> IO Word32
+getPixel x y surf = do
+ bpp <- liftM fromIntegral (pixelFormatGetBytesPerPixel $ surfaceGetPixelFormat surf)
+ ptr <- (surfaceGetPixels surf >>= return.castPtr) :: IO (Ptr Word8)
+ let newPtr = ptr `plusPtr` (y * (fromIntegral $ surfaceGetPitch surf)) `plusPtr` (x * bpp)
+
+ ret <- case bpp of
+ -- bytes = R G B A
+ 1 -> liftM fromIntegral $ peek (castPtr newPtr :: Ptr Word8)
+ 2 -> liftM fromIntegral $ peek (castPtr newPtr :: Ptr Word16)
+ 3 -> do
+ ord1 <- liftM fromIntegral $ peek (castPtr newPtr :: Ptr Word16)
+ ord2 <- liftM fromIntegral $ peek (castPtr (newPtr `plusPtr` 2) :: Ptr Word8)
+ return $ ((ord1 `shiftL` 16) + (ord2 `shiftL` 8)) + 0xFF
+ 4 -> do
+ liftM fromIntegral $ peek (castPtr newPtr :: Ptr Word32)
+ _ -> error "Unrecognized format"
+
+ return $ toBE32 ret
+
+getPixelUnsafe :: Int -> Int -> SDL.Surface -> Word32
+getPixelUnsafe x y surf = unsafePerformIO $ getPixel x y surf
+
+rgbToWord :: Word8 -> Word8 -> Word8 -> Word32
+rgbToWord r g b =
+ let tW32 x = (fromIntegral x) :: Word32 in
+ ( (tW32 r) `shiftL` 24) +
+ ( (tW32 g) `shiftL` 16) +
+ ( (tW32 b) `shiftL` 8) +
+ 0xFF
+
+wordToPixel :: Word32 -> Color4 Word8
+wordToPixel word =
+ Color4 (fromIntegral $ word .&. 0xFF)
+ (fromIntegral $ (word `shiftR` 8) .&. 0xFF)
+ (fromIntegral $ (word `shiftR` 16) .&. 0xFF)
+ (fromIntegral $ (word `shiftR` 24) .&. 0xFF)
+
+getRGBA :: SDL.Surface -> Int -> Int -> IO (Color4 Word8)
+getRGBA surf x y = liftM wordToPixel $ getPixel x y surf
+
+simpleStartup :: String -> (Int,Int) -> IO Surface
+simpleStartup name' (w,h) = do
+ SDL.init [SDL.InitEverything]
+ SDL.setVideoMode w h 32 [SDL.OpenGL, SDL.Resizable, SDL.DoubleBuf]
+ SDL.setCaption name' name'
+ SDL.getVideoSurface
+
+defaultReshape :: Int -> Int -> a -> IO a
+defaultReshape w h ret = do
+ let size = Size (fromIntegral w) (fromIntegral h)
+ viewport $=(Position 0 0, size)
+ _ <- SDL.setVideoMode w h 32 [SDL.OpenGL, SDL.Resizable, SDL.DoubleBuf]
+ return ret
+
+startPipeline :: (Int -> Int -> a -> IO a) -> (Event -> a -> IO a) -> (a -> IO a) -> (a -> IO a) -> a -> IO ()
+startPipeline reshapeH eventH displayH updateH ini = do
+ let pumpEvents' res = do
+ ev <- SDL.pollEvent
+ case ev of
+ Quit -> do
+ putStrLn "Exit event."
+ exitSuccess
+ SDL.NoEvent -> return res
+ VideoResize w h -> reshapeH w h res >>= pumpEvents'
+ _ -> eventH ev res >>= pumpEvents'
+ let runPipeline val = do
+ res <- pumpEvents' val >>= displayH
+ SDL.glSwapBuffers `seq` (updateH res) >>= runPipeline
+
+ -- TODO unhardcode this
+ reshapeH 640 480 ini >>= runPipeline
+
+setupTexturing :: TextureData -> UniformLocation -> Int -> IO ()
+setupTexturing (TextureData _ to) tu unit = do
+ texture Texture2D $= Enabled
+ activeTexture $= TextureUnit (fromIntegral unit)
+ textureBinding Texture2D $= Just to
+ uniform tu $= Index1 (fromIntegral unit::GLint)