コード例 #1
0
ファイル: Tessellation.java プロジェクト: 71104/simulejos
public class Tessellation {
  public static interface Callback {
    void index(short index);
  }

  private final Callback callback;
  private final GLUtessellator tessellator = GLU.gluNewTess();

  private static interface Handler {
    void index(short index);
  }

  private final class TriangleHandler implements Handler {
    @Override
    public void index(short index) {
      callback.index(index);
    }
  }

  private final TriangleHandler triangleHandler = new TriangleHandler();

  private final class TriangleStripHandler implements Handler {
    private boolean first;
    private boolean second;
    private short index1;
    private short index2;

    @Override
    public void index(short index) {
      if (!first) {
        index1 = index;
        first = true;
      } else if (first && !second) {
        index2 = index;
        second = true;
      } else {
        callback.index(index1);
        callback.index(index2);
        callback.index(index);
        index1 = index2;
        index2 = index;
      }
    }
  }

  private final TriangleStripHandler triangleStripHandler = new TriangleStripHandler();

  private final class TriangleFanHandler implements Handler {
    private boolean first;
    private boolean second;
    private short firstIndex;
    private short lastIndex;

    @Override
    public void index(short index) {
      if (!first) {
        firstIndex = index;
        first = true;
      } else if (first && !second) {
        lastIndex = index;
        second = true;
      } else {
        callback.index(firstIndex);
        callback.index(lastIndex);
        callback.index(index);
        lastIndex = index;
      }
    }
  }

  private final TriangleFanHandler triangleFanHandler = new TriangleFanHandler();

  {
    final GLUtessellatorCallback callback =
        new GLUtessellatorCallbackAdapter() {
          private volatile Handler handler;

          @Override
          public void begin(int type) {
            switch (type) {
              case GL.GL_TRIANGLES:
                handler = triangleHandler;
                break;
              case GL.GL_TRIANGLE_STRIP:
                handler = triangleStripHandler;
                break;
              case GL.GL_TRIANGLE_FAN:
                handler = triangleFanHandler;
                break;
            }
          }

          @Override
          public void vertex(Object index) {
            handler.index((short) index);
          }
        };
    GLU.gluTessCallback(tessellator, GLU.GLU_TESS_BEGIN, callback);
    GLU.gluTessCallback(tessellator, GLU.GLU_TESS_VERTEX, callback);
  }

  public Tessellation(float[] vertices, short[] indices, Callback callback) {
    this.callback = callback;
    GLU.gluBeginPolygon(tessellator);
    for (short index : indices) {
      double w = vertices[index * 4 + 3];
      GLU.gluTessVertex(
          tessellator,
          new double[] {
            vertices[index * 4] / w, vertices[index * 4 + 1] / w, vertices[index * 4 + 2] / w
          },
          0,
          index);
    }
    GLU.gluEndPolygon(tessellator);
  }

  @Override
  protected void finalize() {
    GLU.gluDeleteTess(tessellator);
  }
}