WorldWind Java 版学习:7、凹多边形渲染

在 C++ 中进行凹多边形绘制,首先调用 gluNewTess 函数构造一个 GLUtesselator 对象:
GLUtesselator *tobj = gluNewTess();

然后依次设置相关的回调函数:
gluTessCallback(tobj, GLU_TESS_BEGIN, (void(__stdcall*)())beginCallback);
gluTessCallback(tobj, GLU_TESS_END, (void(__stdcall*)())endCallback);
gluTessCallback(tobj, GLU_TESS_ERROR, (void(__stdcall*)())errorCallback);
gluTessCallback(tobj, GLU_TESS_VERTEX, (void(__stdcall*)())vertexCallback);
gluTessCallback(tobj, GLU_TESS_COMBINE, (void(__stdcall*)())combineCallback);
回调函数示例:
void CALLBACK beginCallback(GLenum which)
{
glBegin(which);
}
void CALLBACK endCallback(void)
{
glEnd();
}
void CALLBACK errorCallback(GLenum errorCode)
{
// error
}
void CALLBACK vertexCallback(GLvoid *vertex)
{
glVertex3dv((GLdouble *) vertex);
}
void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut )
{
GLdouble *vertex = new GLdouble[3];
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
*dataOut = vertex;
}

然后按具体情况设置属性:
gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);
设置属性的函数原型为:
void gluTessProperty(GLUtesselator *tessobj, GLenum property, GLdouble value);
如果 property 是 GLU_TESS_BOUNDARY_ONLY, 则 value 是 GL_TRUE 或者 GL_FALSE。当为 GL_TRUE 时, 多边形不填充, 所以默认为 GL_FALSE。
如果 property 是 GLU_TESS_TOLERANCE, 则 value 是一个表示距离的公差值, 表示两个点距离如果足够近将由 GLU_TESS_COMBINE 回调函数进行合并。
如果 property 是 GLU_TESS_WINDING_RULE, 则 value 可以是 GLU_TESS_WINDING_ODD GLU_TESS_WINDING_NONZERO GLU_TESS_WINDING_POSITIVE GLU_TESS_WINDING_NEGATIVE GLU_TESS_WINDING_ABS_GEQ_TWO 它决定了多边形哪部分属于内部,哪部分属于外部。
判断 WINDING 的准则就是环绕准则, 每个点的环绕数就是环绕这个点的所有轮廓线的代数和(逆时针转一圈+1, 顺时针转一圈-1)。

最后调用 gluTessVertex 等函数完成渲染:
gluTessBeginPolygon(tobj, NULL);
gluTessBeginContour(tobj);
gluTessVertex(tobj, vertex, vertex);
gluTessEndContour(tobj);
gluTessEndPolygon(tobj);

在 Java 中也是类似的操作(详见 AbstractSurfaceShape 类的 doTessellateInterior 方法):
GLUtessellator tess = glu.gluNewTess();
glu.gluTessCallback(this.tess, GLU.GLU_TESS_BEGIN, callback);
glu.gluTessCallback(this.tess, GLU.GLU_TESS_VERTEX, callback);
glu.gluTessCallback(this.tess, GLU.GLU_TESS_END, callback);
glu.gluTessCallback(this.tess, GLU.GLU_TESS_COMBINE, callback);
glu.gluTessProperty(this.tess, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_POSITIVE);
glu.gluTessBeginPolygon(tess, null);
glu.gluTessBeginContour(tess);
glu.gluTessVertex(tess, vertex, 0, vertex);
glu.gluTessEndContour(tess);
glu.gluTessEndPolygon(tess);

posted on 2012-11-12 10:56  redfler  阅读(714)  评论(0编辑  收藏  举报

导航