2011-04-12 62 views
4

我一直在研究乒乓着色,並且曾經認爲在我之前的問題之後我已經破解了它。然而,當我能夠在FBO A和FBO B上運行着色器時,有了更深入的着色知識,A的輸出不會被用作B的源。換句話說,我沒有正確地綁定它。將Opengl紋理從第一個fbo綁定到第二個fbo,使用着色器並渲染第二個結果(乒乓)

我使用的代碼如下。第二個着色器的輸出顯示基於顏色的輸出,但第一個着色器將數據設置爲灰度。所以我經常知道這不符合要求。

我會很感激任何(還有!!)的幫助。

代碼下面,

乾杯,

西蒙

- (void) PingPong:(CVImageBufferRef)cameraframe; 
{ 
// Standard texture coords for the rendering pipeline 
static const GLfloat squareVertices[] = { 
    -1.0f, -1.0f, 
    1.0f, -1.0f, 
    -1.0f, 1.0f, 
    1.0f, 1.0f, 
}; 

static const GLfloat textureVertices[] = { 
    1.0f, 1.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    0.0f, 0.0f, 
}; 

if (context) 
{ 
    [EAGLContext setCurrentContext:context]; 
} 

// Create two textures with the same configuration 
int bufferHeight = CVPixelBufferGetHeight(cameraframe); 
int bufferWidth = CVPixelBufferGetWidth(cameraframe); 

// texture 1 
glGenTextures(1, &tex_A); 
glBindTexture(GL_TEXTURE_2D, tex_A); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

// Using BGRA extension to pull in video frame data directly 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraframe)); 

// Texture 2 
glGenTextures(1, &tex_B); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

// Bind framebuffer A 
glBindFramebuffer(GL_FRAMEBUFFER, fbo_A); 
glViewport(0, 0, backingWidth, backingHeight); 

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, tex_A); 

// Update uniform values 
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0); 

// Update attribute values. 
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); 
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

// Use the first shader 
glUseProgram(greyscaleProgram); 

// Render a quad 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Use the second shader 
glUseProgram(program); 

// Bind framebuffer B 
glBindFramebuffer(GL_FRAMEBUFFER, fbo_B); 

// Bind texture A and setup texture units for the shader 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, tex_A); 

// Render output of FBO b is texture B 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_B, 0); 

// Update uniform values 
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0); 

// Update attribute values. 
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
glEnableVertexAttribArray(ATTRIB_VERTEX); 
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); 
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

// Render a quad 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

// Render the whole thing 
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); 
[context presentRenderbuffer:GL_RENDERBUFFER]; 

glDeleteTextures(1, &tex_A); 
glDeleteTextures(1, &tex_B); 
} 

回答

0

認爲什麼可能發生的是,你仍然渲染到幀緩衝存儲器,而不是紋理內存。 iirc glFramebufferTexture2D不充當解析/複製,而是將幀緩衝區綁定到紋理,以便將來的渲染操作被寫入紋理。你可能會遇到更多的問題,但是我非常確定你的glFramebufferTexture2D調用應該在你第一次調用glBindFramebuffer之後立即發生。這可能不是你唯一的問題,但它似乎是一個重要的問題。

+0

是的 - 我已經嘗試綁定tex_a和tex_B到相應的幀緩衝區後立即創建紋理,但後來我得到一個鎖定的屏幕,它永遠不會更新。我目前正在檢查我正在清理所有東西,並清理着色器(等),以便我的程序中沒有其他文物 – Simon 2011-04-22 08:20:07

+0

它看起來不像tex_A應該被綁定到渲染緩衝區,它看起來像你的紋理輸入。另外,我不明白爲什麼你有兩個渲染緩衝區。並且完成它,一旦你綁定了最終的渲染緩衝區,看起來就像你正在顯示的那樣,你永遠不會渲染任何東西。從代碼的外觀來看,從不更新的屏幕似乎暗示着渲染緩衝區實際上正在工作。使用當前的代碼,如果它工作,我不希望任何東西顯示。 – Arelius 2011-04-22 18:43:51

+0

也就是說,我認爲你誤解了glFramebufferTexture2D的功能。您可以使用它來設置要呈現的紋理,**不需要**要渲染的紋理,還可以**不復制將當前渲染緩衝區複製到的紋理。 – Arelius 2011-04-22 18:48:55

相關問題