Common OpenGL functions (iii)

Source: Internet
Author: User
Tags clear screen

Glblendfunc defines the pixel algorithm.void WINAPI glblendfunc (glenum sfactor,glenum dfactor);parameter editing Sfactor specifies how the red-green-blue and alpha-source blending factors are calculated. The initial value is Gl_one. Nine symbolic constants accepted: Gl_one_minus_dst_alpha,gl_zero Gl_one,gl_dst_color gl_one_minus_dst_color,gl_src_alpha GL_ONE_MINUS_SRC _alpha,gl_dst_alpha and Gl_src_alpha_saturate. Dfactor specifies how the red-green-blue and alpha-target blending factors are calculated. The initial value is Gl_zero. Eight symbolic constants accepted: Gl_zero Gl_one,gl_src_color gl_one_minus_src_color,gl_src_alpha Gl_one_minus_src_alpha,gl_dst_alpha, and GL _one_minus_dst_alpha. I. Source factor and Target factor
As we have already mentioned, mixing needs to find out the original color and the color that will be painted, and then get a new color after some sort of processing. Over here The color that will be painted is called the "source Color", and the original color is called the "Target color ".
OpenGL takes the source and target colors out and multiplies them by a factor (the source color is multiplied by the factor called the "source factor", the target color is multiplied by the factor called the "target Factor"), and then added, and the new color is obtained. (It may not be added, the new version of OpenGL can be set to operate, including addition, subtraction, take the larger of the two, take the two smaller, logical operations, etc., but we do not discuss this here for the sake of simplicity)
The following is a mathematical formula to express this operation mode. Suppose that four components of the source color (red, green, blue, alpha) are (Rs, Gs, Bs, as), four components of the target color (Rd, Gd, Bd, Ad), and the source factor (Sr, Sg, Sb, Sa), the target factor is (Dr, Dg, Db, Da). The new color generated by the blend can be expressed as:
(Rs*sr+rd*dr, GS*SG+GD*DG, Bs*sb+bd*db, As*sa+ad*da)
Of course, if a component of the color exceeds 1.0, it is automatically truncated to 1.0, and there is no need to consider cross-border issues.

Source and target factors can be set through the Glblendfunc function. Glblendfunc has two parameters, the former representing the source factor, and the latter representing the target factor. These two parameters can be a variety of values, the following describes the more common several.
Gl_zero:Indicates that using 0.0 as a factor is actually equivalent to not using this color to participate in the blending operation.
Gl_one:Indicates that using 1.0 as a factor is actually equivalent to fully using this color to participate in the blending operation.
Gl_src_alpha:Represents a factor using the alpha value of the source color.
Gl_dst_alpha:Indicates that the alpha value of the target color is used as a factor.
Gl_one_minus_src_alpha:Represents a factor by subtracting the alpha value of the source color by 1.0.
Gl_one_minus_dst_alpha:Indicates that the alpha value of the target color is subtracted from 1.0 as a factor .
In addition, there are Gl_src_color (four components of a source color as four components of a factor), Gl_one_minus_src_color, Gl_dst_color, Gl_one_minus_dst_color, and so on, the first two can only be used to set the target factor in older versions of OpenGL, and the latter two can only be used to set source factors in older versions of OpenGL. The new version of OpenGL does not have this limitation and supports the new Gl_const_color (set a constant color, which takes four components as four components of the factor), Gl_one_minus_const_color, Gl_const_alpha, Gl_ One_minus_const_alpha. There are also gl_src_alpha_saturate. The new version of OpenGL also allows different blending factors for the alpha and RGB values of the color. But none of this is what we need to know now. After all, this is the introductory material, do not need to be too complicated ~

For example:
If you set theGlblendfunc (Gl_one, Gl_zero), which means that the source color is fully used and the target color is not used at all .So the picture effect is consistent with not mixing (of course, the efficiency may be a little bit lower). This is the default setting if the source and target factors are not set.
If you set theGlblendfunc (Gl_zero, gl_one), which means that the source color is not used at all, so no matter what you want to draw, it won't be painted at all.。 (This is not to say that this setting is useless, sometimes it may have a special purpose)
If you set the Glblendfunc (Gl_src_alpha, Gl_one_minus_src_alpha), which indicates that the source color is multiplied by its own ALPHA value, The target color is multiplied by 1.0 minus the alpha value of the source color, so the greater the alpha value of the source color, the greater the percentage of the source color in the new color that is generated, and the smaller the percentage of the target color. In this case, we can simply interpret the alpha value of the source color as "opacity”。 This is also the most common way to mix.
If Glblendfunc (Gl_one, Gl_one) is set, then the source and target colors are fully used, and the final color is actually the simple addition of the two colors. For example Red (1, 0, 0) and green (0, 1, 0) are added (1, 1, 0) and the result is yellow.
Attention:
The so-called source and target colors are related to the order in which they are drawn. If a red object is drawn first, then the Green object is drawn on it. Green is the source color, and red is the target color. If the order is reversed, then red is the source color, and green is the target color. When drawing, you should pay attention to the order so that the source color of the drawing corresponds to the set source factor, and the target color corresponds to the set target factor. Don't get dizzy in a chaotic order.

Three, realize three-dimensional mixing
Maybe you can't wait to draw a three-dimensional scene with a translucent object. But I'm afraid not yet, and one thing to be aware of when mixing three-dimensional scenes is depth buffering.
The depth buffer is a piece of data that records how close each pixel is to the viewer. In the case of deep buffer testing enabled, if the pixels to be drawn are closer than the original pixels, the pixels are drawn. Otherwise, the pixels are ignored and not drawn. This is useful when drawing opaque objects-whether it is drawing near objects first, drawing distant objects, drawing distant objects, drawing near objects, or simply plotting in a chaotic order, and the final result is always near objects that cover far objects.
However, when you need to achieve a translucent effect, you find that everything is not so beautiful. If you draw a translucent object at close range, it retains some information in the depth buffer so that objects in the distance cannot be drawn again. Although translucent objects are still translucent, they do not see the right content through it.
To solve these problems, you need to set the depth buffer to read-only when you draw a translucent object, so that although the translucent object is drawn up, the depth buffer remains in its original state. If another object appears behind a translucent object, it can also be drawn before an opaque object (since the depth of the opaque object is recorded in the depth buffer). To draw an opaque object later, you only need to set the depth buffer to a readable and writable form. Well? You asked me how to draw a part of a translucent part of the opaque object? This is good to do, only need to divide the object into two parts, part of the whole is translucent, part of the whole is opaque, draw separately.
Even with these techniques, we cannot draw in a chaotic order. You must first draw an opaque object and then draw a transparent object. Otherwise, suppose the background is blue, a red glass near, a green object in the middle. If the red translucent glass is drawn first, it is mixed with the blue background, then when the middle green object is drawn in the future, it is not possible to mix with the red glass alone.
In summary, the drawing order is: first, all opaque objects are drawn. If two objects are opaque, then it is no matter who is first. Then, set the depth buffer to read-only. Next, draw all the translucent objects. If two objects are semi-transparent, then who first only need to according to their own wishes (note that the first draw will be "target color", and then the drawing will be "source color", so the order of drawing will have some effect on the result). Finally, the depth buffer is set to a readable writable form.
Call Gldepthmask (gl_false); The depth buffer can be set to read-only form. Call Gldepthmask (gl_true); The depth buffer can be set to a readable writable form.
Some online tutorials, including the famous Nehe tutorials, are used to directly disable the depth buffer when using three-dimensional blending, called gldisable (gl_depth_test). This is not the right thing to do. If you first draw an opaque object and then draw a translucent object behind it, the translucent object behind it will not be displayed (obscured by opaque objects), but if you disable depth buffering, it will still be displayed and blended. Nehe mentioned that some graphics cards may have some problems with the Gldepthmask function, but it may be because I have limited experience and have not found such a situation.

So, the actual demo. Let's draw some translucent and opaque spheres. Suppose there are three spheres, one red opaque, one green translucent, and one blue translucent. Red farthest, green in the middle, blue nearest. The red opaque spheres must be drawn first, and green and blue can be changed in order, depending on what was described earlier. To demonstrate the danger of not setting the depth buffer, we deliberately draw the nearest blue sphere before drawing the green sphere.
To make these spheres a little more stereoscopic, we use light. Set a white light source at (1, 1,-1). The code is as follows:
void SetLight (void) {static const glfloat light_position[] = {1.0f, 1.0f, -1.0f, 1.0f};    static const Glfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};    static const Glfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};    static const Glfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};    GLLIGHTFV (Gl_light0, gl_position, light_position);    GLLIGHTFV (Gl_light0, gl_ambient, light_ambient);    GLLIGHTFV (Gl_light0, Gl_diffuse, Light_diffuse);    GLLIGHTFV (Gl_light0, Gl_specular, light_specular);    Glenable (GL_LIGHT0);    Glenable (gl_lighting); Glenable (gl_depth_test);} Each sphere has a different color. So they all have different textures. Here a function is used to set the material. void setmatirial (const glfloat mat_diffuse[4], glfloat mat_shininess) {static const glfloat mat_specular[] = {0.0f, 0.0    F, 0.0f, 1.0f};    static const Glfloat mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};    GLMATERIALFV (Gl_front, Gl_ambient_and_diffuse, Mat_diffuse);    GLMATERIALFV (Gl_front, Gl_specular, mat_specular); GLMATERIALFV (Gl_front, Gl_emission, Mat_emission); Glmaterialf (Gl_front, gl_shininess, mat_shininess);} With these two functions, we can write the entire program code based on the previous knowledge. Only the part of the drawing is given here, and the rest of us can do it by ourselves.    void Mydisplay (void) {//define some material colors const static Glfloat red_color[] = {1.0f, 0.0f, 0.0f, 1.0f};    Const static Glfloat green_color[] = {0.0f, 1.0f, 0.0f, 0.3333f};    Const static Glfloat blue_color[] = {0.0f, 0.0f, 1.0f, 0.5f}; Clear Screen glclear (Gl_color_buffer_bit |    Gl_depth_buffer_bit);    Start the blending and set the blending factor glenable (gl_blend);    Glblendfunc (Gl_src_alpha, Gl_one_minus_src_alpha);    Set the light source SetLight ();    In the center of (0, 0, 0.5), draw a opaque red sphere with a radius of. 3 (farthest from the observer) Setmatirial (Red_color, 30.0);    Glpushmatrix ();    Gltranslatef (0.0f, 0.0f, 0.5f);    Glutsolidsphere (0.3, 30, 30);    Glpopmatrix ();    The following will draw a translucent object, so the depth buffer is set to read-only gldepthmask (Gl_false);    In the center of (0.2, 0,-0.5), draw a translucent blue sphere with a radius of. 2 (closest to the observer) Setmatirial (Blue_color, 30.0);    Glpushmatrix ();    Gltranslatef (0.2f, 0.0f, -0.5f);    Glutsolidsphere (0.2, 30, 30);    Glpopmatrix (); Take (0.1, 0, 0) as the center, draw a radius of.15 Translucent Green spheres (between the first two spheres) setmatirial (Green_color, 30.0);    Glpushmatrix ();    Gltranslatef (0.1, 0, 0);    Glutsolidsphere (0.15, 30, 30);    Glpopmatrix ();    Complete the drawing of the translucent object and restore the depth buffer to a readable and writable form gldepthmask (gl_true); Glutswapbuffers ();}

  



You can also delete the above two gldepthmask, the result will see the recent blue ball, although translucent, but it is directly behind the red ball, the middle of the green ball is not properly drawn.

Summary:
This lesson describes the knowledge of OpenGL blending capabilities.
Mixing is when drawing, not directly to the new color covering the original old color, but the new color and the old color through a certain operation, resulting in a new color. The new color is called the source color, and the original old color is called the target color. The traditional blend is to multiply the source color by the source factor, the target color multiplied by the target factor, and then the sum.
The source and target factors can be set. The difference between the source factor and the target factor setting directly results in mixed results. Using the alpha value of the source color as the source factor and subtracting the source color alpha value as the target factor by 1.0 is a common way. At this point, the alpha value of the source color corresponds to the effect of opacity. Using this feature, some translucent objects can be drawn.
The order in which they are drawn is important when blending. Because in the drawing, is about to draw the source color, the original existence is the target color, so the first drawn object becomes the target color, later drawn becomes the source color. The order of drawing should be considered clearly, the target color and the set target factor should correspond to the source color and set the source factor corresponds.
In the three-dimensional mixing, not only the source and target factors should be considered, but also the depth buffer should be considered. All opaque objects must be drawn before the translucent objects are drawn. Before you draw a translucent object, you also need to set the depth buffer to read-only, otherwise a screen error may occur.

void Glbindvertexarray (Gluint array);

Binding Vertex Array objects

Array: Specifies the name of the vertex array binding.

Description

glBindVertexArrayBinds the vertex array object with name array . is the name of a vertex array object previously returned from a call to Glgenvertexarrays, or zero array To break the existing vertex array object binding.

If no vertex array object with name array exists, one was array created when is first bound. If The bind is successful no made to the state of the vertex array object, and any previous vertex array object Binding is broken.

Errors

GL_INVALID_OPERATIONis generated if array is isn't zero or the name of a vertex array object previously returned from a call to GlG Envertexarrays.

Common OpenGL functions (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.