今度は3次元の物体を描いてみます。とりあえず立方体。正射影しているため、何もしないと正面から見る形になって単なる正方形に見えてしまうので、rotateで回転してあります。
import Control.Monad import Graphics.Rendering.OpenGL import Graphics.UI.GLUT main = do (progName, _) <- getArgsAndInitialize createWindow "Window" clearColor $= Color4 1.0 1.0 1.0 0.0 displayCallback $= display reshapeCallback $= Just reshape mainLoop display = do clear [ColorBuffer] color $ (Color3 0.0 0.0 0.0 :: Color3 GLfloat) let points :: [(GLfloat, GLfloat, GLfloat)] points = [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 1.0), (1.0, 1.0, 1.0), (0.0, 1.0, 1.0)] edges :: [(Int, Int)] edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)] preservingMatrix $ do rotate 30 (Vector3 1.0 1.0 1.0 :: Vector3 GLfloat) renderPrimitive Lines $ forM_ edges $ \(s, e) -> do let (sx, sy, sz) = points !! s (ex, ey, ez) = points !! e vertex $ Vertex3 sx sy sz vertex $ Vertex3 ex ey ez flush reshape size@(Size w h) = do viewport $= (Position 0 0, size) matrixMode $= Projection loadIdentity ortho (-2.0) 2.0 (-2.0) 2.0 (-2.0) 2.0
orthoの代わりにperspectiveで視野角と見える範囲を指定すると、透視法射影になります。perspectiveはGLUのヘルパー関数ですが、GLとしてはfrustumで見える範囲を指定します。
視点の位置が原点にあるので、translateで移動するか、lookAtで視点を指定しないと何も見えなくなってしまいます。
reshape size@(Size w h) = do viewport $= (Position 0 0, size) matrixMode $= Projection loadIdentity perspective 30.0 (fromIntegral w / fromIntegral h) 1.0 100.0 lookAt (Vertex3 3.0 4.0 5.0) (Vertex3 0.0 0.0 0.0) (Vector3 0.0 1.0 0.0)