~alcinnz/Mondrian

54ddd7a18fcb0fb3d730c8735d7dbc3cc8cc21bb — Adrian Cochrane 1 year, 6 months ago 05c8b4f
Commit missing Image module.
1 files changed, 65 insertions(+), 0 deletions(-)

A lib/Graphics/Rendering/Rect/Image.hs
A lib/Graphics/Rendering/Rect/Image.hs => lib/Graphics/Rendering/Rect/Image.hs +65 -0
@@ 0,0 1,65 @@
module Graphics.Rendering.Rect.Image(
    Atlas, buildAtlas, Texture(..), atlasLookup) where

import qualified Data.HashMap.Lazy as HM
import Data.Text (Text)
import Codec.Picture (DynamicImage(..), Image(..), PixelRGBA8(..), generateImage)
import Codec.Picture.Types (promoteImage, dynamicMap)

import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad (forM)
import Data.Maybe (fromMaybe)

import Typograffiti.GL
import Graphics.GL.Core32
import Graphics.GL.Types
import Graphics.GL.Ext.EXT.Cmyka
import Graphics.GL.Ext.SGIX.Ycrcb
import Graphics.GL.Compatibility32

import Data.Vector.Storable (unsafeWith, unsafeCast)
import Foreign.Ptr (castPtr)
import Foreign.Marshal.Array (allocaArray, peekArray)

data Atlas = Atlas { unAtlas :: HM.HashMap Text GLuint }

buildAtlas :: MonadIO m => (Text -> IO DynamicImage) -> [Text] -> m Atlas
buildAtlas cb srcs = do
    -- TODO Merge textures into an actual atlas.
    let len = length srcs
    textures <- liftIO $ allocaArray (toEnum len) $ \ptr -> do
        glGenTextures (toEnum len) ptr
        peekArray len ptr
    imgs <- liftIO $ forM srcs cb

    forM (zip textures imgs) $ \(texture, dyn) -> do
        let img = dynamicMap (unsafeCast . imageData) dyn
        let (format, word) = glFormat dyn
        liftIO $ glBindTexture GL_TEXTURE_2D texture
        liftIO $ unsafeWith img $
            glTexImage2D GL_TEXTURE_2D 0 GL_RGBA
                    (toEnum $ dynamicMap imageWidth dyn)
                    (toEnum $ dynamicMap imageHeight dyn)
                    0 format word

    return $ Atlas $ HM.fromList $ zip srcs textures

data Texture = Texture GLuint
atlasLookup :: Text -> Atlas -> Texture
atlasLookup key = Texture . fromMaybe 0 . HM.lookup key . unAtlas


glFormat (ImageY8 _) = (GL_LUMINANCE, GL_UNSIGNED_BYTE)
glFormat (ImageY16 _) = (GL_LUMINANCE, GL_UNSIGNED_SHORT)
glFormat (ImageY32 _) = (GL_LUMINANCE, GL_UNSIGNED_INT)
glFormat (ImageYF _) = (GL_LUMINANCE, GL_FLOAT)
glFormat (ImageYA8 _) = (GL_LUMINANCE_ALPHA, GL_BYTE)
glFormat (ImageYA16 _) = (GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT)
glFormat (ImageRGB8 _) = (GL_RGB, GL_UNSIGNED_BYTE)
glFormat (ImageRGB16 _) = (GL_RGB, GL_UNSIGNED_SHORT)
glFormat (ImageRGBF _) = (GL_RGB, GL_FLOAT)
glFormat (ImageRGBA8 _) = (GL_RGBA, GL_UNSIGNED_BYTE)
glFormat (ImageRGBA16 _) = (GL_RGBA, GL_UNSIGNED_BYTE)
glFormat (ImageYCbCr8 _) = (GL_YCRCB_444_SGIX, GL_UNSIGNED_BYTE)
glFormat (ImageCMYK8 _) = (GL_CMYK_EXT, GL_UNSIGNED_BYTE)
glFormat (ImageCMYK16 _) = (GL_CMYK_EXT, GL_UNSIGNED_SHORT)