1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 cc.g_NumberOfDraws = 0; 28 29 cc.GLToClipTransform = function (transformOut) { 30 var projection = new cc.kmMat4(); 31 cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection); 32 33 var modelview = new cc.kmMat4(); 34 cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, modelview); 35 36 cc.kmMat4Multiply(transformOut, projection, modelview); 37 }; 38 //---------------------------------------------------------------------------------------------------------------------- 39 40 /** 41 * @namespace <p> 42 * cc.director is a singleton of DisplayLinkDirector type director.<br/> 43 * Since the cc.director is a singleton, you don't need to call any constructor or create functions,<br/> 44 * the standard way to use it is by calling:<br/> 45 * - cc.director.methodName(); <br/> 46 * 47 * It creates and handle the main Window and manages how and when to execute the Scenes.<br/> 48 * <br/> 49 * The cc.Director is also responsible for:<br/> 50 * - initializing the OpenGL context<br/> 51 * - setting the OpenGL pixel format (default on is RGB565)<br/> 52 * - setting the OpenGL pixel format (default on is RGB565)<br/> 53 * - setting the OpenGL buffer depth (default one is 0-bit)<br/> 54 * - setting the projection (default one is 3D)<br/> 55 * - setting the orientation (default one is Protrait)<br/> 56 * <br/> 57 * <br/> 58 * The cc.director also sets the default OpenGL context:<br/> 59 * - GL_TEXTURE_2D is enabled<br/> 60 * - GL_VERTEX_ARRAY is enabled<br/> 61 * - GL_COLOR_ARRAY is enabled<br/> 62 * - GL_TEXTURE_COORD_ARRAY is enabled<br/> 63 * </p> 64 * <p> 65 * With DisplayLinkDirector functionality, cc.director synchronizes timers with the refresh rate of the display.<br/> 66 * Features and Limitations:<br/> 67 * - Scheduled timers & drawing are synchronizes with the refresh rate of the display<br/> 68 * - Only supports animation intervals of 1/60 1/30 & 1/15<br/> 69 * </p> 70 * @name cc.director 71 */ 72 cc.Director = cc.Class.extend(/** @lends cc.director# */{ 73 //Variables 74 _landscape: false, 75 _nextDeltaTimeZero: false, 76 _paused: false, 77 _purgeDirectorInNextLoop: false, 78 _sendCleanupToScene: false, 79 _animationInterval: 0.0, 80 _oldAnimationInterval: 0.0, 81 _projection: 0, 82 _accumDt: 0.0, 83 _contentScaleFactor: 1.0, 84 85 _displayStats: false, 86 _deltaTime: 0.0, 87 _frameRate: 0.0, 88 89 _FPSLabel: null, 90 _SPFLabel: null, 91 _drawsLabel: null, 92 93 _winSizeInPoints: null, 94 95 _lastUpdate: null, 96 _nextScene: null, 97 _notificationNode: null, 98 _openGLView: null, 99 _scenesStack: null, 100 _projectionDelegate: null, 101 _runningScene: null, 102 103 _frames: 0, 104 _totalFrames: 0, 105 _secondsPerFrame: 0, 106 107 _dirtyRegion: null, 108 109 _scheduler: null, 110 _actionManager: null, 111 _eventProjectionChanged: null, 112 _eventAfterDraw: null, 113 _eventAfterVisit: null, 114 _eventAfterUpdate: null, 115 116 ctor: function () { 117 var self = this; 118 self._lastUpdate = Date.now(); 119 cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () { 120 self._lastUpdate = Date.now(); 121 }); 122 }, 123 124 /** 125 * initializes cc.director 126 * @return {Boolean} 127 */ 128 init: function () { 129 // scenes 130 this._oldAnimationInterval = this._animationInterval = 1.0 / cc.defaultFPS; 131 this._scenesStack = []; 132 // Set default projection (3D) 133 this._projection = cc.Director.PROJECTION_DEFAULT; 134 // projection delegate if "Custom" projection is used 135 this._projectionDelegate = null; 136 137 //FPS 138 this._accumDt = 0; 139 this._frameRate = 0; 140 this._displayStats = false;//can remove 141 this._totalFrames = this._frames = 0; 142 this._lastUpdate = Date.now(); 143 144 //Paused? 145 this._paused = false; 146 147 //purge? 148 this._purgeDirectorInNextLoop = false; 149 150 this._winSizeInPoints = cc.size(0, 0); 151 152 this._openGLView = null; 153 this._contentScaleFactor = 1.0; 154 155 //scheduler 156 this._scheduler = new cc.Scheduler(); 157 //action manager 158 this._actionManager = cc.ActionManager ? new cc.ActionManager() : null; 159 this._scheduler.scheduleUpdateForTarget(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false); 160 161 this._eventAfterDraw = new cc.EventCustom(cc.Director.EVENT_AFTER_DRAW); 162 this._eventAfterDraw.setUserData(this); 163 this._eventAfterVisit = new cc.EventCustom(cc.Director.EVENT_AFTER_VISIT); 164 this._eventAfterVisit.setUserData(this); 165 this._eventAfterUpdate = new cc.EventCustom(cc.Director.EVENT_AFTER_UPDATE); 166 this._eventAfterUpdate.setUserData(this); 167 this._eventProjectionChanged = new cc.EventCustom(cc.Director.EVENT_PROJECTION_CHANGED); 168 this._eventProjectionChanged.setUserData(this); 169 170 return true; 171 }, 172 173 /** 174 * calculates delta time since last time it was called 175 */ 176 calculateDeltaTime: function () { 177 var now = Date.now(); 178 179 // new delta time. 180 if (this._nextDeltaTimeZero) { 181 this._deltaTime = 0; 182 this._nextDeltaTimeZero = false; 183 } else { 184 this._deltaTime = (now - this._lastUpdate) / 1000; 185 } 186 187 if ((cc.game.config[cc.game.CONFIG_KEY.debugMode] > 0) && (this._deltaTime > 0.2)) 188 this._deltaTime = 1 / 60.0; 189 190 this._lastUpdate = now; 191 }, 192 193 /** 194 * convertToGL move to CCDirectorWebGL 195 * convertToUI move to CCDirectorWebGL 196 */ 197 198 /** 199 * Draw the scene. This method is called every frame. Don't call it manually. 200 */ 201 drawScene: function () { 202 // calculate "global" dt 203 this.calculateDeltaTime(); 204 205 //tick before glClear: issue #533 206 if (!this._paused) { 207 this._scheduler.update(this._deltaTime); 208 cc.eventManager.dispatchEvent(this._eventAfterUpdate); 209 } 210 211 this._clear(); 212 213 /* to avoid flickr, nextScene MUST be here: after tick and before draw. 214 XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ 215 if (this._nextScene) { 216 this.setNextScene(); 217 } 218 219 if (this._beforeVisitScene) this._beforeVisitScene(); 220 221 // draw the scene 222 if (this._runningScene) { 223 this._runningScene.visit(); 224 cc.eventManager.dispatchEvent(this._eventAfterVisit); 225 } 226 227 // draw the notifications node 228 if (this._notificationNode) 229 this._notificationNode.visit(); 230 231 if (this._displayStats) 232 this._showStats(); 233 234 if (this._afterVisitScene) this._afterVisitScene(); 235 236 //TODO 237 cc.eventManager.dispatchEvent(this._eventAfterDraw); 238 this._totalFrames++; 239 240 if (this._displayStats) 241 this._calculateMPF(); 242 }, 243 244 _beforeVisitScene: null, 245 _afterVisitScene: null, 246 247 /** 248 * end director 249 */ 250 end: function () { 251 this._purgeDirectorInNextLoop = true; 252 }, 253 254 /** 255 * <p>get the size in pixels of the surface. It could be different than the screen size.<br/> 256 * High-res devices might have a higher surface size than the screen size.<br/> 257 * Only available when compiled using SDK >= 4.0. 258 * </p> 259 * @return {Number} 260 */ 261 getContentScaleFactor: function () { 262 return this._contentScaleFactor; 263 }, 264 265 /** 266 * <p> 267 * This object will be visited after the main scene is visited.<br/> 268 * This object MUST implement the "visit" selector.<br/> 269 * Useful to hook a notification object, like CCNotifications (http://github.com/manucorporat/CCNotifications) 270 * </p> 271 * @return {cc.Node} 272 */ 273 getNotificationNode: function () { 274 return this._notificationNode; 275 }, 276 277 /** 278 * <p> 279 * returns the size of the OpenGL view in points.<br/> 280 * It takes into account any possible rotation (device orientation) of the window 281 * </p> 282 * @return {cc.Size} 283 */ 284 getWinSize: function () { 285 return this._winSizeInPoints; 286 }, 287 288 /** 289 * <p> 290 * returns the size of the OpenGL view in pixels.<br/> 291 * It takes into account any possible rotation (device orientation) of the window.<br/> 292 * On Mac winSize and winSizeInPixels return the same value. 293 * </p> 294 * @return {cc.Size} 295 */ 296 getWinSizeInPixels: function () { 297 return cc.size(this._winSizeInPoints.width * this._contentScaleFactor, this._winSizeInPoints.height * this._contentScaleFactor); 298 }, 299 300 /** 301 * getVisibleSize/getVisibleOrigin move to CCDirectorWebGL/CCDirectorCanvas 302 * getZEye move to CCDirectorWebGL 303 */ 304 305 /** 306 * pause director 307 */ 308 pause: function () { 309 if (this._paused) 310 return; 311 312 this._oldAnimationInterval = this._animationInterval; 313 // when paused, don't consume CPU 314 this.setAnimationInterval(1 / 4.0); 315 this._paused = true; 316 }, 317 318 /** 319 * <p> 320 * Pops out a scene from the queue.<br/> 321 * This scene will replace the running one.<br/> 322 * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.<br/> 323 * ONLY call it if there is a running scene. 324 * </p> 325 */ 326 popScene: function () { 327 328 cc.assert(this._runningScene, cc._LogInfos.Director_popScene); 329 330 this._scenesStack.pop(); 331 var c = this._scenesStack.length; 332 333 if (c == 0) 334 this.end(); 335 else { 336 this._sendCleanupToScene = true; 337 this._nextScene = this._scenesStack[c - 1]; 338 } 339 }, 340 341 /** 342 * Removes cached all cocos2d cached data. It will purge the cc.textureCache, cc.spriteFrameCache, cc.animationCache 343 */ 344 purgeCachedData: function () { 345 cc.animationCache._clear(); 346 cc.spriteFrameCache._clear(); 347 cc.textureCache._clear(); 348 }, 349 350 /** 351 * purge Director 352 */ 353 purgeDirector: function () { 354 //cleanup scheduler 355 this.getScheduler().unscheduleAllCallbacks(); 356 357 // Disable event dispatching 358 if (cc.eventManager) 359 cc.eventManager.setEnabled(false); 360 361 // don't release the event handlers 362 // They are needed in case the director is run again 363 364 if (this._runningScene) { 365 this._runningScene.onExitTransitionDidStart(); 366 this._runningScene.onExit(); 367 this._runningScene.cleanup(); 368 } 369 370 this._runningScene = null; 371 this._nextScene = null; 372 373 // remove all objects, but don't release it. 374 // runScene might be executed after 'end'. 375 this._scenesStack.length = 0; 376 377 this.stopAnimation(); 378 379 // Clear all caches 380 this.purgeCachedData(); 381 382 cc.checkGLErrorDebug(); 383 }, 384 385 /** 386 * <p> 387 * Suspends the execution of the running scene, pushing it on the stack of suspended scenes.<br/> 388 * The new scene will be executed.<br/> 389 * Try to avoid big stacks of pushed scenes to reduce memory allocation.<br/> 390 * ONLY call it if there is a running scene. 391 * </p> 392 * @param {cc.Scene} scene 393 */ 394 pushScene: function (scene) { 395 396 cc.assert(scene, cc._LogInfos.Director_pushScene); 397 398 this._sendCleanupToScene = false; 399 400 this._scenesStack.push(scene); 401 this._nextScene = scene; 402 }, 403 404 /** 405 * Run a scene. Replaces the running scene with a new one when the scene is running. 406 * @param {cc.Scene} scene 407 */ 408 runScene: function (scene) { 409 410 cc.assert(scene, cc._LogInfos.Director_pushScene); 411 412 if (!this._runningScene) { 413 //start scene 414 this.pushScene(scene); 415 this.startAnimation(); 416 } else { 417 //replace scene 418 var i = this._scenesStack.length; 419 if (i === 0) { 420 this._sendCleanupToScene = true; 421 this._scenesStack[i] = scene; 422 this._nextScene = scene; 423 } else { 424 this._sendCleanupToScene = true; 425 this._scenesStack[i - 1] = scene; 426 this._nextScene = scene; 427 } 428 } 429 }, 430 431 /** 432 * resume director 433 */ 434 resume: function () { 435 if (!this._paused) { 436 return; 437 } 438 439 this.setAnimationInterval(this._oldAnimationInterval); 440 this._lastUpdate = Date.now(); 441 if (!this._lastUpdate) { 442 cc.log(cc._LogInfos.Director_resume); 443 } 444 445 this._paused = false; 446 this._deltaTime = 0; 447 }, 448 449 /** 450 * <p> 451 * The size in pixels of the surface. It could be different than the screen size.<br/> 452 * High-res devices might have a higher surface size than the screen size.<br/> 453 * Only available when compiled using SDK >= 4.0. 454 * </p> 455 * @param {Number} scaleFactor 456 */ 457 setContentScaleFactor: function (scaleFactor) { 458 if (scaleFactor != this._contentScaleFactor) { 459 this._contentScaleFactor = scaleFactor; 460 this._createStatsLabel(); 461 } 462 }, 463 464 /** 465 * enables/disables OpenGL depth test 466 * @param {Boolean} on 467 * 468 * setDepthTest move to CCDirectorCanvas/CCDirectorWebGL 469 */ 470 471 /** 472 * sets the default values based on the CCConfiguration info 473 */ 474 setDefaultValues: function () { 475 476 }, 477 478 /** 479 * set next delta time is zero 480 * @param {Boolean} nextDeltaTimeZero 481 */ 482 setNextDeltaTimeZero: function (nextDeltaTimeZero) { 483 this._nextDeltaTimeZero = nextDeltaTimeZero; 484 }, 485 486 /** 487 * set next scene 488 */ 489 setNextScene: function () { 490 var runningIsTransition = false, newIsTransition = false; 491 if (cc.TransitionScene) { 492 runningIsTransition = this._runningScene ? this._runningScene instanceof cc.TransitionScene : false; 493 newIsTransition = this._nextScene ? this._nextScene instanceof cc.TransitionScene : false; 494 } 495 496 // If it is not a transition, call onExit/cleanup 497 if (!newIsTransition) { 498 var locRunningScene = this._runningScene; 499 if (locRunningScene) { 500 locRunningScene.onExitTransitionDidStart(); 501 locRunningScene.onExit(); 502 } 503 504 // issue #709. the root node (scene) should receive the cleanup message too 505 // otherwise it might be leaked. 506 if (this._sendCleanupToScene && locRunningScene) 507 locRunningScene.cleanup(); 508 } 509 510 this._runningScene = this._nextScene; 511 512 this._nextScene = null; 513 if ((!runningIsTransition) && (this._runningScene != null)) { 514 this._runningScene.onEnter(); 515 this._runningScene.onEnterTransitionDidFinish(); 516 } 517 }, 518 519 /** 520 * set Notification Node 521 * @param {cc.Node} node 522 */ 523 setNotificationNode: function (node) { 524 this._notificationNode = node; 525 }, 526 527 /** 528 * CCDirector delegate. It shall implemente the CCDirectorDelegate protocol 529 * @return {cc.DirectorDelegate} 530 */ 531 getDelegate: function () { 532 return this._projectionDelegate; 533 }, 534 535 setDelegate: function (delegate) { 536 this._projectionDelegate = delegate; 537 }, 538 539 /** 540 * Set the CCEGLView, where everything is rendered 541 * @param {*} openGLView 542 * 543 * setOpenGLView move to CCDirectorCanvas/CCDirectorWebGL 544 * setViewport move to CCDirectorWebGL 545 */ 546 547 /** 548 * Sets an OpenGL projection 549 * @param {Number} projection 550 * 551 * setProjection move to CCDiretorCanvas/CCDiretorWebGL 552 */ 553 554 /** 555 * shows the FPS in the screen 556 */ 557 _showStats: function () { 558 this._frames++; 559 this._accumDt += this._deltaTime; 560 if (this._FPSLabel && this._SPFLabel && this._drawsLabel) { 561 if (this._accumDt > cc.DIRECTOR_FPS_INTERVAL) { 562 this._SPFLabel.string = this._secondsPerFrame.toFixed(3); 563 564 this._frameRate = this._frames / this._accumDt; 565 this._frames = 0; 566 this._accumDt = 0; 567 568 this._FPSLabel.string = this._frameRate.toFixed(1); 569 this._drawsLabel.string = (0 | cc.g_NumberOfDraws).toString(); 570 } 571 this._FPSLabel.visit(); 572 this._SPFLabel.visit(); 573 this._drawsLabel.visit(); 574 } else 575 this._createStatsLabel(); 576 cc.g_NumberOfDraws = 0; 577 }, 578 579 /** 580 * <p> 581 * Whether or not the replaced scene will receive the cleanup message.<br> 582 * If the new scene is pushed, then the old scene won't receive the "cleanup" message.<br/> 583 * If the new scene replaces the old one, the it will receive the "cleanup" message. 584 * </p> 585 * @return {Boolean} 586 */ 587 isSendCleanupToScene: function () { 588 return this._sendCleanupToScene; 589 }, 590 591 /** 592 * Get current running Scene. Director can only run one Scene at the time 593 * @return {cc.Scene} 594 */ 595 getRunningScene: function () { 596 return this._runningScene; 597 }, 598 599 /** 600 * Get the FPS value 601 * @return {Number} 602 */ 603 getAnimationInterval: function () { 604 return this._animationInterval; 605 }, 606 607 /** 608 * Whether or not to display the FPS on the bottom-left corner 609 * @return {Boolean} 610 */ 611 isDisplayStats: function () { 612 return this._displayStats; 613 }, 614 615 /** 616 * Display the FPS on the bottom-left corner 617 * @param {Boolean} displayStats 618 */ 619 setDisplayStats: function (displayStats) { 620 this._displayStats = displayStats; 621 }, 622 623 /** 624 * seconds per frame 625 * @return {Number} 626 */ 627 getSecondsPerFrame: function () { 628 return this._secondsPerFrame; 629 }, 630 631 /** 632 * is next delta time zero 633 * @return {Boolean} 634 */ 635 isNextDeltaTimeZero: function () { 636 return this._nextDeltaTimeZero; 637 }, 638 639 /** 640 * Whether or not the Director is paused 641 * @return {Boolean} 642 */ 643 isPaused: function () { 644 return this._paused; 645 }, 646 647 /** 648 * How many frames were called since the director started 649 * @return {Number} 650 */ 651 getTotalFrames: function () { 652 return this._totalFrames; 653 }, 654 655 /** 656 * <p> 657 * Pops out all scenes from the queue until the root scene in the queue. <br/> 658 * This scene will replace the running one. <br/> 659 * Internally it will call `popToSceneStackLevel(1)` 660 * </p> 661 */ 662 popToRootScene: function () { 663 this.popToSceneStackLevel(1); 664 }, 665 666 /** 667 * <p> 668 * Pops out all scenes from the queue until it reaches `level`. <br/> 669 * If level is 0, it will end the director. <br/> 670 * If level is 1, it will pop all scenes until it reaches to root scene. <br/> 671 * If level is <= than the current stack level, it won't do anything. 672 * </p> 673 * @param {Number} level 674 */ 675 popToSceneStackLevel: function (level) { 676 677 cc.assert(this._runningScene, cc._LogInfos.Director_popToSceneStackLevel_2); 678 679 var locScenesStack = this._scenesStack; 680 var c = locScenesStack.length; 681 682 if (c == 0) { 683 this.end(); 684 return; 685 } 686 // current level or lower -> nothing 687 if (level > c) 688 return; 689 690 // pop stack until reaching desired level 691 while (c > level) { 692 var current = locScenesStack.pop(); 693 if (current.running) { 694 current.onExitTransitionDidStart(); 695 current.onExit(); 696 } 697 current.cleanup(); 698 c--; 699 } 700 this._nextScene = locScenesStack[locScenesStack.length - 1]; 701 this._sendCleanupToScene = false; 702 }, 703 704 /** 705 * (cc.Scheduler associated with this director) 706 */ 707 getScheduler: function () { 708 return this._scheduler; 709 }, 710 711 setScheduler: function (scheduler) { 712 if (this._scheduler != scheduler) { 713 this._scheduler = scheduler; 714 } 715 }, 716 717 getActionManager: function () { 718 return this._actionManager; 719 }, 720 setActionManager: function (actionManager) { 721 if (this._actionManager != actionManager) { 722 this._actionManager = actionManager; 723 } 724 }, 725 726 getDeltaTime: function () { 727 return this._deltaTime; 728 }, 729 730 _createStatsLabel: null, 731 732 _calculateMPF: function () { 733 var now = Date.now(); 734 this._secondsPerFrame = (now - this._lastUpdate) / 1000; 735 } 736 }); 737 738 cc.Director.EVENT_PROJECTION_CHANGED = "director_projection_changed"; 739 cc.Director.EVENT_AFTER_DRAW = "director_after_draw"; 740 cc.Director.EVENT_AFTER_VISIT = "director_after_visit"; 741 cc.Director.EVENT_AFTER_UPDATE = "director_after_update"; 742 743 /*************************************************** 744 * implementation of DisplayLinkDirector 745 **************************************************/ 746 cc.DisplayLinkDirector = cc.Director.extend(/** @lends cc.director# */{ 747 invalid: false, 748 749 /** 750 * start Animation 751 */ 752 startAnimation: function () { 753 this._nextDeltaTimeZero = true; 754 this.invalid = false; 755 }, 756 757 /** 758 * main loop of director 759 */ 760 mainLoop: function () { 761 if (this._purgeDirectorInNextLoop) { 762 this._purgeDirectorInNextLoop = false; 763 this.purgeDirector(); 764 } 765 else if (!this.invalid) { 766 this.drawScene(); 767 } 768 }, 769 770 /** 771 * stop animation 772 */ 773 stopAnimation: function () { 774 this.invalid = true; 775 }, 776 777 /** 778 * set Animation Interval 779 * @param {Number} value 780 */ 781 setAnimationInterval: function (value) { 782 this._animationInterval = value; 783 if (!this.invalid) { 784 this.stopAnimation(); 785 this.startAnimation(); 786 } 787 } 788 }); 789 790 cc.Director.sharedDirector = null; 791 cc.Director.firstUseDirector = true; 792 793 cc.Director._getInstance = function () { 794 if (cc.Director.firstUseDirector) { 795 cc.Director.firstUseDirector = false; 796 cc.Director.sharedDirector = new cc.DisplayLinkDirector(); 797 cc.Director.sharedDirector.init(); 798 } 799 return cc.Director.sharedDirector; 800 }; 801 802 /** 803 * set default fps to 60 804 * @type Number 805 */ 806 cc.defaultFPS = 60; 807 808 //Possible OpenGL projections used by director 809 /** 810 * sets a 2D projection (orthogonal projection) 811 * @constant 812 * @type Number 813 */ 814 cc.Director.PROJECTION_2D = 0; 815 816 /** 817 * sets a 3D projection with a fovy=60, znear=0.5f and zfar=1500. 818 * @constant 819 * @type Number 820 */ 821 cc.Director.PROJECTION_3D = 1; 822 823 /** 824 * it calls "updateProjection" on the projection delegate. 825 * @constant 826 * @type Number 827 */ 828 cc.Director.PROJECTION_CUSTOM = 3; 829 830 /** 831 * Default projection is 3D projection 832 * @constant 833 * @type Number 834 */ 835 cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D; 836 837 if (cc._renderType === cc._RENDER_TYPE_CANVAS) { 838 839 var _p = cc.Director.prototype; 840 841 _p.setProjection = function (projection) { 842 this._projection = projection; 843 cc.eventManager.dispatchEvent(this._eventProjectionChanged); 844 }; 845 846 _p.setDepthTest = function () { 847 }; 848 849 _p.setOpenGLView = function (openGLView) { 850 // set size 851 this._winSizeInPoints.width = cc._canvas.width; //this._openGLView.getDesignResolutionSize(); 852 this._winSizeInPoints.height = cc._canvas.height; 853 this._openGLView = openGLView || cc.view; 854 if (cc.eventManager) 855 cc.eventManager.setEnabled(true); 856 }; 857 858 _p._clear = function () { 859 var viewport = this._openGLView.getViewPortRect(); 860 cc._renderContext.clearRect(-viewport.x, viewport.y, viewport.width, -viewport.height); 861 }; 862 863 864 _p._createStatsLabel = function () { 865 var _t = this; 866 var fontSize = 0; 867 if (_t._winSizeInPoints.width > _t._winSizeInPoints.height) 868 fontSize = 0 | (_t._winSizeInPoints.height / 320 * 24); 869 else 870 fontSize = 0 | (_t._winSizeInPoints.width / 320 * 24); 871 872 _t._FPSLabel = cc.LabelTTF.create("000.0", "Arial", fontSize); 873 _t._SPFLabel = cc.LabelTTF.create("0.000", "Arial", fontSize); 874 _t._drawsLabel = cc.LabelTTF.create("0000", "Arial", fontSize); 875 876 var locStatsPosition = cc.DIRECTOR_STATS_POSITION; 877 _t._drawsLabel.setPosition(_t._drawsLabel.width / 2 + locStatsPosition.x, _t._drawsLabel.height * 5 / 2 + locStatsPosition.y); 878 _t._SPFLabel.setPosition(_t._SPFLabel.width / 2 + locStatsPosition.x, _t._SPFLabel.height * 3 / 2 + locStatsPosition.y); 879 _t._FPSLabel.setPosition(_t._FPSLabel.width / 2 + locStatsPosition.x, _t._FPSLabel.height / 2 + locStatsPosition.y); 880 }; 881 882 _p.getVisibleSize = function () { 883 //if (this._openGLView) { 884 //return this._openGLView.getVisibleSize(); 885 //} else { 886 return this.getWinSize(); 887 //} 888 }; 889 890 _p.getVisibleOrigin = function () { 891 //if (this._openGLView) { 892 //return this._openGLView.getVisibleOrigin(); 893 //} else { 894 return cc.p(0, 0); 895 //} 896 }; 897 } else { 898 cc.Director._fpsImage = new Image(); 899 cc._addEventListener(cc.Director._fpsImage, "load", function () { 900 cc.Director._fpsImageLoaded = true; 901 }); 902 if (cc._fpsImage) { 903 cc.Director._fpsImage.src = cc._fpsImage; 904 } 905 cc.assert(typeof cc._tmp.DirectorWebGL === "function", cc._LogInfos.MissingFile, "CCDirectorWebGL.js"); 906 cc._tmp.DirectorWebGL(); 907 delete cc._tmp.DirectorWebGL; 908 }