|
|
@@ -0,0 +1,378 @@ |
|
|
<html> |
|
|
|
|
|
<head> |
|
|
<title>Learning WebGL</title> |
|
|
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> |
|
|
|
|
|
<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script> |
|
|
<script type="text/javascript" src="webgl-utils.js"></script> |
|
|
|
|
|
<script id="shader-fs" type="x-shader/x-fragment"> |
|
|
precision mediump float; |
|
|
|
|
|
varying vec4 vColor; |
|
|
varying vec2 vTextureCoord; |
|
|
|
|
|
uniform sampler2D uSampler; |
|
|
void main(void) |
|
|
{ |
|
|
gl_FragColor=texture2D(uSampler,vTextureCoord); |
|
|
} |
|
|
</script> |
|
|
|
|
|
<script id="shader-vs" type="x-shader/x-vertex"> |
|
|
attribute vec3 aVertexPosition; |
|
|
attribute vec4 aVertexColor; |
|
|
|
|
|
attribute vec2 aTextureCoord; |
|
|
|
|
|
uniform mat4 uMVMatrix; |
|
|
uniform mat4 uPMatrix; |
|
|
|
|
|
varying vec4 vColor; |
|
|
varying vec2 vTextureCoord; |
|
|
|
|
|
void main(void) |
|
|
{ |
|
|
gl_Position=uPMatrix * uMVMatrix * vec4(aVertexPosition,1.0); |
|
|
vColor=aVertexColor; |
|
|
vTextureCoord=aTextureCoord; |
|
|
} |
|
|
</script> |
|
|
|
|
|
<script type="text/javascript"> |
|
|
|
|
|
function handleLoadedTexture(texture) |
|
|
{ |
|
|
gl.bindTexture(gl.TEXTURE_2D, texture); |
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); |
|
|
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,texture.image); |
|
|
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST); |
|
|
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST); |
|
|
gl.bindTexture(gl.TEXTURE_2D,null); |
|
|
} |
|
|
var myTexture; |
|
|
function initTexture() |
|
|
{ |
|
|
myTexture=gl.createTexture(); |
|
|
myTexture.image=new Image(); |
|
|
myTexture.image.onload= function() { |
|
|
handleLoadedTexture(myTexture); |
|
|
} |
|
|
myTexture.image.src="nehe.gif"; |
|
|
} |
|
|
var mvMatrix=mat4.create(); |
|
|
var pMatrix=mat4.create(); |
|
|
var mvMatrixStack=[]; |
|
|
|
|
|
function mvPushMatrix() |
|
|
{ |
|
|
var copy=mat4.create(); |
|
|
mat4.set(mvMatrix,copy); |
|
|
mvMatrixStack.push(copy); |
|
|
} |
|
|
function mvPopMatrix() |
|
|
{ |
|
|
if (mvMatrixStack.length==0) { |
|
|
throw "ya 3am mesh pop"; |
|
|
} |
|
|
mvMatrix=mvMatrixStack.pop(); |
|
|
} |
|
|
|
|
|
function setUniforms() |
|
|
{ |
|
|
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,false,pMatrix); |
|
|
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform,false,mvMatrix); |
|
|
} |
|
|
|
|
|
function getShader(gl,id) |
|
|
{ |
|
|
var shaderScript=document.getElementById(id); |
|
|
if(!shaderScript) |
|
|
{ |
|
|
return null; |
|
|
} |
|
|
var str=""; |
|
|
var script=shaderScript.firstChild; |
|
|
while(script){ |
|
|
if(script.nodeType==3) |
|
|
{ |
|
|
str+=script.textContent; |
|
|
} |
|
|
script=script.nextSibling; |
|
|
} |
|
|
var shader; |
|
|
if(shaderScript.type == "x-shader/x-fragment") |
|
|
{ |
|
|
shader=gl.createShader(gl.FRAGMENT_SHADER); |
|
|
} |
|
|
else if(shaderScript.type == "x-shader/x-vertex" ) |
|
|
{ |
|
|
shader=gl.createShader(gl.VERTEX_SHADER); |
|
|
} |
|
|
else |
|
|
{ |
|
|
return null; |
|
|
} |
|
|
gl.shaderSource(shader,str); |
|
|
gl.compileShader(shader); |
|
|
if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) |
|
|
{ |
|
|
alert(gl.getShaderInfoLog(shader)); |
|
|
return null; |
|
|
} |
|
|
return shader; |
|
|
} |
|
|
var shaderProgram; |
|
|
var gl; |
|
|
function initShaders() |
|
|
{ |
|
|
var fragementShader=getShader(gl,"shader-fs"); |
|
|
var vertexShader=getShader(gl,"shader-vs"); |
|
|
|
|
|
shaderProgram=gl.createProgram(); |
|
|
gl.attachShader(shaderProgram,vertexShader); |
|
|
gl.attachShader(shaderProgram,fragementShader); |
|
|
|
|
|
gl.linkProgram(shaderProgram); |
|
|
|
|
|
if(!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)) |
|
|
{ |
|
|
alert("cloud not initialise shaders"); |
|
|
} |
|
|
gl.useProgram(shaderProgram); |
|
|
|
|
|
shaderProgram.vertexPositionAttribute=gl.getAttribLocation(shaderProgram,"aVertexPosition"); |
|
|
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); |
|
|
|
|
|
// shaderProgram.vertexColorAttribute=gl.getAttribLocation(shaderProgram,"aVertexColor"); |
|
|
// gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); |
|
|
|
|
|
shaderProgram.textureCoordsAttribute=gl.getAttribLocation(shaderProgram,"aTextureCoord"); |
|
|
gl.enableVertexAttribArray(shaderProgram.textureCoordsAttribute); |
|
|
|
|
|
shaderProgram.samplerUniform=gl.getUniformLocation(shaderProgram,"uSampler"); |
|
|
shaderProgram.pMatrixUniform=gl.getUniformLocation(shaderProgram,"uPMatrix"); |
|
|
shaderProgram.mvMatrixUniform=gl.getUniformLocation(shaderProgram,"uMVMatrix"); |
|
|
} |
|
|
|
|
|
|
|
|
function initGL(canvas) |
|
|
{ |
|
|
try{ |
|
|
gl=canvas.getContext("experimental-webgl"); |
|
|
gl.viewportWidth=canvas.width; |
|
|
gl.viewportHeight=canvas.height; |
|
|
} |
|
|
catch(e){} |
|
|
if(!gl) |
|
|
{ |
|
|
alert("mafesh webgl"); |
|
|
} |
|
|
} |
|
|
|
|
|
var cubeVertexPositionBuffer; |
|
|
var cubeVertexColorBuffer; |
|
|
var cubeVertexIndicesBuffer; |
|
|
var cubeVertexTextureCoordBuffer; |
|
|
|
|
|
function initBuffer() |
|
|
{ |
|
|
cubeVertexPositionBuffer=gl.createBuffer(); |
|
|
gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexPositionBuffer); |
|
|
vertices = [ |
|
|
// Front face |
|
|
-1.0, -1.0, 1.0, |
|
|
1.0, -1.0, 1.0, |
|
|
1.0, 1.0, 1.0, |
|
|
-1.0, 1.0, 1.0, |
|
|
|
|
|
// Back face |
|
|
-1.0, -1.0, -1.0, |
|
|
-1.0, 1.0, -1.0, |
|
|
1.0, 1.0, -1.0, |
|
|
1.0, -1.0, -1.0, |
|
|
|
|
|
// Top face |
|
|
-1.0, 1.0, -1.0, |
|
|
-1.0, 1.0, 1.0, |
|
|
1.0, 1.0, 1.0, |
|
|
1.0, 1.0, -1.0, |
|
|
|
|
|
// Bottom face |
|
|
-1.0, -1.0, -1.0, |
|
|
1.0, -1.0, -1.0, |
|
|
1.0, -1.0, 1.0, |
|
|
-1.0, -1.0, 1.0, |
|
|
|
|
|
// Right face |
|
|
1.0, -1.0, -1.0, |
|
|
1.0, 1.0, -1.0, |
|
|
1.0, 1.0, 1.0, |
|
|
1.0, -1.0, 1.0, |
|
|
|
|
|
// Left face |
|
|
-1.0, -1.0, -1.0, |
|
|
-1.0, -1.0, 1.0, |
|
|
-1.0, 1.0, 1.0, |
|
|
-1.0, 1.0, -1.0 |
|
|
]; |
|
|
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW); |
|
|
cubeVertexPositionBuffer.itemSize=3; |
|
|
cubeVertexPositionBuffer.numItems=24; |
|
|
|
|
|
cubeVertexColorBuffer=gl.createBuffer(); |
|
|
gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexColorBuffer); |
|
|
var colors=[ |
|
|
[1.0, 0.0, 0.0, 1.0], // Front face |
|
|
[1.0, 1.0, 0.0, 1.0], // Back face |
|
|
[0.0, 1.0, 0.0, 1.0], // Top face |
|
|
[1.0, 0.5, 0.5, 1.0], // Bottom face |
|
|
[1.0, 0.0, 1.0, 1.0], // Right face |
|
|
[0.0, 0.0, 1.0, 1.0] // Left face |
|
|
]; |
|
|
var unpackedColors=[]; |
|
|
for (var i in colors) { |
|
|
var color=colors[i]; |
|
|
for(var j=0;j<4 ; j++) |
|
|
{ |
|
|
unpackedColors=unpackedColors.concat(color); |
|
|
} |
|
|
} |
|
|
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(unpackedColors),gl.STATIC_DRAW); |
|
|
cubeVertexColorBuffer.itemSize=4; |
|
|
cubeVertexColorBuffer.numItems=24; |
|
|
|
|
|
cubeVertexIndicesBuffer=gl.createBuffer(); |
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,cubeVertexIndicesBuffer); |
|
|
var cubeVertexIndices=[ |
|
|
0,1,2, 0,2,3, |
|
|
4,5,6, 4,6,7, |
|
|
8,9,10, 8,10,11, |
|
|
12,13,14, 12,14,15, |
|
|
16,17,18, 16,18,19, |
|
|
20,21,22, 20,22,23 |
|
|
] |
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(cubeVertexIndices),gl.STATIC_DRAW); |
|
|
cubeVertexIndicesBuffer.itemSize=1; |
|
|
cubeVertexIndicesBuffer.numItems=36; |
|
|
|
|
|
|
|
|
cubeVertexTextureCoordBuffer=gl.createBuffer(); |
|
|
gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexTextureCoordBuffer); |
|
|
var textureCoords = [ |
|
|
// Front face |
|
|
0.0, 0.0, |
|
|
1.0, 0.0, |
|
|
1.0, 1.0, |
|
|
0.0, 1.0, |
|
|
|
|
|
// Back face |
|
|
1.0, 0.0, |
|
|
1.0, 1.0, |
|
|
0.0, 1.0, |
|
|
0.0, 0.0, |
|
|
|
|
|
// Top face |
|
|
0.0, 1.0, |
|
|
0.0, 0.0, |
|
|
1.0, 0.0, |
|
|
1.0, 1.0, |
|
|
|
|
|
// Bottom face |
|
|
1.0, 1.0, |
|
|
0.0, 1.0, |
|
|
0.0, 0.0, |
|
|
1.0, 0.0, |
|
|
|
|
|
// Right face |
|
|
1.0, 0.0, |
|
|
1.0, 1.0, |
|
|
0.0, 1.0, |
|
|
0.0, 0.0, |
|
|
|
|
|
// Left face |
|
|
0.0, 0.0, |
|
|
1.0, 0.0, |
|
|
1.0, 1.0, |
|
|
0.0, 1.0, |
|
|
]; |
|
|
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(textureCoords),gl.STATIC_DRAW); |
|
|
cubeVertexTextureCoordBuffer.itemSize=2; |
|
|
cubeVertexTextureCoordBuffer.numItems=24; |
|
|
|
|
|
} |
|
|
function degree_to_redian(degree) |
|
|
{ |
|
|
return degree*Math.PI/180.0; |
|
|
} |
|
|
function drawScene() |
|
|
{ |
|
|
gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight); |
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
|
|
|
|
|
mat4.perspective(45,gl.viewportWidth/gl.viewportHeight,0.1,100.0,pMatrix); |
|
|
mat4.identity(mvMatrix); |
|
|
mat4.translate(mvMatrix,[0.0,0.0,-7.0]); |
|
|
mat4.rotate(mvMatrix,degree_to_redian(rTri),[1.0,1.0,1.0]); |
|
|
gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexPositionBuffer); |
|
|
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,cubeVertexPositionBuffer.itemSize,gl.FLOAT,false,0,0); |
|
|
gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexTextureCoordBuffer); |
|
|
gl.vertexAttribPointer(shaderProgram.textureCoordsAttribute,cubeVertexTextureCoordBuffer.itemSize,gl.FLOAT,false,0,0); |
|
|
|
|
|
gl.activeTexture(gl.TEXTURE0); |
|
|
gl.bindTexture(gl.TEXTURE_2D,myTexture); |
|
|
gl.uniform1i(shaderProgram.samplerUniform,0); |
|
|
|
|
|
// gl.bindBuffer(gl.ARRAY_BUFFER,cubeVertexColorBuffer); |
|
|
// gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,cubeVertexColorBuffer.itemSize,gl.FLOAT,false,0,0); |
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,cubeVertexIndicesBuffer); |
|
|
setUniforms(); |
|
|
|
|
|
gl.drawElements(gl.TRIANGLES,cubeVertexIndicesBuffer.numItems,gl.UNSIGNED_SHORT,0); |
|
|
//gl.drawArrays(gl.TRIANGLES_STRIPS,0,cubeVertexPositionBuffer.numItems); |
|
|
} |
|
|
|
|
|
function webGLStart() |
|
|
{ |
|
|
var canvas=document.getElementById("canvas"); |
|
|
initGL(canvas); |
|
|
initShaders(); |
|
|
initBuffer(); |
|
|
initTexture(); |
|
|
gl.clearColor(0.0,0.0,0.0,1.0); |
|
|
gl.enable(gl.DEPTH_TEST) |
|
|
//drawScene(); |
|
|
tick(); |
|
|
} |
|
|
|
|
|
var rTri=0; |
|
|
var lastTime = 0; |
|
|
|
|
|
function animate() { |
|
|
var timeNow = new Date().getTime(); |
|
|
if (lastTime != 0) { |
|
|
var elapsed = timeNow - lastTime; |
|
|
|
|
|
rTri += (90 * elapsed) / 1000.0; |
|
|
} |
|
|
lastTime = timeNow; |
|
|
} |
|
|
|
|
|
function tick() |
|
|
{ |
|
|
requestAnimFrame(tick); |
|
|
drawScene(); |
|
|
animate(); |
|
|
} |
|
|
</script> |
|
|
|
|
|
|
|
|
</head> |
|
|
|
|
|
|
|
|
<body onload="webGLStart()"> |
|
|
<canvas id="canvas" style="border: none;" width="500" height="500"></canvas> |
|
|
</body> |
|
|
|
|
|
</html> |