opengl polygon 三角剖分

本文介绍了在非固定管线时代的OpenGL中,如何使用gluNewTess函数将复杂多边形分割为三角形,包括gluTessProperty和gluTessCallback的设置,以及处理分割后面片的BeginMode和点序列。提到的GLU_TESS_ERROR和替代方法如earcut算法和CGAL库也被提及。
摘要由CSDN通过智能技术生成

        固定管线时代的openGL可以使用GL_POLYGON来描画简单的凸多边形。但是无法直接描画凹的,带孔的或者自交的多边形。

        而非固定管线时代openGL3.*,openGL4.*,直接就没有了GL_POLYGON。

        不管是那种情况,都需要将多边形转化为三角形(三角形,三角带,三角扇)。我们很容易在网络上搜索到gluNewTess这个系列的函数,用来分割多边形。但是所有的例子都是在旧版本openGL下进行的,其实在这个系列函数在新版本openGL中仍然可以使用。现在开始正文,内容比较简单。

1.gluNewTess 创建一个tess对象

2.gluTessProperty 设置下环绕方向

3.gluTessCallback 设置回调函数(GLU_TESS_BEGIN,GLU_TESS_END,GLU_TESS_VERTEX等)

4.gluTessBeginPolygon,gluTessBeginContour,gluTessVertex等函数

以上部分参考网络上的例子。这里只说一下注意的地方。

多边形会被分割为多个面片,每个面片的BeginMode类型是不一样的,有可能是GL_TRIANGLE_STRIP或者GL_TRIANGLE_FAN。比如一个18个点的多边形,可能会被分割成3个面片:6个点组成的GL_TRIANGLE_STRIP,9个点组成的GL_TRIANGLE_FAN,9个点组成的GL_TRIANGLE_STRIP。(数组是我编的,但是a.分割不会创建新点,b.因为存在不同三角形共用点的情况,分割后的点数量大于分割前的。)

基于上面的讨论,我们需要获取每面片的BeginMode和点序列。相关代码如下:

1.

GLenum g_Type;
void CALLBACK beginCallback(GLenum which) 
{
	//glBegin(which);
	g_Type = which;
}

在GLU_TESS_BEGIN的回调函数中,取得BeginMode(BeginMode就是glBegin的参数。在新版openGL中,我们不使用glBegin系列函数来描画图形。所以这里不调用 glBegin.

2.

std::vector<vec3 > g_vecPoint3D;
void CALLBACK vetexCallback(GLdouble * vertex)
{
	g_vecPoint3D.push_back(vec3(vertex[0], vertex[1], vertex[2]));
}

在GLU_TESS_VERTEX的回调函数中,取得分割后的坐标。

3.

std::vector<std::pair<GLenum, std::vector<vec3>>> g_vecvecPoint3D;
void CALLBACK endCallback(void)
{
	//glEnd(which);
	g_vecvecPoint3D.push_back(std::make_pair(g_Type, g_vecPoint3D));
	g_vecPoint3D.clear();
}

如果进入了GLU_TESS_END的回调函数,标志着一个分割后的面片已经结束了。此时,我们已获得的坐标点就是一个面片的所有坐标点。将beginMode和坐标一起存起来。(std::make_pair(g_Type, g_vecPoint3D))

4.重复1,2,3,得到每个面片的beginMode和坐标列。

这样一来,polygon就分割完成了。可以描画数据或者将数据存起来。

====================================

如果注册了GLU_TESS_ERROR回调函数,以下是错误码。

/* TessError */
#define GLU_TESS_ERROR1     100151
#define GLU_TESS_ERROR2     100152
#define GLU_TESS_ERROR3     100153
#define GLU_TESS_ERROR4     100154
#define GLU_TESS_ERROR5     100155
#define GLU_TESS_ERROR6     100156
#define GLU_TESS_ERROR7     100157
#define GLU_TESS_ERROR8     100158

#define GLU_TESS_MISSING_BEGIN_POLYGON  GLU_TESS_ERROR1
#define GLU_TESS_MISSING_BEGIN_CONTOUR  GLU_TESS_ERROR2
#define GLU_TESS_MISSING_END_POLYGON    GLU_TESS_ERROR3
#define GLU_TESS_MISSING_END_CONTOUR    GLU_TESS_ERROR4
#define GLU_TESS_COORD_TOO_LARGE        GLU_TESS_ERROR5
#define GLU_TESS_NEED_COMBINE_CALLBACK  GLU_TESS_ERROR6



glu1.3.pdf (khronos.org)
 glu文档。

===============================

其他的分割方法:

1.earcut算法,https://github.com/mapbox/earcut.hpp

支持多种语言,按官方的描述就是快.只需要一个头文件。官网写着需要openGL SDK.

由于算法的原因,会产生很不"完美的三角形",比如2个角度很小的锐角和1个大钝角,这可能不是你想要的。只支持2d,3D场合需要先将图形拍扁。但是由于会产生不完美的三角形,转回3D后的效果,和你想的可能相差很大。

不过以上只是推测,不负任何责任。

2.CGAL 

打开网站,看一眼目录,你就能感觉到这个库很强大。

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值