This file lists the programs that are referenced in the OpenGL Programming Guide, Fourth Edition, by chapter. For each program, the version of OpenGL that is required is listed with the program. Chapter 1: Introduction to OpenGL Hello.hs (1.0) Double.hs (1.0) Chapter 2: State Management and Drawing Geometric Objects Lines.hs (1.0) Polys.hs (1.0) VArray.hs (1.1) MVArray.hs (1.4) Chapter 3: Viewing Cube.hs (1.0) Model.hs (1.0) Clip.hs (1.0) Planet.hs (1.0) Robot.hs (1.0) UnProject.hs (1.1) Chapter 4: Color Smooth.hs (1.0) Chapter 5: Lighting Light.hs (1.0) MoveLight.hs (1.0) Material.hs (1.0) ColorMat.hs (1.1) Scene.hs (1.0) Chapter 6: Blending, Antialiasing, Fog, and Polygon Offset BlendEqn.hs (1.3 or ARB_imaging_subset) Alpha.hs (1.0) Alpha3D.hs (1.1) AARGB.hs (1.1) AAIndex.hs (1.1) Multisamp.hs (1.3) Fog.hs (1.0) FogIndex.hs (1.0) FogCoord.hs (1.4) PointP.hs (1.4) PolyOff.hs (1.1) Chapter 7: Display Lists Torus.hs (1.0) DList.hs (1.0) Stroke.hs (1.0) Chapter 8: Drawing Pixels, Bitmaps, Fonts, and Images DrawF.hs (1.0) Font.hs (1.0) Image.hs (1.1) ColorTable.hs (ARB_imaging_subset) Convolution.hs (ARB_imaging_subset) ColorMatrix.hs (ARB_imaging_subset) Histogram.hs (ARB_imaging_subset) Minmax.hs (ARB_imaging_subset) Chapter 9: Texture Mapping Checker.hs (1.0) TexSub.hs (1.1) Texture3D.hs (1.2) Mipmap.hs (1.0) TexBind.hs (1.1) TexGen.hs (1.1) CubeMap.hs (1.3) MultiTex.hs (1.3 or ARB_multitexture) Combiner.hs (1.3) ShadowMap.hs (1.4) Wrap.hs (1.0) TexProx.hs (1.1) Chapter 10: The Framebuffer Stencil.hs (1.0) AccPersp.hs (1.0) AccAnti.hs (1.0) DOF.hs (1.0) Chapter 11: Tessellators and Quadrics Tess.hs (1.1) TessWind.hs (1.1) Quadric.hs (1.1) Chapter 12: Evaluators and NURBS BezCurve.hs (1.1) BezSurf.hs (1.1) BezMesh.hs (1.1) TextureSurf.hs (1.1) Surface.hs (1.1) SurfPoints.hs (1.2) Trim.hs (1.1) Chapter 13: Selection and Feedback Select.hs (1.1) PickSquare.hs (1.0) PickDepth.hs (1.0) Feedback.hs (1.0) Chapter 14: Now That You Know Color Plates: Teapots.hs (1.1) Some remarks regarding the style of the programs: To ease comparisons, the Haskell programs in this directory try to stay as close to the original examples in C as possible. Consequently, they should not be considered as examples for the best way to implement things in Haskell. The Haskell OpenGL binding uses overloading quite extensively, which makes its use quite flexible, e.g.: class Vertex a where vertex :: a -> IO () vertexv :: Ptr a -> IO () This single class subsumes all 24 vertex specification calls in OpenGL's C binding, i.e. glVertex{234}{sifd}[v](), with the help of the following class and instances: class VertexComponent a -- an opaque class VertexComponent GLshort VertexComponent GLint VertexComponent GLfloat VertexComponent GLdouble VertexComponent a => Vertex (Vertex2 a) VertexComponent a => Vertex (Vertex3 a) VertexComponent a => Vertex (Vertex4 a) There is a small inconvenience with this when used in "toy" programs: Haskell's numeric literals are overloaded, too, so the programmer's help is needed to disambiguate the type of expressions like: vertex (Vertex3 0 0 1) Let's assume we mean the equivalent of glVertex3f() here. One can either use an explicitly typed helper function: let vertex3f = vertex :: Vertex3 GLfloat -> IO () in vertex3f (Vertex3 0 0 1) This comes in handy when there are a lot of uses of vertex3f. An alternative is to use a type annotation for the literal: vertex (Vertex3 0 0 (1 :: GLfloat)) or a type annotation for the vertex: vertex (Vertex3 0 0 1 :: Vertex3 GLfloat) This is largely a matter of taste and normally not a problem in "real" programs with type signatures for functions. Sometimes different callbacks need to share some state, which is done via global variables in the C examples. To achieve a unified presentation, all Haskell examples use a `State' type for this purpose, which collects the different parts of the global state, i.e. one or more IORefs. There are alternatives for modeling this, which should be considered in own programs, depending on the use cases: * Separate IORefs: This makes it explicit which parts of the program need which parts of the state. * A single IORef/MVar containing all the state: This enables one to change the whole state atomically, which is often quite handy in multithreaded programs. * A custom monad: This can hide all the state threading behind the scenes.