0

I want to use function glReadPixels() to do screenshot of my scene. And it works great if I don't use multisampling. But if I do I get GL_INVALID_OPERATION in glResolveMultisampleFramebufferAPPLE(). Is there a way to resolve this problem?

My save function:

    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)

I use default frame buffer initialized by GLKit with glkView.drawableMultisample = GLKViewDrawableMultisample.Multisample4X

2
  • Shouldnt "GL_FRAMEBUFFER_BINDING_OES" be "READ_FRAMEBUFFER_BINDING_APPLE" ? Commented Jan 26, 2016 at 15:36
  • @prabindh, thank you for the answer! But there is an error: Use of unresolved identifier 'GL_FRAMEBUFFER_BINDIND_APPLE' Commented Jan 26, 2016 at 16:50

1 Answer 1

1

I have tried your sample and it seems that after some modifications it works. Modificated code:

        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)

Also here is quote from APPLE_framebuffer_multisample.txt extension description which explains why modified code works, as far as I understand.

Calling BindFramebuffer with set to FRAMEBUFFER binds the framebuffer to both DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE.

APPLE_framebuffer_multisample

Sign up to request clarification or add additional context in comments.

3 Comments

Rolan, thank you for the answer, but it's really possible, because of default frame buffer installed by GLKView
Which OpenGL ES version you are using? Because if ES 3.0 is used glBlitFramebuffer should be used instead of glRenderbufferStorageMultisampleAPPLE.
I use OpenGL ES 2.0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.