@@ -1,6 +1,8 @@
1Elm.Native.Graphics.WebGL = {};
1Elm.Native.Graphics.WebGL = {};
2Elm.Native.Graphics.WebGL.make = function(elm) {
2Elm.Native.Graphics.WebGL.make = function(elm) {
4 elm.Native = elm.Native || {};
6 elm.Native = elm.Native || {};
5 elm.Native.Graphics = elm.Native.Graphics || {};
7 elm.Native.Graphics = elm.Native.Graphics || {};
6 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
8 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
@@ -17,17 +19,29 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
18 function encapsulate(program, buffer, uniforms) {
20 function encapsulate(program, buffer, uniforms) {
20− var model = {
22+ return model = {
21 program: program,
23 program: program,
22 buffer: buffer,
24 buffer: buffer,
23 uniforms: uniforms
25 uniforms: uniforms
30+ function link (vSrc, fSrc) {
32+ var guid = Utils.guid();
34+ console.log("Wrapped program #" + guid);
26− return model;
36+ return program = {
30− function link (gl, vSrc, fSrc) {
44+ function do_link (gl, vSrc, fSrc) {
32 function createShader(str, type) {
46 function createShader(str, type) {
@@ -47,6 +61,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
47 var vshader = createShader(vSrc, gl.VERTEX_SHADER);
61 var vshader = createShader(vSrc, gl.VERTEX_SHADER);
48 var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
62 var fshader = createShader(fSrc, gl.FRAGMENT_SHADER);
49 var program = gl.createProgram();
63 var program = gl.createProgram();
64+ console.log("Created shaders and program");
51 gl.attachShader(program, vshader);
66 gl.attachShader(program, vshader);
52 gl.attachShader(program, fshader);
67 gl.attachShader(program, fshader);
@@ -59,7 +74,20 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
77+ function bind (bufferElems) {
79+ var guid = Utils.guid();
81+ console.log("Wrapped buffer #" + guid);
85+ bufferElems: bufferElems
62− function bind (gl, program, bufferElems) {
90+ function do_bind (gl, program, bufferElems) {
64 var buffers = {};
92 var buffers = {};
@@ -74,9 +102,15 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
74 // and then bind each one-at-a-time
102 // and then bind each one-at-a-time
75 var data = [];
103 var data = [];
76 List.each(function(elem){
104 List.each(function(elem){
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]);
77− data.push(elem[attribute.name][0]);
111+ data.push(elem._2[attribute.name][0]);
78− data.push(elem[attribute.name][1]);
112+ data.push(elem._2[attribute.name][1]);
79− data.push(elem[attribute.name][2]);
113+ data.push(elem._2[attribute.name][2]);
80 }, bufferElems);
114 }, bufferElems);
81 var array = new Float32Array(data);
115 var array = new Float32Array(data);
@@ -96,8 +130,8 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
99− var numIndices = List.length(bufferElems);
133+ var numIndices = 3 * List.length(bufferElems);
100− var indices = List.toArray(List.range(0,numIndices));
134+ var indices = List.toArray(List.range(0, numIndices - 1));
101 console.log("Created index buffer");
135 console.log("Created index buffer");
102 var indexBuffer = gl.createBuffer();
136 var indexBuffer = gl.createBuffer();
103 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
137 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
@@ -113,13 +147,21 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
116− function drawGL(gl,state) {
150+ function drawGL(model) {
152+ var gl = model.cache.gl;
118 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
154 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
155+ console.log("Drawing");
157+ function drawModel(m) {
120− function drawModel(model) {
159+ var program = model.cache.programs[m.program.guid];
161+ program = do_link(gl, m.program.vSrc, m.program.fSrc);
162+ model.cache.programs[m.program.guid] = program;
122− var program = model.program;
123 gl.useProgram(program);
165 gl.useProgram(program);
125 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
167 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
@@ -128,7 +170,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
128 var uniformLocation = gl.getUniformLocation(program, uniform.name);
170 var uniformLocation = gl.getUniformLocation(program, uniform.name);
129 switch (uniform.type) {
171 switch (uniform.type) {
130 case gl.FLOAT_MAT4:
172 case gl.FLOAT_MAT4:
131− gl.uniformMatrix4fv(uniformLocation, false, model.uniforms[uniform.name]);
173+ gl.uniformMatrix4fv(uniformLocation, false, m.uniforms[uniform.name]);
134 console.log("Unsupported uniform type: " + uniform.type);
176 console.log("Unsupported uniform type: " + uniform.type);
@@ -136,8 +178,14 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
139− var numIndices = model.buffer.numIndices;
181+ var buffer = model.cache.buffers[m.buffer.guid];
183+ buffer = do_bind(gl, program, m.buffer.bufferElems);
184+ model.cache.buffers[m.buffer.guid] = buffer;
187+ var numIndices = buffer.numIndices;
140− var indexBuffer = model.buffer.indexBuffer;
188+ var indexBuffer = buffer.indexBuffer;
141 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
189 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
143 var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
191 var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
@@ -145,7 +193,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
145 var attribute = gl.getActiveAttrib(program, i);
193 var attribute = gl.getActiveAttrib(program, i);
146 var attribLocation = gl.getAttribLocation(program, attribute.name);
194 var attribLocation = gl.getAttribLocation(program, attribute.name);
147 gl.enableVertexAttribArray(attribLocation);
195 gl.enableVertexAttribArray(attribLocation);
148− attributeBuffer = model.buffer.buffers[attribute.name];
196+ attributeBuffer = buffer.buffers[attribute.name];
150 switch (attribute.type) {
198 switch (attribute.type) {
151 case gl.FLOAT_VEC3:
199 case gl.FLOAT_VEC3:
@@ -162,58 +210,59 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
165− List.each(drawModel, state.models);
213+ List.each(drawModel, model.models);
169− function webgl(sDimensions, sfDraw) {
217+ function webgl(dimensions, models) {
171 if (!window.WebGLRenderingContext) {
219 if (!window.WebGLRenderingContext) {
172 throw new Error("It appears your browser does not support WebGL! http://get.webgl.org/troubleshooting");
220 throw new Error("It appears your browser does not support WebGL! http://get.webgl.org/troubleshooting");
176− var node = newNode('canvas');
224+ var w = dimensions._0;
177− var gl = node.getContext('webgl');
225+ var h = dimensions._1;
178− var sGL = Signal.constant(gl);
180− var sModels = sfDraw(sGL);
227+ function render(model) {
182− function makeGLelement(dimensions, models, gl) {
229+ var node = newNode('canvas');
230+ var gl = node.getContext('webgl');
184− var w = dimensions._0;
232+ model.cache.gl = gl;
185− var h = dimensions._1;
233+ model.cache.programs = [];
234+ model.cache.buffers = [];
187− function render(state) {
188− drawGL(gl,state);
236+ drawGL(model);
189− return node;
237+ return node;
192− function update(_node, oldState, newState) {
196− var elem = {
241+ function update(_node, oldModel, newModel) {
206− return A3(newElement, w, h, elem);
243+ newModel.cache = oldModel.cache;
210− return A4(Signal.lift3,F3(makeGLelement),sDimensions,sModels,sGL);
248+ var elem = {
259+ return A3(newElement, w, h, elem);
214 return elm.Native.Graphics.WebGL.values = {
263 return elm.Native.Graphics.WebGL.values = {
215− link:F3(link),
264+ link:F2(link),
216− bind:F3(bind),
265+ bind:bind,
217 encapsulate:F3(encapsulate),
266 encapsulate:F3(encapsulate),
218 webgl:F2(webgl)
267 webgl:F2(webgl)