为OpenGL ES设置CAEAGLLayer属性?

时间:2012-01-28 16:55:11

标签: ios opengl-es

使用帧缓冲对象在iOS上进行渲染,根据Apple的OpenGL ES编程指南,这似乎是苹果在iOS上渲染的首选方式,应该使用glRenderbufferStorage()来指定宽度和高度等属性根据Munshi,Ginsburg和Shreiner的OpenGL ES 2.0编程指南。 Apple将此替换为renderbufferStorage:fromDrawable:上面指南中发送给EAGLContext的消息。

然后,Apple继续写入以从Renderbuffer获取宽度和高度,因为该缓冲区在创建它们时没有进一步细节。

宽度和高度为0。

CAEAGLLayer类参考写入“设置图层边界以匹配显示的尺寸”。 CAEAGLLayer类是Apple希望用作视图的后备类的类。这是通过从视图layerClass方法返回它来完成的。此CAEAGLLayer只有一个属性“drawableProperties”,它是一个NSDictionary。不幸的是,文档很少。尺寸无法设定。

因此:如何为OpenGL ES设置CAEAGLLayer属性?

这是我到目前为止的代码(请注意,Apple的一个老例子使用了initWithCoder,我猜不到或者从某个地方得到了我不记得使用initWithFrame):

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code
        theCAEAGLLayer = (CAEAGLLayer*)self.layer;
        theCAEAGLLayer.opaque = YES;
        theEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        [EAGLContext setCurrentContext:theEAGLContext];
        glGenFramebuffers(1, &theFramebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, theFramebuffer);
        glGenRenderbuffers(1, &theColorRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, theColorRenderbuffer);
        [theEAGLContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:theCAEAGLLayer];
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, theColorRenderbuffer);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &widthOfTheColorRenderbuffer);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &heightOfTheColorRenderbuffer);
        glGenRenderbuffers(1, &theDepthRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, theDepthRenderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, widthOfTheColorRenderbuffer, heightOfTheColorRenderbuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, theDepthRenderbuffer);
        if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        {

        }
    }
    return self;
}

1 个答案:

答案 0 :(得分:1)

正确答案:

UIKit将某些操作批处理并将它们推迟到runloop的后期。那是因为您可能有代码更改视图的大小并更改其中的不同文本位。你可能希望这些东西以原子方式发生。

这对您来说意味着该图层尚未调整大小。您是否尝试将所拥有的内容移至- (void)layoutSubviews

如果您计划仅定位iOS 5,则可以使用GLKView并避免为自己编写任何此类内容。

其他评论:

glRenderbufferStorage会在OpenGL可以绘制的不透明位置创建存储,但操作系统应该如何猜测哪个帧缓冲区是您要向用户显示的那个,而不仅仅是中间结果? OpenGL规范明确没有定义如何与特定操作系统进行通信。在iOS中,它是通过renderbufferStorage:fromDrawable:实现的 - 它表示添加的存储等同于iOS知道如何合成的CALayer。 Apple的方法不是glRenderbufferStorage的替代品,它会做glRenderbufferStorage不能也不应该做的事情,而且即使仅针对iOS编程,也会有很多次使用它。

- (id)initWithFrame:是您手动创建视图时使用的初始化工具。系统使用- (id)initWithCoder:从NIB加载视图。

您的UIView是否明确指定其layerClassCAEAGLLayer?如果没有,则允许对您的EAGL上下文的调用失败。