私はあなたの助けをお願いしたいのですが、私はちょっと迷っています。ユニバーサルになるようにゲームをアップグレードしています。私はcocos2d-iphoneバージョン1.0.1を使用しています。CCDirectorIOSクラスを拡張したので、iPhoneの解像度をiPadにスケーリングします(幅のみ、ストレッチなし)。ほぼ完璧に動作します。私は安定した60fpsを次のように取得します:
- 3GS iPhone / iPod、通常のテクスチャ、Retinaを搭載した4G iPod / iPhone
- テクスチャ。
ここに厄介な部分があります:
- iPad 1/2/3 / mini、iPhoneアプリ(ユニバーサルではない)、Retinaテクスチャ=安定した60 fps、
- iPad 1/2およびmini、アプリをユニバーサルに設定、Retinaテクスチャ= 20 fps、
- 通常のテクスチャでは60fps、iPad3ではRetinaテクスチャ=安定した60fpsです。
そのため、網膜テクスチャを備えた20fpsの低解像度iPadで動作します。私はそれを理解することはできません。
変更されたCCDirectorIOSクラスのソースは次のとおりです(変更のみ)。
//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;
}
//...
AppdelegateのapplicationDidFinishLaunchの最後に、次のものを追加しました。
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];
すべてをvirtualHeightとVirtualWidthに配置して、すべてが画面に表示されるようにします。