2012-09-17 107 views
1

我用這樣的代碼來設置我的幀緩衝:渲染到紋理和渲染的同時,以渲染

glGenRenderbuffers(1, &colorBuffer_) ; 

glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer_); 

if (!colorBuffer_) 
{ 
    NSLog(@"glGenRenderbuffers() failed"); 
    break; 
} 

[self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:drawable_]; 
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width_); 
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height_); 

glGenFramebuffers(1, &fbo); 

glBindFramebuffer(GL_FRAMEBUFFER, fbo); 

if (!fbo) 
{ 
    NSLog(@"glGenFramebuffers() failed"); 
    break; 
} 

CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.context, NULL, &textureCache_); 
if (err) 
{ 
    NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err); 
} 
CFDictionaryRef empty; // empty value for attr value. 
CFMutableDictionaryRef attrs; 
empty = CFDictionaryCreate(kCFAllocatorDefault, // our empty IOSurface properties dictionary 
          NULL, 
          NULL, 
          0, 
          &kCFTypeDictionaryKeyCallBacks, 
          &kCFTypeDictionaryValueCallBacks); 
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 
            1, 
            &kCFTypeDictionaryKeyCallBacks, 
            &kCFTypeDictionaryValueCallBacks); 

CFDictionarySetValue(attrs, 
        kCVPixelBufferIOSurfacePropertiesKey, 
        empty); 

CVPixelBufferCreate(kCFAllocatorDefault, 
        (int)width_, 
        (int)height_, 
        kCVPixelFormatType_32BGRA, 
        attrs, 
        &renderTarget_); 

err = CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, 
                textureCache_, renderTarget_, 
                NULL, // texture attributes 
                GL_TEXTURE_2D, 
                GL_RGBA, // opengl format 
                (int)width_, 
                (int)height_, 
                GL_BGRA, // native iOS format 
                GL_UNSIGNED_BYTE, 
                0, 
                &renderTexture_); 
if (err) 
{ 
    NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err); 
} 

CFRelease(attrs); 
CFRelease(empty); 

glBindTexture(CVOpenGLESTextureGetTarget(renderTexture_), CVOpenGLESTextureGetName(renderTexture_)); 
checkForErrors(); 

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

NSLog(@"%u", CVOpenGLESTextureGetName(renderTexture_)); 

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture_), 0); 

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer_); 

我想渲染到紋理和渲染渲染(見屏幕渲染的結果)與此同時。但是這個代碼不起作用。我認爲我不能同時使用glFramebufferTexture2DglFramebufferRenderbuffer。我對嗎?我該怎麼做?

回答

4

你是對的,你不能將紋理和渲染緩衝區都附加到相同的連接點,以自動渲染到兩者。

只需將其渲染到紋理,然後在屏幕上繪製屏幕大小的紋理四邊形以顯示它。當然,記得在渲染到它的時候解除你的紋理(glBindTexture(GL_TEXTURE_2D, 0)),而目前你不這樣做。

或者按照其他方式將結果渲染到屏幕上,然後使用glCopyTexSubImage2D將這些結果複製到紋理中。但最終你不會得到副本,不管是以繪製紋理四邊形還是直接從幀緩衝到紋理副本的形式進行間接處理。

編輯:你也可以解決這個使用多個渲染目標,通過附加紋理和渲染,以不同的顏色附件和撲滅在片段着色器多個頻道得到的顏色(使用gl_FragData[i]而不是gl_FragColor) 。但我不確定這是否真的會給你買東西,再加上它需要你的着色器知道雙重渲染。最後,我不確定ES實際上是否支持多重渲染目標。

+0

我有一個類似於蘋果GLPAint示例的應用程序(使用kEAGLDrawablePropertyRetainedBacking = YES)。螞蟻渲染紋理並同時繪製紋理四邊形太昂貴。有其他方法可以快速完成嗎? –

+0

@miksayer我列出了每一個明顯的方式來做到這一點。你真的需要每幀更新紋理嗎?如果沒有,那麼只需在屏幕上繼續渲染,並在需要時僅使用「glCopyTexSubImage2D」。我不知道這個GLPaint應用程序的語義,但如果它是一些標準的繪畫應用程序,則只需要在需要時更新實際圖像(紋理),或者至少在完成交互式繪製任務時(例如當釋放鼠標/手指/無論)。 –

+0

好的,我會試試。 thx –