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