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

Reply via email to