Skip to content

Instantly share code, notes, and snippets.

@rdm
Created January 12, 2014 03:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rdm/8380444 to your computer and use it in GitHub Desktop.
Save rdm/8380444 to your computer and use it in GitHub Desktop.
A quick demo of something paint-like in webgl
<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>
@nvcken
Copy link

nvcken commented Mar 25, 2020

image
I tried and it is painted like this, look weird , do it work properly ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment