【问题标题】:Is there a way to force GLUtessellator to use GL_TRIANGLES only?有没有办法强制 GLUtessellator 只使用 GL_TRIANGLES?
【发布时间】:2012-09-21 15:21:55
【问题描述】:

我正在尝试使用 GLUtesselator 在 OpenGL 中生成 3D 凸出文本。以下是相关代码:

private boolean createText(final String displayText)
{
    final Font font = new Font("Times New Roman", Font.TRUETYPE_FONT, 3);
    final float depth = 1000f;
    final float flatness = 0.0001f;

    final GlyphVector glyphVector = font.createGlyphVector(
            new FontRenderContext(new AffineTransform(), true, true), new StringCharacterIterator(displayText));
    final GeneralPath generalPath = (GeneralPath) glyphVector.getOutline();
    final PathIterator pathIterator = generalPath.getPathIterator(AffineTransform.getScaleInstance(1.0, -1.0),
            flatness);

    tesselateFace(pathIterator, false, 0.0f);
    return false;
}

private void tesselateFace(final PathIterator pathIterator, final boolean justBoundary, final double tessZ)
{
    final GLUtessellatorCallback callback = new TessellatorCallback();
    final GLUtessellator tessellator = glu.gluNewTess();

    glu.gluTessCallback(tessellator, GLU.GLU_TESS_BEGIN, callback);
    glu.gluTessCallback(tessellator, GLU.GLU_TESS_END, callback);
    glu.gluTessCallback(tessellator, GLU.GLU_TESS_ERROR, callback);
    glu.gluTessCallback(tessellator, GLU.GLU_TESS_VERTEX, callback);
    glu.gluTessCallback(tessellator, GLU.GLU_TESS_COMBINE, callback);

    if (pathIterator.getWindingRule() == PathIterator.WIND_EVEN_ODD)
        glu.gluTessProperty(tessellator, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_ODD);
    else
        glu.gluTessProperty(tessellator, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NONZERO);

    if (justBoundary)
        glu.gluTessProperty(tessellator, GLU.GLU_TESS_BOUNDARY_ONLY, GL.GL_TRUE);
    else
        glu.gluTessProperty(tessellator, GLU.GLU_TESS_BOUNDARY_ONLY, GL.GL_FALSE);

    glu.gluTessProperty(tessellator, GLU.GLU_TESS_EDGE_FLAG, GL.GL_TRUE);

    glu.gluTessBeginPolygon(tessellator, (double[]) null);

    while (!pathIterator.isDone())
    {
        final double[] coords = new double[3];
        coords[2] = tessZ;
        switch (pathIterator.currentSegment(coords))
        {
        case PathIterator.SEG_MOVETO:
            glu.gluTessBeginContour(tessellator);
            break;
        case PathIterator.SEG_LINETO:
            glu.gluTessVertex(tessellator, coords, 0, coords);
            break;
        case PathIterator.SEG_CLOSE:
            glu.gluTessEndContour(tessellator);
            break;
        }

        pathIterator.next();
    }
    glu.gluTessEndPolygon(tessellator);

    glu.gluDeleteTess(tessellator);
}

如果我相信第 11 章中的红皮书,

...如果有一个与启用边缘标志的 GLU_TESS_EDGE_FLAG 关联的回调,则仅使用 GL_TRIANGLES 调用 GLU_TESS_BEGIN 回调。

那么我认为我应该只使用GL_TRIANGLES 绘图。

但是,我可以看到在我的自定义 tessellator 回调中调用的类型可以是 GL_TRIANGLE_FANGL_TRIANGLE_STRIPGL_TRIANGLES 中的任何一个。我只问是否有办法强制执行此操作,因为我太忙于创建一个 VBO 来处理除 GL_QUADSGL_TRIANGLES 之外的任何其他内容。

【问题讨论】:

  • 我在你的函数中发现了一个错误。在PathIterator.SEG_MOVETO 的情况下,您没有调用GLU.gluTessVertex(tessellator, coords, 0, coords)

标签: opengl glu tesselation


【解决方案1】:

我敢肯定,如果你只是提供了边缘回调(即使你什么都没做),你只会得到三角形。 我过去一定遇到过同样的问题,并找到了这段代码和评论:

// providing this callback should stop triangle fans / strips coming back
if not fBoundaryOnly then
    gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, @tessEdgeData); 

注意,这是 Delphi 代码,但应该仍然有意义。 @tessEdgeData 是指向不做任何事情的回调例程的指针。

【讨论】:

    【解决方案2】:

    sergeantKK 的解决方案有效。

    如果有人在 c++ 中需要它,代码如下所示:

    void CALLBACK edgeCallback(void){return;}
    gluTessCallback(Tobj, GLU_TESS_EDGE_FLAG_DATA,reinterpret_cast<_GLUfuncptr>(edgeCallback));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多