• 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配合使用,不然不起作用 )。

  • 相关阅读:
    ASP.Net请求小周期
    创建型设计模式
    eml文件解析实例,简历信息抓取工具
    Microsoft ReportViewer 控件类型版本兼容问题及解决方法
    WCF IIS 部署错误处理
    如何使Wpf浏览器应用程序被完全信任运行
    Server 2008 r2 多用户远程桌面配置
    The configuration section 'system.serviceModel' cannot be read because it is missing a section decla
    spss C# 二次开发 学习笔记(六)——Spss统计结果的输出
    spss C# 二次开发 学习笔记(二)——Spss以及统计术语解释(IT人眼中的统计术语)
  • 原文地址:https://www.cnblogs.com/lovebay/p/15494510.html
Copyright © 2020-2023  润新知