当我调整CAEAGLLayer的大小时,OpenGL绘图搞砸了

时间:2011-08-31 17:27:59

标签: iphone ios ipad opengl-es calayer

我正在尝试在我的应用程序中实现一些基本的OpenGL,并且在这样做时,我使用SDK附带的GLPaint示例作为跳出点。我的代码本身可以正常工作,但是一旦我将所有内容移到我的应用程序中,相同的代码就会失败。

根据我的尝试,问题是(1)基元在第一次绘制时出现压扁,然后在绘制后续基元时浮动到屏幕顶部,或者(2)基本体根本不出现

我已将其缩小到我的应用程序要求调整CAEAGLLayer大小的事实。它位于UIScrollView中,可以随时移动和调整大小(捏合,拖动等)。如在GLPaint示例中,每次视图调整大小时(通过layoutSubviews),我都会移除帧缓冲区并重新创建它,但这并不是'工作。 (由于GLPaint示例从不调整大小,我怀疑示例代码的这一部分从未工作过,因为它从未需要。)

仅当我将CAEAGLLayer设置为1024 x 768的常量大小时,代码才能按预期工作:

self.layer.frame = CGRectMake(0, 0, 1024, 768);

我将该行更改为:

self.layer.frame = self.bounds;

问题又回来了。我的layoutSubviews方法的其余部分如下所示:

[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];

if (needsClearView) {
    [self clearView];
    needsClearView = NO;
}

destroyFramebuffer和createFramebuffer方法与GLPaint示例大部分没有变化。引用视图大小的唯一其他代码是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);

我已经尝试过更改这里的值,并将这些行移到别处,但我尝试过的任何内容都没有效果。有人对我有什么建议吗?

3 个答案:

答案 0 :(得分:4)

前几天我遇到了同样的问题,我想出来了。在重新创建帧缓冲区之前,您需要使用新大小调用glOrthofglViewport。我是在layoutSubviews电话中做到的:

-(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;
    }
}

请务必先致电glLoadIdentityglOrthof与当前矩阵相乘。

答案 1 :(得分:1)

我发现CAEAGLLayer不满意,除非bounds.width是8的倍数。

答案 2 :(得分:1)

在VC中使用PaintingView并更改其框架时,我遇到了同样的问题。通过在更改框架之前在视图上应用CGAffineTransform来解决此问题。

即:

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);