import Graphics.Rendering.OpenGL import Graphics.UI.GLUT import Data.IORef import System.Random import Data.List import Textures type Point = (Float,Float,Float) type MyQuad = (Point,Point,Point,Point,Int) makeLandscape :: Float->Float->[Float]->[MyQuad] makeLandscape width breadth rands = map (makeQuad pointList) $ zip buildList subRands where pointList = map (\((a,b),c)->(a,b,c)) $ zip [(x,y) | x<-[0.0 .. width],y<-[0.0 .. breadth]] rands buildList = [(x,y) | x<-[0.0 .. (width-1)],y<-[0.0 .. (breadth-1)]] subRands = drop (length pointList) rands makeQuad :: [Point]->((Float,Float),Float)->MyQuad makeQuad points ((x,y),t) | t< 0.25 = (tl,tr,br,bl,1) | otherwise = (tl,tr,br,bl,0) where innerFindPoint = findPoint points tl = innerFindPoint x y tr = innerFindPoint (x+1) y bl = innerFindPoint x (y+1) br = innerFindPoint (x+1) (y+1) findPoint :: [Point]->Float->Float->Point findPoint points x y | b == Nothing = (0,0,0) | otherwise = c where d = (\(m,n,o)->if m==x && n==y then True else False) b = find d points (Just c) = b main = do (progname, _) <- getArgsAndInitialize initialDisplayMode $= [WithDepthBuffer,DoubleBuffered,RGBAMode] createWindow "Hello World" gen <- getStdGen let ns = randomRs (0,2) gen :: [Float] let myMap = makeLandscape 30 30 ns notSure <- getAndCreateTextures ["rock","other"] depthFunc $= Just Less matrixMode $= Projection loadIdentity let near = 1 far = 40 right = 1 top = 1 frustum (-right) right (-top) top near far matrixMode $= Modelview 0 tme <- get elapsedTime lasttime <- newIORef(tme) frame <- newIORef(-1.0) idleCallback $= Just (idle lasttime) windowSize $= Size 800 500 lighting $= Enabled ambient (Light 0) $= Color4 1 1 1 1 diffuse (Light 0) $= Color4 1 1 1 1 light (Light 0) $= Enabled displayCallback $= (display notSure myMap frame) mainLoop idle :: IORef(Int) -> IO() idle lasttime = do lTime <- readIORef lasttime currenttime <- get elapsedTime case (currenttime - lTime >= 16) of True -> do writeIORef lasttime currenttime postRedisplay Nothing return () _ -> return () display :: [Maybe TextureObject]->[MyQuad]->IORef(Float) -> IO() display images landscape f = do frame <- readIORef f clear [ColorBuffer,DepthBuffer] texture Texture2D $= Enabled loadIdentity translate (Vector3 (-15) (-3) ((-43+frame)::GLfloat)) preservingMatrix $ do mapM (drawMyQuad images) landscape flush writeIORef f (frame+0.05) swapBuffers drawMyQuad :: [Maybe TextureObject]->MyQuad->IO() drawMyQuad texs (pa,pb,pc,pd,t) = do textureBinding Texture2D $= texs !! t let (pax,pay,paz) = pa let (pbx,pby,pbz) = pb let (pcx,pcy,pcz) = pc let (pdx,pdy,pdz) = pd renderPrimitive Quads $ makeVertices [(pax,paz,pay,0,0), (pbx,pbz,pby,0,1), (pcx,pcz,pcy,1,1), (pdx,pdz,pdy,1,0)] makeVertices ((x,y,z,tx,ty):[]) = do (texCoord (TexCoord2 (tx::GLfloat) ty)) (vertex (Vertex3 x y z)) makeVertices ((x,y,z,tx,ty):xs) = do (texCoord (TexCoord2 (tx::GLfloat) ty)) (vertex (Vertex3 (x::GLfloat) y z)) makeVertices xs