`PrimitiveStream`

s implement the `Functor`

class, which provides the
`fmap`

method that you can use to manipulate those streams. This corresponds to writing and using
vertex shaders, but in a much more modular way. You may for instance apply `fmap`

several times in a sequence, effectively creating complex shaders.

Instances are also provided for the `Monoid`

class, so several streams (of the same type) can be
concatenated. The order is preserved, meaning that the primitives in stream `a`

in `a `

will be
drawn before the primitives in `mappend`

b`b`

.

All atomic values except textures in vertex streams uses the `Vertex`

type constructor.
Composite types are created by composing the atomic `Vertex`

types, rather than wrapping the
composite type in the `Vertex`

type constructors.

`Vertex`

instances for are provided for most of Prelude's numerical classes. Since `Eq`

, `Ord`

and `Show`

are prerequisites for these classes, instances are provided for them too, even though
their methods all will generate errors if used (except `min`

and `max`

). Use the instances of
`EqB`

, `OrdB`

and `IfB`

from the Boolean package if you want to compare `Vertex`

values.
Hyperbolic trigonometrical functions aren't provided either.

Rewrite rule specializations are provided for the Vec package functions `norm`

, `normalize`

,
`dot`

and `cross`

on vectors of `Vertex`

`Float`

, so the use of these functions (and others
from that package that is defined in terms of them) are highly encouraged.

- data PrimitiveStream p a
- data Vertex a
- class GPU a => VertexInput a where
- toVertex :: CPU a -> InputAssembler a

- data InputAssembler a
- data Triangle
- data Line
- data Point = PointList
- class Primitive p
- toGPUStream :: (VertexInput a, Primitive p) => p -> [CPU a] -> PrimitiveStream p a
- toIndexedGPUStream :: (VertexInput a, Primitive p) => p -> [CPU a] -> [Int] -> PrimitiveStream p a

# Data types

data PrimitiveStream p a Source

A stream of primitives built by vertices on the GPU. The first parameter is the primitive type (currently `Triangle`

, `Line`

or `Point`

) and the second the
the type of each primitives' vertices' type (built up of atoms of type `Vertex`

).

Functor (PrimitiveStream p) | |

Monoid (PrimitiveStream p a) |

Eq (Vertex a) | |

Floating (Vertex Float) | |

Fractional (Vertex Float) | |

Num (Vertex Float) | |

Num (Vertex Int) | |

Ord (Vertex Float) | |

Ord (Vertex Int) | |

Show (Vertex a) | |

Boolean (Vertex Bool) | |

Convert (Vertex Float) | |

Convert (Vertex Int) | |

Real' (Vertex Float) | |

GPU (Vertex Bool) | |

GPU (Vertex Float) | |

GPU (Vertex Int) | |

VertexInput (Vertex Float) | |

VertexOutput (Vertex Float) | |

IfB (Vertex Bool) (Vertex Bool) | |

IfB (Vertex Bool) (Vertex Float) | |

IfB (Vertex Bool) (Vertex Int) | |

Eq a => EqB (Vertex Bool) (Vertex a) | |

Ord a => OrdB (Vertex Bool) (Vertex a) |

# Creating primitive streams

class GPU a => VertexInput a whereSource

The context of types that can be converted into vertices in `PrimitiveStream`

s.
Create your own instances in terms of the existing ones, e.g. convert your vertex data to `Float`

s,
turn them into `Vertex`

`Float`

s with `toVertex`

and then convert them to your vertex data representation.

toVertex :: CPU a -> InputAssembler aSource

Turns an ordinary value into a vertex value in the `InputAssembler`

monad. The following rule must be satisfied:

toVertex undefined >> a = a

This ensures that its definition always use the same series of `toVertex`

calls to convert values of the same type.
This unfortunatly rules out ordinary lists (but instances for fixed length lists from the Vec package are however provided).

VertexInput () | |

VertexInput (Vertex Float) | |

(VertexInput a, VertexInput b) => VertexInput (a, b) | |

(VertexInput a, VertexInput b) => VertexInput (:. a b) | |

(VertexInput a, VertexInput b, VertexInput c) => VertexInput (a, b, c) | |

(VertexInput a, VertexInput b, VertexInput c, VertexInput d) => VertexInput (a, b, c, d) |

data InputAssembler a Source

A monad in which CPU data gets converted to vertex data.
Use `toVertex`

in the existing instances of `VertexInput`

to operate in this monad.

:: (VertexInput a, Primitive p) | |

=> p | The primitive type. |

-> [CPU a] | A list of vertices, with the layout specified by the primitive type. |

-> PrimitiveStream p a | The resulting |

Converts a list of values to a `PrimitiveStream`

, using a specified `Primitive`

type.
This function is lazy in the aspect that if parts of the values aren't used on the GPU, they won't
get evaluated and transferred there either.

:: (VertexInput a, Primitive p) | |

=> p | The primitive type. |

-> [CPU a] | A list of vertices. |

-> [Int] | A list of indexes into the vertex list, with the layout specified by the primitive type. |

-> PrimitiveStream p a | The resulting |

Converts a list of values to a `PrimitiveStream`

, using a specified `Primitive`

type and an index list.
This will use index buffer objects on the GPU, and is recommended if several primitives share vertices.
This function is lazy in the aspect that if parts of the values aren't used on the GPU, they won't
get evaluated and transferred there either.