Есть ли способ заставить GLUtessellator использовать только GL_TRIANGLES? - PullRequest
3 голосов
/ 30 июня 2011

Я пытаюсь использовать GLUtesselator для создания трехмерного экструдированного текста в OpenGL. Вот соответствующий код:

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, который включает флаги границ, обратный вызов GLU_TESS_BEGIN вызывается только с GL_TRIANGLES.

тогда я считаю, что я должен рисовать только с использованием GL_TRIANGLES.

Однако я вижу, что тип, вызываемый в моих пользовательских обратных вызовах tessellator, может быть любым из GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP или GL_TRIANGLES. Я только спрашиваю, есть ли способ заставить это, потому что у меня слишком мало времени для создания VBO, которое может обрабатывать что-то еще, кроме GL_QUADS или GL_TRIANGLES.

Ответы [ 2 ]

2 голосов
/ 31 октября 2011

Решение sergeantKK работает.

В случае, если кому-то это нужно на c ++, код выглядит следующим образом:

void CALLBACK edgeCallback(void){return;}
gluTessCallback(Tobj, GLU_TESS_EDGE_FLAG_DATA,reinterpret_cast<_GLUfuncptr>(edgeCallback));
2 голосов
/ 26 октября 2011

Я уверен, что если вы только что предоставили обратный вызов (даже если вы ничего не сделали с ним), вы получите только треугольники. Должно быть, в прошлом у меня была такая же проблема, и я нашел этот код и комментарий:

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

Nb, это код Delphi, но он все же должен иметь смысл. @tessEdgeData - указатель на процедуру обратного вызова, которая ничего не делает.

...