summaryrefslogtreecommitdiff
path: root/CubeMap.hs
blob: 337881f4dd71c6a26328938fe0e52028bd117400 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
        }