OpenGL chain filter (frame buffer off screen rendering)

Keywords: OpenGL

The special effects written by OpenGL can be realized by a single shader in some applications, that is, by modifying the vertex shader or slice shader. However, more scenes require the combination of multiple special effects. For example, the final effect is the image gray plus upside down. If the effect is not complex, it can be realized by modifying the slice shader. When the effect is complex, the modular development of special effects, combined special effects and special effects will be realized through chain filters.

1, Chain filter concept

Chain filter realizes the combination and superposition of special effects through frame buffer off screen rendering technology. The desired effect is finally achieved through multiple draw ings.

2, Frame buffering in rendering flow

The workflow of OpenGL is to input pixel data and vertex data. After the two kinds of data are operated respectively, the fragments are obtained through rasterization, then processed, finally drawn to the frame buffer, and finally converted into pixel data. The final destination of OpenGL pipeline rendering is FrameBuffer. The following is the opengl rendering flowchart.

3, Framebuffer object

In the opengl rendering pipeline, geometric data and texture are transformed and tested many times, and finally displayed on the screen in the form of two-dimensional pixels. The final rendering destination of the OpenGL pipeline is called a frame buffer. Frame buffer is a collection of two-dimensional arrays and storage areas used by OpenG: color cache, depth cache, template cache and cumulative cache. Generally, the frame cache is completely generated and managed by the window system and used by OpenGL. This default frame cache is called "window system provided" frame cache. OpenGL allows us to define our own frame buffer, that is, we can define our own color buffer, even depth buffer and template buffer. In a frame cache object, there are multiple color correlation points, a depth correlation point, and a template. There is at least one color association point in each frame cache, and its number is related to the physical graphics card. You can use GL_MAX_COLOR_ATTACHMENTS_EXT to query the maximum number of color association points.
Note: there are no images stored in FBO, only multiple associated points.

4, Custom frame buffer

1: Create a frame buffer

unsigned int fbo;
glGenFramebuffers(1, &fbo);

2: Bind frame buffer. Frame buffer will be turned on when bound
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

3: Render to texture

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

5, Render chain

The combination structure of multiple special effects is as follows. Binding frame buffer 0 is used to activate the default frame buffer again and have visual effects in the main window.

1: Grayscale fragment shaderGray

precision highp float; uniform sampler2D Texture; 
varying vec2 TextureCoordsVarying; 
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main (void) { 
 vec4 mask = texture2D(Texture, TextureCoordsVarying); 
 floatluminance = dot(mask.rgb, W); 
 gl_FragColor = vec4(vec3(luminance), 1.0); 
}

1: Upside down fragment shaderReverse

precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;

void main (void) {
    vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
    gl_FragColor = color;
}

The pseudo code is as follows:

// Step one

unsigned int fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

DrawShaderGray(); //Draw results in texture

//setp two  
DrawWithGrayInShaderReverse(texture)

Posted by mmonaco on Fri, 05 Nov 2021 18:09:18 -0700