forked from KyleCotton/CodingChallenge
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRendering2D.hs
More file actions
108 lines (94 loc) · 3.66 KB
/
Rendering2D.hs
File metadata and controls
108 lines (94 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
module Rendering2D where
import Data.List
import Test.QuickCheck
import Graphics.UI.GLUT hiding (Matrix, Angle)
import Data.IORef
import Control.Concurrent
import Game2D
type Matrix = [[GLfloat]]
type Vector = [GLfloat]
type Point = (GLfloat, GLfloat)
type Angle = GLfloat
gridWidth :: Float
gridWidth = 100
gridHight :: Float
gridHight = 100
--takes in a size and a point and creates a square of the given size at that point
makeSquare :: GLfloat -> Point -> [Point]
--creates a square of the given size at the origin then moves it to the point
makeSquare size center = moveSquare byOrigin center
where
--moves a square by adding the values of the point to each point
moveSquare xs (x, y)= [((x + x'), (y + y'))| (x', y') <- xs]
--creates a square around the origin
byOrigin = [(radius', radius'), (-radius', radius'), (-radius', -radius'), (radius', -radius')]
radius' = (size/ 2)
--takes in a list of points with values from 0 to 100 and 'maps' them from -1 to 1
mapPoints :: [Point] -> [Point]
mapPoints lst = [(((x-xOffset)/xOffset)+(1/gridWidth), -(((y-yOffset)/yOffset) + (1/gridWidth))) | (y,x)<-lst]
where
xOffset = (gridWidth/2)
yOffset = (gridHight/2)
--takes a list of points and returns a list of squares (list of four points) for each point
makeSquares :: [Point] -> [Point]
makeSquares lst = concat [makeSquare (2/gridWidth) point | point<-lst]
numOfGens :: Int
numOfGens = 30
--gets all generations that will be used of a given grid
gens :: [Grid]
gens = [x | x <- (nIterations numOfGens theOtherGrid), x /= []]
--rus the 2d game of life
maindraw :: IO ()
maindraw = do
generation <- newIORef 0
run <- newIORef True
--displays points
displayCallback $= (display gens generation)
--checks wheter to change generation by looking at user input
keyboardMouseCallback $= Just (keyboardMouse run)
--chages to the next generation
idleCallback $= Just (idle run generation)
mainLoop
--if the user presses the space bar, change the next generation 'flag' to false
keyboardMouse :: IORef Bool -> KeyboardMouseCallback
--if a key is pressed
keyboardMouse run key Down _ _ = do
run' <- readIORef run
--if that key is the spacebar invert the vlaue of the next generation 'flag' otherwise do nothing
if key == (Char ' ') then (writeIORef run (not run')) else return ()
--if no key is pressed do nothing
keyboardMouse _ _ _ _ _ = return ()
reshape :: ReshapeCallback
reshape size = do
viewport $= (Position 0 0, size)
postRedisplay Nothing
--displays the points as a loop
display :: [Grid] -> IORef Int -> DisplayCallback
display population generation = do
--helper function that creates a color
let color3f r g b = color $ Color3 r g (b :: GLfloat)
--clears the color buffer
clear [ ColorBuffer ]
gen <- readIORef generation
--renders groups of four vertexs as squares
renderPrimitive Quads $ do
--sets the colour to green
color3f 0 1 0
--gets the current generation and converts it too squares, then draws those squares
mapM_ (\(x, y) -> vertex $ Vertex2 x y) (makeSquares . mapPoints $ gridToLivingPoints (population !! gen))
flush
--limits the frame rate
threadDelay (200000)
--tells the double buffer to update
swapBuffers
--changes the current generation by 1
idle :: IORef Bool -> IORef Int -> IdleCallback
idle run gen = do
gen' <- readIORef gen
run' <- readIORef run
--if the next generation 'flag' is true then move to the next generation otherwise do nothing
if run' then writeIORef gen (nextGen gen') else return ()
postRedisplay Nothing
where
--moves to the next generation then when it gets to the last generation it goes back to the start
nextGen curGen = (curGen + 1) `mod` (length gens-1)