How to custom init an EAGLView? - ios

In my iOS project, glView ends up with height=0 and width=0 even though CGRect frame correctly gets the screen's dimensions in the previous line.
- (void) applicationDidFinishLaunching:(UIApplication*)application {
CGRect frame = [[UIScreen mainScreen] bounds];
EAGLView *glView = [EAGLView viewWithFrame:frame
pixelFormat:kEAGLColorFormatRGB565
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0
];
}
Is there some other way I need to create my EAGLView *glView in order for it to be init'ed properly?

You will have to add the glView to a UIWindow. Check out the app delegate code in the Cocos2D project templates.

Related

Objective - C, what does [UIScreen mainScreen].bounds.size.width actually give and what does initWithSize: actually require?

I am writing a GUI, with a main menu, a second screen and a back button to the main menu. From the initial main menu I use the following lines of code:
midScreenX = [UIScreen mainScreen].bounds.size.width/2;
midScreenY = [UIScreen mainScreen].bounds.size.height/2;
WarScene *battle = [[WarScene alloc] initWithSize: CGSizeMake(midScreenX*2, midScreenY*2)];
SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
SKView * skView = (SKView *)self.view;
UIView *viewToRemove = [self.view viewWithTag:101];
[viewToRemove removeFromSuperview];
[skView presentScene:battle transition:reveal];
This works... I think. I open up a new scene, my second scene is the correct size and at least fills the screen. There is a node in that scene which is too big for the screen, and I am working on changing that, but I don't think that that would actually effect the UIScreen's bounds.
The problem arises when I return to the main menu with the following code:
midScreenX = [UIScreen mainScreen].bounds.size.width/2;
midScreenY = [UIScreen mainScreen].bounds.size.height/2;
GameScene *map = [[GameScene alloc] initWithSize: CGSizeMake(midScreenX*2 ,midScreenY*2)];
SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
SKView * skView = (SKView *)self.view;
UIView *viewToRemove = [self.view viewWithTag:3];
[viewToRemove removeFromSuperview];
[skView presentScene:map transition:reveal];
As far as I can work out, the values being passed through should be exactly the same as the values initially sent for [UIScreen mainScreen].bounds.size and yet the scene which is initialised is far too big.
Is there anything that I could be doing which might affect [UIScreen mainScreen].bounds.size? Or have I misunderstood what init and .bounds actually do?
In terms of what I have already done to try and solve this problem myself, I have looked at examples of how scenes are normally initialised. I see that often values are used in place of .bounds for example :
initWithSize: CGSizeMake(1024,768)
However, wouldn't that mean that on different devices the scene wouldn't be shown properly/fully?
if you are using iOS 6 or iOS 7,
both [UIScreen mainScreen].bounds.size.width and [UIScreen mainScreen].bounds.size.height is same in all orientation..
but in iOS 8 it give one value in landscape and give another value in portrait mode
NSLog(#"width %f",[[UIScreen mainScreen] bounds].size.width); //portrait ios7 or 6 = 320 , landscape ios7 or 6 = 320
NSLog(#"height %f",[[UIScreen mainScreen] bounds].size.height); //portrait ios7 or 6 = 568 , landscape ios7 or 6 = 568
NSLog(#"width %f",[[UIScreen mainScreen] bounds].size.width); //portrait ios8 = 320 , landscape ios8 = 568
NSLog(#"height %f",[[UIScreen mainScreen] bounds].size.height); //portrait ios8 = 568 , landscape ios8 = 320
so we can check conditions like this,
CGFloat midScreenX,midScreenY;
if (UIDeviceOrientationIsLandscape((UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]))
{
//landscape mode
midScreenX = ([[UIScreen mainScreen]bounds].size.width>[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
midScreenY = ([[UIScreen mainScreen]bounds].size.width<[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
}
else
{
//portrait mode
midScreenX = [[UIScreen mainScreen]bounds].size.width/2;
midScreenY = [[UIScreen mainScreen]bounds].size.height/2;
}
I hope you warScene and gameScene are subclass of SKScene. The method initWithSize returns, A newly initialized scene object. and parameter 'size' is The size of the scene in points.
For more information refer https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKScene_Ref/index.html#//apple_ref/occ/instm/SKScene/initWithSize:

IOS Landscape Mode not working OPEN GL

Ok tried almost everything and it didn't work.
I need my engine to start up in LandscapeRight mode, therefore i call:
//
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
The problem is that the rest is not rotated at all,
I managed to rotate the view by using:
[pExternViewController setTransform:CGAffineTransformMakeRotation(M_PI/2.0f)];
But it doesn't work as expected, the Frame Buffer size is correct now:
FrameBuffer: width: 960, height: 640
Still you can see it is not 960x640, and i can't figure out why?
Ok, finally made it.
First add this key to your plist file (required)
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
Screen Size definitions
#define SCREEN_WIDTH (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)
#define IOS_VERSION_LOWER_THAN_8 (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
The window initialization
- (void) applicationDidFinishLaunching: (UIApplication*) application
{
// Start in Landscape
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
// Disable Auto Lock screen
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
// Set Bounds with the proper screen resolution
CGRect screenBounds = [[UIScreen mainScreen] bounds];
screenBounds = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Create window and view controler
m_window = [[UIWindow alloc] initWithFrame: screenBounds];
m_window.backgroundColor = [UIColor redColor];
// Create new view controller
pExternViewController = [SvgzViewController alloc] ;
// Initialize view controler with all pointers set up
if( [pExternViewController initWithFrame: screenBounds ] == nil)
{
assert(!"Failed to initialize screen");
exit(0);
}
// Rotate the window
[m_window setTransform:CGAffineTransformMakeRotation(M_PI/2.0f)];
// Set the proper window center after transformation
m_window.center = CGPointMake(screenBounds.size.height/2, screenBounds.size.width/2);
// Add GL window
[m_window addSubview: pExternViewController];
//
[m_window makeKeyAndVisible];
}
At least no GL side change has to be done by doing it this way.

GlView causes OpenGL error

I am new in cocos2d.I am making a gaming with uiview with cocos2d(3.0 Beta) platform.I set a GLView in custom viewcontroller. Below is my code.
- (void)setupCocos2D {
CCGLView *glView = [CCGLView viewWithFrame:self.view.bounds pixelFormat:kEAGLColorFormatRGB565 depthFormat:0];**
glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view insertSubview:glView atIndex:0];
[[CCDirector sharedDirector] setView:glView];**
}
It's working fine.But when we put on object then give me Following Memory worning.
OpenGL error 0x0506 in -[CCSprite draw] 544
OpenGL error 0x0502 in -[CCGLView swapBuffers] 287**
I think when we call ([[CCDirector sharedDirector] setView:glView]) setView method it's not find CCDirector method but UIView method.I can't Access the CCDirector method.Same Method I also can't call in AppDelegate class.
- (void)applicationWillTerminate:(UIApplication *)application {
CCDirector *director = [CCDirector sharedDirector];
//openGLView is now (setView in Latest version).It's Can't Access here.**
[[director openGLView] removeFromSuperview];
[director end];
}
You use below Code in setupCocos2D
- (void)setupCocos2D
{
[[CCDirector sharedDirector] end];
UIWindow *window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window_ setBackgroundColor:[UIColor whiteColor]];
CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGB565
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// Display FSP and SPF
[director_ setDisplayStats:NO];
// set FPS at 60
[director_ setAnimationInterval:1.0/60];
// attach the openglView to the director
[director_ setView:glView];
// 2D projection
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director_ enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change this setting at any time.
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO]; // Default: NO. No fallback suffixes are going to be used
[sharedFileUtils setiPhoneRetinaDisplaySuffix:#"-hd"]; // Default on iPhone RetinaDisplay is "-hd"
[sharedFileUtils setiPadSuffix:#"-ipad"]; // Default on iPad is "ipad"
[sharedFileUtils setiPadRetinaDisplaySuffix:#"-ipadhd"]; // Default on iPad RetinaDisplay is "-ipadhd"
// Assume that PVR images have premultiplied alpha
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
}

OpenGL error 0x0506 in DrawSegment 190

I created an Xcode Project, where I use cocos2d as a static library (I don't use the template).
To incorporate cocos2d in my storyboard, I followed the tutorial here: cocos2d & storyboards
As a result I setup CCDirector by using the CCViewController class described in the tutorial.
Everything works fine, except every now and then the console spits out a number of OpenGL errors like:
OpenGL error 0x0506 in DrawSegment 190
My CCGLView is created like this in viewDidLoad:
CGRect rect = self.view.frame;
CGFloat width;
CGFloat height;
if (rect.size.width > rect.size.height)
{
width = rect.size.width;
height = rect.size.height;
}
else
{
width = rect.size.height;
height = rect.size.width;
}
CCGLView *glView = [CCGLView viewWithFrame:CGRectMake(0, 0, width, height)
pixelFormat:kEAGLColorFormatRGB565
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
What are these OpenGL errors, and how can I fix them? If I use the template I don't have these problems.

CCSprite does not display on iPad+Retina

I have another weird problem which I have not been able to solve in reasonable time. My app works well on iPhone 4S and iPod 4-th with and without retina enabled. It also works well on iPad3 without retina. But when iPad has retina enabled, CCSprites just do not appear. I do have camera image underlay which is shown but not graphics on top of it. I think I have all "-hd" versions of files available and they are also shown well on iPhone in retina mode.
I paste code which I think is related:
- (void) applicationDidFinishLaunching:(UIApplication*)applicationv{
CCLOG(#"applicationDidFinishLaunching");
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
[CCDirector setDirectorType:kCCDirectorTypeDefault];
CCDirector *director = [CCDirector sharedDirector];
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
viewController.wantsFullScreenLayout = YES;
EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
// attach the openglView to the director
[director setOpenGLView:glView];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeRight];
#endif
[director setAnimationInterval:1.0/20];
[director setDisplayFPS:NO];
[viewController setView:glView];
[window addSubview: viewController.view];
[CCDirector sharedDirector].openGLView.backgroundColor = [UIColor clearColor];
[CCDirector sharedDirector].openGLView.opaque = NO;
glClearColor(0.0, 0.0, 0.0, 0.0);
_cameraView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_cameraView.opaque = NO;
_cameraView.backgroundColor=[UIColor clearColor];
[window addSubview:_cameraView];
_imageView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[_cameraView addSubview:_imageView];
[window bringSubviewToFront:viewController.view];
[window makeKeyAndVisible];
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
CCScene *scene = [CCScene node];
_layer =[[[HelloWorldLayer alloc] init] autorelease];
_menu =[MenuScene node];
[scene addChild:_layer];
[_layer addChild:_menu];
viewController.fdLayer = _layer;
_layer.root = viewController;
[[CCDirector sharedDirector] runWithScene: scene];
And MenuScene.m:
#implementation MenuScene
+(id) scene {
CCScene* scene = [CCScene node];
CCLayer* layer = [MenuScene node];
[scene addChild:layer];
return scene;
}
-(id) init {
if ((self = [super init])) {
CCLOG(#"init %#", self);
CGSize screen = [[CCDirector sharedDirector] winSize];
CCLOG(#"%f %f",screen.width,screen.height);
CCLayerColor *b = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 100) width:screen.width height:screen.height/4];
b.isRelativeAnchorPoint=YES;
b.anchorPoint=ccp(0, 1); // left top corner
b.position=ccp(0, screen.height);
[self addChild:b];
CCSprite* bg = [CCSprite spriteWithFile:#"01-main-logo.png"];
bg.position = CGPointMake(screen.width / 2, screen.height*0.12);
[b addChild:bg];
EDIT: I made temporary hack:
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
}
but question remains - why?
Problem solved. "Make Clean" was not enough. Keeping "Option" button down when pressing "Clean" forces even more to be cleaned up. After that things started to work. There is also possibility that it was related to "Compress PNG files" setting which I changed to "No" after problems started but it was maybe not enforced. Anyway problem gone away and thanks for watching :)

Resources