From 492f117fd3f76c7a5778ca2a07c6f5803242b8e0 Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Sun, 24 Apr 2005 22:59:51 +0000
Subject: Merged with current JOGL trunk (by using -r HEAD)

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JSR-231@262 232f8b59-042b-4e1e-8c03-345bb8c30851
---
 src/net/java/games/jogl/util/GLUT.java | 344 +++++++++++++++++++++++++++++++++
 1 file changed, 344 insertions(+)

(limited to 'src/net/java/games/jogl/util/GLUT.java')

diff --git a/src/net/java/games/jogl/util/GLUT.java b/src/net/java/games/jogl/util/GLUT.java
index 36b54d6b1..70144d66e 100644
--- a/src/net/java/games/jogl/util/GLUT.java
+++ b/src/net/java/games/jogl/util/GLUT.java
@@ -204,6 +204,74 @@ public class GLUT {
     tetrahedron(gl, GL.GL_TRIANGLES);
   }
 
+/**
+   * Renders the teapot as a solid shape of the specified size. The teapot is
+   * created in a way that replicates the C GLUT implementation.
+   * 
+   * @param gl
+   *        the OpenGL context in which to render the teapot
+   * @param scale
+   *        the factor by which to scale the teapot
+   */
+  public void glutSolidTeapot(GL gl, double scale) {
+    glutSolidTeapot(gl, scale, true);
+  }
+
+  /**
+   * Renders the teapot as a solid shape of the specified size. The teapot can
+   * either be created in a way that is backward-compatible with the standard
+   * C glut library (i.e. broken), or in a more pleasing way (i.e. with
+   * surfaces whose front-faces point outwards and standing on the z=0 plane,
+   * instead of the y=-1 plane). Both surface normals and texture coordinates
+   * for the teapot are generated. The teapot is generated with OpenGL
+   * evaluators.
+   * 
+   * @param gl
+   *        the OpenGL context in which to render the teapot
+   * @param scale
+   *        the factor by which to scale the teapot
+   * @param cStyle
+   *        whether to create the teapot in exactly the same way as in the C
+   *        implementation of GLUT
+   */
+  public void glutSolidTeapot(GL gl, double scale, boolean cStyle) {
+    teapot(gl, 14, scale, GL.GL_FILL, cStyle);
+  }
+
+  /**
+   * Renders the teapot as a wireframe shape of the specified size. The teapot
+   * is created in a way that replicates the C GLUT implementation.
+   * 
+   * @param gl
+   *        the OpenGL context in which to render the teapot
+   * @param scale
+   *        the factor by which to scale the teapot
+   */
+  public void glutWireTeapot(GL gl, double scale) {
+    glutWireTeapot(gl, scale, true);
+  }
+  
+  /**
+   * Renders the teapot as a wireframe shape of the specified size. The teapot
+   * can either be created in a way that is backward-compatible with the
+   * standard C glut library (i.e. broken), or in a more pleasing way (i.e.
+   * with surfaces whose front-faces point outwards and standing on the z=0
+   * plane, instead of the y=-1 plane). Both surface normals and texture
+   * coordinates for the teapot are generated. The teapot is generated with
+   * OpenGL evaluators.
+   * 
+   * @param gl
+   *        the OpenGL context in which to render the teapot
+   * @param scale
+   *        the factor by which to scale the teapot
+   * @param cStyle
+   *        whether to create the teapot in exactly the same way as in the C
+   *        implementation of GLUT
+   */
+  public void glutWireTeapot(GL gl, double scale, boolean cStyle) {
+    teapot(gl, 10, scale, GL.GL_LINE, cStyle);
+  }
+
   //----------------------------------------------------------------------
   // Fonts
   //
@@ -736,6 +804,282 @@ public class GLUT {
       drawtriangle(gl, i, tdata, tndex, shadeType);
   }
 
+  // Teapot implementation (a modified port of glut_teapot.c)
+  //
+  // Rim, body, lid, and bottom data must be reflected in x and
+  // y; handle and spout data across the y axis only.
+  private static final int[][] teapotPatchData = {
+    /* rim */
+    {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+    /* body */
+    {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
+    {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
+    /* lid */
+    {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
+    {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
+    /* bottom */
+    {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
+    /* handle */
+    {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
+    {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
+    /* spout */
+    {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
+    {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
+  };
+  private static final float[][] teapotCPData = {
+    {0.2f, 0f, 2.7f},
+    {0.2f, -0.112f, 2.7f},
+    {0.112f, -0.2f, 2.7f},
+    {0f, -0.2f, 2.7f},
+    {1.3375f, 0f, 2.53125f},
+    {1.3375f, -0.749f, 2.53125f},
+    {0.749f, -1.3375f, 2.53125f},
+    {0f, -1.3375f, 2.53125f},
+    {1.4375f, 0f, 2.53125f},
+    {1.4375f, -0.805f, 2.53125f},
+    {0.805f, -1.4375f, 2.53125f},
+    {0f, -1.4375f, 2.53125f},
+    {1.5f, 0f, 2.4f},
+    {1.5f, -0.84f, 2.4f},
+    {0.84f, -1.5f, 2.4f},
+    {0f, -1.5f, 2.4f},
+    {1.75f, 0f, 1.875f},
+    {1.75f, -0.98f, 1.875f},
+    {0.98f, -1.75f, 1.875f},
+    {0f, -1.75f, 1.875f},
+    {2f, 0f, 1.35f},
+    {2f, -1.12f, 1.35f},
+    {1.12f, -2f, 1.35f},
+    {0f, -2f, 1.35f},
+    {2f, 0f, 0.9f},
+    {2f, -1.12f, 0.9f},
+    {1.12f, -2f, 0.9f},
+    {0f, -2f, 0.9f},
+    {-2f, 0f, 0.9f},
+    {2f, 0f, 0.45f},
+    {2f, -1.12f, 0.45f},
+    {1.12f, -2f, 0.45f},
+    {0f, -2f, 0.45f},
+    {1.5f, 0f, 0.225f},
+    {1.5f, -0.84f, 0.225f},
+    {0.84f, -1.5f, 0.225f},
+    {0f, -1.5f, 0.225f},
+    {1.5f, 0f, 0.15f},
+    {1.5f, -0.84f, 0.15f},
+    {0.84f, -1.5f, 0.15f},
+    {0f, -1.5f, 0.15f},
+    {-1.6f, 0f, 2.025f},
+    {-1.6f, -0.3f, 2.025f},
+    {-1.5f, -0.3f, 2.25f},
+    {-1.5f, 0f, 2.25f},
+    {-2.3f, 0f, 2.025f},
+    {-2.3f, -0.3f, 2.025f},
+    {-2.5f, -0.3f, 2.25f},
+    {-2.5f, 0f, 2.25f},
+    {-2.7f, 0f, 2.025f},
+    {-2.7f, -0.3f, 2.025f},
+    {-3f, -0.3f, 2.25f},
+    {-3f, 0f, 2.25f},
+    {-2.7f, 0f, 1.8f},
+    {-2.7f, -0.3f, 1.8f},
+    {-3f, -0.3f, 1.8f},
+    {-3f, 0f, 1.8f},
+    {-2.7f, 0f, 1.575f},
+    {-2.7f, -0.3f, 1.575f},
+    {-3f, -0.3f, 1.35f},
+    {-3f, 0f, 1.35f},
+    {-2.5f, 0f, 1.125f},
+    {-2.5f, -0.3f, 1.125f},
+    {-2.65f, -0.3f, 0.9375f},
+    {-2.65f, 0f, 0.9375f},
+    {-2f, -0.3f, 0.9f},
+    {-1.9f, -0.3f, 0.6f},
+    {-1.9f, 0f, 0.6f},
+    {1.7f, 0f, 1.425f},
+    {1.7f, -0.66f, 1.425f},
+    {1.7f, -0.66f, 0.6f},
+    {1.7f, 0f, 0.6f},
+    {2.6f, 0f, 1.425f},
+    {2.6f, -0.66f, 1.425f},
+    {3.1f, -0.66f, 0.825f},
+    {3.1f, 0f, 0.825f},
+    {2.3f, 0f, 2.1f},
+    {2.3f, -0.25f, 2.1f},
+    {2.4f, -0.25f, 2.025f},
+    {2.4f, 0f, 2.025f},
+    {2.7f, 0f, 2.4f},
+    {2.7f, -0.25f, 2.4f},
+    {3.3f, -0.25f, 2.4f},
+    {3.3f, 0f, 2.4f},
+    {2.8f, 0f, 2.475f},
+    {2.8f, -0.25f, 2.475f},
+    {3.525f, -0.25f, 2.49375f},
+    {3.525f, 0f, 2.49375f},
+    {2.9f, 0f, 2.475f},
+    {2.9f, -0.15f, 2.475f},
+    {3.45f, -0.15f, 2.5125f},
+    {3.45f, 0f, 2.5125f},
+    {2.8f, 0f, 2.4f},
+    {2.8f, -0.15f, 2.4f},
+    {3.2f, -0.15f, 2.4f},
+    {3.2f, 0f, 2.4f},
+    {0f, 0f, 3.15f},
+    {0.8f, 0f, 3.15f},
+    {0.8f, -0.45f, 3.15f},
+    {0.45f, -0.8f, 3.15f},
+    {0f, -0.8f, 3.15f},
+    {0f, 0f, 2.85f},
+    {1.4f, 0f, 2.4f},
+    {1.4f, -0.784f, 2.4f},
+    {0.784f, -1.4f, 2.4f},
+    {0f, -1.4f, 2.4f},
+    {0.4f, 0f, 2.55f},
+    {0.4f, -0.224f, 2.55f},
+    {0.224f, -0.4f, 2.55f},
+    {0f, -0.4f, 2.55f},
+    {1.3f, 0f, 2.55f},
+    {1.3f, -0.728f, 2.55f},
+    {0.728f, -1.3f, 2.55f},
+    {0f, -1.3f, 2.55f},
+    {1.3f, 0f, 2.4f},
+    {1.3f, -0.728f, 2.4f},
+    {0.728f, -1.3f, 2.4f},
+    {0f, -1.3f, 2.4f},
+    {0f, 0f, 0f},
+    {1.425f, -0.798f, 0f},
+    {1.5f, 0f, 0.075f},
+    {1.425f, 0f, 0f},
+    {0.798f, -1.425f, 0f},
+    {0f, -1.5f, 0.075f},
+    {0f, -1.425f, 0f},
+    {1.5f, -0.84f, 0.075f},
+    {0.84f, -1.5f, 0.075f}
+  };
+  // Since GL.glMap2f expects a packed array of floats, we must convert
+  // from a 3-dimensional array to a 1-dimensional array
+  private static final float[] teapotTex = {
+    0, 0, 1, 0, 0, 1, 1, 1
+  };
+
+  private static void teapot(GL gl,
+                             int grid,
+                             double scale,
+                             int type,
+                             boolean backCompatible)
+  {
+    // As mentioned above, GL.glMap2f expects a packed array of floats
+    float[] p = new float[4*4*3];
+    float[] q = new float[4*4*3];
+    float[] r = new float[4*4*3];
+    float[] s = new float[4*4*3];
+    int i, j, k, l;
+  
+    gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_EVAL_BIT | GL.GL_POLYGON_BIT);
+    gl.glEnable(GL.GL_AUTO_NORMAL);
+    gl.glEnable(GL.GL_NORMALIZE);
+    gl.glEnable(GL.GL_MAP2_VERTEX_3);
+    gl.glEnable(GL.GL_MAP2_TEXTURE_COORD_2);
+    if (!backCompatible) {
+      // The time has come to have the teapot no longer be inside out
+      gl.glFrontFace(GL.GL_CW);
+      gl.glScaled(0.5*scale, 0.5*scale, 0.5*scale);
+    } else {
+      // We want the teapot in it's backward compatible position and
+      // orientation
+      gl.glPushMatrix();
+      gl.glRotatef(270.0f, 1, 0, 0);
+      gl.glScalef((float)(0.5 * scale),
+                  (float)(0.5 * scale),
+                  (float)(0.5 * scale));
+      gl.glTranslatef(0.0f, 0.0f, -1.5f);
+    }
+    for (i = 0; i < 10; i++) {
+      for (j = 0; j < 4; j++) {
+        for (k = 0; k < 4; k++) {
+          for (l = 0; l < 3; l++) {
+            p[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+            q[(j*4+k)*3+l] =
+              teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+            if (l == 1)
+              q[(j*4+k)*3+l] *= -1.0;
+            if (i < 6) {
+              r[(j*4+k)*3+l] =
+                teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+              if (l == 0)
+                r[(j*4+k)*3+l] *= -1.0;
+              s[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+              if (l == 0)
+                s[(j*4+k)*3+l] *= -1.0;
+              if (l == 1)
+                s[(j*4+k)*3+l] *= -1.0;
+            }
+          }
+        }
+      }
+      gl.glMap2f(GL.GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, teapotTex);
+      gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, p);
+      gl.glMapGrid2f(grid, 0.0f, 1.0f, grid, 0.0f, 1.0f);
+      evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+      gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, q);
+      evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+      if (i < 6) {
+        gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, r);
+        evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+        gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, s);
+        evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+      }
+    }
+    if (backCompatible) {
+      gl.glPopMatrix();
+    }
+    gl.glPopAttrib();
+  }
+  
+  private static void evaluateTeapotMesh(GL gl,
+                                         int grid,
+                                         int type,
+                                         int partNum,
+                                         boolean repairSingularities)
+  {
+    if (repairSingularities && (partNum == 5 || partNum == 3)) {
+      // Instead of using evaluators that give bad results at singularities,
+      // evaluate by hand
+      gl.glPolygonMode(GL.GL_FRONT_AND_BACK, type);
+      for (int nv = 0; nv < grid; nv++) {
+        if (nv == 0) {
+          // Draw a small triangle-fan to fill the hole
+          gl.glDisable(GL.GL_AUTO_NORMAL);
+          gl.glNormal3f(0, 0, partNum == 3 ? 1 : -1);
+          gl.glBegin(GL.GL_TRIANGLE_FAN);
+          {
+            gl.glEvalCoord2f(0, 0);
+            // Note that we draw in clock-wise order to match the evaluator
+            // method
+            for (int nu = 0; nu <= grid; nu++)
+            {
+              gl.glEvalCoord2f(nu / (float)grid, (1f / grid) / (float)grid);
+            }
+          }
+          gl.glEnd();
+          gl.glEnable(GL.GL_AUTO_NORMAL);
+        }
+        // Draw the rest of the piece as an evaluated quad-strip
+        gl.glBegin(GL.GL_QUAD_STRIP);
+        {
+          // Note that we draw in clock-wise order to match the evaluator method
+          for (int nu = grid; nu >= 0; nu--) {
+            gl.glEvalCoord2f(nu / (float)grid, (nv + 1) / (float)grid);
+            gl.glEvalCoord2f(nu / (float)grid, Math.max(nv, 1f / grid)
+                                                         / (float)grid);
+          }
+        }
+        gl.glEnd();
+      }
+    } else {
+      gl.glEvalMesh2(type, 0, grid, 0, grid);
+    }
+  }
+
   //----------------------------------------------------------------------
   // Font implementation
   //
-- 
cgit v1.2.3