This commit is contained in:
Ming 2010-09-30 07:54:15 +00:00
parent 72aee0eace
commit 0247182dc3
2 changed files with 58 additions and 46 deletions

View File

@ -125,6 +125,10 @@ bool CCDirector::init(void)
// FPS // FPS
m_bDisplayFPS = false; m_bDisplayFPS = false;
m_nFrames = 0; m_nFrames = 0;
m_pszFPS = new char[10];
m_fExpectedFrameRate = 1 / m_dAnimationInterval;
// paused ? // paused ?
m_bPaused = false; m_bPaused = false;
@ -136,6 +140,7 @@ bool CCDirector::init(void)
m_bIsContentScaleSupported =false; m_bIsContentScaleSupported =false;
m_pLastUpdate = new struct cc_timeval(); m_pLastUpdate = new struct cc_timeval();
m_pLastComputeTime = new struct cc_timeval();
// create autorelease pool // create autorelease pool
NSPoolManager::getInstance()->push(); NSPoolManager::getInstance()->push();
@ -162,8 +167,13 @@ CCDirector::~CCDirector(void)
NSPoolManager::getInstance()->pop(); NSPoolManager::getInstance()->pop();
// delete m_pLastUpdate // delete m_pLastUpdate
delete m_pLastUpdate; CCX_SAFE_DELETE(m_pLastUpdate);
m_pLastUpdate = NULL;
// delete last compute time
CCX_SAFE_DELETE(m_pLastComputeTime);
// delete fps string
delete []m_pszFPS;
} }
void CCDirector::setGLDefaultValues(void) void CCDirector::setGLDefaultValues(void)
@ -181,11 +191,8 @@ void CCDirector::setGLDefaultValues(void)
#if CC_DIRECTOR_FAST_FPS #if CC_DIRECTOR_FAST_FPS
if (! m_pFPSLabel) if (! m_pFPSLabel)
{ {
// CCTexture2DPixelFormat currentFormat = CCTexture2D::defaultAlphaPixelFormat();
// CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGBA4444);
m_pFPSLabel = CCLabel::labelWithString("00.0", "XXX", 24); m_pFPSLabel = CCLabel::labelWithString("00.0", "XXX", 24);
m_pFPSLabel->retain(); m_pFPSLabel->retain();
/*CCTexture2D::setDefaultAlphaPixelFormat(currentFormat);*/
} }
#endif #endif
} }
@ -261,7 +268,7 @@ void CCDirector::calculateDeltaTime(void)
m_fDeltaTime = 0; m_fDeltaTime = 0;
m_bNextDeltaTimeZero = false; m_bNextDeltaTimeZero = false;
} }
else else
{ {
m_fDeltaTime = (now.tv_sec - m_pLastUpdate->tv_sec) + (now.tv_usec - m_pLastUpdate->tv_usec) / 1000000.0f; m_fDeltaTime = (now.tv_sec - m_pLastUpdate->tv_sec) + (now.tv_usec - m_pLastUpdate->tv_usec) / 1000000.0f;
m_fDeltaTime = MAX(0, m_fDeltaTime); m_fDeltaTime = MAX(0, m_fDeltaTime);
@ -656,8 +663,6 @@ void CCDirector::end(void)
void CCDirector::setNextScene(void) void CCDirector::setNextScene(void)
{ {
// bool runningIsTransition = dynamic_cast<CCTransitionScene *>(m_pRunningScene) != NULL;
// bool newIsTransition = dynamic_cast<CCTransitionScene *>(m_pNextScene) != NULL;
ccSceneFlag runningSceneType = ccNormalScene; ccSceneFlag runningSceneType = ccNormalScene;
ccSceneFlag newSceneType = m_pNextScene->getSceneType(); ccSceneFlag newSceneType = m_pNextScene->getSceneType();
@ -691,7 +696,6 @@ void CCDirector::setNextScene(void)
m_pNextScene->retain(); m_pNextScene->retain();
m_pNextScene = NULL; m_pNextScene = NULL;
/*if (! runningIsTransition && m_pRunningScene)*/
if (! (runningSceneType & ccTransitionScene) && m_pRunningScene) if (! (runningSceneType & ccTransitionScene) && m_pRunningScene)
{ {
m_pRunningScene->onEnter(); m_pRunningScene->onEnter();
@ -754,25 +758,29 @@ void CCDirector::preMainLoop(void)
// updates the FPS every frame // updates the FPS every frame
void CCDirector::showFPS(void) void CCDirector::showFPS(void)
{ {
++m_nFrames; sprintf(m_pszFPS, "%.1f", m_fFrameRate);
m_fAccumDt += m_fDeltaTime; m_pFPSLabel->setString(m_pszFPS);
if (m_fAccumDt > CC_DIRECTOR_FPS_INTERVAL)
{
m_fFrameRate = m_nFrames / m_fAccumDt;
m_nFrames = 0;
m_fAccumDt = 0;
char *str = new char[10];
sprintf(str, "%.1f", m_fFrameRate);
m_pFPSLabel->setString(str);
delete [] str;
}
m_pFPSLabel->draw(); m_pFPSLabel->draw();
} }
#endif // CC_DIRECTOR_FAST_FPS #endif // CC_DIRECTOR_FAST_FPS
void CCDirector::computeFrameRate()
{
static bool bFirstTime = true;
struct cc_timeval now;
CCTime::gettimeofdayCocos2d(&now, NULL);
if (! bFirstTime)
{
m_fAccumDt += ((now.tv_sec - m_pLastComputeTime->tv_sec) + (now.tv_usec - m_pLastComputeTime->tv_usec) / 1000000.0f);
m_fFrameRate = m_nFrames / m_fAccumDt;
}
bFirstTime = false;
*m_pLastComputeTime = now;
}
#if CC_ENABLE_PROFILERS #if CC_ENABLE_PROFILERS
void CCDirector::showProfilers() void CCDirector::showProfilers()
{ {
@ -798,26 +806,23 @@ void CCDisplayLinkDirector::startAnimation(void)
} }
m_bInvalid = false; m_bInvalid = false;
// approximate frame rate
// assumes device refreshes at 60 fps
//int frameInterval = (int) floor(animationInterval * 60.0f);
//CCLOG(@"cocos2d: Frame interval: %d", frameInterval);
//displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(preMainLoop:)];
//[displayLink setFrameInterval:frameInterval];
//[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
} }
void CCDisplayLinkDirector::preMainLoop(void) void CCDisplayLinkDirector::preMainLoop(void)
{ {
if (! m_bInvalid) if (! m_bInvalid)
{ {
drawScene(); // compute frame rate
computeFrameRate();
// release the objects
NSPoolManager::getInstance()->pop(); if (m_fFrameRate < m_fExpectedFrameRate)
{
drawScene();
++m_nFrames;
// release the objects
NSPoolManager::getInstance()->pop();
}
} }
} }
@ -829,6 +834,7 @@ void CCDisplayLinkDirector::stopAnimation(void)
void CCDisplayLinkDirector::setAnimationInterval(double dValue) void CCDisplayLinkDirector::setAnimationInterval(double dValue)
{ {
m_dAnimationInterval = dValue; m_dAnimationInterval = dValue;
m_fExpectedFrameRate = 1 / m_dAnimationInterval;
if (! m_bInvalid) if (! m_bInvalid)
{ {
stopAnimation(); stopAnimation();

View File

@ -207,7 +207,7 @@ public:
/** Get the FPS value */ /** Get the FPS value */
inline double getAnimationInterval(void) { return m_dAnimationInterval; } inline double getAnimationInterval(void) { return m_dAnimationInterval; }
/** Set the FPS value. Now it has not effect. */ /** Set the FPS value. */
virtual void setAnimationInterval(double dValue); virtual void setAnimationInterval(double dValue);
/** Whether or not to display the FPS on the bottom-left corner */ /** Whether or not to display the FPS on the bottom-left corner */
@ -343,7 +343,7 @@ public:
/** Pauses the running scene. /** Pauses the running scene.
The running scene will be _drawed_ but all scheduled timers will be paused The running scene will be _drawed_ but all scheduled timers will be paused
While paused, the draw rate will be 4 FPS to reduce CPU consuption While paused, the draw rate will be 4 FPS to reduce CPU consumption
*/ */
void pause(void); void pause(void);
@ -354,13 +354,13 @@ public:
void resume(void); void resume(void);
/** Stops the animation. Nothing will be drawn. The main loop won't be triggered anymore. /** Stops the animation. Nothing will be drawn. The main loop won't be triggered anymore.
If you wan't to pause your animation call [pause] instead. If you don't want to pause your animation call [pause] instead.
*/ */
virtual void stopAnimation(void); virtual void stopAnimation(void);
/** The main loop is triggered again. /** The main loop is triggered again.
Call this function only if [stopAnimation] was called earlier Call this function only if [stopAnimation] was called earlier
@warning Dont' call this function to start the main loop. To run the main loop call runWithScene @warning Don't call this function to start the main loop. To run the main loop call runWithScene
*/ */
virtual void startAnimation(void); virtual void startAnimation(void);
@ -401,7 +401,7 @@ public:
- kCCDirectorTypeDisplayLink - kCCDirectorTypeDisplayLink
Each Director has it's own benefits, limitations. Each Director has it's own benefits, limitations.
Now we only support DisplayLink director, so it has not effect Now we only support DisplayLink director, so it has not effect.
This method should be called before any other call to the director. This method should be called before any other call to the director.
@ -434,6 +434,9 @@ protected:
*/ */
void recalculateProjectionAndEAGLViewSize(); void recalculateProjectionAndEAGLViewSize();
protected:
void computeFrameRate(void);
protected: protected:
/* The CCXEGLView, where everything is rendered */ /* The CCXEGLView, where everything is rendered */
cocos2d::CCXEGLView *m_pobOpenGLView; cocos2d::CCXEGLView *m_pobOpenGLView;
@ -454,6 +457,7 @@ protected:
int m_nFrames; int m_nFrames;
ccTime m_fAccumDt; ccTime m_fAccumDt;
ccTime m_fFrameRate; ccTime m_fFrameRate;
ccTime m_fExpectedFrameRate;
#if CC_DIRECTOR_FAST_FPS #if CC_DIRECTOR_FAST_FPS
CCLabel *m_pFPSLabel; CCLabel *m_pFPSLabel;
#endif #endif
@ -477,6 +481,9 @@ protected:
/* last time the main loop was updated */ /* last time the main loop was updated */
struct cc_timeval *m_pLastUpdate; struct cc_timeval *m_pLastUpdate;
/* last time the frame fate is computed */
struct cc_timeval *m_pLastComputeTime;
/* delta time since last tick to main loop */ /* delta time since last tick to main loop */
ccTime m_fDeltaTime; ccTime m_fDeltaTime;
@ -497,6 +504,9 @@ protected:
/* contentScaleFactor could be simulated */ /* contentScaleFactor could be simulated */
bool m_bIsContentScaleSupported; bool m_bIsContentScaleSupported;
/* store the fps string */
char *m_pszFPS;
#if CC_ENABLE_PROFILERS #if CC_ENABLE_PROFILERS
ccTime m_fAccumDtForProfiler; ccTime m_fAccumDtForProfiler;
@ -507,12 +517,9 @@ protected:
@brief DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display. @brief DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display.
Features and Limitations: Features and Limitations:
- Only available on 3.1+
- Scheduled timers & drawing are synchronizes with the refresh rate of the display - Scheduled timers & drawing are synchronizes with the refresh rate of the display
- Only supports animation intervals of 1/60 1/30 & 1/15 - Only supports animation intervals of 1/60 1/30 & 1/15
It is the recommended Director if the SDK is 3.1 or newer
@since v0.8.2 @since v0.8.2
*/ */
class CCDisplayLinkDirector : public CCDirector class CCDisplayLinkDirector : public CCDirector
@ -520,7 +527,6 @@ class CCDisplayLinkDirector : public CCDirector
public: public:
CCDisplayLinkDirector(void) {} CCDisplayLinkDirector(void) {}
//static CCDisplayLinkDirector* getSharedDirector(void);
virtual void preMainLoop(void); virtual void preMainLoop(void);
virtual void setAnimationInterval(double dValue); virtual void setAnimationInterval(double dValue);
virtual void startAnimation(void); virtual void startAnimation(void);