开发者

Is there a way to force GLUtessellator to use GL_TRIANGLES only?

I'm trying to use GLUtesselator to produce 3D extruded text in OpenGL. Here is the relevant code:

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.gluTessProp开发者_如何学Certy(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);
}

If I am to believe the RedBook in Chapter 11,

... if there is a callback associated with GLU_TESS_EDGE_FLAG that enables edge flags, the GLU_TESS_BEGIN callback is called only with GL_TRIANGLES.

then I believe that I should only be drawing using GL_TRIANGLES.

However, I can see that the type being called in my custom tessellator callbacks can be any of GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP or GL_TRIANGLES. I only ask if there's a way to force this because I'm too pushed for time to create a VBO that can handle anything else other than GL_QUADS or GL_TRIANGLES.


I'm sure if you just provided the edge callback (even if you did nothing with it), you would only get triangles. I must have had the same issue in the past and found this code and comment:

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

Nb, this is Delphi code but should still make sense. @tessEdgeData is a pointer to the callback routine which does nothing.


sergeantKK 's solution works.

In case someone needs it in c++, the code looks like this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜