@@ -15,76 +15,111 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
1515 var MJS = Elm.Native.MJS.make(elm);
1616 var List = Elm.Native.List.make(elm);
1717
18− function createShader(gl, str, type) {
19− var shader = gl.createShader(type);
20− gl.shaderSource(shader, str);
21− gl.compileShader(shader);
18+ function encapsulate(program, buffer, uniforms) {
2219
23− if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
24− throw gl.getShaderInfoLog(shader);
25− }
20+ var model = {
21+ program: program,
22+ buffer: buffer,
23+ uniforms: uniforms
24+ };
2625
27− return shader;
28− };
26+ return model;
2927
30− function linkProgram(vSrc, fSrc, context) {
31− var gl = context.gl;
32− var vshader = createShader(gl, vSrc, gl.VERTEX_SHADER);
33− var fshader = createShader(gl, fSrc, gl.FRAGMENT_SHADER);
34− var program = gl.createProgram()
35− gl.attachShader(program, vshader);
36− gl.attachShader(program, fshader);
37− gl.linkProgram(program);
38− if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
39− throw gl.getProgramInfoLog(program);
40− }
41− return program;
4228 }
4329
44− function drawGL(model) {
45− var aspect = model.aspect;
30+ function webgl(w, h, draw) {
4631
47− var gl = model.gl;
48− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
32+ var node = newNode('canvas');
33+ var gl = node.getContext('webgl');
4934
50− var program = model.program;
35+ function link (vSrc, fSrc) {
5136
52− function drawMesh(mesh, sceneMatrix) {
53− gl.useProgram(program.programPtr);
54−
55− gl.enableVertexAttribArray(program.vertexPositionAttribute);
56− gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indexBuffer);
57− gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexPosBuffer);
58− gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
37+ function createShader(str, type) {
5938
60− gl.enableVertexAttribArray(program.vertexColorAttribute);
61− gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexColorBuffer);
62− gl.vertexAttribPointer(program.vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
39+ var shader = gl.createShader(type);
40+
41+ gl.shaderSource(shader, str);
42+ gl.compileShader(shader);
43+ var compile = gl.COMPILE_STATUS;
44+ if (!gl.getShaderParameter(shader,compile)) {
45+ throw gl.getShaderInfoLog(shader);
46+ }
47+
48+ return shader;
49+
50+ };
51+
52+ var vshader = createShader(vSrc, gl.VERTEX_SHADER);
53+ var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
54+ var program = gl.createProgram();
55+
56+ gl.attachShader(program, vshader);
57+ gl.attachShader(program, fshader);
58+ gl.linkProgram(program);
59+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
60+ throw gl.getProgramInfoLog(program);
61+ }
62+
63+ return program;
6364
64− gl.uniformMatrix4fv(program.sceneMatrixUniform, false, sceneMatrix);
65−
66− gl.drawElements(gl.TRIANGLES, mesh.numIndices, gl.UNSIGNED_SHORT, 0);
6765 }
6866
69− var sceneMatrixStack = [MJS.M4x4.identity];
70−
71− function drawScene(scene,n) {
72− switch(scene.ctor) {
73− case 'SceneLeaf':
74− drawMesh(scene._0, sceneMatrixStack[n]);
75− break;
76− default:
77− var m = scene._0;
78− sceneMatrixStack[n+1] = MJS.M4x4.mul(sceneMatrixStack[n],m)
79− function drawChild(c) {
80− drawScene(c,n+1);
81− }
82− var children = scene._1;
83− List.each(drawChild, children);
84− break;
67+ function bind (program, bufferElems) {
68+
69+ var bufferObject = {};
70+
71+ var attributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
72+ for (var i = 0; i < attributes; i += 1) {
73+ var attribute = gl.getActiveAttrib(program, i);
74+ switch (attribute.type) {
75+ case gl.FLOAT_VEC3:
76+
77+ // Might want to invert the loop
78+ // to build the array buffer first
79+ // and then bind each one-at-a-time
80+ var data = [];
81+ List.each(function(elem){
82+ data.push(elem[attribute.name][0]);
83+ data.push(elem[attribute.name][1]);
84+ data.push(elem[attribute.name][2]);
85+ }, bufferElems);
86+ var array = new Float32Array(data);
87+
88+ var buffer = gl.createBuffer();
89+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
90+ gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
91+
92+ bufferObject[attribute.name] = buffer;
93+
94+ break;
95+
96+ default:
97+ console.log("Bad buffer type");
98+ break;
99+ }
100+
85101 }
102+
103+ return bufferObject;
104+
105+ }
106+
107+ function render(model) {
108+ drawGL(model);
109+ return model.node;
86110 }
87−
111+
112+ function update(canvasNode, oldModel, newModel) {
113+ drawGL(newModel)
114+ }
115+
116+ }
117+
118+ function drawGL(model) {
119+
120+ var gl = model.gl;
121+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
122+
88123 function drawModel(glModel) {
89124 var program = glModel.program;
90125 gl.useProgram(program);
@@ -156,90 +191,26 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
156191 drawGL(newModel)
157192 }
158193
159− function makeGL(w,h) {
160− var node = newNode('canvas');
161− var gl = node.getContext('webgl');
162− return Signal.constant({w:w,h:h,gl:gl,node:node});
163− }
164−
165− function bufferMesh(triangles, context) {
166− var indices = [];
167− var positions = [];
168− var colors = [];
169−
170− function pushTriangle(n, node) {
171− if (node.ctor === "[]") return;
172− var tri = node._0;
173− for (var i = 0; i < 3; i+= 1) {
174− indices.push(3 * n + i);
175− var vertex = tri['_' + i];
176− for (var j = 0; j < 3; j += 1) {
177− positions.push(vertex.pos[j]);
178− }
179− colors.push(vertex.color._0 / 256);
180− colors.push(vertex.color._1 / 256);
181− colors.push(vertex.color._2 / 256);
182− colors.push(vertex.color._3);
183− }
184− pushTriangle(n+1,node._1);
185− }
186−
187− pushTriangle(0,triangles);
188−
189− var gl = context.gl;
190−
191− var indexBuffer = gl.createBuffer();
192− gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
193− gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
194−
195− var vertexPosBuffer = gl.createBuffer();
196− gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
197− gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
198−
199− var vertexColorBuffer = gl.createBuffer();
200− gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
201− gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
202−
203− return {
204− indexBuffer: indexBuffer,
205− vertexPosBuffer: vertexPosBuffer,
206− vertexColorBuffer: vertexColorBuffer,
207− numIndices: indices.length,
208− };
209−
210− }
211−
212194 function webgl(context, glModels) {
213−
195+
214196 return A3(newElement, context.w, context.h, {
215197 ctor: 'Custom',
216− type: 'WebGL',
217− render: render,
218− update: update,
219− model: {
220− aspect: context.w/context.h,
221− node: context.node,
222− gl: context.gl,
223− glModels: glModels,
224− },
198+ type: 'WebGL',
199+ render: render,
200+ update: update,
201+ model: {
202+ aspect: context.w/context.h,
203+ node: context.node,
204+ gl: context.gl,
205+ glModels: glModels,
206+ },
225207 });
226208
227209 }
228210
229− function linkModel(program, uniforms, attributes) {
230− return {
231− program: program,
232− uniforms: uniforms,
233− attributes: attributes,
234− };
235− }
236−
237211 return elm.Native.Graphics.WebGL.values = {
238− makeGL:F2(makeGL),
239− bufferMesh:F2(bufferMesh),
240− webgl:F2(webgl),
241− linkProgram:F3(linkProgram),
242− linkModel:F3(linkModel),
212+ encapsulate:F3(linkModel),
213+ webgl:F3(webgl),
243214 };
244215
245216};