on master help sign in
matrix stack, vertexPos, and vertexColor all work!
commit517b17a65c86f3b23904cbe65a124c007597d216 authorJohn P Mayer Jr <john.p.mayer.jr@gmail.com> dateSat 16 Nov 2013, 00:34 (13 years ago) parentdf9ebcf
6 files changed+123−30
libraries/Graphics/WebGL.elm+2−2 libraries/MJS.elm+3 libraries/Native/Graphics/WebGL.js+62−27 libraries/Native/List.js+13−1 tests/good/.gitignore+2 tests/good/Box.elm+41
libraries/Graphics/WebGL.elm+2−2
@@ -21,8 +21,8 @@ type GLTriangle = { a: GLPoint, b: GLPoint, c: GLPoint }
2121
2222data Mesh = Fake_Mesh
2323
24−makeMesh : [GLTriangle] -> GLContext -> Mesh
25−makeMesh = Native.Graphics.WebGL.makeMesh
24+bindMesh : [GLTriangle] -> GLContext -> Mesh
25+bindMesh = Native.Graphics.WebGL.bindMesh
2626
2727data Scene = Node M4x4 [Scene] | Leaf Mesh
2828
libraries/MJS.elm+3
@@ -14,3 +14,6 @@ v3 = Native.MJS.v3
1414
1515m4x4identity : M4x4
1616m4x4identity = 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) {
66 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
77 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
88
9− //var Render = ElmRuntime.use(ElmRuntime.Render.Element);
109 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
1110
1211 var Signal = Elm.Signal.make(elm);
1312 var newElement = Elm.Graphics.Element.make(elm).newElement;
14− //var JS = Elm.Native.JavaScript.make(elm);
1513 var Utils = Elm.Native.Utils.make(elm);
1614 var Tuple2 = Utils.Tuple2;
1715 var MJS = Elm.Native.MJS.make(elm);
16+ var List = Elm.Native.List.make(elm);
1817
1918 function createShader(gl, str, type) {
2019 var shader = gl.createShader(type);
@@ -57,14 +56,12 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
5756 var geoVert = "attribute vec3 aVertexPosition;\
5857 attribute vec4 aVertexColor;\
5958 \
60− uniform mat4 uMMatrix;\
61− uniform mat4 uPMatrix;\
62− uniform mat4 uVMatrix;\
59+ uniform mat4 uSceneMatrix;\
6360 \
6461 varying vec4 vVertexColor;\
6562 \
6663 void main() {\
67− gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aVertexPosition, 1.0);\
64+ gl_Position = uSceneMatrix * vec4(aVertexPosition, 1.0);\
6865 vVertexColor = aVertexColor;\
6966 }"
7067
@@ -79,22 +76,50 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
7976 function drawGL(model) {
8077 var aspect = model.aspect;
8178
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);
8381
84− var eye = MJS.V3.$(0,0,1);
85− var center = MJS.V3.$(0,0,0);
86− var up = MJS.V3.$(0,1,0);
82+ var program = model.program;
8783
88− var viewMatrix = MJS.M4x4.makeLookAt(eye,center,up);
89−
90− var modelMatrixStack = [MJS.M4x4.identity];
84+ function drawMesh(mesh, sceneMatrix) {
85+ gl.useProgram(program.programPtr);
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);
9191
92− var gl = model.gl;
93− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
92+ gl.enableVertexAttribArray(program.vertexColorAttribute);
93+ gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexColorBuffer);
94+ gl.vertexAttribPointer(program.vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
9495
95− var scene = model.scene;
96− console.log(scene);
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:
109+ var m = scene._0;
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+ }
97119
120+ var scene = model.scene;
121+ drawScene(scene,0);
122+
98123 }
99124
100125 /*
@@ -115,11 +140,20 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
115140 function glContext(w,h) {
116141 var node = newNode('canvas');
117142 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+ };
119153 return Signal.constant({w:w,h:h,gl:gl,node:node,program:program});
120154 }
121155
122− function makeMesh(triangles, context) {
156+ function bindMesh(triangles, context) {
123157 var indices = [];
124158 var positions = [];
125159 var colors = [];
@@ -134,9 +168,9 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
134168 for (var j = 0; j < 3; j += 1) {
135169 positions.push(vertex.pos[j]);
136170 }
137− colors.push(vertex.color._0);
138− colors.push(vertex.color._1);
139− colors.push(vertex.color._2);
171+ colors.push(vertex.color._0 / 256);
172+ colors.push(vertex.color._1 / 256);
173+ colors.push(vertex.color._2 / 256);
140174 colors.push(vertex.color._3);
141175 }
142176 pushTriangle(n+1,node._1);
@@ -154,14 +188,15 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
154188 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
155189 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
156190
157− var vertexColors = gl.createBuffer();
158− gl.bindBuffer(gl.ARRAY_BUFFER, vertexColors);
191+ var vertexColorBuffer = gl.createBuffer();
192+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
159193 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
160194
161195 return {
162− indexBuffer:indexBuffer,
196+ indexBuffer: indexBuffer,
163197 vertexPosBuffer: vertexPosBuffer,
164− vertexColors: vertexColors
198+ vertexColorBuffer: vertexColorBuffer,
199+ numIndices: indices.length,
165200 };
166201
167202 }
@@ -186,7 +221,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
186221
187222 return elm.Native.Graphics.WebGL.values = {
188223 glContext:F2(glContext),
189− makeMesh:F2(makeMesh),
224+ bindMesh:F2(bindMesh),
190225 renderGL:F2(renderGL),
191226 };
192227
libraries/Native/List.js+13−1
@@ -280,6 +280,16 @@ Elm.Native.List.make = function(elm) {
280280 return fromArray(out);
281281 }
282282
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+
283293 Elm.Native.List.values = {
284294 Nil:Nil,
285295 Cons:Cons,
@@ -317,7 +327,9 @@ Elm.Native.List.make = function(elm) {
317327 drop:F2(drop),
318328 repeat:F2(repeat),
319329
320− join:F2(join)
330+ join:F2(join),
331+
332+ each:each
321333 };
322334 return elm.Native.List.values = Elm.Native.List.values;
323335
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)