Created
May 27, 2013 10:17
-
-
Save rhulha/5656346 to your computer and use it in GitHub Desktop.
self-contained WebGL demo
This file contains 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> | |
<head> | |
<title>WebGL</title> | |
</head> | |
<body marginheight="0" marginwidth="0" bgcolor="blue"> | |
<canvas id="webgl-canvas" style="border: none; width:100%; height: 100%" width="100" height="100"> | |
</canvas> | |
<script> | |
"use strict"; | |
var canvas = document.getElementById("webgl-canvas"); | |
canvas.width = canvas.clientWidth; | |
canvas.height = canvas.clientHeight; | |
console.log(canvas.clientWidth +" "+ canvas.clientHeight); | |
var gl = canvas.getContext("experimental-webgl"); | |
gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight); | |
gl.clearColor(0, 0, 0, 1); | |
gl.enable(gl.DEPTH_TEST); | |
function getShader(type, text) { | |
var shader = gl.createShader(type); | |
gl.shaderSource(shader, text); | |
gl.compileShader(shader); | |
if( ! gl.getShaderParameter(shader, gl.COMPILE_STATUS) ) | |
throw gl.getShaderInfoLog(shader); | |
return shader; | |
} | |
var vertexShader = "attribute vec3 vertexPosition;"+ | |
"attribute vec2 textureCoord;"+ | |
"uniform mat4 mvMatrix;"+ | |
"uniform mat4 pMatrix;"+ | |
"varying vec2 vTextureCoord;"+ | |
"void main(void) {"+ | |
" gl_Position = pMatrix * mvMatrix * vec4(vertexPosition, 1.0);"+ | |
" vTextureCoord = textureCoord; }"; | |
var fragmentShader = "precision mediump float;"+ | |
"varying vec2 vTextureCoord;"+ | |
"uniform sampler2D sampler;"+ | |
"void main(void) {"+ | |
" gl_FragColor = texture2D(sampler, vec2(vTextureCoord.s, vTextureCoord.t)); }"; | |
var shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, getShader( gl.VERTEX_SHADER, vertexShader)); | |
gl.attachShader(shaderProgram, getShader( gl.FRAGMENT_SHADER, fragmentShader)); | |
gl.linkProgram(shaderProgram); | |
gl.useProgram(shaderProgram); | |
var vpLoc = gl.getAttribLocation(shaderProgram, "vertexPosition"); | |
gl.enableVertexAttribArray(vpLoc); | |
var tcLoc = gl.getAttribLocation(shaderProgram, "textureCoord"); | |
gl.enableVertexAttribArray(tcLoc); | |
var pmLoc = gl.getUniformLocation(shaderProgram, "pMatrix"); | |
var mvLoc = gl.getUniformLocation(shaderProgram, "mvMatrix"); | |
var sampler = gl.getUniformLocation(shaderProgram, "sampler"); | |
function getPerspectiveMatrix( fov, aspectRatio, near, far ) { | |
var f = 1/Math.tan(fov * Math.PI / 360.0); // some divide fov by 2 instead. | |
return new Float32Array([ f/aspectRatio, 0, 0, 0, 0, f, 0, 0, 0, 0, (near+far)/(near-far), -1, 0, 0, 2*near*far/(near-far), 0]); | |
} | |
var pMatrix = getPerspectiveMatrix( 45, canvas.clientWidth/canvas.clientHeight, 0.1, 1000); | |
function pushVertices( obj, v, n) { | |
for ( var i = 0; i<v.length; i++) { | |
obj.v.push( 2*!(v[i]&1)-1, 2*!(v[i]&2)-1, 2*!(v[i]&4)-1 ); // vertices | |
//obj.t.push( i&1?1:0, i&2?1:0 ); // uv mapping | |
obj.n.push.apply( obj.n, n); // normals | |
} | |
obj.t.push( 0,0,1,0,1,1,0,1 ); // uv mapping | |
} | |
function getBox() { | |
var obj = { v : [], n : [], t : [], i : []}; | |
var van = [ // vertices and normals | |
[[0, 4, 6, 2], [-1, 0, 0]], | |
[[1, 3, 7, 5], [+1, 0, 0]], | |
[[0, 1, 5, 4], [0, -1, 0]], | |
[[2, 6, 7, 3], [0, +1, 0]], | |
[[0, 2, 3, 1], [0, 0, -1]], | |
[[4, 5, 7, 6], [0, 0, +1]] | |
]; | |
for ( var i = 0; i<van.length; i++) { | |
pushVertices( obj, van[i][0], van[i][1] ); | |
obj.i.push( 4*i+0, 4*i+1, 4*i+2, 4*i+0, 4*i+2, 4*i+3); | |
} | |
return obj; | |
} | |
var box = getBox(); | |
function createBuffer( target, type, data) { | |
var b = gl.createBuffer(); | |
gl.bindBuffer( target, b); | |
gl.bufferData( target, new type(data), gl.STATIC_DRAW); | |
return b; | |
} | |
function setUpBuffers( obj) { | |
obj.vb = createBuffer( gl.ARRAY_BUFFER, Float32Array, obj.v); | |
obj.nb = createBuffer( gl.ARRAY_BUFFER, Float32Array, obj.n); | |
obj.tb = createBuffer( gl.ARRAY_BUFFER, Float32Array, obj.t); | |
obj.ib = createBuffer( gl.ELEMENT_ARRAY_BUFFER, Uint16Array, obj.i); | |
} | |
setUpBuffers( box); | |
box.texture = gl.createTexture(); | |
var image = new Image(); | |
var ready = false; | |
image.onload = function () { | |
gl.bindTexture(gl.TEXTURE_2D, box.texture); | |
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); | |
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_NEAREST); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
gl.bindTexture(gl.TEXTURE_2D, null); | |
ready = true; | |
} | |
//image.src="tex.jpg"; | |
//image.src = "http://learningwebgl.com/lessons/lesson05/nehe.gif";//"tex.jpg"; | |
image.src= "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEABAMAAACuXLVVAAAABGdBTUEAALGPC/xhBQAAAA9QTFRFABEsAAobAAUQAC2SAAAAobC6MgAAAK1JREFUeNrt0jEBACAMxMAOSEACDooD8K8JXPxyUXBDqsPVvtEOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAWMNKAmQYsEwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfECHewiS34IF3lURAAAAAElFTkSuQmCC"; | |
var mvMatrix = new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]); // identity | |
mvMatrix[14]=-10; | |
function rotate( mat, angle, x, y, z) { | |
var s, c, t, a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, b00, b01, b02, b10, b11, b12, b20, b21, b22; | |
var len = Math.sqrt(x * x + y * y + z * z); | |
x /= len; y /= len; z /= len; | |
s = Math.sin(angle); c = Math.cos(angle); t = 1 - c; | |
a00=mat[0];a01=mat[1];a02=mat[2];a03=mat[3];a10=mat[4];a11=mat[5]; | |
a12=mat[6];a13=mat[7];a20=mat[8];a21=mat[9];a22=mat[10];a23=mat[11]; | |
b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; // Construct the elements of the rotation matrix | |
b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; | |
b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; | |
// Perform rotation-specific matrix multiplication | |
mat[0] = a00 * b00 + a10 * b01 + a20 * b02; mat[1] = a01 * b00 + a11 * b01 + a21 * b02; | |
mat[2] = a02 * b00 + a12 * b01 + a22 * b02; mat[3] = a03 * b00 + a13 * b01 + a23 * b02; | |
mat[4] = a00 * b10 + a10 * b11 + a20 * b12; mat[5] = a01 * b10 + a11 * b11 + a21 * b12; | |
mat[6] = a02 * b10 + a12 * b11 + a22 * b12; mat[7] = a03 * b10 + a13 * b11 + a23 * b12; | |
mat[8] = a00 * b20 + a10 * b21 + a20 * b22; mat[9] = a01 * b20 + a11 * b21 + a21 * b22; | |
mat[10] = a02 * b20 + a12 * b21 + a22 * b22; mat[11] = a03 * b20 + a13 * b21 + a23 * b22; | |
} | |
function drawScene( obj) { | |
gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight); | |
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | |
gl.bindBuffer( gl.ARRAY_BUFFER, obj.vb); | |
gl.vertexAttribPointer( vpLoc, 3, gl.FLOAT, false, 0, 0); | |
gl.bindBuffer( gl.ARRAY_BUFFER, obj.tb); | |
gl.vertexAttribPointer( tcLoc, 2, gl.FLOAT, false, 0, 0); | |
gl.activeTexture( gl.TEXTURE0); | |
gl.bindTexture( gl.TEXTURE_2D, obj.texture); | |
gl.uniform1i( sampler, 0); | |
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, obj.ib); | |
gl.uniformMatrix4fv( pmLoc, false, pMatrix); | |
gl.uniformMatrix4fv( mvLoc, false, mvMatrix); | |
gl.drawElements( gl.TRIANGLES, obj.i.length, gl.UNSIGNED_SHORT, 0); | |
} | |
var rotX, rotY; | |
var lastTime=0; | |
function tick( timeNow) { | |
var elapsed = timeNow - lastTime; | |
lastTime = timeNow; | |
if(isNaN(elapsed)) elapsed = 0; | |
requestAnimationFrame(tick); | |
if( ready) { | |
drawScene(box); | |
rotate( mvMatrix, elapsed/1000, 0.1,0.7,0.2); | |
} | |
} | |
console.log( 'error: ' + gl.getError()); | |
requestAnimationFrame(tick); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment