Win32 OpenGL programming (13) Hide surface elimination (deep test) and fog Effect

Source: Internet
Author: User
Tags mercurial

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

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.