diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9f27852 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/simple-textured-cube-and-lighting-webgl2.iml b/.idea/simple-textured-cube-and-lighting-webgl2.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/simple-textured-cube-and-lighting-webgl2.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/shadedCube.html b/shadedCube.html new file mode 100644 index 0000000..3a564de --- /dev/null +++ b/shadedCube.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +Oops ... your browser doesn't support the HTML5 canvas element + + + + \ No newline at end of file diff --git a/shadedCube_js/MV.js b/shadedCube_js/MV.js new file mode 100644 index 0000000..16f3f37 --- /dev/null +++ b/shadedCube_js/MV.js @@ -0,0 +1,936 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Angel.js +// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// +// Helper functions +// + +function _argumentsToArray( args ) +{ + return [].concat.apply( [], Array.prototype.slice.apply(args) ); +} + +//---------------------------------------------------------------------------- + +function radians( degrees ) { + return degrees * Math.PI / 180.0; +} + +//---------------------------------------------------------------------------- +// +// Vector Constructors +// + +function vec2() +{ + var result = _argumentsToArray( arguments ); + + switch ( result.length ) { + case 0: result.push( 0.0 ); + case 1: result.push( 0.0 ); + } + + return result.splice( 0, 2 ); +} + +function vec3() +{ + var result = _argumentsToArray( arguments ); + + switch ( result.length ) { + case 0: result.push( 0.0 ); + case 1: result.push( 0.0 ); + case 2: result.push( 0.0 ); + } + + return result.splice( 0, 3 ); +} + +function vec4() +{ + var result = _argumentsToArray( arguments ); + + switch ( result.length ) { + case 0: result.push( 0.0 ); + case 1: result.push( 0.0 ); + case 2: result.push( 0.0 ); + case 3: result.push( 1.0 ); + } + + return result.splice( 0, 4 ); +} + +//---------------------------------------------------------------------------- +// +// Matrix Constructors +// + +function mat2() +{ + var v = _argumentsToArray( arguments ); + + var m = []; + switch ( v.length ) { + case 0: + v[0] = 1; + case 1: + m = [ + vec2( v[0], 0.0 ), + vec2( 0.0, v[0] ) + ]; + break; + + default: + m.push( vec2(v) ); v.splice( 0, 2 ); + m.push( vec2(v) ); + break; + } + + m.matrix = true; + + return m; +} + +//---------------------------------------------------------------------------- + +function mat3() +{ + var v = _argumentsToArray( arguments ); + + var m = []; + switch ( v.length ) { + case 0: + v[0] = 1; + case 1: + m = [ + vec3( v[0], 0.0, 0.0 ), + vec3( 0.0, v[0], 0.0 ), + vec3( 0.0, 0.0, v[0] ) + ]; + break; + + default: + m.push( vec3(v) ); v.splice( 0, 3 ); + m.push( vec3(v) ); v.splice( 0, 3 ); + m.push( vec3(v) ); + break; + } + + m.matrix = true; + + return m; +} + +//---------------------------------------------------------------------------- + +function mat4() +{ + var v = _argumentsToArray( arguments ); + + var m = []; + switch ( v.length ) { + case 0: + v[0] = 1; + case 1: + m = [ + vec4( v[0], 0.0, 0.0, 0.0 ), + vec4( 0.0, v[0], 0.0, 0.0 ), + vec4( 0.0, 0.0, v[0], 0.0 ), + vec4( 0.0, 0.0, 0.0, v[0] ) + ]; + break; + + default: + m.push( vec4(v) ); v.splice( 0, 4 ); + m.push( vec4(v) ); v.splice( 0, 4 ); + m.push( vec4(v) ); v.splice( 0, 4 ); + m.push( vec4(v) ); + break; + } + + m.matrix = true; + + return m; +} + +//---------------------------------------------------------------------------- +// +// Generic Mathematical Operations for Vectors and Matrices +// + +function equal( u, v ) +{ + if ( u.length != v.length ) { return false; } + + if ( u.matrix && v.matrix ) { + for ( var i = 0; i < u.length; ++i ) { + if ( u[i].length != v[i].length ) { return false; } + for ( var j = 0; j < u[i].length; ++j ) { + if ( u[i][j] !== v[i][j] ) { return false; } + } + } + } + else if ( u.matrix && !v.matrix || !u.matrix && v.matrix ) { + return false; + } + else { + for ( var i = 0; i < u.length; ++i ) { + if ( u[i] !== v[i] ) { return false; } + } + } + + return true; +} + +//---------------------------------------------------------------------------- + +function add( u, v ) +{ + var result = []; + + if ( u.matrix && v.matrix ) { + if ( u.length != v.length ) { + throw "add(): trying to add matrices of different dimensions"; + } + + for ( var i = 0; i < u.length; ++i ) { + if ( u[i].length != v[i].length ) { + throw "add(): trying to add matrices of different dimensions"; + } + result.push( [] ); + for ( var j = 0; j < u[i].length; ++j ) { + result[i].push( u[i][j] + v[i][j] ); + } + } + + result.matrix = true; + + return result; + } + else if ( u.matrix && !v.matrix || !u.matrix && v.matrix ) { + throw "add(): trying to add matrix and non-matrix variables"; + } + else { + if ( u.length != v.length ) { + throw "add(): vectors are not the same dimension"; + } + + for ( var i = 0; i < u.length; ++i ) { + result.push( u[i] + v[i] ); + } + + return result; + } +} + +//---------------------------------------------------------------------------- + +function subtract( u, v ) +{ + var result = []; + + if ( u.matrix && v.matrix ) { + if ( u.length != v.length ) { + throw "subtract(): trying to subtract matrices" + + " of different dimensions"; + } + + for ( var i = 0; i < u.length; ++i ) { + if ( u[i].length != v[i].length ) { + throw "subtract(): trying to subtact matrices" + + " of different dimensions"; + } + result.push( [] ); + for ( var j = 0; j < u[i].length; ++j ) { + result[i].push( u[i][j] - v[i][j] ); + } + } + + result.matrix = true; + + return result; + } + else if ( u.matrix && !v.matrix || !u.matrix && v.matrix ) { + throw "subtact(): trying to subtact matrix and non-matrix variables"; + } + else { + if ( u.length != v.length ) { + throw "subtract(): vectors are not the same length"; + } + + for ( var i = 0; i < u.length; ++i ) { + result.push( u[i] - v[i] ); + } + + return result; + } +} + +//---------------------------------------------------------------------------- + +function mult( u, v ) +{ + var result = []; + + if ( u.matrix && v.matrix ) { + if ( u.length != v.length ) { + throw "mult(): trying to add matrices of different dimensions"; + } + + for ( var i = 0; i < u.length; ++i ) { + if ( u[i].length != v[i].length ) { + throw "mult(): trying to add matrices of different dimensions"; + } + } + + for ( var i = 0; i < u.length; ++i ) { + result.push( [] ); + + for ( var j = 0; j < v.length; ++j ) { + var sum = 0.0; + for ( var k = 0; k < u.length; ++k ) { + sum += u[i][k] * v[k][j]; + } + result[i].push( sum ); + } + } + + result.matrix = true; + + return result; + } + else { + if ( u.length != v.length ) { + throw "mult(): vectors are not the same dimension"; + } + + for ( var i = 0; i < u.length; ++i ) { + result.push( u[i] * v[i] ); + } + + return result; + } +} + +//---------------------------------------------------------------------------- +// +// Basic Transformation Matrix Generators +// + +function translate( x, y, z ) +{ + if ( Array.isArray(x) && x.length == 3 ) { + z = x[2]; + y = x[1]; + x = x[0]; + } + + var result = mat4(); + result[0][3] = x; + result[1][3] = y; + result[2][3] = z; + + return result; +} + +//---------------------------------------------------------------------------- + +function rotate( angle, axis ) +{ + if ( !Array.isArray(axis) ) { + axis = [ arguments[1], arguments[2], arguments[3] ]; + } + + var v = normalize( axis ); + + var x = v[0]; + var y = v[1]; + var z = v[2]; + + var c = Math.cos( radians(angle) ); + var omc = 1.0 - c; + var s = Math.sin( radians(angle) ); + + var result = mat4( + vec4( x*x*omc + c, x*y*omc - z*s, x*z*omc + y*s, 0.0 ), + vec4( x*y*omc + z*s, y*y*omc + c, y*z*omc - x*s, 0.0 ), + vec4( x*z*omc - y*s, y*z*omc + x*s, z*z*omc + c, 0.0 ), + vec4() + ); + + return result; +} + +//---------------------------------------------------------------------------- + +function scalem( x, y, z ) +{ + if ( Array.isArray(x) && x.length == 3 ) { + z = x[2]; + y = x[1]; + x = x[0]; + } + + var result = mat4(); + result[0][0] = x; + result[1][1] = y; + result[2][2] = z; + + return result; +} + +//---------------------------------------------------------------------------- +// +// ModelView Matrix Generators +// + +function lookAt( eye, at, up ) +{ + if ( !Array.isArray(eye) || eye.length != 3) { + throw "lookAt(): first parameter [eye] must be an a vec3"; + } + + if ( !Array.isArray(at) || at.length != 3) { + throw "lookAt(): first parameter [at] must be an a vec3"; + } + + if ( !Array.isArray(up) || up.length != 3) { + throw "lookAt(): first parameter [up] must be an a vec3"; + } + + if ( equal(eye, at) ) { + return mat4(); + } + + var v = normalize( subtract(at, eye) ); // view direction vector + var n = normalize( cross(v, up) ); // perpendicular vector + var u = normalize( cross(n, v) ); // "new" up vector + + v = negate( v ); + + var result = mat4( + vec4( n, -dot(n, eye) ), + vec4( u, -dot(u, eye) ), + vec4( v, -dot(v, eye) ), + vec4() + ); + + return result; +} + +//---------------------------------------------------------------------------- +// +// Projection Matrix Generators +// + +function ortho( left, right, bottom, top, near, far ) +{ + if ( left == right ) { throw "ortho(): left and right are equal"; } + if ( bottom == top ) { throw "ortho(): bottom and top are equal"; } + if ( near == far ) { throw "ortho(): near and far are equal"; } + + var w = right - left; + var h = top - bottom; + var d = far - near; + + var result = mat4(); + result[0][0] = 2.0 / w; + result[1][1] = 2.0 / h; + result[2][2] = -2.0 / d; + result[0][3] = -(left + right) / w; + result[1][3] = -(top + bottom) / h; + result[2][3] = -(near + far) / d; + + return result; +} + +//---------------------------------------------------------------------------- + +function perspective( fovy, aspect, near, far ) +{ + var f = 1.0 / Math.tan( radians(fovy) / 2 ); + var d = far - near; + + var result = mat4(); + result[0][0] = f / aspect; + result[1][1] = f; + result[2][2] = -(near + far) / d; + result[2][3] = -2 * near * far / d; + result[3][2] = -1; + result[3][3] = 0.0; + + return result; +} + +//---------------------------------------------------------------------------- +// +// Matrix Functions +// + +function transpose( m ) +{ + if ( !m.matrix ) { + return "transpose(): trying to transpose a non-matrix"; + } + + var result = []; + for ( var i = 0; i < m.length; ++i ) { + result.push( [] ); + for ( var j = 0; j < m[i].length; ++j ) { + result[i].push( m[j][i] ); + } + } + + result.matrix = true; + + return result; +} + +//---------------------------------------------------------------------------- +// +// Vector Functions +// + +function dot( u, v ) +{ + if ( u.length != v.length ) { + throw "dot(): vectors are not the same dimension"; + } + + var sum = 0.0; + for ( var i = 0; i < u.length; ++i ) { + sum += u[i] * v[i]; + } + + return sum; +} + +//---------------------------------------------------------------------------- + +function negate( u ) +{ + var result = []; + for ( var i = 0; i < u.length; ++i ) { + result.push( -u[i] ); + } + + return result; +} + +//---------------------------------------------------------------------------- + +function cross( u, v ) +{ + if ( !Array.isArray(u) || u.length < 3 ) { + throw "cross(): first argument is not a vector of at least 3"; + } + + if ( !Array.isArray(v) || v.length < 3 ) { + throw "cross(): second argument is not a vector of at least 3"; + } + + var result = [ + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ]; + + return result; +} + +//---------------------------------------------------------------------------- + +function length( u ) +{ + return Math.sqrt( dot(u, u) ); +} + +//---------------------------------------------------------------------------- + +function normalize( u, excludeLastComponent ) +{ + if ( excludeLastComponent ) { + var last = u.pop(); + } + + var len = length( u ); + + if ( !isFinite(len) ) { + throw "normalize: vector " + u + " has zero length"; + } + + for ( var i = 0; i < u.length; ++i ) { + u[i] /= len; + } + + if ( excludeLastComponent ) { + u.push( last ); + } + + return u; +} + +//---------------------------------------------------------------------------- + +function mix( u, v, s ) +{ + if ( typeof s !== "number" ) { + throw "mix: the last paramter " + s + " must be a number"; + } + + if ( u.length != v.length ) { + throw "vector dimension mismatch"; + } + + var result = []; + for ( var i = 0; i < u.length; ++i ) { + result.push( (1.0 - s) * u[i] + s * v[i] ); + } + + return result; +} + +//---------------------------------------------------------------------------- +// +// Vector and Matrix functions +// + +function scale( s, u ) +{ + if ( !Array.isArray(u) ) { + throw "scale: second parameter " + u + " is not a vector"; + } + + var result = []; + for ( var i = 0; i < u.length; ++i ) { + result.push( s * u[i] ); + } + + return result; +} + +//---------------------------------------------------------------------------- +// +// +// + +function flatten( v ) +{ + if ( v.matrix === true ) { + v = transpose( v ); + } + + var n = v.length; + var elemsAreArrays = false; + + if ( Array.isArray(v[0]) ) { + elemsAreArrays = true; + n *= v[0].length; + } + + var floats = new Float32Array( n ); + + if ( elemsAreArrays ) { + var idx = 0; + for ( var i = 0; i < v.length; ++i ) { + for ( var j = 0; j < v[i].length; ++j ) { + floats[idx++] = v[i][j]; + } + } + } + else { + for ( var i = 0; i < v.length; ++i ) { + floats[i] = v[i]; + } + } + + return floats; +} + +//---------------------------------------------------------------------------- + +var sizeof = { + 'vec2' : new Float32Array( flatten(vec2()) ).byteLength, + 'vec3' : new Float32Array( flatten(vec3()) ).byteLength, + 'vec4' : new Float32Array( flatten(vec4()) ).byteLength, + 'mat2' : new Float32Array( flatten(mat2()) ).byteLength, + 'mat3' : new Float32Array( flatten(mat3()) ).byteLength, + 'mat4' : new Float32Array( flatten(mat4()) ).byteLength +}; + +// new functions 5/2/2015 + +// printing + +function printm(m) +{ + if(m.length == 2) + for(var i=0; i" + gl.getShaderInfoLog( vertShdr ) + ""; + alert( msg ); + return -1; + } + } + + var fragElem = document.getElementById( fragmentShaderId ); + if ( !fragElem ) { + alert( "Unable to load vertex shader " + fragmentShaderId ); + return -1; + } + else { + fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); + gl.shaderSource( fragShdr, fragElem.text ); + gl.compileShader( fragShdr ); + if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { + var msg = "Fragment shader failed to compile. The error log is:" + + "
" + gl.getShaderInfoLog( fragShdr ) + "
"; + alert( msg ); + return -1; + } + } + + var program = gl.createProgram(); + gl.attachShader( program, vertShdr ); + gl.attachShader( program, fragShdr ); + gl.linkProgram( program ); + + if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { + var msg = "Shader program failed to link. The error log is:" + + "
" + gl.getProgramInfoLog( program ) + "
"; + alert( msg ); + return -1; + } + + return program; +} diff --git a/shadedCube_js/shadedCube.js b/shadedCube_js/shadedCube.js new file mode 100644 index 0000000..0e23343 --- /dev/null +++ b/shadedCube_js/shadedCube.js @@ -0,0 +1,259 @@ + + +var canvas; +var gl; + +var numVertices = 36; + +var pointsArray = []; +var normalsArray = []; + +var vertices = [ + vec4( -0.5, -0.5, 0.5, 1.0 ), + vec4( -0.5, 0.5, 0.5, 1.0 ), + vec4( 0.5, 0.5, 0.5, 1.0 ), + vec4( 0.5, -0.5, 0.5, 1.0 ), + vec4( -0.5, -0.5, -0.5, 1.0 ), + vec4( -0.5, 0.5, -0.5, 1.0 ), + vec4( 0.5, 0.5, -0.5, 1.0 ), + vec4( 0.5, -0.5, -0.5, 1.0 ) + ]; + +var lightPosition = vec4(1.0, 1.0, 1.0, 0.0 ); +var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0 ); +var lightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 ); +var lightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 ); + +var materialAmbient = vec4( 1.0, 1.0, 1.0, 1.0 ); +var materialDiffuse = vec4( 1.0, 1.0, 1.0, 1.0); +var materialSpecular = vec4( 1.0, 1.0, 1.0, 1.0 ); +var materialShininess = 100.0; + +var ctm; +var ambientColor, diffuseColor, specularColor; +var modelView, projection; +var viewerPos; +var program; + +var xAxis = 0; +var yAxis = 1; +var zAxis = 2; +var axis = 0; +var theta =[0, 0, 0]; + +var thetaLoc; + +var flag = true; + +var textureBuffer; +var text1; + +const texturePositions = [ + // top + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + + 0, 1, + 0, 0, + 1, 0, + 0, 1, + 1, 0, + 1, 1, + +]; + +function quad(a, b, c, d) { + + var t1 = subtract(vertices[b], vertices[a]); + var t2 = subtract(vertices[c], vertices[b]); + var normal = cross(t1, t2); + var normal = vec3(normal); + + + pointsArray.push(vertices[a]); + normalsArray.push(normal); + pointsArray.push(vertices[b]); + normalsArray.push(normal); + pointsArray.push(vertices[c]); + normalsArray.push(normal); + pointsArray.push(vertices[a]); + normalsArray.push(normal); + pointsArray.push(vertices[c]); + normalsArray.push(normal); + pointsArray.push(vertices[d]); + normalsArray.push(normal); +} + + +function colorCube() +{ + quad( 1, 0, 3, 2 ); + quad( 2, 3, 7, 6 ); + quad( 3, 0, 4, 7 ); + quad( 6, 5, 1, 2 ); + quad( 4, 5, 6, 7 ); + quad( 5, 4, 0, 1 ); +} + + +window.onload = function init() { + canvas = document.getElementById( "gl-canvas" ); + + //gl = WebGLUtils.setupWebGL( canvas ); + gl = canvas.getContext("webgl2"); + if ( !gl ) { alert( "WebGL isn't available" ); } + + gl.viewport( 0, 0, canvas.width, canvas.height ); + gl.clearColor( 1.0, 1.0, 1.0, 1.0 ); + + gl.enable(gl.DEPTH_TEST); + + // + // Load shaders and initialize attribute buffers + // + program = initShaders( gl, "vertex-shader", "fragment-shader" ); + gl.useProgram( program ); + + colorCube(); + + var nBuffer = gl.createBuffer(); + gl.bindBuffer( gl.ARRAY_BUFFER, nBuffer ); + gl.bufferData( gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW ); + + var vNormal = gl.getAttribLocation( program, "vNormal" ); + gl.vertexAttribPointer( vNormal, 3, gl.FLOAT, false, 0, 0 ); + gl.enableVertexAttribArray( vNormal ); + + var vBuffer = gl.createBuffer(); + gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer ); + gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW ); + + var vPosition = gl.getAttribLocation(program, "vPosition"); + gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(vPosition); + + textureBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texturePositions), gl.STATIC_DRAW); + + thetaLoc = gl.getUniformLocation(program, "theta"); + + viewerPos = vec3(0.0, 0.0, -20.0 ); + + projection = ortho(-1, 1, -1, 1, -100, 100); + + ambientProduct = mult(lightAmbient, materialAmbient); + diffuseProduct = mult(lightDiffuse, materialDiffuse); + specularProduct = mult(lightSpecular, materialSpecular); + + var value = 10.0; + document.getElementById("ButtonX").onclick = function(){axis = xAxis;}; + document.getElementById("ButtonY").onclick = function(){axis = yAxis;}; + document.getElementById("ButtonZ").onclick = function(){axis = zAxis;}; + document.getElementById("ButtonT").onclick = function(){flag = !flag;}; + document.getElementById("LightX+").onclick = function(){lightPosition[0] = lightPosition[0] + value;}; + document.getElementById("LightX-").onclick = function(){lightPosition[0] = lightPosition[0] - value;}; + document.getElementById("LightY+").onclick = function(){lightPosition[1] = lightPosition[1] + value;}; + document.getElementById("LightY-").onclick = function(){lightPosition[1] = lightPosition[1] - value;}; + document.getElementById("LightZ+").onclick = function(){lightPosition[2] = lightPosition[2] + value;}; + document.getElementById("LightZ-").onclick = function(){lightPosition[2] = lightPosition[2] - value;}; + + gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"), + flatten(ambientProduct)); + gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"), + flatten(diffuseProduct) ); + gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"), + flatten(specularProduct) ); + gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"), + flatten(lightPosition) ); + + gl.uniform1f(gl.getUniformLocation(program, + "shininess"),materialShininess); + + gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), + false, flatten(projection)); + + text1 = loadTexture(); + + + render(); +} + +function loadTexture() { + var createTexture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, createTexture); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255, 255])); + + var image = new Image(); + image.src = "snowflake.png"; + image.addEventListener('load', function() { + + gl.bindTexture(gl.TEXTURE_2D, createTexture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image); + gl.generateMipmap(gl.TEXTURE_2D); + gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR ); + gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); + }); + + gl.uniform1i(gl.getUniformLocation(program, "textureSampler"), 0); + return createTexture; +} + +var render = function(){ + + gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + if(flag) theta[axis] += 2.0; + + modelView = mat4(); + modelView = mult(modelView, rotate(theta[xAxis], [1, 0, 0] )); + modelView = mult(modelView, rotate(theta[yAxis], [0, 1, 0] )); + modelView = mult(modelView, rotate(theta[zAxis], [0, 0, 1] )); + + gl.uniformMatrix4fv( gl.getUniformLocation(program, + "modelViewMatrix"), false, flatten(modelView) ); + + gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"), flatten(lightPosition) ); + + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.vertexAttribPointer(gl.getAttribLocation(program, "texturePosition"), 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(gl.getAttribLocation(program, "texturePosition")); + + gl.drawArrays( gl.TRIANGLES, 0, numVertices ); + + + requestAnimFrame(render); +} diff --git a/shadedCube_js/webgl-utils.js b/shadedCube_js/webgl-utils.js new file mode 100644 index 0000000..289cadd --- /dev/null +++ b/shadedCube_js/webgl-utils.js @@ -0,0 +1,164 @@ +/* + * Copyright 2010, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/** + * @fileoverview This file contains functions every webgl program will need + * a version of one way or another. + * + * Instead of setting up a context manually it is recommended to + * use. This will check for success or failure. On failure it + * will attempt to present an approriate message to the user. + * + * gl = WebGLUtils.setupWebGL(canvas); + * + * For animated WebGL apps use of setTimeout or setInterval are + * discouraged. It is recommended you structure your rendering + * loop like this. + * + * function render() { + * window.requestAnimFrame(render, canvas); + * + * // do rendering + * ... + * } + * render(); + * + * This will call your rendering function up to the refresh rate + * of your display but will stop rendering if your app is not + * visible. + */ + +WebGLUtils = function() { + +/** + * Creates the HTLM for a failure message + * @param {string} canvasContainerId id of container of th + * canvas. + * @return {string} The html. + */ +var makeFailHTML = function(msg) { + return '' + + '' + + '
' + + '
' + + '
' + msg + '
' + + '
' + + '
'; +}; + +/** + * Mesasge for getting a webgl browser + * @type {string} + */ +var GET_A_WEBGL_BROWSER = '' + + 'This page requires a browser that supports WebGL.
' + + 'Click here to upgrade your browser.'; + +/** + * Mesasge for need better hardware + * @type {string} + */ +var OTHER_PROBLEM = '' + + "It doesn't appear your computer can support WebGL.
" + + 'Click here for more information.'; + +/** + * Creates a webgl context. If creation fails it will + * change the contents of the container of the + * tag to an error message with the correct links for WebGL. + * @param {Element} canvas. The canvas element to create a + * context from. + * @param {WebGLContextCreationAttirbutes} opt_attribs Any + * creation attributes you want to pass in. + * @return {WebGLRenderingContext} The created context. + */ +var setupWebGL = function(canvas, opt_attribs) { + function showLink(str) { + var container = canvas.parentNode; + if (container) { + container.innerHTML = makeFailHTML(str); + } + }; + + if (!window.WebGLRenderingContext) { + showLink(GET_A_WEBGL_BROWSER); + return null; + } + + var context = create3DContext(canvas, opt_attribs); + if (!context) { + showLink(OTHER_PROBLEM); + } + return context; +}; + +/** + * Creates a webgl context. + * @param {!Canvas} canvas The canvas tag to get context + * from. If one is not passed in one will be created. + * @return {!WebGLContext} The created context. + */ +var create3DContext = function(canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + try { + context = canvas.getContext(names[ii], opt_attribs); + } catch(e) {} + if (context) { + break; + } + } + return context; +} + +return { + create3DContext: create3DContext, + setupWebGL: setupWebGL +}; +}(); + +/** + * Provides requestAnimationFrame in a cross browser way. + */ +window.requestAnimFrame = (function() { + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { + window.setTimeout(callback, 1000/60); + }; +})(); + + diff --git a/snowflake.png b/snowflake.png new file mode 100644 index 0000000..a449ced Binary files /dev/null and b/snowflake.png differ