on master help sign in
matrix stack, vertexPos, and vertexColor all work!
517b17aJohn P Mayer Jr
libraries/Graphics/WebGL.elm+2−2
@@ -21,8 +21,8 @@ type GLTriangle = { a: GLPoint, b: GLPoint, c: GLPoint }
21
21
22data Mesh = Fake_Mesh
22data Mesh = Fake_Mesh
23
23
24−makeMesh : [GLTriangle] -> GLContext -> Mesh
24+bindMesh : [GLTriangle] -> GLContext -> Mesh
25−makeMesh = Native.Graphics.WebGL.makeMesh
25+bindMesh = Native.Graphics.WebGL.bindMesh
26
26
27data Scene = Node M4x4 [Scene] | Leaf Mesh
27data Scene = Node M4x4 [Scene] | Leaf Mesh
28
28
libraries/MJS.elm+3
@@ -14,3 +14,6 @@ v3 = Native.MJS.v3
14
14
15m4x4identity : M4x4
15m4x4identity : M4x4
16m4x4identity = Native.MJS.m4x4identity
16m4x4identity = Native.MJS.m4x4identity
17+
18+m4x4makeRotate : Float -> V3 -> M4x4
19+m4x4makeRotate = Native.MJS.m4x4makeRotate
libraries/Native/Graphics/WebGL.js+62−27
@@ -6,15 +6,14 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
6 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
6 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
7 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
7 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
8
8
9− //var Render = ElmRuntime.use(ElmRuntime.Render.Element);
10 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
9 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
11
10
12 var Signal = Elm.Signal.make(elm);
11 var Signal = Elm.Signal.make(elm);
13 var newElement = Elm.Graphics.Element.make(elm).newElement;
12 var newElement = Elm.Graphics.Element.make(elm).newElement;
14− //var JS = Elm.Native.JavaScript.make(elm);
15 var Utils = Elm.Native.Utils.make(elm);
13 var Utils = Elm.Native.Utils.make(elm);
16 var Tuple2 = Utils.Tuple2;
14 var Tuple2 = Utils.Tuple2;
17 var MJS = Elm.Native.MJS.make(elm);
15 var MJS = Elm.Native.MJS.make(elm);
16+ var List = Elm.Native.List.make(elm);
18
17
19 function createShader(gl, str, type) {
18 function createShader(gl, str, type) {
20 var shader = gl.createShader(type);
19 var shader = gl.createShader(type);
@@ -57,14 +56,12 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
57 var geoVert = "attribute vec3 aVertexPosition;\
56 var geoVert = "attribute vec3 aVertexPosition;\
58 attribute vec4 aVertexColor;\
57 attribute vec4 aVertexColor;\
59 \
58 \
60− uniform mat4 uMMatrix;\
59+ uniform mat4 uSceneMatrix;\
61− uniform mat4 uPMatrix;\
62− uniform mat4 uVMatrix;\
63 \
60 \
64 varying vec4 vVertexColor;\
61 varying vec4 vVertexColor;\
65 \
62 \
66 void main() {\
63 void main() {\
67− gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aVertexPosition, 1.0);\
64+ gl_Position = uSceneMatrix * vec4(aVertexPosition, 1.0);\
68 vVertexColor = aVertexColor;\
65 vVertexColor = aVertexColor;\
69 }"
66 }"
70
67
@@ -79,22 +76,50 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
79 function drawGL(model) {
76 function drawGL(model) {
80 var aspect = model.aspect;
77 var aspect = model.aspect;
81
78
82− var projectionMatrix = MJS.M4x4.makePerspective(45, aspect, 0.01, 100);
79+ var gl = model.gl;
80+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
83
81
84− var eye = MJS.V3.$(0,0,1);
82+ var program = model.program;
85− var center = MJS.V3.$(0,0,0);
86− var up = MJS.V3.$(0,1,0);
87
83
88− var viewMatrix = MJS.M4x4.makeLookAt(eye,center,up);
84+ function drawMesh(mesh, sceneMatrix) {
89−
85+ gl.useProgram(program.programPtr);
90− var modelMatrixStack = [MJS.M4x4.identity];
86+
87+ gl.enableVertexAttribArray(program.vertexPositionAttribute);
88+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indexBuffer);
89+ gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexPosBuffer);
90+ gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
91
91
92− var gl = model.gl;
92+ gl.enableVertexAttribArray(program.vertexColorAttribute);
93− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
93+ gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexColorBuffer);
94+ gl.vertexAttribPointer(program.vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
94
95
96+ gl.uniformMatrix4fv(program.sceneMatrixUniform, false, sceneMatrix);
97+
98+ gl.drawElements(gl.TRIANGLES, mesh.numIndices, gl.UNSIGNED_SHORT, 0);
99+ }
100+
101+ var sceneMatrixStack = [MJS.M4x4.identity];
102+
103+ function drawScene(scene,n) {
104+ switch(scene.ctor) {
105+ case 'Leaf':
106+ drawMesh(scene._0, sceneMatrixStack[n]);
107+ break;
108+ default:
95− var scene = model.scene;
109+ var m = scene._0;
96− console.log(scene);
110+ sceneMatrixStack[n+1] = MJS.M4x4.mul(sceneMatrixStack[n],m)
111+ function drawChild(c) {
112+ drawScene(c,n+1);
113+ }
114+ var children = scene._1;
115+ List.each(drawChild, children);
116+ break;
117+ }
118+ }
97
119
120+ var scene = model.scene;
121+ drawScene(scene,0);
122+
98 }
123 }
99
124
100 /*
125 /*
@@ -115,11 +140,20 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
115 function glContext(w,h) {
140 function glContext(w,h) {
116 var node = newNode('canvas');
141 var node = newNode('canvas');
117 var gl = node.getContext('webgl');
142 var gl = node.getContext('webgl');
118− var program = createProgram(gl, geoVert, geoFrag);
143+ var programPtr = createProgram(gl, geoVert, geoFrag);
144+ var vertexPositionAttribute = gl.getAttribLocation(programPtr,'aVertexPosition');
145+ var vertexColorAttribute = gl.getAttribLocation(programPtr,'aVertexColor');
146+ var sceneMatrixUniform = gl.getUniformLocation(programPtr, 'uSceneMatrix');
147+ var program = {
148+ programPtr: programPtr,
149+ vertexPositionAttribute: vertexPositionAttribute,
150+ vertexColorAttribute: vertexColorAttribute,
151+ sceneMatrixUniform: sceneMatrixUniform,
152+ };
119 return Signal.constant({w:w,h:h,gl:gl,node:node,program:program});
153 return Signal.constant({w:w,h:h,gl:gl,node:node,program:program});
120 }
154 }
121
155
122− function makeMesh(triangles, context) {
156+ function bindMesh(triangles, context) {
123 var indices = [];
157 var indices = [];
124 var positions = [];
158 var positions = [];
125 var colors = [];
159 var colors = [];
@@ -134,9 +168,9 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
134 for (var j = 0; j < 3; j += 1) {
168 for (var j = 0; j < 3; j += 1) {
135 positions.push(vertex.pos[j]);
169 positions.push(vertex.pos[j]);
136 }
170 }
137− colors.push(vertex.color._0);
171+ colors.push(vertex.color._0 / 256);
138− colors.push(vertex.color._1);
172+ colors.push(vertex.color._1 / 256);
139− colors.push(vertex.color._2);
173+ colors.push(vertex.color._2 / 256);
140 colors.push(vertex.color._3);
174 colors.push(vertex.color._3);
141 }
175 }
142 pushTriangle(n+1,node._1);
176 pushTriangle(n+1,node._1);
@@ -154,14 +188,15 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
154 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
188 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
155 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
189 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
156
190
157− var vertexColors = gl.createBuffer();
191+ var vertexColorBuffer = gl.createBuffer();
158− gl.bindBuffer(gl.ARRAY_BUFFER, vertexColors);
192+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
159 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
193 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
160
194
161 return {
195 return {
162− indexBuffer:indexBuffer,
196+ indexBuffer: indexBuffer,
163 vertexPosBuffer: vertexPosBuffer,
197 vertexPosBuffer: vertexPosBuffer,
164− vertexColors: vertexColors
198+ vertexColorBuffer: vertexColorBuffer,
199+ numIndices: indices.length,
165 };
200 };
166
201
167 }
202 }
@@ -186,7 +221,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
186
221
187 return elm.Native.Graphics.WebGL.values = {
222 return elm.Native.Graphics.WebGL.values = {
188 glContext:F2(glContext),
223 glContext:F2(glContext),
189− makeMesh:F2(makeMesh),
224+ bindMesh:F2(bindMesh),
190 renderGL:F2(renderGL),
225 renderGL:F2(renderGL),
191 };
226 };
192
227
libraries/Native/List.js+13−1
@@ -280,6 +280,16 @@ Elm.Native.List.make = function(elm) {
280 return fromArray(out);
280 return fromArray(out);
281 }
281 }
282
282
283+ /*
284+ * Only to be used internally; do some side effects for each elem
285+ */
286+ function each(action, xs) {
287+ while(xs.ctor !== '[]') {
288+ action(xs._0);
289+ xs = xs._1;
290+ }
291+ }
292+
283 Elm.Native.List.values = {
293 Elm.Native.List.values = {
284 Nil:Nil,
294 Nil:Nil,
285 Cons:Cons,
295 Cons:Cons,
@@ -317,7 +327,9 @@ Elm.Native.List.make = function(elm) {
317 drop:F2(drop),
327 drop:F2(drop),
318 repeat:F2(repeat),
328 repeat:F2(repeat),
319
329
320− join:F2(join)
330+ join:F2(join),
331+
332+ each:each
321 };
333 };
322 return elm.Native.List.values = Elm.Native.List.values;
334 return elm.Native.List.values = Elm.Native.List.values;
323
335
tests/good/.gitignorenew file+2
@@ -0,0 +1,2 @@
1+build
2+cache
tests/good/Box.elmnew file+41
@@ -0,0 +1,41 @@
1+
2+import open Color
3+import open Graphics.WebGL
4+import open MJS
5+
6+-- Setup the GL context
7+
8+context : Signal GLContext
9+context = glContext 400 400
10+
11+-- Define what our picture looks like
12+
13+top = v3 0 1 0
14+left = v3 -1 -1 0
15+right = v3 1 -1 0
16+
17+triangle : GLTriangle
18+triangle = GLTriangle (GLPoint top red) (GLPoint left blue) (GLPoint right green)
19+
20+-- Bind our picture to a mesh in our GL context
21+
22+triMesh : Signal Mesh
23+triMesh = lift (bindMesh [triangle]) context
24+
25+-- Given an angle and a Mesh, what does the scene look like?
26+
27+scene : Float -> Mesh -> Scene
28+scene angle mesh =
29+ let xAxis = v3 1 0 0
30+ yAxis = v3 0 1 0
31+ rotationX = m4x4makeRotate (angle / 2) xAxis
32+ rotationY = m4x4makeRotate (angle / 3) yAxis
33+ in Node rotationX [Node rotationY [Leaf mesh]]
34+
35+-- Standard accumulator and wiring it up with main
36+
37+angle : Signal Float
38+angle = foldp (\_ a -> a + 0.1) 0 (fps 25)
39+
40+main : Signal Element
41+main = lift2 renderGL context (lift2 scene angle triMesh)