OpenGL basic graphics programming-special optical processing

Source: Internet
Author: User
14.1 Illumination Model
The concept of OpenGL illumination model consists of the following three parts: 1) Global extensive intensity; 2) the viewpoint is still near the scene, and 3) whether the front and back of an object are illuminated separately.

  14.1.1 Global Environment light
As mentioned above, each light source can provide ambient light for a scenario. In addition, there is an ambient light, which does not come from any specific light source, that is, global ambient light. The following uses the gl_light_model_ambient parameter to describe the rgba intensity of global ambient light:

Glfloat lmodel_ambient [] = {0.2, 0.2, 0.2, 1.0 };
Gllightmodelfv (gllight_model_ambient, lmodel_ambient );

In this example, the value of lmodel_ambient is the default value of gl_light_model_ambient. These values generate a small amount of white ambient light.

  14.1.2 near point of view and infinite farsighted point
The viewpoint position can affect the calculation of the mirror highlight. That is to say, the height intensity of the vertex depends on the vertex method vector, from the vertex to the light source direction and from the vertex to the viewpoint direction. In fact, you cannot move the viewpoint by calling the illumination function. However, different assumptions can be made for illumination computing, so that the viewpoint seems to move. For an infinitely distant point, the direction from the viewpoint to any vertex remains fixed. By default, the point is infinitely distant. For a near-viewpoint object, the direction from each vertex to the viewpoint is different and needs to be calculated one by one to reduce the overall performance, but the effect is more realistic. The following Function Code assumes myopia:

Gllightmodeli (gl_light_model_local_viewer, gl_true );

This call places the viewpoint at the origin of the viewpoint coordinate system. To switch to an infinitely distant point, you only need to change the parameter gl_true to gl_false.

  14.1.3 dual-sided illumination
Illumination calculation usually applies to all polygon, whether positive or negative. Generally, the front polygon is always used to set illumination conditions. Therefore, the back polygon cannot be correctly illuminated. In the example in chapter 7 of the basics, an object is a ball that can be seen only by the Front polygon, that is, the outside of the ball. In this case, you do not have to consider the back illumination. If the ball is split and the surface inside the ball is visible, You need to calculate the illumination of the internal polygon. The following function should be called:

Gllightmodeli (light_model_two_side, gl_true );

Enable dual-sided illumination. In fact, OpenGL defines an inverse normal vector for the back polygon (relative to the front polygon ). In general, this means that the normal vectors of visible front polygon and visible back polygon face to the observer, rather than inside, so that all polygon can be correctly illuminated. To disable double-sided lighting, you only need to change the parameter gl_true to gl_false.

14.2 Light Source Position and Attenuation
As mentioned in the basics, the light source has two forms: Infinite remote light source and near light source. The infinite remote light source is also called a directed light source, that is, when the light arrives at an object, it is a parallel light, such as the sunlight in real life. The near-light source is also called the positioning light source. The position of the light source in the scene affects the illumination effect of the scene, especially the direction in which the light arrives at the object. Desk Lamp is an example of positioning a light source. In all previous lighting-related examples, a directed light source is used, for example:

Glfloat light_position [] = {1.0, 1.0, 1.0, 0.0 };
Gllightfv (gl_light0, gl_position, light_position );

The homogeneous coordinates (x, y, z, W) are used to coordinate the position of the light source. Here, W is 0, so the corresponding light source is oriented light (x, y, z) describe the direction of the light source. This direction also requires model transformation. The default value of gl_position is (0.0, 0.0, 1.0, 0.0). It defines a parallel light source pointing to the Z negative axis. If W is not zero, the light source is the positioning light source. (X, Y, Z, W) specifies the position of the light source in the homogeneous coordinate system. The position is saved in the viewpoint coordinate system after model transformation.
The farther away from the light source, the smaller the light intensity. Because the directed light source is an infinite remote light source, distance transformation has almost no effect on the light intensity. Therefore, the directed light does not decay, but the positioning light degrades. The light attenuation of OpenGL is calculated by multiplying the light emitting volume of the light source by the attenuation factor. The attenuation factor is described in Chapter 10 Table 10-2. By default, the constant attenuation factor is 1.0, and the other two factors are 0.0. You can also define these values by yourself, such:

Gllightf (gl_light0, gl_constant_attenuation, 2.0 );
Gllightf (gl_light0, gl_linear_attenuation, 1.0 );
Gllightf (gl_light0, gl_quadratic_attenuation, 0.5 );

  Note:: The intensity of ambient light, diffuse light, and mirror light is reduced, and only the intensity of Radiant light and global ambient light is not reduced.

14.3. Concentrating and multi-Light Source

  14.3.1 concentration
The positioning light source can be defined as a spotlight, that is, the shape of the light is limited to a cone. The definition of concentration in OpenGL includes the following steps:
1)Defines the location of a poly (light source) source.. The position of the poly light source is the same as that of the general oriented light source. For example:

Glfloat light_position [] = {1.0, 1.0, 1.0, 1.0 };
Gllightfv (gl_light0, light_position, light_position );

2)Define the concentration cutoff Angle. The angle between the axis and the center line of the Light cone given by the gl_spot_cutoff parameter can also be said to be half of the top angle of the Light cone, as shown in 14-1. This parameter is 180.0, that is, the top angle is 360 degrees. light is emitted to all directions, so the concentration is disabled. Generally, when the concentration starts, the concentration cutoff angle is limited to [0.0, 90.0]. For example, the following code sets the ending angle to 45 degrees:

Gllightf (gl_light0, gl_spot_cutoff, 45.0 );

3)Define concentration direction. The direction of concentration determines the axis of the Light cone, which is defined in the same coordinate. The default value is (0.0, 0.0,-1.0), that is, pointing to the Z negative axis. The direction of concentration must also undergo geometric transformation, and the results are stored in the viewpoint coordinate system. It is defined as follows:

Glfloat spot_direction [] = {-1.0,-1.0, 0.0 };
Gllightfv (gl_light0, gl_spot_direction, spot_direction );

4)Define Concentration Index. The gl_spot_exponent parameter controls the degree of concentration of light. The center of the light Cone has the maximum light intensity, and the light intensity on the edge is smaller. The default value is 0. For example:

Gllightf (gl_light0, gl_spot_exponent, 2.0 );

In addition to defining the concentration index to control the distribution of light intensity in the cone, you can also use the attenuation factor settings described in the previous section, because the attenuation factor is multiplied by the light intensity to obtain the final light intensity value.

  14.3.2 multi-light source and routine
As mentioned above, a maximum of eight light sources can be set in the scenario (based on the specific implementation of OpenGL, there may be more ). In the case of multiple light sources, OpenGL needs to calculate the light intensity of each vertex from each light source, which increases the computing workload and reduces the performance. Therefore, it is best to reduce the number of light sources as much as possible in real-time simulation. We have discussed the constants of eight light sources: gl_light0, gl_light1 ,... , Light7,Note:: The default value of gl_light0 is different from that of other light sources. The following code defines the red concentration:

Glfloat lightmap ambient [] = {0.2, 0.2, 0.2, 1.0 };
Glfloat light=diffuse [] = {1.0, 0.0, 0.0, 1.0 };
Glfloat lightdeskspecular [] = {1.0, 0.6, 0.6, 1.0 };
Glfloat lightfill position [] = {-3.0,-3.0, 3.0, 1.0 };

Glfloat spot_direction [] = {1.0, 1.0,-1.0 };

Gllightfv (gl_light1, gl_ambient, lightmap ambient );
Gllightfv (gl_light1, gl_diffuse, light1_diffuse );
Gllightfv (gl_light1, gl_specular, light1_specular );
Gllightfv (gl_light1, gl_position, light1_position );

Gllightf (gl_light1, gl_spot_cutoff, 30.0 );
Gllightfv (gl_light1, gl_spot_direction, spot_direction );

Glable (gl_light1 );

// This Code describes a red cube that represents the defined concentrating light source //
// Can be added to the display () function of the program. //

Glpushmatrix ();
Gltranslated (-3.0,-3.0, 3.0 );
Gldisable (gl_lighting );
Glcolor3f (1.0, 0.0, 0.0 );
Auxwirecube (0.1 );
Glable (gl_lighting );
Glpopmatrix ();

//////////////////////////////////////// //////////////////////////

Add the code to the illumination routine (light2.c) in Chapter 10 of the basics:

  Example 14-1 Use of concentration and multi-Light Source(Spmulght. c)

# Include "Glos. H"
# Include <Gl/Gl. h>
# Include <Gl/Glu. h>
# Include <Gl/Glaux. h>

Void myinit (void );
Void callback myreshape (glsizei W, glsizei H );
Void callback display (void );

/* Initialize the light source and material */
Void myinit (void)
{
Glfloat mat_ambient [] = {0.2, 0.2, 0.2, 1.0 };
Glfloat mat_diffuse [] = {0.8, 0.8, 0.8, 1.0 };
Glfloat mat_specular [] = {1.0, 1.0, 1.0, 1.0 };
Glfloat mat_shininess [] ={ 50.0 };

Glfloat light0_diffuse [] = {0.0, 0.0, 1.0, 1.0 };
Glfloat light0_position [] = {1.0, 1.0, 1.0, 0.0 };

Glfloat lightmap ambient [] = {0.2, 0.2, 0.2, 1.0 };
Glfloat light=diffuse [] = {1.0, 0.0, 0.0, 1.0 };
Glfloat lightdeskspecular [] = {1.0, 0.6, 0.6, 1.0 };
Glfloat lightfill position [] = {-3.0,-3.0, 3.0, 1.0 };

Glfloat spot_direction [] = {1.0, 1.0,-1.0 };

Glmaterialfv (gl_front, gl_ambient, mat_ambient );
Glmaterialfv (gl_front, gl_diffuse, mat_diffuse );
Glmaterialfv (gl_front, gl_specular, mat_specular );
Glmaterialfv (gl_front, gl_shininess, mat_shininess );

Gllightfv (gl_light0, gl_diffuse, light0_diffuse );
Gllightfv (gl_light0, gl_position, light0_position );

Gllightfv (gl_light1, gl_ambient, lightmap ambient );
Gllightfv (gl_light1, gl_diffuse, light1_diffuse );
Gllightfv (gl_light1, gl_specular, light1_specular );
Gllightfv (gl_light1, gl_position, light1_position );

Gllightf (gl_light1, gl_spot_cutoff, 30.0 );
Gllightfv (gl_light1, gl_spot_direction, spot_direction );

Glable (gl_lighting );
Glable (gl_light0 );
Glable (gl_light1 );
Gldepthfunc (gl_less );
Glenable (gl_depth_test );
}

Void callback display (void)
{
Glclear (gl_color_buffer_bit | gl_depth_buffer_bit );

Glpushmatrix ();
Gltranslated (-3.0,-3.0, 3.0 );
Gldisable (gl_lighting );
Glcolor3f (1.0, 0.0, 0.0 );
Auxwirecube (0.1 );
Glable (gl_lighting );
Glpopmatrix ();

Auxsolidsphere (2.0 );
Glflush ();
}

Void callback myreshape (glsizei W, glsizei H)
{
Glviewport (0, 0, W, H );
Glmatrixmode (gl_projection );
Glloadidentity ();
If (W <= H)
Glortho (-5.5, 5.5,-5.5 * (glfloat) h/(glfloat) W, 5.5 * (glfloat) h/(glfloat) W,
-10.0, 10.0 );
Else
Glortho (-5.5 * (glfloat) W/(glfloat) h, 5.5 * (glfloat) W/(glfloat) H,
-5.5, 5.5,-10.0, 10.0 );
Glmatrixmode (gl_modelview );
Glloadidentity ();
}

Void main (void)
{
Auxinitdisplaymode (aux_single | aux_rgba );
Auxinitposition (0, 0,500,500 );
Auxinitwindow ("spotlight and multi_lights ");
Myinit ();
Auxreshapefunc (myreshape );
Auxmainloop (Display );
}

The program running result is that the ball is illuminated by two light sources, one is blue-oriented light and the other is red light.

Figure 14-1 concentration and multi-Light Source


14.4 control of light source position and direction
The position and direction of the OpenGL light source are the same as those of other geometric elements. Especially when gllight * () is used to describe the position and direction of the light source, the position and direction must go through the current transformation matrix and be stored in the viewpoint coordinate system, note that projection matrix transformation does not work for them. OpenGL can achieve three different effects by adjusting the relative positions of the light source function and the viewpoint transformation function in the program: 1) The position of the light source remains fixed, 2) the light source moves around the static object, 3) the light source moves with the viewpoint.
In the first case, in order to obtain the effect of fixed position of the light source, the position of the light source must be set after all viewpoint and model transformations. In the second case, there are two ways to achieve this effect. One is to set the position of the light source after the model transformation, and the change will modify the position of the light source; the other is to make the object and the viewpoint move around the light source, and the relative light source can move around the object. In the third case, to create a light source that moves along the line of sight, you must set the position of the light source before the Viewpoint Change. The Viewpoint Change affects the light source and the viewpoint in the same way. The following is an example of light source movement:

  Example 14-1 light source movement routine(Mvlight. c)

# Include "Glos. H"
# Include <Gl/Gl. h>
# Include <Gl/Glu. h>
# Include <Gl/Glaux. h>

Void myinit (void );
Void callback movelight (aux_eventrec * event );
Void callback display (void );
Void callback myreshape (glsizei W, glsizei H );

Static int step = 0;

Void callback movelight (aux_eventrec * event)
{
Step = (Step + 15) % 360;
}

Void myinit (void)
{
Glfloat mat_diffuse [] = {0.0, 0.5, 1.0, 1.0 };
Glfloat mat_ambient [] = {0.0, 0.2, 1.0, 1.0 };
Glfloat light_diffuse [] = {1.0, 1.0, 1.0, 1.0 };
Glfloat light_ambient [] = {0.0, 0.5, 0.5, 1.0 };

Glmaterialfv (gl_front_and_back, gl_diffuse, mat_diffuse );
Gllightfv (gl_light0, gl_diffuse, light_diffuse );
Gllightfv (gl_light0, gl_ambient, light_ambient );
Glable (gl_lighting );
Glable (gl_light0 );

Gldepthfunc (gl_less );
Glenable (gl_depth_test );
}

Void callback display (void)
{
Glfloat position [] = {0.0, 0.0, 1.5, 1.0 };

Glclear (gl_color_buffer_bit | gl_depth_buffer_bit );
Glpushmatrix ();
Gltranslatef (0.0, 0.0,-5.0 );

Glpushmatrix ();
Glrotated (gldouble) Step,-1.0, 1.0, 1.0 );
Glrotated (0.0, 1.0, 0.0, 0.0 );
Gllightfv (gl_light0, gl_position, position );

Gltranslated (0.0, 0.0, 1.5 );
Gldisable (gl_lighting );
Glcolor3f (1.0, 1.0, 0.0 );
Auxwiresphere (0.1 );
Glable (gl_lighting );
Glpopmatrix ();

Auxsolidtorus (0.275, 0.85 );
Glpopmatrix ();
Glflush ();
}

Void callback myreshape (glsizei W, glsizei H)
{
Glviewport (0, 0, W, H );
Glmatrixmode (gl_projection );
Glloadidentity ();
Gluperspective (40.0, (glfloat) W/(glfloat) h, 1.0, 20.0 );
Glmatrixmode (gl_modelview );
}

Void main (void)
{
Auxinitdisplaymode (aux_single | aux_rgba );
Auxinitposition (0, 0,500,500 );
Auxinitwindow ("moving light ");
Myinit ();
Auxmousefunc (aux_leftbutton, aux_mousedown, movelight );
Auxreshapefunc (myreshape );
Auxmainloop (Display );
}

The above program running result shows a Blue Circle in the center of the screen. Press the left mouse button to move the light source. A yellow ball represents the light source.

Figure 14-2 light source movement


14.5. Radiant light
The radiant light has been applied in the previous chapter. For more information, see the running effect of the material change routine 10.4.4 (chgmat1.c. It is once again emphasized that by defining an rgba value for gl_emission, an object can look like a light of this color to achieve a special effect. In fact, objects in real life do not emit light except the light source, but we can use this feature to simulate lights and other light sources. The Code is as follows:

Glfloat mat_emission [] = {0.3, 0.3, 0.5, 0.0 };
Glmaterialfv (gl_front, gl_emission, mat_emission );

In this way, the object looks a little luminous. For example, to draw an open desk lamp, you can define the material of a ball into the above form, and create a poly light source inside the ball, so that the light bulb effect will come out.

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.