程序员今日看点

OpenGL ES 3.0编程指南:第七章. Primitive

2016-10-21  本文已影响108人  别卡机

[TOC]

4. Rasterization

光栅化阶段处理每一个单独的图元,为这个图元产生合适的片段集。其中的每一个片段都包含了表示像素位置的整数坐标,和用来传给片段shader来显示颜色的一些额外数据。

本节主要介绍在光栅化阶段,应用程序可以控制的一些选项。

Culling(剔除)

在三角形进行光栅化之前,我们能够通过设置三角形的朝向来丢弃一部分三角形,以此来提高效率,这就是剔除。

首先,要设定好顶点顺序的哪个方向是正面(朝向视口的那一面):

void glFrontFace (GLenum dir)

  • dir : 可取值为GL_CW(顺时针)和GL_CCW(逆时针),默认值是GL_CCW。

然后,设置要剔除哪一面的三角形:

void glCullFace (GLenum mode)

  • mode : 可取值为GL_FRONT、GL_BACK、GL_FRONT_AND_BACK。默认值是GL_BACK。

最后,设置是否开启剔除操作:

void glEnable (GLenum cap)
void glDisable (GLenum cap)

  • cap : 值为CL_CULL_FACE。默认情况下,剔除操作未开启。

Polygon Offset (多边形偏移)

当两个多边形深度值相同时,深度缓冲不能将两者区分出来,导致像素重叠,位于后面的图元的像素会被绘制到前面的图元上,通过 多边形偏移 可以解决此问题。多边形偏移是在深度测试之前,对图元的深度值增加或减少一个微小的偏移量,来推远或拉近该图元,以此来将两个图元分开,当然在深度缓存中存储的还是原始深度值。

偏移值设置如下:

void glPolygonOffset (GLfloat factor, GLfloat units)

  • depth offset = m * factor + r * units
    m是多边形深度的斜率的最大值(由OpenGL ES在光栅化阶段计算得出),r是能产生在窗口坐标系的深度值中可分辨的差异的最小值,r是由具体实现OpenGL的平台指定的一个常量

(关于多边形偏移的详细介绍,可以参考这里http://www.cnblogs.com/bitzhuwei/p/polygon-offset-for-stitching-andz-fighting.html))

5. Occlusion Queries(遮挡查询)

遮挡查询是用查询对象来跟踪通过深度测试的片段或样本。

如果一个物体被其他物体遮挡住了,那么就不需要绘制这个物体了,在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率。使用遮挡查询允许我们判断一个物体进行深度测试之后是否可见,如果不可见则不需要调用任何渲染该物体的命令。具体步骤如下:

  1. 调用 glGenQueries 生成查询对象ID:

void glGenQueries (GLsizei n, GLuint * ids)

  • n : 要生成的查询对象的数量
  • ids : 储存生成的查询对象的数组
  1. 调用 glBeginQuery ()开始遮挡查询:

void glBeginQuery (GLenum target, GLuint id)

  • target : 可取值为
    GL_ANY_SAMPLES_PASSED
    GL_ANY_SAMPLES_PASSED_CONSERVATIVE(GL_ANY_SAMPLES_PASSED_CONSERVATIVE性能较高,但精度较低)
    GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
  • id : 指明查询对象的名字(id)
  1. 渲染包围体,有时物体过于复杂,包含顶点较多,可以用该物体的包围体去进行遮挡判断,因为包围体包围着整个该物体,如果包围体被全部遮挡,那么该物体也一定被全部遮挡

  2. 调用 glEndQuery结束遮挡查询:

void glEndQuery (GLenum target)

  • target : 可取值为
    GL_ANY_SAMPLES_PASSED
    GL_ANY_SAMPLES_PASSED_CONSERVATIVE
    GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
  1. 调用 glGetQueryObjectuiv, 根据查询对象的id来获取遮挡查询的结果,根据结果进行相应的操作:

void glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint * params)

  • id : 指明查询对象的名字(id)
  • pname : 可取值为
    GL_QUERY_RESULT
    GL_QUERY_RESULT_AVAILABLE
  • params : 如果 pname 的值为 GL_QUERY_RESULT, params为通过了深度测试的片段的数量,如果数量为0,则表示这个物体完全被遮挡
    如果 pname 的值为 GL_QUERY_RESULT_AVAILABLE, 则该方法用来检查遮挡查询是否完成了,param值为 GL_TRUE 或 GL_FALSE
  1. 调用glDeleteQueries删除ID,回收资源:

void glDeleteQueries (GLsizei n, GLuint * ids)

  • n : 要删除的查询对象的数量
  • ids : 要删除的查询对象的数组

(关于遮挡查询的详细介绍,可以参考这里http://my.oschina.net/sweetdark/blog/189666)

上一篇下一篇

猜你喜欢

热点阅读