Last active
August 29, 2015 14:22
-
-
Save mathdoodle/f8cbd86b803bd4cebd50 to your computer and use it in GitHub Desktop.
WebGL Experiment
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
{ | |
"uuid": "bbfa42ad-3a1d-41a2-a752-7d700d0f9b13", | |
"description": "WebGL Experiment", | |
"dependencies": { | |
"DomReady": "latest", | |
"gl-matrix": "2.2.1" | |
} | |
} |
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
<!doctype html> | |
<html> | |
<head> | |
<style> | |
/* STYLE-MARKER */ | |
</style> | |
<script id='shader-vs' type='x-shader/x-vertex'> | |
attribute vec3 aVertexPosition; | |
attribute vec3 aVertexColor; | |
uniform mat4 uMVMatrix; | |
uniform mat4 uPMatrix; | |
varying highp vec4 vColor; | |
void main(void) { | |
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); | |
vColor = vec4(aVertexColor, 1.0); | |
gl_PointSize = 10.0; | |
} | |
</script> | |
<script id='shader-fs' type='x-shader/x-fragment'> | |
varying highp vec4 vColor; | |
void main(void) { | |
gl_FragColor = vColor; | |
} | |
</script> | |
<!-- SCRIPTS-MARKER --> | |
<script> | |
// CODE-MARKER | |
</script> | |
</head> | |
<body> | |
<canvas id='my-canvas' width='400' height='300'> | |
Your browser does not support the HTML5 canvas element. | |
</canvas> | |
</body> | |
</html> |
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
DomReady.ready(main); | |
interface Drawable { | |
getIndexArray(): Uint16Array; | |
getIndexLength(): number; | |
getVertexArray(): Float32Array; | |
} | |
function main() { | |
var canvas = <HTMLCanvasElement>document.getElementById('my-canvas'); | |
var gl: WebGLRenderingContext = initWebGL(canvas); | |
// Compile and link the shaders into a program. | |
var vs_source = document.getElementById('shader-vs').innerText; | |
var fs_source = document.getElementById('shader-fs').innerText; | |
var program = makeProgram(gl, vs_source, fs_source); | |
gl.useProgram(program); | |
var colors: number[] = [ | |
// front face | |
1.0, 0.0, 0.0, // 0 | |
1.0, 0.0, 0.0, // 1 | |
1.0, 0.0, 0.0, // 2 | |
0.0, 0.0, 1.0, // 3 | |
0.0, 0.0, 1.0, // 4 | |
0.0, 0.0, 1.0, // 5 | |
// rear face | |
1.0, 0.0, 0.0, // 6 | |
1.0, 0.0, 0.0, // 7 | |
1.0, 0.0, 0.0, // 8 | |
0.0, 0.0, 1.0, // 9 | |
0.0, 0.0, 1.0, // 10 | |
0.0, 0.0, 1.0 // 11 | |
]; | |
var cbo = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, cbo); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); | |
var prism = makePrism(); | |
var vbo = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vbo); | |
gl.bufferData(gl.ARRAY_BUFFER, prism.getVertexArray(), gl.STATIC_DRAW); | |
var ibo = gl.createBuffer(); | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo); | |
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, prism.getIndexArray(), gl.STATIC_DRAW); | |
var mvMatrix = <Float32Array>mat4.create(); | |
var pMatrix = <Float32Array>mat4.create(); | |
var uMVMatrix = gl.getUniformLocation(program, 'uMVMatrix'); | |
var uPMatrix = gl.getUniformLocation(program, 'uPMatrix'); | |
var angle = 0; | |
function animLoop() { | |
// Clear the viewport. | |
gl.clearColor(0.5, 0.5, 0.6, 1.0); | |
gl.enable(gl.DEPTH_TEST); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
gl.viewport(0, 0, canvas.width, canvas.height); | |
mat4.perspective(pMatrix, 45, canvas.width/canvas.height,0.1,100.0); | |
mat4.identity(mvMatrix); | |
mat4.translate(mvMatrix, mvMatrix, [-1.0, -1.0, -7.0]); | |
mat4.rotate(mvMatrix, mvMatrix, angle, [0.0, 1.0, 0.0]); | |
var aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); | |
gl.enableVertexAttribArray(aVertexPosition); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vbo); | |
gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0); | |
var aVertexColor = gl.getAttribLocation(program, 'aVertexColor'); | |
gl.enableVertexAttribArray(aVertexColor); | |
gl.bindBuffer(gl.ARRAY_BUFFER, cbo); | |
gl.vertexAttribPointer(aVertexColor, 3, gl.FLOAT, false, 0, 0); | |
gl.uniformMatrix4fv(uMVMatrix, false, mvMatrix); | |
gl.uniformMatrix4fv(uPMatrix, false, pMatrix); | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo); | |
gl.drawElements(gl.TRIANGLES, prism.getIndexLength(), gl.UNSIGNED_SHORT, 0); | |
angle += 0.01; | |
requestAnimationFrame(animLoop); | |
} | |
animLoop(); | |
} | |
function initWebGL(canvas: HTMLCanvasElement): WebGLRenderingContext { | |
var context: WebGLRenderingContext = null; | |
try { | |
// Try to grab the standard context. If it fails, fallback to experimental. | |
context = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); | |
} | |
catch(e) { | |
} | |
if (context) { | |
return context; | |
} | |
else { | |
throw new Error("Unable to initialize WebGL. Your browser may not support it."); | |
} | |
} | |
/** | |
* Creates a WebGLProgram with compiled and linked shaders. | |
*/ | |
function makeProgram(gl: WebGLRenderingContext, vertexShader: string, fragmentShader: string): WebGLProgram { | |
// TODO: Proper cleanup if we throw an error at any point. | |
var vs = gl.createShader(gl.VERTEX_SHADER); | |
gl.shaderSource(vs, vertexShader); | |
gl.compileShader(vs); | |
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { | |
throw new Error(gl.getShaderInfoLog(vs)); | |
} | |
var fs = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(fs, fragmentShader); | |
gl.compileShader(fs); | |
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { | |
throw new Error(gl.getShaderInfoLog(fs)); | |
} | |
var program = gl.createProgram(); | |
gl.attachShader(program, vs); | |
gl.attachShader(program, fs); | |
gl.linkProgram(program); | |
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { | |
throw new Error(gl.getProgramInfoLog(program)); | |
} | |
return program; | |
} | |
class Prism implements Drawable { | |
private indices: number[]; | |
private vertices: number[]; | |
constructor(indices: number[], vertices: number[]) { | |
this.indices = indices; | |
this.vertices = vertices; | |
} | |
getIndexArray(): Uint16Array { | |
return new Uint16Array(this.indices); | |
} | |
getIndexLength(): number { | |
return this.indices.length; | |
} | |
getVertexArray(): Float32Array { | |
return new Float32Array(this.vertices); | |
} | |
} | |
function makePrism(): Drawable { | |
var vertices: number[] = [ | |
0.0, 0.0, 0.0, // 0 | |
1.0, 0.0, 0.0, // 1 | |
2.0, 0.0, 0.0, // 2 | |
0.5, 1.0, 0.0, // 3 | |
1.5, 1.0, 0.0, // 4 | |
1.0, 2.0, 0.0, // 5 | |
0.0, 0.0, -2.0, // 6 | |
1.0, 0.0, -2.0, // 7 | |
2.0, 0.0, -2.0, // 8 | |
0.5, 1.0, -2.0, // 9 | |
1.5, 1.0, -2.0, // 10 | |
1.0, 2.0, -2.0 // 11 | |
]; | |
var indices: number[] = [ | |
// front face | |
0, 1, 3, // 0 | |
1, 3, 4, // 1 | |
1, 2, 4, // 2 | |
3, 4, 5, // 3 | |
// rear face | |
6, 7, 9, // 4 | |
7, 9, 10, // 5 | |
7, 8, 10, // 6 | |
9, 10, 11, // 7 | |
// left side | |
0, 3, 6, // 8 | |
3, 6, 9, // 9 | |
3, 5, 9, // 10 | |
5, 9, 11, // 11 | |
// right side | |
2, 4, 8, // 12 | |
4, 8, 10, // 13 | |
4, 5, 10, // 14 | |
5, 10, 11, // 15 | |
// bottom | |
0, 6, 8, // 16 | |
8, 2, 0 // 17 | |
]; | |
return new Prism(indices, vertices); | |
} |
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
body { background-color: white; } | |
canvas { | |
background-color: black; | |
position: absolute; | |
left: 200px; | |
top: 100px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment