OpenGL ES运行多个着色器
问题描述:
基于前面的问题,我一直在研究如何在一次传递中运行多个着色器(即,有一个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);
}
答
哪里是你画的代码?绘图是触发着色器执行的原因,而我现在看到它的代码有零绘制调用(glDrawArrays,glDrawElements等),所以它不工作,因为你没有绘制。
绘制一个全屏幕四元组来触发每个过程的着色器执行,它将起作用。
此外,建议使用glCheckFramebufferStatus检查您的FBO配置是否受支持,并且可以在您的GL实施中使用。
谢谢。我拿它,我需要为每个glUseProgram做一个触发渲染缓冲区/纹理?那么一个进入纹理,一个进入最终的渲染缓冲区? – Simon 2011-03-29 13:05:14
@Simon - 是的,每次你想使用着色器程序渲染时,你都需要做一次glDraw *。如果你想要一个实例的例子,请参阅[这个示例应用程序](http://www.sunsetlakesoftware.com/sites/default/files/ColorTracking.zip),我使用着色器进行两阶段渲染,就像你在尝试什么。 – 2011-03-29 14:34:51
@Brad - 这是你在哪里使用读像素通过rawPositionPixels读入fbo,然后调用setDisplay ...和UseProgram? – Simon 2011-03-29 15:23:40