关于网格化tessellation的理解和问题

本文详细解析使用GLUTessellator进行网状化的基本步骤,并指出常见错误及其解决方法,包括如何正确处理顶点数组、多环绕情况下的顶点数不等、环绕线交叉等问题。
 原文 点击打开链接

 首先网格化的步骤为(代码示意)

GLUtesselator *pTessLator;
pTessLator=gluNewTess(); //创建网格化对象
gluTessCallback(pTessLator,GLU_TESS_BEGIN,(void (__stdcall *)())glBegin);//设置回调函数
gluTessCallback(pTessLator,GLU_TESS_END,(void (__stdcall *)())glEnd);
gluTessCallback(pTessLator,GLU_VERTEX,(void (__stdcall *)())glVertex3dv);
gluTessCallback(pTessLator,GLU_TESS_ERROR,(void (__stdcall *)())TessError);
gluTessBeginPolygon(pTessLator,NULL);//开始一条曲线,后面逐一指定顶点,所以第二参数为空
gluTessBeginContour(pTessLator);
group=&(tess.groups[0]);
vector<VertexPoint>::iterator it;
GLdouble vertex[10][3];
int i=0;
for (it=group->vertexsArray.begin();it!=group->vertexsArray.end() ;it++)
{
VertexPoint vp=*it;
vertex[i][0]=vp.xyz[0];
vertex[i][1]=vp.xyz[1];
vertex[i][2]=vp.xyz[2];
gluTessVertex(pTessLator,vertex[i],vertex[i]);

}
gluTessEndContour(pTessLator);
gluTessEndPolygon(pTessLator);
gluDeleteTess(pTessLator);


上面代码正确执行了网格化
 

但是,上述代码中的红色代码片段。有以下五点:

 

1. 就是如果只有一个环绕,环绕上各个顶点在三维空间上应尽量处于同一个平面,否则可能看不到网格化结果(这里不解释网格化原理);如果存在多个环绕,相邻环绕可以处在同一平面,也可以不处在同一平面,但是他们之间的深度不能超过他们之间的平面宽度,否则也看不到多环绕的网格化结果。


2. 个就是顶点数组变量vertex,如果vertex的定义放在for循环里面,而且改成一维数组的形式,如下面代码所示
for (it=group->vertexsArray.begin();it!=group->vertexsArray.end() ;it++)
{
VertexPoint vp=*it;
GLdouble vertex[3]={vp.xyz[0],vp.xyz[1],vp.xyz[2]};
gluTessVertex(pTessLator,vertex,vertex); 
}
顶点vertex就成了for循环里的局部变量,这时候不能进行网格化,运行看不到结果。原因就是gluTessVertex(pTessLator,vertex,vertex)的第三个参数是void* data类型的,它就是顶点数据来源,必须提供一个跟网格化对象pTessLator同作用域或者更大作用域的数据来源指针,以便回调传给glVertex函数绘制顶点,否则无法找到顶点渲染。

3. 在上面正确运行结果的代码里面,gluTessVertex(pTessLator,vertex[i],vertex[i])的第三个参数vertex[i]指定了顶点的数据来源,不一定要跟第二个参数一致,可以是vertex[(i+a)%N],其中a为任一正整数,N为分隔化曲线的顶点个数。如可以改为

gluTessVertex(pTessLator,vertex[i],vertex[(i+5)%10]);//加入顶点总数为10

程序运行结果正确


4.如果是多个环绕的网格化,相邻环绕各自环绕曲线上的顶点数可以不相等,如下图示,外环绕有是个控制顶点,内部则有五个


5.如果是多环绕,相邻环绕线不能有交叉,否则看不到结果
如下环绕线就不能网格化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值