4

我正在尝试使用 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);

        /// . . .

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

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

- (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 来跳过这些设置?

4

2 回答 2

1

问题是该层在初始化时没有尺寸。这反过来又使得尝试将渲染缓冲区存储设置为层意味着缓冲区为 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);
}
于 2013-08-12T18:20:47.953 回答
0

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

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

您还必须在 MYCEAGLLayer 上设置 drawableProperties。

于 2013-08-12T17:31:31.650 回答