繁体   English   中英

如何使用openGL上下文设置CAEAGLLayer子类:当前绘制帧缓冲区无效

[英]how to set up CAEAGLLayer subclass with openGL context: Current draw framebuffer is invalid

我正在尝试使用gl上下文设置CAEAGLLayer子类。 也就是说,不是创建一个返回CAEAGLLayer并从UIView子类中将gl上下文绑定到该层的UIView子类,而是直接对该层进行子类化并尝试在图层的init中设置上下文,如下所示:

- (id)init
{
    self = [super init];
    if (self) {
        self.opaque = YES;

        _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        NSAssert([EAGLContext setCurrentContext:_glContext], @"");

        glGenRenderbuffers(1, &_colorRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
        [_glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:self];

        glGenFramebuffers(1, &_framebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);

        /// . . .

到目前为止,一切似乎都很好。 但是,然后我尝试创建一个带有“pass-thru”顶点/片段着色器对的着色器程序,并且在链接程序时没有返回任何错误,验证失败说:“当前绘制帧缓冲区无效。”

链接和验证着色器程序的代码(在附加着色器之后)看起来像这样,以防万一:

- (BOOL)linkAndValidateProgram
{
    GLint status;
    glLinkProgram(_shaderProgram);

#ifdef DEBUG
    GLint infoLogLength;
    GLchar *infoLog = NULL;
    glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength);
    if (infoLogLength > 0) {
        infoLog = (GLchar *)malloc(infoLogLength);
        glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog);
        NSLog(@"Program link log:\n%s", infoLog);
        free(infoLog);
    }
#endif

    glGetProgramiv(_shaderProgram, GL_LINK_STATUS, &status);
    if (!status) {
        return NO;
    }

    glValidateProgram(_shaderProgram);

#ifdef DEBUG
    glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength);
    if (infoLogLength > 0) {
        infoLog = (GLchar *)malloc(infoLogLength);
        glGetProgramInfoLog(_shaderProgram, infoLogLength, &infoLogLength, infoLog);
        NSLog(@"Program validation log:\n%s", infoLog);
        free(infoLog);
    }
#endif

    glGetProgramiv(_shaderProgram, GL_VALIDATE_STATUS, &status);
    if (!status) {
        return NO;
    }

    glUseProgram(_shaderProgram);
    return YES;
}

我想知道在整个CAEAGLLayer生命周期的某个时刻是否可能有一些额外的设置,我可能不知道并且可能会尝试在init中设置GL而跳过?

问题是在init中该层没有维度。 这反过来使得它尝试将渲染缓冲区存储设置到层意味着缓冲区为0。

更新:我目前最好的想法是,不是在init上强加一个大小(为了测试的目的而工作得很好但是很好的hacky),我应该在层改变大小时重新设置缓冲存储。 所以我重写-setBounds:像这样:

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];
    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:self];
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &someVariableToHoldWidthIfYouNeedIt);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &someVariableToHoldHeightIfYouNeedIt);
}

据我所知,你必须覆盖View中的layerClass方法,就像这样

    + (Class)layerClass
    {
       return [MYCEAGLLayer class];
    }

您还必须在MYCEAGLLayer上设置drawableProperties。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM