2013-08-20 11 views
8

मैं एक आईओएस ओपनजीएल ईएस एप्लीकेशन विकसित कर रहा हूं।- [ईएजीएलकॉन्टेक्स्ट रेंडरबफर स्टोरेज: से ड्रॉबल:] दूसरी बार विफल रहा?

मैं सामान्य EAGLView/ES2Render सामान कर रहा हूं।

स्टार्टअप पर frambuffer निर्माण सफल होता है, निम्नलिखित कोड का उपयोग कर: UIView के -layoutSubviews कहा जाता है और मैं बदले में -resizeFromLayer: निष्पादित

- (BOOL) createFramebuffers 
{ 
    [EAGLContext setCurrentContext:_mainContext]; 

    // [ A ] On-screen 

    // 1. Framebuffer 
    glGenFramebuffers(1, &_mainFramebuffer); 
    bindFramebuffer(_mainFramebuffer); 

    // 2. Color buffer 
    glGenRenderbuffers(1, &_mainColorbuffer); 
    bindRenderbuffer(_mainColorbuffer); 

    // Adjust size to view's layer: 
    CAEAGLLayer* layer = (CAEAGLLayer*)[_view layer]; 

    if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) { 
     // something went horribly wrong 
     NSLog(@"-[ES2Renderer createFramebuffers]: Failed to obtain renderbuffer storage from layer!"); 
     return NO; 
    } 

    // Query new size: 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight); 

    // Attach to color: 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _mainColorbuffer); 

    // 3. Depth buffer 
    glGenRenderbuffers(1, &_depthBuffer); 
    bindRenderbuffer(_depthBuffer); 

    if (_useStencilBuffer) { 
     // Depth + Stencil 

     // Allocate storage: 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight); 

     // Attach to depth: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer); 

     // Attach to stencil: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer); 
    } 
    else{ 
     // Depth only 

     // Allocate storage: 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight); 

     // Attachto depth: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer); 

    } 

    // 4. Validate the set: 
    GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 

    if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) { 
     // Something went wrong! 

     NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@", 
       [self stringFromFramebufferStauts:framebufferStatus]); 

     return NO; 
    } 

    // [ B ] Off-screen (Render-to-texture) 

    // 1. Framebuffer 
    glGenFramebuffers(1, &_transFramebuffer); 
    bindFramebuffer(_transFramebuffer); 

    // 2. Depth buffer 
    glGenRenderbuffers(1, &_transDepthBuffer); 
    bindRenderbuffer(_transDepthBuffer); 

    if (_useStencilBuffer) { 
     // Allocate storage: 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight); 

     // Attach to depth: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer); 

     // Attach to stencil: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer); 
    } 
    else{ 
     // Allocate storage 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight); 

     // Attach to depth: 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer); 
    } 


    // 3. Textures (color buffers) 

    GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2}; 

    for (NSUInteger i=0; i < 2; i++) { 

     GLuint* texPtr = texPtrs[i]; 

     // Create: 
     glGenTextures(1, texPtr); 

     // Bind: 
     bindTexture2D(*texPtr); 

     // Configure for pixel-aligned use: 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

     // Allocate storage: 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 

     // Attach: 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0); 

     framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 

     // Validate: 
     if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) { 
      // Something went wrong! 

      NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@", 
        [self stringFromFramebufferStauts:framebufferStatus]); 

      return NO; 
     } 
    } 

    // Final State: 

    bindFramebuffer(_mainFramebuffer); 
    bindRenderbuffer(_mainColorbuffer); 
    bindTexture2D(0); 


    NSLog(@"-[ES2Renderer createFramebuffers] Succeeded."); 
    return YES; 
} 

इसके तुरंत बाद,:

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer 
{ 
    // [ A ] On screen framebuffer 

    bindFramebuffer(_mainFramebuffer); 

    // 1. Resize color buffer 
    bindRenderbuffer(_mainColorbuffer); 

    if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) { 
     // Something went wrong 
     return NO; // <-- SECOND TIME ON, THIS HAPPENS 
    } 

    // Query new size: 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight); 

    // 2. Resize depth buffer 
    bindRenderbuffer(_depthBuffer); 

    if (_useStencilBuffer) { 
     // (Depth & Stencil) 

     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight); 
    } 
    else{ 
     // (Depth only) 

     glRenderbufferStorage(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight); 
    } 

    // ...Validate: 
    GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 

    if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) { 
     // Something went wrong! 

     NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@", 
       [self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)]); 

     return NO; 
    } 

    // [ B ] Off screen (render-to-terxture) framebuffer 

    bindFramebuffer(_transFramebuffer); 

    // 1. Resize depth buffer 

    bindRenderbuffer(_transDepthBuffer); 

    if (_useStencilBuffer) { 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight); 
    } 
    else{ 
     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);   
    } 


    // 2. Resize textures 

    GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2}; 

    for (NSUInteger i=0; i < 2; i++) { 

     GLuint* texPtr = texPtrs[i]; 

     // Bind: 
     bindTexture2D(*texPtr); 

     // Configure for pixel-aligned use: 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

     // Allocate storage: 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 

     // Attach: 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0); 


     // Validate: 
     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
      // Something went wrong! 
      NSString* statusString = [self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)]; 
      NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@", statusString); 
      return NO; 
     } 
    } 

    bindFramebuffer(_mainFramebuffer); 
    bindRenderbuffer(_mainColorbuffer); 


    // Pass new ortho projection to shaders 
    [self initializeModelViewMatrix]; 
    [self initializeSpriteProgram]; 

    // Set new viewport 
    glViewport(0, 0, _backingWidth, _backingHeight); 

    NSLog(@"-[ES2Renderer resizeFromLayer:]: Succeeded."); 

    return YES; 
} 

क्या की कुछ भी नहीं मैं मैं कर रहा हूँ विशेष है। मेरे पास दृश्य संक्रमणों को प्रस्तुत करने के लिए एक अलग फ्रेमबफर है, जिसमें दो बनावट रंग से जुड़ी हैं, और गहराई है।

दूसरी बार -renderbufferStorage:fromDrawable: कहा जाता है (-layoutSubviews ->resizeFromLayer:), यह हमेशा विफल रहता है (रिटर्न NO); glGetError() पर कॉल करने से पहले कोई त्रुटि नहीं होती है, लेकिन GL_INVALID_OPERATION रिटर्न के बाद इसे सही कॉल करना। यदि मैं इसे अनदेखा करता हूं और आगे बढ़ता हूं, glGetRenderbufferParameteriv() अभी भी मुझे सही चौड़ाई और ऊंचाई (640 और 1136 क्रमशः, एक आईफोन 5 पर) प्राप्त करता है, लेकिन glCheckFramebufferStatus()GL_FRAMEBUFFER_UNSUPPORTED वापस आ जाएगा।

वैकल्पिक रूप से, मैं ऊपर resizeFromLayer: को छोड़ दिया है और इस से बदल दिया:

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer 
{ 
    [self destroyFramebuffers]; 

    return [self createFramebuffers]; 
} 

... लेकिन एक ही त्रुटि बनी रहती है (-renderStorage:fromDrawable: विफल रहता है; -createFramebuffers अंदर इस समय)।

अभी के लिए, मैं बस YES (मेरा ऐप केवल पोर्ट्रेट का समर्थन करता है, इसलिए कोई स्क्रीन आकार परिवर्तन वास्तव में कभी नहीं होता है), लेकिन मैं वास्तव में इसे ठीक करना चाहता हूं क्योंकि एक दिन मुझे परिदृश्य, आदि का समर्थन करने की आवश्यकता होगी ...

+0

मैं हाल ही में इस समस्या का सामना करना पड़ा तरह नष्ट कर सकते हैं, लेकिन केवल जब एक iOS 7 डिवाइस पर चल रहा (सिम्युलेटर नहीं)। दुर्भाग्य से मुझे नहीं पता कि इसका क्या कारण है, लेकिन समस्या को ठीक करने के लिए डिवाइस को पुनरारंभ करना दिखाई दिया। हालांकि बहुत परेशान है, और कोई गारंटी नहीं है कि यह फिर से नहीं होगा ... – Stuart

उत्तर

1

एक संभव कारण यह है कि renderbufferStorage:fromDrawable: विफल हो रहा है कि _mainContext उस समय वर्तमान संदर्भ नहीं है। भले ही ऐसा लगता है कि कोई अन्य संदर्भ 'वर्तमान' स्थिति चोरी नहीं कर सका, तो मैं gl या EAGL कोड से पहले [EAGLContext setCurrentContext:_mainContext] पर कॉल करने की सलाह देता हूं जो उस संदर्भ से जुड़े ऑब्जेक्ट्स पर संचालित होता है (उदाहरण के लिए resizeFromLayer: विधि की शुरुआत में)।

1

एक और संभावित कारण यह है कि आपकी परत का आकार बहुत बड़ा है। इसके अलावा सुनिश्चित करें कि आप हर बार एक नया फ्रेमबफर और रेंडरबफर का उपयोग कर रहे हैं। और आपने नए बनाने से पहले अपने पुराने लोगों को नष्ट कर दिया है।

आप उन्हें इस

if let displayFramebuffer = self.displayFramebuffer { 
    var temporaryFramebuffer = displayFramebuffer 
    glDeleteFramebuffers(1, &temporaryFramebuffer) 
    self.displayFramebuffer = nil 
} 

if let displayRenderbuffer = self.displayRenderbuffer { 
    var temporaryRenderbuffer = displayRenderbuffer 
    glDeleteRenderbuffers(1, &temporaryRenderbuffer) 
    self.displayRenderbuffer = nil 
} 
संबंधित मुद्दे