-
-
Save yangsibai/495f14b4c22e241492c518779454504d to your computer and use it in GitHub Desktop.
A quick demo of something paint-like in webgl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment