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 DrawableStatsAttachment::invalidate(FieldContainer *obj) { if(obj == NULL) return; AttachmentContainer *cont = dynamic_cast<AttachmentContainer *>(obj); // Called on a non-AttachmentContainer? if(cont == NULL) return; // Find the attachment DrawableStatsAttachment *st = get(cont); if(st == NULL) // Found the end of the chain return; // Invalidate it st->reset(); // Traverse upwards if(st->getMFParents()->size()) { // Can't have more than 1 FieldContainer *p = dynamic_cast<FieldContainer *>(st->getParents(0)); // Is this attached to a NodeCore? NodeCore *c = dynamic_cast<NodeCore *>(p); if(c != NULL) { MFParentFieldContainerPtr::const_iterator pnI; for( pnI = c->getMFParents()->begin(); pnI != c->getMFParents()->end (); ++pnI) { Node *node = dynamic_cast<Node *>(*pnI); invalidate(node); } } // Is this attached to a Node? Node *n = dynamic_cast<Node *>(p); if(n != NULL) { Node *par = n->getParent(); invalidate(par); } } }
void DrawableStatsAttachmentBase::execSyncV( FieldContainer &oFrom, ConstFieldMaskArg whichField, AspectOffsetStore &oOffsets, ConstFieldMaskArg syncMode, const UInt32 uiSyncInfo) { DrawableStatsAttachment *pThis = static_cast<DrawableStatsAttachment *>(this); pThis->execSync(static_cast<DrawableStatsAttachment *>(&oFrom), whichField, oOffsets, syncMode, uiSyncInfo); }
void RenderPartition::dropFunctor(DrawFunctor &drawFunc, State *pState, Int32 iSortKey, bool bIgnoreOverrides) { if(_eMode == SimpleCallback) return; RenderAction *ract = dynamic_cast<RenderAction *>(_oDrawEnv.getAction()); Node *actNode = ract ->getActNode(); NodeCore *actCore = actNode->getCore (); bool bOverrodeState = false; StateOverride *pStateOverride = NULL; DrawableStatsAttachment *st = DrawableStatsAttachment::get(actCore); if(st == NULL) { DrawableStatsAttachment::addTo(actCore); st = DrawableStatsAttachment::get(actCore); } st->validate(); if(_oDrawEnv.getStatCollector() != NULL) { _oDrawEnv.getStatCollector()->getElem( RenderAction::statNTriangles)->add(st->getTriangles()); } _uiNumTriangles += st->getTriangles(); #ifdef OSG_NEW_SHADER bOverrodeState = pushShaderState(pState); #endif // OSG_NEW_SHADER if(_sStateOverrides.top()->empty() == false && bIgnoreOverrides == false ) { pStateOverride = _sStateOverrides.top(); } bool bTransparent = (pState->isTransparent() ) || (pStateOverride != NULL ? pStateOverride->isTransparent() : false); if(_bSortTrans == true && bTransparent == true) { BuildKeyMapIt mapIt = _mTransMatTrees.lower_bound(iSortKey); if(mapIt == _mTransMatTrees.end() || mapIt->first != iSortKey) { TreeBuilderBase *pBuilder = _pTreeBuilderPool->create<DepthSortTreeBuilder>(); pBuilder->setNodePool(_pNodePool); mapIt = _mTransMatTrees.insert( mapIt, BuildKeyMap::value_type(iSortKey, pBuilder)); } if(mapIt->second == NULL) { TreeBuilderBase *pBuilder = _pTreeBuilderPool->create<DepthSortTreeBuilder>(); pBuilder->setNodePool(_pNodePool); mapIt->second = pBuilder; } mapIt->second->add(_oDrawEnv.getAction(), this, drawFunc, pState, pStateOverride); } else if(ract != NULL && ract->getOcclusionCulling() == true) { BuildKeyMapIt mapIt = _mMatTrees.lower_bound(iSortKey); if(mapIt == _mMatTrees.end() || mapIt->first != iSortKey) { TreeBuilderBase *pBuilder = _pTreeBuilderPool->create<OcclusionCullingTreeBuilder>(); pBuilder->setNodePool(_pNodePool); mapIt = _mMatTrees.insert(mapIt, std::make_pair(iSortKey, pBuilder)); } if(mapIt->second == NULL) { mapIt->second = _pTreeBuilderPool->create<OcclusionCullingTreeBuilder>(); mapIt->second->setNodePool(_pNodePool); } mapIt->second->add(_oDrawEnv.getAction(), this, drawFunc, pState, pStateOverride); } else { BuildKeyMapIt mapIt = _mMatTrees.lower_bound(iSortKey); if(mapIt == _mMatTrees.end() || mapIt->first != iSortKey) { TreeBuilderBase *pBuilder = _pTreeBuilderPool->create<StateSortTreeBuilder>(); pBuilder->setNodePool(_pNodePool); mapIt = _mMatTrees.insert( mapIt, BuildKeyMap::value_type(iSortKey, pBuilder)); } if(mapIt->second == NULL) { mapIt->second = _pTreeBuilderPool->create<StateSortTreeBuilder>(); mapIt->second->setNodePool(_pNodePool); } mapIt->second->add(_oDrawEnv.getAction(), this, drawFunc, pState, pStateOverride); } #ifdef OSG_NEW_SHADER if(bOverrodeState == true) { this->popState(); } #endif }
void OcclusionCullingTreeBuilder::testNode(OCRenderTreeNode *pNode, DrawEnv &denv, RenderPartitionBase *part, Real32 &scr_percent) { while (pNode != NULL) { //MATRIX SETUP UInt32 uiNextMatrix = pNode->getMatrixStore().first; if(uiNextMatrix != 0 && uiNextMatrix != _uiActiveMatrix) { glLoadMatrixf(pNode->getMatrixStore().second.getValues()); _uiActiveMatrix = uiNextMatrix; _currMatrix.second = pNode->getMatrixStore().second; updateTopMatrix(denv); denv.setObjectToWorld(_accMatrix); ++part->_uiNumMatrixChanges; } const BoxVolume &volume = pNode->getVolume(); Pnt3f min,max; volume.getBounds(min, max); Pnt3f p[8]; p[0].setValues(min[0],min[1],min[2]); p[1].setValues(max[0],min[1],min[2]); p[2].setValues(min[0],max[1],min[2]); p[3].setValues(min[0],min[1],max[2]); p[4].setValues(max[0],max[1],min[2]); p[5].setValues(max[0],min[1],max[2]); p[6].setValues(min[0],max[1],max[2]); p[7].setValues(max[0],max[1],max[2]); //std::cout << "OtoW:" << std::endl; //std::cout << denv.getObjectToWorld() << std::endl; //std::cout << "WtoC:" << std::endl; //std::cout << worldToCam << std::endl; for(UInt32 i = 0; i<8;i++) { // std::cout << p[i] << "=>"; denv.getObjectToWorld().mult (p[i], p[i]); _worldToScreen .multFull(p[i], p[i]); //std::cout << p[i] << " "; } min=p[0]; max=p[0]; for(UInt32 i = 0; i<8; i++) { for(UInt32 j=0; j<2; j++) { if(p[i][j] < min[j]) { min[j] = p[i][j]; } if(p[i][j] > max[j]) { max[j] = p[i][j]; } } } max[0] = osgClamp(-1.f, max[0], 1.f); max[1] = osgClamp(-1.f, max[1], 1.f); min[0] = osgClamp(-1.f, min[0], 1.f); min[1] = osgClamp(-1.f, min[1], 1.f); // cbb is the percent of the screen real estate this would cover Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f; //std::cout << cur_node << ":" << pix << " "; //std::cout << pNode->getScalar() << std::endl; //Make decision if(pNode->hasFunctor() == false) //Nothing to do { //renderNode drawNode(pNode, denv, part); } else { //make decision //if(0 > 1) if(cbb > scr_percent) // Rendering major occluders { drawNode(pNode, denv, part); //scr_percent+=cbb; } else { Real32 pcov; pcov = sqrt(scr_percent) - sqrt(cbb); pcov *= pcov; //std::cout << "cbb:" << cbb << " scr_percent:" << scr_percent <<" pcov:" << pcov << std::endl; //if(scr_percent - pcov > 0.001) if(pcov > _coveredProbThreshold || cbb < 0.001) // If within threshold or reall small { //Get triangles DrawableStatsAttachment *st = DrawableStatsAttachment::get(pNode->getNode()->getCore()); st->validate(); UInt32 triangles = st->getTriangles(); if(cbb * _vpWidth * _vpHeight < _minFeatureSize) //small feature culling { StatCollector *sc = _ract->getStatCollector(); if(sc != NULL) sc->getElem(statNOccTriangles)-> add(triangles); if(_ract->getOcclusionCullingDebug() && pNode->getNode()) { pNode->getNode()->setTravMask( pNode->getNode()->getTravMask() | _ract->getOcclusionCulledDebugMask() ); } pNode->setIsRendered(true); } else if( triangles <= _minTriangleCount ) { drawNode(pNode, denv, part); } else if((_testPendingNodes.size() == _numTestSamples - 1)) // Make sure we have room to draw a test { drawTestResults(denv, part); if(_testPendingNodes.size() == _numTestSamples - 1) // If we are waiting on a result, draw a node { drawNode(pNode, denv, part); } else { drawTestNode(pNode, denv, part); // Made room, go ahead and draw a test node } } else { drawTestNode(pNode, denv, part); //Plenty of room in buffer to draw a test node } } else { drawNode(pNode, denv, part); // Probably not being covered up...draw the real node //scr_percent+=cbb; } } scr_percent += ((1.0 - scr_percent) * cbb); } //DRAW CHILDREN OR GO TO TOP AND DO IT AGAIN if(pNode->getFirstChild() != NULL) { OCRenderTreeNode *child = static_cast<OCRenderTreeNode *>(pNode->getFirstChild()); testNode(child, denv, part, scr_percent); } pNode = static_cast<OCRenderTreeNode *>(pNode->getBrother()); } }