} if (bigArray != bigArrayVBO) {
    public void display(GLDrawable drawable) {      // Don't try to do OpenGL operations if we're tearing things down      if (quit) {        return;      }      GL  gl  = drawable.getGL();      GLU glu = drawable.getGLU();      // Check to see whether to animate      if (getFlag(' ')) {        phase += phaseRate;        phase2 += phase2Rate;        if (phase > (float) (20 * Math.PI)) {          phase = 0;        }        if (phase2 < (float) (-20 * Math.PI)) {          phase2 = 0;        }      }      PeriodicIterator loX =        new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase, (float) ((1.f/tileSize)*lofreq*Math.PI));      PeriodicIterator loY = new PeriodicIterator(loX);      PeriodicIterator hiX =        new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase2, (float) ((1.f/tileSize)*hifreq*Math.PI));      PeriodicIterator hiY = new PeriodicIterator(hiX);      if (toggleVBO) {        vboEnabled = !vboEnabled;        if (!vboEnabled) {          bigArray = bigArraySystem;          setupBuffers();        }        toggleVBO = false;      }      if (toggleLighting) {        if (getFlag('d')) {          gl.glDisable(GL.GL_LIGHTING);        } else {          gl.glEnable(GL.GL_LIGHTING);        }        toggleLighting = false;      }      if (toggleLightingModel) {        if(getFlag('i')) {          // infinite light          gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0 });          gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0);        } else {          gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, -.5f,1 });          gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 1);        }        toggleLightingModel = false;      }      if (recomputeElements) {        computeElements();        recomputeElements = false;      }      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);      gl.glPushMatrix();      final float[] modelViewMatrix = new float[] {          1, 0, 0, 0,          0, 1, 0, 0,          0, 0, 1, 0,          0, 0, -1, 1      };      gl.glLoadMatrixf(modelViewMatrix);      // FIXME: add mouse interaction      // camera.apply_inverse_transform();      // object.apply_transform();      int cur = 0;      int numSlabs = tileSize / STRIP_SIZE;      if (vboEnabled) {        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, bigBufferObject);      } else {        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);      }      for(int slab = numSlabs; --slab>=0; ) {        cur = slab % numBuffers;        if (vboEnabled) {          ByteBuffer tmp = gl.glMapBufferARB(GL.GL_ARRAY_BUFFER_ARB, GL.GL_WRITE_ONLY_ARB);          if (tmp == null) {            throw new RuntimeException("Unable to map vertex buffer object");          }          if (tmp != bigArrayVBOBytes) {            bigArrayVBOBytes = tmp;            bigArrayVBO = setupBuffer(tmp);            bigArray = bigArrayVBO;            setupBuffers();          }        }        FloatBuffer v = buffers[cur].vertices;        int vertexIndex = 0;        if (vboEnabled) {          gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, BufferUtils.bufferOffset(buffers[cur].vertexOffset));          gl.glNormalPointer(   GL.GL_FLOAT, 6 * SIZEOF_FLOAT, BufferUtils.bufferOffset(buffers[cur].normalOffset));        } else {          gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, v);          gl.glNormalPointer(   GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normals);        }        for(int jj=STRIP_SIZE; --jj>=0; ) {          ysinlo[jj] = sinArray[loY.getIndex()];          ycoslo[jj] = cosArray[loY.getIndex()]; loY.incr();          ysinhi[jj] = sinArray[hiY.getIndex()];          ycoshi[jj] = cosArray[hiY.getIndex()]; hiY.incr();        }        loY.decr();        hiY.decr();        for(int i = tileSize; --i>=0; ) {          float x = xyArray[i];          int loXIndex = loX.getIndex();          int hiXIndex = hiX.getIndex();          int jOffset = (STRIP_SIZE-1)*slab;          float nx = locoef * -cosArray[loXIndex] + hicoef * -cosArray[hiXIndex];          // Help the HotSpot Client Compiler by hoisting loop          // invariant variables into locals. Note that this may be          // good practice for innermost loops anyway since under          // the new memory model operations like accidental          // synchronization may force any compiler to reload these          // fields from memory, destroying their ability to          // optimize.          float locoef_tmp = locoef;          float hicoef_tmp = hicoef;          float[] ysinlo_tmp = ysinlo;          float[] ysinhi_tmp = ysinhi;          float[] ycoslo_tmp = ycoslo;          float[] ycoshi_tmp = ycoshi;          float[] sinArray_tmp = sinArray;          float[] xyArray_tmp = xyArray;          for(int j = STRIP_SIZE; --j>=0; ) {            float y;            y = xyArray_tmp[j + jOffset];            float ny;            v.put(vertexIndex, x);            v.put(vertexIndex + 1, y);            v.put(vertexIndex + 2, (locoef_tmp * (sinArray_tmp[loXIndex] + ysinlo_tmp[j]) +                                    hicoef_tmp * (sinArray_tmp[hiXIndex] + ysinhi_tmp[j])));            v.put(vertexIndex + 3, nx);            ny = locoef_tmp * -ycoslo_tmp[j] + hicoef_tmp * -ycoshi_tmp[j];            v.put(vertexIndex + 4, ny);            v.put(vertexIndex + 5, .15f); //.15f * (1.f - sqrt(nx * nx + ny * ny));            vertexIndex += 6;          }          loX.incr();          hiX.incr();        }        loX.reset();        hiX.reset();        if (vboEnabled) {          gl.glUnmapBufferARB(GL.GL_ARRAY_BUFFER_ARB);        }        for (int i = 0; i < elements.length; i++) {          ++numDrawElementsCalls;          gl.glDrawElements(primitive, elements[i].length, GL.GL_UNSIGNED_INT, elements[i]);          if(getFlag('f')) {            gl.glFlush();          }        }      }      gl.glPopMatrix();      if (getFlag('r')) {        if (!firstProfiledFrame) {          if (++profiledFrameCount == 30) {            long endTimeMillis = System.currentTimeMillis();            double secs = (endTimeMillis - startTimeMillis) / 1000.0;            double fps  = 30.0 / secs;            double ppf  = tileSize * tileSize * 2;            double mpps = ppf * fps / 1000000.0;            System.err.println("fps: " + fps + " polys/frame: " + ppf + " million polys/sec: " + mpps +                               " DrawElements calls/frame: " + (numDrawElementsCalls / 30));            profiledFrameCount = 0;            numDrawElementsCalls = 0;            startTimeMillis = System.currentTimeMillis();          }        } else {          startTimeMillis = System.currentTimeMillis();          firstProfiledFrame = false;        }      }    }