public void paint(GeometryViewer viewer, GL gl, GLU glu) {
    float knots[] = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f};
    float flatControlPoints[];
    int i, j, k, flatCounter = 0;

    flatControlPoints = new float[4 * 4 * 3];
    for (i = 0; i < 4; i++)
      for (j = 0; j < 4; j++)
        for (k = 0; k < 3; k++) flatControlPoints[flatCounter++] = controlPoints[i][j][k];

    gl.pushMatrix();
    gl.rotate(330.0f, 1.f, 0.f, 0.f);
    gl.scale(0.5f, 0.5f, -0.5f);

    surface.beginSurface();
    surface.nurbsSurface(knots, knots, 4 * 3, 3, flatControlPoints, 4, 4, MAP2_VERTEX_3);
    surface.endSurface();

    if (showPoints == true) {
      gl.pointSize(5.0f);
      gl.disable(LIGHTING);
      gl.color(1.0f, 1.0f, 0.0f);
      gl.begin(POINTS);
      for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
          gl.vertex(controlPoints[i][j][0], controlPoints[i][j][1], controlPoints[i][j][2]);
        }
      }
      gl.end();
      gl.enable(LIGHTING);
    }
    gl.popMatrix();
  }
  public void glInit(GeometryViewer viewer, GL gl, GLU glu) {
    surface = getNewSurface();

    float mat_diffuse[] = {0.7f, 0.7f, 0.7f, 1.0f};
    float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
    float mat_shininess[] = {100.0f};

    gl.material(FRONT, DIFFUSE, mat_diffuse);
    gl.material(FRONT, SPECULAR, mat_specular);
    gl.material(FRONT, SHININESS, mat_shininess);

    gl.enable(LIGHTING);
    gl.enable(LIGHT0);
    gl.enable(DEPTH_TEST);
    gl.enable(AUTO_NORMAL);
    gl.enable(NORMALIZE);

    initSurface();

    surface.nurbsProperty(GLU_SAMPLING_TOLERANCE, 25.0f);
    surface.nurbsProperty(GLU_DISPLAY_MODE, GLU_FILL);
  }