ombra-0.2.2.0: Graphics/Rendering/Ombra/Layer.hs
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.