void OcclusionCullingTreeBuilder::drawTestResults(DrawEnv             &denv,
                                                  RenderPartitionBase *part)
{
    OCRenderTreeNode* pNode;
    while (!_testPendingNodes.empty())
    {
        pNode = _testPendingNodes.front();
        //DRAW DRAW DRAW
        if(pNode->hasFunctor() == true && !pNode->getIsRendered())
        {
            Window* win = denv.getWindow();
            GetQueryObjectuivT getquiv =
                reinterpret_cast<GetQueryObjectuivT>(
                    win->getFunction(_funcGetQueryObjectuivARB));
            GLuint available = 0;
            getquiv(_testSamples[pNode->getResultNum()], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
            if (!available)
            {
                //std::cout << "Waiting on " << pNode->getResultNum() << " buf size:" << _testPendingNodes.size() << std::endl;
                return;
            }
            GLuint sampleCount = 1;  //XXX: Set to what it should be from calc above.
            getquiv(_testSamples[pNode->getResultNum()], GL_QUERY_RESULT_ARB, &sampleCount);

            if(sampleCount > _visPixelThreshold)
            {
                drawNode(pNode, denv, part);
            }
            else
            {
                StatCollector *sc = _ract->getStatCollector();
                if(sc != NULL)
                    sc->getElem(statNOccInvisible)->inc();

                DrawableStatsAttachment *st =
                    DrawableStatsAttachment::get(pNode->getNode()->getCore());

                st->validate();

                if(sc != NULL)
                    sc->getElem(statNOccTriangles)->
                        add(st->getTriangles());

                if(_ract->getOcclusionCullingDebug() && pNode->getNode())
                {
                    pNode->getNode()->setTravMask(
                        pNode->getNode()->getTravMask() |
                        _ract->getOcclusionCulledDebugMask()
                        );
                }
            }
        }
        //std::cout << "Popped: " << pNode->getResultNum() << " buf size now: " << _testPendingNodes.size() - 1 <<  std::endl;
        _testPendingNodes.pop();
    }
}
void OcclusionCullingTreeBuilder::drawTestNode(OCRenderTreeNode    *pNode,
                                               DrawEnv             &denv,
                                               RenderPartitionBase *part)
{

    //std::cout << "Front: " << _currSample << " Back: " << _currSampleBack << std::endl;
    while(_testPendingNodes.size() == _numTestSamples - 1)
    {
        drawTestResults(denv, part);
        //std::cout << "NOW:  Front: " << _currSample << " Back: " << _currSampleBack << std::endl;
    }

    //DRAW DRAW DRAW
    Window* win = denv.getWindow();
    pNode->setIsRendered(false);


    if(_ract->getOcclusionCullingDebug() && pNode->getNode())
    {
        pNode->getNode()->setTravMask(
            pNode->getNode()->getTravMask() |
            _ract->getOcclusionTestedDebugMask()
            );
    }

    const BoxVolume &volume = pNode->getVolume();
    Pnt3f min,max;
    volume.getBounds(min, max);
    static GLfloat n[6][3] = {
    {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
    {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0}
    };
    static GLint faces[6][4] = {
    { 0, 1, 2, 3}, { 3, 2, 6, 7}, { 7, 6, 5, 4},
    { 4, 5, 1, 0}, { 5, 6, 2, 1}, { 7, 4, 0, 3}
    };

    GLfloat v[8][3];
    v[0][0] = v[1][0] = v[2][0] = v[3][0] = min[0];
    v[4][0] = v[5][0] = v[6][0] = v[7][0] = max[0];
    v[0][1] = v[1][1] = v[4][1] = v[5][1] = min[1];
    v[2][1] = v[3][1] = v[6][1] = v[7][1] = max[1];
    v[0][2] = v[3][2] = v[4][2] = v[7][2] = min[2];
    v[1][2] = v[2][2] = v[5][2] = v[6][2] = max[2];


    if(_currSample == _numTestSamples - 1)
    {
        _currSample = 0;
    }
    _currSample++;

    StatCollector *sc = _ract->getStatCollector();
    if(sc != NULL)
        sc->getElem(statNOccTests    )->inc();

    enterTesting(denv, part);
    BeginQueryT beginq = reinterpret_cast<BeginQueryT>(
        win->getFunction(_funcBeginQueryARB));
    //std::cout << "Push: " << _currSample << std::endl;
    pNode->setResultNum(_currSample);
    beginq(GL_SAMPLES_PASSED_ARB, _testSamples[_currSample]);
    glBegin(GL_QUADS);
    for(UInt32 i = 0; i<6; i++)
    {
           glNormal3fv(&n[i][0]);
           glVertex3fv(&v[faces[i][0]][0]);
           glNormal3fv(&n[i][0]);
           glVertex3fv(&v[faces[i][1]][0]);
           glNormal3fv(&n[i][0]);
           glVertex3fv(&v[faces[i][2]][0]);
           glNormal3fv(&n[i][0]);
           glVertex3fv(&v[faces[i][3]][0]);
    }
    glEnd();

    EndQueryT endq = reinterpret_cast<EndQueryT>(
        win->getFunction(_funcEndQueryARB));

    endq(GL_SAMPLES_PASSED_ARB);
    _testPendingNodes.push(pNode);
}
void OcclusionCullingTreeBuilder::draw(DrawEnv             &denv,
                                       RenderPartitionBase *part)
{
#if 1 //CHECK_ENV_ACTION
    //std::cout << "Frame Start" << std::endl;
    Window* win = denv.getWindow();

    if(_sortMode == ModeAdaptiveBucket)
    {
        // Merge all the buckets to a tree
        for(UInt32 i = 0; i < _numBuckets; ++i)
        {
            if(_buckets[i] != NULL)
            {
                _pRoot->addChild(_buckets[i]);
            }
        }
    }

    if(!win->hasExtension(_extOcclusionQuery))
    {
        // Don't have it, just draw the whole tree.
        SLOG << "Missing OCC GL extensions!!" << endLog;

        _uiActiveMatrix = 0;
        Inherited::drawNode(_pRoot, denv, part);

        return;
    }

//SETUP
// done in add, action should never change
//    _ract = dynamic_cast<RenderAction*>(denv.getAction());

    if(!_ract)
    {
        FFATAL(("OcclusionCullingTreeBuilder::draw: Action in denv is not a "
                "RenderAction!\n"));
        return;
    }

    _uiActiveMatrix = 0;
    Real32 screenCoveredPercentage = 0.f;
    if(_ract->getOcclusionCullingQueryBufferSize() != _numTestSamples || !_occInitialized)
    {
        _numTestSamples = _ract->getOcclusionCullingQueryBufferSize();
        //std::cout << "Buf size: " << _numTestSamples << std::endl;
        _testSamples.resize(_numTestSamples);
        //std::cout << "Performing OCC on " << _numNodes << " nodes." << std::endl;

        GenQueryT genquer = reinterpret_cast<GenQueryT>(
            win->getFunction(_funcGenQueriesARB));
        genquer(_numTestSamples, &(_testSamples.front()));
        _occInitialized = true;
    }

    if(!_isOccStateCreated)
    {
        _isOccStateCreated = true;

        // register an exit function to clean up the State object
        addPreFactoryExitFunction(&releaseTestingState);

        // Create an empty state to render test nodes.
        _testingStatePtr = State::create();

        DepthChunkUnrecPtr dc = DepthChunk::create();
        dc->setReadOnly(true);
        _testingStatePtr->addChunk(dc);

        ColorMaskChunkUnrecPtr cc = ColorMaskChunk::create();
        cc->setMaskR(false);
        cc->setMaskG(false);
        cc->setMaskB(false);
        cc->setMaskA(false);
        _testingStatePtr->addChunk(cc);

        PolygonChunkUnrecPtr pc = PolygonChunk::create();
        pc->setCullFace(GL_BACK);
        _testingStatePtr->addChunk(pc);

        commitChanges();
    }

    //glGenQueriesARB(_numNodes, queries);
    //std::cout << "Calculated Pixels" << std::endl;

    _vpWidth  = denv.getPixelWidth();
    _vpHeight = denv.getPixelHeight();

    _worldToScreen = denv.getVPWorldToScreen();

    _testingState = &*_testingStatePtr;


    _minFeatureSize = _ract->getOcclusionCullingMinimumFeatureSize();
    _visPixelThreshold = _ract->getOcclusionCullingVisibilityThreshold();
    _coveredProbThreshold = _ract->getOcclusionCullingCoveredThreshold();
    _minTriangleCount = _ract->getOcclusionCullingMinimumTriangleCount();
    _inTesting = false;

    _currSample = 0;
//DRAW / TEST / RE-DRAW ON BUFFER FULL
    testNode(_pRoot, denv, part, screenCoveredPercentage);

    StatCollector *sc = _ract->getStatCollector();
    if(sc != NULL)
        sc->getElem(statNOccNodes)->add(_numNodes);
    _numNodes=0;
    _uiActiveMatrix = 0;

    leaveTesting(denv, part);

//RESULTS / RE-DRAW
    while( !_testPendingNodes.empty() )
    {
        drawTestResults(denv, part);
    }

    //std::cout << "Calc Pixels" << std::endl;


    if(sc != NULL)
    {
        Real32 percentage =
            Real32(sc->getElem(statNOccInvisible)->get()) /
            Real32(sc->getElem(statNOccTests)->get());
        sc->getElem(statNOccSuccessTestPer)->set(percentage);
    }

    //std::cout << "Real pixels " << std::endl;
    //std::cout << std::endl;

   // screen_covered_percentage = 1.0;
   // drawNode(_pRoot, denv, part, screen_covered_percentage);
    _numNodes=0;
    _currSample = 0;
    //std::cout << "Frame End" << std::endl;
#endif
}