Home | History | Annotate | Download | only in src
      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