| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010, Google Inc. | 2 * Copyright 2010, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 */ | 90 */ |
| 91 o3d.Renderer.clients_ = []; | 91 o3d.Renderer.clients_ = []; |
| 92 | 92 |
| 93 | 93 |
| 94 /** | 94 /** |
| 95 * Renders all clients associated with this renderer. | 95 * Renders all clients associated with this renderer. |
| 96 */ | 96 */ |
| 97 o3d.Renderer.renderClients = function() { | 97 o3d.Renderer.renderClients = function() { |
| 98 for (var i = 0; i < o3d.Renderer.clients_.length; ++i) { | 98 for (var i = 0; i < o3d.Renderer.clients_.length; ++i) { |
| 99 var client = o3d.Renderer.clients_[i]; | 99 var client = o3d.Renderer.clients_[i]; |
| 100 var renderEvent = new o3d.RenderEvent; | 100 |
| 101 var now = (new Date()).getTime() * 0.001; | 101 client.render(); |
| 102 if(client.then_ == 0.0) | |
| 103 renderEvent.elapsedTime = 0.0; | |
| 104 else | |
| 105 renderEvent.elapsedTime = now - client.then_; | |
| 106 client.updateDisplayInfo_(); | |
| 107 if (client.render_callback) { | |
| 108 client.render_callback(renderEvent); | |
| 109 } | |
| 110 client.then_ = now; | |
| 111 client.renderTree(client.renderGraphRoot); | |
| 112 } | 102 } |
| 113 }; | 103 }; |
| 114 | 104 |
| 115 | 105 |
| 116 /** | 106 /** |
| 117 * Sets a timer to traverse the rendergraph every sixtieth of a second. | 107 * Sets a timer to traverse the rendergraph every sixtieth of a second. |
| 118 */ | 108 */ |
| 119 o3d.Renderer.installRenderInterval = function() { | 109 o3d.Renderer.installRenderInterval = function() { |
| 120 o3d.Renderer.render_callback_interval_ = setInterval( | 110 o3d.Renderer.render_callback_interval_ = setInterval( |
| 121 "o3d.Renderer.renderClients()", 1000.0 / 60.0); | 111 "o3d.Renderer.renderClients()", 1000.0 / 60.0); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 * The Client class is the main point of entry to O3D. It defines methods | 196 * The Client class is the main point of entry to O3D. It defines methods |
| 207 * for creating and deleting packs. Each new object created by the Client is | 197 * for creating and deleting packs. Each new object created by the Client is |
| 208 * assigned a unique ID. | 198 * assigned a unique ID. |
| 209 * | 199 * |
| 210 * The Client has a root transform for the transform graph and a root render | 200 * The Client has a root transform for the transform graph and a root render |
| 211 * node for the render graph. | 201 * node for the render graph. |
| 212 * @constructor | 202 * @constructor |
| 213 */ | 203 */ |
| 214 o3d.Client = function() { | 204 o3d.Client = function() { |
| 215 o3d.NamedObject.call(this); | 205 o3d.NamedObject.call(this); |
| 216 this.root = new o3d.Transform; | 206 |
| 217 this.renderGraphRoot = new o3d.RenderNode; | 207 var tempPack = this.createPack(); |
| 218 this.root = new o3d.Transform; | 208 this.root = tempPack.createObject('Transform'); |
| 209 this.renderGraphRoot = tempPack.createObject('RenderNode'); |
| 219 this.clientId = o3d.Client.nextId++; | 210 this.clientId = o3d.Client.nextId++; |
| 211 this.packs_ = [tempPack]; |
| 220 | 212 |
| 221 if (o3d.Renderer.clients_.length == 0) | 213 if (o3d.Renderer.clients_.length == 0) |
| 222 o3d.Renderer.installRenderInterval(); | 214 o3d.Renderer.installRenderInterval(); |
| 223 | 215 |
| 224 o3d.Renderer.clients_.push(this); | 216 o3d.Renderer.clients_.push(this); |
| 225 }; | 217 }; |
| 226 o3d.inherit('Client', 'NamedObject'); | 218 o3d.inherit('Client', 'NamedObject'); |
| 227 | 219 |
| 228 /** | 220 /** |
| 229 * @type {function(!o3d.RenderEvent): void} | 221 * @type {function(!o3d.RenderEvent): void} |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 254 |
| 263 | 255 |
| 264 /** | 256 /** |
| 265 * The transform graph root. | 257 * The transform graph root. |
| 266 * @type {o3d.Transform} | 258 * @type {o3d.Transform} |
| 267 */ | 259 */ |
| 268 o3d.Client.prototype.root = null; | 260 o3d.Client.prototype.root = null; |
| 269 | 261 |
| 270 | 262 |
| 271 /** | 263 /** |
| 264 * A list of all packs for this client. |
| 265 * @type {!Array.<!o3d.Pack>} |
| 266 */ |
| 267 o3d.Client.prototype.packs_ = []; |
| 268 |
| 269 |
| 270 /** |
| 272 * Function that gets called when the client encounters an error. | 271 * Function that gets called when the client encounters an error. |
| 273 */ | 272 */ |
| 274 o3d.Client.prototype.error_callback = function(error_message) { | 273 o3d.Client.prototype.error_callback = function(error_message) { |
| 275 alert(error_message); | 274 alert(error_message); |
| 276 }; | 275 }; |
| 277 | 276 |
| 278 | 277 |
| 279 /** | 278 /** |
| 280 * Function that gets called right before the client renders. | 279 * Function that gets called right before the client renders. |
| 281 */ | 280 */ |
| (...skipping 24 matching lines...) Expand all Loading... |
| 306 | 305 |
| 307 | 306 |
| 308 /** | 307 /** |
| 309 * Creates a pack object. | 308 * Creates a pack object. |
| 310 * A pack object. | 309 * A pack object. |
| 311 * @return {!o3d.Pack} A new pack object. | 310 * @return {!o3d.Pack} A new pack object. |
| 312 */ | 311 */ |
| 313 o3d.Client.prototype.createPack = | 312 o3d.Client.prototype.createPack = |
| 314 function() { | 313 function() { |
| 315 var pack = new o3d.Pack; | 314 var pack = new o3d.Pack; |
| 315 pack.client = this; |
| 316 pack.gl = this.gl; | 316 pack.gl = this.gl; |
| 317 this.packs_.push(pack); |
| 317 return pack; | 318 return pack; |
| 318 }; | 319 }; |
| 319 | 320 |
| 320 | 321 |
| 321 /** | 322 /** |
| 323 * Creates a pack object. |
| 324 * A pack object. |
| 325 * @param {!o3d.Pack} pack The pack to remove. |
| 326 */ |
| 327 o3d.Client.prototype.destroyPack = |
| 328 function(pack) { |
| 329 o3d.removeFromArray(this.packs_, pack); |
| 330 }; |
| 331 |
| 332 |
| 333 |
| 334 /** |
| 322 * Searches the Client for an object matching the given id. | 335 * Searches the Client for an object matching the given id. |
| 323 * | 336 * |
| 324 * @param {number} id The id of the object to look for. | 337 * @param {number} id The id of the object to look for. |
| 325 * @return {o3d.ObjectBase} The object or null if a object | 338 * @return {o3d.ObjectBase} The object or null if a object |
| 326 * with the given id is not found. | 339 * with the given id is not found. |
| 327 */ | 340 */ |
| 328 o3d.Client.prototype.getObjectById = | 341 o3d.Client.prototype.getObjectById = |
| 329 function(id) { | 342 function(id) { |
| 330 o3d.notImplemented(); | 343 o3d.notImplemented(); |
| 331 }; | 344 }; |
| 332 | 345 |
| 333 | 346 |
| 334 /** | 347 /** |
| 335 * Searches the Client for objects of a particular name and type. | 348 * Searches the Client for objects of a particular name and type. |
| 336 * @param {string} name name of object to look for. | 349 * @param {string} name name of object to look for. |
| 337 * @param {string} class_name name of class to look for. | 350 * @param {string} class_name name of class to look for. |
| 338 * @return {!Array.<!o3d.ObjectBase>} Array of objects found. | 351 * @return {!Array.<!o3d.ObjectBase>} Array of objects found. |
| 339 */ | 352 */ |
| 340 o3d.Client.prototype.getObjects = | 353 o3d.Client.prototype.getObjects = |
| 341 function(name, class_name) { | 354 function(name, class_name) { |
| 342 o3d.notImplemented(); | 355 var objects = []; |
| 343 return []; | 356 |
| 357 for (var i = 0; i < this.packs_.length; ++i) { |
| 358 var pack = this.packs_[i]; |
| 359 objects = objects.concat(pack.getObjects(name, class_name)); |
| 360 } |
| 361 |
| 362 return objects; |
| 344 }; | 363 }; |
| 345 | 364 |
| 346 | 365 |
| 347 /** | 366 /** |
| 348 * Searches the Client for objects of a particular type. | 367 * Searches the Client for objects of a particular type. |
| 349 * @param {string} class_name name of class to look for. | 368 * @param {string} class_name name of class to look for. |
| 350 * @return {!Array.<!Object>} Array of objects found. | 369 * @return {!Array.<!Object>} Array of objects found. |
| 351 */ | 370 */ |
| 352 o3d.Client.prototype.getObjectsByClassName = | 371 o3d.Client.prototype.getObjectsByClassName = |
| 353 function(class_name) { | 372 function(class_name) { |
| 354 o3d.notImplemented(); | 373 var objects = []; |
| 355 return []; | 374 |
| 375 for (var i = 0; i < this.packs_.length; ++i) { |
| 376 var pack = this.packs_[i]; |
| 377 objects = objects.concat(pack.getObjectsByClassName(class_name)); |
| 378 } |
| 379 |
| 380 return objects; |
| 356 }; | 381 }; |
| 357 | 382 |
| 358 | 383 |
| 359 /** | 384 /** |
| 360 * @type {number} | 385 * @type {number} |
| 361 */ | 386 */ |
| 362 o3d.Client.RenderMode = goog.typedef; | 387 o3d.Client.RenderMode = goog.typedef; |
| 363 | 388 |
| 364 /** | 389 /** |
| 365 * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate. | 390 * RENDERMODE_CONTINUOUS, Draw as often as possible up to refresh rate. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 380 */ | 405 */ |
| 381 o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS; | 406 o3d.Client.prototype.renderMode = o3d.Client.RENDERMODE_CONTINUOUS; |
| 382 | 407 |
| 383 | 408 |
| 384 | 409 |
| 385 /** | 410 /** |
| 386 * Forces a render of the current scene if the current render mode is | 411 * Forces a render of the current scene if the current render mode is |
| 387 * RENDERMODE_ON_DEMAND. | 412 * RENDERMODE_ON_DEMAND. |
| 388 */ | 413 */ |
| 389 o3d.Client.prototype.render = function() { | 414 o3d.Client.prototype.render = function() { |
| 390 this.renderTree(); | 415 // Synthesize a render event. |
| 416 var render_event = new o3d.RenderEvent; |
| 417 |
| 418 var now = (new Date()).getTime() * 0.001; |
| 419 if(this.then_ == 0.0) |
| 420 render_event.elapsedTime = 0.0; |
| 421 else |
| 422 render_event.elapsedTime = now - this.then_; |
| 423 |
| 424 if (this.render_callback) { |
| 425 for (var stat in this.render_stats_) { |
| 426 render_event[stat] = this.render_stats_[stat]; |
| 427 } |
| 428 this.render_callback(render_event); |
| 429 } |
| 430 this.then_ = now; |
| 431 this.renderTree(this.renderGraphRoot); |
| 391 }; | 432 }; |
| 392 | 433 |
| 393 | 434 |
| 435 /** |
| 436 * An object for various statistics that are gather during the render tree |
| 437 * tranversal. |
| 438 * |
| 439 * @type {Object} |
| 440 */ |
| 441 o3d.Client.prototype.render_stats = {} |
| 442 |
| 394 | 443 |
| 395 /** | 444 /** |
| 396 * Renders a render graph. | 445 * Renders a render graph. |
| 397 * | 446 * |
| 398 * Normally the client calls this function automatically for you effectively | 447 * Normally the client calls this function automatically for you effectively |
| 399 * doing a client.renderTree(client.renderGraphRoot) but there are cases | 448 * doing a client.renderTree(client.renderGraphRoot) but there are cases |
| 400 * where it is beneficial to be able to call this yourself and pass it | 449 * where it is beneficial to be able to call this yourself and pass it |
| 401 * different roots when you need to manipulate something between calls. | 450 * different roots when you need to manipulate something between calls. |
| 402 * | 451 * |
| 403 * This function can only be called from inside a render callback. If you call | 452 * This function can only be called from inside a render callback. If you call |
| 404 * it the client will not do its default call as mentioned above. | 453 * it the client will not do its default call as mentioned above. |
| 405 * | 454 * |
| 406 * @param {!o3d.RenderNode} render_node root RenderNode to start rendering from. | 455 * @param {!o3d.RenderNode} render_node root RenderNode to start rendering from. |
| 407 */ | 456 */ |
| 408 o3d.Client.prototype.renderTree = | 457 o3d.Client.prototype.renderTree = |
| 409 function(render_node) { | 458 function(render_node) { |
| 459 |
| 460 this.render_stats_ = { |
| 461 drawElementsCulled: 0, |
| 462 drawElementsProcessed: 0, |
| 463 drawElementsRendered: 0, |
| 464 primitivesRendered: 0, |
| 465 transformsCulled: 0, |
| 466 transformsProcessed: 0 |
| 467 }; |
| 468 |
| 410 render_node.render(); | 469 render_node.render(); |
| 411 }; | 470 }; |
| 412 | 471 |
| 413 | 472 |
| 414 /** | 473 /** |
| 415 * Returns an array of DisplayModes which are available for use in full-screen | 474 * Returns an array of DisplayModes which are available for use in full-screen |
| 416 * mode. | 475 * mode. |
| 417 * An array of DisplayModes. | 476 * An array of DisplayModes. |
| 418 * @type {!Array.<!o3d.Client.DispalyMode>} | 477 * @type {!Array.<!o3d.Client.DispalyMode>} |
| 419 */ | 478 */ |
| 420 o3d.Client.prototype.getDisplayModes = []; | 479 o3d.Client.prototype.getDisplayModes = []; |
| 421 | 480 |
| 422 | 481 |
| 423 | |
| 424 /** | 482 /** |
| 425 * Makes a region of the plugin area that will invoke full-screen mode if | 483 * Makes a region of the plugin area that will invoke full-screen mode if |
| 426 * clicked. The developer is responsible for communicating this to the user, | 484 * clicked. The developer is responsible for communicating this to the user, |
| 427 * as this region has no visible marker. The developer is also responsible for | 485 * as this region has no visible marker. The developer is also responsible for |
| 428 * updating this region if the plugin gets resized, as we don't know whether or | 486 * updating this region if the plugin gets resized, as we don't know whether or |
| 429 * how to scale it. There can be only one full-screen click region at a time; | 487 * how to scale it. There can be only one full-screen click region at a time; |
| 430 * calling this again will override any previous call. | 488 * calling this again will override any previous call. |
| 431 * | 489 * |
| 432 * @param {number} x x position in pixels. | 490 * @param {number} x x position in pixels. |
| 433 * @param {number} y y position in pixels. | 491 * @param {number} y y position in pixels. |
| 434 * @param {number} width width in pixels. | 492 * @param {number} width width in pixels. |
| 435 * @param {number} height height in pixels. | 493 * @param {number} height height in pixels. |
| 436 * @param {number} mode_id Id of mode to use. | 494 * @param {number} mode_id Id of mode to use. |
| 437 */ | 495 */ |
| 438 o3d.Client.prototype.setFullscreenClickRegion = | 496 o3d.Client.prototype.setFullscreenClickRegion = |
| 439 function(x, y, width, height, mode_id) { | 497 function(x, y, width, height, mode_id) { |
| 440 | 498 o3d.notImplemented(); |
| 441 }; | 499 }; |
| 442 | 500 |
| 443 | 501 |
| 444 /** | 502 /** |
| 445 * Deactivates the plugin click region that was previously created with | 503 * Deactivates the plugin click region that was previously created with |
| 446 * SetFullscreenClickRegion(). | 504 * SetFullscreenClickRegion(). |
| 447 */ | 505 */ |
| 448 o3d.Client.prototype.clearFullscreenClickRegion = function() { | 506 o3d.Client.prototype.clearFullscreenClickRegion = function() { |
| 449 o3d.notImplemented(); | 507 o3d.notImplemented(); |
| 450 }; | 508 }; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 588 |
| 531 try {gl = canvas.getContext("experimental-webgl", standard_attributes) } catch
(e) { } | 589 try {gl = canvas.getContext("experimental-webgl", standard_attributes) } catch
(e) { } |
| 532 if (!gl) | 590 if (!gl) |
| 533 try {gl = canvas.getContext("moz-webgl") } catch(e) { } | 591 try {gl = canvas.getContext("moz-webgl") } catch(e) { } |
| 534 if (!gl) { | 592 if (!gl) { |
| 535 alert("No WebGL context found"); | 593 alert("No WebGL context found"); |
| 536 return null; | 594 return null; |
| 537 } | 595 } |
| 538 | 596 |
| 539 this.gl = gl; | 597 this.gl = gl; |
| 598 this.root.gl = gl; |
| 599 this.renderGraphRoot.gl = gl; |
| 540 | 600 |
| 541 gl.client = this; | 601 gl.client = this; |
| 542 this.updateDisplayInfo_(); | 602 gl.displayInfo = {width: canvas.width, |
| 603 height: canvas.height}; |
| 543 }; | 604 }; |
| 544 | 605 |
| 545 | 606 |
| 546 /** | 607 /** |
| 547 * Sets the per frame render callback. | 608 * Sets the per frame render callback. |
| 548 * | 609 * |
| 549 * Note: The callback will not be called recursively. When your callback is | 610 * Note: The callback will not be called recursively. When your callback is |
| 550 * called if you somehow manage to cause the client to render more frames | 611 * called if you somehow manage to cause the client to render more frames |
| 551 * before you've returned from the callback you will not be called for those | 612 * before you've returned from the callback you will not be called for those |
| 552 * frames. | 613 * frames. |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 | 944 |
| 884 | 945 |
| 885 | 946 |
| 886 /** | 947 /** |
| 887 * The canvas associated with this client. | 948 * The canvas associated with this client. |
| 888 * @type {Element} | 949 * @type {Element} |
| 889 */ | 950 */ |
| 890 o3d.Client.prototype.canvas = null; | 951 o3d.Client.prototype.canvas = null; |
| 891 | 952 |
| 892 | 953 |
| 893 /** | |
| 894 * Updates the display information attached to the GL. | |
| 895 * @private | |
| 896 */ | |
| 897 o3d.Client.prototype.updateDisplayInfo_ = function() { | |
| 898 this.gl.displayInfo = {width: this.width, | |
| 899 height: this.height}; | |
| 900 }; | |
| OLD | NEW |