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 }