Skip to content
Snippets Groups Projects
Commit 8a27fea6 authored by jialeh2's avatar jialeh2
Browse files

s

parents
Branches master
No related tags found
No related merge requests found
Pipeline #183304 failed
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Hello Terrain </title>
<meta charset="utf-8">
</head>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexNormal;
attribute vec3 aVertexPosition;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uLightPosition;
uniform vec3 uAmbientLightColor;
uniform vec3 uDiffuseLightColor;
uniform vec3 uSpecularLightColor;
uniform vec3 uKAmbient;
uniform vec3 uKDiffuse;
uniform vec3 uKSpecular;
uniform float uShininess;
varying vec4 vColor;
void main(void) {
// Get the vertex position in eye coordinates
vec4 vertexPositionEye4 = uMVMatrix * vec4(aVertexPosition, 1.0);
vec3 vertexPositionEye3 = vertexPositionEye4.xyz / vertexPositionEye4.w;
// Calculate the vector (l) to the light source
vec3 vectorToLightSource = normalize(uLightPosition - vertexPositionEye3);
// Transform the normal (n) to eye coordinates
vec3 normalEye = normalize(uNMatrix * aVertexNormal);
// Calculate n dot l for diffuse lighting
float diffuseLightWeightning = max(dot(normalEye,
vectorToLightSource), 0.0);
// Calculate the reflection vector (r) that is needed for specular light
vec3 reflectionVector = normalize(reflect(-vectorToLightSource,
normalEye));
// The camera in eye coordinates is located in the origin and is pointing
// along the negative z-axis. Calculate viewVector (v)
// in eye coordinates as:
// (0.0, 0.0, 0.0) - vertexPositionEye3
vec3 viewVectorEye = -normalize(vertexPositionEye3);
float rdotv = max(dot(reflectionVector, viewVectorEye), 0.0);
float specularLightWeightning = pow(rdotv, uShininess);
// Sum up all three reflection components and send to the fragment shader
vColor = vec4(((uAmbientLightColor*uKAmbient)
+ (uDiffuseLightColor*uKDiffuse) * diffuseLightWeightning
+ ((uSpecularLightColor*uKSpecular) * specularLightWeightning)),1.0);
gl_Position = uPMatrix*uMVMatrix*vec4(aVertexPosition, 1.0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script src="gl-matrix-min.js"></script>
<script src="webgl-utils.js"></script>
<script src="Terrain.js"></script>
<script src="HelloTerrain.js"></script>
<body onload="startup();">
<canvas id="myGLCanvas" width="800" height="800"></canvas>
<form id="input_form">
<fieldset>
<legend>Rendering Parameters</legend>
<input type="radio" name="primitive" id="wireframe" value="wireframe"> Wireframe
<input type="radio" name="primitive" id="polygon" id="polygon" value="polygon" checked> Polygon
<input type="radio" name="primitive" id="wirepoly" value="wirepoly" > Polygon with Edges
</fieldset>
</form>
</body>
</html>
/**
* @file A simple WebGL example drawing central Illinois style terrain
* @author Eric Shaffer <shaffer1@illinois.edu>
*/
/** @global The WebGL context */
var gl;
/** @global The HTML5 canvas we draw on */
var canvas;
/** @global A simple GLSL shader program */
var shaderProgram;
/** @global The Modelview matrix */
var mvMatrix = mat4.create();
/** @global The Projection matrix */
var pMatrix = mat4.create();
/** @global The Normal matrix */
var nMatrix = mat3.create();
/** @global The matrix stack for hierarchical modeling */
var mvMatrixStack = [];
/** @global The angle of rotation around the y axis */
var viewRot = 10;
/** @global A glmatrix vector to use for transformations */
var transformVec = vec3.create();
// Initialize the vector....
vec3.set(transformVec,0.0,0.0,-2.0);
/** @global An object holding the geometry for a 3D terrain */
var myTerrain;
// View parameters
/** @global Location of the camera in world coordinates */
var eyePt = vec3.fromValues(0.0,0.0,0.0);
/** @global Direction of the view in world coordinates */
var viewDir = vec3.fromValues(0.0,0.0,-1.0);
/** @global Up vector for view matrix creation, in world coordinates */
var up = vec3.fromValues(0.0,1.0,0.0);
/** @global Location of a point along viewDir in world coordinates */
var viewPt = vec3.fromValues(0.0,0.0,0.0);
//Light parameters
/** @global Light position in VIEW coordinates */
var lightPosition = [0,3,3];
/** @global Ambient light color/intensity for Phong reflection */
var lAmbient = [0,0,0];
/** @global Diffuse light color/intensity for Phong reflection */
var lDiffuse = [1,1,1];
/** @global Specular light color/intensity for Phong reflection */
var lSpecular =[0,0,0];
//Material parameters
/** @global Ambient material color/intensity for Phong reflection */
var kAmbient = [1.0,1.0,1.0];
/** @global Diffuse material color/intensity for Phong reflection */
var kTerrainDiffuse = [205.0/255.0,163.0/255.0,63.0/255.0];
/** @global Specular material color/intensity for Phong reflection */
var kSpecular = [0.0,0.0,0.0];
/** @global Shininess exponent for Phong reflection */
var shininess = 23;
/** @global Edge color fpr wireframeish rendering */
var kEdgeBlack = [0.0,0.0,0.0];
/** @global Edge color for wireframe rendering */
var kEdgeWhite = [1.0,1.0,1.0];
//-------------------------------------------------------------------------
/**
* Sends Modelview matrix to shader
*/
function uploadModelViewMatrixToShader() {
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
//-------------------------------------------------------------------------
/**
* Sends projection matrix to shader
*/
function uploadProjectionMatrixToShader() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform,
false, pMatrix);
}
//-------------------------------------------------------------------------
/**
* Generates and sends the normal matrix to the shader
*/
function uploadNormalMatrixToShader() {
mat3.fromMat4(nMatrix,mvMatrix);
mat3.transpose(nMatrix,nMatrix);
mat3.invert(nMatrix,nMatrix);
gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, nMatrix);
}
//----------------------------------------------------------------------------------
/**
* Pushes matrix onto modelview matrix stack
*/
function mvPushMatrix() {
var copy = mat4.clone(mvMatrix);
mvMatrixStack.push(copy);
}
//----------------------------------------------------------------------------------
/**
* Pops matrix off of modelview matrix stack
*/
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
//----------------------------------------------------------------------------------
/**
* Sends projection/modelview matrices to shader
*/
function setMatrixUniforms() {
uploadModelViewMatrixToShader();
uploadNormalMatrixToShader();
uploadProjectionMatrixToShader();
}
//----------------------------------------------------------------------------------
/**
* Translates degrees to radians
* @param {Number} degrees Degree input to function
* @return {Number} The radians that correspond to the degree input
*/
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
//----------------------------------------------------------------------------------
/**
* Creates a context for WebGL
* @param {element} canvas WebGL canvas
* @return {Object} WebGL context
*/
function createGLContext(canvas) {
var names = ["webgl", "experimental-webgl"];
var context = null;
for (var i=0; i < names.length; i++) {
try {
context = canvas.getContext(names[i]);
} catch(e) {}
if (context) {
break;
}
}
if (context) {
context.viewportWidth = canvas.width;
context.viewportHeight = canvas.height;
} else {
alert("Failed to create WebGL context!");
}
return context;
}
//----------------------------------------------------------------------------------
/**
* Loads Shaders
* @param {string} id ID string for shader to load. Either vertex shader/fragment shader
*/
function loadShaderFromDOM(id) {
var shaderScript = document.getElementById(id);
// If we don't find an element with the specified id
// we do an early exit
if (!shaderScript) {
return null;
}
// Loop through the children for the found DOM element and
// build up the shader source code as a string
var shaderSource = "";
var currentChild = shaderScript.firstChild;
while (currentChild) {
if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
shaderSource += currentChild.textContent;
}
currentChild = currentChild.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, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
//----------------------------------------------------------------------------------
/**
* Setup the fragment and vertex shaders
*/
function setupShaders() {
vertexShader = loadShaderFromDOM("shader-vs");
fragmentShader = loadShaderFromDOM("shader-fs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Failed to setup shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
shaderProgram.uniformLightPositionLoc = gl.getUniformLocation(shaderProgram, "uLightPosition");
shaderProgram.uniformAmbientLightColorLoc = gl.getUniformLocation(shaderProgram, "uAmbientLightColor");
shaderProgram.uniformDiffuseLightColorLoc = gl.getUniformLocation(shaderProgram, "uDiffuseLightColor");
shaderProgram.uniformSpecularLightColorLoc = gl.getUniformLocation(shaderProgram, "uSpecularLightColor");
shaderProgram.uniformShininessLoc = gl.getUniformLocation(shaderProgram, "uShininess");
shaderProgram.uniformAmbientMaterialColorLoc = gl.getUniformLocation(shaderProgram, "uKAmbient");
shaderProgram.uniformDiffuseMaterialColorLoc = gl.getUniformLocation(shaderProgram, "uKDiffuse");
shaderProgram.uniformSpecularMaterialColorLoc = gl.getUniformLocation(shaderProgram, "uKSpecular");
}
//-------------------------------------------------------------------------
/**
* Sends material information to the shader
* @param {Float32} alpha shininess coefficient
* @param {Float32Array} a Ambient material color
* @param {Float32Array} d Diffuse material color
* @param {Float32Array} s Specular material color
*/
function setMaterialUniforms(alpha,a,d,s) {
gl.uniform1f(shaderProgram.uniformShininessLoc, alpha);
gl.uniform3fv(shaderProgram.uniformAmbientMaterialColorLoc, a);
gl.uniform3fv(shaderProgram.uniformDiffuseMaterialColorLoc, d);
gl.uniform3fv(shaderProgram.uniformSpecularMaterialColorLoc, s);
}
//-------------------------------------------------------------------------
/**
* Sends light information to the shader
* @param {Float32Array} loc Location of light source
* @param {Float32Array} a Ambient light strength
* @param {Float32Array} d Diffuse light strength
* @param {Float32Array} s Specular light strength
*/
function setLightUniforms(loc,a,d,s) {
gl.uniform3fv(shaderProgram.uniformLightPositionLoc, loc);
gl.uniform3fv(shaderProgram.uniformAmbientLightColorLoc, a);
gl.uniform3fv(shaderProgram.uniformDiffuseLightColorLoc, d);
gl.uniform3fv(shaderProgram.uniformSpecularLightColorLoc, s);
}
//----------------------------------------------------------------------------------
/**
* Populate buffers with data
*/
function setupBuffers() {
myTerrain = new Terrain(40,-0.5,0.5,-0.5,0.5);
myTerrain.loadBuffers();
}
//----------------------------------------------------------------------------------
/**
* Draw call that applies matrix transformations to model and draws model in frame
*/
function draw() {
//console.log("function draw()")
var transformVec = vec3.create();
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// We'll use perspective
mat4.perspective(pMatrix,degToRad(45),
gl.viewportWidth / gl.viewportHeight,
0.1, 200.0);
// We want to look down -z, so create a lookat point in that direction
vec3.add(viewPt, eyePt, viewDir);
// Then generate the lookat matrix and initialize the MV matrix to that view
mat4.lookAt(mvMatrix,eyePt,viewPt,up);
//Draw Terrain
mvPushMatrix();
vec3.set(transformVec,0.0,-0.25,-2.0);
mat4.translate(mvMatrix, mvMatrix,transformVec);
mat4.rotateY(mvMatrix, mvMatrix, degToRad(viewRot));
mat4.rotateX(mvMatrix, mvMatrix, degToRad(-75));
setMatrixUniforms();
setLightUniforms(lightPosition,lAmbient,lDiffuse,lSpecular);
if ((document.getElementById("polygon").checked) || (document.getElementById("wirepoly").checked))
{
setMaterialUniforms(shininess,kAmbient,kTerrainDiffuse,kSpecular);
myTerrain.drawTriangles();
}
if(document.getElementById("wirepoly").checked)
{
setMaterialUniforms(shininess,kAmbient,kEdgeBlack,kSpecular);
myTerrain.drawEdges();
}
if(document.getElementById("wireframe").checked)
{
setMaterialUniforms(shininess,kAmbient,kEdgeWhite,kSpecular);
myTerrain.drawEdges();
}
mvPopMatrix();
}
//----------------------------------------------------------------------------------
/**
* Startup function called from html code to start program.
*/
function startup() {
canvas = document.getElementById("myGLCanvas");
gl = createGLContext(canvas);
setupShaders();
setupBuffers();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
tick();
}
//----------------------------------------------------------------------------------
/**
* Keeping drawing frames....
*/
function tick() {
requestAnimFrame(tick);
draw();
}
/**
* @fileoverview Terrain - A simple 3D terrain using WebGL
* @author Eric Shaffer
*/
/** Class implementing 3D terrain. */
class Terrain{
/**
* Initialize members of a Terrain object
* @param {number} div Number of triangles along x axis and y axis
* @param {number} minX Minimum X coordinate value
* @param {number} maxX Maximum X coordinate value
* @param {number} minY Minimum Y coordinate value
* @param {number} maxY Maximum Y coordinate value
*/
constructor(div,minX,maxX,minY,maxY){
this.div = div;
this.minX=minX;
this.minY=minY;
this.maxX=maxX;
this.maxY=maxY;
// Allocate vertex array
this.vBuffer = [];
// Allocate triangle array
this.fBuffer = [];
// Allocate normal array
this.nBuffer = [];
// Allocate array for edges so we can draw wireframe
this.eBuffer = [];
console.log("Terrain: Allocated buffers");
this.generateTriangles();
console.log("Terrain: Generated triangles");
this.generateLines();
console.log("Terrain: Generated lines");
for(var i=0; i<200; i++){
this.geneartePlane(0.005);
}
// Get extension for 4 byte integer indices for drwElements
var ext = gl.getExtension('OES_element_index_uint');
if (ext ==null){
alert("OES_element_index_uint is unsupported by your browser and terrain generation cannot proceed.");
}
}
/**
* Set the x,y,z coords of a vertex at location(i,j)
* @param {Object} v an an array of length 3 holding x,y,z coordinates
* @param {number} i the ith row of vertices
* @param {number} j the jth column of vertices
*/
setVertex(v,i,j)
{
var vid = 3*(i(this.div+1)+j);
this.vBuffer[vid] = v[0];
this.vBuffer[vid+1] = v[1];
this.vBuffer[vid+2] = v[2];
//Your code here
}
/**
* Return the x,y,z coordinates of a vertex at location (i,j)
* @param {Object} v an an array of length 3 holding x,y,z coordinates
* @param {number} i the ith row of vertices
* @param {number} j the jth column of vertices
*/
getVertex(v,i,j)
{
//Your code here
var vid = 3*(i*(this.div+1) + j);
v[0] = this.vBuffer[vid];
v[1] = this.vBuffer[vid+1];
v[2] = this.vBuffer[vid+2];
}
geneartePlane(delta)
{
var xn = this.div * (Math.random()-Math.random());
var yn = this.div * (Math.random()-Math.random());
xn = xn/Math.sqrt(xn*xn + yn*yn);
yn = yn/Math.sqrt(xn*xn + yn*yn);
var xp = this.div * Math.random();
var yp = this.div * Math.random();
for (var i = 0; i <=this.div; i++){
for (var j = 0; j <=this.div; j++){
var vid = 3*(i*(this.div+1)+j);
if ((((i-xp)*xn + (j-yp)*yn) >0)&&(this.vBuffer[vid+2]<=0.8)){
this.vBuffer[vid+2] += delta;
}
if ((((i-xp)*xn + (j-yp)*yn) <= 0) && (this.vBuffer[vid+2]>= -0.3)){
this.vBuffer[vid+2] -= delta;
}
}
}
}
getNormals()
{
for(var i=0; i<this.fBuffer.length; i+=3)
{}
}
/**
* Send the buffer objects to WebGL for rendering
*/
loadBuffers()
{
// Specify the vertex coordinates
this.VertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.vBuffer), gl.STATIC_DRAW);
this.VertexPositionBuffer.itemSize = 3;
this.VertexPositionBuffer.numItems = this.numVertices;
console.log("Loaded ", this.VertexPositionBuffer.numItems, " vertices");
// Specify normals to be able to do lighting calculations
this.VertexNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.nBuffer),
gl.STATIC_DRAW);
this.VertexNormalBuffer.itemSize = 3;
this.VertexNormalBuffer.numItems = this.numVertices;
console.log("Loaded ", this.VertexNormalBuffer.numItems, " normals");
// Specify faces of the terrain
this.IndexTriBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexTriBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(this.fBuffer),
gl.STATIC_DRAW);
this.IndexTriBuffer.itemSize = 1;
this.IndexTriBuffer.numItems = this.fBuffer.length;
console.log("Loaded ", this.IndexTriBuffer.numItems, " triangles");
//Setup Edges
this.IndexEdgeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexEdgeBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(this.eBuffer),
gl.STATIC_DRAW);
this.IndexEdgeBuffer.itemSize = 1;
this.IndexEdgeBuffer.numItems = this.eBuffer.length;
console.log("triangulatedPlane: loadBuffers");
}
/**
* Render the triangles
*/
drawTriangles(){
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.VertexPositionBuffer.itemSize,
gl.FLOAT, false, 0, 0);
// Bind normal buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
this.VertexNormalBuffer.itemSize,
gl.FLOAT, false, 0, 0);
//Draw
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexTriBuffer);
gl.drawElements(gl.TRIANGLES, this.IndexTriBuffer.numItems, gl.UNSIGNED_INT,0);
}
/**
* Render the triangle edges wireframe style
*/
drawEdges(){
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.VertexPositionBuffer.itemSize,
gl.FLOAT, false, 0, 0);
// Bind normal buffer
gl.bindBuffer(gl.ARRAY_BUFFER, this.VertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
this.VertexNormalBuffer.itemSize,
gl.FLOAT, false, 0, 0);
//Draw
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.IndexEdgeBuffer);
gl.drawElements(gl.LINES, this.IndexEdgeBuffer.numItems, gl.UNSIGNED_INT,0);
}
/**
* Fill the vertex and buffer arrays
*/
generateTriangles()
{
//Your code here
var deltaX=(this.maxX-this.minX)/this.div;
var deltaY=(this.maxY-this.minY)/this.div;
for(var i=0;i<=this.div;i++)
for(var j=0;j<=this.div;j++)
{
this.vBuffer.push(this.minX+deltaX*j);
this.vBuffer.push(this.minY+deltaY*i);
this.vBuffer.push(0);
this.nBuffer.push(0);
this.nBuffer.push(0);
this.nBuffer.push(1);
}
for(var i=0;i<this.div;i++)
for(var j=0;j<this.div;j++)
{
var vid = i*(this.div+1) + j;
this.fBuffer.push(vid);
this.fBuffer.push(vid+1);
this.fBuffer.push(vid+this.div+1);
this.fBuffer.push(vid+1);
this.fBuffer.push(vid+1+this.div+1);
this.fBuffer.push(vid+this.div+1);
}
//
this.numVertices = this.vBuffer.length/3;
this.numFaces = this.fBuffer.length/3;
}
/**
* Print vertices and triangles to console for debugging
*/
printBuffers()
{
for(var i=0;i<this.numVertices;i++)
{
console.log("v ", this.vBuffer[i*3], " ",
this.vBuffer[i*3 + 1], " ",
this.vBuffer[i*3 + 2], " ");
}
for(var i=0;i<this.numFaces;i++)
{
console.log("f ", this.fBuffer[i*3], " ",
this.fBuffer[i*3 + 1], " ",
this.fBuffer[i*3 + 2], " ");
}
}
/**
* Generates line values from faces in faceArray
* to enable wireframe rendering
*/
generateLines()
{
var numTris=this.fBuffer.length/3;
for(var f=0;f<numTris;f++)
{
var fid=f*3;
this.eBuffer.push(this.fBuffer[fid]);
this.eBuffer.push(this.fBuffer[fid+1]);
this.eBuffer.push(this.fBuffer[fid+1]);
this.eBuffer.push(this.fBuffer[fid+2]);
this.eBuffer.push(this.fBuffer[fid+2]);
this.eBuffer.push(this.fBuffer[fid]);
}
}
}
This diff is collapsed.
/*
* 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 '' +
'<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
'<td align="center">' +
'<div style="display: table-cell; vertical-align: middle;">' +
'<div style="">' + msg + '</div>' +
'</div>' +
'</td></tr></table>';
};
/**
* Mesasge for getting a webgl browser
* @type {string}
*/
var GET_A_WEBGL_BROWSER = '' +
'This page requires a browser that supports WebGL.<br/>' +
'<a href="http://get.webgl.org">Click here to upgrade your browser.</a>';
/**
* Mesasge for need better hardware
* @type {string}
*/
var OTHER_PROBLEM = '' +
"It doesn't appear your computer can support WebGL.<br/>" +
'<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>';
/**
* Creates a webgl context. If creation fails it will
* change the contents of the container of the <canvas>
* 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.
* @param {function:(msg)} opt_onError An function to call
* if there is an error during creation.
* @return {WebGLRenderingContext} The created context.
*/
var setupWebGL = function(canvas, opt_attribs, opt_onError) {
function handleCreationError(msg) {
var container = canvas.parentNode;
if (container) {
var str = window.WebGLRenderingContext ?
OTHER_PROBLEM :
GET_A_WEBGL_BROWSER;
if (msg) {
str += "<br/><br/>Status: " + msg;
}
container.innerHTML = makeFailHTML(str);
}
};
opt_onError = opt_onError || handleCreationError;
if (canvas.addEventListener) {
canvas.addEventListener("webglcontextcreationerror", function(event) {
opt_onError(event.statusMessage);
}, false);
}
var context = create3DContext(canvas, opt_attribs);
if (!context) {
if (!window.WebGLRenderingContext) {
opt_onError("");
}
}
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);
};
})();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment