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