on master help sign in
done with signal now, but need to stop creating so many buffers
commit1afcf6e7a384a0fb8105d7dc241bc2a9eb3a079d authorJohn P Mayer Jr <john.p.mayer.jr@gmail.com> dateMon 9 Dec 2013, 00:07 (13 years ago) parent68e8bca
3 files changed+94−75
libraries/Graphics/WebGL.elm+2−1 libraries/Native/Graphics/WebGL.js+83−69 tests/good/Box.elm+9−5
libraries/Graphics/WebGL.elm+2−1
@@ -4,6 +4,7 @@ module Graphics.WebGL (link, bind, encapsulate, webgl) where
44
55import Graphics.Element (Element)
66import Native.Graphics.WebGL
7+import Signal (Signal)
78
89data GL = Dummy_GL
910
@@ -30,5 +31,5 @@ data Model = Dummy_Model
3031encapsulate : Program a u -> Buffer a -> u -> Model
3132encapsulate = Native.Graphics.WebGL.encapsulate
3233
33−webgl : Int -> Int -> (GL -> [Model]) -> Element
34+webgl : Signal (Int,Int) -> Signal (GL -> [Model]) -> Signal Element
3435webgl = Native.Graphics.WebGL.webgl
libraries/Native/Graphics/WebGL.js+83−69
@@ -81,6 +81,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
8181 var array = new Float32Array(data);
8282
8383 var buffer = gl.createBuffer();
84+ console.log("Created attribute buffer " + attribute.name);
8485 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
8586 gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
8687
@@ -104,96 +105,109 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
104105
105106 }
106107
107− function webgl(w, h, draw) {
108+ function drawGL(gl,state) {
108109
109− var node = newNode('canvas');
110− var gl = node.getContext('webgl');
110+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
111111
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− }
133− }
112+ function drawModel(model) {
134113
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− }
158− }
114+ var program = model.program;
115+ gl.useProgram(program);
159116
160− gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
117+ var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
118+ for (var i = 0; i < numUniforms; i += 1) {
119+ var uniform = gl.getActiveUniform(program, i);
120+ var uniformLocation = gl.getUniformLocation(program, uniform.name);
121+ switch (uniform.type) {
122+ case gl.FLOAT_MAT4:
123+ gl.uniformMatrix4fv(uniformLocation, false, model.uniforms[uniform.name]);
124+ break;
125+ default:
126+ console.log("Unsupported uniform type: " + uniform.type);
127+ break;
128+ }
129+ }
161130
131+ var numIndices = model.buffer.numIndices;
132+ var indices = List.toArray(List.range(0,numIndices));
133+
134+ console.log("Created index buffer");
135+ var indexBuffer = gl.createBuffer();
136+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
137+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
138+
139+ var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
140+ for (var i = 0; i < numAttributes; i += 1) {
141+ var attribute = gl.getActiveAttrib(program, i);
142+ var attribLocation = gl.getAttribLocation(program, attribute.name);
143+ gl.enableVertexAttribArray(attribLocation);
144+ attributeBuffer = model.buffer.buffers[attribute.name];
145+
146+ switch (attribute.type) {
147+ case gl.FLOAT_VEC3:
148+ gl.bindBuffer(gl.ARRAY_BUFFER, attributeBuffer);
149+ gl.vertexAttribPointer(attribLocation, 3, gl.FLOAT, false, 0, 0);
150+ break;
151+ default:
152+ console.log("Unsupported attribute type: " + attribute.type);
153+ break;
154+ }
162155 }
163156
164− List.each(drawModel, state.models);
157+ gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
165158
166159 }
167160
168− function render(state) {
169− drawGL(state);
170− return node;
171− }
161+ List.each(drawModel, state.models);
172162
173− function update(_node, oldState, newState) {
174− drawGL(newState)
175− }
163+ }
176164
177− var models = draw(gl);
165+ function webgl(sDimensions, sDraw) {
166+
167+ var node = newNode('canvas');
168+ var gl = node.getContext('webgl');
169+ var sGL = Signal.constant(gl);
178170
179− var elem = {
180− ctor: 'Custom',
181− type: 'WebGL',
182− render: render,
183− update: update,
184− model: {
185− models: models,
171+ var application = F2(function(f,x) { return f(x); });
172+ var sModels = A3(Signal.lift2,application,sDraw,sGL);
173+
174+ function makeGLelement(dimensions, models, gl) {
175+
176+ var w = dimensions._0;
177+ var h = dimensions._1;
178+
179+ function render(state) {
180+ drawGL(gl,state);
181+ return node;
186182 }
187− };
188183
189− return A3(newElement, w, h, elem);
184+ function update(_node, oldState, newState) {
185+ drawGL(gl,newState)
186+ }
187+
188+ var elem = {
189+ ctor: 'Custom',
190+ type: 'WebGL',
191+ render: render,
192+ update: update,
193+ model: {
194+ models: models,
195+ }
196+ };
197+
198+ return A3(newElement, w, h, elem);
199+
200+ }
201+
202+ return A4(Signal.lift3,F3(makeGLelement),sDimensions,sModels,sGL);
203+
190204 }
191205
192206 return elm.Native.Graphics.WebGL.values = {
193207 link:F3(link),
194208 bind:F3(bind),
195209 encapsulate:F3(encapsulate),
196− webgl:F3(webgl)
210+ webgl:F2(webgl)
197211 };
198212
199213};
tests/good/Box.elm+9−5
@@ -1,5 +1,5 @@
11
2−import MJS (V3,v3)
2+import MJS (V3,v3,m4x4makeRotate)
33import Graphics.WebGL (link, bind, encapsulate, webgl)
44
55-- Define what our geometry looks like
@@ -16,8 +16,9 @@ mesh = map (\vec -> { pos = vec }) [top, left, right]
1616
1717vert = [glShader|
1818attribute vec3 pos;
19+uniform mat4 rot;
1920void main () {
20− gl_Position = vec4(pos, 1.0);
21+ gl_Position = rot * vec4(pos, 1.0);
2122}
2223|]
2324
@@ -27,10 +28,13 @@ void main () {
2728}
2829|]
2930
30−draw gl =
31+draw theta gl =
3132 let prog = link gl vert frag
3233 buf = bind gl prog mesh
33− in [ encapsulate prog buf {} ]
34+ rot = m4x4makeRotate theta <| v3 0 1 0
35+ in [ encapsulate prog buf {rot=rot} ]
3436
35−main = webgl 400 400 draw
37+angle = foldp (\_ n -> n + 0.1) 0 (fps 25)
38+
39+main = webgl (constant (400,400)) (draw <~ angle)
3640