-- 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.2 -- | 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 Graphics.GPipe conveniance module but take all -- sub modules instead, leaving this one out). module Graphics.GPipe.Orphans -- | A Shader is a monad in which PrimitiveStreams and -- FragmentStreams live, together with samplers and uniform -- values. Any computations made on the streams and values in the -- Shader monad will be performed on the GPU. A Shader -- 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 Reader monad, with the -- distinction that there is no ask action, since we cannot make -- the actual monad operation depend on the environment. -- -- A Shader is an instance of Alternative and -- MonadPlus which makes it possible to express choice with -- functions like guard. 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 os and a context with format -- f, closing over an environent of type s. data Shader os s a -- | Compiles a shader into a CompiledShader. This action will -- usually take a second or more, so put it during a loading sequence or -- something. -- -- May throw a GPipeException 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 Render action type CompiledShader os s = s -> Render os () -- | A monad in which shaders are run. data Render os a -- | Run a Render monad, that may have the effect of windows or -- textures being drawn to. -- -- May throw a GPipeException 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 guard, but dependent on the Shaders environment -- value. Since this will be evaluated at shader run time, as opposed to -- shader compile time for guard, using this to do recursion -- will make compileShader diverge. You can break that divergence -- by combining it with a normal guard 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 Maybe value is -- Just something. maybeShader :: (s -> Maybe s') -> Shader os s' () -> Shader os s () -- | Select one of two Shader actions based on whether an -- Either value is Left or Right. chooseShader :: (s -> Either s' s'') -> Shader os s' a -> Shader os s'' a -> Shader os s a -- | Discard all effects of a Shader action (i.e., dont draw -- anything) and just return the resulting value. silenceShader :: Shader os s a -> Shader os s a -- | 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 a = {(A,B),(A,B),(A,B)...} Buffer b -- = {(X,Y,Z),(X,Y,Z),(X,Y,Z),...} -- --
--   do
--      aArr <- newVertexArray a        
--      bArr <- newVertexArray b 
--      let primArr = toPrimitiveArray TriangleList (zipVertices ((a,b) y -> (a,b,y)) aArr (fmap ((_,y,_) -> y) bArr))
--   
--   
-- -- will create a primitive array primArr with this layout: -- {(A,B,Y),(A,B,Y),(A,B,Y)...} module Graphics.GPipe.PrimitiveArray -- | A vertex array is the basic building block for a primitive array. It -- is created from the contents of a Buffer, but unlike a -- Buffer, it may be truncated, zipped with other vertex arrays, -- and even morphed into arrays of a different type with the provided -- Functor instance. A VertexArray t a has elements of -- type a, and t indicates whether the vertex array may -- be used as instances or not. data VertexArray t a -- | A phantom type to indicate that a VertexArray may only be used -- for instances (in toPrimitiveArrayInstanced and -- toPrimitiveArrayIndexedInstanced). data Instances -- | Create a VertexArray from a Buffer. The vertex array -- will have the same number of elements as the buffer, use -- takeVertices and dropVertices to make it smaller. newVertexArray :: Buffer os a -> Render os (VertexArray t a) -- | Retrieve the number of elements in a VertexArray. vertexArrayLength :: VertexArray t a -> Int -- | Zip two VertexArrays using the function given as first -- argument. If either of the argument VertexArrays are restriced -- to Instances only, then so will the resulting array be, as -- depicted by the Combine type family. zipVertices :: (a -> b -> c) -> VertexArray t a -> VertexArray t' b -> VertexArray (Combine t t') c -- | takeVertices n a creates a shorter vertex array by taking the -- n first elements of the array a. takeVertices :: Int -> VertexArray t a -> VertexArray t a -- | dropVertices n a creates a shorter vertex array by dropping -- the n first elements of the array a. The argument -- array a must not be constrained to only Instances. dropVertices :: Int -> VertexArray () a -> VertexArray t a -- | replicateEach n a will create a longer vertex array, only to -- be used for instances, by replicating each element of the array -- a n times. E.g. replicateEach 3 {ABCD...} -- will yield {AAABBBCCCDDD...}. 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 Buffer, -- hence the lack of a Functor instance and no conversion from -- VertexArrays. data IndexArray -- | Create an IndexArray from a Buffer of unsigned integers -- (as constrained by the closed IndexFormat type family -- instances). The index array will have the same number of elements as -- the buffer, use takeIndices and dropIndices to make it -- smaller. The Maybe a 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 IndexArray. indexArrayLength :: IndexArray -> Int -- | takeIndices n a creates a shorter index array by taking the -- n first indices of the array a. takeIndices :: Int -> IndexArray -> IndexArray -- | dropIndices n a creates a shorter index array by dropping the -- n first indices of the array a. 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 B4 a into two B2 as. toB22 :: forall a. (Storable a, BufferFormat (B2 a)) => B4 a -> (B2 a, B2 a) -- | Discard the last component of a B4 a to get a -- B3 a. toB3 :: forall a. (Storable a, BufferFormat (B3 a)) => B4 a -> B3 a -- | Split up a B3 a into a B2 a and a -- B1 a. toB21 :: forall a. (Storable a, BufferFormat (B a)) => B3 a -> (B2 a, B a) -- | Split up a B3 a into a B1 a and a -- B2 a. toB12 :: forall a. (Storable a, BufferFormat (B a)) => B3 a -> (B a, B2 a) -- | Split up a B2 a into two B1 as. toB11 :: forall a. (Storable a, BufferFormat (B a)) => B2 a -> (B a, B a) -- | 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 Format, 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 where getGlFormat = error "You cannot create your own instances of TextureFormat" 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 Color f a type ColorElement f :: * typeStr = error "You cannot create your own instances of ColorSampleable" typeStr4 = error "You cannot create your own instances of ColorSampleable" toColor = error "You cannot create your own instances of ColorSampleable" fromColor = error "You cannot create your own instances of ColorSampleable" setBorderColor = error "You cannot create your own instances of ColorSampleable" samplerPrefix _ = "" where { type family Color f a; type family ColorElement f :: *; } class ColorSampleable c => ColorRenderable c where isSrgb _ = False clearColor = error "You cannot create your own instances of ColorRenderable" 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 where redBits = error "You cannot create your own instances of ContextColorFormat" greenBits = error "You cannot create your own instances of ContextColorFormat" blueBits = error "You cannot create your own instances of ContextColorFormat" alphaBits = error "You cannot create your own instances of ContextColorFormat" windowBits :: WindowFormat c ds -> WindowBits type WindowBits = ((Int, Int, Int, Int, Bool), Int, Int) -- | 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 ContextFactory, such as GPipe-GLFW. module Graphics.GPipe.Context -- | The monad transformer that encapsulates a GPipe context (which wraps -- an OpenGl context). -- -- A value of type ContextT ctx os m a is an action on a context -- with these parameters: -- -- data ContextT ctx os m a -- | Run a ContextT monad transformer that encapsulates an object -- space. You need an implementation of a ContextHandler, which is -- provided by an auxillary package, such as GPipe-GLFW. 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 render 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 clearContextColor 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 ContextHandlerParameters ctx type ContextWindow ctx type WindowParameters 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 -- contextHandlerCreate). 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 contextHandlerCreate) 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 -- contextHandlerCreate). Only ever called once per window, and -- will always be called for each window before the context is deleted -- with contextHandlerDelete. 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 FragmentStream) data GPipeException GPipeException :: String -> GPipeException -- | 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 B a, B2 -- a, B3 a and B4 a where a -- is a normal haskell type such as Int32 or Float. By -- creating instances of the type class BufferFormat you may -- create new composite buffer types. module Graphics.GPipe.Buffer -- | A Buffer os b lives in the object space os and -- contains elements of type b. data Buffer os b -- | The class that constraints which types can live in a buffer. class BufferFormat f where type HostFormat f getGlType = error "This is only defined for BufferColor types" peekPixel = error "This is only defined for BufferColor types" getGlPaddedFormat = error "This is only defined for BufferColor types" where { type family HostFormat f; } -- | An arrow action that turns a value from it's host representation to -- it's buffer representation. Use toBuffer 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 -- --
--   proc ~pattern -> do ...
--   
toBuffer :: BufferFormat f => ToBuffer (HostFormat f) f -- | The arrow type for toBuffer. data ToBuffer a b -- | The atomic buffer value that represents a host value of type -- a. data B a -- | An atomic buffer value that represents a vector of 2 as on -- the host. data B2 a -- | An atomic buffer value that represents a vector of 3 as on -- the host. data B3 a -- | An atomic buffer value that represents a vector of 4 as on -- the host. This works similar to '(B a, B a, B a, B a)' but has some -- performance advantage, especially when used in VertexArrays. 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 Word8 or -- Word16. 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. -- Int or Word). 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). -- -- copyBuffer fromBuffer fromStart toBuffer toStart length will -- copy length elements from position fromStart in -- fromBuffer to position toStart in toBuffer. 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 -- t and a host representation h will evaluate to a -- buffer type used in the transfer. This family is closed, i.e. you -- cannot create additional instances to it. -- | This module provides the DSL for shader operations in GPipe. The type -- S x a is an opaque type that represents a value of -- type a in a shader stage x, eg S F Float -- means a floating point value in a fragment stream. module Graphics.GPipe.Expr data S x a -- | Phantom type used as first argument in S V a -- that denotes that the shader value is a vertex value data V -- | Phantom type used as first argument in S F a -- 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 ConvertFloat a type ConvertInt a type ConvertWord 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 Floats and Doubles. class Floating a => Real' a where rsqrt = (1 /) . sqrt exp2 = (2 **) log2 = logBase 2 mix x y a = x * (1 - a) + y * a fract' x = x - floor' x mod'' x y = x - y * floor' (x / y) floor' x = - ceiling' (- x) ceiling' x = - floor' (- x) 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 where clamp x a = minB (maxB x a) saturate x = clamp x 0 1 step a x = ifB (x <* a) 0 1 smoothstep a b x = let t = saturate ((x - a) / (b - a)) in t * t * (3 - 2 * t) 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 -- | while f g x will iteratively transform x with -- g as long as f generates true. while :: forall a x. (ShaderType a x) => (a -> S x Bool) -> (a -> a) -> a -> a -- | ifThen c f x will return f x if c evaluates -- to true or x otherwise. -- -- In most cases functionally equivalent to ifThenElse' 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. dFdx, dFdy or sampling using -- SampleAuto) ifThen :: forall a x. (ShaderType a x) => S x Bool -> (a -> a) -> a -> a -- | ifThenElse c f g x will return f x if c -- evaluates to true or g x otherwise. -- -- In most cases functionally equivalent to ifThenElse' 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. dFdx, dFdy or sampling using -- SampleAuto) ifThenElse :: forall a b x. (ShaderType a x, ShaderType b x) => S x Bool -> (a -> b) -> (a -> b) -> a -> b -- | Works just like ifB, return second argument if first is -- true otherwise return third argument. -- -- The difference from ifB is that it in most cases generate more -- efficient code when a is a compound type (e.g. a tuple or a -- vector). For simple types such as S x Float, ifThenElse' -- == ifB. 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 ShaderBaseType a 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 (~) 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 -- | 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 Shadow 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 Format for shadow samplers. These samplers have -- specialized sampler values, see sample1DShadow 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 SamplerFilter 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 -- FragmentStreams. 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 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 Shader, -- by turning it into a sampler object (See Sampler1D and -- friends). A texture may also be used as a render target into which -- FragmentStreams 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 -- | A PrimitiveStream can be rasterized, i.e. chopped up in pixel -- sized fragments, each of which contains an interpolated value of the -- primitives vertices, producing a FragmentStream. module Graphics.GPipe.FragmentStream -- | A FragmentStream a is a stream of fragments of type -- a. You may append FragmentStreams using the -- Monoid instance, and you can operate a stream's values using -- the Functor 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 FragmentFormat a where { type family FragmentFormat a; } -- | An arrow action that turns a value from it's vertex representation to -- it's fragment representation. Use toFragment 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 -- -- proc ~pattern -> do .... toFragment :: FragmentInput a => ToFragment a (FragmentFormat a) -- | The arrow type for toFragment. 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 Side, -- Viewport and DepthRange 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 ViewPort -- parameter and the depth range defined by the DepthRange -- 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 DepthRange -- 0 1 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 true, and discard all other fragments. filterFragments :: (a -> FBool) -> FragmentStream a -> FragmentStream a -- | Like fmap, 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 -- | This module defines all functions and types for drawing into a context -- window or texture from a Shader. module Graphics.GPipe.FrameBuffer -- | Draw color values from a FragmentStream 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 FragmentStream 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 FragmentStream -- 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 FragmentStream -- 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 FragmentStream -- 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 FragmentStream 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 FragmentStream 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 FragmentStream using the provided -- function that passes each fragment value into a DrawColors -- monad. The first argument is a function that retrieves a -- Blending setting from the shader environment, which will be -- used for all drawColor actions in the DrawColors monad -- where UseBlending is True. (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 draw, but performs a depth test on each fragment first. -- The DrawColors 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 draw, but performs a stencil test on each fragment first. -- The DrawColors 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 draw, but performs a stencil test and a depth test (in -- that order) on each fragment first. The DrawColors 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 Image 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 -- | True 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 Blending -- setting given to the draw action. If this is False, 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 -- ConstantColor that may be referenced from the -- BlendingFactors. The ConstantColor may be -- undefined if none of the BlendingFactors needs it. This -- kind of blending will only be made on colors with a Float -- representation (e.g. RGB8 or RGB32F, but not -- RGB8I), 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 internal representation (e.g. -- RGB8 or RGB8I, but not RGB32F; note the -- difference with BlendRgbAlpha 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 -- BlendingFactors. 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 -- BlendEquation. 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 -- | True 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. Less 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 PrimitiveArray can be turned into a PrimitiveStream in -- a Shader, in order to operate on the vertices of it and -- ultimately rasterize it into a FragmentStream. module Graphics.GPipe.PrimitiveStream -- | A PrimitiveStream t a is a stream of primitives of -- type t where the vertices are values of type a. You -- can operate a stream's vertex values using the Functor instance -- (this will result in a shader running on the GPU). You may also append -- PrimitiveStreams using the Monoid instance, but if -- possible append the origin PrimitiveArrays 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 VertexFormat a where { type family VertexFormat a; } -- | An arrow action that turns a value from it's buffer representation to -- it's vertex representation. Use toVertex 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 -- -- proc ~pattern -> do .... toVertex :: VertexInput a => ToVertex a (VertexFormat a) -- | The arrow type for toVertex. 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 fmap, 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 fmap, 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 PrimitiveStream of Points 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 -- | Uniform values are constants that you can combine with all vertices or -- fragments of a PrimitiveStream or FragmentStream. -- They are loaded from a Buffer 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 UniformFormat a x 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 toUniform 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 -- -- proc ~pattern -> do .... toUniform :: UniformInput a => ToUniform x a (UniformFormat a x) -- | The arrow type for toUniform. data ToUniform x a b -- | Load a uniform value from a Buffer into a Shader. 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 readme at the source -- repository. You could also go directly to a working example -- or the tutorials: Part 1, Part 2, Part 3, Part -- 4, Part 5. -- -- This module reexports relevant GPipe modules and the external -- Linear and Data.Boolean modules. module Graphics.GPipe