on master help sign in
done with signal now, but need to stop creating so many buffers
1afcf6eJohn P Mayer Jr
libraries/Graphics/WebGL.elm+2−1
@@ -4,6 +4,7 @@ module Graphics.WebGL (link, bind, encapsulate, webgl) where
4
4
5import Graphics.Element (Element)
5import Graphics.Element (Element)
6import Native.Graphics.WebGL
6import Native.Graphics.WebGL
7+import Signal (Signal)
7
8
8data GL = Dummy_GL
9data GL = Dummy_GL
9
10
@@ -30,5 +31,5 @@ data Model = Dummy_Model
30encapsulate : Program a u -> Buffer a -> u -> Model
31encapsulate : Program a u -> Buffer a -> u -> Model
31encapsulate = Native.Graphics.WebGL.encapsulate
32encapsulate = Native.Graphics.WebGL.encapsulate
32
33
33−webgl : Int -> Int -> (GL -> [Model]) -> Element
34+webgl : Signal (Int,Int) -> Signal (GL -> [Model]) -> Signal Element
34webgl = Native.Graphics.WebGL.webgl
35webgl = Native.Graphics.WebGL.webgl
libraries/Native/Graphics/WebGL.js+83−69
@@ -81,6 +81,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
81 var array = new Float32Array(data);
81 var array = new Float32Array(data);
82
82
83 var buffer = gl.createBuffer();
83 var buffer = gl.createBuffer();
84+ console.log("Created attribute buffer " + attribute.name);
84 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
85 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
85 gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
86 gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
86
87
@@ -104,96 +105,109 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
104
105
105 }
106 }
106
107
107− function webgl(w, h, draw) {
108+ function drawGL(gl,state) {
108
109
109− var node = newNode('canvas');
110+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
110− var gl = node.getContext('webgl');
111
111
112− function drawGL(state) {
113−
114− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
115−
116− function drawModel(model) {
112+ 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− }
134
113
135− var numIndices = model.buffer.numIndices;
114+ var program = model.program;
136− var indices = List.toArray(List.range(0,numIndices));
115+ gl.useProgram(program);
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− }
159
116
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+ }
161
130
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+ }
162 }
155 }
163
156
164− List.each(drawModel, state.models);
157+ gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
165
158
166 }
159 }
167
160
168− function render(state) {
161+ List.each(drawModel, state.models);
169− drawGL(state);
170− return node;
171− }
172
162
173− function update(_node, oldState, newState) {
174− drawGL(newState)
175− }
163+ }
176
164
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);
178
170
179− var elem = {
171+ var application = F2(function(f,x) { return f(x); });
180− ctor: 'Custom',
172+ var sModels = A3(Signal.lift2,application,sDraw,sGL);
181− type: 'WebGL',
173+
182− render: render,
174+ function makeGLelement(dimensions, models, gl) {
183− update: update,
175+
184− model: {
176+ var w = dimensions._0;
185− models: models,
177+ var h = dimensions._1;
178+
179+ function render(state) {
180+ drawGL(gl,state);
181+ return node;
186 }
182 }
187− };
188
183
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+
189− return A3(newElement, w, h, elem);
198+ return A3(newElement, w, h, elem);
199+
200+ }
201+
202+ return A4(Signal.lift3,F3(makeGLelement),sDimensions,sModels,sGL);
203+
190 }
204 }
191
205
192 return elm.Native.Graphics.WebGL.values = {
206 return elm.Native.Graphics.WebGL.values = {
193 link:F3(link),
207 link:F3(link),
194 bind:F3(bind),
208 bind:F3(bind),
195 encapsulate:F3(encapsulate),
209 encapsulate:F3(encapsulate),
196− webgl:F3(webgl)
210+ webgl:F2(webgl)
197 };
211 };
198
212
199};
213};
tests/good/Box.elm+9−5
@@ -1,5 +1,5 @@
1
1
2−import MJS (V3,v3)
2+import MJS (V3,v3,m4x4makeRotate)
3import Graphics.WebGL (link, bind, encapsulate, webgl)
3import Graphics.WebGL (link, bind, encapsulate, webgl)
4
4
5-- Define what our geometry looks like
5-- Define what our geometry looks like
@@ -16,8 +16,9 @@ mesh = map (\vec -> { pos = vec }) [top, left, right]
16
16
17vert = [glShader|
17vert = [glShader|
18attribute vec3 pos;
18attribute vec3 pos;
19+uniform mat4 rot;
19void main () {
20void main () {
20− gl_Position = vec4(pos, 1.0);
21+ gl_Position = rot * vec4(pos, 1.0);
21}
22}
22|]
23|]
23
24
@@ -27,10 +28,13 @@ void main () {
27}
28}
28|]
29|]
29
30
30−draw gl =
31+draw theta gl =
31 let prog = link gl vert frag
32 let prog = link gl vert frag
32 buf = bind gl prog mesh
33 buf = bind gl prog mesh
34+ rot = m4x4makeRotate theta <| v3 0 1 0
33− in [ encapsulate prog buf {} ]
35+ in [ encapsulate prog buf {rot=rot} ]
34
36
37+angle = foldp (\_ n -> n + 0.1) 0 (fps 25)
38+
35−main = webgl 400 400 draw
39+main = webgl (constant (400,400)) (draw <~ angle)
36
40