After trying to overcome some line wrap problems, I am getting an error in Safari.
[Error] TypeError: 'null' is not an object (evaluating 'gl.createProgram') beginProgram (webgl.html, line 25) onload (webgl.html, line 44) Line 25: var program = gl.createProgram(); Line 44: program = beginProgram(gl, '2d-fragment-shader', '2d-vertex-shader'); Any ideas? And On Sat, Jan 11, 2014 at 8:22 PM, Raul Miller <[email protected]> wrote: > Here's an example of using webgl. It's a start of what might turn into > a paint program. > > If it's working right you should see a green square on the page when > it loads. Drag the mouse over it and random colored squares will > appear with a magenta triangle on the right (over top of the drawing - > the green square underneath). > > My next step, I think, will involve introducing a second "program" - > my understanding is that a webgl "program" always consists of the two > shaders and that different operations are performed by using different > programs. In J terms, a shader is probably best thought of as a > specialized gerund (one for position with vertices being an item, one > for color where a "pixel" or a "fragment" being an item), a program as > a conjunction or the verb which results after giving the conjunction a > pair of these shaders. > > The subtle distinction between a pixel and a fragment is also kind of > interesting, but I want to try more things so I have a better > understanding of the capabilities of this kind of system. > > I am also thinking of writing a J-like library so I can work with > comfortable-ish operations in javascript (maybe closer to VSAPL than > true J, because I just want basic functionality - if I want to do > heavy duty computation I think I'd prefer to use JHS, and the > limitations of browser access to things like files only reinforce that > impression). > > Anyways, since other people are working with webgl, perhaps this is of > interest. (I should also note that I've not made any significant > effort to make this portable, so I have no idea if it will work for > you. If nothing else, not all browsers even support webgl.) > > Thanks, > > -- > Raul > > <html> > <title>WebGL Example</title> > <script src=" > http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> > <script> > > function useShader(gl, program, scriptId) { > var shaderScript= document.getElementById(scriptId); > console.log('shaderScript: ',shaderScript); > var shaderType= gl[shaderScript.type.replace(/.*\//,'')]; > console.log('shaderType: ',shaderType); > var shader= gl.createShader(shaderType); console.log('shader: > ',shader); > gl.shaderSource(shader, shaderScript.text); > gl.compileShader(shader); > var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); > console.log('compiled: ',compiled); > if (!compiled) { > throw('error creating shader "' + scriptId + '": ' + > gl.getShaderInfoLog(shader)); > } > gl.attachShader(program, shader); > return shader; > }; > > function beginProgram(gl, pixelShader, vertexShader) { > var program = gl.createProgram(); console.log('program: ',program); > useShader(gl, program, pixelShader); console.log('pixel shader: > ',pixelShader); > useShader(gl, program, vertexShader); console.log('vertex > shader',vertexShader); > gl.linkProgram(program); > if (!gl.getProgramParameter(program, gl.LINK_STATUS)) > {throw('error from linkProgram: '+gl.getProgramInfoLog(program))} > gl.useProgram(program); > return program; > }; > > window.onload = function() { > window.canvas = document.getElementById("canvas"); > console.log('canvas: ',canvas); > window.gl = canvas.getContext('webgl', {preserveDrawingBuffer: > true}); console.log('graphics library: ',gl); > window.bcr= canvas.getBoundingClientRect(); console.log('bounding > client rectangle (left, top): ',bcr, bcr.left, bcr.top); > program = beginProgram(gl, '2d-fragment-shader', '2d-vertex-shader'); > > gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); > > // tell vertex shader the size of our drawing region > gl.uniform2f(gl.getUniformLocation(program, "resolution"), > canvas.width, canvas.height); > > // and where each vertex is - our array buffer will be shaped as a > list of coordinate pairs > var positionLocation = gl.getAttribLocation(program, "position"); > console.log('positionLocation: ',positionLocation); > gl.enableVertexAttribArray(positionLocation); > gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); > > // meanwhile, our fragment shader will need to know what color we > are drawing > window.colorLocation= gl.getUniformLocation(program, 'color'); > console.log('colorLocation: ',colorLocation); > > // example of rendering: draw a pair of green triangles to form a > square > gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([20,30, 50,30, > 20,60, 20,60, 50,30, 50,60]), gl.STATIC_DRAW); > gl.uniform4f(colorLocation, 0, 1, 0, 1); // (red,green,blue,alpha) > gl.drawArrays(gl.TRIANGLES, 0, 6); > > self.mousedown= 0; > $('#canvas').on('mousedown', function(e) {render(1,e)}); > $('#canvas').on('mousemove', function(e) {render(0,e)}); > $('body').on('mouseup', function(e) {render(-1,e)}); > window.gl = canvas.getContext('webgl'); console.log('gl: ',gl); > > } > > function render(mode, e) { > if (0===mode && 1===mousedown) { > var x= e.clientX-bcr.left; > var y= e.clientY-bcr.top; > var width= 9; > var height=9; > > gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ > x, y, > x+width, y, > x, y+height, > x, y+height, > x+width, y, > x+width, y+height]), gl.STATIC_DRAW); > gl.uniform4f(colorLocation, Math.random(), Math.random(), > Math.random(), 1); > gl.drawArrays(gl.TRIANGLES, 0, 6); > > // each time we add something to the screen put a purple triangle on top > of it > gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ > 310, 10, > 390, 80, > 310, 149]), gl.STATIC_DRAW); > gl.uniform4f(colorLocation, 1, 0, 1, 1); > gl.drawArrays(gl.TRIANGLES, 0, 3); > } else { > self.mousedown= mode; > } > } > > function randomInt(range){return Math.floor(Math.random()*range);} > > </script> > <script id="2d-vertex-shader" type="x-shader/VERTEX_SHADER"> > attribute vec2 position; > uniform vec2 resolution; > void main() { > vec2 zeroToOne = position / resolution; // convert the rectangle > from pixels to 0.0 to 1.0 > vec2 zeroToTwo = zeroToOne * 2.0; // convert from 0->1 to 0->2 > vec2 clipSpace = zeroToTwo - 1.0; // convert from 0->2 to -1->+1 > (clipspace) > gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); > } > </script> > <script id="2d-fragment-shader" type="x-shader/FRAGMENT_SHADER"> > precision mediump float; > uniform vec4 color; > void main() { > gl_FragColor = color; > } > </script> > > </head> > <body style="margin: 8px"> > <canvas id="canvas" width="400" height="300"></canvas> > </body> > </html> > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm > -- (B=) <-----my sig Brian Schott ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
