zoukankan      html  css  js  c++  java
  • OpenGL 之 glPolygonOffset(二)

    Polygon Offset

    If you want to highlight the edges of a solid object, you might try to draw the object with polygon mode GL_FILL and then draw it again, but in a different color with polygon mode GL_LINE. However, because lines and filled polygons are not rasterized in exactly the same way, the depth values generated for pixels on a line are usually not the same as the depth values for a polygon edge, even between the same two vertices. The highlighting lines may fade in and out of the coincident polygons, which is sometimes called "stitching" and is visually unpleasant.

    The visual unpleasantness can be eliminated by using polygon offset, which adds an appropriate offset to force coincident z values apart to cleanly separate a polygon edge from its highlighting line. (The stencil buffer, described in "Stencil Test" in Chapter 10, can also be used to eliminate stitching. However, polygon offset is almost always faster than stenciling.) Polygon offset is also useful for applying decals to surfaces, rendering images with hidden-line removal. In addition to lines and filled polygons, this technique can also be used with points.

    There are three different ways to turn on polygon offset, one for each type of polygon rasterization mode: GL_FILL, GL_LINE, or GL_POINT. You enable the polygon offset by passing the appropriate parameter to glEnable(), either GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT. You must also call glPolygonMode() to set the current polygon rasterization method.

    void glPolygonOffset(GLfloat factor, GLfloat units);
    When enabled, the depth value of each fragment is added to a calculated offset value. The offset is added before the depth test is performed and before the depth value is written into the depth buffer. The offset value o is calculated by:
    o = m * factor + r * units

    where m is the maximum depth slope of the polygon and r is the smallest value guaranteed to produce a resolvable difference in window coordinate depth values. The value r is an implementation-specific constant.

    To achieve a nice rendering of the highlighted solid object without visual artifacts, you can either add a positive offset to the solid object (push it away from you) or a negative offset to the wireframe (pull it towards you). The big question is: "How much offset is enough?" Unfortunately, the offset required depends upon various factors, including the depth slope of each polygon and the width of the lines in the wireframe.

    OpenGL calculates the depth slope (see Figure 6-5) of a polygon for you, but it's important that you understand what the depth slope is, so that you choose a reasonable value for factor. The depth slope is the change in z (depth) values divided by the change in either x or y coordinates, as you traverse a polygon. The depth values are in window coordinates, clamped to the range [0, 1]. To estimate the maximum depth slope of a polygon (m in the offset equation), use this formula:

    Figure 6-5 : Polygons and Their Depth Slopes

    For polygons that are parallel to the near and far clipping planes, the depth slope is zero. For the polygons in your scene with a depth slope near zero, only a small, constant offset is needed. To create a small, constant offset, you can pass factor=0.0 and units=1.0 to glPolygonOffset().

    For polygons that are at a great angle to the clipping planes, the depth slope can be significantly greater than zero, and a larger offset may be needed. Small, non-zero values for factor, such as 0.75 or 1.0, are probably enough to generate distinct depth values and eliminate the unpleasant visual artifacts.

    Example 6-8 shows a portion of code, where a display list (which presumably draws a solid object) is first rendered with lighting, the default GL_FILL polygon mode, and polygon offset with factor of 1.0 and units of 1.0. These values ensure that the offset is enough for all polygons in your scene, regardless of depth slope. (These values may actually be a little more offset than the minimum needed, but too much offset is less noticeable than too little.) Then, to highlight the edges of the first object, the object is rendered as an unlit wireframe with the offset disabled.

    Example 6-8 : Polygon Offset to Eliminate Visual Artifacts: polyoff.c

      glEnable(GL_LIGHTING);
       glEnable(GL_LIGHT0);
       glEnable(GL_POLYGON_OFFSET_FILL);
       glPolygonOffset(1.0, 1.0);
       glCallList (list);
       glDisable(GL_POLYGON_OFFSET_FILL);
    
       glDisable(GL_LIGHTING);
       glDisable(GL_LIGHT0);
       glColor3f (1.0, 1.0, 1.0);
       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
       glCallList (list);
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    特别注意(glPolygonOffset需要与glPolygonMode配合使用,不然不起作用 )。

  • 相关阅读:
    Mysql之锁、事务绝版详解干货!
    SSL基础知识(比较清楚)
    数字证书使用流程指南
    HTTPS与SSL
    IIS 6.0 Web园(Web Garden)
    验证数字可以有千分符可以有0个1个小数点小数点后输入后四舍五入保留两位(写个js验证真费劲)
    线程安全
    利用SSL给IIS加把锁(转)
    弹出div后其它不能操作(小技巧)
    关于反射
  • 原文地址:https://www.cnblogs.com/lovebay/p/15494510.html
Copyright © 2011-2022 走看看