OpenGL
References
- Hackage hosts the individual OpenGL binding packages, including their latest API documentation:
- OpenGLRaw contains a low-level wrapper around OpenGL, which is basically a 1:1 mapping of the C API.
- GLURaw is similar to OpenGLRaw, just for the GLU part of OpenGL.
- OpenGL is the high-level view on OpenGL, wrapping OpenGLRaw into something more Haskell-like.
- GLUT is a binding for the OpenGL Utility Toolkit.
- The HOpenGL mailing list can be used for all discussions regarding the use of OpenGL from Haskell.
- GitHub hosts the haskell-opengl organization for Haskell OpenGL development.
The examples directory in the GLUT package contains lots of examples, including translations of the Red Book examples. Both the API documentation and theses examples are best studied with the original specs and the original Red Book examples at hand. An index of examples can be found at the OpenGL wiki page Code Resources.
Projects using the OpenGL bindings
- Haskell-GLSL-eDSL, A GLSL code generating DSL embedded in Haskell
- plissken, a 3D version of snake
- Endless Cavern, a 2D procedurally-generated exploration game.
- Frag, a 3D first-person shooter game.
- Monadius, a 2D scrolling arcade game.
- Roguestar, a roguelike adventure game using 3D graphics.
- Shu-thing, a 2D scrolling arcade game.
- Topkata, a jumping ball puzzle game.
- PolyFunViz, a toolkit for scientific visualization (e.g. surfaces, flows, contours, volumes)
- Raincat, a 2d puzzle game
- Gloss, hides the pain of drawing simple vector graphics behind a nice data type and a few display functions
See also the reverse dependencies list on haskellers.com
HOpenGL Resources
- OpenGLTutorial1 and OpenGLTutorial2
- Beautiful Code, Compelling Evidence: Functional Programming for Information Visualization and Visual Analytics - Writing visualizations using OpenGL or Cairo (PDF)
- Andre Furtado's nice tutorial written in 2001 (bitrotted)
OpenGL Resources
- OpenGL FAQ and Troubleshooting Guide (PDF) Assumes some knowledge of OpenGL. Good for those who have written something but want to avoid common pitfalls.
Getting Started
- use the Haskell port (Hackage package) of the NeHe Tutorials
- read the Haskell OpenGL Tutorial on GitHub
- use the (in progress) Haskell port of the OpenGL Wikibook, using the modern programmable pipeline
- assuming you know Haskell, any OpenGL tutorial of your choice should get you going (browsing the OpenGL site is also a good idea)
- use the Red Book, and its example code translations, to understand the small differences between OpenGL and HOpenGL
- use the OpenGL and GLUT specs to find your way around the HOpenGL Haddock documentation
- use the HOpenGL list for questions and success stories
Additional software
- FTGL: Portable TrueType font rendering for OpenGL using the Freetype2 library
- GLFW: A binding for GLFW, An OpenGL Framework
- GLUtil: Miscellaneous OpenGL utilities
- vinyl-gl: Utilities for working with OpenGL's GLSL shading language and vinyl records
- graphics-drawingcombinators: A functional interface to 2D drawing in OpenGL
- GPipe: A functional graphics API for programmable GPUs
- LambdaCube 3D: domain specific language and library that makes it possible to program GPUs in a purely functional style
- The freetype2 package; bindings to FreeType, a software font engine
Somewhat related is SDL, which is based on OpenGL:
- SDL: Binding to libSDL
- SDL-gfx: Binding to libSDL_gfx
- SDL-image: Binding to libSDL_image
- SDL-mixer: Binding to libSDL_mixer
- SDL-mpeg: Binding to the SMPEG library
- SDL-ttf: Binding to libSDL_ttf
To add sound to OpenGL applications:
- OpenAL: A binding to the OpenAL cross-platform 3D audio API
- ALUT: A binding for the OpenAL Utility Toolkit
A fork of HOpenGL:
Experiments with raw bindings to GLFW/OpenGL produced with HSFFIG
Troubleshooting
I can't display text with renderString
It's probably because the text is displayed too big. Setting a much smaller scale factor before calling renderString should solve the problem.
scale 0.001 0.001 (0.001∷GLfloat)
renderString Roman "Test string"
Animations flicker
If you're not using DoubleBuffered display mode, turn that on. Also, you must set the display mode before creating the window you're going to be drawing in. To check if you've enabled double buffering use something like:
db <- get doubleBuffered
and set DoubleBuffered mode (before creating your windows!) like this:
initialDisplayMode $= [DoubleBuffered]
createWindow "My Window"
swapBuffers
The depth buffer doesn't work (things that are closer to the camera are occluded by things that are farther from the camera)
Make sure that depthFunc is set:
depthFunc $= Just Less
Furthermore, if you're using GLFW, the following var has to be greater than zero:
get (windowParam DepthBits)
If DepthBits is 0, you probably forgot set it before the call to createWindow, like so:
windowHint WindowHint'DepthBits 16
Once you enable the depth buffer, you will need to clear it before each cycle of your drawing method:
clear [ColorBuffer, DepthBuffer]
See also: The OpenGL FAQ: 12.010 How do I make depth buffering work?