Reproduced in: http://blog.csdn.net/Crazyjumper/archive/2007/12/26/1968567.aspx
Reproduced in: http://blog.csdn.net/Crazyjumper/archive/2007/12/26/1968567.aspx
Reproduced in: http://blog.csdn.net/Crazyjumper/archive/2007/12/26/1968567.aspx
Hello everyone. Now, due to the relationship of participation in the work, it is not updated for a long time. Taking advantage of the National Day's free time, I finally wrote another lesson. I feel that the introduction is almost complete. After this lesson, I will be able to skip it. In the future, I may write some of my own experiences in this area and take an advanced course.
Now we will release the content of Lesson 12th.
First, connect to the previous course:
Lesson 1: write the first OpenGL program
Lesson 2: drawing geometric figures
Lesson 3: some details about geometric drawing
Lesson 4: Color Selection
Lesson 5: three-dimensional spatial transformation
Lesson 6: animation production
Lesson 7: use light to show the stereoscopy
Lesson 8: Use the display list
Lesson 9: Use a mixture to achieve translucent Effect
Lesson 10: BMP file and pixel operations
Lesson 11th: getting started with texture
Lesson 12th, OpenGL fragment test -- → content of this course
The fragment test is to test each pixel. Only tested pixels are drawn. pixels that fail the test are not drawn. OpenGL provides a variety of test operations, which can achieve some special effects.
In the previous course, we mentioned the concept of "Deep test", which is particularly useful in 3D scenarios. If we plot an object that is closer to us and draw an object that is farther away without using the deep test, the object that is farther away will be drawn later, it will overwrite the close object. This effect is not what we want.
If a deep test is used, the situation will be different: every time a pixel is drawn, OpenGL records the "depth" of this pixel (the depth can be understood: the distance between the pixel and the observer. If a new Pixel is about to overwrite the original pixel, the depth test checks whether the new depth is smaller than the original depth value. If yes, the pixels are overwritten and the painting is successful. If not, the original pixels are not overwritten and the painting is canceled. In this way, even if we first draw relatively close objects and then draw relatively far objects, the far objects will not overwrite the close objects.
In fact, no matter whether deep testing is enabled or not, OpenGL tries to write deep data into the buffer when pixels are drawn, unless gldepthmask (gl_false) is called to disable writing. In addition to regular tests, these deep data can also be used for interesting purposes, such as creating shadows.
In addition to deep testing, OpenGL also provides tailoring testing, Alpha testing, and template testing.
1. tailoring Test
The cropping test is used to restrict the painting area. We can specify a rectangular cropping window. When the cropping test is enabled, only the pixels in the window can be drawn, and the pixel will be discarded. In other words, no matter how you draw the image, pixels outside the cropping window will not be modified.
Some may have played Warcraft 3. If a soldier is selected during the game, the avatar of the soldier will appear in a box below the screen. To ensure that the profile picture does not overwrite the pixels in any way, you can use the cropping test.
You can use the following code to enable or disable the cropping test:
Glable (gl_scissor_test); // enable the tailoring Test
Gldisable (gl_scissor_test); // disable the cropping test.
You can use the following code to specify a crop window with the position (x, y), width, and height. Glscissor (X, Y, width, height );
Note that the OpenGL window coordinates are in the lower left corner (0, 0) and in the upper right corner (width, height), which is different from Windows.
There is also a way to ensure that pixels are only drawn to a specific rectangular area, which is the transformation of the view (introduced in section 3rd of Lesson 5 ). However, the differences between the test and the test are different. To zoom in or out of a rectangle, You can scale all the content to a proper size and place it in the area of a rectangle. However, the cropping test will not zoom in or out of the rectangle range and the pixels will be ignored directly.
2. Alpha Testing
In the previous course, we learned that the alpha value of pixels can be used for mixed operations. In fact, the Alpha value has another purpose, which is Alpha testing. When each pixel is about to be drawn, if the Alpha test is started, OpenGL checks the Alpha value of the pixel and only draws pixels whose Alpha value meets the conditions (strictly speaking, pixels that meet the condition will pass this test and perform the following test. Only those that pass the test can be drawn.) If the condition is not met, no painting is performed. This "condition" can be: Always pass (default), always fail, pass when greater than the set value, pass when less than the set value, pass when equal to the set value is passed, greater than or equal to the set value is passed, less than or equal to the set value is passed, not equal to the set the value is passed.
If we need to draw an image, and some parts of the image are transparent (imagine, first draw a picture and then draw a picture frame, the image in the photo frame is transparent in many places, so that you can see the following picture through the photo frame), then you can use Alpha testing. Set the Alpha value of all places in the image that need transparency to 0.0, the Alpha value of places that do not need transparency to 1.0, and then set the Alpha test passing condition: "If it is greater than 0.5, it will pass" to achieve the goal. Of course, you can also set the Alpha value to 1.0 where transparency is required, the Alpha value to 0.0 where transparency is not required, and then set the condition to "pass if it is less than 0.5 ". There are usually more than one setting method for Alpha testing. You can choose one based on your preferences and actual needs.
You can use the following code to enable or disable Alpha testing:
Glable (gl_alpha_test); // enable Alpha Testing
Gldisable (gl_alpha_test); // disable Alpha Testing
You can use the following code to set the Alpha test condition to "pass if it is greater than 0.5 ":
Glalphafunc (gl_greater, 0.5f );
The second parameter of the function indicates the set value for comparison. The first parameter is the comparison method. In addition to gl_less (pass if it is smaller than), you can also select:
Gl_always (always pass ),
Gl_never (always fail ),
Gl_less (pass if it is smaller ),
Gl_lequal (pass if it is less than or equal ),
Gl_equal (equivalent to pass ),
Gl_gequal (pass if it is greater than or equal ),
Gl_notequal (pass if not equal ).
Now let's look at a practical example. How can I combine a photo image and a photo frame image? For the sake of simplicity, we use the 24-bit BMP file that has been used in the previous two lessons as the image format. (Because it is published to the network, in order to save capacity, I published the JPG format. After downloading, you can use the drawing tool that comes with Windows XP to open it and save it as a 24-bit BMP file)
Note: The first image is a desktop background of the famous online game World of Warcraft, Which is used here to avoid copyright issues. If anything is wrong, please promptly point out that I will change it immediately.
In the 24-bit BMP file format, BGR occupies 8 bits and does not save the Alpha value. Therefore, the Alpha test cannot be used directly. Note that in the photo frame, all the locations that need to be transparent are white, so we set the Alpha value of all the white (or very close to white) pixels in the program to 0.0, set its pixel Alpha value to 1.0, and set the Alpha test condition to "pass if it is greater than 0.5. This technology, which uses a special color to represent a transparent color, is sometimes used as a color key technology.
Use the code in the previous lesson 11th to read the image as a texture, and then use the following function to set the Alpha value of each pixel in the "current texture.
/* Convert the current texture BGR format to bgra format
* If the pixel RGB value in the texture differs from the specified RGB value by no more than absolute, set Alpha to 0.0; otherwise, set it to 1.0.
*/
Void texture_colorkey (glubyte R, glubyte g, glubyte B, glubyte absolute)
{
Glint width, height;
Glubyte * pixels = 0;
// Obtain the texture size information
Glgettexlevelparameteriv (gl_texture_2d, 0, gl_texture_width, & width );
Glgettexlevelparameteriv (gl_texture_2d, 0, gl_texture_height, & height );
// Allocate space and obtain texture pixels
Pixels = (glubyte *) malloc (width * height * 4 );
If (pixels = 0)
Return;
Glgetteximage (gl_texture_2d, 0, gl_bgra_ext, gl_unsigned_byte, pixels );
// Modify the Alpha value in the pixel
// Pixels [I * 4], pixels [I * 4 + 1], pixels [I * 4 + 2], and pixels [I * 4 + 3]
// Indicates the blue, green, red, and Alpha components of the I pixel respectively. 0 indicates the minimum, and 255 indicates the maximum.
{
Glint I;
Glint COUNT = width * height;
For (I = 0; I <count; ++ I)
{
If (ABS (pixels [I * 4]-B) <= absolute
& ABS (pixels [I * 4 + 1]-g) <= absolute
& ABS (pixels [I * 4 + 2]-R) <= absolute)
Pixels [I * 4 + 3] = 0;
Else
Pixels [I * 4 + 3] = 255;
}
}
// Reset the modified pixels to the texture to release the memory.
Glteximage2d (gl_texture_2d, 0, gl_rgba, width, height, 0,
Gl_bgra_ext, gl_unsigned_byte, pixels );
Free (pixels );
}
With the texture, we turn on the texture, specify the appropriate texture coordinates and draw a rectangle so that the image can be drawn on the screen. We first draw the texture of the photo, and then draw the texture of the photo frame. The program code is as follows:
Void display (void)
{
Static int initialized = 0;
Static gluint texwindow = 0;
Static gluint texpicture = 0;
// Perform initialization, including reading photos, reading photo frames, converting the color of the photo frames from BGR to bgra, and enabling 2D textures.
If (! Initialized)
{
Texpicture = load_texture ("pic.bmp ");
Texwindow = load_texture ("window.bmp ");
Glbindtexture (gl_texture_2d, texwindow );
Texture_colorkey (255,255,255, 10 );
Glable (gl_texture_2d );
Initialized = 1;
}
// Clear the screen
Glclear (gl_color_buffer_bit );
// Draw a photo. At this time, the Alpha test is not required and all pixels are drawn.
Glbindtexture (gl_texture_2d, texpicture );
Gldisable (gl_alpha_test );
Glbegin (gl_quads );
Gltexcoord2f (0, 0); glvertex2f (-1.0f,-1.0f );
Gltexcoord2f (0, 1); glvertex2f (-1.0f, 1.0f );
Gltexcoord2f (1, 1); glvertex2f (1.0f, 1.0f );
Gltexcoord2f (1, 0); glvertex2f (1.0f,-1.0f );
Glend ();
// Draw a photo frame. In this case, perform the Alpha test and only draw pixels in the opaque part.
Glbindtexture (gl_texture_2d, texwindow );
Glenable (gl_alpha_test );
Glalphafunc (gl_greater, 0.5f );
Glbegin (gl_quads );
Gltexcoord2f (0, 0); glvertex2f (-1.0f,-1.0f );
Gltexcoord2f (0, 1); glvertex2f (-1.0f, 1.0f );
Gltexcoord2f (1, 1); glvertex2f (1.0f, 1.0f );
Gltexcoord2f (1, 0); glvertex2f (1.0f,-1.0f );
Glend ();
// Exchange Buffer
Gluswapbuffers ();
}
Specifically, the load_texture function is copied from Lesson 11th (This function also uses a power_of_two function, a BMP _header_length constant, which is also copied) without modification. The main function is basically the same as that of other courses and is no longer repeated.
After the program is run, it will be found that the connection between the photo frame and the photo is somewhat unnatural, because although some edge parts of the photo frame look white to the naked eye, the RGB value is actually quite different from the pure white value, therefore, when the program calculates its alpha value, it does not need to be transparent. The solution is to carefully process each pixel in the photo frame and apply the plain white color where transparency is required. This may be a task that requires patience.
You may think: we have learned how to use a hybrid operation to achieve semi-transparency. Naturally, you can achieve full transparency through settings. That is to say, almost all the effects of alpha testing can be achieved through the OpenGL hybrid function. So why do we still need an Alpha test? The answer is, this is related to performance. The final result can be obtained after a simple comparison of the Alpha test size, while a hybrid operation generally requires multiplication, reducing the performance. In addition, the OpenGL test sequence is: tailoring test, Alpha test, template test, and deep test. If a test fails, the next step is not performed, and the hybrid operation is performed only when all tests pass. Therefore, when Alpha testing is used, transparent pixels do not need to undergo template testing or deep testing. If a hybrid operation is used, even transparent pixels require template tests and deep tests, which may degrade the performance. Another point: For those "Transparent" pixels, if Alpha testing is used, the "Transparent" pixels will not pass the test, so the pixel depth value will not be modified; in the hybrid operation, although the pixel color is not modified, its depth value may be modified.
Therefore, if all pixels are "Transparent" or "non-transparent", try Alpha testing instead of hybrid operations. Hybrid operations are used only when a translucent pixel is to be drawn.
3. template Test
Template testing is a complex method in all OpenGL tests.
First, the template test requires a template buffer, which is specified during OpenGL initialization. If you use the glut toolkit, you can add the maid in the parameter when calling the gluinitdisplaymode function. For example:
Fig );
In Windows, even if the template buffer is not explicitly required, the template buffer is sometimes allocated. However, to ensure the versatility of the program, it is best to specify the template buffer. If no template buffer is allocated, all pixels for template testing will pass the test.
You can enable or disable the template test by using glenable/gldisable.
Glable (gl_stencil_test); // enable template Test
Gldisable (gl_stencil_test); // disable template Test
OpenGL saves a "template value" for each pixel in the template buffer. When the pixel needs to perform a template test, it compares the set template reference value with the "template value" of the pixel, if the test is passed and the condition is not met, it is discarded and not drawn.
The condition settings are similar to those in the Alpha test. However, in the Alpha test, floating point numbers are used for comparison, while in the template test, integers are used for comparison. There are also eight comparison cases: always pass, never pass, pass if greater than, pass if smaller than, pass if greater than or equal to, pass if less than or equal to, pass if equal to, pass if not equal.
Glstencilfunc (gl_less, 3, mask );
This Code sets the template test condition as: "if it is less than 3, it passes ". The first two parameters of glstencilfunc are similar to those of glalphafunc. The third parameter indicates that, if compared, only the binary value of mask is 1. For example, if the template value of a certain pixel is 5 (Binary 101), and the binary value of mask is 00000011, because only the last two digits are compared, and the last two digits of 5 are 01, they are actually less than 3, therefore, the test is passed.
How to Set the "template value" of pixels? The glclear function can reset the template values of all pixels. The Code is as follows:
Glclear (gl_stencil_buffer_bit );
You can reset the color value and template value at the same time:
Glclear (gl_color_buffer_bit | gl_stencil_buffer_bit );
Just as you can use the glclearcolor function to specify the color after the screen is cleared, you can also use the glclearstencel function to specify the "template value" after the reset ".
The "template value" of each pixel is changed based on the template test results and the results of the deep test.
Glstencilop (fail, zfail, zpass );
This function specifies how the "template value" Changes in three cases. The first parameter indicates how the template test is changed when it is not passed; the second parameter indicates how the template test is passed, but the depth test is not passed; the third parameter indicates how the template test and the deep test change. If the template test is not started, the template test is always passed. If the deep test is not enabled, the deep test is always passed)
The changes can be:
Gl_keep (not changed, which is also the default value ),
Gl_zero (return to zero ),
Gl_replace (use the set value in the test condition to replace the current template value ),
Gl_incr (increases by 1, but remains unchanged if it is already the maximum ),
Gl_incr_wrap (increase by 1, but if it is already the maximum value, it starts from scratch ),
Gl_decr (1 less, but remains unchanged if it is already zero ),
Gl_decr_wrap (reduce 1, but if it is already zero, reset it to the maximum value ),
Gl_invert (bitwise inversion ).
In the new version of OpenGL, The glstencilfuncseparate function and glstencilopseparate function can be used to change the template test conditions and template values on the front and back of a polygon. These two functions are similar to glstencilfunc and glstencilop, respectively. They only have a parameter "face" added at the beginning to specify the plane that is currently set. You can select gl_front, gl_back, and gl_front_and_back.
Note: The template buffer is a little different from the depth buffer. Whether or not deep testing is enabled, the depth value of this pixel is always reset when pixels are drawn (unless gldepthmask (gl_false);) is set );). If the template test is not enabled, the template value of the pixel remains unchanged. The template value of the pixel can be modified only when the template test is enabled. (This conclusion was obtained from my own experiment, and I have not found any information on it. If there are any errors, please correct them)
In addition, although the template test is provided from OpenGL 1.0, there seems to be not many hardware implementation template tests for personal computers, many computer systems directly use CPU operations to complete template testing. Therefore, in some old graphics cards or most integrated graphics cards, a large number of frequent use of template tests may cause low program running efficiency. Do not use the glstencilfuncseparate and glstencilopseparate functions for high-end personal computers.
As mentioned above, you can use the cropping test to limit the area to the area of a rectangle. However, if you want to restrict the area to an irregular area, you need to use a template for testing.
For example, draw a lake and the surrounding trees, and then draw the reflection of the trees in the lake. To ensure that the reflection is properly restricted on the lake surface, you can use a template for testing. The procedure is as follows:
(1) Close the template test and draw the ground and trees.
(2) Enable the template test and use glclear to set the template value of all pixels to 0.
(3) set glstencilfunc (gl_always, 1, 1); glstencilop (gl_keep, gl_keep, gl_replace); To draw the lake surface. In this way, the "template value" of pixels on the lake surface is 1, while the "template value" of pixels in other places is 0.
(4) set glstencilfunc (gl_equal, 1, 1); glstencilop (gl_keep, gl_keep, gl_keep); To draw the reflection. In this way, only the pixels with the "template value" being 1 will be drawn. Therefore, only the pixels of the "water surface" can be replaced by the reflected pixels, while the hidden pixels remain unchanged.
Let's look at a real example. This is a simple scenario: A Sphere and a plane mirror exist in the space. We can see the image of the sphere in the plane mirror at a special observation point, and the image is on the edge of the plane mirror. Some images cannot be displayed due to the size limitation of the plane mirror. The effects of the entire scenario are as follows:
The idea of drawing this scenario is similar to the lake reflection mentioned above.
If the plane where the plane mirror is located is exactly the plane determined by the X axis and Y axis, then the sphere and its image in the plane mirror are about this plane symmetry. We use a draw_sphere function to draw a sphere. First, we call this function to draw the sphere itself, then call glscalef (1.0f, 1.0f,-1.0f), and then call the draw_sphere function, you can draw a sphere image.
Note that the deep test is enabled because it is a 3D scenario. However, in the observer's position, the image of the sphere is actually behind the plane mirror. That is to say, if the image is drawn in the conventional way, the plane mirror will overwrite the image, this is not what we want. Solution: Set the depth buffer to read-only, draw a plane mirror, set the depth buffer to a writable state, and draw the image behind the plane mirror.
Some may ask: if the deep test is disabled when the image is drawn, will the image not be blocked by the plane mirror? Why do I need to enable the deep test and set the deep buffer to read-only? The actual situation is: Although disabling the deep test does prevent the image from being blocked by the plane mirror, the image itself may have several problems. The image we see is a sphere, but in fact this sphere is composed of many polygon. Some of these polygon represent what we can see as "Front ", some represent the "back" we cannot see ". If the deep test is disabled, and some "back" polygon are drawn first than the "front" polygon, the back of the sphere will block the front, which is not the expected effect. To ensure that the front side can block the back, you should enable the deep test.
The code for plotting is as follows:
Void draw_sphere ()
{
// Set the light source
Glable (gl_lighting );
Glable (gl_light0 );
{
Glfloat
Pos [] = {5.0f, 5.0f, 0.0f, 1.0f },
Ambient [] = {0.0f, 0.0f, 1.0f, 1.0f };
Gllightfv (gl_light0, gl_position, POS );
Gllightfv (gl_light0, gl_ambient, ambient );
}
// Draw a sphere
Glcolor3f (1, 0, 0 );
Glpushmatrix ();
Gltranslatef (0, 0, 2 );
Glusolidsphere (0.5, 20, 20 );
Glpopmatrix ();
}
Void display (void)
{
// Clear the screen
Glclear (gl_color_buffer_bit | gl_depth_buffer_bit );
// Set the observation point
Glmatrixmode (gl_projection );
Glloadidentity ();
Gluperspective (60, 1, 5, 25 );
Glmatrixmode (gl_modelview );
Glloadidentity ();
Glulookat (5, 0, 6.5, 0, 0, 0, 0, 1, 0 );
Glenable (gl_depth_test );
// Draw a sphere
Gldisable (gl_stencil_test );
Draw_sphere ();
// Draw a plane mirror. Set template buffer while drawing.
// In addition, to ensure that the image after the plane mirror can be correctly drawn, you must set the depth buffer to read-only when drawing the plane mirror.
// Temporarily disable the illumination effect during painting
Glclearstenpencil (0 );
Glclear (gl_stencil_buffer_bit );
Glstencilfunc (gl_always, 1, 0xff );
Glstencilop (gl_keep, gl_keep, gl_replace );
Glenable (gl_stencil_test );
Gldisable (gl_lighting );
Glcolor3f (0.5f, 0.5f, 0.5f );
Gldepthmask (gl_false );
Glrectf (-1.5f,-1.5f, 1.5f, 1.5f );
Gldepthmask (gl_true );
// Draw a sphere that is symmetric with the previous sphere about the plane mirror. Note that the position of the light source must also be changed.
// Because the plane mirror is a plane determined by the X axis and Y axis, symmetry can be achieved as long as the zcoordinate is reversed.
// In order to ensure that the sphere is restricted within the plane mirror, use the template for testing.
Glstencilfunc (gl_equal, 1, 0xff );
Glstencilop (gl_keep, gl_keep, gl_replace );
Glscalef (1.0f, 1.0f,-1.0f );
Draw_sphere ();
// Exchange Buffer
Gluswapbuffers ();
//
Grab ();
}
At the end of the display function, a grab function is called to save the current image to a BMP file. This function was originally used in both Lesson 10 and lesson 11th. However, I found a bug, but now I have modified it: Add glreadbuffer (gl_front); to the beginning of the function. Note that this function should be called immediately after it is drawn (if dual buffering is used, it should be called after the switching buffer.
You may feel that the settings for template testing are so complicated that many functions can be implemented. There must be more than one "limit the pixel painting range ". This is actually the case, but now we only want to talk about this.
In fact, if you do not need to draw a translucent effect, sometimes you can use the hybrid function to replace the template test. The following steps can be used to draw an image:
(1) Clear the screen, set the appropriate value in glclearcolor to ensure that the alpha value of the pixel after the screen is cleared is 0.0
(2) disable the blending function, draw the sphere itself, and set the appropriate color (or illumination and material) to ensure that the alpha value of all drawn pixels is 0.0
(3) Draw a plane mirror and set the appropriate color (or illumination and material) to ensure that the alpha value of all painted pixels is 1.0
(4) Enable the hybrid function. Use gl_dst_alpha as the source factor, and gl_one_minus_dst_alpha as the target factor. In this way, only pixels with the original alpha of 1.0 can be modified, the pixels with Alpha 0.0 remain unchanged. Then, draw the image object. Make sure that the alpha value of all painted pixels is 1.0.
In some OpenGL implementations, template testing is implemented by software, while hybrid functions are implemented by hardware. In this case, you can consider this alternative method to improve the running efficiency. However, not all template tests can be replaced by the hybrid function. Such replace is not natural, complex, and error-prone.
In addition, always note: when using a mixture for simulation, even if the original Alpha value of a pixel is 0.0, the color of a pixel does not change after painting, however, the depth value of this pixel may be modified. If a template test is used, the depth value of the pixel that fails the test will not change. In addition, in the template test and hybrid functions, the pixel template value modification methods are different.
4. Deep Test
At the beginning of this lesson, we have briefly described deep testing. Here is the complete content.
Deep testing requires a deep buffer, which is similar to template testing requires a template buffer. If you use the glut toolkit, you can add glu_depth to the parameter when calling the gluinitdisplaymode function, so as to explicitly specify the need to use the depth buffer.
The implementation principles of deep testing and template testing are similar. They both store a certain pixel value in a buffer zone. When testing is required, the saved value is compared with another value, to determine whether the test is successful. The difference between the two is that the template test sets a value and compares the value with the "template value" of the pixel during the test, the depth test calculates the depth based on the spatial coordinates of the vertex, and compares the depth with the "depth value" of the pixel. That is to say, a value needs to be specified for the template test as a comparative reference. In the deep test, the reference value for this comparison is automatically calculated by OpenGL Based on the spatial coordinates.
The glenable/gldisable function enables or disables deep testing.
Glable (gl_depth_test); // enable deep Test
Gldisable (gl_depth_test); // disable deep Test
There are also eight conditions for passing the test, which are the same as those in Alpha testing. The condition settings are completed through the gldepthfunc function. The default value is gl_less.
Gldepthfunc (gl_less );
Compared with the template test, the deep test application is much more frequent. Deep tests are used for almost all 3D scenes. Because of this, almost all OpenGL implementations provide hardware support for deep testing. Although the implementation principles of the two are similar, deep testing may be much faster than template testing. Of course, there is little intersection between the two tests in the application. Generally, one test is not used to replace the other test.
Summary:
This course introduces four tests provided by OpenGL: tailoring test, Alpha test, template test, and deep test. OpenGL performs the above four tests on each pixel to be drawn. Each pixel enters the next test only after passing one test, and only the pixels that pass all tests are drawn, pixels that fail the test will be discarded and will not be drawn. Each test can be enabled or disabled independently. If a test is disabled, all pixels can pass the test smoothly.
Cropping test means that only pixels inside the specified rectangle can pass the test.
Alpha testing means that only pixels that meet the specified link conditions can pass the test if the Alpha value is compared with the set value.
Template test means that only pixels that meet the specific link conditions can pass the test when the pixel template value is compared with the set value.
Deep testing means that only pixels that match the pixel depth value with the new depth value can pass the test if they meet specific link conditions.
The preceding relationship conditions can be greater than, less than, equal to, greater than or equal to, less than or equal to, not equal to, always pass, and never pass.
Template test requires a template buffer, and deep test requires a depth buffer. These buffers are specified during OpenGL initialization. If you use the glut toolkit, you can specify it in the gluinitdisplaymode function. Whether or not to enable the deep test, OpenGL will attempt to modify the depth value of the pixel when the pixel is drawn. OpenGL will attempt to modify the template value of the pixel only when the template test is enabled, when the template test is disabled, OpenGL does not modify the template value of the pixel when the pixel is drawn.
Using these test operations, you can control whether pixels are drawn or not, thus achieving some special effects. You can use the hybrid function to achieve translucent. You can also achieve full transparency through settings, so you can simulate pixel color rendering or not painting. However, it is only a simulation of the color. OpenGL can save the color, depth value, and template value for pixels. When the pixel color is transparent by means of mixing, the pixel color does not change, but the depth value may change, the template value is affected by the third parameter in the glstencilfunc function. When the test operation is transparent, the pixel color does not change, and the depth value does not change, the template value is affected by the first two parameters in the glstencilfunc function.
In addition, the bug in a function in Lesson 10 and lesson 11th was corrected. In the grab function, add a glreadbuffer (gl_front) at the beginning to ensure that the read content is exactly the displayed content.