glResolveMultisampleFramebufferAPPLE()在iOS上生成GL_INVALID_OPERATION(OpenGL ES 2.0)

时间:2016-01-26 14:52:04

标签: opengl-es opengl-es-2.0 glreadpixels multisampling

我想使用函数glReadPixels()来截取我的场景。如果我不使用多重采样,它的效果很好。但如果我这样做,我会在GL_INVALID_OPERATION中获得glResolveMultisampleFramebufferAPPLE()。有没有办法解决这个问题?

我的保存功能:

    var wid = GLint()
    var hei = GLint()
    glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_WIDTH), &wid)
    glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_HEIGHT), &hei)
    let byteLength = Int(hei * wid) * 4
    let bytes = UnsafeMutablePointer<GLubyte>.alloc(byteLength)

    // init non-multisampled frame buffer
    var framebuffer: GLuint = 0
    var colorRenderbuffer: GLuint = 0

    glGenFramebuffersOES(1, &framebuffer)
    glBindFramebufferOES(GLenum(GL_FRAMEBUFFER_OES), framebuffer)

    glGenRenderbuffersOES(1, &colorRenderbuffer)
    glBindRenderbufferOES(GLenum(GL_RENDERBUFFER_OES), colorRenderbuffer)
    glRenderbufferStorageOES(GLenum(GL_RENDERBUFFER_OES), GLenum(GL_RGBA8_OES), wid, hei)
    glFramebufferRenderbufferOES(GLenum(GL_FRAMEBUFFER_OES), GLenum(GL_COLOR_ATTACHMENT0_OES), GLenum(GL_RENDERBUFFER_OES), colorRenderbuffer)

    glBindFramebufferOES(GLenum(GL_DRAW_FRAMEBUFFER_APPLE), framebuffer)

    var default: GLint = 0
    glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING_OES), &default)
    glBindFramebufferOES(GLenum(GL_READ_FRAMEBUFFER_APPLE), GLuint(default));

    myglGetError() // OK
    glResolveMultisampleFramebufferAPPLE()
    myglGetError() // GL_INVALID_OPERATION

    glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer)

    glReadPixels(0, 0, GLsizei(wid), GLsizei(hei), GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), bytes)

    glBindFramebuffer(GLenum(GL_FRAMEBUFFER), GLuint(default));
    glDeleteFramebuffers(1, &framebuffer)

我使用GLKit初始化的默认帧缓冲区glkView.drawableMultisample = GLKViewDrawableMultisample.Multisample4X

1 个答案:

答案 0 :(得分:1)

我已经尝试了你的样本,似乎经过一些修改后它才有效。 修改后的代码:

        var wid = GLint()
    var hei = GLint()
    glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_WIDTH), &wid)
    glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_HEIGHT), &hei)
    var def: GLint = 0
    glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING_OES), &def)

    // init non-multisampled frame buffer
    var framebuffer: GLuint = 0
    var colorRenderbuffer: GLuint = 0

    glGenFramebuffersOES(1, &framebuffer)
    glBindFramebufferOES(GLenum(GL_FRAMEBUFFER_OES), framebuffer)

    glGenRenderbuffersOES(1, &colorRenderbuffer)
    glBindRenderbufferOES(GLenum(GL_RENDERBUFFER_OES), colorRenderbuffer)
    glRenderbufferStorageOES(GLenum(GL_RENDERBUFFER_OES), GLenum(GL_RGBA8_OES), wid, hei)
    glFramebufferRenderbufferOES(GLenum(GL_FRAMEBUFFER_OES), GLenum(GL_COLOR_ATTACHMENT0_OES), GLenum(GL_RENDERBUFFER_OES), colorRenderbuffer)

    glBindFramebufferOES(GLenum(GL_DRAW_FRAMEBUFFER_APPLE), framebuffer)

    //commented
    //here GL_FRAMEBUFFER_BINDING_OES will be overrided by previous call of
    // 'glBindRenderbufferOES(GLenum(GL_RENDERBUFFER_OES), colorRenderbuffer)'
    //var def: GLint = 0
    //glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING_OES), &def
    glBindFramebufferOES(GLenum(GL_READ_FRAMEBUFFER_APPLE), GLuint(def));

    var err = glGetError()
    print(String(format: "Error %X",  err))
    glResolveMultisampleFramebufferAPPLE()
    err = glGetError()
    print(String(format: "Error %X",  err)) // GL_INVALID_OPERATION

    glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer)

此处引用APPLE_framebuffer_multisample.txt扩展说明,解释了为什么修改后的代码可以解释。

  

呼叫       设置为FRAMEBUFFER的BindFramebuffer绑定       framebuffer同时为DRAW_FRAMEBUFFER_APPLE和READ_FRAMEBUFFER_APPLE。

APPLE_framebuffer_multisample