My OpenGL thematic learning directory, hope to learn with you exchange progress!
- OpenGL Learning (I) – Terminology understanding
- OpenGL learning (2) — Xcode build OpenGL environment
- OpenGL learning (three) – OpenGL base rendering
- OpenGL learning (4) – front & back culling and depth testing
- OpenGL Learning (5) – Cropping and Blending
- OpenGL Learning (6) – Base textures
- OpenGL Learning (7) — Summary of basic change Comprehensive Exercise practice
- OpenGL ES Learning (8)
- OpenGL learning (nine) — OpenGL ES preliminary exploration (next) GLKit
- OpenGL learning (10) – GLSL syntax introduction
- OpenGL learning (11) – using GLSL to load pictures
- OpenGL learning (12) — OpenGL ES texture flipping strategy comparison
A, cutting
Another way to improve rendering performance is to refresh only the parts of the screen that have changed. We may also need to restrict OpengGL rendering to a small rectangular area (clipping box) in the window. The clipping test is the first additional test to determine slice visibility. By default, the clipping box is the same size as the window, and no clipping test is performed. We can turn on clipping tests using the glEnable function, which is used almost everywhere.
glEnable(GL_SCISSOR_TEST);// Enable clipping test
Copy the code
You can also turn off clipping tests using the corresponding glDisable function.
glDisable(GL_SCISSOR_TEST);// Turn off clipping tests
Copy the code
Clipping boxes can be set to position and size using the following functions:
void glScissor(Glint x,Glint y,GLSize width,GLSize height);
Parameter x,y: specify the position of the point at the lower left corner of the clipping box (x,y);
Parameters width, height: Specifies the width and height of the clipping.
The following program uses the clipping test to draw a set of overlapping colored rectangles. It clears the color buffer three times, each time specifying a smaller clipping box than the previous one.
// 1. Set the screen clearing color to blue
glClearColor(0.0 f.0.0 f.1.0 f.0.0 f);
glClear(GL_COLOR_BUFFER_BIT);
// 2. Now crop the middle red rectangle
glClearColor(1.0 f.0.0 f.0.0 f.0.0 f);// (1) Set the clipping area color to red
glScissor(50.50.300.200);// (2) Set the clipping size
glEnable(GL_SCISSOR_TEST);// (3) Enable clipping test
glClear(GL_COLOR_BUFFER_BIT);// (4) Enable screen clearing and perform clipping
// 2. Finally cut out a small green rectangle
// Set the clear screen color to green
glClearColor(0.0 f.1.0 f.0.0 f.0.0 f);
glScissor(100.100.200.100);
glClear(GL_COLOR_BUFFER_BIT);
// Turn off clipping tests
glDisable(GL_SCISSOR_TEST);
// Swap buffers and flush
glutSwapBuffers();
Copy the code
Function thinking – glFlush and glutSwapBuffers
Function prototype:
void glFlush(void void)
void glutSwapBuffers(void)
- GlFlush forces the execution of the command to be printed immediately, rather than stored in a buffer waiting for other OpenGL commands. GlutSwapBuffers are used when performing double buffering exchanges. But in the case of glutSwapBuffers, the same effect can be achieved without glFlush, because when we perform a double-buffer swap, we implicitly perform a flush operation.
The effect picture is as follows:
Second, the hybrid
We know that normally OpenGL renders with the color values in the color buffer, and the depth values for each pixel in the depth buffer. When depth testing is turned off, the new color value simply overwrites the other values that already exist in the color buffer. When depth tests are turned on, less depth values Z are retained. However, if the blending function is turned on, the underlying color values will not be cleared.
Enable mixed function:glEnable(GL_BLEND);
With blending enabled, the new color is combined with an existing color value in the color buffer.
1, color combination
Target color: The color value already stored in the color buffer.
Source color: The color value entered into the color buffer as the result of the current render command, which may or may not interact with the target color. Both the target and source colors contain separate red, green, and blue components and an optional alpha value. If we ignore alpha, OpenGL will set it to 1.0. When blending is enabled, the way source and destination colors are combined is controlled by blending equations. By default the equation is as follows: Cf = (CS * S) + (Cd * D)
- Cf: The resulting color of the final calculation
- Cs: source color
- Cd: Is the target color
- S: source mixing factor
- D: Target mixing factor.
These mixing factors are set using glBlendFunc functions: glBlendFunc(GLenum S, GLenum D); Both S and D are enumerated values, not actual values that can be specified directly.
The following table lists the values available for blending functions:
function | RGB mixing factor | Alpha mixing factor |
---|---|---|
GL_ZERO | (0, 0) | 0 |
GL_ONE | ,1,1 (1) | 1 |
GL_SRC_COLOR | (Rs,Gs,Bs) | As |
GL_ONE_MINUS_SRC_COLOR | ,1,1 (1) – (Rs, Gs, Bs) | 1-As |
GL_DST_COLOR | (Rd,Gd,Bd) | Ad |
GL_ONE_MINUS_DST_COLOR | ,1,1 (1) – (Rd, Gd, Bd) | 1-Ad |
GL_SRC_ALPHA | (As,As,As) | As |
GL_ONE_MINUS_SRC_ALPHA | ,1,1 (1) – (As, As, As) | 1-As |
GL_DST_ALPHA | (Ad,Ad,Ad) | Ad |
GL_ONE_MINUS_DST_ALPHA | ,1,1 (1) – (Ad, Ad, Ad) | 1-Ad |
GL_CONSTANT_COLOR | (Rc,Gc,Bc) | Ac |
GL_ONE_MINUS_CONSTANT_COLOR | ,1,1 (1) – (Rc, Gc, Bc) | 1-Ac |
GL_CONSTANT_ALPHA | (Ac,Ac,Ac) | Ac |
GL_ONE_MINUS_CONSTANT_ALPHA | ,1,1 (1) – (Ac, Ac, Ac) | 1-Ac |
GL_SRC_ALPHA_SATURATE | (f,f,f)* | 1 |
Where f=min(As, 1-ad) colors are represented As floating point numbers, so it’s perfectly legal to add, subtract, and even multiply them. The above table may seem a little confusing, but here’s an example of a common combination of blending functions.
glBlendFun(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
For example, if the color buffer already has a blue (0.0F, 0.0F, 1.0f, 0.0F), this is the target color (Cd). If you draw something on this with an alpha of 0.6 ** red (1.0F, 0.0F, 0.0F, 0.6f) **, you can calculate the final color as follows. Cd = target color = (0.0f, 0.0f, 1.0f, 0.0f) Cs = source color = (1.0f, 0.0f, 0.0f, 0.0f, 0.6f) S = source alpha = 0.6d = 1 minus alpha = 1.0-0.6 = 0.4 Equation: Cf = (Cs * S) + (Cd * D) = (Red * S) + (Blue * 0.4)
The final color is a scaled combination of the original blue (the target color) and the later red (the source color). The higher the alpha value of the source color, the more source color components are added and the less the target color remains. As shown in figure:
2. Change the mixing equation
Cf = (Cs * S) + (Cd * D)
There are actually five different mixed equations to choose from, as shown in the table below, which we can do by using the following function:
void glBlendEquation(GLenum mode);
Copy the code
model | function |
---|---|
GL_FUNC _ADD | Cf = (Cs * S) + (Cd * D) |
GL_FUNC_SUBTRACT | Cf = (Cs * S) – (Cd * D) |
GL_FUNC_REVERSE_SUBTRACT | Cf = (Cd * D) – (Cs * S) |
GL_MIN | Cf = min(Cs, Cd) |
GL_MAX | Cf = max(Cs, Cd) |
In addition to glBlendFunc, ha can be more flexible with the following functions.
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
Copy the code
- StrRGB: blending factor of source color
- DstRGB: blending factor of the target color
- StrAlpha: Alpha factor of the source color
- DstAlpha: Alpha factor of the target color
The glBlendFunc function specifies a blending function for source and target RGBA values, while the glBlendFuncSeparate function allows separate blending functions for RGB and alpha components.
In the mixing factor table, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, Both GL_ONE_MINUS_CONSTANT_ALPHA values allow the introduction of a constant blending color into the blending equation. This color is initially black ** (0.0f, 0.0f, 0.0f, 0.0f) **, but can be modified with the following function:
void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );
Copy the code
3, anti-aliasing
Another use of OpenGL’s hybrid features is anti-aliasing. In most cases a single render fragment will be mapped to a single pixel on the computer screen. These pixels are square (or nearly square), and it is usually clear to see the boundary between the two colors. They are often called jagged, which gives the impression of an unnatural image. To eliminate jagged edges between pixels, OpengGL uses the blending feature to blend the colors of fragments, which blends the target color of a pixel with the colors of surrounding pixels. Turning on the anti-aliasing feature is easy. Start with the blending feature
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Copy the code
We also need to make sure that the mixing equation is set to GL_ADD. After blending is enabled and the correct blending function and blending equation is selected, the glEnable function is optionally called for anti-aliasing of points, lines, and polygons.
glEnable(GL_POINT_SMOOTH); // Smooth out points
glEnable(GL_LINE_SMOOTH); // Smooth out lines
glEnable(GL_POLYGON_SMOOTH); // Smooth out polygon edges
Copy the code
4. Multiple sampling
Anti-aliasing Smoothing of points and lines is widely supported, but smoothing of polygons is not implemented on all platforms. Even when GL_POLYGON_SMOOTH is available, anti-aliasing the entire scene is not as convenient as might be expected. This is because anti-aliasing is based on hybrid operations, which requires sorting all primiples from front to back, which can be very cumbersome.
OpenGL 1.3 added a feature called multisampling to solve this problem. An additional buffer is added to the frame buffer that already contains color, depth, and template values. All primitives are sampled multiple times at each pixel, and the results are stored in this buffer. Each time this pixel is updated, these sample values are parsed to produce a single value. GLUT provides a bit segment (GLUT_MULTISAMPLE) that allows such a frame buffer to be requested. For example, to request a multi-sampled, full-color, double-buffered town buffer with depth, you can call:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
Copy the code
Multiple sampling can be turned on or off using the glEnable/glDisable combination (using the GLUT_MULTISAMPLE tag).
glEnable(GL_MULTISAMPLE)
Copy the code
or
glDisable(GL_MULTISAMPLE)
Copy the code
When multiple sampling is enabled, the smoothing features of points, lines, and polygons are ignored (if they are enabled). This means that point and line smoothing (anti-aliasing) cannot be used at the same time when using multiple samples. In certain implementations, points and lines can work better with anti-aliasing than with multiple sampling. Therefore, multiple sampling can be turned off when drawing points and lines, and turned on again when drawing other solid geometries. Here’s an example:
glDisable(GL_MULTISAMPLE);// Disable multiple sampling
glEnable(GL_POINT_SMOOTH);// Anti-aliasing of the opening point
glEnable(GL_LINE_SMOOTH);// Enable line anti-aliasing
// Draw points and lines... glDisable(GL_POINT_SMOOTH);// Close the anti-aliasing process
glDisable(GL_LINE_SMOOTH);// Turn off line anti-aliasing
glEnable(GL_MULTISAMPLE);// Enable multiple sampling
// Draw a polygon...Copy the code
If there is no multisample buffer, OpenGL assumes that GL_MULTISAMPLE is disabled.
The multisample buffer uses the RGB value of the fragment by default and does not include the alpha component of the color. We can modify this behavior by calling glEnable, using one of the following three values.
- GL_SAMPLE_ALPHA_TO_COVERAGE — uses the alpha value.
- GL_SAMPLE_ALPHA_TO_ON — Set alpha to 1 and use it.
- GL_SAMPLE_COVERAGE — uses the value set by glSampleCoverage.
When GL_SAMPLE_ALPHA_TO_COVERAGE is enabled, the glSampleConverage function allows you to specify a specific value as a result of bitwise and manipulation with the fragment coverage value. void glSampleConverage (GLclampf value, GLboolean invert);
The above summary refers to and partly extracts the following articles, thanks very much to the following authors for sharing! :
1. OpenGL Super Dictionary 5th Edition
2. OpenGL Programming Guide (Eighth Edition)