tmpCubeMapFilenamePattern = null;
tmpCubeMapFilenamePrefix  = null; tmpCubeMapFilenameSuffix  = null;
  private void initOpenGL(GL gl) {    loadTextures(gl, tmpSpinFilename, tmpDropletFilename, tmpCubeMapFilenamePattern);    tmpSpinFilename           = null;    tmpDropletFilename        = null;    tmpCubeMapFilenamePattern = null;    gl.glMatrixMode(GL.GL_MODELVIEW);    gl.glLoadIdentity();    gl.glMatrixMode(GL.GL_PROJECTION);    gl.glLoadIdentity();    glu.gluOrtho2D(-1, 1, -1, 1);        gl.glClearColor(0, 0, 0, 0);    gl.glDisable(GL.GL_LIGHTING);    gl.glDisable(GL.GL_DEPTH_TEST);          createAndWriteUVOffsets(gl, initialMapDimensions[0], initialMapDimensions[1]);    checkExtension(gl, "GL_ARB_vertex_program");    checkExtension(gl, "GL_ARB_fragment_program");    checkExtension(gl, "GL_ARB_multitexture");    ///////////////////////////////////////////////////////////////////////////    // UV Offset Vertex Program    ///////////////////////////////////////////////////////////////////////////    int[] tmpInt = new int[1];    gl.glGenProgramsARB(1, tmpInt, 0);    vertexProgramID = tmpInt[0];    gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vertexProgramID);    String programBuffer = "!!ARBvp1.0\n" +"# Constant memory location declarations (must match those in Java sources)\n" +"# CV_UV_OFFSET_TO_USE = 0\n" +"\n" +"# CV_UV_T0_NO_OFFSET  = 1\n" +"# CV_UV_T0_TYPE1      = 2\n" +"# CV_UV_T0_TYPE2      = 3\n" +"# CV_UV_T0_TYPE3      = 4\n" +"# CV_UV_T0_TYPE4      = 5\n" +"\n" +"# CV_UV_T1_NO_OFFSET  = 6\n" +"# CV_UV_T1_TYPE1      = 7\n" +"# CV_UV_T1_TYPE2      = 8\n" +"# CV_UV_T1_TYPE3      = 9\n" +"# CV_UV_T1_TYPE4      = 10\n" +"\n" +"# CV_UV_T2_NO_OFFSET  = 11\n" +"# CV_UV_T2_TYPE1      = 12\n" +"# CV_UV_T2_TYPE2      = 13\n" +"# CV_UV_T2_TYPE3      = 14\n" +"# CV_UV_T2_TYPE4      = 15\n" +"\n" +"# CV_UV_T3_NO_OFFSET  = 16\n" +"# CV_UV_T3_TYPE1      = 17\n" +"# CV_UV_T3_TYPE2      = 18\n" +"# CV_UV_T3_TYPE3      = 19\n" +"# CV_UV_T3_TYPE4      = 20\n" +"\n" +"# CV_CONSTS_1         = 21\n" +"\n" +"# Parameters\n" +"PARAM mvp [4]       = { state.matrix.mvp };     # modelview projection matrix\n" +"PARAM uvOffsetToUse = program.env[0];\n" +"PARAM uvOffsets[20] = { program.env[1..20] };\n" +"\n" +"# Addresses\n" +"ADDRESS addr;\n" +"\n" +"# Per vertex inputs\n" +"ATTRIB iPos         = vertex.position;          #position\n" +"\n" +"# Outputs\n" +"OUTPUT oPos         = result.position;          #position\n" +"\n" +"# Transform vertex-position to clip-space\n" +"DP4 oPos.x, iPos, mvp[0];\n" +"DP4 oPos.y, iPos, mvp[1];\n" +"DP4 oPos.z, iPos, mvp[2];\n" +"DP4 oPos.w, iPos, mvp[3];\n" +"\n" +"# Read which set of offsets to use\n" +"ARL addr.x, uvOffsetToUse.x;\n" +"\n" +"#    c[CV_CONSTS_1] = c[28]\n" +"#    x = 0\n" +"#    y = 0.5\n" +"#    z = 1\n" +"#    w = 2.0f\n" +"\n" +"#    Put a scale factor into r0 so the sample points\n" +"#    can be moved farther from the texel being written\n" +"#    MOV R0, c[28].z;\n" +"\n" +"# Add the offsets to the input texture\n" +"# coordinate, creating 4 sets of independent\n" +"# texture coordinates.\n" +"ADD result.texcoord[0], uvOffsets[addr.x     ], vertex.texcoord[0];\n" +"ADD result.texcoord[1], uvOffsets[addr.x + 5 ], vertex.texcoord[0];\n" +"ADD result.texcoord[2], uvOffsets[addr.x + 10], vertex.texcoord[0];\n" +"ADD result.texcoord[3], uvOffsets[addr.x + 15], vertex.texcoord[0];\n" +"\n" +"END\n";    // set up constants (not currently used in the vertex program, though)    float[] rCVConsts = new float[] { 0, 0.5f, 1.0f, 2.0f };    gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_CONSTS_1, rCVConsts, 0);    loadProgram(gl, GL.GL_VERTEX_PROGRAM_ARB, programBuffer);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup for equal weight combination of texels    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_EQ_WEIGHT_COMBINE] = gl.glGenLists(1);    initEqWeightCombine_PostMult(gl, displayListIDs[CA_FRAGMENT_PROGRAM_EQ_WEIGHT_COMBINE]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup for computing force from neighbors (step 1)    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_NEIGHBOR_FORCE_CALC_1] = gl.glGenLists(1);    initNeighborForceCalcStep1(gl, displayListIDs[CA_FRAGMENT_PROGRAM_NEIGHBOR_FORCE_CALC_1]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup for computing force from neighbors (step 2)    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_NEIGHBOR_FORCE_CALC_2] = gl.glGenLists(1);    initNeighborForceCalcStep2(gl, displayListIDs[CA_FRAGMENT_PROGRAM_NEIGHBOR_FORCE_CALC_2]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup to apply force    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_APPLY_FORCE] = gl.glGenLists(1);    initApplyForce(gl, displayListIDs[CA_FRAGMENT_PROGRAM_APPLY_FORCE]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup to apply velocity    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_APPLY_VELOCITY] = gl.glGenLists(1);    initApplyVelocity(gl, displayListIDs[CA_FRAGMENT_PROGRAM_APPLY_VELOCITY]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup to create a normal map    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_CREATE_NORMAL_MAP] = gl.glGenLists(1);    initCreateNormalMap(gl, displayListIDs[CA_FRAGMENT_PROGRAM_CREATE_NORMAL_MAP]);    ///////////////////////////////////////////////////////////////////////////    // fragment program setup for dot product reflection    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_FRAGMENT_PROGRAM_REFLECT] = gl.glGenLists(1);    initDotProductReflect(gl, displayListIDs[CA_FRAGMENT_PROGRAM_REFLECT]);    ///////////////////////////////////////////////////////////////////////////    // display list to render a single screen space quad.    ///////////////////////////////////////////////////////////////////////////    displayListIDs[CA_DRAW_SCREEN_QUAD] = gl.glGenLists(1);    gl.glNewList(displayListIDs[CA_DRAW_SCREEN_QUAD], GL.GL_COMPILE);    gl.glColor4f(1, 1, 1, 1);    gl.glBegin(GL.GL_TRIANGLE_STRIP);    gl.glTexCoord2f(0, 1); gl.glVertex2f(-1,  1);    gl.glTexCoord2f(0, 0); gl.glVertex2f(-1, -1);    gl.glTexCoord2f(1, 1); gl.glVertex2f( 1,  1);    gl.glTexCoord2f(1, 0); gl.glVertex2f( 1, -1);    gl.glEnd();    gl.glEndList();  }