protected void CreateBracketMesh() {
    // System.err.println( iWidth + " " + iHeight + " " + iDepth );
    Attributes kAttributes = new Attributes();
    kAttributes.SetPChannels(3);

    int iVQuantity = 3;
    VertexBuffer pkVB = new VertexBuffer(kAttributes, iVQuantity);

    // generate geometry

    float[] afChannels = pkVB.GetData();
    int iIndex = 0;
    afChannels[iIndex++] = 0;
    afChannels[iIndex++] = -1.0f;
    afChannels[iIndex++] = 0.0f;
    afChannels[iIndex++] = 0;
    afChannels[iIndex++] = 0.0f;
    afChannels[iIndex++] = 0.5f;
    afChannels[iIndex++] = 0;
    afChannels[iIndex++] = 0.95f;
    afChannels[iIndex++] = 1.0f;

    m_kBracketPoints = new Polypoint(pkVB);
    AlphaState kAlpha = new AlphaState();
    kAlpha.BlendEnabled = true;
    kAlpha.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    kAlpha.DstBlend = AlphaState.DstBlendMode.DBF_ONE;
    m_kBracketPoints.AttachGlobalState(kAlpha);
    m_kBracketPoints.UpdateGS();
    m_kBracketPoints.UpdateRS();
  }
  private void cleanUp() {
    // System.err.println( "VolumeImageViewerPoint dispose()" );
    if (m_kHistogramPoints2D != null) {
      m_pkRenderer.ReleaseResources(m_kHistogramPoints2D);
      m_kHistogramPoints2D.dispose();
      m_kHistogramPoints2D = null;
    }
    if (m_kEntropyPoints2D != null) {
      m_pkRenderer.ReleaseResources(m_kEntropyPoints2D);
      m_kEntropyPoints2D.dispose();
      m_kEntropyPoints2D = null;
    }
    if (m_kImagePointsDual != null) {
      m_kImagePointsDual.DetachAllEffects();
      m_pkRenderer.ReleaseResources(m_kImagePointsDual);
      m_kImagePointsDual.dispose();
      m_kImagePointsDual = null;
    }

    if (m_kHistogramOutput != null) {
      m_kHistogramOutput.GetTarget(0).GetImage().dispose();
      m_kHistogramOutput.GetTarget(0).dispose();
      m_kHistogramOutput.TerminateBuffer();
      m_kHistogramOutput.dispose();
    }
    if (m_kHistogramOutputB != null) {
      m_kHistogramOutputB.GetTarget(0).GetImage().dispose();
      m_kHistogramOutputB.GetTarget(0).dispose();
      m_kHistogramOutputB.TerminateBuffer();
      m_kHistogramOutputB.dispose();
    }
    if (m_kEntropyOut != null) {
      m_kEntropyOut.GetTarget(0).GetImage().dispose();
      m_kEntropyOut.GetTarget(0).dispose();
      m_kEntropyOut.TerminateBuffer();
      m_kEntropyOut.dispose();
    }
    if (m_akImageReduceEntropy != null) {
      m_pkRenderer.ReleaseResources(m_akImageReduceEntropy);
      m_akImageReduceEntropy.dispose();
    }
    if (m_akCollapse2D != null) {
      m_pkRenderer.ReleaseResources(m_akCollapse2D);
      m_akCollapse2D.dispose();
    }
    if (m_akCollapseColumns != null) {
      m_pkRenderer.ReleaseResources(m_akCollapseColumns);
      m_akCollapseColumns.dispose();
    }
    if (m_akCollapseRows != null) {
      m_pkRenderer.ReleaseResources(m_akCollapseRows);
      m_akCollapseRows.dispose();
    }
  }
  protected void CreateScene(GLAutoDrawable arg0) {
    int iWidth = m_iWidth;
    int iHeight = m_iHeight;

    int iDepth = m_kImageA.nDims == 3 ? m_kImageA.extents[2] : 1;
    m_kHistogramOutput = CreateRenderTarget(arg0, "Histogram2D", iWidth, iHeight);
    m_kHistogramOutputB = CreateRenderTarget(arg0, "Histogram2DB", iWidth, iHeight);
    m_kEntropyOut = CreateRenderTarget(arg0, "EntropyOut", 1, 1);

    if (CreateImageMesh(m_kImageA.extents[0], m_kImageA.extents[1], iDepth) == null) {
      CreateImageMesh(m_kImageA.extents[0], m_kImageA.extents[1], 1);
      m_iRenderLoops = iDepth;
      System.err.println("Switching to 2.5D");
    }
    m_kImagePointsDual.AttachEffect(m_kImageEffectDual);
    m_kImageEffectDual.SetImageSize(m_kImageA.extents[0], m_kImageA.extents[1], iDepth);

    CreateHistogramMesh(m_iWidth, m_iHeight);
    m_akCollapse2D =
        new VolumeHistogramEffect(m_kHistogramOutput.GetTarget(0), VolumeHistogramEffect.NONE);
    m_akCollapseColumns =
        new VolumeHistogramEffect(
            m_kHistogramOutput.GetTarget(0), VolumeHistogramEffect.COLLAPSE_COLUMNS);
    m_akCollapseRows =
        new VolumeHistogramEffect(
            m_kHistogramOutput.GetTarget(0), VolumeHistogramEffect.COLLAPSE_ROWS);

    m_kHistogramPoints2D.AttachEffect(m_akCollapse2D);
    AlphaState pkAState = m_akCollapse2D.GetBlending(0);
    pkAState.BlendEnabled = true;
    pkAState.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    pkAState.DstBlend = AlphaState.DstBlendMode.DBF_ONE;

    m_kHistogramPoints2D.AttachEffect(m_akCollapseColumns);
    pkAState = m_akCollapseColumns.GetBlending(0);
    pkAState.BlendEnabled = true;
    pkAState.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    pkAState.DstBlend = AlphaState.DstBlendMode.DBF_ONE;

    m_kHistogramPoints2D.AttachEffect(m_akCollapseRows);
    pkAState = m_akCollapseRows.GetBlending(0);
    pkAState.BlendEnabled = true;
    pkAState.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    pkAState.DstBlend = AlphaState.DstBlendMode.DBF_ONE;

    double dSize = m_kImageA.dataSize;
    m_akImageReduceEntropy = new ImageReduceEffect(m_kHistogramOutputB.GetTarget(0), dSize);
    m_kEntropyPoints2D.AttachEffect(m_akImageReduceEntropy);
    /*
          m_kImageLineMinPass2a = new LineMinimizationEffect( m_kBracketOut.GetTarget(0), m_kEntropyOut.GetTarget(0), m_fMinDist, (float)dSize, m_kImageA.nDims  );
          m_kImageLineMinDual.SetImageSize( m_kImageA.extents[0],m_kImageA.extents[1],iDepth );
    */
  }
  private void calcEntropy(ModelSimpleImage kImage, double dNumSamples) {
    m_kImagePointsDual.DetachAllEffects();
    m_kImagePointsDual.AttachEffect(m_kImageEffectDual);
    m_pkRenderer.Resize(
        m_kHistogramOutput.GetTarget(0).GetImage().GetBound(0),
        m_kHistogramOutput.GetTarget(0).GetImage().GetBound(1));
    m_kHistogramOutput.Enable();
    m_pkRenderer.ClearColorDepth();
    // m_pkRenderer.ClearBuffers();
    int iDepth = m_kImageA.nDims == 3 ? m_kImageA.extents[2] : 1;
    float fInv2 = 1.0f / (iDepth);
    float fW;
    for (int i = 0; i < m_iRenderLoops; i++) {
      if (m_iRenderLoops == 1) {
        m_kImageEffectDual.ZSlice(0f);
      } else {
        fW = i * fInv2;
        m_kImageEffectDual.ZSlice(((2.0f * fW - 1.0f)));
        m_kImageEffectDual.UseZSlice();
      }
      m_pkRenderer.Draw(m_kImagePointsDual);
    }
    // writeImage();
    m_kHistogramOutput.Disable();
    // printTarget( "HistoOut" , m_kHistogramOutput.GetTarget(0) );

    m_pkRenderer.Resize(
        m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(0),
        m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(1));
    m_kHistogramOutputB.Enable();
    m_pkRenderer.ClearColorDepth();
    // m_pkRenderer.ClearBuffers();

    // m_kHistogramPoints2D.DetachAllEffects();
    // m_kHistogramPoints2D.AttachEffect(m_akCollapse2D);
    m_pkRenderer.Draw(m_kHistogramPoints2D);

    // m_kHistogramPoints2D.DetachAllEffects();
    // m_kHistogramPoints2D.AttachEffect(m_akCollapseColumns);
    // m_pkRenderer.Draw(m_kHistogramPoints2D);

    // m_kHistogramPoints2D.DetachAllEffects();
    // m_kHistogramPoints2D.AttachEffect(m_akCollapseRows);
    // m_pkRenderer.Draw(m_kHistogramPoints2D);

    // m_pkRenderer.Draw(m_kHistogramPoints2D);
    m_kHistogramOutputB.Disable();
    // printTarget( "HistoOut" , m_kHistogramOutputB.GetTarget(0) );
    ReduceDualA(dNumSamples);
  }
  protected ResourceIdentifier CreateImageMesh(int iWidth, int iHeight, int iDepth) {
    // System.err.println( iWidth + " " + iHeight + " " + iDepth );
    Attributes kAttributes = new Attributes();
    kAttributes.SetPChannels(3);

    int iVQuantity = iWidth * iHeight * iDepth;
    VertexBuffer pkVB = new VertexBuffer(kAttributes, iVQuantity);

    // generate geometry
    float fInv0 = 1.0f / (iWidth - 1.0f);
    float fInv1 = 1.0f / (iHeight - 1.0f);
    float fInv2 = 1.0f / (iDepth);
    float fU, fV, fW;
    int i0, i1, i2;

    float[] afChannels = pkVB.GetData();
    int iIndex = 0;

    for (i2 = 0; i2 < iDepth; i2++) {
      fW = i2 * fInv2;
      for (i1 = 0; i1 < iHeight; i1++) {
        fV = i1 * fInv1;
        for (i0 = 0; i0 < iWidth; i0++) {
          fU = i0 * fInv0;
          afChannels[iIndex++] = ((2.0f * fU - 1.0f));
          afChannels[iIndex++] = ((2.0f * fV - 1.0f));
          afChannels[iIndex++] = ((2.0f * fW - 1.0f));
        }
      }
    }

    m_kImagePointsDual = new Polypoint(pkVB);
    m_kAlpha = new AlphaState();
    m_kAlpha.BlendEnabled = true;
    m_kAlpha.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    m_kAlpha.DstBlend = AlphaState.DstBlendMode.DBF_ONE;
    m_kImagePointsDual.AttachGlobalState(m_kAlpha);
    m_kImagePointsDual.UpdateGS();
    m_kImagePointsDual.UpdateRS();

    return m_pkRenderer.LoadVBuffer(pkVB.GetAttributes(), pkVB.GetAttributes(), pkVB);
  }
  protected void CreateHistogramMesh(int iWidth, int iHeight) {
    Attributes kAttributes = new Attributes();
    kAttributes.SetPChannels(3);

    int iVQuantity = iWidth * iHeight;
    VertexBuffer pkVB = new VertexBuffer(kAttributes, iVQuantity);

    // generate geometry
    float fInv0 = 1.0f / (iWidth);
    float fInv1 = 1.0f / (iHeight);
    float fU, fV;
    int i0, i1;

    float[] afChannels = pkVB.GetData();
    int iIndex = 0;

    for (i1 = 0; i1 < iHeight; i1++) {
      fV = i1 * fInv1;
      for (i0 = 0; i0 < iWidth; i0++) {
        fU = i0 * fInv0;
        afChannels[iIndex++] = ((2.0f * fU - 1.0f));
        afChannels[iIndex++] = ((2.0f * fV - 1.0f));
        afChannels[iIndex++] = 0f;

        // System.err.println( ((2.0f*fU-1.0f)) + " " + ((2.0f*fV-1.0f)));
      }
    }
    m_kHistogramPoints2D = new Polypoint(pkVB);
    m_kEntropyPoints2D = new Polypoint(pkVB);

    AlphaState kAlpha = new AlphaState();
    kAlpha.BlendEnabled = true;
    kAlpha.SrcBlend = AlphaState.SrcBlendMode.SBF_ONE;
    kAlpha.DstBlend = AlphaState.DstBlendMode.DBF_ONE;

    m_kHistogramPoints2D.AttachGlobalState(kAlpha);
    m_kHistogramPoints2D.UpdateGS();
    m_kHistogramPoints2D.UpdateRS();

    m_kEntropyPoints2D.AttachGlobalState(kAlpha);
    m_kEntropyPoints2D.UpdateGS();
    m_kEntropyPoints2D.UpdateRS();
  }
  private void calcLineMin() {
    m_kImagePointsDual.DetachAllEffects();
    m_kImagePointsDual.AttachEffect(m_kImageLineMinDual);
    boolean bEarly = false;
    Texture kTarget = null;
    OpenGLFrameBuffer kCurrentBracket = m_kBracketOut;
    OpenGLFrameBuffer kNewBracket = m_kBracketNewOut;
    OpenGLFrameBuffer kTempBracket;
    for (int i = 0; i < 100; i++) {
      m_kCalcTransform.SetTexture(kCurrentBracket.GetTarget(0), 0, 0);
      m_kImageLineMinPass2a.SetTexture(kCurrentBracket.GetTarget(0), 0, 0);

      // 1. Create the transform matrix based on the current bracket.
      m_pkRenderer.Resize(
          m_kTransformOut.GetTarget(0).GetImage().GetBound(0),
          m_kTransformOut.GetTarget(0).GetImage().GetBound(1));
      m_kTransformOut.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kTransformPoints);
      m_kTransformOut.Disable();
      /*
      kTarget = m_kTransformOut.GetTarget(0);
      m_pkRenderer.GetTexImage( kTarget );
      for ( int j = 0; j < kTarget.GetImage().GetFloatData().length; j++ )
      {
          System.err.print( kTarget.GetImage().GetFloatData()[j] + " " );
      }
      System.err.println( " " ); */

      // 1. Render all image points w/LineMin1 shaders
      m_pkRenderer.Resize(
          m_kHistogramOutput.GetTarget(0).GetImage().GetBound(0),
          m_kHistogramOutput.GetTarget(0).GetImage().GetBound(1));
      m_kHistogramOutput.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kImagePointsDual);
      m_kHistogramOutput.Disable();

      // 2. Render Histogram points
      m_pkRenderer.Resize(
          m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(0),
          m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(1));
      m_kHistogramOutputB.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kHistogramPoints2D);
      m_kHistogramOutputB.Disable();

      // 3. Render Entropy points w/LineMin1 shader
      m_pkRenderer.Resize(
          m_kEntropyOut.GetTarget(0).GetImage().GetBound(0),
          m_kEntropyOut.GetTarget(0).GetImage().GetBound(1));
      m_kEntropyOut.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kEntropyPoints2D);
      m_kEntropyOut.Disable();

      // 4. Render bracket points w/LineMin2 shader
      m_kBracketPoints.DetachAllEffects();
      m_kBracketPoints.AttachEffect(m_kImageLineMinPass2a);
      m_pkRenderer.Resize(
          kNewBracket.GetTarget(0).GetImage().GetBound(0),
          kNewBracket.GetTarget(0).GetImage().GetBound(1));
      kNewBracket.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kBracketPoints);
      kNewBracket.Disable();
      kTempBracket = kCurrentBracket;
      kCurrentBracket = kNewBracket;
      kNewBracket = kTempBracket;

      if ((i % 6) == 0) {
        // kTarget = m_kBracketOut.GetTarget(0);
        kTarget = kCurrentBracket.GetTarget(0);
        m_pkRenderer.GetTexImage(kTarget);
        /*
        System.err.println("");
        System.err.println("");
        System.err.println( "GPU BracketA = " + kTarget.GetImage().GetFloatData()[0] + " " + kTarget.GetImage().GetFloatData()[1]);
        System.err.println( "GPU BracketB = " + kTarget.GetImage().GetFloatData()[4] + " " + kTarget.GetImage().GetFloatData()[5]);
        System.err.println( "GPU BracketC = " + kTarget.GetImage().GetFloatData()[8] + " " + kTarget.GetImage().GetFloatData()[9]);
        System.err.println( "   " + i + " xNew = " + kTarget.GetImage().GetFloatData()[3] + " yNew = " +
                kTarget.GetImage().GetFloatData()[6]  + " case: " + kTarget.GetImage().GetFloatData()[7] + " " +
                kTarget.GetImage().GetFloatData()[10] + " " +
                kTarget.GetImage().GetFloatData()[11]);
                */
        if ((Math.abs(kTarget.GetImage().GetFloatData()[8] - kTarget.GetImage().GetFloatData()[0])
            <= m_fUnitTolerance)) {
          m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
          m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
          bEarly = true;
          break;
        }
        if (kTarget.GetImage().GetFloatData()[3] == 0) {
          m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
          m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
          bEarly = true;
          System.err.println("BREAK EARLY BAD");
          break;
        }
      }
    }
    if (!bEarly) {
      // kTarget = m_kBracketOut.GetTarget(0);
      kTarget = kCurrentBracket.GetTarget(0);
      m_pkRenderer.GetTexImage(kTarget);
      m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
      m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
      /*
          System.err.println("");
          System.err.println("");
          System.err.println( "GPU BracketA = " + kTarget.GetImage().GetFloatData()[0] + " " + kTarget.GetImage().GetFloatData()[1]);
          System.err.println( "GPU BracketB = " + kTarget.GetImage().GetFloatData()[4] + " " + kTarget.GetImage().GetFloatData()[5]);
          System.err.println( "GPU BracketC = " + kTarget.GetImage().GetFloatData()[8] + " " + kTarget.GetImage().GetFloatData()[9]);
      */
    }
    // System.err.println( m_afBracketB[0] + " " + m_afBracketB[1] );
  }
  public void dispose(GLAutoDrawable arg0) {

    cleanUp();
    if (m_kTextureA != null) {
      m_kTextureA.Release();
      m_kTextureA.GetImage().dispose();
      m_kTextureA.dispose();
      m_kTextureA = null;
    }
    if (m_kTextureB != null) {
      m_kTextureB.Release();
      m_kTextureB.GetImage().dispose();
      m_kTextureB.dispose();
      m_kTextureB = null;
    }

    if (m_kBracketPoints != null) {
      m_pkRenderer.ReleaseResources(m_kBracketPoints);
      m_kBracketPoints.dispose();
      m_kBracketPoints = null;
    }
    if (m_kTransformPoints != null) {
      m_pkRenderer.ReleaseResources(m_kTransformPoints);
      m_kTransformPoints.dispose();
      m_kTransformPoints = null;
    }

    if (m_kImageEffectDual != null) {
      m_pkRenderer.ReleaseResources(m_kImageEffectDual);
      m_kImageEffectDual.dispose();
    }
    if (m_kImageLineMinDual != null) {
      m_pkRenderer.ReleaseResources(m_kImageLineMinDual);
      m_kImageLineMinDual.dispose();
    }
    if (m_kCalcTransform != null) {
      m_pkRenderer.ReleaseResources(m_kCalcTransform);
      m_kCalcTransform.dispose();
    }

    if (m_kBracketOut != null) {
      m_kBracketOut.GetTarget(0).GetImage().dispose();
      m_kBracketOut.GetTarget(0).dispose();
      m_kBracketOut.TerminateBuffer();
      m_kBracketOut.dispose();
    }
    if (m_kTransformOut != null) {
      m_kTransformOut.GetTarget(0).GetImage().dispose();
      m_kTransformOut.GetTarget(0).dispose();
      m_kTransformOut.TerminateBuffer();
      m_kTransformOut.dispose();
    }
    if (m_kBracketNewOut != null) {
      m_kBracketNewOut.GetTarget(0).GetImage().dispose();
      m_kBracketNewOut.GetTarget(0).dispose();
      m_kBracketNewOut.TerminateBuffer();
      m_kBracketNewOut.dispose();
    }

    ImageCatalog.GetActive().dispose();
    VertexProgramCatalog.GetActive().dispose();
    PixelProgramCatalog.GetActive().dispose();
    CompiledProgramCatalog.GetActive().dispose();

    super.dispose();
  }