-1

I would like to ask your help, I'm kind of lost. I am upgrading my game so it could be universal. I'm using cocos2d-iphone version 1.0.1. I've extended the CCDirectorIOS class, so it scales the the iPhone resolution to iPad (only the width, no stretch). It works almost perfectly. I get stable 60 fps with:

  • 3GS iPhone/iPod, normal textures, 4G iPod/iPhone with Retina
  • textures.

Here comes the akward part:

  • iPad 1/2/3/mini, iPhone app (not Universal), with Retina textures = stable 60 fps,
  • iPad 1/2 and mini, app set to Universal, with Retina textures = 20 fps,
  • and with normal textures 60 fps and the iPad 3 with Retina textures = stable 60 fps.

So it runs on lowres iPads with 20 fps with retina textures. I can't figure it out.

Here's the source of the modified CCDirectorIOS class (only the modifications):

//CCDirectorIOS.h only the modified

typedef enum {
/// sets a 2D projection (orthogonal projection).
kCCDirectorProjection2D,

/// sets a 3D projection with a fovy=60, znear=0.5f and zfar=1500.
kCCDirectorProjection3D,

/// it calls "updateProjection" on the projection delegate.
kCCDirectorProjectionCustom,

/// Detault projection is 3D projection
kCCDirectorProjectionDefault = kCCDirectorProjection2D, // this was 3D

// backward compatibility stuff
CCDirectorProjection2D = kCCDirectorProjection2D,
CCDirectorProjection3D = kCCDirectorProjection3D,
CCDirectorProjectionCustom = kCCDirectorProjectionCustom,

} ccDirectorProjection;

@interface CCDirector : NSObject
{
//...

float m_VirtualWindowScale; //default 1
float m_VirtualWindowHeight; // default 0
float m_VirtualWindowWidth; // default 0
float mScaleFactor;
//...
}
//...

// stretch and virtual height
-(void) setVirtualWindowScale: (float) scale andH:(float) height;
-(float) getVirtualWindowScale;
-(float) getVirtualWindowHeight;
-(float) getVirtualWindowWidth;
//...
@end



//CCDirectorIOS.m only the modified

//...
-(void) setProjection:(ccDirectorProjection)projection
{
CGSize size = winSizeInPixels_;

switch (projection) {
case kCCDirectorProjection2D:
{
glViewport(0, 0, size.width, size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ccglOrtho(0, size.width / m_VirtualWindowScale, 0, size.height / m_VirtualWindowScale, -1024 * CC_CONTENT_SCALE_FACTOR(), 1024 * CC_CONTENT_SCALE_FACTOR()); //-----------
glMatrixMode(GL_MODELVIEW);
//glDepthFunc(GL_ALWAYS);
glLoadIdentity();
break;
}

case kCCDirectorProjection3D:
{
float zeye = [self getZEye];

glViewport(0, 0, size.width, size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//   gluPerspective(60, (GLfloat)size.width/size.height, zeye-size.height/2, zeye+size.height/2 );
gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( size.width/2, size.height/2, zeye,
size.width/2, size.height/2, 0,
0.0f, 1.0f, 0.0f);
break;
}

case kCCDirectorProjectionCustom:
if( projectionDelegate_ )
[projectionDelegate_ updateProjection];
break;

default:
CCLOG(@"cocos2d: Director: unrecognized projecgtion");
break;
}

projection_ = projection;
}

//...

-(CGPoint)convertToGL:(CGPoint)uiPoint
{
CGSize s = winSizeInPoints_;
float newY = s.height - uiPoint.y;
float newX = s.width - uiPoint.x;

CGPoint ret = CGPointZero;
switch ( deviceOrientation_) {
case CCDeviceOrientationPortrait:
ret = ccp( uiPoint.x, newY );
break;
case CCDeviceOrientationPortraitUpsideDown:
ret = ccp(newX, uiPoint.y);
break;
case CCDeviceOrientationLandscapeLeft:
ret.x = uiPoint.y;
ret.y = uiPoint.x;
break;
case CCDeviceOrientationLandscapeRight:
ret.x = newY;
ret.y = newX;
break;
}
ret = ccpMult(ret, 1.0f / m_VirtualWindowScale); //-----------
return ret;
}

-(CGPoint)convertToUI:(CGPoint)glPoint
{
CGSize winSize = winSizeInPoints_;
int oppositeX = winSize.width - glPoint.x;
int oppositeY = winSize.height - glPoint.y;
CGPoint uiPoint = CGPointZero;
switch ( deviceOrientation_) {
case CCDeviceOrientationPortrait:
uiPoint = ccp(glPoint.x, oppositeY);
break;
case CCDeviceOrientationPortraitUpsideDown:
uiPoint = ccp(oppositeX, glPoint.y);
break;
case CCDeviceOrientationLandscapeLeft:
uiPoint = ccp(glPoint.y, glPoint.x);
break;
case CCDeviceOrientationLandscapeRight:
// Can't use oppositeX/Y because x/y are flipped
uiPoint = ccp(winSize.width-glPoint.y, winSize.height-glPoint.x);
break;
}
//uiPoint = ccpMult(uiPoint, 1/__ccContentScaleFactor);
uiPoint = ccpMult(uiPoint, 1/(__ccContentScaleFactor* m_VirtualWindowScale)); //-----------
return uiPoint;
}

//...

At the end of my applicationDidFinishLaunch in Appdelegate I added these:

if ([[CCDirector sharedDirector] enableRetinaDisplay: YES]) {
NSLog(@"Retina Display enabled");
}

if ([[UIDevice currentDevice].model isEqualToString:@"iPad"]) {
[[CCDirector sharedDirector] setContentScaleFactor:2.0f];
}

NSLog(@"inpixels: %f inpoints: %f", [[CCDirector sharedDirector] winSizeInPixels].width, [[CCDirector sharedDirector] winSize].width);

int screenWidth = [[CCDirector sharedDirector] winSize].width; 
int screenHeight = [[CCDirector sharedDirector] winSize].height;

float scale = screenWidth / 320.0f;
float virtualHeight = screenHeight / scale;

[[CCDirector sharedDirector] setVirtualWindowScale:scale andH:virtualHeight]; 

I position everything to the virtualHeight, and VirtualWidth, so everything stays on the screen.

McDermott
  • 1,025
  • 2
  • 16
  • 28
  • Retina textures on non-Retina devices makes no sense and is counterproductive. Imagine a texture using 4x memory on a device that has 1/4th the memory (iPad 1) of a Retina iPad. – CodeSmile Feb 01 '13 at 09:22
  • I set the app to iPhone (not universal) and run it on an iPad 1GEN, it runs in letterbox, but with Retina textures. 60 fps, no memory warning, perfect. Then I set it to Universal, the game runs fullscreen, same Retina textures, no memory warnings and 20 fps. BTW, all the Retina assets fits in 16 MB of memory. – McDermott Feb 01 '13 at 09:30
  • 1
    the difference is fillrate, an iPad app needs to render about 4x as many pixels as a iPhone app, you can't compare their performance. Just use non Retina textures for non Retina devices. – CodeSmile Feb 01 '13 at 09:38

1 Answers1

1

You should not use scalefactor, i.e dont use the line below [SPStage setContentScaleFactor:2.0f]

if you dnt set scale factor everything runs smooth at 30 fps. But the downside is that the app is now running without HD graphics. Everything looks blurry on the iPad.

It's a tough decision.Best is to turn an iPhone app into Universal, but you have to sacrifice performance. Your way of using tailored textures and content scale of 1 gives perfect result, but that means more work in modifiying the code.

Bharat Gulati
  • 796
  • 6
  • 12
  • Yes, I wanted to do this without huge ammount of modifications. But it looks like I have to stay with the blurred version. – McDermott Feb 04 '13 at 10:25