-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Typesafe functional GPU graphics programming
--   
--   A typesafe API based on the conceptual model of OpenGl, but without
--   the imperative state machine. Aims to be as close to the raw OpenGl
--   performance as possible, without compromising type safety or
--   functional style. Includes DSL for shaders to provide type safety even
--   when crossing into that domain. Uses OpenGl 3.3 core profile under the
--   hood.
@package GPipe
@version 2.2.3


-- | This module provides the DSL for shader operations in GPipe. The type
--   <tt><a>S</a> x a</tt> is an opaque type that represents a value of
--   type <tt>a</tt> in a shader stage <tt>x</tt>, eg <tt>S F Float</tt>
--   means a floating point value in a fragment stream.
module Graphics.GPipe.Expr
data S x a

-- | Phantom type used as first argument in <tt><a>S</a> <a>V</a> a</tt>
--   that denotes that the shader value is a vertex value
data V

-- | Phantom type used as first argument in <tt><a>S</a> <a>F</a> a</tt>
--   that denotes that the shader value is a fragment value
data F
type VFloat = S V Float
type VInt = S V Int
type VWord = S V Word
type VBool = S V Bool
type FFloat = S F Float
type FInt = S F Int
type FWord = S F Word
type FBool = S F Bool

-- | Provides a common way to convert numeric types to integer and floating
--   point representations.
class Convert a where {
    type family ConvertFloat a;
    type family ConvertInt a;
    type family ConvertWord a;
}

-- | Convert to a floating point number.
toFloat :: Convert a => a -> ConvertFloat a

-- | Convert to an integral number, using truncation if necessary.
toInt :: Convert a => a -> ConvertInt a

-- | Convert to an unsigned integral number, using truncation if necessary.
toWord :: Convert a => a -> ConvertWord a
class Integral' a
div' :: Integral' a => a -> a -> a
mod' :: Integral' a => a -> a -> a

-- | This class provides the GPU functions either not found in Prelude's
--   numerical classes, or that has wrong types. Instances are also
--   provided for normal <a>Float</a>s and <a>Double</a>s.
class Floating a => Real' a
rsqrt :: Real' a => a -> a
exp2 :: Real' a => a -> a
log2 :: Real' a => a -> a
floor' :: Real' a => a -> a
ceiling' :: Real' a => a -> a
fract' :: Real' a => a -> a
mod'' :: Real' a => a -> a -> a
mix :: Real' a => a -> a -> a -> a
atan2' :: Real' a => a -> a -> a

-- | This class provides various order comparing functions
class (IfB a, OrdB a, Floating a) => FloatingOrd a
clamp :: FloatingOrd a => a -> a -> a -> a
saturate :: FloatingOrd a => a -> a
step :: FloatingOrd a => a -> a -> a
smoothstep :: FloatingOrd a => a -> a -> a -> a

-- | The derivative in x using local differencing of the rasterized value.
dFdx :: FFloat -> FFloat

-- | The derivative in y using local differencing of the rasterized value.
dFdy :: FFloat -> FFloat

-- | The sum of the absolute derivative in x and y using local differencing
--   of the rasterized value.
fwidth :: FFloat -> FFloat

-- | <tt>while f g x</tt> will iteratively transform <tt>x</tt> with
--   <tt>g</tt> as long as <tt>f</tt> generates <a>true</a>.
while :: forall a x. (ShaderType a x) => (a -> S x Bool) -> (a -> a) -> a -> a

-- | <tt>ifThen c f x</tt> will return <tt>f x</tt> if <tt>c</tt> evaluates
--   to <a>true</a> or <tt>x</tt> otherwise.
--   
--   In most cases functionally equivalent to <a>ifThenElse'</a> but
--   usually generate smaller shader code since the last argument is not
--   inlined into the two branches, which also would affect implicit
--   derivates (e.g. <a>dFdx</a>, <a>dFdy</a> or sampling using
--   <tt>SampleAuto</tt>)
ifThen :: forall a x. (ShaderType a x) => S x Bool -> (a -> a) -> a -> a

-- | <tt>ifThenElse c f g x</tt> will return <tt>f x</tt> if <tt>c</tt>
--   evaluates to <a>true</a> or <tt>g x</tt> otherwise.
--   
--   In most cases functionally equivalent to <a>ifThenElse'</a> but
--   usually generate smaller shader code since the last argument is not
--   inlined into the two branches, which also would affect implicit
--   derivates (e.g. <a>dFdx</a>, <a>dFdy</a> or sampling using
--   <tt>SampleAuto</tt>)
ifThenElse :: forall a b x. (ShaderType a x, ShaderType b x) => S x Bool -> (a -> b) -> (a -> b) -> a -> b

-- | Works just like <a>ifB</a>, return second argument if first is
--   <a>true</a> otherwise return third argument.
--   
--   The difference from <a>ifB</a> is that it in most cases generate more
--   efficient code when <tt>a</tt> is a compound type (e.g. a tuple or a
--   vector). For simple types such as <tt>S x Float</tt>, <tt>ifThenElse'
--   == ifB</tt>.
ifThenElse' :: forall a x. (ShaderType a x) => S x Bool -> a -> a -> a

-- | An opaque type
data ShaderBase a x

-- | Constraint for types that may pass in and out of shader control
--   structures. Define your own instances in terms of others and make sure
--   to make toBase as lazy as possible.
class ShaderType a x where {
    type family ShaderBaseType a;
}

-- | Convert this type to the shader base type. Make sure this is as lazy
--   as possible (e.g. use tilde (<tt>~</tt>) on each pattern match).
toBase :: ShaderType a x => x -> a -> ShaderBase (ShaderBaseType a) x

-- | Convert back from the shader base type to this type.
fromBase :: ShaderType a x => x -> ShaderBase (ShaderBaseType a) x -> a


-- | Buffers are arrays of data that resides on the GPU. A buffer is
--   strongly typed with an immutable size, but it's content is mutable. A
--   buffer lives in an object space and may be shared between contexts.
--   
--   Buffers in GPipe are used to store vertices, indices and uniform
--   values and can also be used to copy pixel data to and from textures.
--   They can be written from the host (ie the normal Haskell world) but
--   cannot be read back (but textures can).
--   
--   The atomic buffer element types are <tt><a>B</a> a</tt>, <tt><a>B2</a>
--   a</tt>, <tt><a>B3</a> a</tt> and <tt><a>B4</a> a</tt> where <tt>a</tt>
--   is a normal haskell type such as <tt>Int32</tt> or <a>Float</a>. By
--   creating instances of the type class <a>BufferFormat</a> you may
--   create new composite buffer types.
module Graphics.GPipe.Buffer

-- | A <tt>Buffer os b</tt> lives in the object space <tt>os</tt> and
--   contains elements of type <tt>b</tt>.
data Buffer os b

-- | The class that constraints which types can live in a buffer.
class BufferFormat f where {
    type family HostFormat f;
}

-- | An arrow action that turns a value from it's host representation to
--   it's buffer representation. Use <a>toBuffer</a> from the GPipe
--   provided instances to operate in this arrow. Also note that this arrow
--   needs to be able to return a value lazily, so ensure you use
--   
--   <pre>
--   proc ~pattern -&gt; do ...
--   </pre>
toBuffer :: BufferFormat f => ToBuffer (HostFormat f) f

-- | The arrow type for <a>toBuffer</a>.
data ToBuffer a b

-- | The atomic buffer value that represents a host value of type
--   <tt>a</tt>.
data B a

-- | An atomic buffer value that represents a vector of 2 <tt>a</tt>s on
--   the host.
data B2 a

-- | An atomic buffer value that represents a vector of 3 <tt>a</tt>s on
--   the host.
data B3 a

-- | An atomic buffer value that represents a vector of 4 <tt>a</tt>s on
--   the host. This works similar to '(B a, B a, B a, B a)' but has some
--   performance advantage, especially when used in <tt>VertexArray</tt>s.
data B4 a

-- | This works like a 'B a', but has an alignment smaller than 4 bytes
--   that is the limit for vertex buffers, and thus cannot be used for
--   those. Index buffers on the other hand need to be tightly packed, so
--   you need to use this type for index buffers of <a>Word8</a> or
--   <a>Word16</a>.
data BPacked a

-- | This wrapper is used for integer values to indicate that it should be
--   interpreted as a floating point value, in the range [-1,1] or [0,1]
--   depending on wether it is a signed or unsigned integer (i.e.
--   <a>Int</a> or <a>Word</a>).
newtype Normalized a
Normalized :: a -> Normalized a

-- | Create a buffer with a specified number of elements.
newBuffer :: (MonadIO m, BufferFormat b, ContextHandler ctx) => Int -> ContextT ctx os m (Buffer os b)

-- | Retrieve the number of elements in a buffer.
bufferLength :: Buffer os b -> Int

-- | Write a buffer from the host (i.e. the normal Haskell world).
writeBuffer :: (ContextHandler ctx, MonadIO m) => Buffer os b -> BufferStartPos -> [HostFormat b] -> ContextT ctx os m ()

-- | Copies values from one buffer to another (of the same type).
--   
--   <tt>copyBuffer fromBuffer fromStart toBuffer toStart length</tt> will
--   copy <tt>length</tt> elements from position <tt>fromStart</tt> in
--   <tt>fromBuffer</tt> to position <tt>toStart</tt> in <tt>toBuffer</tt>.
copyBuffer :: (ContextHandler ctx, MonadIO m) => Buffer os b -> BufferStartPos -> Buffer os b -> BufferStartPos -> Int -> ContextT ctx os m ()
type BufferStartPos = Int

-- | This type family restricts what host and buffer types a texture format
--   may be converted into. 'BufferColor t h' for a texture representation
--   <tt>t</tt> and a host representation <tt>h</tt> will evaluate to a
--   buffer type used in the transfer. This family is closed, i.e. you
--   cannot create additional instances to it.


-- | A Context in GPipe (just as in OpenGl) consist of two things, a window
--   and an object space. The object space consists of Buffers, Textures
--   and Shaders. You may create a context without a window (for example
--   for rendering to textures that are saved as pngs instead of showed),
--   and you can create a context that shares the object space with another
--   context.
--   
--   Context creation is abstracted away from GPipe, and you need a package
--   that provides a <tt>ContextFactory</tt>, such as <tt>GPipe-GLFW</tt>.
module Graphics.GPipe.Context

-- | The monad transformer that encapsulates a GPipe context (which wraps
--   an OpenGl context).
--   
--   A value of type <tt>ContextT ctx os m a</tt> is an action on a context
--   with these parameters:
--   
--   <ul>
--   <li><i><tt>ctx</tt></i> The context handler.</li>
--   <li><i><tt>os</tt></i> An abstract type that is used to denote the
--   object space. This is an forall type defined by the <a>runContextT</a>
--   call which will restrict any objects created inside this context to be
--   returned from it or used by another context (the same trick as the
--   <tt>ST</tt> monad uses).</li>
--   <li><i><tt>m</tt></i> The monad this monad transformer wraps. Need to
--   have <a>IO</a> in the bottom for this <a>ContextT</a> to be
--   runnable.</li>
--   <li><i><tt>a</tt></i> The value returned from this monad action.</li>
--   </ul>
data ContextT ctx os m a

-- | Run a <a>ContextT</a> monad transformer that encapsulates an object
--   space. You need an implementation of a <a>ContextHandler</a>, which is
--   provided by an auxillary package, such as <tt>GPipe-GLFW</tt>.
runContextT :: (MonadIO m, MonadAsyncException m, ContextHandler ctx) => ContextHandlerParameters ctx -> (forall os. ContextT ctx os m a) -> m a
data Window os c ds

-- | Creates a window
newWindow :: (ContextHandler ctx, MonadIO m) => WindowFormat c ds -> WindowParameters ctx -> ContextT ctx os m (Window os c ds)

-- | Deletes a window. Any rendering to this window will become a noop.
deleteWindow :: (ContextHandler ctx, MonadIO m) => Window os c ds -> ContextT ctx os m ()

-- | Return the current size of the context frame buffer. This is needed to
--   set viewport size and to get the aspect ratio to calculate projection
--   matrices.
getFrameBufferSize :: (ContextHandler ctx, MonadIO m) => Window os c ds -> ContextT ctx os m (V2 Int)

-- | Run this action after a <a>render</a> call to swap out the context
--   windows back buffer with the front buffer, effectively showing the
--   result. This call may block if vsync is enabled in the system and/or
--   too many frames are outstanding. After this call, the context window
--   content is undefined and should be cleared at earliest convenience
--   using <tt>clearContextColor</tt> and friends.
swapWindowBuffers :: (ContextHandler ctx, MonadIO m) => Window os c ds -> ContextT ctx os m ()

-- | Use the context window handle, which type is specific to the window
--   system used. This handle shouldn't be returned from this function
withContextWindow :: MonadIO m => Window os c ds -> (Maybe (ContextWindow ctx) -> IO a) -> ContextT ctx os m a

-- | Class implementing a window handler that can create openGL contexts,
--   such as GLFW or GLUT
class ContextHandler ctx where {
    data family ContextHandlerParameters ctx;
    type family ContextWindow ctx;
    type family WindowParameters ctx;
}

-- | Create a context handler. Called from the main thread
contextHandlerCreate :: ContextHandler ctx => ContextHandlerParameters ctx -> IO ctx

-- | Delete the context handler. All contexts created from this handler
--   will be deleted using contextDelete prior to calling this.
contextHandlerDelete :: ContextHandler ctx => ctx -> IO ()

-- | Create a new context sharing all other contexts created by this
--   ContextHandler. If the parameter is Nothing, a hidden off-screen
--   context is created, otherwise creates a window with the provided
--   window bits and implementation specific parameters. Only ever called
--   from the mainthread (i.e. the thread that called
--   contextHandlerCreate).
createContext :: ContextHandler ctx => ctx -> Maybe (WindowBits, WindowParameters ctx) -> IO (ContextWindow ctx)

-- | Run an OpenGL IO action in this context, that doesn't return any value
--   to the caller. This may be run after contextDelete or
--   contextHandlerDelete has been called. The thread calling this may not
--   be the same creating the context (for finalizers it is most definetly
--   not). May also be called on previously deleted windows in the case of
--   finalizers.
contextDoAsync :: ContextHandler ctx => ctx -> Maybe (ContextWindow ctx) -> IO () -> IO ()

-- | Swap the front and back buffers in the context's default frame buffer.
--   Only ever called from the mainthread (i.e. the thread that called
--   <a>contextHandlerCreate</a>). Never called on deleted windows.
contextSwap :: ContextHandler ctx => ctx -> ContextWindow ctx -> IO ()

-- | Get the current size of the context's default framebuffer (which may
--   change if the window is resized). Only ever called from the mainthread
--   (i.e. the thread that called <a>contextHandlerCreate</a>)
contextFrameBufferSize :: ContextHandler ctx => ctx -> ContextWindow ctx -> IO (Int, Int)

-- | Delete a context and close any associated window. Only ever called
--   from the mainthread (i.e. the thread that called
--   <a>contextHandlerCreate</a>). Only ever called once per window, and
--   will always be called for each window before the context is deleted
--   with <a>contextHandlerDelete</a>.
contextDelete :: ContextHandler ctx => ctx -> ContextWindow ctx -> IO ()

-- | This kind of exception may be thrown from GPipe when a GPU hardware
--   limit is reached (for instance, too many textures are drawn to from
--   the same <tt>FragmentStream</tt>)
data GPipeException
GPipeException :: String -> GPipeException


-- | This module provides data types for all formats of textures and frame
--   buffers. None of the type classes in this module are intended to be
--   instanced by anyone else. In fact, GPipe only uses these type classes
--   through the GADT <a>Format</a>, which is closed, so any new instances
--   wouldnt be considered anyway.
module Graphics.GPipe.Format
data Format a
[R8] :: Format RFloat
[R8S] :: Format RFloat
[R16] :: Format RFloat
[R16S] :: Format RFloat
[R16F] :: Format RFloat
[R32F] :: Format RFloat
[R8I] :: Format RInt
[R16I] :: Format RInt
[R32I] :: Format RInt
[R8UI] :: Format RWord
[R16UI] :: Format RWord
[R32UI] :: Format RWord
[RG8] :: Format RGFloat
[RG8S] :: Format RGFloat
[RG16] :: Format RGFloat
[RG16S] :: Format RGFloat
[RG16F] :: Format RGFloat
[RG32F] :: Format RGFloat
[RG8I] :: Format RGInt
[RG16I] :: Format RGInt
[RG32I] :: Format RGInt
[RG8UI] :: Format RGWord
[RG16UI] :: Format RGWord
[RG32UI] :: Format RGWord
[R3G3B2] :: Format RGBFloat
[RGB4] :: Format RGBFloat
[RGB5] :: Format RGBFloat
[RGB8] :: Format RGBFloat
[RGB8S] :: Format RGBFloat
[RGB10] :: Format RGBFloat
[RGB12] :: Format RGBFloat
[RGB16] :: Format RGBFloat
[RGB16S] :: Format RGBFloat
[RGB16F] :: Format RGBFloat
[RGB32F] :: Format RGBFloat
[R11FG11FB10F] :: Format RGBFloat
[RGB9E5] :: Format RGBFloat
[SRGB8] :: Format RGBFloat
[RGB8I] :: Format RGBInt
[RGB16I] :: Format RGBInt
[RGB32I] :: Format RGBInt
[RGBWord] :: Format RGBWord
[RGB8UI] :: Format RGBWord
[RGB16UI] :: Format RGBWord
[RGB32UI] :: Format RGBWord
[RGBA2] :: Format RGBAFloat
[RGBA4] :: Format RGBAFloat
[RGB5A1] :: Format RGBAFloat
[RGBA8] :: Format RGBAFloat
[RGBA8S] :: Format RGBAFloat
[RGB10A2] :: Format RGBAFloat
[RGBA12] :: Format RGBAFloat
[RGBA16] :: Format RGBAFloat
[RGBA16S] :: Format RGBAFloat
[RGBA16F] :: Format RGBAFloat
[RGBA32F] :: Format RGBAFloat
[SRGB8A8] :: Format RGBAFloat
[RGBA8I] :: Format RGBAInt
[RGBA16I] :: Format RGBAInt
[RGBA32I] :: Format RGBAInt
[RGBA8UI] :: Format RGBAWord
[RGBA16UI] :: Format RGBAWord
[RGBA32UI] :: Format RGBAWord
[Depth16] :: Format Depth
[Depth24] :: Format Depth
[Depth32] :: Format Depth
[Depth32F] :: Format Depth
[Stencil1] :: Format Stencil
[Stencil4] :: Format Stencil
[Stencil8] :: Format Stencil
[Stencil16] :: Format Stencil
[Depth24Stencil8] :: Format DepthStencil
[Depth32FStencil8] :: Format DepthStencil
class TextureFormat f
data RFloat
data RInt
data RWord
data RGFloat
data RGInt
data RGWord
data RGBFloat
data RGBInt
data RGBWord
data RGBAFloat
data RGBAInt
data RGBAWord
data Depth
data Stencil
data DepthStencil
class TextureFormat f => ColorSampleable f where {
    type family Color f a;
    type family ColorElement f :: *;
}
class ColorSampleable c => ColorRenderable c
class ColorSampleable f => DepthRenderable f
class StencilRenderable f
data WindowFormat c ds
[WindowFormatColor] :: ContextColorFormat c => Format c -> WindowFormat c ()
[WindowFormatColorDepth] :: ContextColorFormat c => Format c -> Format Depth -> WindowFormat c Depth
[WindowFormatColorStencil] :: ContextColorFormat c => Format c -> Format Stencil -> WindowFormat c Stencil
[WindowFormatColorDepthStencilSeparate] :: ContextColorFormat c => Format c -> Format Depth -> Format Stencil -> WindowFormat c DepthStencil
[WindowFormatColorDepthStencilCombined] :: ContextColorFormat c => Format c -> Format DepthStencil -> WindowFormat c DepthStencil
[WindowFormatDepth] :: Format Depth -> WindowFormat () Depth
[WindowFormatStencil] :: Format Stencil -> WindowFormat () Stencil
[WindowFormatDepthStencilSeparate] :: Format Depth -> Format Stencil -> WindowFormat () DepthStencil
[WindowFormatDepthStencilCombined] :: Format DepthStencil -> WindowFormat () DepthStencil
class ColorRenderable c => ContextColorFormat c
windowBits :: WindowFormat c ds -> WindowBits
type WindowBits = ((Int, Int, Int, Int, Bool), Int, Int)


-- | This module defines all functions and types for drawing into a context
--   window or texture from a <a>Shader</a>.
module Graphics.GPipe.FrameBuffer

-- | Draw color values from a <a>FragmentStream</a> into the window.
drawWindowColor :: forall os s c ds. ContextColorFormat c => (s -> (Window os c ds, ContextColorOption c)) -> FragmentStream (FragColor c) -> Shader os s ()

-- | Perform a depth test for each fragment from a <a>FragmentStream</a> in
--   the window. This doesn't draw any color values and only affects the
--   depth buffer.
drawWindowDepth :: forall os s c ds. DepthRenderable ds => (s -> (Window os c ds, DepthOption)) -> FragmentStream FragDepth -> Shader os s ()

-- | Perform a depth test for each fragment from a <a>FragmentStream</a>
--   and write a color value from each fragment that passes the test into
--   the window.
drawWindowColorDepth :: forall os s c ds. (ContextColorFormat c, DepthRenderable ds) => (s -> (Window os c ds, ContextColorOption c, DepthOption)) -> FragmentStream (FragColor c, FragDepth) -> Shader os s ()

-- | Perform a stencil test for each fragment from a <a>FragmentStream</a>
--   in the window. This doesn't draw any color values and only affects the
--   stencil buffer.
drawWindowStencil :: forall os s c ds. StencilRenderable ds => (s -> (Window os c ds, StencilOptions)) -> FragmentStream () -> Shader os s ()

-- | Perform a stencil test for each fragment from a <a>FragmentStream</a>
--   and write a color value from each fragment that passes the test into
--   the window.
drawWindowColorStencil :: forall os s c ds. (ContextColorFormat c, StencilRenderable ds) => (s -> (Window os c ds, ContextColorOption c, StencilOptions)) -> FragmentStream (FragColor c) -> Shader os s ()

-- | Perform a stencil test and depth test (in that order) for each
--   fragment from a <a>FragmentStream</a> in the window. This doesnt draw
--   any color values and only affects the depth and stencil buffer.
drawWindowDepthStencil :: forall os s c ds. (DepthRenderable ds, StencilRenderable ds) => (s -> (Window os c ds, DepthStencilOption)) -> FragmentStream FragDepth -> Shader os s ()

-- | Perform a stencil test and depth test (in that order) for each
--   fragment from a <a>FragmentStream</a> and write a color value from
--   each fragment that passes the tests into the window.
drawWindowColorDepthStencil :: forall os s c ds. (ContextColorFormat c, DepthRenderable ds, StencilRenderable ds) => (s -> (Window os c ds, ContextColorOption c, DepthStencilOption)) -> FragmentStream (FragColor c, FragDepth) -> Shader os s ()

-- | Draw all fragments in a <a>FragmentStream</a> using the provided
--   function that passes each fragment value into a <a>DrawColors</a>
--   monad. The first argument is a function that retrieves a
--   <a>Blending</a> setting from the shader environment, which will be
--   used for all <a>drawColor</a> actions in the <a>DrawColors</a> monad
--   where <a>UseBlending</a> is <a>True</a>. (OpenGl 3.3 unfortunately
--   doesn't support having different blending settings for different color
--   targets.)
draw :: forall a os f s. (s -> Blending) -> FragmentStream a -> (a -> DrawColors os s ()) -> Shader os s ()

-- | Like <a>draw</a>, but performs a depth test on each fragment first.
--   The <a>DrawColors</a> monad is then only run for fragments where the
--   depth test passes.
drawDepth :: forall a os f s d. DepthRenderable d => (s -> (Blending, Image (Format d), DepthOption)) -> FragmentStream (a, FragDepth) -> (a -> DrawColors os s ()) -> Shader os s ()

-- | Like <a>draw</a>, but performs a stencil test on each fragment first.
--   The <a>DrawColors</a> monad is then only run for fragments where the
--   stencil test passes.
drawStencil :: forall a os f s st. StencilRenderable st => (s -> (Blending, Image (Format st), StencilOptions)) -> FragmentStream a -> (a -> DrawColors os s ()) -> Shader os s ()

-- | Like <a>draw</a>, but performs a stencil test and a depth test (in
--   that order) on each fragment first. The <a>DrawColors</a> monad is
--   then only run for fragments where the stencil and depth test passes.
drawDepthStencil :: forall a os f s d st. (DepthRenderable d, StencilRenderable st) => (s -> (Blending, Image (Format d), Image (Format st), DepthStencilOption)) -> FragmentStream (a, FragDepth) -> (a -> DrawColors os s ()) -> Shader os s ()

-- | Draw color values into a color renderable texture image.
drawColor :: forall c s os. ColorRenderable c => (s -> (Image (Format c), ColorMask c, UseBlending)) -> FragColor c -> DrawColors os s ()

-- | A monad in which individual color images can be drawn.
data DrawColors os s a

-- | A texture image is a reference to a 2D array of pixels in a texture.
--   Some textures contain one <a>Image</a> per level of detail while some
--   contain several.
data Image f

-- | Compare two images that doesn't necessarily has same type
imageEquals :: Image a -> Image b -> Bool

-- | Retrieve the 2D size an image
imageSize :: Image f -> V2 Int
getTexture1DImage :: Texture1D os f -> Level -> Render os (Image f)
getTexture1DArrayImage :: Texture1DArray os f -> Level -> Int -> Render os (Image f)
getTexture2DImage :: Texture2D os f -> Level -> Render os (Image f)
getTexture2DArrayImage :: Texture2DArray os f -> Level -> Int -> Render os (Image f)
getTexture3DImage :: Texture3D os f -> Level -> Int -> Render os (Image f)
getTextureCubeImage :: TextureCube os f -> Level -> CubeSide -> Render os (Image f)

-- | Fill the window's back buffer with a constant color value
clearWindowColor :: forall os c ds. ContextColorFormat c => Window os c ds -> Color c Float -> Render os ()

-- | Fill the window's back depth buffer with a constant depth value (in
--   the range [0,1])
clearWindowDepth :: DepthRenderable ds => Window os c ds -> Float -> Render os ()

-- | Fill the window's back stencil buffer with a constant stencil value
clearWindowStencil :: StencilRenderable ds => Window os c ds -> Int -> Render os ()

-- | Fill the window's back depth and stencil buffers with a constant depth
--   value (in the range [0,1]) and a constant stencil value
clearWindowDepthStencil :: Window os c DepthStencil -> Float -> Int -> Render os ()

-- | Fill a color image with a constant color value
clearImageColor :: forall c os. ColorRenderable c => Image (Format c) -> Color c (ColorElement c) -> Render os ()

-- | Fill a depth image with a constant depth value (in the range [0,1])
clearImageDepth :: DepthRenderable d => Image (Format d) -> Float -> Render os ()

-- | Fill a depth image with a constant stencil value
clearImageStencil :: StencilRenderable s => Image (Format s) -> Int -> Render os ()

-- | Fill a combined depth stencil image with a constant depth value (in
--   the range [0,1]) and a constant stencil value
clearImageDepthStencil :: Image (Format DepthStencil) -> Float -> Int -> Render os ()
type FragColor c = Color c (S F (ColorElement c))
data ContextColorOption f
ContextColorOption :: Blending -> (ColorMask f) -> ContextColorOption f

-- | <a>True</a> for each color component that should be written to the
--   target.
type ColorMask f = Color f Bool

-- | Indicates whether this color draw should use the <a>Blending</a>
--   setting given to the draw action. If this is <a>False</a>, the
--   fragment's color value will simply replace the target value.
type UseBlending = Bool

-- | Denotes how each fragment's color value should be blended with the
--   target value.
data Blending

-- | The fragment's color will simply replace the target value.
NoBlending :: Blending

-- | The fragment's color will be blended using an equation and a set of
--   factors for the RGB components, and a separate equation and set of
--   factors for the Alpha component (if present), and a
--   <a>ConstantColor</a> that may be referenced from the
--   <a>BlendingFactors</a>. The <a>ConstantColor</a> may be
--   <a>undefined</a> if none of the <a>BlendingFactors</a> needs it. This
--   kind of blending will only be made on colors with a <a>Float</a>
--   representation (e.g. <a>RGB8</a> or <a>RGB32F</a>, but not
--   <a>RGB8I</a>), integer colors will simply replace the target value.
BlendRgbAlpha :: (BlendEquation, BlendEquation) -> (BlendingFactors, BlendingFactors) -> ConstantColor -> Blending

-- | A logical operation that will be done on the bits of the fragment
--   color and the target color. This kind of blending is only done on
--   colors that has a integral <i>internal</i> representation (e.g.
--   <a>RGB8</a> or <a>RGB8I</a>, but not <a>RGB32F</a>; note the
--   difference with <tt>BlendRgbAlpha</tt> restriction). For targets with
--   an internal floating point representation, the fragment value will
--   simply replace the target value.
LogicOp :: LogicOp -> Blending
type ConstantColor = V4 Float

-- | A set of blending factors used for the source (fragment) and the
--   destination (target).
data BlendingFactors
BlendingFactors :: BlendingFactor -> BlendingFactor -> BlendingFactors
[blendFactorSrc] :: BlendingFactors -> BlendingFactor
[blendFactorDst] :: BlendingFactors -> BlendingFactor

-- | The equation used to combine the source (fragment) and the destination
--   (target) after they have been multiplied with their respective
--   <a>BlendingFactor</a>s.
data BlendEquation
FuncAdd :: BlendEquation
FuncSubtract :: BlendEquation
FuncReverseSubtract :: BlendEquation
Min :: BlendEquation
Max :: BlendEquation

-- | A factor that the source (fragment) or the destination (target) will
--   be multiplied with before combined with the other in the
--   <a>BlendEquation</a>.
data BlendingFactor
Zero :: BlendingFactor
One :: BlendingFactor
SrcColor :: BlendingFactor
OneMinusSrcColor :: BlendingFactor
DstColor :: BlendingFactor
OneMinusDstColor :: BlendingFactor
SrcAlpha :: BlendingFactor
OneMinusSrcAlpha :: BlendingFactor
DstAlpha :: BlendingFactor
OneMinusDstAlpha :: BlendingFactor
ConstantColor :: BlendingFactor
OneMinusConstantColor :: BlendingFactor
ConstantAlpha :: BlendingFactor
OneMinusConstantAlpha :: BlendingFactor
SrcAlphaSaturate :: BlendingFactor

-- | A bitwise logical operation that will be used to combine colors that
--   has an integral internal representation.
data LogicOp
Clear :: LogicOp
And :: LogicOp
AndReverse :: LogicOp
Copy :: LogicOp
AndInverted :: LogicOp
Noop :: LogicOp
Xor :: LogicOp
Or :: LogicOp
Nor :: LogicOp
Equiv :: LogicOp
Invert :: LogicOp
OrReverse :: LogicOp
CopyInverted :: LogicOp
OrInverted :: LogicOp
Nand :: LogicOp
Set :: LogicOp
type FragDepth = FFloat
data DepthOption
DepthOption :: DepthFunction -> DepthMask -> DepthOption

-- | <a>True</a> if the depth component should be written to the target.
type DepthMask = Bool

-- | The function used to compare the fragment's depth and the depth
--   buffers depth with. E.g. <a>Less</a> means "where fragment's depth is
--   less than the buffers current depth".
type DepthFunction = ComparisonFunction
type StencilOptions = FrontBack StencilOption
data StencilOption
StencilOption :: ComparisonFunction -> Int -> StencilOp -> StencilOp -> Word -> Word -> StencilOption
[stencilTest] :: StencilOption -> ComparisonFunction
[stencilReference] :: StencilOption -> Int
[opWhenStencilFail] :: StencilOption -> StencilOp
[opWhenStencilPass] :: StencilOption -> StencilOp
[stencilReadBitMask] :: StencilOption -> Word
[stencilWriteBitMask] :: StencilOption -> Word
data DepthStencilOption
DepthStencilOption :: StencilOptions -> DepthOption -> FrontBack StencilOp -> DepthStencilOption
[dsStencilOptions] :: DepthStencilOption -> StencilOptions
[dsDepthOption] :: DepthStencilOption -> DepthOption
[opWhenStencilPassButDepthFail] :: DepthStencilOption -> FrontBack StencilOp
data FrontBack a
FrontBack :: a -> a -> FrontBack a
[front] :: FrontBack a -> a
[back] :: FrontBack a -> a

-- | Denotes the operation that will be performed on the target's stencil
--   value
data StencilOp
OpZero :: StencilOp
OpKeep :: StencilOp
OpReplace :: StencilOp
OpIncr :: StencilOp
OpIncrWrap :: StencilOp
OpDecr :: StencilOp
OpDecrWrap :: StencilOp
OpInvert :: StencilOp


-- | A <a>PrimitiveStream</a> can be rasterized, i.e. chopped up in pixel
--   sized fragments, each of which contains an interpolated value of the
--   primitives vertices, producing a <a>FragmentStream</a>.
module Graphics.GPipe.FragmentStream

-- | A <tt><a>FragmentStream</a> a </tt> is a stream of fragments of type
--   <tt>a</tt>. You may append <a>FragmentStream</a>s using the
--   <a>Monoid</a> instance, and you can operate a stream's values using
--   the <a>Functor</a> instance (this will result in a shader running on
--   the GPU).
data FragmentStream a

-- | This class constraints which vertex types can be turned into fragment
--   values, and what type those values have.
class FragmentInput a where {
    type family FragmentFormat a;
}

-- | An arrow action that turns a value from it's vertex representation to
--   it's fragment representation. Use <a>toFragment</a> from the GPipe
--   provided instances to operate in this arrow. Also note that this arrow
--   needs to be able to return a value lazily, so ensure you use
--   
--   <tt>proc ~pattern -&gt; do ...</tt>.
toFragment :: FragmentInput a => ToFragment a (FragmentFormat a)

-- | The arrow type for <a>toFragment</a>.
data ToFragment a b

-- | A float value that is not interpolated (like integers), and all
--   fragments will instead get the value of the primitive's last vertex
data FlatVFloat
Flat :: VFloat -> FlatVFloat

-- | A float value that doesn't get divided by the interpolated position's
--   w-component during interpolation.
data NoPerspectiveVFloat
NoPerspective :: VFloat -> NoPerspectiveVFloat

-- | Rasterize a stream of primitives into fragments, using a <a>Side</a>,
--   <tt>Viewport</tt> and <a>DepthRange</a> from the shader environment.
--   Primitives will be transformed from canonical view space, i.e.
--   [(-1,-1,-1),(1,1,1)], to the 2D space defined by the <a>ViewPort</a>
--   parameter and the depth range defined by the <a>DepthRange</a>
--   parameter.
rasterize :: forall p a s os f. FragmentInput a => (s -> (Side, ViewPort, DepthRange)) -> PrimitiveStream p (VPos, a) -> Shader os s (FragmentStream (FragmentFormat a))
type VPos = V4 VFloat

-- | Defines which side to rasterize. Non triangle primitives only has a
--   front side.
data Side
Front :: Side
Back :: Side
FrontAndBack :: Side

-- | The viewport in pixel coordinates (where (0,0) is the lower left
--   corner) in to which the canonical view volume [(-1,-1,-1),(1,1,1)] is
--   transformed and clipped/scissored.
data ViewPort
ViewPort :: V2 Int -> V2 Int -> ViewPort
[viewPortLowerLeft] :: ViewPort -> V2 Int
[viewPortSize] :: ViewPort -> V2 Int

-- | The fragment depth range to map the canonical view volume's
--   z-coordinate to. Depth values are clamped to [0,1], so <tt>DepthRange
--   0 1</tt> gives maximum depth resolution.
data DepthRange
DepthRange :: Float -> Float -> DepthRange
[minDepth] :: DepthRange -> Float
[maxDepth] :: DepthRange -> Float

-- | Filter out fragments from the stream where the predicate in the first
--   argument evaluates to <a>true</a>, and discard all other fragments.
filterFragments :: (a -> FBool) -> FragmentStream a -> FragmentStream a

-- | Like <a>fmap</a>, but where various auto generated information from
--   the rasterization is provided for each vertex.
withRasterizedInfo :: (a -> RasterizedInfo -> b) -> FragmentStream a -> FragmentStream b
data RasterizedInfo
RasterizedInfo :: V4 FFloat -> FBool -> V2 FFloat -> RasterizedInfo
[rasterizedFragCoord] :: RasterizedInfo -> V4 FFloat
[rasterizedFrontFacing] :: RasterizedInfo -> FBool
[rasterizedPointCoord] :: RasterizedInfo -> V2 FFloat


-- | Orphan boolean instances for linear types. These are placed in a
--   separate module so you can choose to not import them (in that case, do
--   not import the <tt>Graphics.GPipe</tt> conveniance module but take all
--   sub modules instead, leaving this one out).
module Graphics.GPipe.Orphans


-- | PrimitiveArrays (aka VAOs in OpenGl) are the main input to compiled
--   shaders. A primitive array is created from one or more zipped vertex
--   arrays. A primitive array may also be instanced, using one or more
--   zipped vertex arrays as instance arrays. And lastly, an index array
--   may also be used to pick vertices for the primitive array.
--   
--   Any possible combination of interleaved or non-interleaved vertex
--   buffers may be used, for example:
--   
--   Buffer <tt>a</tt> = <tt>{(A,B),(A,B),(A,B)...}</tt> Buffer <tt>b</tt>
--   = <tt>{(X,Y,Z),(X,Y,Z),(X,Y,Z),...}</tt>
--   
--   <pre>
--   do
--      aArr &lt;- newVertexArray a        
--      bArr &lt;- newVertexArray b 
--      let primArr = toPrimitiveArray TriangleList (zipVertices ((a,b) y -&gt; (a,b,y)) aArr (fmap ((_,y,_) -&gt; y) bArr))
--   
--   </pre>
--   
--   will create a primitive array <tt>primArr</tt> with this layout:
--   <tt>{(A,B,Y),(A,B,Y),(A,B,Y)...}</tt>
module Graphics.GPipe.PrimitiveArray

-- | A vertex array is the basic building block for a primitive array. It
--   is created from the contents of a <a>Buffer</a>, but unlike a
--   <a>Buffer</a>, it may be truncated, zipped with other vertex arrays,
--   and even morphed into arrays of a different type with the provided
--   <a>Functor</a> instance. A <tt>VertexArray t a</tt> has elements of
--   type <tt>a</tt>, and <tt>t</tt> indicates whether the vertex array may
--   be used as instances or not.
data VertexArray t a

-- | A phantom type to indicate that a <a>VertexArray</a> may only be used
--   for instances (in <a>toPrimitiveArrayInstanced</a> and
--   <a>toPrimitiveArrayIndexedInstanced</a>).
data Instances

-- | Create a <a>VertexArray</a> from a <a>Buffer</a>. The vertex array
--   will have the same number of elements as the buffer, use
--   <a>takeVertices</a> and <a>dropVertices</a> to make it smaller.
newVertexArray :: Buffer os a -> Render os (VertexArray t a)

-- | Retrieve the number of elements in a <a>VertexArray</a>.
vertexArrayLength :: VertexArray t a -> Int

-- | Zip two <a>VertexArray</a>s using the function given as first
--   argument. If either of the argument <a>VertexArray</a>s are restriced
--   to <a>Instances</a> only, then so will the resulting array be, as
--   depicted by the <a>Combine</a> type family.
zipVertices :: (a -> b -> c) -> VertexArray t a -> VertexArray t' b -> VertexArray (Combine t t') c

-- | <tt>takeVertices n a</tt> creates a shorter vertex array by taking the
--   <tt>n</tt> first elements of the array <tt>a</tt>.
takeVertices :: Int -> VertexArray t a -> VertexArray t a

-- | <tt>dropVertices n a</tt> creates a shorter vertex array by dropping
--   the <tt>n</tt> first elements of the array <tt>a</tt>. The argument
--   array <tt>a</tt> must not be constrained to only <a>Instances</a>.
dropVertices :: Int -> VertexArray () a -> VertexArray t a

-- | <tt>replicateEach n a</tt> will create a longer vertex array, only to
--   be used for instances, by replicating each element of the array
--   <tt>a</tt> <tt>n</tt> times. E.g. <tt>replicateEach 3 {ABCD...}</tt>
--   will yield <tt>{AAABBBCCCDDD...}</tt>. This is particulary useful
--   before zipping the array with another that has a different replication
--   rate.
replicateEach :: Int -> VertexArray t a -> VertexArray Instances a

-- | An index array is like a vertex array, but contains only integer
--   indices. These indices must come from a tightly packed <a>Buffer</a>,
--   hence the lack of a <a>Functor</a> instance and no conversion from
--   <a>VertexArray</a>s.
data IndexArray

-- | Create an <a>IndexArray</a> from a <a>Buffer</a> of unsigned integers
--   (as constrained by the closed <a>IndexFormat</a> type family
--   instances). The index array will have the same number of elements as
--   the buffer, use <a>takeIndices</a> and <a>dropIndices</a> to make it
--   smaller. The <tt>Maybe a</tt> argument is used to optionally denote a
--   primitive restart index.
newIndexArray :: forall os f b a. (BufferFormat b, Integral a, IndexFormat b ~ a) => Buffer os b -> Maybe a -> Render os IndexArray

-- | Numer of indices in an <a>IndexArray</a>.
indexArrayLength :: IndexArray -> Int

-- | <tt>takeIndices n a</tt> creates a shorter index array by taking the
--   <tt>n</tt> first indices of the array <tt>a</tt>.
takeIndices :: Int -> IndexArray -> IndexArray

-- | <tt>dropIndices n a</tt> creates a shorter index array by dropping the
--   <tt>n</tt> first indices of the array <tt>a</tt>.
dropIndices :: Int -> IndexArray -> IndexArray

-- | An array of primitives
data PrimitiveArray p a
data PrimitiveTopology p
[TriangleList] :: PrimitiveTopology Triangles
[TriangleStrip] :: PrimitiveTopology Triangles
[TriangleFan] :: PrimitiveTopology Triangles
[LineList] :: PrimitiveTopology Lines
[LineStrip] :: PrimitiveTopology Lines
[LineLoop] :: PrimitiveTopology Lines
[PointList] :: PrimitiveTopology Points
data Triangles
data Lines
data Points
toPrimitiveArray :: PrimitiveTopology p -> VertexArray () a -> PrimitiveArray p a
toPrimitiveArrayIndexed :: PrimitiveTopology p -> IndexArray -> VertexArray () a -> PrimitiveArray p a
toPrimitiveArrayInstanced :: PrimitiveTopology p -> (a -> b -> c) -> VertexArray () a -> VertexArray t b -> PrimitiveArray p c
toPrimitiveArrayIndexedInstanced :: PrimitiveTopology p -> IndexArray -> (a -> b -> c) -> VertexArray () a -> VertexArray t b -> PrimitiveArray p c

-- | Split up a <tt><a>B4</a> a</tt> into two <tt><a>B2</a> a</tt>s.
toB22 :: forall a. (Storable a, BufferFormat (B2 a)) => B4 a -> (B2 a, B2 a)

-- | Discard the last component of a <tt><a>B4</a> a</tt> to get a
--   <tt><a>B3</a> a</tt>.
toB3 :: forall a. (Storable a, BufferFormat (B3 a)) => B4 a -> B3 a

-- | Split up a <tt><a>B3</a> a</tt> into a <tt><a>B2</a> a</tt> and a
--   <tt><tt>B1</tt> a</tt>.
toB21 :: forall a. (Storable a, BufferFormat (B a)) => B3 a -> (B2 a, B a)

-- | Split up a <tt><a>B3</a> a</tt> into a <tt><tt>B1</tt> a</tt> and a
--   <tt><a>B2</a> a</tt>.
toB12 :: forall a. (Storable a, BufferFormat (B a)) => B3 a -> (B a, B2 a)

-- | Split up a <tt><a>B2</a> a</tt> into two <tt><tt>B1</tt> a</tt>s.
toB11 :: forall a. (Storable a, BufferFormat (B a)) => B2 a -> (B a, B a)


-- | A <a>PrimitiveArray</a> can be turned into a <a>PrimitiveStream</a> in
--   a <a>Shader</a>, in order to operate on the vertices of it and
--   ultimately rasterize it into a <a>FragmentStream</a>.
module Graphics.GPipe.PrimitiveStream

-- | A <tt><a>PrimitiveStream</a> t a </tt> is a stream of primitives of
--   type <tt>t</tt> where the vertices are values of type <tt>a</tt>. You
--   can operate a stream's vertex values using the <a>Functor</a> instance
--   (this will result in a shader running on the GPU). You may also append
--   <a>PrimitiveStream</a>s using the <a>Monoid</a> instance, but if
--   possible append the origin <a>PrimitiveArray</a>s instead, as this
--   will create more optimized draw calls.
data PrimitiveStream t a

-- | This class constraints which buffer types can be turned into vertex
--   values, and what type those values have.
class VertexInput a where {
    type family VertexFormat a;
}

-- | An arrow action that turns a value from it's buffer representation to
--   it's vertex representation. Use <a>toVertex</a> from the GPipe
--   provided instances to operate in this arrow. Also note that this arrow
--   needs to be able to return a value lazily, so ensure you use
--   
--   <tt>proc ~pattern -&gt; do ...</tt>.
toVertex :: VertexInput a => ToVertex a (VertexFormat a)

-- | The arrow type for <a>toVertex</a>.
data ToVertex a b

-- | Create a primitive stream from a primitive array provided from the
--   shader environment.
toPrimitiveStream :: forall os f s a p. VertexInput a => (s -> PrimitiveArray p a) -> Shader os s (PrimitiveStream p (VertexFormat a))

-- | Like <a>fmap</a>, but where the vertex and instance IDs are provided
--   as arguments as well.
withInputIndices :: (a -> InputIndices -> b) -> PrimitiveStream p a -> PrimitiveStream p b
data InputIndices
InputIndices :: VInt -> VInt -> InputIndices
[inputVertexID] :: InputIndices -> VInt
[inputInstanceID] :: InputIndices -> VInt

-- | Like <a>fmap</a>, but where each point's size is provided as arguments
--   as well, and a new point size is set for each point in addition to the
--   new vertex value.
--   
--   When a <a>PrimitiveStream</a> of <a>Points</a> is created, all points
--   will have the default size of 1.
withPointSize :: (a -> PointSize -> (b, PointSize)) -> PrimitiveStream Points a -> PrimitiveStream Points b
type PointSize = VFloat


-- | A sampler is a value from which filtered color samples may be taken
--   inside a shader. A sampler is created from a texture and some sampling
--   parameters. There also exist <a>Shadow</a> samplers that doesnt return
--   a sampled color value, but instead compare a reference value to the
--   texture value.
module Graphics.GPipe.Sampler
data Sampler1D f
data Sampler1DArray f
data Sampler2D f
data Sampler2DArray f
data Sampler3D f
data SamplerCube f

-- | Used instead of <a>Format</a> for shadow samplers. These samplers have
--   specialized sampler values, see <a>sample1DShadow</a> and friends.
data Shadow
newSampler1D :: forall os s c. ColorSampleable c => (s -> (Texture1D os (Format c), SamplerFilter c, (EdgeMode, BorderColor c))) -> Shader os s (Sampler1D (Format c))
newSampler1DArray :: forall os s c. ColorSampleable c => (s -> (Texture1DArray os (Format c), SamplerFilter c, (EdgeMode, BorderColor c))) -> Shader os s (Sampler1DArray (Format c))
newSampler2D :: forall os s c. ColorSampleable c => (s -> (Texture2D os (Format c), SamplerFilter c, (EdgeMode2, BorderColor c))) -> Shader os s (Sampler2D (Format c))
newSampler2DArray :: forall os s c. ColorSampleable c => (s -> (Texture2DArray os (Format c), SamplerFilter c, (EdgeMode2, BorderColor c))) -> Shader os s (Sampler2DArray (Format c))
newSampler3D :: forall os s c. ColorRenderable c => (s -> (Texture3D os (Format c), SamplerFilter c, (EdgeMode3, BorderColor c))) -> Shader os s (Sampler3D (Format c))
newSamplerCube :: forall os s c. ColorSampleable c => (s -> (TextureCube os (Format c), SamplerFilter c)) -> Shader os s (SamplerCube (Format c))
newSampler1DShadow :: forall os s d. DepthRenderable d => (s -> (Texture1D os (Format d), SamplerFilter d, (EdgeMode, BorderColor d), ComparisonFunction)) -> Shader os s (Sampler1D Shadow)
newSampler1DArrayShadow :: forall os s d. DepthRenderable d => (s -> (Texture1DArray os (Format d), SamplerFilter d, (EdgeMode, BorderColor d), ComparisonFunction)) -> Shader os s (Sampler1DArray Shadow)
newSampler2DShadow :: forall os s d. DepthRenderable d => (s -> (Texture2D os d, SamplerFilter (Format d), (EdgeMode2, BorderColor d), ComparisonFunction)) -> Shader os s (Sampler2D Shadow)
newSampler2DArrayShadow :: forall os s d. DepthRenderable d => (s -> (Texture2DArray os (Format d), SamplerFilter d, (EdgeMode2, BorderColor d), ComparisonFunction)) -> Shader os s (Sampler2DArray Shadow)
newSamplerCubeShadow :: forall os s d. DepthRenderable d => (s -> (TextureCube os (Format d), SamplerFilter d, ComparisonFunction)) -> Shader os s (SamplerCube Shadow)
data Filter
Nearest :: Filter
Linear :: Filter
data EdgeMode
Repeat :: EdgeMode
Mirror :: EdgeMode
ClampToEdge :: EdgeMode
ClampToBorder :: EdgeMode
type EdgeMode2 = V2 EdgeMode
type EdgeMode3 = V3 EdgeMode
type BorderColor c = Color c (ColorElement c)
type Anisotropy = Maybe Float
type MinFilter = Filter
type MagFilter = Filter
type LodFilter = Filter

-- | A GADT for sample filters, where <a>SamplerFilter</a> cannot be used
--   for integer textures.
data SamplerFilter c
[SamplerFilter] :: (ColorElement c ~ Float) => MagFilter -> MinFilter -> LodFilter -> Anisotropy -> SamplerFilter c
[SamplerNearest] :: SamplerFilter c
data ComparisonFunction
Never :: ComparisonFunction
Less :: ComparisonFunction
Equal :: ComparisonFunction
Lequal :: ComparisonFunction
Greater :: ComparisonFunction
Notequal :: ComparisonFunction
Gequal :: ComparisonFunction
Always :: ComparisonFunction
sampler1DSize :: Sampler1D f -> S x Level -> S x Int
sampler1DArraySize :: Sampler1DArray f -> S x Level -> V2 (S x Int)
sampler2DSize :: Sampler2D f -> S x Level -> V2 (S x Int)
sampler2DArraySize :: Sampler2DArray f -> S x Level -> V3 (S x Int)
sampler3DSize :: Sampler3D f -> S x Level -> V3 (S x Int)
samplerCubeSize :: SamplerCube f -> S x Level -> S x Int
sample1D :: forall c x. ColorSampleable c => Sampler1D (Format c) -> SampleLod1 x -> SampleProj x -> SampleOffset1 x -> S x Float -> ColorSample x c
sample1DArray :: forall c x. ColorSampleable c => Sampler1DArray (Format c) -> SampleLod1 x -> SampleOffset1 x -> V2 (S x Float) -> ColorSample x c
sample2D :: forall c x. ColorSampleable c => Sampler2D (Format c) -> SampleLod2 x -> SampleProj x -> SampleOffset2 x -> V2 (S x Float) -> ColorSample x c
sample2DArray :: forall c x. ColorSampleable c => Sampler2DArray (Format c) -> SampleLod2 x -> SampleOffset2 x -> V3 (S x Float) -> ColorSample x c
sample3D :: forall c x. ColorSampleable c => Sampler3D (Format c) -> SampleLod3 x -> SampleProj x -> SampleOffset3 x -> V3 (S x Float) -> ColorSample x c
sampleCube :: forall c x. ColorSampleable c => SamplerCube (Format c) -> SampleLod3 x -> V3 (S x Float) -> ColorSample x c
sample1DShadow :: forall x. Sampler1D Shadow -> SampleLod1 x -> SampleProj x -> SampleOffset1 x -> ReferenceValue x -> S x Float -> S x Float
sample1DArrayShadow :: forall x. Sampler1DArray Shadow -> SampleLod1 x -> SampleOffset1 x -> ReferenceValue x -> V2 (S x Float) -> S x Float
sample2DShadow :: forall x. Sampler2D Shadow -> SampleLod2 x -> SampleProj x -> SampleOffset2 x -> ReferenceValue x -> V2 (S x Float) -> S x Float
sample2DArrayShadow :: forall x. Sampler2DArray Shadow -> SampleLod2' x -> SampleOffset2 x -> ReferenceValue x -> V3 (S x Float) -> S x Float
sampleCubeShadow :: forall x. SamplerCube Shadow -> SampleLod3' x -> ReferenceValue x -> V3 (S x Float) -> S x Float
texelFetch1D :: forall c x. ColorSampleable c => Sampler1D (Format c) -> SampleOffset1 x -> S x Level -> S x Int -> ColorSample x c
texelFetch1DArray :: forall c x. ColorSampleable c => Sampler1DArray (Format c) -> SampleOffset1 x -> S x Level -> V2 (S x Int) -> ColorSample x c
texelFetch2D :: forall c x. ColorSampleable c => Sampler2D (Format c) -> SampleOffset2 x -> S x Level -> V2 (S x Int) -> ColorSample x c
texelFetch2DArray :: forall c x. ColorSampleable c => Sampler2DArray (Format c) -> SampleOffset2 x -> S x Level -> V3 (S x Int) -> ColorSample x c
texelFetch3D :: forall c x. ColorSampleable c => Sampler3D (Format c) -> SampleOffset3 x -> S x Level -> V3 (S x Int) -> ColorSample x c

-- | A GADT to specify where the level of detail and/or partial derivates
--   should be taken from. Some values of this GADT are restricted to only
--   <tt>FragmentStream</tt>s.
data SampleLod vx x
[SampleAuto] :: SampleLod v F
[SampleBias] :: FFloat -> SampleLod vx F
[SampleLod] :: S x Float -> SampleLod vx x
[SampleGrad] :: vx -> vx -> SampleLod vx x
type SampleLod1 x = SampleLod (S x Float) x
type SampleLod2 x = SampleLod (V2 (S x Float)) x
type SampleLod3 x = SampleLod (V3 (S x Float)) x

-- | For some reason, OpenGl doesnt allow explicit lod to be specified for
--   some sampler types, hence this extra GADT.
data SampleLod' vx x
[SampleAuto'] :: SampleLod' v F
[SampleBias'] :: FFloat -> SampleLod' vx F
[SampleGrad'] :: vx -> vx -> SampleLod' vx x
type SampleLod2' x = SampleLod' (V2 (S x Float)) x
type SampleLod3' x = SampleLod' (V3 (S x Float)) x
fromLod' :: SampleLod' v x -> SampleLod v x
type SampleProj x = Maybe (S x Float)
type SampleOffset1 x = Maybe Int
type SampleOffset2 x = Maybe (V2 Int)
type SampleOffset3 x = Maybe (V3 Int)
type ReferenceValue x = S x Float

-- | The type of a color sample made by a texture t
type ColorSample x f = Color f (S x (ColorElement f))


-- | A <a>Shader</a> is a monad in which <tt>PrimitiveStream</tt>s and
--   <tt>FragmentStream</tt>s live, together with samplers and uniform
--   values. Any computations made on the streams and values in the
--   <a>Shader</a> monad will be performed on the GPU. A <a>Shader</a>
--   needs to be compiled before it can be used. In order to make it work
--   over different environments after it has been compiled, it closes over
--   an environment value just like a <tt>Reader</tt> monad, with the
--   distinction that there is no <tt>ask</tt> action, since we cannot make
--   the actual monad operation depend on the environment.
--   
--   A <a>Shader</a> is an instance of <tt>Alternative</tt> and
--   <tt>MonadPlus</tt> which makes it possible to express choice with
--   functions like <tt>guard</tt>. The left most alternative will always
--   be the resulting monad.
module Graphics.GPipe.Shader

-- | The monad in which all GPU computations are done. 'Shader os s a'
--   lives in an object space <tt>os</tt> and a context with format
--   <tt>f</tt>, closing over an environent of type <tt>s</tt>.
data Shader os s a

-- | Compiles a shader into a <a>CompiledShader</a>. This action will
--   usually take a second or more, so put it during a loading sequence or
--   something.
--   
--   May throw a <a>GPipeException</a> if the graphics driver doesn't
--   support something in this shader (e.g. too many interpolated floats
--   sent between a vertex and a fragment shader)
compileShader :: (ContextHandler ctx, MonadIO m, MonadException m) => Shader os x () -> ContextT ctx os m (CompiledShader os x)

-- | A compiled shader is just a function that takes an environment and
--   returns a <a>Render</a> action
type CompiledShader os s = s -> Render os ()

-- | A monad in which shaders are run.
data Render os a

-- | Run a <a>Render</a> monad, that may have the effect of windows or
--   textures being drawn to.
--   
--   May throw a <a>GPipeException</a> if a combination of draw images
--   (FBO) used by this render call is unsupported by the graphics driver
render :: (ContextHandler ctx, MonadIO m, MonadException m) => Render os () -> ContextT ctx os m ()

-- | Like <tt>guard</tt>, but dependent on the <tt>Shaders</tt> environment
--   value. Since this will be evaluated at shader run time, as opposed to
--   shader compile time for <tt>guard</tt>, using this to do recursion
--   will make <a>compileShader</a> diverge. You can break that divergence
--   by combining it with a normal <tt>guard</tt> and a maximum loop count.
guard' :: (s -> Bool) -> Shader os s ()

-- | Map the environment to a different environment and run a Shader in
--   that sub environment, returning it's result.
mapShader :: (s -> s') -> Shader os s' a -> Shader os s a

-- | Conditionally run the effects of a shader when a <a>Maybe</a> value is
--   <a>Just</a> something.
maybeShader :: (s -> Maybe s') -> Shader os s' () -> Shader os s ()

-- | Select one of two <a>Shader</a> actions based on whether an
--   <a>Either</a> value is <a>Left</a> or <a>Right</a>.
chooseShader :: (s -> Either s' s'') -> Shader os s' a -> Shader os s'' a -> Shader os s a

-- | Discard all effects of a <a>Shader</a> action (i.e., dont draw
--   anything) and just return the resulting value.
silenceShader :: Shader os s a -> Shader os s a


-- | A texture is a spatially arranged map of pixels that resides on the
--   GPU. A texture can be a 1D, 2D or 3D image, or an array of several
--   same sized 1D or 2D images, or a cube map with six square images. A
--   texture may also have several levels of detail, in decreasing size.
--   
--   A texture has a strongly typed format and immutable size and number of
--   levels, but its content is mutable. A texture lives in an object space
--   and may be shared between contexts.
--   
--   The main purpose for a texture is to be sampled in a <tt>Shader</tt>,
--   by turning it into a sampler object (See <a>Sampler1D</a> and
--   friends). A texture may also be used as a render target into which
--   <a>FragmentStream</a>s are drawn, thus generating the texture on the
--   GPU. To that end, a texture may not only be written from the host
--   (i.e. the normal Haskell world) but also read back.
module Graphics.GPipe.Texture
data Texture1D os a
data Texture1DArray os a
data Texture2D os a
data Texture2DArray os a
data Texture3D os a
data TextureCube os a
data CubeSide
CubePosX :: CubeSide
CubeNegX :: CubeSide
CubePosY :: CubeSide
CubeNegY :: CubeSide
CubePosZ :: CubeSide
CubeNegZ :: CubeSide
newTexture1D :: forall ctx w os f c m. (ContextHandler ctx, ColorSampleable c, MonadIO m) => Format c -> Size1 -> MaxLevels -> ContextT ctx os m (Texture1D os (Format c))
newTexture1DArray :: forall ctx w os f c m. (ContextHandler ctx, ColorSampleable c, MonadIO m) => Format c -> Size2 -> MaxLevels -> ContextT ctx os m (Texture1DArray os (Format c))
newTexture2D :: forall ctx w os f c m. (ContextHandler ctx, TextureFormat c, MonadIO m) => Format c -> Size2 -> MaxLevels -> ContextT ctx os m (Texture2D os (Format c))
newTexture2DArray :: forall ctx w os f c m. (ContextHandler ctx, ColorSampleable c, MonadIO m) => Format c -> Size3 -> MaxLevels -> ContextT ctx os m (Texture2DArray os (Format c))
newTexture3D :: forall ctx w os f c m. (ContextHandler ctx, ColorRenderable c, MonadIO m) => Format c -> Size3 -> MaxLevels -> ContextT ctx os m (Texture3D os (Format c))
newTextureCube :: forall ctx w os f c m. (ContextHandler ctx, ColorSampleable c, MonadIO m) => Format c -> Size1 -> MaxLevels -> ContextT ctx os m (TextureCube os (Format c))
texture1DLevels :: Texture1D os f -> Int
texture1DArrayLevels :: Texture1DArray os f -> Int
texture2DLevels :: Texture2D os f -> Int
texture2DArrayLevels :: Texture2DArray os f -> Int
texture3DLevels :: Texture3D os f -> Int
textureCubeLevels :: TextureCube os f -> Int
texture1DSizes :: Texture1D os f -> [Size1]
texture1DArraySizes :: Texture1DArray os f -> [Size2]
texture2DSizes :: Texture2D os f -> [Size2]
texture2DArraySizes :: Texture2DArray os f -> [Size3]
texture3DSizes :: Texture3D os f -> [Size3]
textureCubeSizes :: TextureCube os f -> [Size1]
writeTexture1D :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture1D os (Format c) -> Level -> StartPos1 -> Size1 -> [h] -> ContextT ctx os m ()
writeTexture1DArray :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture1DArray os (Format c) -> Level -> StartPos2 -> Size2 -> [h] -> ContextT ctx os m ()
writeTexture2D :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture2D os (Format c) -> Level -> StartPos2 -> Size2 -> [h] -> ContextT ctx os m ()
writeTexture2DArray :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture2DArray os (Format c) -> Level -> StartPos3 -> Size3 -> [h] -> ContextT ctx os m ()
writeTexture3D :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture3D os (Format c) -> Level -> StartPos3 -> Size3 -> [h] -> ContextT ctx os m ()
writeTextureCube :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => TextureCube os (Format c) -> Level -> CubeSide -> StartPos2 -> Size2 -> [h] -> ContextT ctx os m ()
writeTexture1DFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture1D os (Format c) -> Level -> StartPos1 -> Size1 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
writeTexture1DArrayFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture1DArray os (Format c) -> Level -> StartPos2 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
writeTexture2DFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture2D os (Format c) -> Level -> StartPos2 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
writeTexture2DArrayFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture2DArray os (Format c) -> Level -> StartPos3 -> Size3 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
writeTexture3DFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture3D os (Format c) -> Level -> StartPos3 -> Size3 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
writeTextureCubeFromBuffer :: forall ctx b c h w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => TextureCube os (Format c) -> Level -> CubeSide -> StartPos2 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
generateTexture1DMipmap :: (ContextHandler ctx, MonadIO m) => Texture1D os f -> ContextT ctx os m ()
generateTexture1DArrayMipmap :: (ContextHandler ctx, MonadIO m) => Texture1DArray os f -> ContextT ctx os m ()
generateTexture2DMipmap :: (ContextHandler ctx, MonadIO m) => Texture2D os f -> ContextT ctx os m ()
generateTexture2DArrayMipmap :: (ContextHandler ctx, MonadIO m) => Texture2DArray os f -> ContextT ctx os m ()
generateTexture3DMipmap :: (ContextHandler ctx, MonadIO m) => Texture3D os f -> ContextT ctx os m ()
generateTextureCubeMipmap :: (ContextHandler ctx, MonadIO m) => TextureCube os f -> ContextT ctx os m ()
readTexture1D :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture1D os (Format c) -> Level -> StartPos1 -> Size1 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTexture1DArray :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture1DArray os (Format c) -> Level -> StartPos2 -> Size1 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTexture2D :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture2D os (Format c) -> Level -> StartPos2 -> Size2 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTexture2DArray :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture2DArray os (Format c) -> Level -> StartPos3 -> Size2 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTexture3D :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => Texture3D os (Format c) -> Level -> StartPos3 -> Size2 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTextureCube :: forall ctx a b c h w os f m. (ContextHandler ctx, MonadAsyncException m, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) h ~ b, h ~ HostFormat b) => TextureCube os (Format c) -> Level -> CubeSide -> StartPos2 -> Size2 -> (a -> h -> ContextT ctx os m a) -> a -> ContextT ctx os m a
readTexture1DToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture1D os (Format c) -> Level -> StartPos1 -> Size1 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
readTexture1DArrayToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture1DArray os (Format c) -> Level -> StartPos2 -> Size1 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
readTexture2DToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture2D os (Format c) -> Level -> StartPos2 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
readTexture2DArrayToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture2DArray os (Format c) -> Level -> StartPos3 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
readTexture3DToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => Texture3D os (Format c) -> Level -> StartPos3 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
readTextureCubeToBuffer :: forall ctx b c w os f m. (ContextHandler ctx, MonadIO m, BufferFormat b, ColorSampleable c, BufferColor (Color c (ColorElement c)) (HostFormat b) ~ b) => TextureCube os (Format c) -> Level -> CubeSide -> StartPos2 -> Size2 -> Buffer os b -> BufferStartPos -> ContextT ctx os m ()
type MaxLevels = Int
type Level = Int
type Size1 = Int
type Size2 = V2 Int
type Size3 = V3 Int
type StartPos1 = Int
type StartPos2 = V2 Int
type StartPos3 = V3 Int


-- | Uniform values are constants that you can combine with all vertices or
--   fragments of a <tt>PrimitiveStream</tt> or <tt>FragmentStream</tt>.
--   They are loaded from a <a>Buffer</a> and OpenGl uniform blocks are
--   used under the hood.
module Graphics.GPipe.Uniform

-- | This class constraints which buffer types can be loaded as uniforms,
--   and what type those values have.
class BufferFormat a => UniformInput a where {
    type family UniformFormat a x;
}

-- | An arrow action that turns a value from it's buffer representation to
--   it's vertex or fragment representation. Use <a>toUniform</a> from the
--   GPipe provided instances to operate in this arrow. Also note that this
--   arrow needs to be able to return a value lazily, so ensure you use
--   
--   <tt>proc ~pattern -&gt; do ...</tt>.
toUniform :: UniformInput a => ToUniform x a (UniformFormat a x)

-- | The arrow type for <a>toUniform</a>.
data ToUniform x a b

-- | Load a uniform value from a <a>Buffer</a> into a <a>Shader</a>. The
--   argument function is used to retrieve the buffer and the index into
--   this buffer from the shader environment.
getUniform :: forall os f s b x. (UniformInput b) => (s -> (Buffer os (Uniform b), Int)) -> Shader os s (UniformFormat b x)

-- | Any buffer value that is going to be used as a uniform needs to be
--   wrapped in this newtype. This will cause is to be aligned properly for
--   uniform usage. It can still be used as input for vertex arrays, but
--   due to the uniform alignment it will probably be padded quite heavily
--   and thus wasteful.
newtype Uniform a
Uniform :: a -> Uniform a


-- | A typesafe API based on the conceptual model of OpenGl, but without
--   the imperative state machine. GPipe aims to be as close to raw OpenGl
--   performance as possible, without compromising type safety or
--   functional style. Includes an embedded domain specific language for
--   GLSL shaders which provides type safety even when crossing into that
--   domain. Uses the OpenGl 3.3 core profile under the hood.
--   
--   To learn GPipe, start with the <a>readme</a> at the <a>source
--   repository</a>. You could also go directly to <a>a working example</a>
--   or the tutorials: <a>Part 1</a>, <a>Part 2</a>, <a>Part 3</a>, <a>Part
--   4</a>, <a>Part 5</a>.
--   
--   This module reexports relevant GPipe modules and the external
--   <a>Linear</a> and <a>Data.Boolean</a> modules.
module Graphics.GPipe
