代码之家  ›  专栏  ›  技术社区  ›  Ilya Suzdalnitski

OpenGL ES-紫色或黑色屏幕

  •  0
  • Ilya Suzdalnitski  · 技术社区  · 14 年前

    我在我的iphone应用程序中使用opengl es,有时在启动过程中,屏幕会变为紫色或黑色——在一个例子中是20。这种情况只有在初始化过程中才会发生,如果屏幕变成黑色或紫色,它将保持这种颜色-只有重新启动应用程序才有帮助。 另外,我发现当这个bug发生时,应用程序正在运行(我可以通过控制台看到游戏循环工作),但是iphone停止响应触摸(touchesbearth方法没有被调用)。

    这是我的代码:

    #define USE_DEPTH_BUFFER FALSE
    
    @implementation EAGLView
    
    @synthesize context;
    
    + (Class)layerClass {
        return [CAEAGLLayer class];
    }
    
    - (id)initWithFrame: (CGRect)frame {
        NSLog(@"init EAGLView");
        if ( (self = [super initWithFrame: frame]) ) {
            NSLog(@"initializing CAEAGLLayer and EAGLContext");
            // Get the layer
            CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
    
            eaglLayer.opaque = YES;
            eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
    
            context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    
            if (!context || ![EAGLContext setCurrentContext:context]) {
                NSLog(@"!context || ![EAGLContext setCurrentContext:context]");
                [self release];
                return nil;
            }
        }
        return self;
    }
    
    - (void)layoutSubviews {
        [EAGLContext setCurrentContext: context];
        [self destroyFramebuffer];
        [self createFramebuffer];
    }
    
    
    - (BOOL)createFramebuffer {
    
        glGenFramebuffersOES(1, &viewFramebuffer);
        glGenRenderbuffersOES(1, &viewRenderbuffer);
    
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
    
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
    
        if (USE_DEPTH_BUFFER) {
            glGenRenderbuffersOES(1, &depthRenderbuffer);
            glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
            glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
            glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
        }
    
        if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
            NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
            return NO;
        }
        return YES;
    }
    
    
    - (void)destroyFramebuffer {
    
        glDeleteFramebuffersOES(1, &viewFramebuffer);
        viewFramebuffer = 0;
        glDeleteRenderbuffersOES(1, &viewRenderbuffer);
        viewRenderbuffer = 0;
    
        if(depthRenderbuffer) {
            glDeleteRenderbuffersOES(1, &depthRenderbuffer);
            depthRenderbuffer = 0;
        }
    }
    
    -(void) startDrawing: (GLfloat) viewWidth andHeight: (GLfloat) viewHeight
    {
        [EAGLContext setCurrentContext: context]; 
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
        glViewport(0, 0, backingWidth, backingHeight); 
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity();
        glRotatef(-90.0f, 0.0f , 0.0f, 1.0f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
        glClear(GL_COLOR_BUFFER_BIT); 
    } 
    
    -(void) endDrawing
    { 
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
        [context presentRenderbuffer: GL_RENDERBUFFER_OES]; 
    }
    
    - (void)dealloc {
        if ([EAGLContext currentContext] == context) {
            [EAGLContext setCurrentContext:nil];
        }
    
        [context release];  
        [super dealloc];
    }
    
    ...touches processing...
    
    @end
    

    可能有什么问题,我该怎么解决?

    提前谢谢你, 伊利亚。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Patrick    14 年前

    听起来像是我在另一个电话里遇到的问题。 在那里发生的事情是,有时我们在尝试分配纹理时会“内存不足”,从那时起,opengl就不会渲染,应用程序的非可视部分仍然正常运行。

    请确保经常调用glgeterror,并在每次报告gl_no_error以外的内容时跟踪消息/中断。(为此我们有一个宏,以便在调试时,在 每一个 opengl调用。)