Mercurial > hg > Members > e105711
comparison webGL/src/J3DI.js @ 0:9285dae61395 draft
1st commit,just play sounds.
author | e105711 <yomitan.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 25 Apr 2012 23:45:59 +0900 |
parents | |
children | 55702e139f69 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9285dae61395 |
---|---|
1 /* | |
2 * Copyright (C) 2009 Apple Inc. All Rights Reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 */ | |
25 | |
26 // | |
27 // initWebGL | |
28 // | |
29 // Initialize the Canvas element with the passed name as a WebGL object and return the | |
30 // WebGLRenderingContext. | |
31 // | |
32 // Load shaders with the passed names and create a program with them. Return this program | |
33 // in the 'program' property of the returned context. | |
34 // | |
35 // For each string in the passed attribs array, bind an attrib with that name at that index. | |
36 // Once the attribs are bound, link the program and then use it. | |
37 // | |
38 // Set the clear color to the passed array (4 values) and set the clear depth to the passed value. | |
39 // Enable depth testing and blending with a blend func of (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) | |
40 // | |
41 // A console function is added to the context: console(string). This can be replaced | |
42 // by the caller. By default, it maps to the window.console() function on WebKit and to | |
43 // an empty function on other browsers. | |
44 // | |
45 function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth) | |
46 { | |
47 var canvas = document.getElementById(canvasName); | |
48 var gl = canvas.getContext("experimental-webgl"); | |
49 if (!gl) { | |
50 alert("No WebGL context found"); | |
51 return null; | |
52 } | |
53 | |
54 // Add a console | |
55 gl.console = ("console" in window) ? window.console : { log: function() { } }; | |
56 | |
57 // create our shaders | |
58 var vertexShader = loadShader(gl, vshader); | |
59 var fragmentShader = loadShader(gl, fshader); | |
60 | |
61 if (!vertexShader || !fragmentShader) | |
62 return null; | |
63 | |
64 // Create the program object | |
65 gl.program = gl.createProgram(); | |
66 | |
67 if (!gl.program) | |
68 return null; | |
69 | |
70 // Attach our two shaders to the program | |
71 gl.attachShader (gl.program, vertexShader); | |
72 gl.attachShader (gl.program, fragmentShader); | |
73 | |
74 // Bind attributes | |
75 for (var i = 0; i < attribs.length; ++i) | |
76 gl.bindAttribLocation (gl.program, i, attribs[i]); | |
77 | |
78 // Link the program | |
79 gl.linkProgram(gl.program); | |
80 | |
81 // Check the link status | |
82 var linked = gl.getProgramParameter(gl.program, gl.LINK_STATUS); | |
83 if (!linked) { | |
84 // something went wrong with the link | |
85 var error = gl.getProgramInfoLog (gl.program); | |
86 gl.console.log("Error in program linking:"+error); | |
87 | |
88 gl.deleteProgram(gl.program); | |
89 gl.deleteProgram(fragmentShader); | |
90 gl.deleteProgram(vertexShader); | |
91 | |
92 return null; | |
93 } | |
94 | |
95 gl.useProgram(gl.program); | |
96 | |
97 gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); | |
98 gl.clearDepth(clearDepth); | |
99 | |
100 gl.enable(gl.DEPTH_TEST); | |
101 gl.enable(gl.BLEND); | |
102 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); | |
103 | |
104 return gl; | |
105 } | |
106 | |
107 // | |
108 // loadShader | |
109 // | |
110 // 'shaderId' is the id of a <script> element containing the shader source string. | |
111 // Load this shader and return the WebGLShader object corresponding to it. | |
112 // | |
113 function loadShader(ctx, shaderId) | |
114 { | |
115 var shaderScript = document.getElementById(shaderId); | |
116 if (!shaderScript) { | |
117 ctx.console.log("*** Error: shader script '"+shaderId+"' not found"); | |
118 return null; | |
119 } | |
120 | |
121 if (shaderScript.type == "x-shader/x-vertex") | |
122 var shaderType = ctx.VERTEX_SHADER; | |
123 else if (shaderScript.type == "x-shader/x-fragment") | |
124 var shaderType = ctx.FRAGMENT_SHADER; | |
125 else { | |
126 ctx.console.log("*** Error: shader script '"+shaderId+"' of undefined type '"+shaderScript.type+"'"); | |
127 return null; | |
128 } | |
129 | |
130 // Create the shader object | |
131 var shader = ctx.createShader(shaderType); | |
132 if (shader == null) { | |
133 ctx.console.log("*** Error: unable to create shader '"+shaderId+"'"); | |
134 return null; | |
135 } | |
136 | |
137 // Load the shader source | |
138 ctx.shaderSource(shader, shaderScript.text); | |
139 | |
140 // Compile the shader | |
141 ctx.compileShader(shader); | |
142 | |
143 // Check the compile status | |
144 var compiled = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS); | |
145 if (!compiled) { | |
146 // Something went wrong during compilation; get the error | |
147 var error = ctx.getShaderInfoLog(shader); | |
148 ctx.console.log("*** Error compiling shader '"+shaderId+"':"+error); | |
149 ctx.deleteShader(shader); | |
150 return null; | |
151 } | |
152 | |
153 return shader; | |
154 } | |
155 | |
156 // | |
157 // makeBox | |
158 // | |
159 // Create a box with vertices, normals and texCoords. Create VBOs for each as well as the index array. | |
160 // Return an object with the following properties: | |
161 // | |
162 // normalObject WebGLBuffer object for normals | |
163 // texCoordObject WebGLBuffer object for texCoords | |
164 // vertexObject WebGLBuffer object for vertices | |
165 // indexObject WebGLBuffer object for indices | |
166 // numIndices The number of indices in the indexObject | |
167 // | |
168 function makeBox(ctx) | |
169 { | |
170 // box | |
171 // v6----- v5 | |
172 // /| /| | |
173 // v1------v0| | |
174 // | | | | | |
175 // | |v7---|-|v4 | |
176 // |/ |/ | |
177 // v2------v3 | |
178 // | |
179 // vertex coords array | |
180 var vertices = new Float32Array( | |
181 [ 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0-v1-v2-v3 front | |
182 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0-v3-v4-v5 right | |
183 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0-v5-v6-v1 top | |
184 -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1-v6-v7-v2 left | |
185 -1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7-v4-v3-v2 bottom | |
186 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 ] // v4-v7-v6-v5 back | |
187 ); | |
188 | |
189 // normal array | |
190 var normals = new Float32Array( | |
191 [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front | |
192 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right | |
193 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top | |
194 -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left | |
195 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7-v4-v3-v2 bottom | |
196 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 ] // v4-v7-v6-v5 back | |
197 ); | |
198 | |
199 | |
200 // texCoord array | |
201 var texCoords = new Float32Array( | |
202 [ 1, 1, 0, 1, 0, 0, 1, 0, // v0-v1-v2-v3 front | |
203 0, 1, 0, 0, 1, 0, 1, 1, // v0-v3-v4-v5 right | |
204 1, 0, 1, 1, 0, 1, 0, 0, // v0-v5-v6-v1 top | |
205 1, 1, 0, 1, 0, 0, 1, 0, // v1-v6-v7-v2 left | |
206 0, 0, 1, 0, 1, 1, 0, 1, // v7-v4-v3-v2 bottom | |
207 0, 0, 1, 0, 1, 1, 0, 1 ] // v4-v7-v6-v5 back | |
208 ); | |
209 | |
210 // index array | |
211 var indices = new Uint8Array( | |
212 [ 0, 1, 2, 0, 2, 3, // front | |
213 4, 5, 6, 4, 6, 7, // right | |
214 8, 9,10, 8,10,11, // top | |
215 12,13,14, 12,14,15, // left | |
216 16,17,18, 16,18,19, // bottom | |
217 20,21,22, 20,22,23 ] // back | |
218 ); | |
219 | |
220 var retval = { }; | |
221 | |
222 retval.normalObject = ctx.createBuffer(); | |
223 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject); | |
224 ctx.bufferData(ctx.ARRAY_BUFFER, normals, ctx.STATIC_DRAW); | |
225 | |
226 retval.texCoordObject = ctx.createBuffer(); | |
227 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject); | |
228 ctx.bufferData(ctx.ARRAY_BUFFER, texCoords, ctx.STATIC_DRAW); | |
229 | |
230 retval.vertexObject = ctx.createBuffer(); | |
231 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject); | |
232 ctx.bufferData(ctx.ARRAY_BUFFER, vertices, ctx.STATIC_DRAW); | |
233 | |
234 ctx.bindBuffer(ctx.ARRAY_BUFFER, null); | |
235 | |
236 retval.indexObject = ctx.createBuffer(); | |
237 ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject); | |
238 ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, indices, ctx.STATIC_DRAW); | |
239 ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null); | |
240 | |
241 retval.numIndices = indices.length; | |
242 | |
243 return retval; | |
244 } | |
245 | |
246 // | |
247 // makeSphere | |
248 // | |
249 // Create a sphere with the passed number of latitude and longitude bands and the passed radius. | |
250 // Sphere has vertices, normals and texCoords. Create VBOs for each as well as the index array. | |
251 // Return an object with the following properties: | |
252 // | |
253 // normalObject WebGLBuffer object for normals | |
254 // texCoordObject WebGLBuffer object for texCoords | |
255 // vertexObject WebGLBuffer object for vertices | |
256 // indexObject WebGLBuffer object for indices | |
257 // numIndices The number of indices in the indexObject | |
258 // | |
259 function makeSphere(ctx, radius, lats, longs) | |
260 { | |
261 var geometryData = [ ]; | |
262 var normalData = [ ]; | |
263 var texCoordData = [ ]; | |
264 var indexData = [ ]; | |
265 | |
266 for (var latNumber = 0; latNumber <= lats; ++latNumber) { | |
267 for (var longNumber = 0; longNumber <= longs; ++longNumber) { | |
268 var theta = latNumber * Math.PI / lats; | |
269 var phi = longNumber * 2 * Math.PI / longs; | |
270 var sinTheta = Math.sin(theta); | |
271 var sinPhi = Math.sin(phi); | |
272 var cosTheta = Math.cos(theta); | |
273 var cosPhi = Math.cos(phi); | |
274 | |
275 var x = cosPhi * sinTheta; | |
276 var y = cosTheta; | |
277 var z = sinPhi * sinTheta; | |
278 var u = 1-(longNumber/longs); | |
279 var v = latNumber/lats; | |
280 | |
281 normalData.push(x); | |
282 normalData.push(y); | |
283 normalData.push(z); | |
284 texCoordData.push(u); | |
285 texCoordData.push(v); | |
286 geometryData.push(radius * x); | |
287 geometryData.push(radius * y); | |
288 geometryData.push(radius * z); | |
289 } | |
290 } | |
291 | |
292 for (var latNumber = 0; latNumber < lats; ++latNumber) { | |
293 for (var longNumber = 0; longNumber < longs; ++longNumber) { | |
294 var first = (latNumber * (longs+1)) + longNumber; | |
295 var second = first + longs + 1; | |
296 indexData.push(first); | |
297 indexData.push(second); | |
298 indexData.push(first+1); | |
299 | |
300 indexData.push(second); | |
301 indexData.push(second+1); | |
302 indexData.push(first+1); | |
303 } | |
304 } | |
305 | |
306 var retval = { }; | |
307 | |
308 retval.normalObject = ctx.createBuffer(); | |
309 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject); | |
310 ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(normalData), ctx.STATIC_DRAW); | |
311 | |
312 retval.texCoordObject = ctx.createBuffer(); | |
313 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject); | |
314 ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(texCoordData), ctx.STATIC_DRAW); | |
315 | |
316 retval.vertexObject = ctx.createBuffer(); | |
317 ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject); | |
318 ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(geometryData), ctx.STATIC_DRAW); | |
319 | |
320 retval.numIndices = indexData.length; | |
321 retval.indexObject = ctx.createBuffer(); | |
322 ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject); | |
323 ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), ctx.STREAM_DRAW); | |
324 | |
325 return retval; | |
326 } | |
327 | |
328 // | |
329 // loadObj | |
330 // | |
331 // Load a .obj file from the passed URL. Return an object with a 'loaded' property set to false. | |
332 // When the object load is complete, the 'loaded' property becomes true and the following | |
333 // properties are set: | |
334 // | |
335 // normalObject WebGLBuffer object for normals | |
336 // texCoordObject WebGLBuffer object for texCoords | |
337 // vertexObject WebGLBuffer object for vertices | |
338 // indexObject WebGLBuffer object for indices | |
339 // numIndices The number of indices in the indexObject | |
340 // | |
341 function loadObj(ctx, url) | |
342 { | |
343 var obj = { loaded : false }; | |
344 obj.ctx = ctx; | |
345 var req = new XMLHttpRequest(); | |
346 req.obj = obj; | |
347 req.onreadystatechange = function () { processLoadObj(req) }; | |
348 req.open("GET", url, true); | |
349 req.send(null); | |
350 return obj; | |
351 } | |
352 | |
353 function processLoadObj(req) | |
354 { | |
355 req.obj.ctx.console.log("req="+req) | |
356 // only if req shows "complete" | |
357 if (req.readyState == 4) { | |
358 doLoadObj(req.obj, req.responseText); | |
359 } | |
360 } | |
361 | |
362 function doLoadObj(obj, text) | |
363 { | |
364 vertexArray = [ ]; | |
365 normalArray = [ ]; | |
366 textureArray = [ ]; | |
367 indexArray = [ ]; | |
368 | |
369 var vertex = [ ]; | |
370 var normal = [ ]; | |
371 var texture = [ ]; | |
372 var facemap = { }; | |
373 var index = 0; | |
374 | |
375 // This is a map which associates a range of indices with a name | |
376 // The name comes from the 'g' tag (of the form "g NAME"). Indices | |
377 // are part of one group until another 'g' tag is seen. If any indices | |
378 // come before a 'g' tag, it is given the group name "_unnamed" | |
379 // 'group' is an object whose property names are the group name and | |
380 // whose value is a 2 element array with [<first index>, <num indices>] | |
381 var groups = { }; | |
382 var currentGroup = [-1, 0]; | |
383 groups["_unnamed"] = currentGroup; | |
384 | |
385 var lines = text.split("\n"); | |
386 for (var lineIndex in lines) { | |
387 var line = lines[lineIndex].replace(/[ \t]+/g, " ").replace(/\s\s*$/, ""); | |
388 | |
389 // ignore comments | |
390 if (line[0] == "#") | |
391 continue; | |
392 | |
393 var array = line.split(" "); | |
394 if (array[0] == "g") { | |
395 // new group | |
396 currentGroup = [indexArray.length, 0]; | |
397 groups[array[1]] = currentGroup; | |
398 } | |
399 else if (array[0] == "v") { | |
400 // vertex | |
401 vertex.push(parseFloat(array[1])); | |
402 vertex.push(parseFloat(array[2])); | |
403 vertex.push(parseFloat(array[3])); | |
404 } | |
405 else if (array[0] == "vt") { | |
406 // normal | |
407 texture.push(parseFloat(array[1])); | |
408 texture.push(parseFloat(array[2])); | |
409 } | |
410 else if (array[0] == "vn") { | |
411 // normal | |
412 normal.push(parseFloat(array[1])); | |
413 normal.push(parseFloat(array[2])); | |
414 normal.push(parseFloat(array[3])); | |
415 } | |
416 else if (array[0] == "f") { | |
417 // face | |
418 if (array.length != 4) { | |
419 obj.ctx.console.log("*** Error: face '"+line+"' not handled"); | |
420 continue; | |
421 } | |
422 | |
423 for (var i = 1; i < 4; ++i) { | |
424 if (!(array[i] in facemap)) { | |
425 // add a new entry to the map and arrays | |
426 var f = array[i].split("/"); | |
427 var vtx, nor, tex; | |
428 | |
429 if (f.length == 1) { | |
430 vtx = parseInt(f[0]) - 1; | |
431 nor = vtx; | |
432 tex = vtx; | |
433 } | |
434 else if (f.length = 3) { | |
435 vtx = parseInt(f[0]) - 1; | |
436 tex = parseInt(f[1]) - 1; | |
437 nor = parseInt(f[2]) - 1; | |
438 } | |
439 else { | |
440 obj.ctx.console.log("*** Error: did not understand face '"+array[i]+"'"); | |
441 return null; | |
442 } | |
443 | |
444 // do the vertices | |
445 var x = 0; | |
446 var y = 0; | |
447 var z = 0; | |
448 if (vtx * 3 + 2 < vertex.length) { | |
449 x = vertex[vtx*3]; | |
450 y = vertex[vtx*3+1]; | |
451 z = vertex[vtx*3+2]; | |
452 } | |
453 vertexArray.push(x); | |
454 vertexArray.push(y); | |
455 vertexArray.push(z); | |
456 | |
457 // do the textures | |
458 x = 0; | |
459 y = 0; | |
460 if (tex * 2 + 1 < texture.length) { | |
461 x = texture[tex*2]; | |
462 y = texture[tex*2+1]; | |
463 } | |
464 textureArray.push(x); | |
465 textureArray.push(y); | |
466 | |
467 // do the normals | |
468 x = 0; | |
469 y = 0; | |
470 z = 1; | |
471 if (nor * 3 + 2 < normal.length) { | |
472 x = normal[nor*3]; | |
473 y = normal[nor*3+1]; | |
474 z = normal[nor*3+2]; | |
475 } | |
476 normalArray.push(x); | |
477 normalArray.push(y); | |
478 normalArray.push(z); | |
479 | |
480 facemap[array[i]] = index++; | |
481 } | |
482 | |
483 indexArray.push(facemap[array[i]]); | |
484 currentGroup[1]++; | |
485 } | |
486 } | |
487 } | |
488 | |
489 // set the VBOs | |
490 obj.normalObject = obj.ctx.createBuffer(); | |
491 obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.normalObject); | |
492 obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new Float32Array(normalArray), obj.ctx.STATIC_DRAW); | |
493 | |
494 obj.texCoordObject = obj.ctx.createBuffer(); | |
495 obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.texCoordObject); | |
496 obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new Float32Array(textureArray), obj.ctx.STATIC_DRAW); | |
497 | |
498 obj.vertexObject = obj.ctx.createBuffer(); | |
499 obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.vertexObject); | |
500 obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new Float32Array(vertexArray), obj.ctx.STATIC_DRAW); | |
501 | |
502 obj.numIndices = indexArray.length; | |
503 obj.indexObject = obj.ctx.createBuffer(); | |
504 obj.ctx.bindBuffer(obj.ctx.ELEMENT_ARRAY_BUFFER, obj.indexObject); | |
505 obj.ctx.bufferData(obj.ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexArray), obj.ctx.STREAM_DRAW); | |
506 | |
507 obj.groups = groups; | |
508 | |
509 obj.loaded = true; | |
510 } | |
511 | |
512 // | |
513 // loadImageTexture | |
514 // | |
515 // Load the image at the passed url, place it in a new WebGLTexture object and return the WebGLTexture. | |
516 // | |
517 function loadImageTexture(ctx, url) | |
518 { | |
519 var texture = ctx.createTexture(); | |
520 texture.image = new Image(); | |
521 texture.image.onload = function() { doLoadImageTexture(ctx, texture.image, texture) } | |
522 texture.image.src = url; | |
523 return texture; | |
524 } | |
525 | |
526 function doLoadImageTexture(ctx, image, texture) | |
527 { | |
528 ctx.bindTexture(ctx.TEXTURE_2D, texture); | |
529 ctx.texImage2D( | |
530 ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, image); | |
531 ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); | |
532 ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); | |
533 ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); | |
534 ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); | |
535 //ctx.generateMipmap(ctx.TEXTURE_2D) | |
536 ctx.bindTexture(ctx.TEXTURE_2D, null); | |
537 } | |
538 | |
539 // | |
540 // Framerate object | |
541 // | |
542 // This object keeps track of framerate and displays it as the innerHTML text of the | |
543 // HTML element with the passed id. Once created you call snapshot at the end | |
544 // of every rendering cycle. Every 500ms the framerate is updated in the HTML element. | |
545 // | |
546 Framerate = function(id) | |
547 { | |
548 this.numFramerates = 10; | |
549 this.framerateUpdateInterval = 500; | |
550 this.id = id; | |
551 | |
552 this.renderTime = -1; | |
553 this.framerates = [ ]; | |
554 self = this; | |
555 var fr = function() { self.updateFramerate() } | |
556 setInterval(fr, this.framerateUpdateInterval); | |
557 } | |
558 | |
559 Framerate.prototype.updateFramerate = function() | |
560 { | |
561 var tot = 0; | |
562 for (var i = 0; i < this.framerates.length; ++i) | |
563 tot += this.framerates[i]; | |
564 | |
565 var framerate = tot / this.framerates.length; | |
566 framerate = Math.round(framerate); | |
567 document.getElementById(this.id).innerHTML = "Framerate:"+framerate+"fps"; | |
568 } | |
569 | |
570 Framerate.prototype.snapshot = function() | |
571 { | |
572 if (this.renderTime < 0) | |
573 this.renderTime = new Date().getTime(); | |
574 else { | |
575 var newTime = new Date().getTime(); | |
576 var t = newTime - this.renderTime; | |
577 var framerate = 1000/t; | |
578 this.framerates.push(framerate); | |
579 while (this.framerates.length > this.numFramerates) | |
580 this.framerates.shift(); | |
581 this.renderTime = newTime; | |
582 } | |
583 } |