我正在开发一个iOS openGL ES应用程序.
我正在做通常的EAGLView / ES2Render.
在启动时,使用以下代码创建frambuffer成功:
- (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,_depthBuffer); // Attach to stencil: glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_STENCIL_ATTACHMENT,_depthBuffer); } else{ // Depth only // Allocate storage: glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24_OES,_backingHeight); // Attachto depth: glFramebufferRenderbuffer(GL_FRAMEBUFFER,_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,_transDepthBuffer); // Attach to stencil: glFramebufferRenderbuffer(GL_FRAMEBUFFER,_transDepthBuffer); } else{ // Allocate storage glRenderbufferStorage(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_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,GL_RGBA,_backingHeight,GL_UNSIGNED_BYTE,0); // Attach: glFramebufferTexture2D(GL_FRAMEBUFFER,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; }
不久之后,UIView的-layoutSubviews被调用,然后我执行-resizeFromLayer ::
- (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,&_backingHeight); // 2. Resize depth buffer bindRenderbuffer(_depthBuffer); if (_useStencilBuffer) { // (Depth & Stencil) glRenderbufferStorage(GL_RENDERBUFFER,_backingHeight); } else{ // (Depth only) glRenderbufferStorage(GL_FRAMEBUFFER,_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,_backingHeight); } else{ glRenderbufferStorage(GL_RENDERBUFFER,_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,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,_backingHeight); NSLog(@"-[ES2Renderer resizeFromLayer:]: Succeeded."); return YES; }
我所做的一切都不是特别的.我有一个单独的帧缓冲区来渲染场景过渡,有两个纹理可以附加到颜色和深度.
第二次-renderbufferStorage:fromDrawable:被调用(-layoutSubviews – > resizeFromLayer :),它总是失败(返回NO);在此之前调用glGetError()不会导致错误,但在返回GL_INVALID_OPERATION后立即调用它.
如果我忽略了这一点并继续,glGetRenderbufferParameteriv()仍然可以获得正确的宽度和高度(分别在iPhone 5上为640和1136),但glCheckFramebufferStatus()将返回GL_FRAMEBUFFER_UNSUPPORTED.
或者,我跳过上面的resizeFromLayer:并将其替换为:
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer { [self destroyFramebuffers]; return [self createFramebuffers]; }
…但是同样的错误仍然存在(-renderStorage:fromDrawable:Failed;这次是在-createFramebuffers中).
现在,我只返回YES(我的应用只支持肖像,所以实际上没有发生屏幕尺寸变化),但我真的想修复它,因为有一天我需要支持景观等…