我正在使用 gluTess* 函数来绘制非凸多边形。为了避免在每一步都重新进行镶嵌,我将结果存储在一个数组中,并使用 OpenGL 的顶点数组功能进行绘制。
我的问题是,由于某种原因,我第一次使用 gluTess* 时只绘制了部分三角形。如果我强制重新创建 gluTess*,那么一切都很好。
请注意,为了重新创建 gluTess*,我完全销毁包含顶点数组的对象并重新创建它(这会强制重新计算顶点数组对象)。
知道为什么会这样吗?
一些随机的想法:
- 可能是因为对于第一个 OpenGL 调用,窗口还没有达到完整大小吗?
- 我是否需要设置一些 OpenGL 状态,这将在稍后完成,但不是在第一次调用时完成?
谢谢。
编辑:作为测试,我刚刚创建、销毁并重新创建了顶点数组。它解决了问题。这意味着:在 OpenGL 状态没有任何变化的情况下,第一次调用 gluTess* 无法正确细分多边形。但是第二个成功了。以前有人注意到吗?
编辑(2):这是代码:
VA va;
GLUtesselator *t = gluNewTess();
gluTessCallback(t, GLU_TESS_BEGIN_DATA, (GLvoid (*)())beginVA);
gluTessCallback(t, GLU_TESS_END_DATA, (GLvoid (*)())endVA);
gluTessCallback(t, GLU_TESS_VERTEX_DATA, (GLvoid (*)())vertexVA);
gluTessCallback(t, GLU_TESS_ERROR, (GLvoid (*)())&tessError);
gluTessCallback(t, GLU_TESS_COMBINE, (GLvoid (*)())&tessCombine);
gluTessProperty(t, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
gluTessProperty(t, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(t, &va);
gluTessBeginContour(t);
foreach(Point3d& p, points)
gluTessVertex(t, const_cast<GLdouble*>(p.c_data()), (void*)&p);
gluTessEndContour(t);
gluTessEndPolygon(t);
gluDeleteTess(t);
随着第二次调用成功,我怀疑 beginVA、endVA 和 vertexVA 工作正常(正如我所说,第二次调用是通过破坏主要保存顶点数组的数据结构 VA 进行的)。
编辑(3):这是缺少的代码:
struct VA
{
std::vector<Point3d> positions; // Vertex array
GLenum current_mode; // Drawing mode (GL_TRIANGLE, *_FAN or *_STRIP)
Point3d v1, v2; // Two last vertices for _FAN or _STRIP
bool has_v1, has_v2; // did we get the two last vertices?
int n; // Index of the vertex, for *_STRIP
};
void beginVA(GLenum mode, VA *va)
{
va->current_mode = mode; // Store the mode
va->has_v1 = va->has_v2 = false; // We haven't had any vertex yet
va->n = 0;
}
void endVA(VA *va)
{
va->current_mode = 0; // Not really necessary, but cleaner
}
void vertexVA(Point3d *p, VA *va)
{
++va->n;
if(va->current_mode == GL_TRIANGLES) // The simple case
va->positions.push_back(*p);
else if(!va->has_v1) {
va->v1 = *p;
va->has_v1 = true;
} else if(!va->has_v2) {
va->v2 = *p;
va->has_v2 = true;
} else if(va->current_mode == GL_TRIANGLE_STRIP) {
if(va->n%2 == 1) {
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
} else {
va->positions.push_back(va->v2);
va->positions.push_back(va->v1);
va->positions.push_back(*p);
}
va->v1 = va->v2;
va->v2 = *p;
} else { // GL_TRIANGLE_FAN
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
va->v2 = *p;
}
}
编辑(4):最后,错误出现在其他地方。我一定是累了,我使用了一个 std::vector 来存储 combine 函数的结果。我不知道为什么后来它起作用了,但是它肯定是正常的,它第一次不起作用!对不起,我现在关闭这个话题。