Changeset 299
- Timestamp:
- 10/16/06 09:11:30 (2 years ago)
- Files:
-
- branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp (modified) (5 diffs)
- branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.h (modified) (4 diffs)
- branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/build.info (modified) (1 diff)
- branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/testOcclusionCulling.cpp (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp
r291 r299 91 91 "percentage of successful tests for occlusion"); 92 92 93 94 bool OcclusionCullingTreeBuilder::_isOccStateCreated = false; 95 StatePtr OcclusionCullingTreeBuilder::_testingStatePtr; 96 State *OcclusionCullingTreeBuilder::_testingState; 97 93 98 // Some typedefs to clean up OpenGL extension handling 94 99 … … 121 126 122 127 _buckets.clear(); 123 _buckets.resize(_nBuckets); 128 _buckets.resize(_nBuckets); 129 _bucketsWork.clear(); 130 _bucketsWork.resize(_nBuckets); 124 131 } 125 132 126 133 OcclusionCullingTreeBuilder::~OcclusionCullingTreeBuilder(void) 127 134 { 135 // Should delete queries here, but those need GL context... 136 delete [] _testSamples; 128 137 } 129 138 … … 136 145 _buckets.clear(); 137 146 _buckets.resize(_nBuckets); 147 _bucketsWork.clear(); 148 _bucketsWork.resize(_nBuckets); 149 150 _bucketLow = 0.f; 151 _bucketHigh = 0.f; 152 _bucketScale = 0.f; 138 153 } 139 154 … … 176 191 GenQueryT genquer = (GenQueryT)win->getFunction(_funcGenQueriesARB); 177 192 genquer(uNumNodes, _testSamples); 178 193 _isOccSetup = true; 194 } 195 196 if(!_isOccStateCreated) 197 { 198 _isOccStateCreated = true; 179 199 // Create an empty state to render test nodes. 180 200 _testingStatePtr = State::create(); … … 630 650 } 631 651 652 // Assumed to be between 0 and 1 for fixed bucket sort. Adaptive doesn't 653 // care. 654 float val = pNode->getScalar(); 655 632 656 if(_pRoot == NULL) 633 657 { 634 658 _pRoot = _pNodePool->create(); 635 } 636 637 #if 1 // Bucket sorting 638 639 float val = pNode->getScalar(); // Assumed to be between 0 and 1 659 _bucketLow = val; 660 _bucketHigh = val + 0.1; 661 _bucketScale = (_nBuckets + 1) / (_bucketHigh - _bucketLow); 662 } 663 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 640 731 int index = osgClamp(0, static_cast<int>(val * _nBuckets), _nBuckets - 1); 641 732 branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.h
r291 r299 81 81 82 82 static OcclusionCullingTreeBuilder Proto; 83 84 static StatElemDesc<StatIntElem> statNOccNodes; 85 static StatElemDesc<StatIntElem> statNOccTests; 86 static StatElemDesc<StatIntElem> statNOccInvisible; 87 static StatElemDesc<StatRealElem> statNOccSuccessTestPer; 83 88 84 89 //----------------------------------------------------------------------- … … 188 193 static UInt32 _funcEndQueryARB; 189 194 190 static StatElemDesc<StatIntElem> statNOccNodes; 191 static StatElemDesc<StatIntElem> statNOccTests; 192 static StatElemDesc<StatIntElem> statNOccInvisible; 193 static StatElemDesc<StatRealElem> statNOccSuccessTestPer; 195 static bool _isOccStateCreated; 196 static StatePtr _testingStatePtr; 197 static State *_testingState; 194 198 195 199 GLuint* _testSamples; … … 200 204 static const int _nBuckets = 1000; //!< number of buckets for approximate sorting 201 205 std::vector<RenderTreeNode*> _buckets; //!< buckets for approximate sorting 206 std::vector<RenderTreeNode*> _bucketsWork; //!< work copy of buckets 207 Real32 _bucketLow; //!< value for lowest bucket 208 Real32 _bucketHigh; //!< value for highest bucket 209 Real32 _bucketScale; //!< 1 / all buckets width 210 202 211 std::vector<RenderTreeNode*> _testNodes; //!< Nodes currently being tested 203 212 … … 209 218 Int32 _vpWidth; 210 219 Int32 _vpHeight; 211 StatePtr _testingStatePtr;212 State *_testingState;213 220 RenderTraversalAction *_rt; 214 221 UInt32 _minFeatureSize; branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/build.info
r280 r299 7 7 osg_dep_libs = ['OSGBase','OSGSystem','OSGGroup','OSGState','OSGDrawable', 'OSGWindow'] 8 8 9 # This is only need in test, but I don't know how to add opt libs to test 10 nvperfsdk_option = opts.GetOption("NVPerfSDK") 11 12 for option in [nvperfsdk_option]: 13 if option.isAvailable(): 14 libs.append(option.library) 15 if option.incDir: 16 cpppath.append(option.incDir) 17 if option.libDir: 18 libpath.append(option.libDir) 19 9 20 # Tests' dependencies 10 21 11 22 osg_test_libs = ['OSGGroup', 'OSGDrawable', 'OSGState', 'OSGFileIO', 12 23 'OSGWindowX', 'OSGUtil','OSGText', 'OSGWindowGLUT'] 24 13 25 test_cpppath = [] 14 26 test_libpath = [] branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/testOcclusionCulling.cpp
r290 r299 2 2 #include <OSGGLUT.h> 3 3 #include <OSGConfig.h> 4 #include <OSGConfigured.h> 4 5 #include <OSGSimpleGeometry.h> 5 6 #include <OSGGLUTWindow.h> … … 18 19 #include "OSGSHLChunk.h" 19 20 21 #include "OSGStatStringElem.h" 22 #include "OSGSimplePool.h" 23 #include "OSGRenderTreeNode.h" 24 #include "OSGOcclusionCullingTreeBuilder.h" 20 25 21 26 OSG_USING_NAMESPACE 27 28 #ifdef OSG_WITH_NVPERFSDK 29 #include <NVPerfSDK.h> 30 31 32 StatElemDesc<StatStringElem> GPUIdleStat("GPUIdle","GPUIdle"); 33 StatElemDesc<StatStringElem> PSBusyStat("PSBusyStat","PSBusyStat"); 34 StatElemDesc<StatStringElem> VSBusyStat("VSBusyStat","VSBusyStat"); 35 StatElemDesc<StatStringElem> TextureWaitStat("TextureWait","TextureWait"); 36 37 StatElemDesc<StatStringElem> *nvStatElems[] = 38 { &GPUIdleStat, &PSBusyStat, &VSBusyStat, &TextureWaitStat }; 39 40 #endif 22 41 23 42 SimpleSceneManager *mgr; 24 43 RenderTraversalAction *tact = NULL; 25 44 RenderAction *act = NULL; 45 RenderAction *debugact = NULL; 26 46 27 47 GLUTWindowPtr mainwin; … … 29 49 int mainwinid = -1, debugwinid = -1; 30 50 51 SimpleStatisticsForegroundPtr statfg; 31 52 StatCollector *collector; 32 53 … … 34 55 bool debug = false; 35 56 bool bGLFinish = false; 57 58 59 60 #ifdef OSG_WITH_NVPERFSDK 61 const GLuint counterEntryCount = 10; 62 const GLuint bufferEntryCount = 10; 63 64 // A simple class to manage counters, sampling, and display of the information 65 class NVDataProvider 66 { 67 public: 68 NVDataProvider() 69 { 70 // We're averaging these, so we'll need to initialize to zero 71 for (GLuint i = 0; i < counterEntryCount; i++) { 72 for (GLuint j = 0; j < bufferEntryCount; j++) { 73 m_counterValues[i][j] = 0.0f; 74 } 75 } 76 m_counterIndexArrayCount = 0; 77 m_counterValuesRRIndex = 0; 78 } 79 80 virtual size_t nCounters() const 81 { 82 return m_counterIndexArrayCount; 83 } 84 85 virtual bool add(GLuint counterIndex) 86 { 87 if (NVPMAddCounter(counterIndex) == NVPM_OK) { 88 m_counterIndexArray[m_counterIndexArrayCount++] = counterIndex; 89 return true; 90 } else { 91 return false; 92 } 93 } 94 95 virtual bool add(char *counterName) 96 { 97 GLuint counterIndex; 98 if (NVPMGetCounterIndex(counterName, &counterIndex) == NVPM_OK) { 99 return add(counterIndex); 100 } else { 101 return false; 102 } 103 } 104 105 virtual bool removeAllCounters() 106 { 107 NVPMRemoveAllCounters(); 108 109 while (m_counterIndexArrayCount) { 110 m_counterIndexArray[--m_counterIndexArrayCount] = 0; 111 } 112 113 return true; 114 } 115 116 virtual bool sample() 117 { 118 GLuint counterIndex, unused; 119 UINT64 events, cycles; 120 121 // Sample the GPU counters 122 NVPMSample(NULL, &unused); 123 124 // Retrieve the current sample values 125 for (counterIndex = 0; 126 counterIndex < m_counterIndexArrayCount; 127 counterIndex++) 128 { 129 NVPMGetCounterValue(m_counterIndexArray[counterIndex], 0, &events, &cycles); 130 131 m_counterValues[counterIndex][m_counterValuesRRIndex] = 132 100.0f * (float) events / (float) cycles; 133 } 134 m_counterValuesRRIndex++; 135 if (m_counterValuesRRIndex >= bufferEntryCount) { 136 m_counterValuesRRIndex = 0; 137 } 138 139 return true; 140 } 141 142 virtual float value(const GLuint counterIndex) const 143 { 144 GLuint entryIndex; 145 GLfloat runningTotal = 0.0f; 146 for (entryIndex = 0; entryIndex < bufferEntryCount; entryIndex++) { 147 runningTotal += 148 m_counterValues[counterIndex][entryIndex] / (float)bufferEntryCount; 149 } 150 return runningTotal; 151 } 152 153 protected: 154 GLuint m_counterIndexArray[counterEntryCount]; 155 GLuint m_counterIndexArrayCount; 156 157 // Maintain a round-robin style buffer and display the average of the 158 // the last bufferEntryCount samples. 159 GLfloat m_counterValues[counterEntryCount][bufferEntryCount]; 160 GLuint m_counterValuesRRIndex; 161 162 } g_nvDataProvider; 163 164 NVDataProvider *nvDataProvider = &g_nvDataProvider; 165 #endif 36 166 37 167 // redraw the window … … 40 170 if(glutGetWindow() == mainwinid) 41 171 { 172 #ifdef OSG_WITH_NVPERFSDK 173 if(nvDataProvider->nCounters()) 174 { 175 nvDataProvider->sample(); 176 177 Char8 str[40]; 178 179 for(int i = 0; i < 4; ++i) 180 { 181 sprintf(str, "%s: %f", nvStatElems[i]->getDescription().str(), 182 nvDataProvider->value(i)); 183 StatStringElem *e = dynamic_cast<StatStringElem*>( 184 collector->getElem(*nvStatElems[i])); 185 e->set(str); 186 } 187 } 188 #endif 42 189 mgr->redraw(); 43 190 } 44 191 else if(glutGetWindow() == debugwinid) 45 192 { 46 // Use RenderAction to prevent new oicclusion culling on debug output 47 debugwin->render(act); 193 // Use RenderAction to prevent new occlusion culling on debug output 194 debugwin->render(debugact); 195 } 196 } 197 198 // Redisplay both windows, if active 199 void redisplay(void) 200 { 201 glutSetWindow(mainwinid); 202 glutPostRedisplay(); 203 if(debugwinid > 0) 204 { 205 glutSetWindow(debugwinid); 206 glutPostRedisplay(); 48 207 } 49 208 } … … 72 231 mgr->mouseButtonPress(button, x, y); 73 232 74 glutSetWindow(mainwinid); 75 glutPostRedisplay(); 76 if(debugwinid > 0) 77 { 78 glutSetWindow(debugwinid); 79 glutPostRedisplay(); 80 } 233 redisplay(); 81 234 } 82 235 … … 86 239 mgr->mouseMove(x, y); 87 240 88 glutSetWindow(mainwinid); 89 glutPostRedisplay(); 90 if(debugwinid > 0) 91 { 92 glutSetWindow(debugwinid); 93 glutPostRedisplay(); 94 } 241 redisplay(); 95 242 } 96 243 … … 111 258 case 27: 112 259 { 260 #ifdef OSG_WITH_NVPERFSDK 261 NVPMShutdown(); 262 #endif 113 263 osgExit(); 114 264 exit(0); … … 175 325 act->setUseGLFinish(bGLFinish); 176 326 break; 177 } 178 179 glutSetWindow(mainwinid); 180 glutPostRedisplay(); 181 if(debugwinid > 0) 182 { 183 glutSetWindow(debugwinid); 184 glutPostRedisplay(); 185 } 327 328 329 case 'y': 330 { 331 Real32 cov = tact->getOcclusionCullingCoveredThreshold(); 332 cov+=0.1; 333 tact->setOcclusionCullingCoveredThreshold(cov); 334 std::cout << "Covered Threshold now: " << cov << std::endl; 335 } 336 break; 337 338 case 'h': 339 { 340 Real32 cov1 = tact->getOcclusionCullingCoveredThreshold(); 341 cov1-=0.1; 342 tact->setOcclusionCullingCoveredThreshold(cov1); 343 std::cout << "Covered Threshold now: " << cov1 << std::endl; 344 } 345 break; 346 347 case 'u': 348 { 349 UInt32 small = tact->getOcclusionCullingMinimumFeatureSize(); 350 small+=1; 351 tact->setOcclusionCullingMinimumFeatureSize(small); 352 std::cout << "Minimum Feature Size now: " << small << std::endl; 353 } 354 break; 355 356 case 'j': 357 { 358 UInt32 small1 = tact->getOcclusionCullingMinimumFeatureSize(); 359 small1-=1; 360 tact->setOcclusionCullingMinimumFeatureSize(small1); 361 std::cout << "Minimum Feature Size now: " << small1 << std::endl; 362 } 363 break; 364 365 case 'i': 366 { 367 UInt32 visT = tact->getOcclusionCullingVisibilityThreshold(); 368 visT+=1; 369 tact->setOcclusionCullingVisibilityThreshold(visT); 370 std::cout << "Visibility Threshold now: " << visT << std::endl; 371 } 372 break; 373 374 case 'k': 375 { 376 UInt32 visTa = tact->getOcclusionCullingVisibilityThreshold(); 377 visTa-=1; 378 tact->setOcclusionCullingVisibilityThreshold(visTa); 379 std::cout << "Visibility Threshold now: " << visTa << std::endl; 380 } 381 break; 382 383 case 'f': 384 { 385 std::cout << "Freeze Occlusion result" << std::endl; 386 387 //initElements(); 388 mgr->setUseTraversalAction(false); 389 390 // Render stuff that is visible and tested 391 mgr->getWindow()->getPort(0)->setTravMask(0x5); 392 } 393 break; 394 395 case 'F': 396 { 397 std::cout << "Unfreeze Occlusion result" << std::endl; 398 399 //initElements(); 400 mgr->setUseTraversalAction(true); 401 402 mgr->getWindow()->getPort(0)->setTravMask(0xffffffff); 403 } 404 break; 405 406 } 407 408 redisplay(); 186 409 } 187 410 … … 265 488 mgr->setUseTraversalAction(true); 266 489 267 tact = RenderTraversalAction::create(); 268 act = RenderAction::create(); 490 tact = RenderTraversalAction::create(); 491 act = RenderAction::create(); 492 debugact = RenderAction::create(); 269 493 270 494 … … 316 540 // add the statistics forground 317 541 318 SimpleStatisticsForegroundPtr statfg = 319 SimpleStatisticsForeground::create(); 542 statfg = SimpleStatisticsForeground::create(); 320 543 321 544 statfg->setSize(25); 322 545 statfg->setColor(Color4f(0,1,0,0.7)); 323 #if 0 324 statfg->addElement(RenderAction::statDrawTime, "Draw FPS: %r.3f"); 325 statfg->addElement(DrawActionBase::statTravTime, "TravTime: %.3f s"); 326 statfg->addElement(RenderAction::statDrawTime, "DrawTime: %.3f s"); 327 statfg->addElement(DrawActionBase::statCullTestedNodes, 328 "%d Nodes culltested"); 329 statfg->addElement(DrawActionBase::statCulledNodes, 330 "%d Nodes culled"); 331 statfg->addElement(RenderAction::statNMaterials, 332 "%d material changes"); 333 statfg->addElement(RenderAction::statNMatrices, 546 547 statfg->addElement(RenderTraversalAction::statDrawTime, "Draw FPS: %r.3f"); 548 statfg->addElement(RenderTraversalAction::statNMatrices, 334 549 "%d matrix changes"); 335 statfg->addElement(Render Action::statNGeometries,336 "%d Nodes drawn");337 statfg->addElement(Render Action::statNTransGeometries,338 "%d transparent Nodes drawn");339 statfg->addElement( Drawable::statNTriangles,340 "%d triangles drawn");341 statfg->addElement( Drawable::statNLines,342 "%d lines drawn");343 statfg->addElement(Drawable::statNPoints, 344 "%d points drawn");345 statfg->addElement(Drawable::statNPrimitives,346 "%d primitive groups drawn");347 statfg->addElement(Drawable::statNVertices,348 "%d vertices transformed");349 statfg->addElement(RenderAction::statNTextures, "%d textures used");350 statfg->addElement( RenderAction::statNTexBytes, "%d bytes of texture used");351 #endif 352 550 statfg->addElement(RenderTraversalAction::statNGeometries, 551 "%d Geometries drawn"); 552 statfg->addElement(RenderTraversalAction::statNStates, 553 "%d state changes"); 554 statfg->addElement(RenderTraversalAction::statNShaders, 555 "%d shader changes"); 556 statfg->addElement(RenderTraversalAction::statNShaderParams, 557 "%d shader param changes"); 558 559 statfg->addElement(OcclusionCullingTreeBuilder::statNOccNodes, 560 "%d nodes in draw tree"); 561 statfg->addElement(OcclusionCullingTreeBuilder::statNOccTests, 562 "%d occ tests"); 563 statfg->addElement(OcclusionCullingTreeBuilder::statNOccInvisible, 564 "%d invisible nodes"); 565 statfg->addElement(OcclusionCullingTreeBuilder::statNOccSuccessTestPer, 566 "%per%% success rate"); 567 353 568 collector = &statfg->editCollector(); 354 569 … … 363 578 mainwin->getPort(0)->addForeground(statfg); 364 579 } 580 581 #ifdef OSG_WITH_NVPERFSDK 582 NVPMRESULT status; 583 584 status = NVPMInit(); 585 if (status != NVPM_OK) { 586 FFATAL(("NVPerfSDK failed to initialize - no GPU data will be available")); 587 } 588 else 589 { 590 nvDataProvider->add("gpu_idle"); 591 nvDataProvider->add("pixel_shader_busy"); 592 nvDataProvider->add("vertex_shader_busy"); 593 nvDataProvider->add("shader_waits_for_texture"); 594 595 statfg->addElement(GPUIdleStat); 596 statfg->addElement(PSBusyStat); 597 statfg->addElement(VSBusyStat); 598 statfg->addElement(TextureWaitStat); 599 600 } 601 #endif 365 602 366 603 // GLUT main loop
