packages feed

phraskell-0.1.1: src/Render.hs

module Render where

import Data.Bits
import Control.Monad
import Foreign
import FractalModel
import Graphics.UI.SDL as SDL

tryGetScreen :: Int -> Int -> Int -> String -> IO (Maybe Surface)
tryGetScreen w h d t = do
  SDL.init [InitVideo]
  screen <- SDL.trySetVideoMode w h d [HWSurface, DoubleBuf]
  SDL.setCaption t [] -- we don’t give a fuck about the title icon
  return screen

-- destroy the render
destroyRender :: IO ()
destroyRender = SDL.quit

type UV = (Int,Int)
type UVs = [[UV]]

-- put a single pixel in a surface
putPixel :: SDL.Pixel -> Surface -> UV -> IO ()
putPixel p s (u,v) = do
  pixels <- castPtr `liftM` surfaceGetPixels s
  pokeElemOff pixels (u + v*surfaceGetWidth s) p

-- pixelize an iteration value
pixelize :: Integer -> SDL.Pixel
pixelize (-1) = Pixel (0 :: Word32)
pixelize i  = Pixel $ (shift r 16) + (shift g 8) + b
{-
  where (r,g,b) = toWord32 $ (0,0,imod256)
        imod256 = i `mod` 256
        toWord32 (r,g,b) = (fromIntegral r, fromIntegral g, fromIntegral b)
-}
  where (r,g,b) = toWord32 $ decodeColor (6*i) 
        toWord32 (r,g,b) = (fromIntegral r, fromIntegral g, fromIntegral b)

-- pixelize an entire SDL Surface
pixelizeSurface :: FractalModel -> Surface -> IO ()
pixelizeSurface (IterFrame iterf) surface = do
  foldM_ (\row line -> foldM_ (\col x -> f (row,col) x >> return (col+1)) 0 line >> return (row+1)) 0 iterf
    where width = surfaceGetWidth surface
          height = surfaceGetHeight surface
          f uv x = putPixel (pixelize x) surface uv

-- to move in some utils module
type RGBColor = (Word8,Word8,Word8)

-- decode a rainbow color
decodeColor :: Integer -> RGBColor
decodeColor i
  | isRed c    = (255,contrib,0)
  | isYellow c = (ncontrib,255,0)
  | isGreen c  = (0,255,contrib)
  | isAzure c  = (0,ncontrib,255)
  | isBlue  c  = (contrib,0,255)
  | otherwise  = (255,0,ncontrib)
    where cr        = 255 -- color range - 1
          contrib   = fromIntegral $ (c `mod` cr)
          ncontrib  = fromIntegral $ 255 - contrib
          c         = i `mod` (6*cr)
          isRed     = (<cr)
          isYellow  = (<2*cr)
          isGreen   = (<3*cr)
          isAzure   = (<4*cr)
          isBlue    = (<5*cr)