首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用CAEAGLLayer上下文设置openGL子类:当前绘制框架缓冲区无效

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

Stack Overflow用户
提问于 2013-08-08 20:42:03
回答 2查看 3K关注 0票数 4

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

代码语言:javascript
复制
- (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”顶点/片段着色器对和的着色器程序,同时链接该程序时不会返回错误,验证失败时会说:“当前绘制框架缓冲区无效。”

链接和验证着色器程序(附加着色器后)的代码如下所示,以防万一:

代码语言:javascript
复制
- (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而跳过?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-12 18:20:47

问题是该层在init中没有维度。这反过来又使得试图将呈现缓冲区存储设置为该层意味着缓冲区为0。

UPDATE:我目前的最佳想法是,与其对init施加大小(这对于测试来说很好,但很麻烦),我应该只是在层大小改变时重新设置缓冲区存储。因此,我要像这样覆盖-setBounds:

代码语言:javascript
复制
- (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);
}
票数 1
EN

Stack Overflow用户

发布于 2013-08-12 17:31:31

据我所知,您必须覆盖视图中的layerClass方法,如下所示

代码语言:javascript
复制
    + (Class)layerClass
    {
       return [MYCEAGLLayer class];
    }

此外,您还必须在drawableProperties上设置MYCEAGLLayer。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18135736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档