2011-03-28 137 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