0

在我正在开发的 OpenGL ES 应用程序中,当我使用 glReadPixels 获取像素但缓冲区为空时。现在我不知道我的代码有什么问题。感谢您的帮助。

- (void)setTextureImage:(UIImage *)image {
    self.textureID = [self createTextureWithImage:image];

    CAEAGLLayer *layer = [[CAEAGLLayer alloc] init];
    layer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    layer.contentsScale = [[UIScreen mainScreen] scale]; 
    layer.opaque = NO;
    [self.layer addSublayer:layer];
    [self bindRenderLayer:layer];
}

- (void)bindRenderLayer:(CALayer <EAGLDrawable> *)layer {
    
    glGenRenderbuffers(1, &renderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
    [self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];

    glGenFramebuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER,
                              renderBuffer);
}

- (GLint)drawableWidth {
    GLint backingWidth;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
    return backingWidth;
}

- (GLint)drawableHeight {
    GLint backingHeight;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
    return backingHeight;
}

上面的示例代码只是显示纹理的一部分,它工作正常。renderBuffer 和 framebuffer 是我班级的财产。示例在这里获取像素代码,使用 glReadPixels 后缓冲区为空?有什么我错过的设置吗?

    glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
    // I'm try to use one or both of the bind method but not worked
    //glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    NSInteger dataLength = self.drawableWidth * self.drawableHeight * 4;
    GLubyte *buffer = (GLubyte *)malloc(dataLength * sizeof(GLubyte));
    glReadPixels(0,
                 0,
                 self.drawableWidth,
                 self.drawableHeight,
                 GL_RGBA,
                 GL_UNSIGNED_BYTE,
                 buffer);

4

1 回答 1

1

我找到了解决方案。当您像这样设置 CAEAGLLayer 的 drawableProperties 时:

    layer.drawableProperties = @{
        kEAGLDrawablePropertyRetainedBacking: @(YES),
        kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
    };

kEAGLDrawablePropertyRetainedBacking = YES使您可以在完成渲染时获得缓冲区。

于 2021-12-12T13:06:39.347 回答