void
TVL1_ColorFlowEstimator_Direct::run(unsigned int I0_TexIDs[3], unsigned int I1_TexIDs[3])
{
    for (int level = _nLevels-1; level >= _startLevel; --level)
    {
        RTT_Buffer * ubuffer1 = _uBuffer1Pyramid[level];
        RTT_Buffer * ubuffer2 = _uBuffer2Pyramid[level];
        RTT_Buffer * pbuffer1 = _pBuffer1Pyramid[level];
        RTT_Buffer * pbuffer2 = _pBuffer2Pyramid[level];
        RTT_Buffer * qbuffer1 = _qBuffer1Pyramid[level];
        RTT_Buffer * qbuffer2 = _qBuffer2Pyramid[level];

        float const lambda = _lambda;
        //float const lambda = _lambda * sqrtf(1 << level);

        if (level == _nLevels-1)
        {
            glClearColor(0, 0, 0, 0);
            ubuffer2->activate();
            glClear(GL_COLOR_BUFFER_BIT);
            pbuffer2->activate();
            glClear(GL_COLOR_BUFFER_BIT);
            qbuffer2->activate();
            glClear(GL_COLOR_BUFFER_BIT);
        }
        else
        {
            //cout << "upsampleDisparities" << endl;
            upsampleDisparities(_uBuffer2Pyramid[level+1]->textureID(),
                                _pBuffer2Pyramid[level+1]->textureID(),
                                _qBuffer2Pyramid[level+1]->textureID(),
                                1.0f, *ubuffer2, *pbuffer2, *qbuffer2);
        }

        int const w = _width / (1 << level);
        int const h = _height / (1 << level);

        RTT_Buffer& warpedBuffer_R = *_warpedBufferPyramids[0][level];
        RTT_Buffer& warpedBuffer_G = *_warpedBufferPyramids[1][level];
        RTT_Buffer& warpedBuffer_B = *_warpedBufferPyramids[2][level];

        float const ds = 1.0f / w;
        float const dt = 1.0f / h;

        _shader_uv->parameter("timestep", _cfg._tau_primal);
        _shader_q->parameter("timestep", _cfg._tau_dual);
        _shader_q->parameter("lambda_q", _cfg._lambdaScale);
        _shader_p->parameter("timestep", _cfg._tau_dual);
        _shader_p->parameter("rcpLambda_p", (lambda / _cfg._lambdaScale));

        for (int iter = 0; iter < _nOuterIterations; ++iter)
        {
            warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs[0], I1_TexIDs[0], level, warpedBuffer_R);
            warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs[1], I1_TexIDs[1], level, warpedBuffer_G);
            warpImageWithFlowField(ubuffer2->textureID(), I0_TexIDs[2], I1_TexIDs[2], level, warpedBuffer_B);
            checkGLErrorsHere0();

            setupNormalizedProjection();

            for (int k = 0; k < _nInnerIterations /* * sqrtf(resizeFactor) */; ++k)
            {
                pbuffer1->activate();

                ubuffer2->enableTexture(GL_TEXTURE0_ARB);
                pbuffer2->enableTexture(GL_TEXTURE1_ARB);

                _shader_p->enable();
                renderNormalizedQuad(GPU_SAMPLE_REVERSE_NEIGHBORS, ds, dt);
                _shader_p->disable();

                //ubuffer2->disableTexture(GL_TEXTURE0_ARB);
                pbuffer2->disableTexture(GL_TEXTURE1_ARB);

                std::swap(pbuffer1, pbuffer2);

                ubuffer1->activate();

                //ubuffer2->enableTexture(GL_TEXTURE0_ARB);
                pbuffer2->enableTexture(GL_TEXTURE1_ARB);
                qbuffer2->enableTexture(GL_TEXTURE2_ARB);
                warpedBuffer_R.enableTexture(GL_TEXTURE3_ARB);
                warpedBuffer_G.enableTexture(GL_TEXTURE4_ARB);
                warpedBuffer_B.enableTexture(GL_TEXTURE5_ARB);

                _shader_uv->enable();
                renderNormalizedQuad(GPU_SAMPLE_REVERSE_NEIGHBORS, ds, dt);
                _shader_uv->disable();

                ubuffer2->disableTexture(GL_TEXTURE0_ARB);
                pbuffer2->disableTexture(GL_TEXTURE1_ARB);

                std::swap(ubuffer1, ubuffer2);

                qbuffer1->activate();

                ubuffer2->enableTexture(GL_TEXTURE0_ARB);

                _shader_q->enable();
                renderNormalizedQuad(GPU_SAMPLE_REVERSE_NEIGHBORS, ds, dt);
                _shader_q->disable();

                ubuffer2->disableTexture(GL_TEXTURE0_ARB);
                qbuffer2->disableTexture(GL_TEXTURE2_ARB);
                warpedBuffer_R.disableTexture(GL_TEXTURE3_ARB);
                warpedBuffer_G.disableTexture(GL_TEXTURE4_ARB);
                warpedBuffer_B.disableTexture(GL_TEXTURE5_ARB);

                std::swap(qbuffer1, qbuffer2);
            } // end for (k)
        } // end for (iter)
    } // end for (level)
} // end TVL1_ColorFlowEstimator_Direct::run()
   void
   PottsLabeling4_LevelFun::iterate(unsigned int costTexId, int nIterations)
   {
      static Cg_FragmentProgram * uShader = 0;
      static Cg_FragmentProgram * pqShader = 0;

      if (uShader == 0)
      {
         uShader = new Cg_FragmentProgram("PottsLabeling4_LevelFun::uShader");
         uShader->setProgramFromFile("potts_4labeling_levelfun_update_u.cg");

         uShader->compile();
         checkGLErrorsHere0();
      }

      if (pqShader == 0)
      {
         pqShader = new Cg_FragmentProgram("PottsLabeling4_LevelFun::pqShader");
         pqShader->setProgramFromFile("potts_4labeling_levelfun_update_pq.cg");
         pqShader->compile();
         checkGLErrorsHere0();
      }

      float const ds = 1.0f/_width;
      float const dt = 1.0f/_height;

      setupNormalizedProjection();

      uShader->parameter("tau", _tau_primal);
      pqShader->parameter("tau", _tau_dual);

      for (int iter = 0; iter < nIterations; ++iter)
      {
         _uBufB->activate();
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

         _uBufA->enableTexture(GL_TEXTURE0);
         _pFboA->getColorTexture(0).enable(GL_TEXTURE1);
         _pFboA->getColorTexture(1).enable(GL_TEXTURE2);
         _pFboA->getColorTexture(2).enable(GL_TEXTURE3);

         uShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         uShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);

         std::swap(_uBufA, _uBufB);

         _pFboB->activate();
         GLenum const buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
         glDrawBuffersARB(3, buffers);
         _uBufA->enableTexture(GL_TEXTURE0);

         glActiveTexture(GL_TEXTURE4);
         glBindTexture(GL_TEXTURE_2D, costTexId);
         glEnable(GL_TEXTURE_2D);

         pqShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         pqShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);
         _pFboA->getColorTexture(0).disable(GL_TEXTURE1);
         _pFboA->getColorTexture(1).disable(GL_TEXTURE2);
         _pFboA->getColorTexture(2).disable(GL_TEXTURE3);

         glActiveTexture(GL_TEXTURE4);
         glDisable(GL_TEXTURE_2D);

         std::swap(_pFboA, _pFboB);
      } // end for (iter)
   } // end PottsLabeling4_LevelFun::iterate()
   void
   BinarySegmentationUzawa::iterate(unsigned int costTexId, unsigned int edgeWeightTexId, int nIterations)
   {
      static Cg_FragmentProgram * uShader = 0;
      static Cg_FragmentProgram * pShader = 0;

      if (uShader == 0)
      {
         uShader = new Cg_FragmentProgram("BinarySegmentationUzawa::uShader");
         uShader->setProgramFromFile("binary_segmentation_uzawa_update_u.cg");
         uShader->compile();
         checkGLErrorsHere0();
      }

      if (pShader == 0)
      {
         pShader = new Cg_FragmentProgram("BinarySegmentationUzawa::pShader");
         pShader->setProgramFromFile("binary_segmentation_uzawa_update_p.cg");
         pShader->compile();
         checkGLErrorsHere0();
      }

      float const ds = 1.0f/_width;
      float const dt = 1.0f/_height;

      setupNormalizedProjection();

      uShader->parameter("tau", _tau_primal);
      pShader->parameter("tau", _tau_dual);
      checkGLErrorsHere0();

      glActiveTexture(GL_TEXTURE2);
      glBindTexture(GL_TEXTURE_2D, costTexId);
      glEnable(GL_TEXTURE_2D);

      glActiveTexture(GL_TEXTURE3);
      glBindTexture(GL_TEXTURE_2D, edgeWeightTexId);
      glEnable(GL_TEXTURE_2D);

      for (int iter = 0; iter < nIterations; ++iter)
      {
         // Update p
         _pBuffer[0]->activate();
         _uBuffer[1]->enableTexture(GL_TEXTURE0);
         _pBuffer[1]->enableTexture(GL_TEXTURE1);

         pShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         pShader->disable();

         _pBuffer[1]->disableTexture(GL_TEXTURE1);

         std::swap(_pBuffer[0], _pBuffer[1]);

         // Update u
         _uBuffer[0]->activate();

         _pBuffer[1]->enableTexture(GL_TEXTURE1);

         uShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         uShader->disable();

         _uBuffer[1]->disableTexture(GL_TEXTURE0);
         _pBuffer[1]->disableTexture(GL_TEXTURE1);

         std::swap(_uBuffer[0], _uBuffer[1]);
      } // end for (iter)

      glActiveTexture(GL_TEXTURE2);
      glDisable(GL_TEXTURE_2D);
      glActiveTexture(GL_TEXTURE3);
      glDisable(GL_TEXTURE_2D);
   } // end BinarySegmentationUzawa::iterate()
   void
   PottsLabeling3_Relaxed::iterate(unsigned int costTexId, int nIterations)
   {
      static Cg_FragmentProgram * uShader = 0;
      static Cg_FragmentProgram * pShader = 0;

      if (uShader == 0)
      {
         uShader = new Cg_FragmentProgram("PottsLabeling3_Relaxed::uShader");
         uShader->setProgramFromFile("potts_3labeling_update_u.cg");

#if defined(GPU_POTTS_LABELING_USE_PACKED_P)
         char const * args[] = { "-DUSE_PACKED_P=1", 0 };
         uShader->compile(args);
#else
         uShader->compile();
#endif
         checkGLErrorsHere0();
      }

      if (pShader == 0)
      {
         pShader = new Cg_FragmentProgram("PottsLabeling3_Relaxed::pShader");
         pShader->setProgramFromFile("potts_3labeling_update_p.cg");
#if defined(GPU_POTTS_LABELING_USE_PACKED_P)
         char const * args[] = { "-DUSE_PACKED_P=1", 0 };
         pShader->compile(args);
#else
         pShader->compile();
#endif
         checkGLErrorsHere0();
      }

      float const ds = 1.0f/_width;
      float const dt = 1.0f/_height;

      setupNormalizedProjection();

      uShader->parameter("theta", _theta);
      pShader->parameter("timestep_over_theta", _timestep/_theta);
      pShader->parameter("epsilon", _epsilon);

      for (int iter = 0; iter < nIterations; ++iter)
      {
#if defined(GPU_POTTS_LABELING_USE_PACKED_P)
         _uBufB->activate();
         //uShader->parameter("theta", theta);
         _uBufA->enableTexture(GL_TEXTURE0);
         _pBufA->enableTexture(GL_TEXTURE1);
         glActiveTexture(GL_TEXTURE2);
         glBindTexture(GL_TEXTURE_2D, costTexId);
         glEnable(GL_TEXTURE_2D);

         uShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         uShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);
         glActiveTexture(GL_TEXTURE2);
         glDisable(GL_TEXTURE_2D);

         std::swap(_uBufA, _uBufB);

         _pBufB->activate();
         //pShader->parameter("timestep_over_theta", tau/theta);
         _uBufA->enableTexture(GL_TEXTURE0);

         pShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         pShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);
         _pBufA->disableTexture(GL_TEXTURE1);

         std::swap(_pBufA, _pBufB);
#else
         _uBufB->activate();
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         //checkGLErrorsHere0();
         //uShader->parameter("theta", theta);
         _uBufA->enableTexture(GL_TEXTURE0);
         _pFboA->getColorTexture(0).enable(GL_TEXTURE1);
         _pFboA->getColorTexture(1).enable(GL_TEXTURE2);
         glActiveTexture(GL_TEXTURE3);
         glBindTexture(GL_TEXTURE_2D, costTexId);
         glEnable(GL_TEXTURE_2D);

         uShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         uShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);
         glActiveTexture(GL_TEXTURE3);
         glDisable(GL_TEXTURE_2D);
//          _pBufA->getColorTexture(0).disable(GL_TEXTURE1);
//          _pBufA->getColorTexture(1).disable(GL_TEXTURE2);

         std::swap(_uBufA, _uBufB);

         //pShader->parameter("timestep_over_theta", tau/theta);

         _pFboB->activate();
         GLenum const buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
         glDrawBuffersARB(2, buffers);
         //checkGLErrorsHere0();
         _uBufA->enableTexture(GL_TEXTURE0);
//          _pBufA->getColorTexture(0).enable(GL_TEXTURE1);
//          _pBufA->getColorTexture(1).enable(GL_TEXTURE2);

         pShader->enable();
         renderNormalizedQuad(GPU_SAMPLE_NEIGHBORS, ds, dt);
         pShader->disable();

         _uBufA->disableTexture(GL_TEXTURE0);
         _pFboA->getColorTexture(0).disable(GL_TEXTURE1);
         _pFboA->getColorTexture(1).disable(GL_TEXTURE2);

         std::swap(_pFboA, _pFboB);
#endif
      } // end for (iter)
   } // end PottsLabeling3_Relaxed::iterate()