Reputation: 740
I'm finally upgrading a very old universal game app I have to play nice with newer OSs and device sizes - I've got everything updated and targeting iOS 6.1 right now but when I run it on the iPhone 5, my actual in game view, which is rendered using open GL into an EAGLView, is positioned very strangely and shows a lot of clipping (see screenshot).
On the "normal" devices that were around when we first created this, everything appears as expected.
In my view controller, I basically load a nib with the right size set for the different devices - iPad and non 4" devices get a 1024x768 view and the 4" device gets a new 1136x640 view.
Then, in my viewDidLoad
, I set up my view's self.view.contentScaleFactor
to [UIScreen mainsScreen] scale]
, I then do some view sizing like so (roughly):
if(iPad){
[self.view setFrame:CGRectMake(0, 0,1024,768)];
[self.view setCenter:CGPointMake(384,512)];
DefaultViewScale=1.2;
}else if(WideScreen){
[self.view setFrame:CGRectMake(0, 0, 568, 320)];
[self.view setCenter:CGPointMake(160, 293)];
DefaultViewScale = 1.0f;
}else{
[self.view setFrame:CGRectMake(0, 0,480,320)];
[self.view setCenter:CGPointMake(160,240)];
DefaultViewScale=1.0f;;
}
Lastly, I apply a transform to scale the view by a factor defined above which I've just hand tweaked and then rotated it since the app is Landscape-Left only.
[self.view
setTransform:
CGAffineTransformConcat(CGAffineTransformMakeScale(DefaultViewScale,DefaultViewScale),
CGAffineTransformMakeRotation(-M_PI_2))];
I then initialize a new EAGLContext (openGL ES 1),
[(EAGLView *)self.view setContext:context];
[(EAGLView *)self.view setFramebuffer];
setFramebuffer is mostly:
[EAGLContext setCurrentContext:context];
// Create default framebuffer object.
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glViewport(0, 0, framebufferWidth, framebufferHeight);
There's some more boilerplate EAGLView code but note that I'm setting the glViewport to whatever gl tells me it's width and height is which is grabbed from the UIView's layer size.
And finally it sets up the projection matrix:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, self.view.frame.size.width , 0, self.view.frame.size.height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND_SRC);
glEnableClientState(GL_VERTEX_ARRAY);
glDisable(GL_DEPTH_TEST);
// Set the colour to use when clearing the screen with glClear
glClearColor(51.0/255.0,135.0/255.0,21.0/255.0, 1.0f);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
This is not my strongest area of knowledge, so let me know if I've missed something and I can get you more info if needed. If anyone has an "a ha" or a similar experience, I'd appreciate some tips in the right direction.
Thanks
Upvotes: 1
Views: 587
Reputation: 46
I suggest ensuring that your launch images are up-to-date.
OpenGL is definitely not my area of expertise, but I had a similar issue when upgrading a flash game to iOS 6. I did not supply appropriate launch images for the retina displays of the new iPhone etc, and my app was run in 'compatibility mode' with margins at the top and bottom of the screen. Admittedly, you don't quite have these margins, but it's possible that it's messing with how big your app thinks its screen is. Might be worth checking out.
Upvotes: 1
Reputation: 32497
Short answer, start using GLKView
instead of EAGLView
.
First, a good way of getting to know the best practice for setting up e.g. an OpenGL context in the most recent version of iOS is to create a new project using the "OpenGL Game" template and look at for reference.
The most significant difference is the GLKView
(introduced in iOS 5.0), which greatly simplifies things for you. It will take care of most of the things you now do manually, including setting up the viewport.
EAGLView
with the GLKView
(make sure to reference GLKit.framework
in your project).setFramebuffer
method. GLKit takes care of this for you.[self.view setTransform:]
call. If your app is full-screen OpenGL, there is no need to use view transforms. (And it not, it is likely that it is still not needed).[context setCurrentContext]
in your viewDidLoad
somewhere.context
property of the GLKView
to the OpenGL context, just as for the EAGLView
.Upvotes: 2
Reputation: 1727
It looks like the transformation you're doing is after setting the frame of the view, and may therefor change the bounds. I would suggest breaking in your draw method and checking the bounds of both the view and its layer.
Remember that the frame is set from the perspective of the parent, while the bounds is in local coordinates. From UIView.h:
do not use frame if view is transformed since it will not correctly reflect the actual location of the view. use bounds + center instead.
Upvotes: 0
Reputation: 2577
Why is your "DefaultViewScale=1.2" on an iPad? If the app is fullscreen, it shouldn't be scaled anymore since it's 1024x768. Are you rescaling something there?
In my OpenGL Apps I just have a EAGLView that is always fullscreen and then read the sizes from the framebufferWidth/height.
If you have a UIViewController, with the HUD-Elements correctly set up, you wouldn't need to do any [self.view setTransform..]. I have the feeling you're making life more complicated for yourself, then it should be!
Just add the EAGLView with "UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth" as the lowest subview of your ViewControllers main view. And set up the rotation code correctly (keep in mind the iOS5 calls so shouldAutoRotateToInterfaceOrientation:.. are deprecated).
Upvotes: 0