1
1
module Example9ST where
2
2
3
+ import Prelude
3
4
import Control.Monad.Eff.WebGL
4
5
import Graphics.WebGL
5
6
import Graphics.WebGLRaw
@@ -19,7 +20,7 @@ import Control.Monad.Eff
19
20
import Control.Monad.Eff.Random
20
21
import Control.Monad
21
22
import Control.Monad.ST
22
- import Debug.Trace
23
+ import Control.Monad.Eff.Console
23
24
import Data.Tuple
24
25
import Data.Foldable (for_ )
25
26
import Data.Date
@@ -28,11 +29,13 @@ import Data.Maybe
28
29
import Data.Maybe.Unsafe (fromJust )
29
30
import Data.Array
30
31
import Data.Array.ST
31
- import Math
32
- import Prelude.Unsafe (unsafeIndex )
32
+ import Math hiding (log )
33
+ import Data.Int (toNumber )
34
+ import KeyEvent
35
+ import Data.Array.Unsafe (unsafeIndex )
33
36
34
37
35
- starCount = 50 :: Number
38
+ starCount = 50 :: Int
36
39
spinStep = 0.1 :: Number
37
40
38
41
type MyBindings =
@@ -83,13 +86,13 @@ type State bindings = {
83
86
starVertices :: Buffer T.Float32 ,
84
87
textureCoords :: Buffer T.Float32 ,
85
88
texture :: WebGLTex ,
86
- lastTime :: Maybe Number ,
89
+ lastTime :: Maybe Int ,
87
90
88
- stars :: [ Star ] ,
91
+ stars :: Array Star ,
89
92
spin :: Number ,
90
93
tilt :: Number ,
91
94
z :: Number ,
92
- currentlyPressedKeys :: [ Number ]
95
+ currentlyPressedKeys :: Array Int
93
96
}
94
97
95
98
vertices = [
@@ -125,15 +128,15 @@ type Star =
125
128
-- Star methods
126
129
starDefault :: Number -> Number -> Star
127
130
starDefault startDist rotSpeed =
128
- { angle : 0
131
+ { angle : 0.0
129
132
, dist : startDist
130
133
, rotationSpeed : rotSpeed
131
- , r : 0
132
- , g : 0
133
- , b : 0
134
- , twinkleR : 0
135
- , twinkleG : 0
136
- , twinkleB : 0
134
+ , r : 0.0
135
+ , g : 0.0
136
+ , b : 0.0
137
+ , twinkleR : 0.0
138
+ , twinkleG : 0.0
139
+ , twinkleB : 0.0
137
140
}
138
141
139
142
starCreate x y =
@@ -150,7 +153,7 @@ starRandomiseColors star = do
150
153
, twinkleB = colors `unsafeIndex` 5
151
154
}
152
155
153
- starAnimate :: forall eff . Number -> Star -> EffWebGL (random :: Random |eff ) Star
156
+ starAnimate :: forall eff . Int -> Star -> EffWebGL (random :: RANDOM |eff ) Star
154
157
starAnimate elapsedTime star = do
155
158
let
156
159
star' = star
@@ -161,39 +164,39 @@ starAnimate elapsedTime star = do
161
164
then starRandomiseColors star' {dist = star'.dist + 5.0 }
162
165
else return star'
163
166
where
164
- step = (elapsedTime * 60 ) / 1000
167
+ step = (toNumber elapsedTime * 60.0 ) / 1000.0
165
168
166
169
starDraw :: forall h eff . State MyBindings -> Boolean -> M.STMat4 h -> Tuple Star Number -> EffWebGL (st :: ST h |eff ) Unit
167
170
starDraw s twinkle mvMatrix (Tuple star mySpin) = do
168
171
mv <- M .cloneSTMat mvMatrix
169
- M .rotateST (degToRad star.angle) (V .vec3' [0 , 1 , 0 ]) mv
170
- M .translateST (V .vec3 star.dist 0 0 ) mv
171
- M .rotateST (degToRad $ negate star.angle) (V .vec3' [0 , 1 , 0 ]) mv
172
- M .rotateST (degToRad $ negate s.tilt) (V .vec3' [1 , 0 , 0 ]) mv
172
+ M .rotateST (degToRad star.angle) (V .vec3' [0.1 , 1.0 , 0. 0 ]) mv
173
+ M .translateST (V .vec3 star.dist 0.0 0. 0 ) mv
174
+ M .rotateST (degToRad $ negate star.angle) (V .vec3' [0.0 , 1.0 , 0. 0 ]) mv
175
+ M .rotateST (degToRad $ negate s.tilt) (V .vec3' [1.0 , 0.0 , 0. 0 ]) mv
173
176
174
177
when twinkle $ do
175
178
setUniformFloats s.bindings.uColor [star.twinkleR, star.twinkleG, star.twinkleB]
176
179
drawStar s mv
177
180
178
- M .rotateST (degToRad mySpin) (V .vec3' [0 , 0 , 1 ]) mv
181
+ M .rotateST (degToRad mySpin) (V .vec3' [0.0 , 0.0 , 1.0 ]) mv
179
182
setUniformFloats s.bindings.uColor [star.r, star.g, star.b]
180
183
drawStar s mv
181
184
182
185
183
- main :: Eff (trace :: Trace , alert :: Alert , now :: Now , random :: Random ) Unit
186
+ main :: Eff (console :: CONSOLE , alert :: Alert , now :: Now , random :: RANDOM ) Unit
184
187
main = do
185
188
runWebGL
186
189
" glcanvas"
187
190
(\s -> alert s)
188
191
\ context -> do
189
- trace " WebGL started"
192
+ log " WebGL started"
190
193
withShaders
191
194
shaders
192
195
(\s -> alert s)
193
196
\ bindings -> do
194
197
vs <- makeBufferFloat vertices
195
198
textureCoords <- makeBufferFloat texCoo
196
- let starParams i = Tuple ((i / starCount) * 5.0 ) (i / starCount)
199
+ let starParams i = Tuple ((toNumber i / toNumber starCount) * 5.0 ) (toNumber i / toNumber starCount)
197
200
ss <- mapM (uncurry starCreate <<< starParams) (0 .. (starCount-1 ))
198
201
clearColor 0.0 0.0 0.0 1.0
199
202
texture2DFor " star.gif" MIPMAP \texture -> do
@@ -218,17 +221,17 @@ main = do
218
221
onKeyUp (handleKeyU stRef)
219
222
tick (stRef :: STRef _ (State MyBindings ))
220
223
221
- tick :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (st :: ST h , trace :: Trace , now :: Now , random :: Random |eff ) Unit
224
+ tick :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (st :: ST h , console :: CONSOLE , now :: Now , random :: RANDOM |eff ) Unit
222
225
tick stRef = do
223
226
drawScene stRef
224
227
handleKeys stRef
225
228
animate stRef
226
229
requestAnimationFrame (tick stRef)
227
230
228
- unpackMilliseconds :: Milliseconds -> Number
231
+ unpackMilliseconds :: Milliseconds -> Int
229
232
unpackMilliseconds (Milliseconds n) = n
230
233
231
- animate :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (st :: ST h , now :: Now , random :: Random |eff ) Unit
234
+ animate :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (st :: ST h , now :: Now , random :: RANDOM |eff ) Unit
232
235
animate stRef = do
233
236
s <- readSTRef stRef
234
237
timeNow <- liftM1 (unpackMilliseconds <<< toEpochMilliseconds) now
@@ -237,7 +240,7 @@ animate stRef = do
237
240
Just lastt ->
238
241
let
239
242
elapsed = timeNow - lastt
240
- spin' = s.spin + (spinStep * length s.stars)
243
+ spin' = s.spin + (spinStep * toNumber ( length s.stars) )
241
244
in do
242
245
stars' <- mapM (starAnimate elapsed) s.stars
243
246
writeSTRef stRef (s {lastTime = Just timeNow, spin=spin', stars=stars'})
@@ -259,7 +262,7 @@ drawScene stRef = do
259
262
withTexture2D s.texture 0 s.bindings.uSampler 0
260
263
261
264
let
262
- pMatrix = M .makePerspective 45 ( canvasWidth / canvasHeight) 0.1 100.0
265
+ pMatrix = M .makePerspective 45.0 (toNumber canvasWidth / toNumber canvasHeight) 0.1 100.0
263
266
ss = zip s.stars (iterateN (+spinStep) (length s.stars) s.spin)
264
267
265
268
setUniformFloats s.bindings.uPMatrix (M .toArray pMatrix)
@@ -271,7 +274,7 @@ initialMVMatrix :: forall h r. Number -> Number -> Eff (st :: ST h | r) (M.STMat
271
274
initialMVMatrix tilt zoom = do
272
275
m <- M .identityST
273
276
M .translateST (V .vec3' [0.0 , 0.0 , zoom]) m
274
- M .rotateST (degToRad tilt) V .i m
277
+ M .rotateST (degToRad tilt) V .i3 m
275
278
return m
276
279
277
280
drawStar s (M.STMat mvMatrix) = do
@@ -280,112 +283,69 @@ drawStar s (M.STMat mvMatrix) = do
280
283
281
284
282
285
-- | collects results of repeated function application, up to n times
283
- iterateN :: forall a . (a -> a ) -> Number -> a -> [ a ] -- pfff... I miss Haskell's laziness...
286
+ iterateN :: forall a . (a -> a ) -> Int -> a -> Array a
284
287
iterateN f = iterate' []
285
288
where
286
289
iterate' res 0 _ = reverse res
287
290
iterate' res n x = iterate' (x:res) (n-1 ) (f x)
288
291
289
292
290
- foreign import getElementByIdFloat
291
- """
292
- function getElementByIdFloat(targ_id) {
293
- return function () {
294
- return parseFloat(document.getElementById(targ_id).value);
295
- };
296
- }
297
- """ :: forall eff . String -> (EffWebGL eff Number )
298
-
299
- foreign import getElementByIdBool
300
- """
301
- function getElementByIdBool(targ_id) {
302
- return function () {
303
- return document.getElementById(targ_id).checked;
304
- };
305
- }
306
- """ :: forall eff . String -> (EffWebGL eff Boolean )
307
-
308
293
-- | Convert from radians to degrees.
309
294
radToDeg :: Number -> Number
310
- radToDeg x = x/pi*180
295
+ radToDeg x = x/pi*180.0
311
296
312
297
-- | Convert from degrees to radians.
313
298
degToRad :: Number -> Number
314
- degToRad x = x/180 *pi
299
+ degToRad x = x/180.0 *pi
315
300
316
301
317
302
-- * Key handling
318
303
319
- handleKeys :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (trace :: Trace , st :: ST h |eff ) Unit
304
+ -- * Key handling
305
+
306
+ handleKeys :: forall h eff . STRef h (State MyBindings ) -> EffWebGL (console :: CONSOLE , st :: ST h |eff ) Unit
320
307
handleKeys stRef = do
321
308
s <- readSTRef stRef
322
309
if null s.currentlyPressedKeys
323
310
then return unit
324
311
else
325
- let z' = if elemIndex 33 s.currentlyPressedKeys /= - 1
326
- then s.z - 0.1
327
- else s.z
328
- z'' = if elemIndex 34 s.currentlyPressedKeys /= - 1
329
- then z' + 0.1
330
- else z'
331
- tilt' = if elemIndex 38 s.currentlyPressedKeys /= - 1
332
- then s.tilt - 2
333
- else s.tilt
334
- tilt'' = if elemIndex 40 s.currentlyPressedKeys /= - 1
335
- then tilt' + 2
336
- else tilt'
312
+ let z' = case elemIndex 33 s.currentlyPressedKeys of
313
+ Just _ -> s.z - 0.1
314
+ Nothing -> s.z
315
+ z'' = case elemIndex 34 s.currentlyPressedKeys of
316
+ Just _ -> z' + 0.1
317
+ Nothing -> z'
318
+ tilt' = case elemIndex 38 s.currentlyPressedKeys of
319
+ Just _ -> s.tilt - 2.0
320
+ Nothing -> s.tilt
321
+ tilt'' = case elemIndex 40 s.currentlyPressedKeys of
322
+ Just _ -> tilt' + 2.0
323
+ Nothing -> tilt'
337
324
in do
338
325
writeSTRef stRef (s{z=z'',tilt=tilt''})
339
- -- trace (show s.currentlyPressedKeys)
326
+ -- log (show s.currentlyPressedKeys)
340
327
return unit
341
328
342
- handleKeyD :: forall h eff . STRef h (State MyBindings ) -> Event -> Eff (st :: ST h , trace :: Trace | eff ) Unit
329
+ handleKeyD :: forall h eff . STRef h (State MyBindings ) -> Event -> Eff (st :: ST h , console :: CONSOLE | eff ) Unit
343
330
handleKeyD stRef event = do
344
- -- trace "handleKeyDown"
331
+ -- log "handleKeyDown"
345
332
let key = eventGetKeyCode event
346
333
s <- readSTRef stRef
347
- let cp = if elemIndex key s.currentlyPressedKeys /= - 1
348
- then s.currentlyPressedKeys
349
- else key : s.currentlyPressedKeys
334
+ let cp = case elemIndex key s.currentlyPressedKeys of
335
+ Just _ -> s.currentlyPressedKeys
336
+ Nothing -> key : s.currentlyPressedKeys
350
337
writeSTRef stRef (s {currentlyPressedKeys = cp})
351
- -- trace (show s.currentlyPressedKeys)
338
+ -- log (show s.currentlyPressedKeys)
352
339
return unit
353
340
354
- handleKeyU :: forall h eff . STRef h (State MyBindings ) -> Event -> Eff (st :: ST h , trace :: Trace | eff ) Unit
341
+ handleKeyU :: forall h eff . STRef h (State MyBindings ) -> Event -> Eff (st :: ST h , console :: CONSOLE | eff ) Unit
355
342
handleKeyU stRef event = do
356
- -- trace "handleKeyUp"
343
+ -- log "handleKeyUp"
357
344
let key = eventGetKeyCode event
358
345
s <- readSTRef stRef
359
- if elemIndex key s.currentlyPressedKeys == - 1
360
- then return unit
361
- else do
346
+ case elemIndex key s.currentlyPressedKeys of
347
+ Nothing -> return unit
348
+ Just _ -> do
362
349
writeSTRef stRef (s {currentlyPressedKeys = delete key s.currentlyPressedKeys})
363
- -- trace (show s.currentlyPressedKeys)
350
+ -- log (show s.currentlyPressedKeys)
364
351
return unit
365
-
366
- foreign import data Event :: *
367
-
368
- foreign import onKeyDown
369
- """
370
- function onKeyDown(handleKeyDown) {
371
- return function() {
372
- document.onkeydown = function(event) {handleKeyDown(event)()};
373
- };}
374
- """ :: forall eff . (Event -> Eff (webgl :: WebGl | eff ) Unit )
375
- -> Eff (webgl :: WebGl | eff ) Unit
376
-
377
- foreign import onKeyUp
378
- """
379
- function onKeyUp(handleKeyUp) {
380
- return function() {
381
- document.onkeyup = function(event) {handleKeyUp(event)()};
382
- };}
383
- """ :: forall eff . (Event -> Eff (webgl :: WebGl | eff ) Unit )
384
- -> Eff (webgl :: WebGl | eff ) Unit
385
-
386
- foreign import eventGetKeyCode
387
- """
388
- function eventGetKeyCode (event) {
389
- return (event.keyCode);
390
- }
391
- """ :: Event -> Number
0 commit comments