A small Tutorial

**(Draft)**
*HOpenGL* the Haskell port
of OpenGL a common library for doing 3D graphics. I more or less took
minutes of my efforts and make them public in this tutorial.
I did not have any prior
experience in graphics programming, when I started to work with
HOpenGL.

The source of this paper is an XML-file. The sources are processed by
an XQuery processor, XSLT scripts and

I'd like to thank Sven Panne

The first two lines import the necessary libraries. The main function
does three things:

The only thing that has changed, is that we make use of one of
the values returned by
For the window definition we use the code from `HelloWindow.hs`. But instead of clearing the screen, when the
window is to be displayed, we use an own display function:
```
We want to draw some points on the screen. So let's define some
points. We can do this in a list. Points in a three dimensional space
are triples of coordinates. We can use floating point numbers for
coordinates in OpenGL.
```

```
Eventually we need the display function, which displays these points.
```

`vertex$Vertex3 x y z) myPoints]]>`

As you see, when the window ist displayed, we want first everything to
be cleared from the window. Then we use the HOpenGL function `renderPrimitive`. The first argument `Point` specifies
what it is that we want to render; points in our case. For the second
argument we need to transform our coordinates into some data, which is
used by HOpenGL. Do not yet worry about this transformation.

As before, you will notice that again for quite a number of
attributes we did not supply explicit values. We did not specify the
Color of the points to be drawn. Moreover we did not define the
coordinates of the graphics window. Looking at its result it is
obviously a two dimensional
view, where the lower left corner seems to have coordinates (-1,-1) and the
upper right corner the (1,1). These values are default values chosen
by the OpenGL library.

`Points` becomes `Polygon`.

The resulting window can be found in figure

Expressions
evaluate to some value without changing any state. This is a nice
property of Haskell, because it makes reasoning about programs easier
and programs are very robust.

A comprehensive introduction to OpenGL can be found in the so called*redbook* . OpenGL comes along with
a utility library called GLU and a system
independent GUI library called GLUT .
*Monads* . Most
Haskell programmers do not
worry about the theory of monads but simply use them, whenever they
do I/O, state changing functions or in parser construction. With
monads functional programs can almost look like ordinary imperative
progams .

Monads are so essential to functional programming, that they have a
special syntactic construct in Haskell, the *do notation*.
Consider the following simple Haskell program, which uses monads:
```
main = do
let x = 5
print x
let x = 6
print x
xs <- getLine
print (length xs)
```

The monadic statements start with the keyword `do`. The
statements have side effects. Variables can be defined and
redefined in `let`-expressions`<-` notation.

On another aspect OpenGL and Haskell perfectly match. In OpenGL
functions are assigned to different data objects,
e.g.

To compile Haskell OpenGL programs you simply have to add the
package information to he command line invocation of GHC,
i.e. use:

`ghc -package GLUT MyProgram.hs`

Everything else, linking etc is done by GHC. You do not have to worry about library paths or anything else.

This tutorial has been written with no prior knowledge of OpenGL and no documentation of HOpenGL at hand.

For the *old* version 1.04 of HOpenGL an online tutorial written
by Andre W B Furtado exists
at

windowSize $= Size 800 500

```
infixr 2 $=
class HasSetter s where
($=) :: s a -> a -> IO ()
```

The variables of HOpenGL, which can be set are of
type x<-get screenSize

When you compile and run this example the size of your screen it
printed:
```
class HasGetter g where
get :: g a -> IO a
```

Variables which implement this class are of
type
But things do not always work so simple as this sounds.
`windowSize` is retrieved:
```
Running this program gives the somehow surprising result:
```

`windowSize` still has the default value `(300,300)`.

The reason for this is, that setting the window size state variable
has not a direct effect. It just states a wish for a window size. Only
in the execution of the function `mainLoop` actual windows will
be created by the window system. Only then the window size will be
taken into account. Up to that moment the window size variable still
has the default value. If you print the window size state within some
function which is executed in the main loop, then you will get the
actual size. By the way: you can try `initialWindowSize` without
getting such complecated surprising results.
`createWindow`. This makes it in the beginning a bit hard
to understand, when the state is changed in which way.

The `createWindow` statement not only constructs a window
object, but keeps this new window as the current window in the
state. After the `createWindow` statement all window effecting
statements like setting the window size, are applied to this new
window object.

```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
main = do
(progName,_) <- getArgsAndInitialize
createAWindow progName
mainLoop
createAWindow windowName = do
createWindow windowName
displayCallback $= display
display =
```clear [ColorBuffer]

For colors several data types are defined. An easy to use one is:
```
data Color4 a = Color4 a a a a
deriving ( Eq, Ord, Show )
```

The four parameters of this constructor specify the red, green and
blue values of the color and additionally a fourth argument, which
denotes the opaqueness of the color. The values are usually
specified by floating numbers of type `GLfloat`. Values for
number attributes are between 0 and 1.

You may wonder, why there is a special type `GLfloat` for
numbers in HOpenGL. The reason is that OpenGL is defined in a way that
it is as independent from concrete types in any implementation as
possible.
However you do not have to worry too much
about this type. You can use ordinary float literals for numbers of
type `GLfloat`. Haskells overloading mechanism ensures that
these literals can create `GLfloat` numbers.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
main = do
getArgsAndInitialize
createAWindow "red"
mainLoop
createAWindow windowName = do
createWindow windowName
displayCallback $= display
display = do
```

`flush` should be
made. Only such a call will ensure that the statements are completely
committed to the device, on which is drawn.
`renderPrimitive`. The first argument of this
functions specifies what kind of primitive is to be drawn. There are
the following primitives defined in OpenGL:

```
data PrimitiveMode =
Points
| Lines
| LineLoop
| LineStrip
| Triangles
| TriangleStrip
| TriangleFan
| Quads
| QuadStrip
| Polygon
deriving ( Eq, Ord, Show )
```

The second
argument defines the points which specify the primitives. These points
are so called vertexes. Vertexes are actually monadic functions which
constitute a point. If you want to define a point in a 3-dimensional
universe with the coordinates $x,\; y,\; z$ then you can use
the following expression in HOpenGL:

or, if you prefer the use of the standard prelude operator `vertex (Vertex3 x y z)``$`:
`vertex$Vertex3 x y z``renderPrimitiv`.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
main = do
getArgsAndInitialize
createAWindow "points"
mainLoop
createAWindow windowName = do
createWindow windowName
displayCallback $= display
display = do
clear [ColorBuffer]
currentColor $= Color4 1 1 0 1
```

If you do not like parantheses then you can of course use the
operator `$` from the prelude and rewrite the line:

`renderPrimitive Points$vertex$Vertex3 (0.1::GLfloat) 0.5 0`
`(0.1::GLfloat)` on one of the float literals. In
larger applications Haskell can usually infer this information from
the context. Just in smaller applications you will sometimes need to
help Haskell's type checker a bit.

The second argument of `renderPrimitive` is a sequence of
monadic statements. So, if you want more than one point to be drawn,
you can define these in a nested *do statement*
*do statement* to define more
points.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
main = do
getArgsAndInitialize
createAWindow "more points"
mainLoop
createAWindow windowName = do
createWindow windowName
displayCallback $= display
display = do
clear [ColorBuffer]
currentColor $= Color4 1 1 0 1
renderPrimitive Points $
```

`map (\(x,y,z)->vertex$Vertex3 x y z)`

and then combining the
sequence of monadic statements into one monadic statement. Therefore
you can use the standard function for monads: `sequence_`. The
standard function `mapM_` is simply the composition of `map` and `sequence_`, such that a list of triples can be
converted to a monadic vertex statement by:

`mapM_ (\(x,y,z) -> vertex$Vertex3 x y z)`

which is the technique used in the introductory example.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
main = do
getArgsAndInitialize
createAWindow "more points"
mainLoop
createAWindow windowName = do
createWindow windowName
displayCallback $= display
display = do
clear [ColorBuffer]
currentColor $= Color4 1 1 0 1
let points = [(0.1,0.6,0::GLfloat)
,(0.2,0.8,0)
,(0.3,0.1,0)
,(0,0,0)
,(0.4,-0.8,0)
,(-0.2,-0.8,0)
]
renderPoints points
flush
makeVertexes = mapM_ (\(x,y,z)->vertex$Vertex3 x y z)
renderPoints = renderAs Points
renderAs figure ps = renderPrimitive figure$makeVertexes ps
```

```
A first function will open a window und use a given display function
for the window graphics:
```

```
The next function creates for a list of points, which are expressed as
triples, and a basic shape a display function which renders the
desired shape.
```

`vertex$Vertex3 x y z)]]>`

Eventually we define a list of points as example and provide a
function for easy use of these points:
```
```

```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

`Lines`. In order that this
works properly an even number of vertexes needs to be supplied to the
function `renderPrimitive`.
```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure*quad*. There are two flavours of
quads.
`Quads` takes quadruples of points and
connects them in order to render a filled figure.
```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

The resulting window can be found in figure```
import PointsForRendering
import Graphics.Rendering.OpenGL
main = mainFor
```

In this case the resulting window looks like the triangle fan we have
seen before.
*GLU* tessellation.
```
The crucial function calculates a list of points which are all on the
circle. You need a bit of basic geometrical knowledge for this.
The coordinates of the points on a circle can be determined
by $\backslash sin(\backslash alpha)$ and $\backslash cos(\backslash alpha)$ where $\backslash alpha$ is between $0$ and $2\backslash pi$.
```

Thus we can easily calculate the coordinates of an arbitrary number of
points on a circle:
```
If we take a large anough number then we will eventually get a circle:
```

```
The following function can be used to render the circle figures:
```

```
```

```
import PointsForRendering
import Circle
import Graphics.Rendering.OpenGL
main = renderInWindow $ do
clear [ColorBuffer]
renderCircleApprox 0.8 10
```

The resulting graphic can be seen in figure```
The resulting graphic can be seen in figure
```

```
The resulting graphic can be seen in figure
```

```
We can simply define the points of the inner and outer ring and merge
these. The resulting list of points can then be rendered as
a
```

`QuadStrip`. Since there is no primitive mode for quad loops,
we need to append the first two points as the last points again:
```
[x,y]) (points++[p])
where
innerPoints = circle innerRadius
outerPoints = circle outerRadius
points@(p:_) = zip innerPoints outerPoints]]>
```

Eventually we provide a small function for rendering ring shapes.
```
```

```
The resulting graphic can be seen in figure
```

```
import Graphics.Rendering.OpenGL
import PointsForRendering
main = renderInWindow display
display = do
```

The resulting graphic can be seen in figure`Maybe (GLint, GLushort)`. The second
argument of the value pair denotes the kind of stipple. For every
short value there is one stipple. The short value has 16 bits. Every
bit stands for a pixel. If for the corresponding short number the bit
is set, then the pixel will be drawn, otherwise not. This means that
for the short number `0` you will not see anything of your
line, and for the value `65535` you will see a solid line.

The integer number of the value pair denotes a factor for the chosen
stipple. For some positiv integer $n$ every bit of the
short number stands for $n$ bits.
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import PointsForRendering
main = renderInWindow display
display = do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
```

The resulting graphic can be seen in figure`renderPrimitive` takes monadic statements as argument and not
simply a list of vertexes? This means we could pass any monadic
statement to the function `renderPrimitive`, not only
statements that define vertexes by the call of the
function `vertex`. There are some statements, which are allowed
in the statements passed to `renderPrimitive`.
One of these is setting the current color before
every call of `vertex` to a new value. When finally rendering
the primitive, OpenGL takes these color values into acount.
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import PointsForRendering
colorTriangle = do
currentColor $= Color4 1 0 0 1
vertex$Vertex3 (-0.5) (-0.5) (0::GLfloat)
currentColor $= Color4 0 1 0 1
vertex$Vertex3 (0.5) (-0.5) (0::GLfloat)
currentColor $= Color4 0 0 1 1
vertex$Vertex3 (-0.5) (0.5) (0::GLfloat)
main = renderInWindow display
display = do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
renderPrimitive Triangles colorTriangle
flush
```

The resulting window can be found in figure`Graphics.Rendering.OpenGL.GLU.Tessellation` there are a number of
functions, which calculate a set of simpler polygons.
For the time being, we will not go
into detail, but give one single example, of how to use this library.
```
We can easily calculate the points on the star rays. They are all on
one circle. We can use our function for defining circle points and get
a list of points. For rendering the star, we take first the points
with odd index followed by the points with even index.
```

```
Vertex3 x y z)(os++es)
where
(os,es) = partition (\(i,_)-> odd i)
$zip [1,2..]
$circlePoints radius rays]]>
```

For tesselation we need to create a `ComplexPolygon`, which has
a list of `ComplexContour`. A `ComplexContour` contains
a list of `AnnotatedVertexes`. The annotation can be used for
color or similar information. We do not make use of this annotation
and simple annotate every vertex with 0.
`AnnotatedVertex v 0) points]]]>`

The function `tesselate` creates a list of simple polygons.
It needs some control information, which we do not explain here.
```
The resulting simple polygons can be rendered with the
function
```

`renderPrimitive`.
```
Now we can test our stars. We render two stars, one with 7 and one
with 5 rays.
```

```
import PointsForRendering
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Star
main = renderInWindow$do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
currentColor $= Color4 1 0 0 1
```

The resulting window can be found in figure```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
main = renderInWindow display
display = do
clear [ColorBuffer]
renderObject Solid$ Teapot 0.6
flush
```

The resulting graphic can be seen in figure

```
import PointsForRendering
import Ring
import Graphics.Rendering.OpenGL
```

We define a function, which creates a ring at a given
position. Therefore we first set the transformation to the
translate transformation then define the ring and finally set the
transformation matrix back to the identity:
```
ringAt x y innerRadius outerRadius = do
```translate$Vector3 x y (0::GLfloat)
ring innerRadius outerRadius

We can test this by placing some ring in different colors on the
screen.
```
main = do
renderInWindow someRings
someRings = do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
loadIdentity
currentColor $= Color4 1 0 0 1
ringAt 0.5 0.3 0.1 0.12
loadIdentity
currentColor $= Color4 0 1 0 1
ringAt (-0.5) 0.3 0.3 0.5
loadIdentity
currentColor $= Color4 0 0 1 1
ringAt (-1) (-1) 0.7 0.75
loadIdentity
currentColor $= Color4 0 1 1 1
ringAt 0.7 0.7 0.2 0.3
```

The resulting graphic can be seen in figure
We write a simple module for rendering filled rectangles:
```
module Squares where
import Graphics.Rendering.OpenGL
import PointsForRendering
```

Here is a function for arbitrary rectangles:
```
A square is just a special case:
```

```
Now we will transform squares.
```

```
import PointsForRendering
import Squares
import Graphics.Rendering.OpenGL
```

We define a function, which applies the rotate transformation to a
square. It is rotated around the $z$-axis.
```
rotatedSquare alpha width = do
```

A further utility function moves some shape to a specified
position. Note that this function resets the matrix again.
```
displayAt x y displayMe = do
translate$Vector3 x y (0::GLfloat)
displayMe
loadIdentity
```

Some squares are defined and rotated:
```
main = do
renderInWindow someSquares
someSquares = do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
currentColor $= Color4 1 0 0 1
displayAt 0.5 0.3$rotatedSquare 15 0.12
currentColor $= Color4 0 1 0 1
displayAt (-0.5) 0.3$rotatedSquare 25 0.5
currentColor $= Color4 0 0 1 1
displayAt (-1) (-1)$rotatedSquare 4 0.75
currentColor $= Color4 0 1 1 1
displayAt 0.7 0.7$rotatedSquare 40 0.3
```

The resulting graphic can be seen in figure

```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
main = renderInWindow display
display = do
clear [ColorBuffer]
```scale 0.3 0.9 (0.3::GLfloat)
translate$Vector3 (-0.3) 0.3 (0::GLfloat)
rotate 30 $Vector3 0 1 (0::GLfloat)
renderObject Solid$ Teapot 0.6
loadIdentity
flush

The resulting graphic can be seen in figure
The code:
```
rotatedSquareAt width alpha x y z = do
translate$Vector3 x w y
rotate alpha $Vector3 0 0 (1::GLfloat)
square width
```

defines a composition of a translate und a rotate transformation,
which is applied to a square figure. A sequence of transformation
statements is composed to a single transformation in the same way as
the standard function composition operator `(.)` composes
functions: `(f . g) x = f(g(x))`. The compositional
function `(f . g)` is the same as first applying
function `g` and then applying `f`. For transformations
in HOpenGL this means that for a sequence of transformations
```
translate$Vector3 x w y
rotate alpha $Vector3 0 0 (1::GLfloat)
```

first the points are rotated and then they are translated.

The order in which transformations are performed is of course not
arbitrary. A rotation after a translation is different to a
translation after a rotation.
```
A black square at the origin:
```

```
currentColor $= Color4 0 0 0 1
square 0.5
loadIdentity
```

A blue square translated:
```
currentColor $= Color4 0 0 1 1
translate$Vector3 0.5 0.5 (0::GLfloat)
square 0.5
loadIdentity
```

A light blue square that is rotated:
```
currentColor $= Color4 0 1 1 1
rotate 35 $Vector3 0 0 (1::GLfloat)
square 0.5
loadIdentity
```

A red square that is first rotated and then translated:
```
currentColor $= Color4 1 0 0 1
translate$Vector3 0.5 0.5 (0::GLfloat)
rotate 35 $Vector3 0 0 (1::GLfloat)
square 0.5
loadIdentity
```

A yellow square that is first translated and then rotated:
```
currentColor $= Color4 1 1 0 1
rotate 35 $Vector3 0 0 (1::GLfloat)
translate$Vector3 0.5 0.5 (0::GLfloat)
square 0.5
loadIdentity
```

The resulting window can be found in figure

Internally every vertex in OpenGL is not represented by 3 coordinates $(x,y,z)$ but by four coordinates $(x,y,z,w)$. The $x,\; y,\; z$ values are devided by $w$. Usually the value of $w$ is $1.0$.

Thus for a transformation matrix you need a matrix of four rows and four
columns. Remember that a matrix is multiplied with a vector in the
following way:
`matrix`. It takes as first argument a
parameter, which specifies in which order the matrix elements appear
in the list: `RowMajor` for row wise and `ColumMajor` for column wise appearance. The function `multMatrix` allows to multiply your newly created transformation
matrix to the current transformation context.
*shear*. Mathematical textbooks
define *shear* in the following way:
*shear* transformation, which leaves $y$ and $z$ coordinates unchanged, and adds to
the $x$ coordinate some value depending on the value
of $y$. For some $f$ we need the following
transformation matrix:
```
module MyTransformations where
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
shear f = do
m <- (newMatrix RowMajor [1,f,0,0
,0,1,0,0
,0,0,1,0
,0,0,0,1])
multMatrix (m:: GLmatrix GLfloat)
```

Let us test our new transformation:
```
import PointsForRendering
import Circle
import Squares
import MyTransformations
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
main = renderInWindow$do
loadIdentity
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
translate$Vector3 0.5 0.5 (0::GLfloat)
shear 0.5
currentColor $= Color4 0 0 1 1
fillCircle 0.5
loadIdentity
translate$Vector3 (-0.5) (-0.5) (0::GLfloat)
shear 0.5
currentColor $= Color4 1 0 0 1
square 0.5
```

The resulting window can be found in figure

```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
import Ring
import Squares
main = renderInWindow display
display = do
clear [ColorBuffer]
translate$Vector3 (-0.1) 0.1 (0::GLfloat)
ring 0.2 0.4
flush
```

HOpenGL provides a function which allows to add some more
transformations to some local parts of your shape. This function is
called `preservingMatrixs` which refers to the fact that
transformations are technically implemented as
matrixes. `preservingMatrix` has one argument, which is a
monadic statement. The application of `preservingMatrix` is a
monadic statement:
`preservingMatrix :: IO a -> IO a`

Every transformation done within this monadic
statement will not be done only locally. It does not effect the
statements which follow after the application of `preservingMatrix`.
`preservingMatrix` we provide
a module, which is able to render a side of the famous Rubik's
Cube. Such a side consists of 9 squares which are of some color and
which have a black frame. We can render such a shape, by rendering the
single framed squares at the origin and then move them to their
position. This movement is done within
a `preservingMatrix` application.
```
Doing a frame involves the four sides of a frame. Each side is created
at the origin and then moved to its final position:
```

```
Each of the nine fields is rendered by drawing its frame and its
colored square:
```

```
Eventually the side of Rubik's Cube can be drawn
```

```
[[Color4 GLfloat]] -> IO ()
renderArea width css
= do
let cs = concat css
cps = zip cs $ areaFields width
mapM_ (\(c,f)-> f(originField width c)) cps
areaFields width =
[makeSquare x y |x<-[1,0,-1],y<-[1,0,-1]]
where
makeSquare xn yn = \f -> preservingMatrix $ do
let
x = xn*width
y = yn*width
translate $Vector3 x y 0
f
red = Color4 1 0 0 (1::GLfloat)
green = Color4 0 1 0 (1::GLfloat)
blue = Color4 0 0 1 (1::GLfloat)
yellow = Color4 1 1 0 (1::GLfloat)
white = Color4 1 1 1 (1::GLfloat)
black = Color4 0 0 0 (1::GLfloat)]]>
```

The following module tests the rendering. Two sides are
rendered. Further transformations are applied to them.
```
import PointsForRendering
import Graphics.Rendering.OpenGL
import PointsForRendering
import RubikFace
_FIELD_WIDTH :: GLfloat
_FIELD_WIDTH = 1/5
main = renderInWindow faces
faces = do
clearColor $= white
clear [ColorBuffer]
loadIdentity
translate $Vector3 (-0.6) 0.4 (0::GLfloat)
renderArea _FIELD_WIDTH r1
loadIdentity
translate $Vector3 (0.1) (-0.3) (0::GLfloat)
rotate 290 $ Vector3 0 0 (1::GLfloat)
scale 1.5 1.5 (1::GLfloat)
renderArea _FIELD_WIDTH r1
r1=[[red,blue,yellow],[white,green,red],[green,yellow,blue]]
```

The reshape function might be empty. This is modelled by the Haskell
data type `Maybe`.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
createWindow progName
displayCallback $= display
```

Run this example. You will see a white square in the middle of a black
screen. Now resize the window. You will notice that the size of the
square will not change. If you make the window smaller parts of the
picture are not displayed, if you enlarge the window parts of the
window contain no image (which means it might be some arbitrary
image). Figure

```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
createWindow progName
displayCallback $= display
```reshapeCallback $= Just reshape
mainLoop
display = do
clear [ColorBuffer]
displayPoints points Quads
where
points
= [(0.5,0.5,0)
,(-0.5,0.5,0)
,(-0.5,-0.5,0)
,(0.5,-0.5,0)]
reshape s@(Size w h) = do
viewport $= (Position 0 0, s)

If you start this program and resize the window, then always the
complete window pane will be used for rendering your image.
```
import Graphics.UI.GLUT
import Graphics.Rendering.OpenGL
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
createWindow progName
clearColor $= Color4 0 0 0 0
displayCallback $= display
reshapeCallback $= Just reshape
mainLoop
display = do
clearColor $= Color4 1 1 1 1
clear [ColorBuffer]
currentColor $= Color4 1 0 0 1
displayPoints ps1 LineLoop
displayPoints ps2 Lines
where
ps1=[(0.5,0.5,0),(-0.5,0.5,0),(-0.5,-0.5,0),(0.5,-0.5,0)]
ps2=[(1,1,0),(-1,-1,0),(-1,1,0),(1,-1,0) ]
reshape s@(Size w h) = do
```viewport $= (Position 50 50, Size (w-80) (h-60))

The resulting window can be found in figure
Projection is equally as transformation internally expressed in terms
of a matrix. The statement `loadIdentity` can refer to the
transformation or to the projection matrix. A state variabble `matrixMode` defines, which of these matrixes these statements
refer to. Therefore it is necessary to switch this variable to the
value `Projection`, before applying the function `ortho` and afterwards to reset the variable back to the
value `ModelView`.
```
import PointsForRendering
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Star
main = do
(progName,_) <- getArgsAndInitialize
createWindow (progName++"1")
displayCallback $= display
```

The resulting windows can be found in figure`ortho` is the simpliest projection we can define. When we will
consider third dimensional szeneries we will learn a more powerful
projection.

If you think these names a bit too technical, then you might use the
following module, which makes `IORef` variables instances of
the type classes `HasGetter` and `HasSetter`. Thus we
can use our own state variables in the same way, we use the HOpenGL
state variables.```
module StateUtil where
import Graphics.Rendering.OpenGL
import Data.IORef
import Graphics.UI.GLUT
--instance HasSetter IORef where
-- ($=) var val = writeIORef var val
--instance HasGetter IORef where
-- get var = readIORef var
new = newIORef
```

` KeyState -> Modifiers -> Position -> IO ()]]>`

A ```
data Key
= Char Char
| SpecialKey SpecialKey
| MouseButton MouseButton
deriving ( Eq, Ord, Show )
```

The keystate informs, if the key has been pressed or released.
```
data KeyState
= Down
| Up
deriving ( Eq, Ord, Show )
```

A modifier denotes, if some extra key is used, like the alt, strg or
shift key:
```
data Modifiers = Modifiers { shift, ctrl, alt :: KeyState }
deriving ( Eq, Ord, Show )
```

And finally the position informs about the current mouse pointer
position.

We create a state variable which stores the current radius of the circle:
radius <- new 0.1

The display function gets this state variable as first argument:

And the keyboard callback gets this variable as first argument:
keyboardMouseCallback $= Just (keyboard radius)
mainLoop

The display function gets the current value for the radius and draws a
filled circle:
```
display radius = do
clear [ColorBuffer]
```r <- get radius
fillCircle r

The keyboard callback reacts on two keyboard events. The value of the
radius variable are changed:

Compile and start this program and press the

We define a constant which denotes the value by which the radius
changes between every redisplay:

Within the main function an ```
main = do
(progName,_) <- getArgsAndInitialize
createWindow progName
radius <- new 0.1
step <- new _STEP
displayCallback $= display radius
```idleCallback $= Just (idle radius step)
mainLoop

The display function renders a ring, depending on the state variable
for the radius:

The idle function changes the value of the variable ```
idle radius step = do
r <- get radius
s <- get step
if r>=1 then step $= (-_STEP)
else if r<=0 then step $= _STEP
else return ()
s <- get step
radius $= r+s
```postRedisplay Nothing

A common solution for this problem in animated pictures is, not to apply the statements of the display function directly to the screen, but to an invisible buffer. When all statements of the display function have been applied to this invisible background buffer, this buffer is copied to the screen. This way only the ready to use final picture is shown on screen and not any intermediate rendering step (e.g. the picture after the clear statement).

OpenGL provides a double buffering mechanism. We only have to activate
this. Therefore we need to set the initial display mode variable
accordingly. Instead of a call to the function `flush` a call
to the function `swapBuffers` needs to be done as last
statement of the display function.
```
import Ring
import PointsForRendering
import StateUtil
import Graphics.Rendering.OpenGL
import Data.IORef
import Graphics.UI.GLUT as GLUT
_STEP = 0.001
main = do
(progName,_) <- getArgsAndInitialize
```

First of all we define some constant values for the game:
x-, y-coordinates of the game, width and height of a paddle, the
radius of the ball, initial factor, how a ball and a paddle changes
its position, and an initial board size.

We define a data type, game. The game state can be characterized by
the position of the ball and the values these coordinates change for
the next redisplay:

The paddles, which are characterized by their position and the
position change on the y-axis (x-axis is fixed for a paddle).

Additionally a game has points for the left and the right player and a
factor which denotes how fast ball and paddles move:

For a starting game we provide the following initial game state:

The main function creates a double buffering window in fullscreen
mode. An initial game state is created and passed to the keyboard,
display, idle and reshape function:

The display function simply gets the ball and paddles from the game
state and renders these:

Paddles are simply rectangles:

We made use of the utility function which moves a shape to some position:

Within the idle function ball and paddles need to be set to their next
position on the field:

The movement on the ball is determined by the upper and lower bound of
the field, by the left and right bound of the field and the position
of the paddles:
```
=yl
&& y <=yl+paddleHeight
= -xDir
|x <= _LEFT-ballRadius = 0
| x+ballRadius >= xr
&& y+ballRadius >=yr
&& y <=yr+paddleHeight
= -xDir
|x >= _RIGHT+ballRadius = 0
|otherwise = xDir
newYDir
|y > _TOP-ballRadius || y< _BOTTOM+ballRadius = -yDir
|newXDir == 0 = 0
|otherwise = yDir
(Ball (x,y) xDir yDir) = ball g
factor = moveFactor g
(xl,yl,_) = leftP g
(xr,yr,_) = rightP g
]]>
```

A paddle moves only on the y-axis. We just need to ensure that it
does not leaves the field. There are maximum and minimum values for y:

The keyboard function: key 'a' moves the left paddle, key 'l' the
right paddle and the space key gets a new ball:
```
=_RIGHT-3*paddleWidth = - _INITIAL_BALL_DIR
|otherwise = xD
if (xD==0)
then game$=g{ball=Ball (x+4*xDir,y) xDir _INITIAL_BALL_DIR}
else return ()
keyboard _ _ _ _ _ = return ()
paddleDir Down = _INITIAL_PADDLE_DIR
paddleDir Up = -_INITIAL_PADDLE_DIR]]>
```

Finally we define the visual part of the screen. The movement factor
of the ball depends on the width of the screen:

Have a break and play ```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import Circle
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
createWindow progName
displayCallback $= display
clearColor $= Color4 1 1 1 1
mainLoop
display = do
clear [ColorBuffer,DepthBuffer]
loadIdentity
```translate (Vector3 0 0 (-0.5::GLfloat))
currentColor $= Color4 1 0 0 1
square 1
loadIdentity
translate (Vector3 0.2 0.2 (0.5::GLfloat))
currentColor $= Color4 0 0 1 1
fillCircle 0.5
flush

However as can be seen in figure ,
the blue circle hides parts of the
red square.
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import Circle
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
```initialDisplayMode $= [WithDepthBuffer]
createWindow progName
depthFunc $= Just Less
displayCallback $= display
clearColor $= Color4 1 1 1 1
mainLoop
display = do
clear [ColorBuffer,DepthBuffer]
loadIdentity
translate (Vector3 0 0 (-0.5::GLfloat))
currentColor $= Color4 1 0 0 1
square 1
loadIdentity
translate (Vector3 0.2 0.2 (0.5::GLfloat))
currentColor $= Color4 0 0 1 1
fillCircle 0.5
flush

Now as can be seen in figure , the
red square hides parts of the blue circle.
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import Circle
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
initialDisplayMode $= [WithDepthBuffer]
createWindow progName
depthFunc $= Just Less
displayCallback $= display
matrixMode $= Projection
loadIdentity
```ortho (-5) 5 (-5) 5 (1) 40
matrixMode $= Modelview 0
clearColor $= Color4 1 1 1 1
mainLoop
display = do
clear [ColorBuffer,DepthBuffer]
loadIdentity
translate (Vector3 0 0 (-2::GLfloat))
currentColor $= Color4 1 0 0 1
square 1
loadIdentity
translate (Vector3 4 4 (-5::GLfloat))
currentColor $= Color4 0 0 1 1
square 1
flush

As can be seen in figure , the
two squares have the same size, even though the red one is closer to
the viewer.
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import Circle
import PointsForRendering
main = do
(progName,_) <- getArgsAndInitialize
initialDisplayMode $= [WithDepthBuffer]
createWindow progName
depthFunc $= Just Less
displayCallback $= display
matrixMode $= Projection
loadIdentity
let near = 1
far = 40
right = 1
top = 1
```frustum (-right) right (-top) top near far
matrixMode $= Modelview 0
clearColor $= Color4 1 1 1 1
mainLoop
display = do
clear [ColorBuffer,DepthBuffer]
loadIdentity
translate (Vector3 0 0 (-2::GLfloat))
currentColor $= Color4 1 0 0 1
square 1
loadIdentity
translate (Vector3 4 4 (-5::GLfloat))
currentColor $= Color4 0 0 1 1
square 1
flush

Now, as can be seen in figure , the
blue square appears to be smaller than the red square.
```
x-0.1)
keyForPos pPos (Char '-') = modPos pPos (id,id,(+)0.1)
keyForPos pPos (SpecialKey KeyLeft) = modPos pPos (id,(+)359,id)
keyForPos pPos (SpecialKey KeyRight)= modPos pPos (id,(+)1,id)
keyForPos pPos (SpecialKey KeyUp) = modPos pPos ((+)1,id,id)
keyForPos pPos (SpecialKey KeyDown) = modPos pPos ((+)359,id,id)
keyForPos _ _ = return ()
modPos pPos (ffst,fsnd,ftrd) = do
(alpha,beta,r) <- get pPos
pPos $= (ffst alpha `mod` 360,fsnd beta `mod` 360,ftrd r)
postRedisplay Nothing
reshape screenSize@(Size w h) = do
viewport $= ((Position 0 0), screenSize)
matrixMode $= Projection
loadIdentity
let near = 0.001
far = 40
fov = 90
ang = (fov*pi)/(360)
top = near / ( cos(ang) / sin(ang) )
aspect = fromIntegral(w)/fromIntegral(h)
right = top*aspect
frustum (-right) right (-top) top near far
matrixMode $= Modelview 0]]>
```

```
module ColorCube where
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import StateUtil
locally = preservingMatrix
colorCube n = do
locally $ do
currentColor $= Color4 1 0 0 1
translate$Vector3 0 0 (-n/2)
square n
locally $ do
currentColor $= Color4 0 1 0 1
translate$Vector3 0 0 (n/2)
square n
locally $ do
currentColor $= Color4 0 0 1 1
translate$Vector3 (n/2) 0 0
rotate 90 $Vector3 0 (1::GLfloat) 0
square n
locally $ do
currentColor $= Color4 1 1 0 1
translate$Vector3 (-n/2) 0 0
rotate 90 $Vector3 0 (1::GLfloat) 0
square n
locally $ do
currentColor $= Color4 0 1 1 1
translate$Vector3 0 (-n/2) 0
rotate 90 $Vector3 (1::GLfloat) 0 0
square n
locally $ do
currentColor $= Color4 1 1 1 1
translate$Vector3 0 (n/2) 0
rotate 90 $Vector3 (1::GLfloat) 0 0
square n
```

The following program allows to use the cursor keys to move around a
cube at the origin:
```
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT as GLUT
import Squares
import OrbitPointOfView
import StateUtil
import ColorCube
main = do
(progName,_) <- getArgsAndInitialize
initialDisplayMode $= [WithDepthBuffer,DoubleBuffered]
createWindow progName
depthFunc $= Just Less
```pPos <- new (90::Int,270::Int,2.0)
keyboardMouseCallback $= Just (keyboard pPos)
displayCallback $= display pPos
reshapeCallback $= Just reshape
mainLoop

The display function sets the viewer's position before rendering the
cube:
```
display pPos = do
loadIdentity
```setPointOfView pPos
clear [ColorBuffer,DepthBuffer]
colorCube 1
swapBuffers

As keyboard function we map directly to the function defined
in keyboard pPos c _ _ _ = keyForPos pPos c

An example how the colored cube can now be seen
is given in figure
A data type is provided for representation of a cube:
```
module RubikLogic where
data Rubik a
= Rubik (Front a) (Top a) (Back a) (Bottom a) (Left a) (Right a)
type Front a = Area a
type Top a = Area a
type Back a = Area a
type Bottom a = Area a
type Left a = Area a
type Right a = Area a
type Area a = [Row a]
type Row a = [a]
data AreaPosition = Front |Top| Back| Bottom| Left| Right
data RubikColor = Red|Blue|Yellow|Green|Orange|White|Black
```

We make the type `Rubik` an instance of the class `Functor`:
```
instance Functor Rubik where
fmap f (Rubik front top back bottom left right)
= Rubik (mf front) (mf top) (mf back)
(mf bottom) (mf left) (mf right)
where
mf = map (map f)
```

The initial cube is defined
```
initCube = Rubik (area Red) (area Blue) (area Yellow)
(area Green)(area Orange)(area White)
area c = [[c,c,c],[c,c,c],[c,c,c]]
```

The main operation on a cube is to turn one of its six sides. The
function `rotateArea` specifies, how this effects a cube.
```
rotateArea RubikLogic.Front
(Rubik front top back bottom left right) =
Rubik front' top' back bottom' left' right'
where
top' = newRow 3 (reverse$column 3 left) top
bottom' = newRow 1 (reverse$column 1 right) bottom
left' = newColumn 3 (row 1 bottom) left
right' = newColumn 1 (row 3 top) right
front' = rotateBy3 front
rotateArea RubikLogic.Back
(Rubik front top back bottom left right) =
Rubik front' top' back' bottom'
(rotateBy2 left') (rotateBy2 right')
where
(Rubik back' bottom' front' top' left' right') =
rotateArea RubikLogic.Front
(Rubik back bottom front top
(rotateBy2 left) (rotateBy2 right))
rotateArea RubikLogic.Bottom
(Rubik front top back bottom left right) =
Rubik front' top back' bottom' left' right'
where
back' = newRow 1 (reverse$row 3 left) back
front' = newRow 3 (row 3 right) front
left' = newRow 3 (row 3 front) left
right' = newRow 3 (reverse$row 1 back) right
bottom' = rotateBy1 bottom
rotateArea RubikLogic.Top
(Rubik front top back bottom left right) =
Rubik front' top' back' bottom left' right'
where
back' = newRow 3 (reverse$row 1 right) back
front' = newRow 1 (row 1 left) front
left' = newRow 1 (reverse$row 3 back) left
right' = newRow 1 (row 1 front) right
top' = rotateBy1 top
rotateArea RubikLogic.Left
(Rubik front top back bottom left right) =
Rubik front' top' back' bottom' left' right
where
top' = newColumn 1 (column 1 front) top
bottom' = newColumn 1 (column 1 back) bottom
left' = rotateBy3 left
back' = newColumn 1 (column 1 top) back
front' = newColumn 1 (column 1 bottom) front
rotateArea RubikLogic.Right
(Rubik front top back bottom left right) =
Rubik front' top' back' bottom' left right'
where
top' = newColumn 3 (column 3 back) top
bottom' = newColumn 3 (column 3 front) bottom
right' = rotateBy3 right
back' = newColumn 3 (column 3 bottom) back
front' = newColumn 3 (column 3 top) front
rotateBy1
[[x1,x2,x3]
,[x8,x,x4]
,[x7,x6,x5]] =
[[x3,x4,x5]
,[x2,x,x6]
,[x1,x8,x7]]
rotateBy2 = rotateBy1 .rotateBy1
rotateBy3 = rotateBy2 .rotateBy1
```

Finally some useful functions for manipulation of an area are given.
```
column n = map (\row->row !! (n-1))
row n area = area !!(n-1)
newRow 1 row [a,r,ea] = [row,r,ea]
newRow 2 row [a,r,ea] = [a,row,ea]
newRow 3 row [a,r,ea] = [a,r,row]
newColumn n column area = map (doIt n) areaC
where
areaC = zip area column
doIt 1 ((r:ow),c) = c:ow
doIt 2 ((r:o:w),c) = r:c:w
doIt 3 ((r:o:w:xs),c) = r:o:c:xs
```

```
The following function maps our abstract color type to concrete OpenGL
colors:
```

```
doColor Red = Color4 1 0 0 1.0
doColor Green = Color4 0 1 0 1.0
doColor Blue = Color4 0 0 1 1.0
doColor Yellow = Color4 1 1 0 1.0
doColor Orange = Color4 1 0.5 0.5 1
doColor White = Color4 1 1 1 1.0
doColor Black = Color4 0 0 0 1.0
```

The resulting window can be found in figure
A light source can be specified fairly easy. First you need to set the
state variable `lighting` to the value `Enabled`. Then
you need to specify the position of your light source. This can
be done by setting a special position state variable,
e.g.

`position (Light 0) $= Vertex4 0.8 0 3.0 5.0`.

And finally you need to turn the light source on by setting its state
variable to enabled: `light (Light 0) $= Enabled`.
```
The resulting window can be found in figure
```

```
The main display function clears the necessary buffers and calls the main
function for rendering the penguin Tux.
```

```
```

```
GLfloat -> GLfloat -> IO ()
scal x y z = scale x y z]]>
```

Furthermore some functions for easy translate and rotate transformations:
```
GLfloat -> GLfloat -> IO ()
transl x y z= translate$Vector3 x y z
rota:: GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
rota a x y z = rotate a $ Vector3 x y z
rotateZ a = rota a 0 0 1
rotateY a = rota a 0 1 0
rotateX a = rota a 1 0 0]]>
```

And eventually some functions to set the material properties for the different
parts of a penguin.
```
```

```
The resulting image can be found in figure
```

```
The resulting image for torso and shoulders
can be found in figure
```

```
```

```
```

```
```

```
The resulting image can be found in figure
```

```
```

```
The resulting window can be found in figure
```