Running multiple OpenGL shaders on CVImageBuffer

In connection with my previous two questions, I spent a week figuring out how to run multiple shaders against the main video buffer. I know what I need to do, but honestly, I canโ€™t get the code to work (the original version is pasted below without ping-pong).

Lack of moments in Eureka now I'm completely stuck :). Code for compiling and linking shaders is not shown for brevity. All this does (successfully - but one shader overwrites the other - so skip the vital step) to the GL-compatible layer, and theres UIToolbar under which, in the end, there will be a button on the shader and a button for launching all shaders.

Thanks,

Simon

-(void) DrawFrame:(CVImageBufferRef)cameraframe; { int bufferHeight = CVPixelBufferGetHeight(cameraframe); int bufferWidth = CVPixelBufferGetWidth(cameraframe); // Create a new texture from the camera frame data, display that using the shaders glGenTextures(1, &videoFrameTexture); glBindTexture(GL_TEXTURE_2D, videoFrameTexture); 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)); 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, }; [self setDisplayFramebuffer]; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, videoFrameTexture); // 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); glUseProgram(greyscaleProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [self presentFramebuffer]; // Obviously here is where the ping pong starts (assuming correct mods // to the framebuffer setup method below glUseProgram(program); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [self presentFramebuffer]; glDeleteTextures(1, &videoFrameTexture); } - (void)setDisplayFramebuffer; { if (context) { [EAGLContext setCurrentContext:context]; if (!viewFramebuffer) { [self createFramebuffers]; } glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); glViewport(0, 0, backingWidth, backingHeight); } } - (BOOL)presentFramebuffer; { BOOL success = FALSE; if (context) { [EAGLContext setCurrentContext:context]; glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); success = [context presentRenderbuffer:GL_RENDERBUFFER]; } return success; } - (BOOL)createFramebuffers { glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); // Onscreen framebuffer object glGenFramebuffers(1, &viewFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); // Render buffer for final output glGenRenderbuffers(1, &viewRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); NSLog(@"Backing width: %d, height: %d", backingWidth, backingHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { NSLog(@"Failure with framebuffer generation"); return NO; } return YES; } 

Edit: Clarified what's missing

+4
source share
1 answer

To render ping pong, you need to do the following:

  • Create 2 textures with the same configuration
  • Create 2 Framebuffers with the same configuration and attach one texture to each framebuffer.

Let's call Framebuffers A and B and the attached texA and texB textures:

To do:

  • Use the first shader with glUseProgram.
  • Bind Framebuffer A.
  • Display quad

Now you have the result of shader execution in texA. To do ping pong:

  • Use the second shader with glUseProgram.
  • Bind Framebuffer B.
  • Bind texA and adjust the texture units for your shader.
  • Display quad
  • Use a shader with glUseProgram.
  • Bind Framebuffer A.
  • Link texB and adjust the texture units.
  • Display quad

Now you have the result in texA and you can repeat this process again, hope this helps!

+4
source

Source: https://habr.com/ru/post/1345828/


All Articles