I'm trying to implement some basic OpenGL in my app, and in doing so, I used the GLPaint example included with the SDK as a jumping off point. My code works fine on its own, but once I move everything over to my app, the same code fails.
Depending on what I 开发者_运维百科try, the problem is either (1) the primitives appear squished when first drawn and then float to the top of the screen as subsequent primitives are drawn, or (2) the primitives don't appear at all.
I've narrowed it down to the fact that my app requires that the CAEAGLLayer be resized. It's in a UIScrollView and may be moved and resized at any time (pinching, dragging, etc.) As in the GLPaint example, I blow away the frame buffer and recreate it each time the view resizes (via layoutSubviews), but this doesn't work. (Since the GLPaint example never resizes, I suspect that this portion of the example code has never worked since it never needed to.)
Only if I set the CAEAGLLayer to a constant size of 1024 x 768, the code works as expected:
self.layer.frame = CGRectMake(0, 0, 1024, 768);
Once I change that line to:
self.layer.frame = self.bounds;
the problems return. The rest of my layoutSubviews method looks like this:
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
if (needsClearView) {
[self clearView];
needsClearView = NO;
}
The destroyFramebuffer and createFramebuffer methods are mostly unchanged from the GLPaint example. The only other code that references the view size are these lines in initWithCoder:
glOrthof(0, self.bounds.size.width, 0, self.bounds.size.height, -1, 1);
glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);
I've tried changing the values here, and moving these lines elsewhere, but nothing I've tried has worked. Anyone have any suggestions for me?
I had the same issue the other day and I figured it out. You do need to call glOrthof
and glViewport
with the new size before you recreate the frame buffer. I did it in the layoutSubviews
call:
-(void)layoutSubviews
{
[EAGLContext setCurrentContext:context];
glMatrixMode(GL_PROJECTION);
CGRect frame = self.bounds;
CGFloat scaleFactor = self.contentScaleFactor;
glLoadIdentity();
glOrthof(0, frame.size.width * scaleFactor, 0, frame.size.height * scaleFactor, -1, 1);
glViewport(0, 0, frame.size.width * scaleFactor, frame.size.height * scaleFactor);
glMatrixMode(GL_MODELVIEW);
[self destroyFramebuffer];
[self createFramebuffer];
// Clear the framebuffer the first time it is allocated
if (needsErase) {
[self erase];
needsErase = NO;
}
}
Make sure you call glLoadIdentity
first, as glOrthof
multiplies with the current matrix.
I had this same issue when using the PaintingView in a VC and changing its frame. Solved it by applying a CGAffineTransform on the view before changing the frame.
ie:
paintingView.transform = CGAffineTransformMakeScale(0.5, 0.5);
paintingView.frame = CGRectMake(paintingView.frame.origin.x, paintingView.frame.origin.y, paintingView.frame.size.width/2, paintingView.frame.size.height/2);
I've found that CAEAGLLayer is not happy unless its bounds.width
is a multiple of 8.
精彩评论