Very strange openGL window coordinates

I wrote a game many years ago, back in the days of iOS 3, using OpenGL ES 1. It remained functional up to iOS 8, but now broke because of one silly line, I didn't set a root view controller which is now required and causes the app to crash on startup. It's litterally a one line fix, but if I submit it like that, it will be rejected because it doesn't support the resolutions of new devices. So I need to update the graphics to the bare minimum to pass the app store requirements (even though the old game was just fine in the store up to now).


Now I've run into this weird problem that I've been trying to understand for days now: for some reason, the openGL coordinates are all wrong on the iPhone 6 simulator (I don't have an actual iPhone 6, just a 5).


I use "glOrthof(0, w, h, 0, 0, 10000.);" with w and h set to the display width and height respectively (375 and 667 on iPhone 6) yet when I draw something at a horizontal coordinate close to 320, it ends up at the very right of the screen. Anything at higher horizontal coordinates ends up off screen. Vertically it's even stranger: 0 seems to correspond to about one and a half physical pixel below the top of the screen. The bottom is around 571.


I first thought the zoom factor was 375/320, which might have made sense, but on close inspection it seems to be very slightly less than that value. If I draw a 100 pixel white square with that assumption (multiplying the coordinates with 320/375), I get a 100 pixel square where the leftmost and rightmost pixels are light gray. ,so it's very slightly smaller than 100 pixels. Also, the top and bottom are both about halfway in between pixels where I would have expected integer pixels.


Things get even stranger with glScissor: this is supposed to use "window coordinates" where 0 is the bottom of the view and, for a full screen view on iPhone 6, 1334 would be the top. In reality, the bottom is somewhere around 197 (?!) and the top is close to 1335. I just found those values by experimenting, calling glScissor and drawing a huge rectangle to see what part got drawn. Again, I thought there would be some nice fraction and offset (1334 corresponding to the top would have made some sort of sense) but no, it's close but not quite those values. For some reason the very top line always remains black even with glScissor off.


I'm completely at a loss here, I have no idea what's going on. Coordinates are just fine on iPhone 4 and 5 (and were always fine on iPhone 3 and earlier, too).


The view covers the whole screen (bounds 0, 0, 375, 667), the openGL backing buffer is 750 x 1334, the view contentscalefactor is set to that of the screen (2.0), everything seems to be as it should be. And glScissor is so basic, taking window coordinates, so none of the transformation matrices should have any effect on that. Display zoom does not seem to be on.


For setting up the openGL, I used sample code (back in the days of iOS 3) which does the following:


+ (Class)layerClass {return [CAEAGLLayer class];


Inside initWithFrame:

CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;


eaglLayer.opaque = true;

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:true], kEAGLDrawablePropertyRetainedBacking,

kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

And creating the back buffer with:

glGenFramebuffersOES(1, &viewFramebuffer);

glGenRenderbuffersOES(1, &viewRenderbuffer);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];

glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

glGenRenderbuffersOES(1, &depthBuffer);

glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthBuffer);

glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT24_OES, backingWidth, backingHeight);

glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthBuffer);

glViewport(0, 0, backingWidth, backingHeight);

printf("%f / %d\n", self.bounds.size.width, backingWidth);


The last printf command outputs 375 / 750 which confirms that the dimensions match (screen scale factor 2). There's certainly no scale factor anywhere near 320/375.


Does anyone have any ideas what might be going on here? And how I can fix this with minimum effort (i.e. not rewriting the entire engine for OpenGL 2 or something like that, I don't even know how to write a shader and I have other projects to work on).


Thanks!


Michel

This probably isn't it, but have you confirmed that the final view frame is what you expect? e.g. 0,0,w,h? I've had things like this happen and spent a long time looking deep in the GL code only to wind up finding out some auto layout thing shifted/expanded my view bounds.

OK, I've finally figured it out. I was not aware that the app actually started in magnified mode because the correct startup image (or xib) was missing. The reason this was not immediately clear, was that I was getting the screen dimensions from [UIScreen mainScreen] which did give 375 x 667 even though the app was running in a magnified 320 x 568 window. Somewhere in my initialisation code, I was setting the window and view bounds to the screen dimensions. So when I looked at their bounds and frames, everything looked native even though in reality I had a magnified window that was only partially on screen.


Adding the launch screen xib should fix this rather easily.


Thanks, mach9!


Michel

Very strange openGL window coordinates
 
 
Q