gl.glBindProgramNV(GL.GL_VERTEX_PROGRAM_NV, vtxProg); gl.glLoadProgramNV(GL.GL_VERTEX_PROGRAM_NV, vtxProg, transformRefract.length(), transformRefract);
gl.glBindProgramARB  (GL.GL_VERTEX_PROGRAM_ARB, vtxProg); gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, transformRefract.length(), transformRefract);
    public void init(GLDrawable drawable) {      GL gl = drawable.getGL();      GLU glu = drawable.getGLU();      float cc = 1.0f;      gl.glClearColor(cc, cc, cc, 1);      gl.glColor3f(1,1,1);      gl.glEnable(GL.GL_DEPTH_TEST);      try {        initExtension(gl, "GL_NV_vertex_program");        initExtension(gl, "GL_NV_register_combiners");        initExtension(gl, "GL_NV_register_combiners");      } catch (RuntimeException e) {        runExit();        throw(e);      }      b[' '] = true; // animate by default      int[] vtxProgTmp = new int[1];      gl.glGenProgramsNV(1, vtxProgTmp);      vtxProg = vtxProgTmp[0];      gl.glBindProgramNV(GL.GL_VERTEX_PROGRAM_NV, vtxProg);      gl.glLoadProgramNV(GL.GL_VERTEX_PROGRAM_NV, vtxProg, transformRefract.length(), transformRefract);      // FIXME: is this necessary? Only for error checking?      //      nvparse((const char *)vprog::transform_refract);            gl.glTrackMatrixNV(GL.GL_VERTEX_PROGRAM_NV, 0,  GL.GL_MODELVIEW_PROJECTION_NV, GL.GL_IDENTITY_NV);      gl.glTrackMatrixNV(GL.GL_VERTEX_PROGRAM_NV, 4,  GL.GL_MODELVIEW,               GL.GL_INVERSE_TRANSPOSE_NV);      gl.glTrackMatrixNV(GL.GL_VERTEX_PROGRAM_NV, 8,  GL.GL_MODELVIEW,               GL.GL_IDENTITY_NV);      gl.glTrackMatrixNV(GL.GL_VERTEX_PROGRAM_NV, 12, GL.GL_TEXTURE,                 GL.GL_IDENTITY_NV);      gl.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 59, 0.0f, 0.0f, 0.0f, 1.0f);    // eye position      gl.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 62, fresnel, fresnel, fresnel, 1.0f);    // fresnel multiplier      gl.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 63, 1.0f, -1.0f, 1.0f, 0.0f);   // texture scale      gl.glProgramParameter4fNV(GL.GL_VERTEX_PROGRAM_NV, 64, 0.0f, 1.0f, 2.0f, 3.0f);    // misc constants      int[] cubemapTmp = new int[1];      gl.glGenTextures(1, cubemapTmp);      cubemap = cubemapTmp[0];      gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap);      gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);      gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);      try {        loadPNGCubemap(gl, glu, "demos/data/cubemaps/uffizi", true);      } catch (IOException e) {        runExit();        throw new RuntimeException(e);      }      gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);      gl.glDisable(GL.GL_CULL_FACE);      initCombiners(gl);      try {        bunnydl = Bunny.gen3DObjectList(gl);      } catch (IOException e) {        throw new RuntimeException(e);      }      drawable.addKeyListener(new KeyAdapter() {          public void keyTyped(KeyEvent e) {            dispatchKey(e.getKeyChar());          }        });      // Register the window with the ManipManager      ManipManager manager = ManipManager.getManipManager();      manager.registerWindow(drawable);      viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons());      viewer.setNoAltKeyMode(true);      viewer.attach(drawable, new BSphereProvider() {	  public BSphere getBoundingSphere() {	    return new BSphere(new Vec3f(0, 0, 0), 1.0f);	  }	});      viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f));      viewer.setZNear(0.1f);      viewer.setZFar(10.0f);    }