1<!DOCTYPE html> 2<!-- 3/* 4 * Copyright (C) 2009 Apple Inc. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 --> 28<html> 29 <head> 30 <title>Many Planets Deep</title> 31 <script type="text/javascript" src="common/webgl-utils.js"></script> 32 <script type="text/javascript" src="debug/webgl-debug.js"></script> 33 <script type="text/javascript" src="cros_fps.js"></script> 34 <script src="resources/J3DI.js"> </script> 35 <script src="resources/J3DIMath.js" type="text/javascript"> </script> 36 37 <script id="vshader" type="x-shader/x-vertex"> 38 uniform mat4 u_modelViewProjMatrix; 39 uniform mat4 u_normalMatrix; 40 uniform vec3 lightDir; 41 42 attribute vec3 vNormal; 43 attribute vec4 vTexCoord; 44 attribute vec4 vPosition; 45 46 varying float v_Dot; 47 varying vec2 v_texCoord; 48 49 void main() 50 { 51 gl_Position = u_modelViewProjMatrix * vPosition; 52 v_texCoord = vTexCoord.st; 53 vec4 transNormal = u_normalMatrix * vec4(vNormal,1); 54 v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); 55 } 56 </script> 57 58 <script id="fshader" type="x-shader/x-fragment"> 59 precision mediump float; 60 61 uniform sampler2D sampler2d; 62 63 varying float v_Dot; 64 varying vec2 v_texCoord; 65 66 void main() 67 { 68 vec4 color = texture2D(sampler2d,v_texCoord); 69 color += vec4(0.1,0.1,0.1,1); 70 gl_FragColor = vec4(color.xyz * v_Dot, color.a); 71 } 72 </script> 73 74 <script> 75 const numRowCols = 4; 76 const numLayers = 3; 77 const layoutWidth = 10; 78 const layoutHeight = 8; 79 const globeSize = 25; 80 const minIncAngle = 0.2; 81 const maxIncAngle = 2; 82 var g = {}; // globals 83 var g_crosFpsCounter = new crosFpsCounter(); 84 var then = 0.0; 85 var lastJSRenderTime = 0.0; 86 87 function init() 88 { 89 var gl = initWebGL("example"); 90 if (!gl) { 91 return; 92 } 93 g.program = simpleSetup(gl, "vshader", "fshader", 94 [ "vPosition", "vTexCoord", "vNormal"], 95 [ 0, 0, 0, 1 ], 10000); 96 gl.uniform3f(gl.getUniformLocation(g.program, "lightDir"), 0, 0, 1); 97 gl.uniform1i(gl.getUniformLocation(g.program, "sampler2d"), 0); 98 99 if (g.program) { 100 g.u_normalMatrixLoc = gl.getUniformLocation(g.program, "u_normalMatrix"); 101 g.u_modelViewProjMatrixLoc = gl.getUniformLocation(g.program, "u_modelViewProjMatrix"); 102 } 103 104 g.sphere = makeSphere(gl, 1, 30, 30); 105 106 // get the images 107 earthTexture = loadImageTexture(gl, "resources/earthmap1k.jpg"); 108 marsTexture = loadImageTexture(gl, "resources/mars500x250.png"); 109 110 return gl; 111 } 112 113 width = -1; 114 height = -1; 115 var requestId; 116 117 function reshape(ctx) 118 { 119 var canvas = document.getElementById('example'); 120 if (canvas.width == width && canvas.height == height) 121 return; 122 123 width = canvas.width; 124 height = canvas.height; 125 126 ctx.viewport(0, 0, width, height); 127 128 g.perspectiveMatrix = new J3DIMatrix4(); 129 g.perspectiveMatrix.perspective(30, width/height, 1, 10000); 130 g.perspectiveMatrix.lookat(0,0,20, 0, 0, 0, 0, 1, 0); 131 } 132 133 function drawOne(ctx, angle, x, y, z, scale, texture) 134 { 135 // setup VBOs 136 ctx.enableVertexAttribArray(0); 137 ctx.enableVertexAttribArray(1); 138 ctx.enableVertexAttribArray(2); 139 140 ctx.bindBuffer(ctx.ARRAY_BUFFER, g.sphere.vertexObject); 141 ctx.vertexAttribPointer(0, 3, ctx.FLOAT, false, 0, 0); 142 143 ctx.bindBuffer(ctx.ARRAY_BUFFER, g.sphere.normalObject); 144 ctx.vertexAttribPointer(2, 3, ctx.FLOAT, false, 0, 0); 145 146 ctx.bindBuffer(ctx.ARRAY_BUFFER, g.sphere.texCoordObject); 147 ctx.vertexAttribPointer(1, 2, ctx.FLOAT, false, 0, 0); 148 149 ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, g.sphere.indexObject); 150 151 // generate the model-view matrix 152 var mvMatrix = new J3DIMatrix4(); 153 mvMatrix.translate(x,y,z); 154 mvMatrix.rotate(30, 1,0,0); 155 mvMatrix.rotate(angle, 0,1,0); 156 mvMatrix.scale(scale, scale, scale); 157 158 // construct the normal matrix from the model-view matrix 159 var normalMatrix = new J3DIMatrix4(mvMatrix); 160 normalMatrix.invert(); 161 normalMatrix.transpose(); 162 normalMatrix.setUniform(ctx, g.u_normalMatrixLoc, false); 163 164 // construct the model-view * projection matrix 165 var mvpMatrix = new J3DIMatrix4(g.perspectiveMatrix); 166 mvpMatrix.multiply(mvMatrix); 167 mvpMatrix.setUniform(ctx, g.u_modelViewProjMatrixLoc, false); 168 169 ctx.bindTexture(ctx.TEXTURE_2D, texture); 170 ctx.drawElements(ctx.TRIANGLES, g.sphere.numIndices, ctx.UNSIGNED_SHORT, 0); 171 } 172 173 function drawPicture(ctx) 174 { 175 var now = new Date().getTime(); 176 if (then != 0.0) { 177 g_crosFpsCounter.update(then, now - then, lastJSRenderTime); 178 } 179 then = now; 180 181 reshape(ctx); 182 ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT); 183 184 var startX = -layoutWidth/2; 185 var startY = -layoutHeight/2; 186 var startZ = 0; 187 var incX = layoutWidth / (numRowCols-1); 188 var incY = layoutHeight / (numRowCols-1); 189 var incZ = -5; 190 191 for (i = 0; i < numLayers; ++i) { 192 for (j = 0; j < numRowCols; ++j) { 193 for (k = 0; k < numRowCols; ++k) { 194 var index = i * numLayers * numRowCols + j * numRowCols + k; 195 196 drawOne(ctx, currentAngles[index], 197 startX + incX * k, 198 startY + incY * j, 199 startZ + incZ * i, 200 showEarth[index] ? 1 : 0.6, showEarth[index] ? earthTexture : marsTexture); 201 202 currentAngles[index] += incAngles[index]; 203 if (currentAngles[index] > 360) 204 currentAngles[index] -= 360; 205 } 206 } 207 } 208 209 ctx.bindTexture(ctx.TEXTURE_2D, null); 210 211 framerate.snapshot(); 212 lastJSRenderTime = new Date().getTime() - then; 213 } 214 215 function start() 216 { 217 var c = document.getElementById("example"); 218 var w = Math.floor(window.innerWidth * 0.9); 219 var h = Math.floor(window.innerHeight * 0.9); 220 221 //c = WebGLDebugUtils.makeLostContextSimulatingCanvas(c); 222 // tell the simulator when to lose context. 223 //c.loseContextInNCalls(1500); 224 225 c.addEventListener('webglcontextlost', handleContextLost, false); 226 c.addEventListener('webglcontextrestored', handleContextRestored, false); 227 228 c.width = w; 229 c.height = h; 230 231 var ctx = init(); 232 if (!ctx) { 233 return; 234 } 235 236 currentAngles = [ ]; 237 incAngles = [ ]; 238 showEarth = [ ]; 239 240 for (var i = 0; i < numRowCols * numRowCols * numLayers; ++i) { 241 currentAngles[i] = 0; 242 incAngles[i] = Math.random() * (maxIncAngle - minIncAngle) + minIncAngle; 243 showEarth[i] = Math.random() > 0.5; 244 } 245 246 framerate = new Framerate("framerate"); 247 var f = function() { 248 drawPicture(ctx) 249 requestId = window.requestAnimFrame(f, c); 250 }; 251 f(); 252 253 function handleContextLost(e) { 254 e.preventDefault(); 255 clearLoadingImages(); 256 if (requestId !== undefined) { 257 window.cancelAnimFrame(requestId); 258 requestId = undefined; 259 } 260 } 261 262 function handleContextRestored() { 263 init(); 264 f(); 265 } 266 } 267 </script> 268 <style type="text/css"> 269 canvas { 270 border: 2px solid black; 271 } 272 </style> 273 </head> 274 <body onload="start()"> 275 <canvas id="example"> 276 There is supposed to be an example drawing here, but it's not important. 277 </canvas> 278 <div id="framerate"></div> 279 </body> 280</html> 281