// Wrapper around the native call for 3D textures
  void updateTextureImage(
      Canvas3D cv,
      int face,
      int numLevels,
      int level,
      int textureFormat,
      int imageFormat,
      int width,
      int height,
      int depth,
      int boundaryWidth,
      int imageDataType,
      Object imageData) {

    Pipeline.getPipeline()
        .updateTexture3DImage(
            cv.ctx,
            numLevels,
            level,
            textureFormat,
            imageFormat,
            width,
            height,
            depth,
            boundaryWidth,
            imageDataType,
            imageData,
            useAutoMipMapGeneration(cv));
  }
  void lookupShaderAttrNames(
      Context ctx,
      ShaderProgramId shaderProgramId,
      String[] attrNames,
      AttrNameInfo[] attrNameInfoArr) {

    int numAttrNames = attrNames.length;

    ShaderAttrLoc[] locArr = new ShaderAttrLoc[numAttrNames];
    int[] typeArr = new int[numAttrNames];
    int[] sizeArr = new int[numAttrNames]; // currently unused
    boolean[] isArrayArr = new boolean[numAttrNames];

    Pipeline.getPipeline()
        .lookupCgShaderAttrNames(
            ctx, shaderProgramId, numAttrNames, attrNames, locArr, typeArr, sizeArr, isArrayArr);

    for (int i = 0; i < numAttrNames; i++) {
      attrNameInfoArr[i] = new AttrNameInfo();
      attrNameInfoArr[i].setLocation(locArr[i]);
      attrNameInfoArr[i].setArray(isArrayArr[i]);
      attrNameInfoArr[i].setType(typeArr[i]);
      /*
      System.err.println(attrNames[i] +
              " : loc = " + locArr[i] +
              ", type = " + typeArr[i] +
              ", isArray = " + isArrayArr[i] +
              ", size = " + sizeArr[i]);
      */
    }
  }
  ShaderError setUniformMatrix4fArray(
      Context ctx,
      ShaderProgramId shaderProgramId,
      ShaderAttrLoc uniformLocation,
      int numElements,
      float[] value) {

    return Pipeline.getPipeline()
        .setCgUniformMatrix4fArray(ctx, shaderProgramId, uniformLocation, numElements, value);
  }
  void updateNative(Canvas3D cv) {
    int gMode = genMode;
    Transform3D m = cv.vworldToEc;

    if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_CUBE_MAP) == 0)
        && ((genMode == TexCoordGeneration.NORMAL_MAP)
            || (genMode == TexCoordGeneration.REFLECTION_MAP))) {
      gMode = TexCoordGeneration.SPHERE_MAP;
    }

    Pipeline.getPipeline()
        .updateTexCoordGeneration(
            cv.ctx, enable, gMode, format, planeS.x, planeS.y, planeS.z, planeS.w, planeT.x,
            planeT.y, planeT.z, planeT.w, planeR.x, planeR.y, planeR.z, planeR.w, planeQ.x,
            planeQ.y, planeQ.z, planeQ.w, m.mat);
  }
  // Wrapper around the native call for 3D textures
  void updateTextureSubImage(
      Canvas3D cv,
      int face,
      int level,
      int xoffset,
      int yoffset,
      int zoffset,
      int textureFormat,
      int imageFormat,
      int imgXOffset,
      int imgYOffset,
      int imgZOffset,
      int tilew,
      int tileh,
      int width,
      int height,
      int depth,
      int imageDataType,
      Object imageData) {

    Pipeline.getPipeline()
        .updateTexture3DSubImage(
            cv.ctx,
            level,
            xoffset,
            yoffset,
            zoffset,
            textureFormat,
            imageFormat,
            imgXOffset,
            imgYOffset,
            imgZOffset,
            tilew,
            tileh,
            width,
            height,
            depth,
            imageDataType,
            imageData,
            useAutoMipMapGeneration(cv));
  }
  void updateTextureBoundary(
      Context ctx,
      int boundaryModeS,
      int boundaryModeT,
      int boundaryModeR,
      float boundaryRed,
      float boundaryGreen,
      float boundaryBlue,
      float boundaryAlpha) {

    Pipeline.getPipeline()
        .updateTexture3DBoundary(
            ctx,
            boundaryModeS,
            boundaryModeT,
            boundaryModeR,
            boundaryRed,
            boundaryGreen,
            boundaryBlue,
            boundaryAlpha);
  }
  void updateTextureLodRange(
      Context ctx, int baseLevel, int maximumLevel, float minimumLod, float maximumLod) {

    Pipeline.getPipeline()
        .updateTexture3DLodRange(ctx, baseLevel, maximumLevel, minimumLod, maximumLod);
  }
  void updateTextureLodOffset(Context ctx, float lodOffsetX, float lodOffsetY, float lodOffsetZ) {

    Pipeline.getPipeline().updateTexture3DLodOffset(ctx, lodOffsetX, lodOffsetY, lodOffsetZ);
  }
 /** Method to compile the native shader. */
 ShaderError compileShader(Context ctx, ShaderId shaderId, String source) {
   return Pipeline.getPipeline().compileCgShader(ctx, shaderId, source);
 }
 /** Method to create the native shader. */
 ShaderError createShader(Context ctx, ShaderRetained shader, ShaderId[] shaderIdArr) {
   return Pipeline.getPipeline().createCgShader(ctx, shader.shaderType, shaderIdArr);
 }
  void updateTextureFilter4Func(Context ctx, int numFilter4FuncPts, float[] filter4FuncPts) {

    Pipeline.getPipeline().updateTexture3DFilter4Func(ctx, numFilter4FuncPts, filter4FuncPts);
  }
 void updateTextureAnisotropicFilter(Context ctx, float degree) {
   Pipeline.getPipeline().updateTexture3DAnisotropicFilter(ctx, degree);
 }
  void updateTextureFilterModes(Context ctx, int minFilter, int magFilter) {

    Pipeline.getPipeline().updateTexture3DFilterModes(ctx, minFilter, magFilter);
  }
 void lookupVertexAttrNames(
     Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, boolean[] errArr) {
   Pipeline.getPipeline()
       .lookupCgVertexAttrNames(ctx, shaderProgramId, attrNames.length, attrNames, errArr);
 }
 /** Method to create the native shader program. */
 ShaderError createShaderProgram(Context ctx, ShaderProgramId[] shaderProgramIdArr) {
   return Pipeline.getPipeline().createCgShaderProgram(ctx, shaderProgramIdArr);
 }
 /** This method updates the native context. */
 void updateNative(Context ctx) {
   Pipeline.getPipeline()
       .updateLineAttributes(
           ctx, lineWidth, linePattern, linePatternMask, linePatternScaleFactor, lineAntialiasing);
 }
 /** Method to disable the native shader program. */
 ShaderError disableShaderProgram(Context ctx) {
   return Pipeline.getPipeline().useCgShaderProgram(ctx, null);
 }
 /** Method to enable the native shader program. */
 ShaderError enableShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
   return Pipeline.getPipeline().useCgShaderProgram(ctx, shaderProgramId);
 }
 /** Method to destroy the native shader program. */
 ShaderError destroyShaderProgram(Context ctx, ShaderProgramId shaderProgramId) {
   return Pipeline.getPipeline().destroyCgShaderProgram(ctx, shaderProgramId);
 }
 /** This method updates the native context. */
 void bindTexture(Context ctx, int objectId, boolean enable) {
   Pipeline.getPipeline().bindTexture3D(ctx, objectId, enable);
 }
  void updateTextureSharpenFunc(
      Context ctx, int numSharpenTextureFuncPts, float[] sharpenTextureFuncPts) {

    Pipeline.getPipeline()
        .updateTexture3DSharpenFunc(ctx, numSharpenTextureFuncPts, sharpenTextureFuncPts);
  }
  ShaderError setUniform4f(
      Context ctx, ShaderProgramId shaderProgramId, ShaderAttrLoc uniformLocation, float[] value) {

    return Pipeline.getPipeline().setCgUniform4f(ctx, shaderProgramId, uniformLocation, value);
  }
 /** Method to link the native shader program. */
 ShaderError linkShaderProgram(
     Context ctx, ShaderProgramId shaderProgramId, ShaderId[] shaderIds) {
   return Pipeline.getPipeline().linkCgShaderProgram(ctx, shaderProgramId, shaderIds);
 }