OpenGL Note 7

Source: Internet
Author: User
Tags emit

Today I want to talk about the basic knowledge of OpenGL. Although there are a lot of content, the organization is clear and there should be no difficulty in understanding it. Even if you do not remember some content, the problem is not big-the light part is a relatively independent content. Its learning can be separated from other aspects, unlike View transformation, which affects many aspects. At the end of the course, an animation demonstration program on the lighting effect is provided. I think everyone will like it.
From a physiological point of view, the eyes see various objects because the light is directly or indirectly directed from them to the eyes. Humans are more responsive to changes in light intensity than to changes in color. Therefore, for humans, light is very much a manifestation of the three-dimensional sense of an object.
See figure 1. Two white sphere of the same size are drawn. The one on the right is without any illumination effect, and it looks like a two-dimensional disc with no stereoscopic feeling. The one on the left uses a simple illumination effect. We can easily think of it as a three-dimensional object through the illumination hierarchy.

Figure 1

OpenGL provides direct support for lighting effects. You only need to call some functions to achieve simple lighting effects. However, before that, we need to understand some basic knowledge.
1. Establish a illumination model
In real life, some objects will emit light, such as the sun and electric lights. Although other objects do not emit light, they can reflect the light from other objects. These lights spread in various ways and finally enter our eyes-so a picture is formed in our eyes.
As far as computers are concerned, it is impossible to accurately simulate the propagation of various kinds of light. For example, in a room with four sides of a rough wall, the light emitted by an electric lamp passes through many reflections in a short time, and is almost filled with every corner of the room, this process cannot be accurately simulated even with the fastest computer. However, we do not need to accurately simulate various kinds of light. We only need to find an approximate calculation method so that the final result of it makes our eyes think that it is true, this is fine.
OpenGL uses this approximation when processing illumination: the illumination system is divided into three parts: light source, material and illumination environment. The light source is the source of light, which can be the previously mentioned sun or lamp. Material refers to the surface of various objects that receive light. Because how an object reflects light is determined only by the surface of the object (the refraction of light is not considered in OpenGL ), the material characteristics determine the characteristics of the light reflected by the object. Lighting environment refers to some additional parameters that will affect the final lighting screen. For example, after multiple reflections of some light, it is impossible to tell which light source it is sent from, specify an environment brightness parameter to bring the final image closer to the actual situation.
In physics, if light is injected into an ideal smooth plane, the light after reflection is quite regular (such reflection is called a mirror reflection ). If light is injected into a rough, non-smooth plane, the light after reflection is messy (such reflection is called diffuse reflection ). Objects in real life do not have absolute mirror reflection or diffuse reflection when reflecting light, but they can be seen as the superposition of these two kinds of reflection. For the light emitted by the light source, you can set the light intensity after the mirror reflection and diffuse reflection respectively. For materials illuminated by light, you can also set the light intensity after the light passes through the mirror reflection and diffuse reflection respectively. These factors combine to form the final illumination effect.

2. Normal vector
According to the light reflection law, the light's outbound direction can be obtained from the light's incident direction and the normal of the incident point. Therefore, after a light source is specified for a specified object, the reflection direction of the light source can be calculated to calculate the image of the light source effect. In OpenGL, the direction of the normal is expressed by a vector.
Unfortunately, OpenGL does not calculate the normal of each vertex on the surface of the object composed of these polygon based on the vertices of the polygon you specify (this sounds a bit confusing ), generally, to achieve illumination, you need to specify its normal vector for each vertex in the code.
The method of specifying the normal vector is similar to that of specifying the color. When specifying a color, you only need to specify the color of each vertex. OpenGL can calculate the color of other vertices on its own. In addition, once the color is specified, unless a new color is specified, all vertices in the future will use this amount as their own color. When specifying a normal vector, you only need to specify the normal vector of each vertex. OpenGL will calculate the normal vector of other points between the vertex. In addition, once the normal vector is specified, unless a new normal vector is specified, all vertices specified in the future will use this constant amount as their own normal vector. The glColor * function can be used to specify the color, while the glNormal * function can be used to specify the normal vector.
Note: The glTranslate * function or glRotate * function can change the appearance of an object, but the normal vector does not change. However, using the glScale * function to scale each coordinate axis to varying degrees may lead to incorrect normal vectors. Although OpenGL provides some measures to correct this problem, but it also brings about various expenses. Therefore, when using a normal vector, try to avoid using the glScale * function. Even if used, it is best to ensure proportional scaling of each coordinate axis.
3. Control light source
In OpenGL, only a limited number of light sources are supported. Use GL_LIGHT0 to represent the 0th light source, GL_LIGHT1 to represent the 1st Light Source, and so on. OpenGL supports at least eight light sources, that is, GL_LIGHT0 to GL_LIGHT7. You can enable these functions using the glEnable function. For example, glable (GL_LIGHT0); can enable light source 0th. You can use the glDisable function to disable the light source. Some OpenGL implementations may support more light sources, but in general, enabling too many light sources will lead to a serious reduction in the program running speed. Some friends who have played 3D Mark may also have some experience. In some scenarios, there may be hundreds of thousands of electric lights. In this case, some similar approaches may be required for programming. Otherwise, such a program cannot run on the current computer.
Each light source can be set with its properties. This action is completed using the glLight * function. The glLight * function has three parameters. The first parameter indicates which light source is set, and the second parameter indicates which property is set for the light source, the third parameter specifies the value of the attribute. There are many attributes of the light source, which will be described below.
(1) GL_AMBIENT, GL_DIFFUSE, and GL_SPECULAR attributes. These three attributes indicate the reflection (and color) of the light emitted by the light source ). Each attribute is represented by four values, representing the R, G, B, and A values of the color respectively. GL_AMBIENT indicates the light emitted by the light source. After many reflections, the light intensity (color) remains in the entire illumination environment ). GL_DIFFUSE indicates the light emitted by the light source. The light intensity (color) is obtained by diffuse reflection when it is exposed to a rough surface ). GL_SPECULAR indicates the intensity (color) of the light emitted by the light source, which is reflected by a mirror when it is shining on a smooth surface ).
(2) GL_POSITION attribute. The position of the light source. It is represented by four values (X, Y, Z, W. If the fourth value of W is zero, it indicates that the light source is in an infinite distance, and the first three values indicate the direction of the light source. This type of light source is called a directional light source. Generally, the sun can be considered as a directional light source. If the fourth value W is not zero, X/W, Y/W, Z/W represent the position of the light source. This type of light source is called a positional light source. For positional light sources, the method for setting their positions is similar to that for setting polygon vertices. Various matrix transformation functions such as glTranslate * and glRotate * are also effective here. The direction light source is much faster than the position light source in computing. Therefore, the direction light source should be used as much as possible when the visual effect permits.
(3) GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, and GL_SPOT_CUTOFF attributes. Indicates that a light source is used as a Spotlight (these properties are only valid for a positional light source ). Many light sources emit light in all directions, but sometimes some light sources only emit light in a certain direction. For example, a flashlight only emits light at a small angle. The GL_SPOT_DIRECTION attribute has three values, indicating a vector, that is, the direction of light source emission. The GL_SPOT_EXPONENT attribute has only one value, indicating the degree of concentration. If it is set to zero, it indicates that the intensity of light emitted to each direction is the same. If it is a positive value, it indicates that the light is centralized to the center, it is receiving more light from the position in the direction of transmission, and less light from other locations. The larger the value, the more obvious the concentration effect. The GL_SPOT_CUTOFF attribute also has only one value, indicating an angle, which is half of the angle covered by the light source emitting light (see figure 2). The value range is between 0 and 90, you can also take the special value 180. When the value is 180, it indicates that the light source emits 360 degrees of light, that is, the spotlight is not used and the light is sent to the entire surrounding area.

Figure 2

(4) GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, and GL_QUADRATIC_ATTENUATION attributes. These three properties represent the linear propagation of light emitted by a light source (these properties are only valid for a positional light source ). In real life, the intensity of light decreases with the increase of distance. OpenGL abstracts this weakening trend into a function:
Attenuation factor = 1/(k1 + k2 * d + k3 * k3 * d)
D indicates the distance, and the initial intensity of the light is multiplied by the attenuation factor to obtain the light intensity of the corresponding distance. K1, k2, and k3 are GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, and GL_QUADRATIC_ATTENUATION. By setting these three constants, we can control the weakening trend of light in the propagation process.

There are still a lot of attributes. Of course, if you use a directional light source, (3) (4) These two types of attributes will not be used, and the problem will become simple and clear.
4. Control materials
Materials are similar to light sources, and many attributes need to be set. The difference is that the light source is set through the glLight * function, while the material is set through the glMaterial * function.
The glMaterial * function has three parameters. The first parameter indicates the attribute of the specified side. It can be GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK. The material of the front, back, or both sides are set. (For more information about "front" and "back", see the content of the previous courses.) parameters 2 and 3 serve the same purpose as parameters 2 and 3 of the glLight * function. The following describes the material attributes that can be specified by the glMaterial * function.
(1) GL_AMBIENT, GL_DIFFUSE, and GL_SPECULAR attributes. These three attributes are similar to the three corresponding properties of the light source. Each attribute is composed of four values. GL_AMBIENT indicates the light intensity (color) that is left in the environment after many reflections ). GL_DIFFUSE indicates the light intensity (color) formed by diffuse reflection when the light is shining on the material ). GL_SPECULAR indicates the light intensity (color) formed after the light is reflected on the mirror ). Generally, GL_AMBIENT and GL_DIFFUSE take the same value to achieve a more realistic effect. You can use GL_AMBIENT_AND_DIFFUSE to set the GL_AMBIENT and GL_DIFFUSE attributes at the same time.
(2) GL_SHININESS attribute. This attribute has only one value, called the "mirror Index". The value range is 0 to 128. The smaller the value, the rougher the material, and the light emitted by the point light source can also generate a large highlight. The larger the value, the more similar the material to the Mirror, the light source after irradiation to the above, produce a small highlight.
(3) GL_EMISSION attribute. This attribute is composed of four values, indicating a color. OpenGL believes that the material itself emits light slightly outward, so that the eyes feel that it has such a color, but the light is so weak that it will not affect the color of other objects.
(4) GL_COLOR_INDEXES attribute. This attribute is only used in the color index mode. Because the illumination in the color index mode is more complex than that in the RGBA mode, and the usage range is small, we will not discuss it here.
5. Select the illumination model
The "illumination model" mentioned here is the term of OpenGL, which is equivalent to the "illumination environment" we mentioned earlier ". In OpenGL, the illumination model consists of four parts: Global ambient light (that is, the light from which the light source cannot be determined if it is fully scattered) the intensity of the image, whether the position of the observation point is near or infinitely distant, and whether the illumination and mirror color are calculated respectively on the front and back of the object (that is, the color specified by the GL_SPECULAR attribute) is the calculation separated from other illumination calculations and applied after texture operations.
The above four aspects are all set through the same function glLightModel. This function has two parameters: the first parameter indicates the project to be set and the second parameter indicates the value to be set.
GL_LIGHT_MODEL_AMBIENT indicates the global ambient light intensity, which consists of four values.
GL_LIGHT_MODEL_LOCAL_VIEWER indicates whether to watch in the near future. If so, it is set to GL_TRUE; otherwise (that is, watching in the infinite distance) it is set to GL_FALSE.
GL_LIGHT_MODEL_TWO_SIDE indicates whether to perform double-sided illumination calculation. If it is set to GL_TRUE, OpenGL will not only calculate the front illumination based on the normal vector, but also reverse the normal vector and calculate the back illumination.
GL_LIGHT_MODEL_COLOR_CONTROL indicates the color calculation method. If it is set to GL_SINGLE_COLOR, the operation is performed in the normal order. The illumination is calculated first, and then the texture is calculated. If it is set to GL_SEPARATE_SPECULAR_COLOR, the GL_SPECULAR attribute is separated. The rest of the illumination is calculated first, and GL_SPECULAR is calculated after the texture operation is complete. The latter can usually make the image more realistic (of course, if you do not perform any texture operations, such separation does not make any sense ).

6. Final preparation
Now it can be said that everything is complete. However, OpenGL disables illumination by default. To enable the light processing function, use the following statement:
Glable (GL_LIGHTING );
To disable the light processing function, use glDisable (GL_LIGHTING.
VII. Sample program
Now, we can write a simple OpenGL program that uses light.
We still use the sun and the Earth as an example (this time we will not consider the Moon ^-^), and use the sun as the light source to simulate the changes in the time when the Earth rotates around the sun. Therefore, you need to set a light source, the sun, and the sun and the Earth. Set the sun light to white, and the position is in the center of the screen. Set the Sun material to emit a red light, set the earth material to emit a pale blue light, and reflect the blue light, the mirror index is set to a relatively small value. For the sake of simplicity, we will not consider the relationship between the sun and the Earth. We will replace it with a sphere of the same size.
About the normal vector. The normal vector at any point on the sphere surface is the vector from the ball center to the point. If you use the glusolidsphere function to draw a sphere, this function automatically specifies these normal vectors without manual pointing out. If you specify a number of vertices to draw a sphere, you must specify that the normal is loud.
Since the sun we use is a positional light source, we need to use matrix transformation when setting its position. Therefore, you must set various matrices before setting the position of the light source. Use the gluPerspective function to create a view with a perspective effect. We will also use the animation knowledge learned in the previous course to make the whole picture move.

The code below is as follows:
# Include <gl/glut. h>

# Define WIDTH 400
# Define HEIGHT 400

Static GLfloat angle = 0.0f;

Void myDisplay (void)

// Create a view
GlMatrixMode (GL_PROJECTION );
GlLoadIdentity ();
GluPerspective (90.0f, 1.0f, 1.0f, 20366f );
GlMatrixMode (GL_MODELVIEW );
GlLoadIdentity ();
GluLookAt (0.0, 5.0,-10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );

// Defines the sun light source, which is a white light source.
GLfloat sun_light_position [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat sun_light_ambient [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat sun_light_diffuse [] = {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat sun_light_specular [] = {1.0f, 1.0f, 1.0f, 1.0f };

GlLightfv (GL_LIGHT0, GL_POSITION, sun_light_position );
GlLightfv (GL_LIGHT0, GL_AMBIENT, sun_light_ambient );
GlLightfv (GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse );
GlLightfv (GL_LIGHT0, GL_SPECULAR, sun_light_specular );

Glable (GL_LIGHT0 );
Glable (GL_LIGHTING );
GlEnable (GL_DEPTH_TEST );

// Define the Sun material and draw the Sun
GLfloat sun_mat_ambient [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat sun_mat_diffuse [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat sun_mat_specular [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat sun_mat_emission [] = {0.5f, 0.0f, 0.0f, 1.0f };
GLfloat sun_mat_shininess = 0.0f;

GlMaterialfv (GL_FRONT, GL_AMBIENT, sun_mat_ambient );
GlMaterialfv (GL_FRONT, GL_DIFFUSE, sun_mat_diffuse );
GlMaterialfv (GL_FRONT, GL_SPECULAR, sun_mat_specular );
GlMaterialfv (GL_FRONT, GL_EMISSION, sun_mat_emission );
GlMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess );

Glusolidsphere (2.0, 40, 32 );

// Define the material of the Earth and draw the Earth
GLfloat earth_mat_ambient [] = {0.0f, 0.0f, 0.5f, 1.0f };
GLfloat earth_mat_diffuse [] = {0.0f, 0.0f, 0.5f, 1.0f };
GLfloat earth_mat_specular [] = {0.0f, 0.0f, 1.0f, 1.0f };
GLfloat earth_mat_emission [] = {0.0f, 0.0f, 0.0f, 1.0f };
GLfloat earth_mat_shininess = 30366f;

GlMaterialfv (GL_FRONT, GL_AMBIENT, earth_mat_ambient );
GlMaterialfv (GL_FRONT, GL_DIFFUSE, earth_mat_diffuse );
GlMaterialfv (GL_FRONT, GL_SPECULAR, earth_mat_specular );
GlMaterialfv (GL_FRONT, GL_EMISSION, earth_mat_emission );
GlMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess );

GlRotatef (angle, 0.0f,-1.0f, 0.0f );
GlTranslatef (5.0f, 0.0f, 0.0f );
Glusolidsphere (2.0, 40, 32 );

Gluswapbuffers ();
Void myIdle (void)
Angle + = 1.0f;
If (angle> = 360.0f)
Angle = 0.0f;
MyDisplay ();

Int main (int argc, char * argv [])
Gluinit (& argc, argv );
Fig );
Gluinitwindowposition (200,200 );
Gluinitwindowsize (WIDTH, HEIGHT );
Ngcreatewindow ("OpenGL lighting demonstration ");
Gludisplayfunc (& myDisplay );
GlutIdleFunc (& myIdle );
Glumainloop ();
Return 0;
This section describes the basic knowledge of OpenGL. OpenGL divides illumination into three parts: light source, material, and illumination mode. Based on the various information of the three parts and the normal vector of the object surface, the final illumination effect can be calculated.
Light sources, materials, and lighting modes all have their own attributes. Despite the wide variety of attributes, these attributes are only set using a few functions. Use the glLight * function to set the properties of the light source. Use the glMaterial * function to set the properties of the material, and use the glLightModel * function to set the lighting mode.
The GL_AMBIENT, GL_DIFFUSE, and GL_SPECULAR attributes are shared by the light source and material. If the light emitted by a light source shines on the surface of a certain material, the final diffuse reflection intensity is jointly determined by the two GL_DIFFUSE attributes, and the final mirror reflection intensity is jointly determined by the two GL_SPECULAR attributes.
Multiple light sources can be used to achieve a variety of lifelike effects. However, increasing the number of light sources will significantly reduce the running speed.
In the process of using OpenGL for illumination, there are many types and quantities of attributes. Generally, you need a lot of experience to skillfully set various attributes to form a realistic illumination effect. (You can also see that attribute settings are not very good in the example program of this course ). However, the artistic nature of setting these attributes far exceeds the technical level. It is often because some art producers set various attributes (and save them as files), and then programs compiled by programmers can execute the rendering work. Therefore, you do not have to worry too much even if you are not proficient in using various attributes. If conditions permit, you can play with software like 3DS MAX, which helps you understand lighting and familiarize yourself with various attribute settings.
At the end of the course, we provided an example program to demonstrate the illumination effect in the sun and Earth models.

OpenGL Note 7

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: 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.