背景色を指定するには、clearColorを指定します。さらに、displayCallbackで指定した関数の中で、背景を塗りつぶした後でflushを呼び出さないとバッファが更新されないようです。
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
main =
do (progName, _) <- getArgsAndInitialize
createWindow "Hello World"
clearColor $= Color4 0.0 0.0 1.0 0.0
displayCallback $= display
mainLoop
display =
do clear [ColorBuffer]
flush
しかし、どこからどう見てもHaskellらしくない。
displayCallbackやclearColorの指定などがグローバルに行われるので、複数のウィンドウをどうやって扱えるのか疑問だったのですが、どうやら最後にcreateWindowしたウィンドウに対して操作することになるようです。
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
main =
do (progName, _) <- getArgsAndInitialize
createWindow "First Window"
clearColor $= Color4 0.0 0.0 1.0 0.0
displayCallback $= display
createWindow "Second Window"
clearColor $= Color4 1.0 0.0 0.0 0.0
displayCallback $= display
actionOnWindowClose $= ContinueExectuion
mainLoop
display =
do clear [ColorBuffer]
flush
actionOnWindowCloseにContinueExectuion*1を指定すると、最後のウィンドウが閉じてからmainLoopが終了するようになります。デフォルトだとExitになっていて、最初のウィンドウを閉じるとmainLoopが終了してプロセスが終了してしまいます。
グローバルなステートがありすぎて、ますますHaskellっぽくなくなっていきます。
*1 ライブラリ自体にtypoがあります
前置きはこれくらいにして、実際に絵を描いてみることにします。とりあえず、線を描いてみます。
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
main =
do (progName, _) <- getArgsAndInitialize
createWindow "Window"
clearColor $= Color4 0.0 0.0 1.0 0.0
displayCallback $= display
mainLoop
display =
do clear [ColorBuffer]
color $ (Color3 1.0 0.0 0.0 :: Color3 GLfloat)
let points :: [(GLfloat, GLfloat)]
points = [(0.9, 0.9), (0.9, -0.9), (-0.9, -0.9), (-0.9, 0.9)]
renderPrimitive LineLoop $
mapM_ (vertex . uncurry Vertex2) points
flush

色を指定するには、colorを使います。描画するコード自体は、renderPrimitiveの中で行います。renderPrimitiveは、最初にglBeginを、最後にglEndを呼び出してくれるラッパーみたいなものですね。