I worked on ping pong shading and thought I hacked it after my previous question. However, with further knowledge of the shaders, it seems that while I can run the shader on FBO A and FBO B, the output from A is not used as a source for B. In other words, I am not binding it correctly.
The code I'm using is below. The output of the second shader displays a color output, but the first shader sets the data in shades of gray. Therefore, I know that this does not work as needed.
I would be grateful for any (even more !!!!) help.
Code below
Greetings
Simon
- (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); }