Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie
Discuss newsgroups and documents
Technorati labels: hidden surface Elimination
, Deep Test
, Fog
, OpenGL
, Depth Test
, Fog hidden surface elimination (deep test)
In fact, this is a lagging topic. In fact, it should be detailed in the lighting section, but it was not involved at the time because there were too many illumination contents.
When we fill in a 3D object, it is different from the plane, because it involves the problem that the previous object blocks the objects behind it. If there is no good built-in mechanism, we can only remember the Z axis of each object through the Program (in fact, it is not necessarily the Z axis, look at the Observed Direction at that time), and then draw the distant object first in order, then draw the object that is close to us. In this way, we can draw the object that is close to us and overwrite the object that is far away.
Of course, this is not a problem if you think it is not difficult, but if these things are implemented by hardware, the efficiency will go up to a level, so OpenGL also provides this method, it is called a deep test. (Depth test) it is quite simple to use. You only need to enable it through glenable. Now let's look at the differences before and after use.
We use the following function to draw a small ball and a small ball.
void DrawBigRedSphere(){ GLfloat mat_specular[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat mat_ambient[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat mat_diffuse[] = { 1.0, 0.0, 0.0, 1.0 }; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glutSolidSphere(0.5, 32, 32);}void DrawSmallBlueSphere(){ GLfloat mat_specular[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat mat_ambient[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat mat_diffuse[] = { 0.0, 0.0, 1.0, 1.0 }; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glutSolidSphere(0.3, 32, 32);}
Drawbigredsphere draws a large red ball, while drawsmallbluesphere draws a small blue ball. The default coordinates are used for painting, that is, the painting is in the center of the screen, and the Z axis does not move, theoretically, the ball will contain a ball, and the ball will be hidden by the ball. We show that this effect should be the same.
Let's take a look at the situation where the deep test is not enabled. We will first draw the big ball, then draw the ball, and then draw it in the reverse order:
The Code is as follows:
void SceneShow(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(-0.5, 0.0, 0.0); DrawBigRedSphere(); DrawSmallBlueSphere(); glPopMatrix(); glPushMatrix(); glTranslatef(0.5, 0.0, 0.0); DrawSmallBlueSphere(); DrawBigRedSphere(); glPopMatrix(); glFlush();}
We will observe the problems caused by the obvious order of drawing. The picture on the left shows that the ball is first drawn and then the ball is drawn. The small basketball actually overwrites the red ball outside of it. In actual use, we can determine by ourselves, and then use the correct drawing method on the right. As the number of images increases, a certain amount of computing is required, the deep test provided by OpenGL provides us with a simpler and more efficient method. In fact, since OpenGL is used after testing, directly draw the final image and ignore the overwrite image. The efficiency is higher than that of overwrite (hardware support is required ).
The above Code only needs to add a line,
Glenable (gl_depth_test );
To enable the deep test, the effect is very different:
The Ultimate simplicity of the world is nothing more than this :)
In order to save space, only key clips are posted. For the complete source code, see the 2009-11-12/gldepthtest/directory of the source code of my blog. For details about how to obtain the complete source code of the blog, see the article.
Fog
Fan drive without fog-Arabic slang
Cloud image fog
Also like the wind-name of a TV series
Fog is a common weather phenomenon. It is normal to simulate it in OpenGL, but it does not play the role of fog in OpenGL. In fact, the fog effect is also used to achieve fuzzy effect, used for simulation of fuzzy, mist, smoke, and pollution.
The usage steps are very simple, just like OpenGL practice. First enable it through glenable, and then there is a glfog * function that can be used to set the fog effect, we will find that, apart from the different concepts, the basic usage steps are almost the same. We started to think that OpenGL's function uses the pname parameter to determine the function's function method is not in line with the good API design philosophy, (refer to designing C ++ APIs of the QT style]
) But to come, the design of the API is not necessarily absolute. This design reduces the number of APIs to a certain extent and makes searching easier, although it also adds the burden of checking the document and viewing the parameters, these are also irrelevant.
First, when there is no fog effect, I use OpenGL to draw three red balls, and the Z axis of the red ball is backward.
The main code is as follows:
Void drawredsphere () {glfloat mat_specular [] = {1.0, 0.0, 0.0, 1.0}; glfloat mat_shininess [] = {50.0}; glfloat mat_ambient [] = {1.0, 0.0, 0.0, 1.0}; glfloat mat_diffuse [] = {1.0, 0.0, 0.0, 1.0}; glmaterialfv (gl_front, gl_specular, mat_specular); glmaterialfv (gl_front, gl_shininess, mat_shininess ); glmaterialfv (gl_front, gl_ambient, mat_ambient); glmaterialfv (gl_front, gl_diffuse, mat_diffuse); glusolidsphere (0.25, 32, 32 );} // perform all the drawing operations here void sceneshow (glvoid) {glclear (gl_color_buffer_bit | cached); glpushmatrix (); gltranslatef (-0.75, 0.0, 0.0); drawredsphere (); glpopmatrix (); glpushmatrix (); gltranslatef (0.0, 0.0,-1.0); drawredsphere (); glpopmatrix (); glpushmatrix (); gltranslatef (0.75, 0.0,-2.0 ); drawredsphere (); glpopmatrix (); glflush ();}
The effect on the image cannot be seen in the Z axis, because the positive projection mode is used. Now let's start the fog effect.
Add the following statement:
glEnable(GL_FOG);GLfloat fogColor[4] = {1.0, 1.0, 1.0, 1.0};glFogi (GL_FOG_MODE, GL_EXP);glFogfv (GL_FOG_COLOR, fogColor);glFogf (GL_FOG_DENSITY, 0.5);
The effect is as follows:
Because the fog color is white, the 3rd red balls are basically completely white .... You can adjust the parameters in the above code to get different results.
For example, the blue fog:
glEnable(GL_FOG);GLfloat fogColor[4] = {0.0, 0.0, 0.5, 1.0};glFogi (GL_FOG_MODE, GL_EXP);glFogfv (GL_FOG_COLOR, fogColor);glFogf (GL_FOG_DENSITY, 0.5);
In order to save space, only key clips are posted. For the complete source code, see the 2009-11-12/glfogsample/directory of the source code of my blog. For more information about how to obtain the complete source code of my blog, see the article.
The main function is actually a glfog *, but the number of parameters is quite large. Let's wait for your own attempts.
OpenGL Reference Manual
":
Glfog-specify fog Parameters
C Specification
Void glfogf (glenum pname,
Glfloat PARAM );
Void glfogi (glenum pname,
Glint PARAM );
Parameters
Pname
Specifies a single-valued fog parameter.
Gl_fog_mode,
Gl_fog_density,
Gl_fog_start,
Gl_fog_end,
Gl_fog_index, and
Gl_fog_coord_src
Are accepted.
Param
Specifies the value that pname will be set.
C Specification
Void glfogfv (glenum pname,
Const glfloat * Params );
Void glfogiv (glenum pname,
Const glint * Params );
Parameters
Pname
Specifies a fog parameter.
Gl_fog_mode,
Gl_fog_density,
Gl_fog_start,
Gl_fog_end,
Gl_fog_index,
Gl_fog_color, and
Gl_fog_coord_src
Are accepted.
Params
Specifies the value or values to be assigned to pname.
Gl_fog_color requires an array of four values.
All other parameters accept an array containing only a single value.
Description
Fog is initially disabled.
While enabled, fog affects rasterized geometry,
Bitmaps, and pixel blocks, but not buffer clear operations. To enable
And disable fog, call glenable and gldisable with argument
Gl_fog.
Glfog assigns the value or values in Params to the fog Parameter
Specified by pname.
The following values are accepted for pname:
Gl_fog_mode
Params is a single integer or floating-point value that specifies
The equation to be used to compute the fog blend factor,
F.
Three symbolic constants are accepted:
Gl_linear,
Gl_exp,
And gl_exp2.
The equations corresponding to these symbolic constants are defined below.
The initial fog mode is gl_exp.
Gl_fog_density
Params is a single integer or floating-point value that specifies
Density,
The fog density used in both exponential fog equations.
Only nonnegative densities are accepted.
The initial fog density is 1.
Gl_fog_start
Params is a single integer or floating-point value that specifies
Start,
The near distance used in the linear fog equation.
The initial near distance is 0.
Gl_fog_end
Params is a single integer or floating-point value that specifies
End,
The far distance used in the linear fog equation.
The initial far distance is 1.
Gl_fog_index
Params is a single integer or floating-point value that specifies
I
F
,
The fog color index.
The initial fog index is 0.
Gl_fog_color
Params contains four integer or floating-point values that specify
C
F
,
The fog color.
Integer values are mapped linearly such that the most positive representable
Value maps to 1.0,
And the most negative representable value maps
-1.0
.
Floating-point values are mapped directly.
After conversion,
All color components are clamped to the range
0
1
.
The initial fog color is (0, 0, 0, 0 ).
Gl_fog_coord_src
Params contains either of the following symbolic constants:
Gl_fog_coord or gl_fragment_depth. gl_fog_coord
Specifies that the current fog coordinate shocould be used as distance Value
In the fog color computation. gl_fragment_depth specifies that
Current fragment depth shocould be used as distance value in the fog
Computation.
For other articles in this series, see the OpenGL topic "Win32 OpenGL series topics ".
"
References
1. OpenGL Reference Manual
, OpenGL Reference Manual
2. OpenGL
OpenGL programming guide
), Dave shreiner, Mason Woo, Jackie neider, Tom Davis
Xu Bo, Mechanical Industry Press
3. nehe OpenGL tutorials, In the http://nehe.gamedev.net/
You can find the tutorials and related code to download. (The PDF version of the tutorials is available) nehe also developed an object-oriented framework. As a demo program, this framework is very suitable. There are also Chinese Versions
Take all the necessary information.
4. OpenGL getting started, by eastcowboy, this is a good tutorial I have found on the Internet. It is quite complete and popular. This is the first address: http://bbs.pfan.cn/post-184355.html
Complete source code retrieval instructions
Due to space limitations, this article generally only posts the main focus of the Code, the full version of the Code with a project (or makefile) (if any) can be downloaded in Google code using mercurial. The article is stored in different directories on the date published by the blog post. Use mercurial to clone the following database:
Https://blog-sample-code.jtianling.googlecode.com/hg/
For how to use mercurial, see Introduction and brief introduction to the distributed and next-generation version control system mercurial.
"
If you only want to browse all the code, you can go to Google Code to view it. the following URL:
Http://code.google.com/p/jtianling/source/browse? Repo = blog-Sample-code
The author of the original article retains the copyright reprinted. Please indicate the original author and give a link
Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie