| <!DOCTYPE html> |
| <!-- |
| /* |
| * Copyright (C) 2009 Apple 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: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. 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. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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. |
| */ |
| --> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| <title>Spinning WebGL Box</title> |
| |
| <script src="resources/J3DI.js"> </script> |
| <script src="resources/J3DIMath.js" type="text/javascript"> </script> |
| <script id="vshader" type="x-shader/x-vertex"> |
| uniform mat4 u_modelViewProjMatrix; |
| uniform mat4 u_normalMatrix; |
| uniform vec3 lightDir; |
| |
| attribute vec3 vNormal; |
| attribute vec4 vColor; |
| attribute vec4 vPosition; |
| |
| varying float v_Dot; |
| varying vec4 v_Color; |
| |
| void main() |
| { |
| gl_Position = u_modelViewProjMatrix * vPosition; |
| v_Color = vColor; |
| vec4 transNormal = u_normalMatrix * vec4(vNormal, 1); |
| v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); |
| } |
| </script> |
| |
| <script id="fshader" type="x-shader/x-fragment"> |
| #ifdef GL_ES |
| precision mediump float; |
| #endif |
| |
| varying float v_Dot; |
| varying vec4 v_Color; |
| |
| void main() |
| { |
| gl_FragColor = vec4(v_Color.xyz * v_Dot, v_Color.a); |
| } |
| </script> |
| |
| <script> |
| function init() |
| { |
| // Initialize |
| var gl = initWebGL( |
| // The id of the Canvas Element |
| "example", |
| // The ids of the vertex and fragment shaders |
| "vshader", "fshader", |
| // The vertex attribute names used by the shaders. |
| // The order they appear here corresponds to their index |
| // used later. |
| [ "vNormal", "vColor", "vPosition"], |
| // The clear color and depth values |
| [ 0, 0, 0, 1 ], 10000); |
| |
| gl.console.log("Starting init..."); |
| |
| // Set up a uniform variable for the shaders |
| gl.uniform3f(gl.getUniformLocation(gl.program, "lightDir"), 0, 0, 1); |
| |
| // Create a box. On return 'gl' contains a 'box' property with |
| // the BufferObjects containing the arrays for vertices, |
| // normals, texture coords, and indices. |
| gl.box = makeBox(gl); |
| |
| // Set up the array of colors for the cube's faces |
| var colors = new Uint8Array( |
| [ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, // v0-v1-v2-v3 front |
| 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, // v0-v3-v4-v5 right |
| 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, // v0-v5-v6-v1 top |
| 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, // v1-v6-v7-v2 left |
| 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, // v7-v4-v3-v2 bottom |
| 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 ] // v4-v7-v6-v5 back |
| ); |
| |
| // Set up the vertex buffer for the colors |
| gl.box.colorObject = gl.createBuffer(); |
| gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.colorObject); |
| gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); |
| |
| // Create some matrices to use later and save their locations in the shaders |
| gl.mvMatrix = new J3DIMatrix4(); |
| gl.u_normalMatrixLoc = gl.getUniformLocation(gl.program, "u_normalMatrix"); |
| gl.normalMatrix = new J3DIMatrix4(); |
| gl.u_modelViewProjMatrixLoc = |
| gl.getUniformLocation(gl.program, "u_modelViewProjMatrix"); |
| gl.mvpMatrix = new J3DIMatrix4(); |
| |
| // Enable all of the vertex attribute arrays. |
| gl.enableVertexAttribArray(0); |
| gl.enableVertexAttribArray(1); |
| gl.enableVertexAttribArray(2); |
| |
| // Set up all the vertex attributes for vertices, normals and colors |
| gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.vertexObject); |
| gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0); |
| |
| gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.normalObject); |
| gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); |
| |
| gl.bindBuffer(gl.ARRAY_BUFFER, gl.box.colorObject); |
| gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0); |
| |
| // Bind the index array |
| gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.box.indexObject); |
| |
| return gl; |
| } |
| |
| width = -1; |
| height = -1; |
| |
| function reshape(gl) |
| { |
| var canvas = document.getElementById('example'); |
| var windowWidth = window.innerWidth - 20; |
| var windowHeight = window.innerHeight - 40; |
| if (windowWidth == width && windowHeight == height) |
| return; |
| |
| width = windowWidth; |
| height = windowHeight; |
| canvas.width = width; |
| canvas.height = height; |
| |
| // Set the viewport and projection matrix for the scene |
| gl.viewport(0, 0, width, height); |
| gl.perspectiveMatrix = new J3DIMatrix4(); |
| gl.perspectiveMatrix.perspective(30, width/height, 1, 10000); |
| gl.perspectiveMatrix.lookat(0, 0, 7, 0, 0, 0, 0, 1, 0); |
| } |
| |
| function drawPicture(gl) |
| { |
| // Make sure the canvas is sized correctly. |
| reshape(gl); |
| |
| // Clear the canvas |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| |
| // Make a model/view matrix. |
| gl.mvMatrix.makeIdentity(); |
| gl.mvMatrix.rotate(20, 1,0,0); |
| gl.mvMatrix.rotate(currentAngle, 0,1,0); |
| |
| // Construct the normal matrix from the model-view matrix and pass it in |
| gl.normalMatrix.load(gl.mvMatrix); |
| gl.normalMatrix.invert(); |
| gl.normalMatrix.transpose(); |
| gl.normalMatrix.setUniform(gl, gl.u_normalMatrixLoc, false); |
| |
| // Construct the model-view * projection matrix and pass it in |
| gl.mvpMatrix.load(gl.perspectiveMatrix); |
| gl.mvpMatrix.multiply(gl.mvMatrix); |
| gl.mvpMatrix.setUniform(gl, gl.u_modelViewProjMatrixLoc, false); |
| |
| // Draw the cube |
| gl.drawElements(gl.TRIANGLES, gl.box.numIndices, gl.UNSIGNED_BYTE, 0); |
| |
| // Finish up. |
| gl.flush(); |
| |
| // Show the framerate |
| framerate.snapshot(); |
| |
| currentAngle += incAngle; |
| if (currentAngle > 360) |
| currentAngle -= 360; |
| } |
| |
| function start() |
| { |
| var c = document.getElementById("example"); |
| var w = Math.floor(window.innerWidth * 0.9); |
| var h = Math.floor(window.innerHeight * 0.9); |
| |
| c.width = w; |
| c.height = h; |
| |
| var gl = init(); |
| currentAngle = 0; |
| incAngle = 0.5; |
| framerate = new Framerate("framerate"); |
| setInterval(function() { drawPicture(gl) }, 10); |
| } |
| </script> |
| <style type="text/css"> |
| canvas { |
| //border: 2px solid black; |
| } |
| .text { |
| position:absolute; |
| top:100px; |
| left:20px; |
| font-size:2em; |
| color: blue; |
| } |
| </style> |
| </head> |
| |
| <body onload="start()"> |
| <canvas id="example"> |
| If you're seeing this your web browser doesn't support the <canvas>> element. Ouch! |
| </canvas> |
| <div class="text">This is some text over the canvas</div> |
| <div id="framerate"></div> |
| </body> |
| |
| </html> |