@@ -1,6 +1,8 @@
11Elm.Native.Graphics.WebGL = {};
22Elm.Native.Graphics.WebGL.make = function(elm) {
33
4+ // LOG LEVEL
5+
46 elm.Native = elm.Native || {};
57 elm.Native.Graphics = elm.Native.Graphics || {};
68 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
@@ -17,17 +19,29 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
1719
1820 function encapsulate(program, buffer, uniforms) {
1921
20− var model = {
22+ return model = {
2123 program: program,
2224 buffer: buffer,
2325 uniforms: uniforms
2426 };
2527
26− return model;
28+ }
29+
30+ function link (vSrc, fSrc) {
31+
32+ var guid = Utils.guid();
33+
34+ console.log("Wrapped program #" + guid);
35+
36+ return program = {
37+ guid: guid,
38+ vSrc: vSrc,
39+ fSrc: fSrc
40+ };
2741
2842 }
2943
30− function link (gl, vSrc, fSrc) {
44+ function do_link (gl, vSrc, fSrc) {
3145
3246 function createShader(str, type) {
3347
@@ -47,6 +61,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
4761 var vshader = createShader(vSrc, gl.VERTEX_SHADER);
4862 var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
4963 var program = gl.createProgram();
64+ console.log("Created shaders and program");
5065
5166 gl.attachShader(program, vshader);
5267 gl.attachShader(program, fshader);
@@ -59,7 +74,20 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
5974
6075 }
6176
62− function bind (gl, program, bufferElems) {
77+ function bind (bufferElems) {
78+
79+ var guid = Utils.guid();
80+
81+ console.log("Wrapped buffer #" + guid);
82+
83+ return buffer = {
84+ guid: guid,
85+ bufferElems: bufferElems
86+ };
87+
88+ }
89+
90+ function do_bind (gl, program, bufferElems) {
6391
6492 var buffers = {};
6593
@@ -74,9 +102,15 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
74102 // and then bind each one-at-a-time
75103 var data = [];
76104 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]);
105+ data.push(elem._0[attribute.name][0]);
106+ data.push(elem._0[attribute.name][1]);
107+ data.push(elem._0[attribute.name][2]);
108+ data.push(elem._1[attribute.name][0]);
109+ data.push(elem._1[attribute.name][1]);
110+ data.push(elem._1[attribute.name][2]);
111+ data.push(elem._2[attribute.name][0]);
112+ data.push(elem._2[attribute.name][1]);
113+ data.push(elem._2[attribute.name][2]);
80114 }, bufferElems);
81115 var array = new Float32Array(data);
82116
@@ -96,8 +130,8 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
96130
97131 }
98132
99− var numIndices = List.length(bufferElems);
100− var indices = List.toArray(List.range(0,numIndices));
133+ var numIndices = 3 * List.length(bufferElems);
134+ var indices = List.toArray(List.range(0, numIndices - 1));
101135 console.log("Created index buffer");
102136 var indexBuffer = gl.createBuffer();
103137 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
@@ -113,13 +147,21 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
113147
114148 }
115149
116− function drawGL(gl,state) {
150+ function drawGL(model) {
151+
152+ var gl = model.cache.gl;
117153
118154 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
155+ console.log("Drawing");
156+
157+ function drawModel(m) {
119158
120− function drawModel(model) {
159+ var program = model.cache.programs[m.program.guid];
160+ if (!program) {
161+ program = do_link(gl, m.program.vSrc, m.program.fSrc);
162+ model.cache.programs[m.program.guid] = program;
163+ }
121164
122− var program = model.program;
123165 gl.useProgram(program);
124166
125167 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
@@ -128,7 +170,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
128170 var uniformLocation = gl.getUniformLocation(program, uniform.name);
129171 switch (uniform.type) {
130172 case gl.FLOAT_MAT4:
131− gl.uniformMatrix4fv(uniformLocation, false, model.uniforms[uniform.name]);
173+ gl.uniformMatrix4fv(uniformLocation, false, m.uniforms[uniform.name]);
132174 break;
133175 default:
134176 console.log("Unsupported uniform type: " + uniform.type);
@@ -136,8 +178,14 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
136178 }
137179 }
138180
139− var numIndices = model.buffer.numIndices;
140− var indexBuffer = model.buffer.indexBuffer;
181+ var buffer = model.cache.buffers[m.buffer.guid];
182+ if (!buffer) {
183+ buffer = do_bind(gl, program, m.buffer.bufferElems);
184+ model.cache.buffers[m.buffer.guid] = buffer;
185+ }
186+
187+ var numIndices = buffer.numIndices;
188+ var indexBuffer = buffer.indexBuffer;
141189 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
142190
143191 var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
@@ -145,7 +193,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
145193 var attribute = gl.getActiveAttrib(program, i);
146194 var attribLocation = gl.getAttribLocation(program, attribute.name);
147195 gl.enableVertexAttribArray(attribLocation);
148− attributeBuffer = model.buffer.buffers[attribute.name];
196+ attributeBuffer = buffer.buffers[attribute.name];
149197
150198 switch (attribute.type) {
151199 case gl.FLOAT_VEC3:
@@ -162,58 +210,59 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
162210
163211 }
164212
165− List.each(drawModel, state.models);
213+ List.each(drawModel, model.models);
166214
167215 }
168216
169− function webgl(sDimensions, sfDraw) {
217+ function webgl(dimensions, models) {
170218
171219 if (!window.WebGLRenderingContext) {
172220 throw new Error("It appears your browser does not support WebGL! http://get.webgl.org/troubleshooting");
173221 return;
174222 }
175223
176− var node = newNode('canvas');
177− var gl = node.getContext('webgl');
178− var sGL = Signal.constant(gl);
224+ var w = dimensions._0;
225+ var h = dimensions._1;
179226
180− var sModels = sfDraw(sGL);
227+ function render(model) {
181228
182− function makeGLelement(dimensions, models, gl) {
229+ var node = newNode('canvas');
230+ var gl = node.getContext('webgl');
183231
184− var w = dimensions._0;
185− var h = dimensions._1;
232+ model.cache.gl = gl;
233+ model.cache.programs = [];
234+ model.cache.buffers = [];
186235
187− function render(state) {
188− drawGL(gl,state);
189− return node;
190− }
236+ drawGL(model);
237+ return node;
191238
192− function update(_node, oldState, newState) {
193− drawGL(gl,newState)
194− }
239+ }
195240
196− var elem = {
197− ctor: 'Custom',
198− type: 'WebGL',
199− render: render,
200− update: update,
201− model: {
202− models: models,
203− }
204− };
241+ function update(_node, oldModel, newModel) {
205242
206− return A3(newElement, w, h, elem);
243+ newModel.cache = oldModel.cache;
244+ drawGL(newModel);
207245
208246 }
209247
210− return A4(Signal.lift3,F3(makeGLelement),sDimensions,sModels,sGL);
248+ var elem = {
249+ ctor: 'Custom',
250+ type: 'WebGL',
251+ render: render,
252+ update: update,
253+ model: {
254+ models: models,
255+ cache: {},
256+ }
257+ };
258+
259+ return A3(newElement, w, h, elem);
211260
212261 }
213262
214263 return elm.Native.Graphics.WebGL.values = {
215− link:F3(link),
216− bind:F3(bind),
264+ link:F2(link),
265+ bind:bind,
217266 encapsulate:F3(encapsulate),
218267 webgl:F2(webgl)
219268 };