diff options
author | Csaba Hruska <csaba.hruska@gmail.com> | 2015-04-30 14:28:27 +0200 |
---|---|---|
committer | Csaba Hruska <csaba.hruska@gmail.com> | 2015-05-18 14:50:52 +0200 |
commit | 91f82aca82dc282d5630c1bddd8dc773c679cc76 (patch) | |
tree | 6060474da94e6fb8a1f46eebd0cba0c5a607cbd3 /Backend/GL/Data.hs | |
parent | 1d047c6fa195901dc149bdbe4b4d0497c9b5f9c6 (diff) |
split dsl compiler and ir backend
Diffstat (limited to 'Backend/GL/Data.hs')
-rw-r--r-- | Backend/GL/Data.hs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/Backend/GL/Data.hs b/Backend/GL/Data.hs new file mode 100644 index 0000000..4eb3fa0 --- /dev/null +++ b/Backend/GL/Data.hs | |||
@@ -0,0 +1,95 @@ | |||
1 | module Backend.GL.Data where | ||
2 | |||
3 | import Control.Applicative | ||
4 | import Control.Monad | ||
5 | import Data.ByteString.Char8 (ByteString) | ||
6 | import Data.IORef | ||
7 | import Data.List as L | ||
8 | import Data.Maybe | ||
9 | import Data.Trie as T | ||
10 | import Foreign | ||
11 | --import qualified Data.IntMap as IM | ||
12 | import qualified Data.Map as Map | ||
13 | import qualified Data.Set as Set | ||
14 | import qualified Data.Vector as V | ||
15 | import qualified Data.Vector.Storable as SV | ||
16 | |||
17 | --import Control.DeepSeq | ||
18 | |||
19 | import Graphics.Rendering.OpenGL.Raw.Core33 | ||
20 | import Data.Word | ||
21 | import Codec.Picture | ||
22 | import Codec.Picture.RGBA8 | ||
23 | |||
24 | import Backend.GL.Type | ||
25 | import Backend.GL.Util | ||
26 | |||
27 | -- Buffer | ||
28 | compileBuffer :: [Array] -> IO Buffer | ||
29 | compileBuffer arrs = do | ||
30 | let calcDesc (offset,setters,descs) (Array arrType cnt setter) = | ||
31 | let size = cnt * sizeOfArrayType arrType | ||
32 | in (size + offset, (offset,size,setter):setters, ArrayDesc arrType cnt offset size:descs) | ||
33 | (bufSize,arrSetters,arrDescs) = foldl' calcDesc (0,[],[]) arrs | ||
34 | bo <- alloca $! \pbo -> glGenBuffers 1 pbo >> peek pbo | ||
35 | glBindBuffer gl_ARRAY_BUFFER bo | ||
36 | glBufferData gl_ARRAY_BUFFER (fromIntegral bufSize) nullPtr gl_STATIC_DRAW | ||
37 | forM_ arrSetters $! \(offset,size,setter) -> setter $! glBufferSubData gl_ARRAY_BUFFER (fromIntegral offset) (fromIntegral size) | ||
38 | glBindBuffer gl_ARRAY_BUFFER 0 | ||
39 | return $! Buffer (V.fromList $! reverse arrDescs) bo | ||
40 | |||
41 | updateBuffer :: Buffer -> [(Int,Array)] -> IO () | ||
42 | updateBuffer (Buffer arrDescs bo) arrs = do | ||
43 | glBindBuffer gl_ARRAY_BUFFER bo | ||
44 | forM arrs $ \(i,Array arrType cnt setter) -> do | ||
45 | let ArrayDesc ty len offset size = arrDescs V.! i | ||
46 | when (ty == arrType && cnt == len) $ | ||
47 | setter $! glBufferSubData gl_ARRAY_BUFFER (fromIntegral offset) (fromIntegral size) | ||
48 | glBindBuffer gl_ARRAY_BUFFER 0 | ||
49 | |||
50 | bufferSize :: Buffer -> Int | ||
51 | bufferSize = V.length . bufArrays | ||
52 | |||
53 | arraySize :: Buffer -> Int -> Int | ||
54 | arraySize buf arrIdx = arrLength $! bufArrays buf V.! arrIdx | ||
55 | |||
56 | arrayType :: Buffer -> Int -> ArrayType | ||
57 | arrayType buf arrIdx = arrType $! bufArrays buf V.! arrIdx | ||
58 | |||
59 | -- Texture | ||
60 | |||
61 | -- FIXME: Temporary implemenation | ||
62 | compileTexture2DRGBAF :: Bool -> Bool -> DynamicImage -> IO TextureData | ||
63 | compileTexture2DRGBAF isMip isClamped bitmap' = do | ||
64 | let bitmap = ImageRGBA8 $ fromDynamicImage bitmap' | ||
65 | glPixelStorei gl_UNPACK_ALIGNMENT 1 | ||
66 | to <- alloca $! \pto -> glGenTextures 1 pto >> peek pto | ||
67 | glBindTexture gl_TEXTURE_2D to | ||
68 | let (width,height) = bitmapSize bitmap | ||
69 | bitmapSize (ImageRGB8 (Image w h _)) = (w,h) | ||
70 | bitmapSize (ImageRGBA8 (Image w h _)) = (w,h) | ||
71 | bitmapSize _ = error "unsupported image type :(" | ||
72 | withBitmap (ImageRGB8 (Image w h v)) f = SV.unsafeWith v $ f (w,h) 3 0 | ||
73 | withBitmap (ImageRGBA8 (Image w h v)) f = SV.unsafeWith v $ f (w,h) 4 0 | ||
74 | withBitmap _ _ = error "unsupported image type :(" | ||
75 | wrapMode = case isClamped of | ||
76 | True -> gl_CLAMP_TO_EDGE | ||
77 | False -> gl_REPEAT | ||
78 | (minFilter,maxLevel) = case isMip of | ||
79 | False -> (gl_LINEAR,0) | ||
80 | True -> (gl_LINEAR_MIPMAP_LINEAR, floor $ log (fromIntegral $ max width height) / log 2) | ||
81 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_WRAP_S $ fromIntegral wrapMode | ||
82 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_WRAP_T $ fromIntegral wrapMode | ||
83 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_MIN_FILTER $ fromIntegral minFilter | ||
84 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_MAG_FILTER $ fromIntegral gl_LINEAR | ||
85 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_BASE_LEVEL 0 | ||
86 | glTexParameteri gl_TEXTURE_2D gl_TEXTURE_MAX_LEVEL $ fromIntegral maxLevel | ||
87 | withBitmap bitmap $ \(w,h) nchn 0 ptr -> do | ||
88 | let internalFormat = fromIntegral gl_RGBA8 | ||
89 | dataFormat = fromIntegral $ case nchn of | ||
90 | 3 -> gl_RGB | ||
91 | 4 -> gl_RGBA | ||
92 | _ -> error "unsupported texture format!" | ||
93 | glTexImage2D gl_TEXTURE_2D 0 internalFormat (fromIntegral w) (fromIntegral h) 0 dataFormat gl_UNSIGNED_BYTE $ castPtr ptr | ||
94 | when isMip $ glGenerateMipmap gl_TEXTURE_2D | ||
95 | return $ TextureData to | ||