2011-11-24 22 views
1

我一整天都在努力尋找答案。OpenGL在從另一個視圖返回後繪製黑色屏幕

問題:

我有OpenGL的看法,我在IB創建,初始化所有緩衝區,並設置其DisplayLink的渲染循環。它工作得很好,一切都很好。但後來我嘗試創建與根控制這個OpenGL視圖,另一個控制器,並使用目前它:

[self presentModalViewController:newPage animated:YES]; 

這很好地顯示出來,就像我想要的。它也很好,沒有發現問題。它也從IB發起。但只要我使用

[self dismissModalViewControllerAnimated:YES]; 

動畫確實發生了,這個視圖下去,但它的股價下跌它留下的「垃圾」背後(的觀點在黑色背景的部分)和以前的OpenGL視圖,住宿黑色。我嘗試刪除並重新創建displayLink,但沒有運氣。我試圖再次破壞/創建framebuffers,並且設法讓它工作一次,但花了很長時間,並且從視圖創建它,我不知道這是否是正確的方法。爲了更容易,下面是我的代碼的一些部分:

- (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 (YES) 
    { 
     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; 
    } 

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 

    return YES; 
    } 

    } 

    - (void)destroyFrameBuffer 
    glDeleteFramebuffersOES(1, &viewFramebuffer); 
    viewFramebuffer = 0; 
    glDeleteRenderbuffersOES(1, &viewRenderbuffer); 
    viewRenderbuffer = 0; 

    if(depthRenderbuffer) 
    { 
     glDeleteRenderbuffersOES(1, &depthRenderbuffer); 
     depthRenderbuffer = 0; 
    } 

    - (void)layoutSubviews 


    [EAGLContext setCurrentContext:context]; 

    [self draw:nil]; 

內部init是我的主要init方法。

- (id)internalInit 
{  

     CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer; 
     eaglLayer.opaque = YES; 


     context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 

     if (!context || ![EAGLContext setCurrentContext:context]) { 
      [self release]; 
      return nil; 
     } 

    [self createFrameBuffer]; 

    [self setupView:self]; 

     [self drawView: nil]; 

     CADisplayLink* displayLink; 
     displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(draw:)]; 
     [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     [displayLink setFrameInterval:1]; 

    return self; 
} 

setupView:方法基本上創建視口,設置視錐,所有必要的變量和狀態。沒什麼特別的。

在此先感謝所有花費的時間。

+0

其實如果我以同樣的方式創建任何其他的UIView(不是openGL),當我解僱它時,我的主要openGL視圖仍然是黑色的。但它仍然被渲染(至少我所有的繪製方法都被調用,並且所有的用戶輸入都被接收和處理)。還有一些來自調試器的幫助,我發現我的frameBuffer,renderBuffer和depthBuffer變量是0(不生成?),所以這可能是我的問題的根源。 – avuthless

+0

通過大量的測試,我發現當我創建另一個opengl視圖時,舊的只是凍結。我認爲它們以某種方式重疊。雖然我寧願他們都保持私人對方。我已經將所有方法聲明爲私有(在.m文件中),我也聲明所有變量都是@private,但這並沒有幫助。我能找到的唯一解決方案是徹底銷燬視圖,然後從頭開始初始化視圖。這對我來說確實有效,但我仍然在尋找正確的答案和方法來解決這個問題。 – avuthless

回答

2

經過一些優化後,我發生了同樣的效果,我已經證明在任何情況下都無法正常工作,對於我解散Game Center視圖或完成播放MPPlayer電影后出現問題。

從蘋果的OpenGL模板時,你會得到一個LayoutSubviews(你可以在上面的窗口在前看不見後得到),你應該銷燬並重新創建你的幀緩衝

- (void)layoutSubviews 
{ 
    // The framebuffer will be re-created at the beginning of the next setFramebuffer method call. 
    [self deleteFramebuffer]; 
} 

在此之後,funcion [(EAGLView *)的自我。查看setFramebuffer];應該被調用以再次創建幀緩衝區,原始模板實際上已經在每幀上調用了它,但是隻有在它被銷燬後才需要調用它。 (我把第一次叫在那裏做一個VAR)

我只是把程序在這裏:

- (void)setFramebuffer 
{ 
    if (context) 
    { 
     [EAGLContext setCurrentContext:context]; 

     if (!defaultFramebuffer) 
      [self createFramebuffer]; 

     glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 
     first = FALSE; 

    } 
} 

- (void)createFramebuffer 
{ 
if (context && !defaultFramebuffer) 
{ 
    NSLog(@"Create Frame Buffer"); 

    [EAGLContext setCurrentContext:context]; 

    // Create default framebuffer object. 
    glGenFramebuffersOES(1, &defaultFramebuffer); 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 

    // Create color render buffer and allocate backing store. 
    glGenRenderbuffersOES(1, &colorRenderbuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &framebufferWidth); 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &framebufferHeight); 

    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 

    // Need a depth buffer 
    glGenRenderbuffersOES(1, &depthRenderbuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); 
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, framebufferWidth, framebufferHeight); 
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); 

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
     NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER_OES)); 
} 

} 

所以這setFramebuffer上被調用的DisplayLink調用的函數。我在MPPlayer遊戲中心發出的didfinish通知中首先將var重置爲FALSE。

如果你找不到你的問題嘗試和調試在EAGL對象級別調用什麼,NSLog的每一個函數,看看是否有什麼奇怪的事情發生在你的緩衝區或綁定。

+0

好吧,當我嘗試重新創建視圖,一直在後臺我看到,我收到壞渲染緩衝參數(寬度和高度返回0)。但你的解決方案是正確的,我發現更多的人在談論這個問題,他們都提供了這樣的指示。我現在將掃描我的代碼中是否存在任何使我無法創建新的渲染緩衝區的缺陷/錯誤。謝謝您的回答! – avuthless

+0

我已經實現了你的方法,他們確實做得很好。但是,當我嘗試與另一個opengl視圖,第一個只停止渲染,並沒有緩衝區娛樂幫助它。爲了測試,我創建了我的opengl場景,並在角落中創建了一個小的子視圖,以查看當這個小視圖初始化時會發生什麼。那麼我的主要opengl視圖就會掛斷。沒有任何移動或刷新。輸入是好的(至少我認爲是這樣),但觀點沒有奏效。看來兩個opengl的觀點不能相處。 – avuthless

+0

是的,兩個opengl的觀點是非常不鼓勵蘋果,但我看到有人這樣做,唉,表現糟糕。我會嘗試瀏覽我的瀏覽器歷史記錄,看看我能否找到它。 – led42

0

'EAGLView在出現或重新出現問題時是黑色'的另一種可能的解釋是您的[EAGLView renderbufferStorage:fromDrawable:]方法未在主線程上調用。從後臺調用此方法將導致通常有效的情況,但非正常情況會變黑。可能不是這裏提到的確切問題的原因,但足以說明它可能對絕望的谷歌將來在這個頁面中陷入困境有用。

0

我有相同的問題,因爲glDepthMask(FALSE)背景框架繪圖保存到圖像,然後不返回正常渲染。希望能幫助到你。

謝謝。

相關問題