2011-03-28 135 views
2

基於前面的問題,我一直在研究如何在一次傳遞中運行多個着色器(即,有一個FBO並渲染爲紋理)。這是Iphone上的OpenGLES 2。OpenGL ES運行多個着色器

我創建了一些代碼,但只運行一幀。所以顯然我做錯了什麼,但我無法發現它。

輸入數據是攝像機的核心視頻緩衝區。

任何指針或修復程序都非常歡迎:)。

感謝,

西蒙

PS:我已經把一切都變成一個方法現在 - 只是這樣我可以簡單地專注於得到它的工作!

- (void) PingPong:(CVImageBufferRef)cameraframe; 
{ 
int bufferHeight = CVPixelBufferGetHeight(cameraframe); 

int bufferWidth = CVPixelBufferGetWidth(cameraframe); 

// Build the first FBO - this is wasteful - don't do this everytime 
GLuint firstFBO; 
glGenFramebuffers(1, &firstFBO); 
glBindFramebuffer(GL_FRAMEBUFFER, firstFBO); 

// Build the first texture and copy the video stuff into it 
GLuint sourcetexture; 
glGenTextures(1, &sourcetexture); 
glBindTexture(GL_TEXTURE_2D, sourcetexture); 
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); 


// Build the second texture 
GLuint nextTexture; 
glGenTextures(1, &nextTexture); 
glBindTexture(GL_TEXTURE_2D, nextTexture); 
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); 

// Attach the texture to our first FBO 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourcetexture, 0); 


// 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)); 

//glDrawBuffer(sourcetexture); 
glEnable(GL_TEXTURE_2D); 
glViewport(0, 0, backingWidth, backingHeight); 
glBindTexture(GL_TEXTURE_2D, sourcetexture); 
glUseProgram(greyscaleProgram); 

// Now do the 2nd pass using the sourcetexture as input 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, nextTexture, 0); 
glBindTexture(GL_TEXTURE_2D, nextTexture); 
glUseProgram(program); 

// Present the framebuffer to the render buffer 
[EAGLContext setCurrentContext:context]; 

glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 

[context presentRenderbuffer:GL_RENDERBUFFER]; 

// Clean up stuff 
glDeleteTextures(1, &sourcetexture); 
glDeleteTextures(1, &nextTexture); 

}

回答

3

哪裏是你畫的代碼?繪圖是觸發着色器執行的原因,而我現在看到它的代碼有零繪製調用(glDrawArrays,glDrawElements等),所以它不工作,因爲你沒有繪製。

繪製一個全屏幕四元組來觸發每個過程的着色器執行,它將起作用。

此外,建議使用glCheckFramebufferStatus檢查您的FBO配置是否受支持,並且可以在您的GL實施中使用。

+0

謝謝。我拿它,我需要爲每個glUseProgram做一個觸發渲染緩衝區/紋理?那麼一個進入紋理,一個進入最終的渲染緩衝區? – Simon 2011-03-29 13:05:14

+2

@Simon - 是的,每次你想使用着色器程序渲染時,你都需要做一次glDraw *。如果你想要一個實例的例子,請參閱[這個示例應用程序](http://www.sunsetlakesoftware.com/sites/default/files/ColorTracking.zip),我使用着色器進行兩階段渲染,就像你在嘗試什麼。 – 2011-03-29 14:34:51

+0

@Brad - 這是你在哪裏使用讀像素通過rawPositionPixels讀入fbo,然後調用setDisplay ...和UseProgram? – Simon 2011-03-29 15:23:40