Show
Ignore:
Timestamp:
10/21/06 13:50:48 (2 years ago)
Author:
dirk
Message:

Added Tri and occed tri stats
added NVPerfKitSDK demo stats in testOcclusionCulling.cpp. These should become core stats later…

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp

    r306 r342  
    5959#include "OSGColorMaskChunk.h" 
    6060#include "OSGPolygonChunk.h" 
     61#include "OSGGeoStatsAttachment.h" 
    6162 
    6263//#define OSG_DUMP_SORTING 
     
    7677UInt32 OcclusionCullingTreeBuilder::_funcEndQueryARB= Window::invalidFunctionID; 
    7778 
    78 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccNodes( 
     79 
     80StatElemDesc<StatIntElem>  OcclusionCullingTreeBuilder::statNOccNodes( 
    7981    "OC-Nodes",  
    8082    "total number of nodes tested for occlusion"); 
    8183 
    82 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccTests( 
     84StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccTests( 
    8385    "OC-Tests",  
    8486    "number of occlusion tests"); 
    85 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccInvisible( 
     87StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccInvisible( 
    8688    "OC-Invisible",  
    8789    "number of nodes found invisible through occlusion"); 
     
    9193    "percentage of successful tests for occlusion"); 
    9294 
     95StatElemDesc<StatIntElem>  OcclusionCullingTreeBuilder::statNOccTriangles( 
     96    "OC-Triangles",  
     97    "number of triangles culled"); 
     98 
     99 
    93100 
    94101bool      OcclusionCullingTreeBuilder::_isOccStateCreated = false; 
    95102StatePtr  OcclusionCullingTreeBuilder::_testingStatePtr; 
    96103State    *OcclusionCullingTreeBuilder::_testingState; 
     104 
     105 
     106OcclusionCullingTreeBuilder::SortModeE OcclusionCullingTreeBuilder::_sortMode =  
     107    OcclusionCullingTreeBuilder::ModeAdaptiveBucket; 
     108UInt32 OcclusionCullingTreeBuilder::_nBuckets = 1000; 
     109 
    97110 
    98111// Some typedefs to clean up OpenGL extension handling 
     
    142155    TreeBuilderBase::reset(); 
    143156    uNumNodes=0; 
    144          
    145     _buckets.clear(); 
    146     _buckets.resize(_nBuckets); 
    147     _bucketsWork.clear(); 
    148     _bucketsWork.resize(_nBuckets); 
    149     
     157     
     158    if(_buckets.size() != _nBuckets) 
     159    {     
     160        _buckets.resize(_nBuckets); 
     161        _bucketsWork.resize(_nBuckets); 
     162    } 
     163     
     164    std::vector<RenderTreeNode*>::iterator it, e;  
     165     
     166    for(it = _buckets.begin(), e = _buckets.end(); 
     167        it != e; ++it) 
     168    { 
     169        *it = NULL; 
     170    } 
     171     
     172    for(it = _bucketsWork.begin(), e = _bucketsWork.end(); 
     173        it != e; ++it) 
     174    { 
     175        *it = NULL; 
     176    } 
     177     
    150178    _bucketLow   = 0.f; 
    151179    _bucketHigh  = 0.f; 
     
    154182 
    155183 
     184/*! Set the sorting mode for the front to back sorter. 
     185*/ 
     186OcclusionCullingTreeBuilder::SortModeE  
     187    OcclusionCullingTreeBuilder::setSortMode(SortModeE mode) 
     188{ 
     189    SortModeE o = _sortMode; 
     190    _sortMode = _sortMode; 
     191     
     192    return o; 
     193} 
     194     
     195/*! Set the numberof buckets to use for the bucket sorters. 
     196*/ 
     197UInt32 OcclusionCullingTreeBuilder::setNBuckets(UInt32 nbuckets) 
     198{ 
     199    UInt32 o = _nBuckets; 
     200    _nBuckets = nbuckets; 
     201     
     202    return o; 
     203} 
     204 
     205 
    156206inline void OcclusionCullingTreeBuilder::enterTesting(DrawEnv &denv, RenderPartition *part) 
    157207{ 
     
    172222{ 
    173223    Window* win = denv.getWindow(); 
     224 
     225    if(_sortMode == ModeAdaptiveBucket) 
     226    { 
     227        // Merge all the buckets to a tree 
     228        for(UInt32 i = 0; i < _nBuckets; ++i) 
     229        { 
     230            if(_buckets[i] != NULL) 
     231            { 
     232                _pRoot->addChild(_buckets[i]); 
     233            } 
     234        } 
     235    } 
    174236     
    175237    if(!win->hasExtension(_extOcclusionQuery)) 
     
    227289 
    228290    vp->getCamera()->getWorldToScreen(_worldToScreen, *vp); 
    229  
     291     
    230292    _testingState = &*_testingStatePtr; 
    231293 
     
    613675                uNumNodes++; 
    614676 
     677                GeoStatsAttachmentPtr st = 
     678                        GeoStatsAttachment::get(pNode->getNode()); 
     679                 
     680                st->validate(); 
     681                 
     682                _rt->getStatistics()->getElem(statNOccTriangles)-> 
     683                        add(st->getTriangles()); 
     684                 
    615685                if(_rt->getOcclusionCullingDebug() && pNode->getNode()) 
    616686                { 
     
    650720    } 
    651721     
    652     // Assumed to be between 0 and 1 for fixed bucket sort. Adaptive doesn't 
    653     // care. 
     722    // Assumed to be between 0 and 1 for bucket sort 
    654723    float val = pNode->getScalar(); 
    655724     
     
    662731    } 
    663732 
    664 #if 0 // Adaptive Bucket sorting 
    665   
    666     int index = static_cast<int>((val - _bucketLow) * _bucketScale); 
    667      
    668     // Do we need to rescale buckets? 
    669     if(index < 0 || index >= _nBuckets) 
    670     { 
    671         Real32 newLow  = osgMin(val, _bucketLow); 
    672         Real32 newHigh = osgMax(val, _bucketHigh); 
    673         Real32 newScale = (_nBuckets + 1) / (newHigh - newLow); 
    674          
    675         // Only want to scale in exponential steps to reduce number 
    676         // of rescales 
    677         Real32 rescale = _bucketScale / newScale; 
    678         UInt32 step = osgnextpower2(static_cast<int>(osgceil(rescale))); 
    679          
    680         newScale = _bucketScale / step; 
    681         Real32 d = (_nBuckets - 1) / newScale - (_bucketHigh - _bucketLow); 
    682         newLow = newLow - d / 2.f; 
    683         newHigh = newLow + (_nBuckets - 1) / newScale; 
    684          
    685         // Move bucket contents around 
    686         Real32 iter = _bucketLow; 
    687         Real32 istep = 1.f / _bucketScale; 
    688          
    689         for(UInt32 i = 0; i < _nBuckets; ++i, iter += istep) 
    690         { 
    691             if(_buckets[i] == NULL) 
    692                 continue; 
    693                  
    694             int index = static_cast<int>((iter - newLow) * newScale); 
    695              
    696             if(_bucketsWork[index] == NULL) 
    697             { 
    698                 _bucketsWork[index] = _buckets[i]; 
    699             } 
    700             else // Need to merge 
    701             { 
    702                 _bucketsWork[index]->addChild(_buckets[i]); 
    703             } 
    704             _buckets[i] = NULL; 
    705         } 
    706          
    707         // Now swap the data 
    708         _buckets.swap(_bucketsWork); 
    709          
    710         _bucketLow   = newLow; 
    711         _bucketHigh  = newHigh; 
    712         _bucketScale = newScale; 
    713          
    714         index = static_cast<int>((val - _bucketLow) * _bucketScale); 
    715     } 
    716      
    717     if(_buckets[index] == NULL) // First node in bucket 
    718     { 
    719         _pRoot->addChild(pNode); 
    720         _buckets[index] = pNode; 
    721     } 
    722     else 
    723     { 
    724         _buckets[index]->addChild(pNode); 
    725     } 
    726     uNumNodes++; 
    727  
    728  
    729 #elif 1 // Bucket sorting 
    730  
    731     int index = osgClamp(0, static_cast<int>(val * _nBuckets), _nBuckets - 1); 
    732      
    733     if(_buckets[index] == NULL) // First node in bucket 
    734     { 
    735         _pRoot->addChild(pNode); 
    736         _buckets[index] = pNode; 
    737     } 
    738     else 
    739     { 
    740         _buckets[index]->addChild(pNode); 
    741     } 
    742     uNumNodes++; 
    743  
    744 #else // Exact Sorting 
    745     if(_pRoot->getFirstChild() == NULL) 
    746     { 
    747         _pRoot->addChild(pNode); 
    748         uNumNodes++; 
    749     } 
    750     else 
    751     { 
    752         RenderTreeNode *pCurrent = _pRoot->getFirstChild(); 
    753  
    754         RenderTreeNode *pLast    = NULL; 
    755         bool            bFound   = false; 
    756  
    757         do 
    758         { 
    759             if(pNode->getScalar() > pCurrent->getScalar()) 
    760             { 
    761                 pLast    = pCurrent; 
    762                 pCurrent = pCurrent->getBrother(); 
     733    switch(_sortMode) 
     734    { 
     735        case ModeAdaptiveBucket: 
     736        {  
     737            int index = osgClamp(0u, static_cast<UInt32>((val - _bucketLow) * _bucketScale), _nBuckets - 1); 
     738 
     739            // Do we need to rescale buckets? 
     740            if(index < 0 || index >= _nBuckets) 
     741            { 
     742                Real32 newLow  = osgMin(val, _bucketLow); 
     743                Real32 newHigh = osgMax(val, _bucketHigh); 
     744                Real32 newScale = (_nBuckets + 1) / (newHigh - newLow); 
     745 
     746                // Only want to scale in exponential steps to reduce number 
     747                // of rescales 
     748                Real32 rescale = _bucketScale / newScale; 
     749                UInt32 step = osgnextpower2(static_cast<int>(osgceil(rescale))); 
     750 
     751                newScale = _bucketScale / step; 
     752                Real32 d = (_nBuckets - 1) / newScale; 
     753                newLow  = osgMax(newLow - d / 2.f, 0.f); 
     754                newHigh = osgMin(newLow + d      , 1.f); 
     755 
     756    #if 0         
     757                std::cout << "ABS: (" << _bucketLow << " - " << _bucketHigh  
     758                          << ") => (" << newLow << " - " << newHigh 
     759                          << ")" << std::endl; 
     760    #endif                   
     761                // Move bucket contents around 
     762                Real32 iter = _bucketLow; 
     763                Real32 istep = 1.f / _bucketScale; 
     764 
     765                for(UInt32 i = 0; i < _nBuckets; ++i, iter += istep) 
     766                { 
     767                    if(_buckets[i] == NULL) 
     768                        continue; 
     769 
     770                    int index = static_cast<int>((iter - newLow) * newScale); 
     771 
     772                    if(_bucketsWork[index] == NULL) 
     773                    { 
     774                        _bucketsWork[index] = _buckets[i]; 
     775                    } 
     776                    else // Need to merge 
     777                    { 
     778                        _bucketsWork[index]->addChild(_buckets[i]); 
     779                    } 
     780                    _buckets[i] = NULL; 
     781                } 
     782 
     783                // Now swap the data 
     784                _buckets.swap(_bucketsWork); 
     785 
     786                _bucketLow   = newLow; 
     787                _bucketHigh  = newHigh; 
     788                _bucketScale = newScale; 
     789 
     790                index = osgClamp(0u, static_cast<UInt32>((val - _bucketLow) * _bucketScale), _nBuckets - 1); 
     791            } 
     792 
     793            if(_buckets[index] == NULL) // First node in bucket 
     794            { 
     795                _buckets[index] = pNode; 
    763796            } 
    764797            else 
    765798            { 
    766                 bFound = true; 
    767             } 
    768  
    769         } while(bFound   == false &&  
    770                 pCurrent != NULL    ); 
    771  
    772         if(bFound == true) 
    773         { 
    774             if(pLast == NULL) 
    775             { 
    776                 _pRoot->insertFirstChild(pNode); 
     799                _buckets[index]->addChild(pNode); 
     800            } 
     801            uNumNodes++; 
     802        } 
     803        break; 
     804 
     805        case ModeBucket: 
     806        { 
     807            int index = osgClamp(0u, static_cast<UInt32>(val * _nBuckets), _nBuckets - 1); 
     808 
     809            if(_buckets[index] == NULL) // First node in bucket 
     810            { 
     811                _pRoot->addChild(pNode); 
     812                _buckets[index] = pNode; 
    777813            } 
    778814            else 
    779815            { 
    780                 _pRoot->insertChildAfter(pLast, pNode); 
     816                _buckets[index]->addChild(pNode); 
    781817            } 
    782818            uNumNodes++; 
    783819        } 
    784         else 
    785         { 
    786             _pRoot->addChild(pNode); 
    787             uNumNodes++; 
    788         } 
    789     } 
    790     //std::cout << "Added : " << uNumNodes << std::endl; 
    791 #endif 
    792      
     820        break; 
     821 
     822        case ModeScalar: 
     823        { 
     824            if(_pRoot->getFirstChild() == NULL) 
     825            { 
     826                _pRoot->addChild(pNode); 
     827                uNumNodes++; 
     828            } 
     829            else 
     830            { 
     831                RenderTreeNode *pCurrent = _pRoot->getFirstChild(); 
     832 
     833                RenderTreeNode *pLast    = NULL; 
     834                bool            bFound   = false; 
     835 
     836                do 
     837                { 
     838                    if(pNode->getScalar() > pCurrent->getScalar()) 
     839                    { 
     840                        pLast    = pCurrent; 
     841                        pCurrent = pCurrent->getBrother(); 
     842                    } 
     843                    else 
     844                    { 
     845                        bFound = true; 
     846                    } 
     847 
     848                } while(bFound   == false &&  
     849                        pCurrent != NULL    ); 
     850 
     851                if(bFound == true) 
     852                { 
     853                    if(pLast == NULL) 
     854                    { 
     855                        _pRoot->insertFirstChild(pNode); 
     856                    } 
     857                    else 
     858                    { 
     859                        _pRoot->insertChildAfter(pLast, pNode); 
     860                    } 
     861                    uNumNodes++; 
     862                } 
     863                else 
     864                { 
     865                    _pRoot->addChild(pNode); 
     866                    uNumNodes++; 
     867                } 
     868            } 
     869        } 
     870        break; 
     871 
     872        default: 
     873            FFATAL(("Unknown sort mode %d!\n", _sortMode)); 
     874            break; 
     875    } 
    793876} 
    794877