2016-01-26 8 views
0

Я хочу использовать функцию glReadPixels(), чтобы сделать снимок экрана моей сцены. И он отлично работает, если я не использую мультисэмплинг. Но если я получу GL_INVALID_OPERATION в glResolveMultisampleFramebufferAPPLE(). Есть ли способ решить эту проблему?glResolveMultisampleFramebufferAPPLE() генерировать GL_INVALID_OPERATION на iOS (OpenGL ES 2.0)

Моя функция сохранения:

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

+0

"GL_FRAMEBUFFER_BINDING_OES не должен" быть "READ_FRAMEBUFFER_BINDING_APPLE"? – prabindh

+0

@prabindh, спасибо за ответ! Но есть ошибка: «Использование неразрешенного идентификатора» GL_FRAMEBUFFER_BINDIND_APPLE'' – vkalit

ответ

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, который объясняет, почему модифицированный код работает, насколько я понимаю.

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

APPLE_framebuffer_multisample

+0

Ролан, спасибо вам за ответ, но это действительно возможно из-за буфера кадров по умолчанию, установленного GLKView – vkalit

+2

Какую версию OpenGL ES вы используете? Поскольку при использовании ES 3.0 'glBlitFramebuffer' следует использовать вместо' glRenderbufferStorageMultisampleAPPLE'. – Rolan

+0

Я использую OpenGL ES 2.0. – vkalit