preface
Some time ago, OpenGL will be used in engineering for some rendering and modeling operations. In the future, this column will be updated to explain the application of typical opengl functions and structures in the way of the highest signal-to-noise ratio. Through this hand-in-hand way, I believe it is the fastest way for novice friends to learn. This column will take care of you, so that you can start to change something and see the effect. In my opinion, this is the most efficient learning method.
Large structure of rendering and modeling code of OpenGL
Since OpenGL is generally only an intermediate processing process in a piece of code, the whole OpenGL operation will be put into one function, and the code structure in the future will be roughly the same as here.
Generally, a typical OpenGL processing fragment includes the following steps:
- Initialize the display mode (RGB mode, double buffer mode).
- Initializes the position of the display window.
- Initializes the size of the display window.
- Set the OpenGL display function.
- Count and timing related to calls that need to change dynamically
- Main function loop.
When setting the OpenGL display function, there are the following typical steps:
- Clear screen and cache
- Define transformation type (previous) article (yes)
- Set camera parameters (viewport transformation)
- Set observation position
- Set light source
- Define object material
- Set buffer swap
Key function analysis
Set camera parameters (viewport transformation)
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f); //Viewport transformation
Set camera parameters void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
aspect indicates the width w height h ratio of the cutting surface, which affects the size of the section of the field of view.
fovy is the amplitude of the eye opening up and down, and the angle value. The smaller the value, the narrower the field of vision (squinting), and the larger the value, the wider the field of vision (opening the big eyes like copper bells);
zNear represents the distance from the near clipping surface to the eye, and zFar represents the distance from the far clipping surface to the eye. Note that zNear and zFar cannot be set to negative values (how can you see things behind the eyes).
Set observation position
gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
gluLookAt is used to define the state of the observer (camera), including the position of the observer in the world coordinate system, the direction of looking in the world coordinate system (which can be understood as the direction of the eye), and the orientation of the observer's head (which can rotate 360 ° on a plane)
void gluLookAt (
GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz);
The first, second and third parameters define the position coordinates of the camera in the world coordinate system
The fourth, fifth and sixth parameters define the position coordinates of the point in the world coordinate system facing the camera. After imaging, this point will be located in the center of the drawing board
The 79th parameter defines the orientation of the camera itself. These three coordinates are the coordinate points in the world coordinate system, which can be understood as the orientation of human head standing at the camera. These three coordinates are the coordinate points in the world coordinate system, not the camera coordinate system, but used to define the direction. Note that this is not the direction of the line of sight (lens), but the direction of the camera itself when placed, which is perpendicular to the direction of the line of sight.
It is easy to understand these parameters from the perspective of the observer.
The first set of parameters defines how far a person stands from an object,
The second set of parameters is to define the direction in which the human eye looks in the world coordinate system. Sometimes there is nothing black on the screen. It may be that the direction of this set of parameters is wrong, and the object may be not far behind you
The third set of parameters is the person's orientation, which also represents a direction, which is perpendicular to the line of sight.
It should always be clear that the world coordinate system in openGL is the right-hand coordinate system. On the two-dimensional screen, the horizontal direction of the screen is the x-axis direction, the right direction is positive, the vertical direction of the screen is the Y-axis direction, the upward direction is positive, the direction perpendicular to the screen is the Z-axis direction, and the outward direction from the screen is positive.
Define light source
GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Residual strength GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Diffuse reflection intensity GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Specular Roll Off GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Light source location glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);//GL_LIGHT0: the definition of No. 0 light source. A total of 8 light sources can be defined glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST);
(1)GL_AMBIENT,GL_DIFFUSE,GL_ Special attribute. These three attributes represent the reflection characteristics (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.
GL_AMBIENT represents the intensity (color) of the light emitted by the light source, which is finally left in the whole lighting environment after many reflections.
GL_DIFFUSE indicates the intensity (color) of the light emitted by the light source after diffuse reflection when it shines on the rough surface.
GL_ Special represents the intensity (color) of the light emitted by the light source after specular reflection when it shines on a smooth surface.
(2)GL_POSITION attribute. Indicates the location of the light source. Represented by four values (X, Y, Z, W).
If the fourth value W is zero, it indicates that the light source is infinitely far away, and the first three values indicate its direction.
This kind of light source is called directional light source. Generally, the sun can be approximately considered as 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 kind of light source is called positional light source.
For positional lighting, setting its position is similar to setting polygon vertices. Various matrix transformation functions such as glTranslate *, glRotate * are also effective here. Directional light source is much faster than positional light source in calculation. Therefore, directional light source should be used as much as possible when visual effect allows.
(3)GL_SPOT_DIRECTION,GL_SPOT_EXPONENT,GL_SPOT_CUTOFF attribute.
Indicates that the light source is used as a spotlight (these attributes are valid only for positional lights).
Many light sources emit light in all directions, but sometimes some light sources only emit light in one direction, such as a flashlight, only at a small angle.
GL_ SPOT_ The direction attribute has three values that represent a vector, the direction in which the light source emits.
GL_ SPOT_ The exponent attribute has only one value, which indicates the degree of concentration. When it is zero, it indicates that the light emitted in all directions within the illumination range has the same intensity. When it is positive, it indicates that the light is concentrated in the center. The position facing the emission direction receives more light, and other positions receive less light.
The higher the value, the more obvious the focusing effect.
GL_ SPOT_ The cutoff attribute also has only one value, which represents an angle. It is half of the angle covered by the light emitted by the light source. Its value range is between 0 and 90, and the special value of 180 can also be taken. When the value is 180, it means that the light emitted by the light source covers 360 degrees, that is, it is emitted to the whole environment without using the spotlight.
(4)GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_ QUADRATIC_ Attribute attribute.
These three attributes represent the linear propagation characteristics of the light emitted by the light source (these attributes are only valid for positional light sources).
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)
Where d is the distance, and the light intensity corresponding to the distance is obtained by multiplying the initial intensity of the light by the attenuation factor.
K1, K2 and K3 are GL respectively_ CONSTANT_ ATTENUATION, GL_ LINEAR_ ATTENUATION, GL_ QUADRATIC_ ATTENUATION. By setting these three constants, we can control the weakening trend of light in the process of propagation.
There are a lot of attributes. Of course, if directional light sources are used, (3) (4) these two attributes will not be used, and the problem becomes simple and clear.
Define material
GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f}; //Similar to light GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f}; //Similar to lighting, usually GL_AMBIENT and GL_DIFFUSE takes the same value, which can achieve a more real effect GLfloat sun_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f}; //Specular reflection GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f}; //Emitting a faint red light GLfloat sun_mat_shininess = 30.0f; //0-128 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); glutSolidSphere(2.0, 40, 32);
Control material:
Materials are similar to light sources, and many properties 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 that specifies which side. Can be GL_FRONT,GL_BACK or GL_FRONT_AND_BACK.
It means to set the material of "front" and "back" respectively, or set both sides at the same time. The second and third parameters are similar to the second and third parameters of glLight * function.
The following describes the material properties that can be specified by the glMaterial * function.
(1)GL_AMBIENT,GL_DIFFUSE,GL_ Special attribute.
These three attributes are similar to the three corresponding attributes of a light source, and each attribute consists of four values.
GL_AMBIENT indicates the intensity (color) of various light rays shining on the material and finally left in the environment after many reflections.
GL_DIFFUSE refers to the intensity (color) of the light after diffuse reflection when the light shines on the material.
GL_SPECULAR indicates the intensity (color) of the light after specular reflection when the light shines on the material.
In general, GL_AMBIENT and GL_DIFFUSE takes the same value, which can achieve a more real effect.
Use GL_AMBIENT_AND_DIFFUSE can set GL at the same time_ Ambient and GL_DIFFUSE property.
(2)GL_ Shinness property.
This attribute has only one value, called "specular index", which ranges from 0 to 128.
The smaller the value is, the coarser the material is. When the light emitted by the point light source shines on it, it can also produce large bright spots.
The higher the value, the more similar the material is to the mirror. When the light source shines on it, it will produce smaller highlights.
(3)GL_ The event property.
The attribute consists of four values that represent 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 property.
This attribute is only used in the color index mode. Since the illumination in the color index mode is more complex than that in the RGBA mode and the scope of use is smaller, it will not be discussed here.
Complete code
#include <gl/glut.h> #define WIDTH 800 #define HEIGHT 600 static GLfloat angle = 0.0f; void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear screen and depth cache // Create perspective view glMatrixMode(GL_PROJECTION); //Declare that the current projection transformation is in progress, GL_MODELVIEW: model transformation, GL_ Project: projection transformation glLoadIdentity(); //Reset the current model observation matrix gluPerspective(90.0f, 1.0f, 1.0f, 20.0f); //Viewport transformation /* Set camera parameters void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) aspect Indicates the width w height h ratio of the clipping surface, which affects the cross-section of the field of view. fovy Is the amplitude of the eyes opening up and down, and the angle value. The smaller the value, the narrower the field of vision (squinting), and the larger the value, the wider the field of vision (opening the big eyes like copper bells); zNear Indicates the distance from the near clipping surface to the eyes, and zFar indicates the distance from the far clipping surface to the eyes. Note that zNear and zFar cannot be set to negative values (how can you see things behind the eyes). */ glMatrixMode(GL_MODELVIEW); //Declare that a model transformation is currently in progress glLoadIdentity(); gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); /* Set observation position gluLookAt It is used to define the state of the observer (camera), including the position of the observer in the world coordinate system, the direction of looking in the world coordinate system (which can be understood as the direction of the eye), and the orientation of the observer's head (which can rotate 360 ° on a plane) void gluLookAt ( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz); The first, second and third parameters define the position coordinates of the camera in the world coordinate system The fourth, fifth and sixth parameters define the position coordinates of the point in the world coordinate system facing the camera. After imaging, this point will be located in the center of the drawing board The 79th parameter defines the orientation of the camera itself. These three coordinates are the coordinate points in the world coordinate system, which can be understood as the orientation of human head standing at the camera. These three coordinates are the coordinate points in the world coordinate system, not the camera coordinate system, but used to define the direction. Note that this is not the direction of the line of sight (lens), but the direction of the camera itself when placed, which is perpendicular to the direction of the line of sight. It is easy to understand these parameters from the perspective of the observer. The first set of parameters defines how far a person stands from an object, The second set of parameters is to define the direction in which the human eye looks in the world coordinate system. Sometimes there is nothing black on the screen. It may be that the direction of this set of parameters is wrong, and the object may be not far behind you The third set of parameters is the person's orientation, which also represents a direction, which is perpendicular to the line of sight. It should always be clear that the world coordinate system in openGL is the right-hand coordinate system. On the two-dimensional screen, the horizontal direction of the screen is the x-axis direction, the right direction is positive, the vertical direction of the screen is the Y-axis direction, the upward direction is positive, the direction perpendicular to the screen is the Z-axis direction, and the outward direction from the screen is positive. */ { GLfloat other_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Residual strength GLfloat other_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Diffuse reflection intensity GLfloat other_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Specular Roll Off GLfloat other_light_position[] = {0.0f, 0.0f, 10.0f, 1.0f}; //Light source location glLightfv(GL_LIGHT1, GL_POSITION, other_light_position);//GL_LIGHT1: definition of No. 1 light source. A total of 8 light sources can be defined glLightfv(GL_LIGHT1, GL_AMBIENT, other_light_ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, other_light_diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, other_light_specular); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); } // Defines the solar light source, which is a white light source { GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Residual strength GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Diffuse reflection intensity GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; //Specular Roll Off GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Light source location /* (1)GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR Properties. These three attributes represent the reflection characteristics (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. GL_AMBIENT Represents the intensity (color) of the light emitted by the light source, which is finally left in the whole lighting environment after many reflections. GL_DIFFUSE Indicates the intensity (color) of the light emitted by the light source after diffuse reflection when it shines on the rough surface. GL_SPECULAR Represents the intensity (color) of the light emitted by the light source after specular reflection when it shines on a smooth surface. (2)GL_POSITION Properties. Indicates the location of the light source. Represented by four values (X, Y, Z, W). If the fourth value W is zero, it indicates that the light source is infinitely far away, and the first three values indicate its direction. This kind of light source is called directional light source. Generally, the sun can be approximately considered as 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 kind of light source is called positional light source. For positional lighting, setting its position is similar to setting polygon vertices. Various matrix transformation functions such as glTranslate *, glRotate * are also effective here. Directional light source is much faster than positional light source in calculation. Therefore, directional light source should be used as much as possible when visual effect allows. (3)GL_SPOT_DIRECTION,GL_SPOT_EXPONENT,GL_SPOT_CUTOFF Properties. Indicates that the light source is used as a spotlight (these attributes are valid only for positional lights). Many light sources emit light in all directions, but sometimes some light sources only emit light in one direction, such as a flashlight, only at a small angle. GL_SPOT_DIRECTION The attribute has three values that represent a vector, the direction in which the light source emits. GL_SPOT_EXPONENT The attribute has only one value, which indicates the degree of concentration. When it is zero, it indicates that the intensity of light emitted in all directions within the illumination range is the same. When it is positive, it indicates that the light is concentrated in the center. The position facing the emission direction receives more light, and other positions receive less light. The higher the value, the more obvious the focusing effect. GL_SPOT_CUTOFF The attribute also has only one value, representing an angle, which is half of the angle covered by the light emitted by the light source. Its value range is between 0 and 90, or the special value of 180 can be taken. When the value is 180, it means that the light emitted by the light source covers 360 degrees, that is, it is emitted to the whole environment without using the spotlight. (4)GL_CONSTANT_ATTENUATION,GL_LINEAR_ATTENUATION,GL_QUADRATIC_ATTENUATION Properties. These three attributes represent the linear propagation characteristics of the light emitted by the light source (these attributes are only valid for positional light sources). 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) Where d is the distance, and the light intensity corresponding to the distance is obtained by multiplying the initial intensity of the light by the attenuation factor. k1, k2, k3 They are GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION. By setting these three constants, we can control the weakening trend of light in the process of propagation. There are a lot of attributes. Of course, if directional light sources are used, (3) (4) these two attributes will not be used, and the problem becomes simple and clear. */ glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);//GL_LIGHT0: the definition of No. 0 light source. A total of 8 light sources can be defined glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); } // Define the material of the sun and paint the sun { GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f}; //Similar to light GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f}; //Similar to lighting, usually GL_AMBIENT and GL_DIFFUSE takes the same value, which can achieve a more real effect GLfloat sun_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f}; //Specular reflection GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f}; //Emitting a faint red light GLfloat sun_mat_shininess = 30.0f; //0-128 /* Control material: Materials are similar to light sources, and many properties 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. glMaterial*The function has three arguments. The first parameter indicates the attribute that specifies which side. Can be GL_FRONT,GL_BACK or GL_FRONT_AND_BACK. It means to set the material of "front" and "back" respectively, or set both sides at the same time. The second and third parameters are similar to the second and third parameters of glLight * function. The following describes the material properties that can be specified by the glMaterial * function. (1)GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR Properties. These three attributes are similar to the three corresponding attributes of a light source, and each attribute consists of four values. GL_AMBIENT It refers to the light intensity (color) left in the environment after many reflections of various light rays on the material. GL_DIFFUSE Indicates the light intensity (color) formed after diffuse reflection when the light shines on the material. GL_SPECULAR It indicates the light intensity (color) formed after specular reflection when the light shines on the material. In general, GL_AMBIENT and GL_DIFFUSE takes the same value, which can achieve a more real effect. Use GL_AMBIENT_AND_DIFFUSE can set GL at the same time_ Ambient and GL_DIFFUSE property. (2)GL_SHININESS Properties. This attribute has only one value, called "specular index", which ranges from 0 to 128. The smaller the value is, the coarser the material is. When the light emitted by the point light source shines on it, it can also produce large bright spots. The higher the value, the more similar the material is to the mirror. When the light source shines on it, it will produce smaller highlights. (3)GL_EMISSION Properties. The attribute consists of four values that represent a color. OpenGL It is considered that the material itself emits light slightly, 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 Properties. This attribute is only used in the color index mode. Since the illumination in the color index mode is more complex than that in the RGBA mode and the scope of use is smaller, it will not be discussed here. */ 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); glutSolidSphere(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 = 30.0f; 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); glutSolidSphere(2.0, 40, 32); } glutSwapBuffers(); } void myIdle(void) { angle += 1.0f; if( angle >= 360.0f ) angle = 0.0f; myDisplay(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(200, 200); glutInitWindowSize(WIDTH, HEIGHT); glutCreateWindow("OpenGL Lighting demonstration"); glutDisplayFunc(&myDisplay); glutIdleFunc(&myIdle); glutMainLoop(); return 0; }
effect
Readers can also modify the above properties and other parameters to try to get different effects.
(please contact me in time for correction if the above content is incorrect, thank you!)