OpenGL Super Treasure Note-occlusion query [go]

Source: Internet
Author: User

Catalogue [-]

    • Before masking the query
    • Bounding body
    • Occlusion Query

In a scene, if some objects are obscured by other objects, they are not visible. Then we don't need to draw it. In complex scenarios, this reduces the processing of a large number of vertices and pixels, dramatically increasing the frame rate. Occlusion queries allow us to determine whether a set of graphs is visible after deep testing.

Before masking the query

In order to show the performance improvement of the occlusion query, we need a control group (rendering the scene without using occlusion queries).

First we draw "main occlusion". This main occlusion does not require much detail, usually walls, ceilings, floors and the like. In the following example, we use 6 walls to form this main occlusion.

Void drawoccluder () {  glcolor3f (0.5f, 0.25f, 0.0f);   glpushmatrix ();     glscalef (30.0f, 30.0f, 1.0f);     gltranslatef (0.0f, 0.0f,  50.0f);     glutsolidcube (10.0f);     gltranslatef (0.0f, 0.0f ,  -100.0f);     glutsolidcube (10.0f);   glpopmatrix ();   Glpushmatrix ();     glscalef (1.0f, 30.0f, 30.0f);     Gltranslatef (50.0f, 0.0f, 0.0f);     glutsolidcube (10.0f);     gltranslatef ( -100.0f, 0.0f, 0.0f);     glutsolidcube (10.0f);   Glpopmatrix ();   glpushmatrix ();     glscalef (30.0f, 1.0f, 30.0f);     gltranslatef (0.0f, 50.0f, 0.0f);     glutsolidcube (10.0f);     gltranslatef (0.0f, -100.0f, 0.0f);     glutsolidcube (10.0f);   glpopmatrix ();} 

Now in each cell, we place a textured sphere with a height of 挌. These spheres may be occluded, or may be occluded objects.

Void drawsphere (Glint spherenum)  { ...    glutsolidsphere (50.0f,  200, 200); &nbsp ...} Void drawmodels (void)  {    //turn on texture   automatically generate texture coordinates   glenable (gl_texture_ 2D);    glenable (gl_texture_gen_s);    glenable (gl_texture_gen_t);    //Draw 27 different colors of spheres   for  (r = 0; r < 3; r++)     { for  (g = 0; g < 3; g++)      {        for  (b = 0; b < 3; b++)         {         glcolor3f (r *  0.5f, g * 0.5f, b * 0.5f);          glpushmatrix ();          gltranslatef (100.0f * r& NBsP;- 100.0f,            100.0f * g  - 100.0f,            100.0f *  b - 100.0f);          drawsphere ((r*9) + (g*3) +b);          glpopmatrix ();        }     }   }   gldisable (GL_TEXTURE_2D);    gldisable (gl_texture_gen_s);    gldisable (gl_texture_gen_t);  }

There is no occlusion query on my machine the frame rate of rendering is around 20.

Bounding body

In occlusion queries, if the boundary of an object is invisible, it means that the object is not visible. So we just need to check the perimeter of the object visible, we can determine whether the object is obscured. The outer bounding body of the object contains the whole object, which means that the volume of the bounding body is greater than or equal to the volume of the object. For a sphere, the bounding body can have many kinds, the most common is cubic box, tetrahedron and so on.

Why choose to surround the body to judge the occlusion, rather than directly with the sphere. Because the sphere is too complex to contain more vertices, rendering is time-consuming. The reason why occlusion can improve performance is that we can render a simple bounding body without the illumination, texture and other effects, and do not need to change the value of the buffer. With these bounding bodies in-depth testing, we can determine which objects are obscured, and those objects that are obscured can not be rendered (no need to invoke any commands to render the object), and if the object has a very large number of vertices, then occlusion can greatly improve performance at this time.

Occlusion Query

To mask a query:

    1. First, generate query object IDs for these objects call Glgenqueries

    2. Call Glbeginquery to start masking queries

    3. Render bounding body

    4. Call Glendquery End occlusion Query

    5. Call Glgetqueryobject[u]iv, extract the result of the occlusion query based on the ID, and perform the corresponding operation according to the result

    6. Gldeletequeries Delete ID, recycle resource

The identifier (ID/name) of the query object is an unsigned integer that can be generated by the Glgenqueries function or defined by itself. The glgenqueries that are generally provided with OpenGL will be more convenient.

void Glgenqueries (Glsizei N, Gluint *ids);

The first parameter is the number of generated IDs, and the second parameter is the array to hold the IDs. 0 is the reserved ID and will not be generated. We can also use Glisquery to determine whether an ID is an ID of a occlusion query object.

void Glisquery (gluint id);

If it returns GL_TRUE, it is not returned gl_false.

With the ID of the Occlusion query object, you can start masking the query. For example

Glbeginquery (gl_samples_passed, 1); Glbegin (gl_triangles); glvertex3f (1.0f, 1.0f, 0.0f), glvertex3f ( -1.0f, 5.0f, 0.0f), glvertex3f (6.0f, 20.0f, 0.0f), Glend (); Glendquery (Gl_ samples_passed);

void Glbeginquery (Glenum target, gluint ID);

Where target must be gl_samples_passed. ID is the ID used to identify this occlusion query.

void Glendquery (Glenum target); End this occlusion query, where target must be gl_samples_passed.

After rendering the object that needs to be obscured, we need to extract the result of the occlusion query, which can be extracted by glgetqueryobject[u]iv, and the function returns the number of fragments or samples.

void Glgetqueryobjectiv (glenum ID, glenum pname, Glint *param);

void Glgetqueryobjectuiv (glenum ID, glenum pname, Gluint *param);

The ID is the id,pname of this occlusion query object if it is Gl_query_result, the Param will contain a fragment or sample (if multiple sampling is enabled) through the depth test, if the number is 0, the object is completely obscured.

There may be a delay when you complete the occlusion query operation. We can check whether it is done by setting PName to Gl_query_result_available. If the occlusion query is effectively completed, then Param will be gl_true, otherwise gl_false.

Cases:

int count = 1000; Wait 1000 cycles Gluint queryready = gl_false;while (!queryready && count--) {glgetqueryobjectuiv (1, Gl_query_result _available, &queryready);} Gluint samples;glgetqueryobjectuiv (1, Gl_query_result, &samples); if (Samples > 0) drawsomething ();

After using the occlusion query object, call Gldeletequeries to reclaim the resource.

void Gldeletequeries (Glsizei n, const gluint *ids);

To modify the previous example, we can first render the bounding body of the 27 spheres, make occlusion queries, and if any of the enclosing bodies are completely obscured, we do not need to draw this sphere. The code snippet is as follows:

Void drawmodels (void)  { glint r, g, b; //draw the main occlusion drawoccluder ();  // As you draw the bounding body, the simpler the better. Turn off textures, lighting and so on. You do not need to write a value to the buffer. Glshademodel (Gl_flat);  gldisable (gl_lighting);  gldisable (gl_color_material);  glDisable (GL_ NORMALIZE);  gldepthmask (Gl_false);  glcolormask (0, 0, 0, 0); //  draw 27 cubes for   (r = 0; r < 3; r++)  { for  (g = 0; g  < 3; g++)  { for  (b = 0; b < 3; b++)  {  if  (Showboundingvolume)  glcolor3f (r * 0.5f, g * 0.5f, b *  0.5f);  glpushmatrix ();  gltranslatef (100.0f * r - 100.0f,  100.0f  * g - 100.0f,  100.0f * b - 100.0f)  //Start masking query Glbeginquery (GL _samples_passed, queryids[(r*9) + (g*3) +b])  //draw bounding body glutsolidcube (100.0f);  //End occlusion Query GLEndquery (gl_samples_passed);  glpopmatrix ()  } } }//return to normal rendering state gldisable (gl_polygon_stipple);  glshademodel (Gl_smooth);  glenable (gl_lighting);  glenable (gl_color_material);  glEnable (GL_ NORMALIZE);  glcolormask (1, 1, 1, 1);  gldepthmask (gl_true);  //Open Texture   Automatic generation of texture coordinates glenable (gl_texture_2d);  glenable (gl_texture_gen_s);  glenable (gl_texture_gen_t);  // Draw 27 Different color spheres for  (r = 0; r < 3; r++)  { for  (g =  0; g < 3; g++)  { for  (b = 0; b < 3; b++ )  { glcolor3f (r * 0.5f, g * 0.5f, b * 0.5f);  Glpushmatrix ();  gltranslatef (100.0f * r - 100.0f,  100.0f * g  - 100.0f,  100.0f * b - 100.0f);  //function is based on, Occlusion the results of the query to determine whether to draw this sphere drawsphere ((r*9) + (g*3) +b);  glpopmatrIX ();  } } } gldisable (gl_texture_2d);  gldisable (gl_texture_gen_s);  glDisable (GL_ texture_gen_t);  }
void Drawsphere (Glint spherenum) {Glboolean occluded = Gl_false;     if (occlusiondetection) {glint passingsamples;     Check if the object is completely obscured Glgetqueryobjectiv (Queryids[spherenum], Gl_query_result, &passingsamples);   if (Passingsamples = = 0) occluded = gl_true;   }//Not obscured then draw if (!occluded) {Glutsolidsphere (50.0f, 200, 200); } }

With the occlusion query, the frame rate reached about 32, of course, but also to see the angle of viewing the scene. If you look at a point where most of the spheres are obscured, the performance increases.

Example_osgocclusionquery in the OSG
A) demonstrates the use of Osg::occlusionquerynode.

OpenGL Super Treasure Note-occlusion query [go]

Related Article

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.