module CubeMap ( loadSkyboxes , Skyboxes(..) ) where import LambdaCube.GL as LC import LambdaCube.GL.Mesh as LC import LambdaCube.GL.Data (uploadCubeMapToGPU) import Data.Maybe import Control.Monad import Data.List import System.Directory import System.FilePath import Codec.Archive.Zip import qualified Data.ByteString.Lazy as Lazy import Codec.Picture as Juicy image_names_xyz_dir :: [String] image_names_xyz_dir = [ "xforward" , "xreverse" , "yforward" , "yreverse" , "zforward" , "zreverse" ] image_names_np_xyz :: [String] image_names_np_xyz = [ "negx" , "negy" , "negz" , "posx" , "posy" , "posz" ] filterImageNames :: [String] -> [String] filterImageNames fns = map snd $ sortOn fst $ go (zip [0..] image_names_xyz_dir) (zip [1,3,5,0,2,4] image_names_np_xyz) $ sort fns where go ((n,x):xs) ys (fn:fns) | x `isPrefixOf` fn = (n,fn) : go xs ys fns go xs ((n,y):ys) (fn:fns) | y `isPrefixOf` fn = (n,fn) : go xs ys fns go xs ys ( _:fns) = go xs ys fns go xs ys [] = [] data Skyboxes = Skyboxes { skyboxCount :: Int , skyboxNames :: [String] , skyboxLoad :: Int -> IO (Either String [DynamicImage]) } loadSkyboxes :: IO Skyboxes loadSkyboxes = do let dir = "./skyboxes" zips <- listDirectory dir let len = length zips return Skyboxes { skyboxCount = len , skyboxNames = zips , skyboxLoad = \n -> do let fn = zips !! mod n len archive <- toArchive <$> Lazy.readFile (dir fn) let es = mapMaybe (`findEntryByPath` archive) $ filterImageNames (filesInArchive archive) imgs <- forM es $ \entry -> do return $ Juicy.decodeImage $ Lazy.toStrict $ fromEntry entry return $ sequence imgs }