Changeset 342 for branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp
- Timestamp:
- 10/21/06 13:50:48 (2 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp
r306 r342 59 59 #include "OSGColorMaskChunk.h" 60 60 #include "OSGPolygonChunk.h" 61 #include "OSGGeoStatsAttachment.h" 61 62 62 63 //#define OSG_DUMP_SORTING … … 76 77 UInt32 OcclusionCullingTreeBuilder::_funcEndQueryARB= Window::invalidFunctionID; 77 78 78 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccNodes( 79 80 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccNodes( 79 81 "OC-Nodes", 80 82 "total number of nodes tested for occlusion"); 81 83 82 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccTests(84 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccTests( 83 85 "OC-Tests", 84 86 "number of occlusion tests"); 85 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccInvisible(87 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccInvisible( 86 88 "OC-Invisible", 87 89 "number of nodes found invisible through occlusion"); … … 91 93 "percentage of successful tests for occlusion"); 92 94 95 StatElemDesc<StatIntElem> OcclusionCullingTreeBuilder::statNOccTriangles( 96 "OC-Triangles", 97 "number of triangles culled"); 98 99 93 100 94 101 bool OcclusionCullingTreeBuilder::_isOccStateCreated = false; 95 102 StatePtr OcclusionCullingTreeBuilder::_testingStatePtr; 96 103 State *OcclusionCullingTreeBuilder::_testingState; 104 105 106 OcclusionCullingTreeBuilder::SortModeE OcclusionCullingTreeBuilder::_sortMode = 107 OcclusionCullingTreeBuilder::ModeAdaptiveBucket; 108 UInt32 OcclusionCullingTreeBuilder::_nBuckets = 1000; 109 97 110 98 111 // Some typedefs to clean up OpenGL extension handling … … 142 155 TreeBuilderBase::reset(); 143 156 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 150 178 _bucketLow = 0.f; 151 179 _bucketHigh = 0.f; … … 154 182 155 183 184 /*! Set the sorting mode for the front to back sorter. 185 */ 186 OcclusionCullingTreeBuilder::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 */ 197 UInt32 OcclusionCullingTreeBuilder::setNBuckets(UInt32 nbuckets) 198 { 199 UInt32 o = _nBuckets; 200 _nBuckets = nbuckets; 201 202 return o; 203 } 204 205 156 206 inline void OcclusionCullingTreeBuilder::enterTesting(DrawEnv &denv, RenderPartition *part) 157 207 { … … 172 222 { 173 223 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 } 174 236 175 237 if(!win->hasExtension(_extOcclusionQuery)) … … 227 289 228 290 vp->getCamera()->getWorldToScreen(_worldToScreen, *vp); 229 291 230 292 _testingState = &*_testingStatePtr; 231 293 … … 613 675 uNumNodes++; 614 676 677 GeoStatsAttachmentPtr st = 678 GeoStatsAttachment::get(pNode->getNode()); 679 680 st->validate(); 681 682 _rt->getStatistics()->getElem(statNOccTriangles)-> 683 add(st->getTriangles()); 684 615 685 if(_rt->getOcclusionCullingDebug() && pNode->getNode()) 616 686 { … … 650 720 } 651 721 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 654 723 float val = pNode->getScalar(); 655 724 … … 662 731 } 663 732 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; 763 796 } 764 797 else 765 798 { 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; 777 813 } 778 814 else 779 815 { 780 _ pRoot->insertChildAfter(pLast,pNode);816 _buckets[index]->addChild(pNode); 781 817 } 782 818 uNumNodes++; 783 819 } 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 } 793 876 } 794 877
