@@ -5,72 +5,77 @@ import MJS (V3,M4x4,v3,makeRotate,makePerspective,makeLookAt,mul)
5import Graphics.WebGL (Triangle, zipTriangle, Shader, Model, model, webgl)
5import Graphics.WebGL (Triangle, zipTriangle, Shader, Model, model, webgl)
6import Window(dimensions)
6import Window(dimensions)
8−-- Define what our geometry looks like
8+-- Create a cube in which each point has a color
10−p0 = v3 1 1 1
10+type ColorPoint = { color:V3, point:V3 }
12−p2 = v3 -1 -1 1
12+face : Color -> V3 -> V3 -> V3 -> V3 -> [Triangle ColorPoint]
13−p3 = v3 1 -1 1
13+face color a b c d =
19−front = [(p0,p1,p2),(p2,p3,p0)]
20−back = [(p5,p6,p7),(p7,p4,p5)]
21−right = [(p0,p3,p4),(p4,p5,p0)]
22−left = [(p1,p2,p7),(p7,p6,p1)]
23−top = [(p0,p5,p6),(p6,p1,p0)]
24−bottom = [(p3,p4,p7),(p7,p2,p3)]
26−positions = front ++ back ++ right ++ left ++ top ++ bottom
28−toV3 color =
14+ let toV3 color =
29− let c = toRgb color
15+ let c = toRgb color
30− in v3 (toFloat c.red / 255) (toFloat c.green / 255) (toFloat c.blue / 255)
16+ in v3 (toFloat c.red / 255) (toFloat c.green / 255) (toFloat c.blue / 255)
31−
17+ p = ColorPoint (toV3 color)
19+ [ (p a, p b, p c), (p c, p d, p a) ]
32−colors : [Triangle V3]
21+cube : [Triangle ColorPoint]
34− concatMap (\c' -> let c = toV3 c' in repeat 2 (c,c,c))
23+ let rft = v3 1 1 1 -- right, front, top
35− [gray,red,green,blue,yellow,purple]
24+ lft = v3 -1 1 1 -- left, front, top
37−mesh : [Triangle {pos : V3, color : V3}]
26+ rbt = v3 1 -1 1
38−mesh = zipWith (zipTriangle (\pos color -> { pos = pos, color = color })) positions colors
27+ rbb = v3 1 -1 -1
40−per : M4x4
29+ lfb = v3 -1 1 -1
41−per = makePerspective 45 1 0.01 100
30+ lbb = v3 -1 -1 -1
43−cam : M4x4
32+ concat [ face green rft rfb rbb rbt -- right
44−cam = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
33+ , face blue rft rfb lfb lft -- front
34+ , face purple lft lfb lbb lbt -- left
35+ , face orange rbt rbb lbb lbt -- back
41+main = webgl (400,400) <~ lift scene angle
46angle : Signal Float
43angle : Signal Float
47−angle = foldp (\dt theta -> theta + dt / 10000) 0 (fps 25)
44+angle = foldp (\dt theta -> theta + dt / 5000) 0 (fps 25)
49−rot : Signal { rot : M4x4, per : M4x4, cam : M4x4, shade : Float }
46+scene : Float -> [Model]
50−rot = (\t -> { rot = mul (makeRotate (3*t) (v3 0 1 0)) (makeRotate (2*t) (v3 1 0 0)), per = per, cam = cam, shade = 0.8 }) <~ angle
47+scene angle =
48+ [ model vertexShader fragmentShader cube (uniforms angle) ]
52−draw : Signal [Model]
50+uniforms : Float -> { rotation:M4x4, perspective:M4x4, camera:M4x4, shade:Float }
53−draw = combine [ model vertexShader fragmentShader mesh <~ rot ]
51+uniforms t =
52+ { rotation = mul (makeRotate (3*t) (v3 0 1 0)) (makeRotate (2*t) (v3 1 0 0))
53+ , perspective = makePerspective 45 1 0.01 100
54+ , camera = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
55−main = webgl <~ dimensions ~ draw
58+-- Shaders
57−vertexShader : Shader {a | pos : V3, color : V3} {b | rot : M4x4, per : M4x4, cam : M4x4} {vcolor : V3}
60+vertexShader : Shader { attr | point:V3, color:V3 }
61+ { unif | rotation:M4x4, perspective:M4x4, camera:M4x4 }
58vertexShader = [glShader|
63vertexShader = [glShader|
60−attribute vec3 pos;
65+attribute vec3 point;
61attribute vec3 color;
66attribute vec3 color;
62−uniform mat4 per;
67+uniform mat4 perspective;
63−uniform mat4 cam;
68+uniform mat4 camera;
64−uniform mat4 rot;
69+uniform mat4 rotation;
65varying vec3 vcolor;
70varying vec3 vcolor;
66void main () {
71void main () {
67− gl_Position = per * cam * rot * vec4(pos, 1.0);
72+ gl_Position = perspective * camera * rotation * vec4(point, 1.0);
68 vcolor = color;
73 vcolor = color;
73−fragmentShader : Shader {} {b | shade : Float} {vcolor : V3}
78+fragmentShader : Shader {} {u | shade : Float} {vcolor : V3}
74fragmentShader = [glShader|
79fragmentShader = [glShader|
76precision mediump float;
81precision mediump float;