-- 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.5 -- | 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 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 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 -- | 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 { -- | A base type that this type can convert into. Use the -- ShaderBaseType function on an existing instance of -- ShaderType to define this in your instance. 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 -- | 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 { -- | The type a value of this format has when it lives on the host (i.e. -- normal Haskell world) 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. type family BufferColor c h -- | 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: -- --
-- 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 type family Combine t t' -- | 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 type family IndexFormat a -- | 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) -- | 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 { -- | The type the buffer value will be turned into once it becomes a vertex -- value. 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 -- | 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 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 -- | 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 -- | 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 { -- | The type the buffer value will be turned into once it becomes a vertex -- or fragment value (the x parameter is either V or -- F). 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