1/* 2 * Copyright 2010, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 33/** 34 * @fileoverview This file contains functions every webgl program will need 35 * a version of one way or another. 36 * 37 * Instead of setting up a context manually it is recommended to 38 * use. This will check for success or failure. On failure it 39 * will attempt to present an approriate message to the user. 40 * 41 * gl = WebGLUtils.setupWebGL(canvas); 42 * 43 * For animated WebGL apps use of setTimeout or setInterval are 44 * discouraged. It is recommended you structure your rendering 45 * loop like this. 46 * 47 * function render() { 48 * window.requestAnimFrame(render, canvas); 49 * 50 * // do rendering 51 * ... 52 * } 53 * render(); 54 * 55 * This will call your rendering function up to the refresh rate 56 * of your display but will stop rendering if your app is not 57 * visible. 58 */ 59 60WebGLUtils = function() { 61 62/** 63 * Creates the HTLM for a failure message 64 * @param {string} canvasContainerId id of container of th 65 * canvas. 66 * @return {string} The html. 67 */ 68var makeFailHTML = function(msg) { 69 return '' + 70 '<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' + 71 '<td align="center">' + 72 '<div style="display: table-cell; vertical-align: middle;">' + 73 '<div style="">' + msg + '</div>' + 74 '</div>' + 75 '</td></tr></table>'; 76}; 77 78/** 79 * Mesasge for getting a webgl browser 80 * @type {string} 81 */ 82var GET_A_WEBGL_BROWSER = '' + 83 'This page requires a browser that supports WebGL.<br/>' + 84 '<a href="http://get.webgl.org">Click here to upgrade your browser.</a>'; 85 86/** 87 * Mesasge for need better hardware 88 * @type {string} 89 */ 90var OTHER_PROBLEM = '' + 91 "It doesn't appear your computer can support WebGL.<br/>" + 92 '<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>'; 93 94/** 95 * Creates a webgl context. If creation fails it will 96 * change the contents of the container of the <canvas> 97 * tag to an error message with the correct links for WebGL. 98 * @param {Element} canvas. The canvas element to create a 99 * context from. 100 * @param {WebGLContextCreationAttirbutes} opt_attribs Any 101 * creation attributes you want to pass in. 102 * @return {WebGLRenderingContext} The created context. 103 */ 104var setupWebGL = function(canvas, opt_attribs) { 105 function showLink(str) { 106 var container = canvas.parentNode; 107 if (container) { 108 container.innerHTML = makeFailHTML(str); 109 } 110 }; 111 112 if (!window.WebGLRenderingContext) { 113 showLink(GET_A_WEBGL_BROWSER); 114 return null; 115 } 116 117 var context = create3DContext(canvas, opt_attribs); 118 if (!context) { 119 showLink(OTHER_PROBLEM); 120 } 121 return context; 122}; 123 124/** 125 * Creates a webgl context. 126 * @param {!Canvas} canvas The canvas tag to get context 127 * from. If one is not passed in one will be created. 128 * @return {!WebGLContext} The created context. 129 */ 130var create3DContext = function(canvas, opt_attribs) { 131 var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; 132 var context = null; 133 for (var ii = 0; ii < names.length; ++ii) { 134 try { 135 context = canvas.getContext(names[ii], opt_attribs); 136 } catch(e) {} 137 if (context) { 138 break; 139 } 140 } 141 return context; 142} 143 144return { 145 create3DContext: create3DContext, 146 setupWebGL: setupWebGL 147}; 148}(); 149 150/** 151 * Provides requestAnimationFrame in a cross browser way. 152 */ 153window.requestAnimFrame = (function() { 154 return window.requestAnimationFrame || 155 window.webkitRequestAnimationFrame || 156 window.mozRequestAnimationFrame || 157 window.oRequestAnimationFrame || 158 window.msRequestAnimationFrame || 159 function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { 160 return window.setTimeout(callback, 1000/60); 161 }; 162})(); 163 164/** 165 * Provides cancelAnimationFrame in a cross browser way. 166 */ 167window.cancelAnimFrame = (function() { 168 return window.cancelAnimationFrame || 169 window.webkitCancelAnimationFrame || 170 window.mozCancelAnimationFrame || 171 window.oCancelAnimationFrame || 172 window.msCancelAnimationFrame || 173 window.clearTimeout; 174})(); 175 176 177