@@ -27,190 +27,173 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
2727
2828 }
2929
30− function webgl(w, h, draw) {
31−
32− var node = newNode('canvas');
33− var gl = node.getContext('webgl');
34−
35− function link (vSrc, fSrc) {
30+ function link (gl, vSrc, fSrc) {
3631
37− function createShader(str, type) {
32+ function createShader(str, type) {
3833
39− var shader = gl.createShader(type);
34+ var shader = gl.createShader(type);
4035
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− };
36+ gl.shaderSource(shader, str);
37+ gl.compileShader(shader);
38+ var compile = gl.COMPILE_STATUS;
39+ if (!gl.getShaderParameter(shader,compile)) {
40+ throw gl.getShaderInfoLog(shader);
41+ }
5142
52− var vshader = createShader(vSrc, gl.VERTEX_SHADER);
53− var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
54− var program = gl.createProgram();
43+ return shader;
5544
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− }
45+ };
6246
63− return program;
47+ var vshader = createShader(vSrc, gl.VERTEX_SHADER);
48+ var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
49+ var program = gl.createProgram();
6450
51+ gl.attachShader(program, vshader);
52+ gl.attachShader(program, fshader);
53+ gl.linkProgram(program);
54+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
55+ throw gl.getProgramInfoLog(program);
6556 }
6657
67− function bind (program, bufferElems) {
58+ return program;
6859
69− var bufferObject = {};
60+ }
7061
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:
62+ function bind (gl, program, bufferElems) {
7663
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);
64+ var buffers = {};
8765
88− var buffer = gl.createBuffer();
89− gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
90− gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
66+ var attributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
67+ for (var i = 0; i < attributes; i += 1) {
68+ var attribute = gl.getActiveAttrib(program, i);
69+ switch (attribute.type) {
70+ case gl.FLOAT_VEC3:
9171
92− bufferObject[attribute.name] = buffer;
72+ // Might want to invert the loop
73+ // to build the array buffer first
74+ // and then bind each one-at-a-time
75+ var data = [];
76+ List.each(function(elem){
77+ data.push(elem[attribute.name][0]);
78+ data.push(elem[attribute.name][1]);
79+ data.push(elem[attribute.name][2]);
80+ }, bufferElems);
81+ var array = new Float32Array(data);
9382
94− break;
83+ var buffer = gl.createBuffer();
84+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
85+ gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
9586
96− default:
97− console.log("Bad buffer type");
98− break;
99− }
87+ buffers[attribute.name] = buffer;
10088
101− }
89+ break;
10290
103− return bufferObject;
91+ default:
92+ console.log("Bad buffer type");
93+ break;
94+ }
10495
10596 }
10697
107− function render(model) {
108− drawGL(model);
109− return model.node;
110− }
98+ var bufferObject = {
99+ numIndices: List.length(bufferElems),
100+ buffers: buffers
101+ };
111102
112− function update(canvasNode, oldModel, newModel) {
113− drawGL(newModel)
114− }
103+ return bufferObject;
115104
116105 }
117106
118− function drawGL(model) {
119−
120− var gl = model.gl;
121− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
122−
123− function drawModel(glModel) {
124− var program = glModel.program;
125− gl.useProgram(program);
126−
127− var activeUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
128− for (var i = 0; i < activeUniforms; i += 1) {
129− var uniform = gl.getActiveUniform(program, i);
130− var uniformLocation = gl.getUniformLocation(program, uniform.name);
131− switch (uniform.type) {
132− case gl.FLOAT_MAT4:
133− gl.uniformMatrix4fv(uniformLocation, false, glModel.uniforms[uniform.name]);
134− break;
135− default:
136− console.log("Unsupported uniform type: " + uniform.type);
137− break;
107+ function webgl(w, h, draw) {
108+
109+ var node = newNode('canvas');
110+ var gl = node.getContext('webgl');
111+
112+ function drawGL(state) {
113+
114+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
115+
116+ function drawModel(model) {
117+
118+ var program = model.program;
119+ gl.useProgram(program);
120+
121+ var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
122+ for (var i = 0; i < numUniforms; i += 1) {
123+ var uniform = gl.getActiveUniform(program, i);
124+ var uniformLocation = gl.getUniformLocation(program, uniform.name);
125+ switch (uniform.type) {
126+ case gl.FLOAT_MAT4:
127+ gl.uniformMatrix4fv(uniformLocation, false, model.uniforms[uniform.name]);
128+ break;
129+ default:
130+ console.log("Unsupported uniform type: " + uniform.type);
131+ break;
132+ }
138133 }
139− }
140134
141− var numIndices = List.length(glModel.attributes);
142− var indices = List.toArray(List.range(0,numIndices));
143− var indexBuffer = gl.createBuffer();
144− gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
145− gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
146−
147− var activeAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
148− for (var i = 0; i < activeAttributes; i += 1) {
149− var attribute = gl.getActiveAttrib(program, i);
150− var attribLocation = gl.getAttribLocation(program, attribute.name);
151− gl.enableVertexAttribArray(attribLocation);
152− switch (attribute.type) {
153− case gl.FLOAT_VEC3:
154− var data = [];
155− List.each(function(elem){
156− data.push(elem[attribute.name][0]);
157− data.push(elem[attribute.name][1]);
158− data.push(elem[attribute.name][2]);
159− }, glModel.attributes);
160− var attributeBuffer = gl.createBuffer();
161− gl.bindBuffer(gl.ARRAY_BUFFER, attributeBuffer);
162− gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
163− gl.vertexAttribPointer(attribLocation, 3, gl.FLOAT, false, 0, 0);
164− break;
165− default:
166− console.log("Unsupported attribute type: " + attribute.type);
167− break;
135+ var numIndices = model.buffer.numIndices;
136+ var indices = List.toArray(List.range(0,numIndices));
137+
138+ var indexBuffer = gl.createBuffer();
139+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
140+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
141+
142+ var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
143+ for (var i = 0; i < numAttributes; i += 1) {
144+ var attribute = gl.getActiveAttrib(program, i);
145+ var attribLocation = gl.getAttribLocation(program, attribute.name);
146+ gl.enableVertexAttribArray(attribLocation);
147+ attributeBuffer = model.buffer.buffers[attribute.name];
148+
149+ switch (attribute.type) {
150+ case gl.FLOAT_VEC3:
151+ gl.bindBuffer(gl.ARRAY_BUFFER, attributeBuffer);
152+ gl.vertexAttribPointer(attribLocation, 3, gl.FLOAT, false, 0, 0);
153+ break;
154+ default:
155+ console.log("Unsupported attribute type: " + attribute.type);
156+ break;
157+ }
168158 }
169− }
170159
171− gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
160+ gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
172161
173− }
162+ }
174163
175− List.each(drawModel, model.glModels);
164+ List.each(drawModel, state.models);
176165
177− }
166+ }
178167
179− /*
180− * Called for new node, caches lots of stuff
181− */
182− function render(model) {
183− drawGL(model);
184− return model.node;
185− }
168+ function render(state) {
169+ drawGL(state);
170+ return node;
171+ }
186172
187− /*
188− * Called at existing node
189− */
190− function update(canvasNode, oldModel, newModel) {
191− drawGL(newModel)
192− }
173+ function update(_node, oldState, newState) {
174+ drawGL(newState)
175+ }
193176
194− function webgl(context, glModels) {
177+ var models = draw(gl);
195178
196− return A3(newElement, context.w, context.h, {
179+ var elem = {
197180 ctor: 'Custom',
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− },
207− });
181+ type: 'WebGL',
182+ render: render,
183+ update: update,
184+ model: {
185+ models: models,
186+ }
187+ };
208188
189+ return A3(newElement, w, h, elem);
209190 }
210191
211192 return elm.Native.Graphics.WebGL.values = {
212− encapsulate:F3(linkModel),
213− webgl:F3(webgl),
193+ link:F3(link),
194+ bind:F3(bind),
195+ encapsulate:F3(encapsulate),
196+ webgl:F3(webgl)
214197 };
215198
216199};