Skip to content

Commit 0247182

Browse files
author
Ming
committed
fixed #173
1 parent 72aee0e commit 0247182

File tree

2 files changed

+57
-45
lines changed

2 files changed

+57
-45
lines changed

cocos2dx/CCDirector.cpp

+42-36
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ bool CCDirector::init(void)
125125
// FPS
126126
m_bDisplayFPS = false;
127127
m_nFrames = 0;
128+
m_pszFPS = new char[10];
129+
m_fExpectedFrameRate = 1 / m_dAnimationInterval;
130+
131+
128132

129133
// paused ?
130134
m_bPaused = false;
@@ -136,6 +140,7 @@ bool CCDirector::init(void)
136140
m_bIsContentScaleSupported =false;
137141

138142
m_pLastUpdate = new struct cc_timeval();
143+
m_pLastComputeTime = new struct cc_timeval();
139144

140145
// create autorelease pool
141146
NSPoolManager::getInstance()->push();
@@ -162,8 +167,13 @@ CCDirector::~CCDirector(void)
162167
NSPoolManager::getInstance()->pop();
163168

164169
// delete m_pLastUpdate
165-
delete m_pLastUpdate;
166-
m_pLastUpdate = NULL;
170+
CCX_SAFE_DELETE(m_pLastUpdate);
171+
172+
// delete last compute time
173+
CCX_SAFE_DELETE(m_pLastComputeTime);
174+
175+
// delete fps string
176+
delete []m_pszFPS;
167177
}
168178

169179
void CCDirector::setGLDefaultValues(void)
@@ -181,11 +191,8 @@ void CCDirector::setGLDefaultValues(void)
181191
#if CC_DIRECTOR_FAST_FPS
182192
if (! m_pFPSLabel)
183193
{
184-
// CCTexture2DPixelFormat currentFormat = CCTexture2D::defaultAlphaPixelFormat();
185-
// CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA4444);
186194
m_pFPSLabel = CCLabel::labelWithString("00.0", "XXX", 24);
187195
m_pFPSLabel->retain();
188-
/*CCTexture2D::setDefaultAlphaPixelFormat(currentFormat);*/
189196
}
190197
#endif
191198
}
@@ -261,7 +268,7 @@ void CCDirector::calculateDeltaTime(void)
261268
m_fDeltaTime = 0;
262269
m_bNextDeltaTimeZero = false;
263270
}
264-
else
271+
else
265272
{
266273
m_fDeltaTime = (now.tv_sec - m_pLastUpdate->tv_sec) + (now.tv_usec - m_pLastUpdate->tv_usec) / 1000000.0f;
267274
m_fDeltaTime = MAX(0, m_fDeltaTime);
@@ -656,8 +663,6 @@ void CCDirector::end(void)
656663

657664
void CCDirector::setNextScene(void)
658665
{
659-
// bool runningIsTransition = dynamic_cast<CCTransitionScene *>(m_pRunningScene) != NULL;
660-
// bool newIsTransition = dynamic_cast<CCTransitionScene *>(m_pNextScene) != NULL;
661666
ccSceneFlag runningSceneType = ccNormalScene;
662667
ccSceneFlag newSceneType = m_pNextScene->getSceneType();
663668

@@ -691,7 +696,6 @@ void CCDirector::setNextScene(void)
691696
m_pNextScene->retain();
692697
m_pNextScene = NULL;
693698

694-
/*if (! runningIsTransition && m_pRunningScene)*/
695699
if (! (runningSceneType & ccTransitionScene) && m_pRunningScene)
696700
{
697701
m_pRunningScene->onEnter();
@@ -754,24 +758,28 @@ void CCDirector::preMainLoop(void)
754758
// updates the FPS every frame
755759
void CCDirector::showFPS(void)
756760
{
757-
++m_nFrames;
758-
m_fAccumDt += m_fDeltaTime;
761+
sprintf(m_pszFPS, "%.1f", m_fFrameRate);
762+
m_pFPSLabel->setString(m_pszFPS);
759763

760-
if (m_fAccumDt > CC_DIRECTOR_FPS_INTERVAL)
761-
{
764+
m_pFPSLabel->draw();
765+
}
766+
#endif // CC_DIRECTOR_FAST_FPS
767+
768+
void CCDirector::computeFrameRate()
769+
{
770+
static bool bFirstTime = true;
771+
struct cc_timeval now;
772+
773+
CCTime::gettimeofdayCocos2d(&now, NULL);
774+
if (! bFirstTime)
775+
{
776+
m_fAccumDt += ((now.tv_sec - m_pLastComputeTime->tv_sec) + (now.tv_usec - m_pLastComputeTime->tv_usec) / 1000000.0f);
762777
m_fFrameRate = m_nFrames / m_fAccumDt;
763-
m_nFrames = 0;
764-
m_fAccumDt = 0;
765-
766-
char *str = new char[10];
767-
sprintf(str, "%.1f", m_fFrameRate);
768-
m_pFPSLabel->setString(str);
769-
delete [] str;
770778
}
771779

772-
m_pFPSLabel->draw();
780+
bFirstTime = false;
781+
*m_pLastComputeTime = now;
773782
}
774-
#endif // CC_DIRECTOR_FAST_FPS
775783

776784
#if CC_ENABLE_PROFILERS
777785
void CCDirector::showProfilers()
@@ -798,26 +806,23 @@ void CCDisplayLinkDirector::startAnimation(void)
798806
}
799807

800808
m_bInvalid = false;
801-
802-
// approximate frame rate
803-
// assumes device refreshes at 60 fps
804-
//int frameInterval = (int) floor(animationInterval * 60.0f);
805-
806-
//CCLOG(@"cocos2d: Frame interval: %d", frameInterval);
807-
808-
//displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(preMainLoop:)];
809-
//[displayLink setFrameInterval:frameInterval];
810-
//[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
811809
}
812810

813811
void CCDisplayLinkDirector::preMainLoop(void)
814812
{
815813
if (! m_bInvalid)
816814
{
817-
drawScene();
818-
819-
// release the objects
820-
NSPoolManager::getInstance()->pop();
815+
// compute frame rate
816+
computeFrameRate();
817+
818+
if (m_fFrameRate < m_fExpectedFrameRate)
819+
{
820+
drawScene();
821+
++m_nFrames;
822+
823+
// release the objects
824+
NSPoolManager::getInstance()->pop();
825+
}
821826
}
822827
}
823828

@@ -829,6 +834,7 @@ void CCDisplayLinkDirector::stopAnimation(void)
829834
void CCDisplayLinkDirector::setAnimationInterval(double dValue)
830835
{
831836
m_dAnimationInterval = dValue;
837+
m_fExpectedFrameRate = 1 / m_dAnimationInterval;
832838
if (! m_bInvalid)
833839
{
834840
stopAnimation();

cocos2dx/include/CCDirector.h

+15-9
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ class CCX_DLL CCDirector : public NSObject
207207

208208
/** Get the FPS value */
209209
inline double getAnimationInterval(void) { return m_dAnimationInterval; }
210-
/** Set the FPS value. Now it has not effect. */
210+
/** Set the FPS value. */
211211
virtual void setAnimationInterval(double dValue);
212212

213213
/** Whether or not to display the FPS on the bottom-left corner */
@@ -343,7 +343,7 @@ class CCX_DLL CCDirector : public NSObject
343343

344344
/** Pauses the running scene.
345345
The running scene will be _drawed_ but all scheduled timers will be paused
346-
While paused, the draw rate will be 4 FPS to reduce CPU consuption
346+
While paused, the draw rate will be 4 FPS to reduce CPU consumption
347347
*/
348348
void pause(void);
349349

@@ -354,13 +354,13 @@ class CCX_DLL CCDirector : public NSObject
354354
void resume(void);
355355

356356
/** Stops the animation. Nothing will be drawn. The main loop won't be triggered anymore.
357-
If you wan't to pause your animation call [pause] instead.
357+
If you don't want to pause your animation call [pause] instead.
358358
*/
359359
virtual void stopAnimation(void);
360360

361361
/** The main loop is triggered again.
362362
Call this function only if [stopAnimation] was called earlier
363-
@warning Dont' call this function to start the main loop. To run the main loop call runWithScene
363+
@warning Don't call this function to start the main loop. To run the main loop call runWithScene
364364
*/
365365
virtual void startAnimation(void);
366366

@@ -401,7 +401,7 @@ class CCX_DLL CCDirector : public NSObject
401401
- kCCDirectorTypeDisplayLink
402402
403403
Each Director has it's own benefits, limitations.
404-
Now we only support DisplayLink director, so it has not effect
404+
Now we only support DisplayLink director, so it has not effect.
405405
406406
This method should be called before any other call to the director.
407407
@@ -434,6 +434,9 @@ class CCX_DLL CCDirector : public NSObject
434434
*/
435435
void recalculateProjectionAndEAGLViewSize();
436436

437+
protected:
438+
void computeFrameRate(void);
439+
437440
protected:
438441
/* The CCXEGLView, where everything is rendered */
439442
cocos2d::CCXEGLView *m_pobOpenGLView;
@@ -454,6 +457,7 @@ class CCX_DLL CCDirector : public NSObject
454457
int m_nFrames;
455458
ccTime m_fAccumDt;
456459
ccTime m_fFrameRate;
460+
ccTime m_fExpectedFrameRate;
457461
#if CC_DIRECTOR_FAST_FPS
458462
CCLabel *m_pFPSLabel;
459463
#endif
@@ -477,6 +481,9 @@ class CCX_DLL CCDirector : public NSObject
477481
/* last time the main loop was updated */
478482
struct cc_timeval *m_pLastUpdate;
479483

484+
/* last time the frame fate is computed */
485+
struct cc_timeval *m_pLastComputeTime;
486+
480487
/* delta time since last tick to main loop */
481488
ccTime m_fDeltaTime;
482489

@@ -497,6 +504,9 @@ class CCX_DLL CCDirector : public NSObject
497504

498505
/* contentScaleFactor could be simulated */
499506
bool m_bIsContentScaleSupported;
507+
508+
/* store the fps string */
509+
char *m_pszFPS;
500510

501511
#if CC_ENABLE_PROFILERS
502512
ccTime m_fAccumDtForProfiler;
@@ -507,20 +517,16 @@ class CCX_DLL CCDirector : public NSObject
507517
@brief DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display.
508518
509519
Features and Limitations:
510-
- Only available on 3.1+
511520
- Scheduled timers & drawing are synchronizes with the refresh rate of the display
512521
- Only supports animation intervals of 1/60 1/30 & 1/15
513522
514-
It is the recommended Director if the SDK is 3.1 or newer
515-
516523
@since v0.8.2
517524
*/
518525
class CCDisplayLinkDirector : public CCDirector
519526
{
520527
public:
521528
CCDisplayLinkDirector(void) {}
522529

523-
//static CCDisplayLinkDirector* getSharedDirector(void);
524530
virtual void preMainLoop(void);
525531
virtual void setAnimationInterval(double dValue);
526532
virtual void startAnimation(void);

0 commit comments

Comments
 (0)