issue #1405:multi resolution works ok

This commit is contained in:
minggo 2012-08-07 14:29:46 +08:00
parent 5399aac590
commit 5d8f909af4
9 changed files with 107 additions and 134 deletions

View File

@ -56,6 +56,15 @@ THE SOFTWARE.
#include "CCEGLView.h"
#include <string>
/**
Position of the FPS
Default: 0,0 (bottom-left corner)
*/
#ifndef CC_DIRECTOR_STATS_POSITION
#define CC_DIRECTOR_STATS_POSITION CCDirector::sharedDirector()->getOpenGLView()->getVisibleOrigin()
#endif
using namespace std;
unsigned int g_uNumberOfDraws = 0;
@ -754,9 +763,9 @@ void CCDirector::createStatsLabel()
CCTexture2D::setDefaultAlphaPixelFormat(currentFormat);
m_pDrawsLabel->setPosition( ccpAdd( ccp(0,34), CC_DIRECTOR_STATS_POSITION ) );
m_pSPFLabel->setPosition( ccpAdd( ccp(0,17), CC_DIRECTOR_STATS_POSITION ) );
m_pFPSLabel->setPosition( CC_DIRECTOR_STATS_POSITION );
m_pDrawsLabel->setPosition(ccpAdd(ccp(0,34), CC_DIRECTOR_STATS_POSITION));
m_pSPFLabel->setPosition(ccpAdd(ccp(0,17), CC_DIRECTOR_STATS_POSITION));
m_pFPSLabel->setPosition(CC_DIRECTOR_STATS_POSITION);
}
@ -766,16 +775,7 @@ void CCDirector::createStatsLabel()
void CCDirector::updateContentScaleFactor()
{
// [openGLView responseToSelector:@selector(setContentScaleFactor)]
if (m_pobOpenGLView->canSetContentScaleFactor())
{
m_pobOpenGLView->setContentScaleFactor(m_fContentScaleFactor);
m_bIsContentScaleSupported = true;
}
else
{
CCLOG("cocos2d: setContentScaleFactor:'is not supported on this device");
}
m_bIsContentScaleSupported = m_pobOpenGLView->setContentScaleFactor(m_fContentScaleFactor);
}
bool CCDirector::enableRetinaDisplay(bool enabled)
@ -791,15 +791,8 @@ bool CCDirector::enableRetinaDisplay(bool enabled)
{
return false;
}
// setContentScaleFactor is not supported
if (! m_pobOpenGLView->canSetContentScaleFactor())
{
return false;
}
// SD device
if (m_pobOpenGLView->getMainScreenScale() == 1.0)
if (! m_pobOpenGLView->enableRetina())
{
return false;
}

View File

@ -404,7 +404,9 @@ protected:
WatcherCallbackFun m_pWatcherFun;
void *m_pWatcherSender;
// CCEGLViewProtocol will recreate stats labels to fit visible rect
friend class CCEGLViewProtocol;
};
/**

View File

@ -76,16 +76,6 @@ To enabled set it to 1. Disabled by default.
#define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 0
#endif
/** @def CC_DIRECTOR_STATS_POSITION
Position of the FPS
Default: 0,0 (bottom-left corner)
*/
#ifndef CC_DIRECTOR_STATS_POSITION
#define CC_DIRECTOR_STATS_POSITION ccp(0,0)
#endif
/** @def CC_DIRECTOR_FPS_INTERVAL
Senconds between FPS updates.
0.5 seconds, means that the FPS number will be updated every 0.5 seconds.

View File

@ -48,8 +48,8 @@ CCEGLViewProtocol::CCEGLViewProtocol()
, m_fYScale(1.0f)
, m_fXScale(1.0f)
, m_bIsRetinaEnabled(false)
, m_eResolutionPolicy(kResolutionUnKnown)
{
strncpy(m_szViewName, "Cocos2d-x Game", sizeof(m_szViewName));
}
CCEGLViewProtocol::~CCEGLViewProtocol()
@ -57,21 +57,10 @@ CCEGLViewProtocol::~CCEGLViewProtocol()
}
void CCEGLViewProtocol::setFrameSize(float width, float height)
{
m_obScreenSize.setSize(width, height);
m_obViewPortRect.size.setSize(width, height);
m_obDesignResolutionSize.setSize(width, height);
}
CCSize CCEGLViewProtocol::getFrameSize()
{
return m_obScreenSize;
}
void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
CCAssert(CC_CONTENT_SCALE_FACTOR() == 1.0f, "retina and scale mode can't be opened at the same time!");
CCAssert(m_bIsRetinaEnabled == false, "can not enable retina while set design resolution size!");
CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");
if (width == 0.0f || height == 0.0f)
{
@ -98,6 +87,19 @@ void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, Resol
float viewPortH = m_obDesignResolutionSize.height * m_fYScale;
m_obViewPortRect.setRect((m_obScreenSize.width - viewPortW) / 2, (m_obScreenSize.height - viewPortH) / 2, viewPortW, viewPortH);
m_eResolutionPolicy = resolutionPolicy;
setViewPortInPoints(0, 0, m_obScreenSize.width, m_obScreenSize.height);
// reset director's member vaviables to fit visible rect
CCDirector::sharedDirector()->createStatsLabel();
CCDirector::sharedDirector()->m_obWinSizeInPoints = CCDirector::sharedDirector()->m_obWinSizeInPixels = getSize();
}
bool CCEGLViewProtocol::enableRetina()
{
return false;
}
CCSize CCEGLViewProtocol::getSize()
@ -105,31 +107,34 @@ CCSize CCEGLViewProtocol::getSize()
return m_obDesignResolutionSize;
}
void CCEGLViewProtocol::setSize(float width, float height)
{
m_obDesignResolutionSize = m_obScreenSize = CCSizeMake(width, height);
}
CCSize CCEGLViewProtocol::getVisibleSize()
{
/*
float width = m_obSizeInPoint.width;
float height = m_sSizeInPoint.height;
if (m_fXScale > m_fYScale)
if (m_eResolutionPolicy == kResolutionScaleFullScreen)
{
width *= (m_fYScale/m_fXScale);
return CCSizeMake(m_obScreenSize.width/m_fXScale, m_obScreenSize.height/m_fYScale);
}
if (m_fYScale > m_fXScale)
else
{
height *= (m_fXScale/m_fYScale);
return m_obDesignResolutionSize;
}
return CCSizeMake(width, height);
*/
return CCSizeZero;
}
CCPoint CCEGLViewProtocol::getVisibleOrigin()
{
return CCPointZero;
if (m_eResolutionPolicy == kResolutionScaleFullScreen)
{
return CCPointMake((m_obDesignResolutionSize.width - m_obScreenSize.width/m_fXScale)/2,
(m_obDesignResolutionSize.height - m_obScreenSize.height/m_fYScale)/2);
}
else
{
return CCPointZero;
}
}
void CCEGLViewProtocol::setTouchDelegate(EGLTouchDelegate * pDelegate)
@ -142,16 +147,11 @@ float CCEGLViewProtocol::getScreenScaleFactor()
return m_fScreenScaleFactor;
}
bool CCEGLViewProtocol::canSetContentScaleFactor()
bool CCEGLViewProtocol::setContentScaleFactor(float contentScaleFactor)
{
return false;
}
void CCEGLViewProtocol::setContentScaleFactor(float contentScaleFactor)
{
// should not run here
}
void CCEGLViewProtocol::setViewPortInPoints(float x , float y , float w , float h)
{
glViewport((GLint)(x * m_fXScale + m_obViewPortRect.origin.x),
@ -168,24 +168,6 @@ void CCEGLViewProtocol::setScissorInPoints(float x , float y , float w , float h
(GLsizei)(h * m_fYScale));
}
float CCEGLViewProtocol::getMainScreenScale()
{
return -1.0f;
}
void CCEGLViewProtocol::setViewName(const char* pszViewName)
{
if (pszViewName != NULL && strlen(pszViewName) > 0)
{
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
}
}
const char* CCEGLViewProtocol::getViewName()
{
return m_szViewName;
}
void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[])
{
CCSet set;
@ -223,7 +205,7 @@ void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float
(y - m_obViewPortRect.origin.y) / m_fYScale);
}
CCLog("x = %f y = %f", pTouch->getLocation().x, pTouch->getLocation().y);
CCLog("x = %f y = %f", pTouch->getLocationInView().x, pTouch->getLocationInView().y);
CCInteger* pInterObj = new CCInteger(nUnusedIndex);
s_TouchesIntergerDict.setObject(pInterObj, id);

View File

@ -10,7 +10,9 @@ enum ResolutionPolicy
// the output will fill the screen, scale of x and y is the same
kResolutionScaleFullScreen,
// scale of x and y is the same, there may be black block in x or y coordinate
kResolutionScaleNotFullScreen
kResolutionScaleNotFullScreen,
kResolutionUnKnown,
};
NS_CC_BEGIN
@ -37,20 +39,16 @@ public:
virtual void setIMEKeyboardState(bool bOpen) = 0;
virtual CCSize getSize();
virtual void setSize(float width, float height);
virtual CCSize getVisibleSize();
virtual CCPoint getVisibleOrigin();
virtual void setFrameSize(float width, float height);
virtual CCSize getFrameSize();
virtual void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy);
virtual void setTouchDelegate(EGLTouchDelegate * pDelegate);
virtual float getScreenScaleFactor();
virtual bool canSetContentScaleFactor();
virtual void setContentScaleFactor(float contentScaleFactor);
virtual bool setContentScaleFactor(float contentScaleFactor);
virtual void setViewPortInPoints(float x , float y , float w , float h);
virtual void setScissorInPoints(float x , float y , float w , float h);
virtual float getMainScreenScale();
virtual void setViewName(const char* pszViewName);
const char* getViewName();
virtual bool enableRetina();
/** handle touch events by default, if you want to custom your handles, please override these functions */
virtual void handleTouchesBegin(int num, int ids[], float xs[], float ys[]);

View File

@ -38,21 +38,17 @@ public:
CCEGLView();
~CCEGLView();
CCSize getSize();
bool isOpenGLReady();
bool canSetContentScaleFactor();
bool isIpad();
void setContentScaleFactor(float contentScaleFactor);
virtual bool isOpenGLReady();
virtual bool isIpad();
virtual bool setContentScaleFactor(float contentScaleFactor);
virtual CCSize getFrameSize();
virtual bool enableRetina();
// keep compatible
void end();
void swapBuffers();
virtual void end();
virtual void swapBuffers();
float getMainScreenScale();
void setIMEKeyboardState(bool bOpen);
virtual void setIMEKeyboardState(bool bOpen);
static CCEGLView& sharedOpenGLView();

View File

@ -32,7 +32,8 @@ NS_CC_BEGIN
CCEGLView::CCEGLView()
{
m_obScreenSize.width = m_obDesignResolutionSize.width = [[EAGLView sharedEGLView] getWidth];
m_obScreenSize.height = m_obDesignResolutionSize.height = [[EAGLView sharedEGLView] getHeight];
}
CCEGLView::~CCEGLView()
@ -40,13 +41,6 @@ CCEGLView::~CCEGLView()
}
CCSize CCEGLView::getSize()
{
cocos2d::CCSize size([[EAGLView sharedEGLView] getWidth], [[EAGLView sharedEGLView] getHeight]);
return size;
}
bool CCEGLView::isIpad()
{
return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
@ -57,19 +51,38 @@ bool CCEGLView::isOpenGLReady()
return [EAGLView sharedEGLView] != NULL;
}
bool CCEGLView::canSetContentScaleFactor()
bool CCEGLView::setContentScaleFactor(float contentScaleFactor)
{
return [[EAGLView sharedEGLView] respondsToSelector:@selector(setContentScaleFactor:)];
// can not enable retina because have used resolution policy
assert(m_eResolutionPolicy == kResolutionUnKnown);
if ([[EAGLView sharedEGLView] respondsToSelector:@selector(setContentScaleFactor:)])
{
UIView * view = [EAGLView sharedEGLView];
view.contentScaleFactor = contentScaleFactor;
[view setNeedsLayout];
m_fXScale = m_fYScale = contentScaleFactor;
m_bIsRetinaEnabled = true;
return true;
}
else
{
return false;
}
}
void CCEGLView::setContentScaleFactor(float contentScaleFactor)
bool CCEGLView::enableRetina()
{
UIView * view = [EAGLView sharedEGLView];
view.contentScaleFactor = contentScaleFactor;
[view setNeedsLayout];
bool ret = true;
m_fXScale = m_fYScale = contentScaleFactor;
m_bIsRetinaEnabled = true;
// can set content scale factor?
ret &= [[EAGLView sharedEGLView] respondsToSelector:@selector(setContentScaleFactor:)];
// SD device?
ret &= ([[UIScreen mainScreen] scale] != 1.0f);
return ret;
}
void CCEGLView::end()
@ -110,10 +123,5 @@ CCEGLView& CCEGLView::sharedOpenGLView()
return instance;
}
float CCEGLView::getMainScreenScale()
{
return [[UIScreen mainScreen] scale];
}
NS_CC_END

View File

@ -16,6 +16,9 @@ bool AppDelegate::applicationDidFinishLaunching() {
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());
// can not enable retina if invoke
CCEGLView::sharedOpenGLView().setDesignResolutionSize(480, 320, kResolutionScaleFullScreen);
// enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
pDirector->enableRetinaDisplay(true);

View File

@ -26,6 +26,9 @@ bool HelloWorld::init()
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getOpenGLView()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getOpenGLView()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
@ -37,11 +40,11 @@ bool HelloWorld::init()
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback) );
pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );
pCloseItem->setPosition( ccp(visibleSize.width - 20, origin.y + 20) );
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition( CCPointZero );
pMenu->setPosition(origin);
this->addChild(pMenu, 1);
/////////////////////////////
@ -50,11 +53,9 @@ bool HelloWorld::init()
// add a label shows "Hello World"
// create and initialize a label
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
// ask director the window size
CCSize size = CCDirector::sharedDirector()->getWinSize();
// position the label on the center of the screen
pLabel->setPosition( ccp(size.width / 2, size.height - 50) );
pLabel->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height - 50 + origin.y));
// add the label as a child to this layer
this->addChild(pLabel, 1);
@ -63,7 +64,7 @@ bool HelloWorld::init()
CCSprite* pSprite = CCSprite::create("HelloWorld.png");
// position the sprite on the center of the screen
pSprite->setPosition( ccp(size.width/2, size.height/2) );
pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
// add the sprite as a child to this layer
this->addChild(pSprite, 0);