module Graphics.Rendering.Ombra.Layer ( Buffer(..), Layer, layer, over, clear, -- * Programs Compatible, Program, program, -- * Sublayers subLayer, colorSubLayer, depthSubLayer, colorDepthSubLayer, colorStencilSubLayer, colorSubLayer', depthSubLayer', colorDepthSubLayer', colorStencilSubLayer', buffersSubLayer, buffersDepthSubLayer, buffersStencilSubLayer, -- * Layers with return values -- $extlayers Layer', LayerStatus(..), drawable, castLayer, -- ** Temporary textures TTexture, withTTexture, permanent, -- ** Drawing to textures depthToTexture, colorDepthToTexture, colorStencilToTexture, colorToTexture', depthToTexture', colorDepthToTexture', colorStencilToTexture', buffersDepthToTexture, buffersStencilToTexture ) where import Data.Word (Word8) import Graphics.Rendering.Ombra.Backend (GLES) import Graphics.Rendering.Ombra.Color import Graphics.Rendering.Ombra.Internal.TList import Graphics.Rendering.Ombra.Layer.Internal import Graphics.Rendering.Ombra.Object import Graphics.Rendering.Ombra.Shader.Program import Graphics.Rendering.Ombra.Texture -- | Create a simple Layer from a Program and an Object. layer :: (Subset progAttr grpAttr, Subset progUni grpUni) => Program progUni progAttr -> Object grpUni grpAttr -> Layer' s t () layer = Layer infixl 1 `over` -- | Draw the first Layer over the second one. This means that the first Layer -- will use the same buffers (color, depth, stencil) of the second, but -- the visibility of the objects still depends on their depth. over :: Layer -> Layer -> Layer over = flip (>>) -- | Alias for 'colorSubLayer'. subLayer :: Int -> Int -> Layer -> (Texture -> Layer) -> Layer subLayer = colorSubLayer -- | Use a 'Layer' as a 'Texture' on another. colorSubLayer :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Layer -- ^ Layer to draw on a 'Texture'. -> (Texture -> Layer) -- ^ Layers using the texture. -> Layer colorSubLayer w h l = colorDepthSubLayer w h l . flip . const -- | Use a 'Layer' as a depth 'Texture' on another. depthSubLayer :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Layer -- ^ Layer to draw on a -- depth 'Texture'. -> (Texture -> Layer) -- ^ Layers using the texture. -> Layer depthSubLayer w h l f = drawable $ depthToTexture w h (castLayer l) >>= \(_, t) -> withTTexture t f -- | Combination of 'colorSubLayer' and 'depthSubLayer'. colorDepthSubLayer :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Layer -- ^ Layer to draw on the -- 'Texture's. -> (Texture -> Texture -> Layer) -- ^ Color, depth. -> Layer colorDepthSubLayer w h l f = drawable $ colorDepthToTexture w h (castLayer l) >>= \(_, ct, dt) -> withTTextures [ct, dt] $ \[ct', dt'] -> f ct' dt' -- | 'colorSubLayer' with a stencil buffer. colorStencilSubLayer :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Layer -- ^ Layer to draw on a 'Texture' -> (Texture -> Layer) -- ^ Color. -> Layer colorStencilSubLayer w h l f = drawable $ colorStencilToTexture w h (castLayer l) >>= \(_, t) -> withTTexture t f -- | Extended version of 'colorSubLayer' that reads and converts the Texture -- pixels. colorSubLayer' :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Int -- ^ First pixel to read X -> Int -- ^ First pixel to read Y -> Int -- ^ Width of the rectangle to read -> Int -- ^ Height of the rectangle to read -> Layer -- ^ Layer to draw on a 'Texture'. -> (Texture -> [Color] -> Layer) -- ^ Function using the texture. -> Layer colorSubLayer' w h rx ry rw rh l f = drawable $ colorToTexture' w h rx ry rw rh (castLayer l) >>= \(_, t, c) -> withTTexture t $ flip f c -- | Extended version of 'depthSubLayer'. Not supported on WebGL. depthSubLayer' :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Int -- ^ First pixel to read X -> Int -- ^ First pixel to read Y -> Int -- ^ Width of the rectangle to read -> Int -- ^ Height of the rectangle to read -> Layer -- ^ Layer to draw on a depth 'Texture'. -> (Texture -> [Word8] -> Layer) -- ^ Layers using the texture. -> Layer depthSubLayer' w h rx ry rw rh l f = drawable $ depthToTexture' w h rx ry rw rh (castLayer l) >>= \(_, t, d) -> withTTexture t $ flip f d -- | Extended version of 'colorDepthSubLayer'. Not supported on WebGL. colorDepthSubLayer' :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Int -- ^ First pixel to read X -> Int -- ^ First pixel to read Y -> Int -- ^ Width of the rectangle to read -> Int -- ^ Height of the rectangle to read -> Layer -- ^ Layer to draw on a 'Texture' -> (Texture -> Texture -> [Color] -> [Word8] -> Layer) -- ^ Layers using -- the texture. -> Layer colorDepthSubLayer' w h rx ry rw rh l f = drawable $ colorDepthToTexture' w h rx ry rw rh (castLayer l) >>= \(_, ct, dt, c, d) -> withTTextures [ct, dt] $ \[ct', dt'] -> f ct' dt' c d -- | 'colorSubLayer'' with an additional stencil buffer. colorStencilSubLayer' :: Int -- ^ Texture width. -> Int -- ^ Texture height. -> Int -- ^ First pixel to read X -> Int -- ^ First pixel to read Y -> Int -- ^ Width of the rectangle to read -> Int -- ^ Height of the rectangle to read -> Layer -- ^ Layer to draw on a 'Texture'. -> (Texture -> [Color] -> Layer) -- ^ Function using the texture. -> Layer colorStencilSubLayer' w h rx ry rw rh l f = drawable $ colorStencilToTexture' w h rx ry rw rh (castLayer l) >>= \(_, t, c) -> withTTexture t $ flip f c -- | Draw a 'Layer' with multiple floating point colors -- (use 'Fragment2', 'Fragment3', etc.) to some 'Texture's and use them to -- create another Layer. buffersSubLayer :: Int -- ^ Textures width. -> Int -- ^ Textures height. -> Int -- ^ Number of colors. -> Layer -- ^ Layer to draw. -> ([Texture] -> Layer) -- ^ Function using the textures. -> Layer buffersSubLayer w h n l = buffersDepthSubLayer w h n l . flip . const -- | Combination of 'buffersSubLayer' and 'depthSubLayer'. buffersDepthSubLayer :: Int -- ^ Textures width. -> Int -- ^ Textures height. -> Int -- ^ Number of colors. -> Layer -- ^ Layer to draw. -> ([Texture] -> Texture -> Layer) -- ^ Function using the -- buffers textures and -- the depth texture. -> Layer buffersDepthSubLayer w h n l f = drawable $ buffersDepthToTexture w h n (castLayer l) >>= \(_, bts, dt) -> withTTextures (dt : bts) $ \(dt' : bts') -> f bts' dt' -- | 'buffersSubLayer' with an additional stencil buffer. buffersStencilSubLayer :: Int -- ^ Textures width. -> Int -- ^ Textures height. -> Int -- ^ Number of colors. -> Layer -- ^ Layer to draw. -> ([Texture] -> Layer) -- ^ Function using the texture. -> Layer buffersStencilSubLayer w h n l f = drawable $ buffersStencilToTexture w h n (castLayer l) >>= \(_, bts) -> withTTextures bts f -- $extlayers -- Functions like 'subLayer' create temporary textures that usually have to be -- freed immediately after drawing the layer, otherwise they may waste a lot of -- GPU memory if @subLayer@ is called in every frame. The 'Layer'' type lets -- you extract those textures after having made permanent.