一、什么叫分格化?
分格化就是把复杂多边形(非凸多边形,如下图)分割成凸多边形的过程。典型的复杂多变性主要有三类:凹多边形、中间有洞的多边形以及自相交多边形。
二、为什么要进行分格化?
因为OpenGL只能够保证正确渲染凸多边形,而不能保证渲染复杂多边行结果的正确性(当然有时也正确)。至于OpenGL为什么不提供对复杂多边形的正确性支持,主要是由于渲染性能方面的考虑。
三、如何分格化?
glu(OpenGL Utility Library,OpenGL实用库)提供一系列的分格化函数供我们调用。在分格化一个复杂多边形时,需要执行以下几个典型步骤:
1. 用gluNewTess()函数创建一个分格化对象;
2. 调用gluTessCallback()函数注册相关回调函数,这些回调函数在分格化执行时调用。其中,最为复杂的情况是当分格化算法检测到多边形存在相交并且必须调用在GLU_TESS_COMBINE回调函数中所注册的函数的时候;
3. 调用gluTessProperty()函数制定分格化属性。其中最重要的属性是环绕规则,它确定了多边形的哪些区域应该填充,哪些区域不应该着色;
4.
通过制定一个或多个闭合多边形的轮廓来渲染经过分格化的多边形。如果物体的数据时静态的,可以把经过分格化的多边形放在显示列表中(如果不需要反复重新进行分格化计算,使用显示列表可以提高效率);
5. 如果需要对其他物体进行分格化,可以复用原来的分格化队形。如果完成对分格化对象的操作,可以使用gluDeleteTess()函数删除该分格化对象。
分格化实际上是在把顶点传入OpenGL管线之前,先将其传到分格化对象(tessellator),分格化对象处理完后,tessellator再把处理后的顶点传入到OpenGL管线。
四、详解
1. 分格化对象
创建分格化对象,需要调用:
GLUtesselator* gluNewTess(void);
此函数创建一个新的分格化对象,并返回一个指向它的指针。如果创建失败,该函数返回NULL指针。可以在所有的分格化任务中复用同一个分格化对象。(分格化的单词为tessellate,此处应该是拼写错误!)
2. 回调函数
为什么要引入回调函数?有两方面的意义:一是给用户查看信息的机会;二是给用户修改信息的机会。回调函数的注册是调用如下函数: