Changeset 868 for GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src
- Timestamp:
- 05/01/06 00:08:09 (19 years ago)
- Location:
- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp
r865 r868 15 15 #include "ViewCellsManager.h" 16 16 17 18 // normal terrain rendering 19 const static NORMAL_RENDER_HACK = false; 20 17 21 namespace Ogre { 18 22 … … 20 24 OcclusionCullingSceneManager::OcclusionCullingSceneManager( 21 25 GtpVisibility::VisibilityManager *visManager): 26 TerrainSceneManager(), 22 27 mVisibilityManager(visManager), 23 28 mShowVisualization(false), … … 30 35 mIsDepthPassPhase(false), 31 36 mUseItemBuffer(false), 32 //mUseItemBuffer(true),33 37 mIsItemBufferPhase(false), 34 38 mCurrentEntityId(1), … … 41 45 mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem); 42 46 43 #if 0 47 if (0) 48 { 44 49 mDisplayNodes = true; 45 50 mShowBoundingBoxes = true; 46 51 mShowBoxes = true; 47 #endif 52 } 53 48 54 // TODO: set maxdepth to reasonable value 49 55 mMaxDepth = 50; … … 98 104 } 99 105 //mItemBufferPass->setAmbient(1, 1, 0); 106 } 107 //----------------------------------------------------------------------- 108 void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam) 109 { 110 // add player camera for visualization purpose 111 try 112 { 113 Camera *c; 114 if ((c = getCamera("PlayerCam")) != NULL) 115 { 116 getRenderQueue()->addRenderable(c); 117 } 118 } 119 catch (...) 120 { 121 // ignore 122 } 123 // add bounding boxes of rendered objects 124 for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) 125 { 126 getRenderQueue()->addRenderable(*it); 127 } 128 129 if (mRenderNodesForViz || mRenderNodesContentForViz) 130 { 131 // HACK: change node material so it is better suited for visualization 132 MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial"); 133 nodeMat->setAmbient(1, 1, 0); 134 nodeMat->setLightingEnabled(true); 135 nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); 136 137 for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it) 138 { 139 if (mRenderNodesForViz) 140 { 141 // render the leaf nodes 142 if (((*it)->numAttachedObjects() > 0) && ((*it)->numChildren() == 0) && 143 (*it)->getAttachedObject(0)->getMovableType() == "Entity") 144 { 145 getRenderQueue()->addRenderable((*it)); 146 } 147 148 // addbounding boxes instead of node itself 149 //(*it)->_addBoundingBoxToQueue(getRenderQueue()); 150 } 151 if (mRenderNodesContentForViz) 152 { 153 (*it)->_addToRenderQueue(cam, getRenderQueue(), false); 154 } 155 } 156 } 157 } 158 //----------------------------------------------------------------------- 159 Pass *OcclusionCullingSceneManager::setPass(Pass* pass) 160 { 161 if (NORMAL_RENDER_HACK) 162 { 163 return SceneManager::setPass(pass); 164 } 165 166 // TODO: setting vertex program is not efficient 167 //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass); 168 169 // set depth fill pass if we currently do not make an aabb occlusion query 170 const bool useDepthPass = 171 (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery()); 172 173 Pass *usedPass = useDepthPass ? mDepthPass : pass; 174 175 IlluminationRenderStage savedStage = mIlluminationStage; 176 177 // set illumination stage to NONE so no shadow material is used 178 // for depth pass or for occlusion query 179 if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery()) 180 { 181 mIlluminationStage = IRS_NONE; 182 } 183 184 // --- set vertex program of current pass in order to set correct depth 185 if (mExecuteVertexProgramForAllPasses && 186 mIsDepthPassPhase && 187 pass->hasVertexProgram()) 188 { 189 // add vertex program of current pass to depth pass 190 mDepthPass->setVertexProgram(pass->getVertexProgramName()); 191 192 if (mDepthPass->hasVertexProgram()) 193 { 194 const GpuProgramPtr& prg = mDepthPass->getVertexProgram(); 195 // Load this program if not done already 196 if (!prg->isLoaded()) 197 prg->load(); 198 // Copy params 199 mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters()); 200 } 201 } 202 else if (mDepthPass->hasVertexProgram()) // reset vertex program 203 { 204 mDepthPass->setVertexProgram(""); 205 } 206 207 // save old depth write: needed for item buffer 208 const bool IsDepthWrite = usedPass->getDepthWriteEnabled(); 209 210 // global option which enables / disables depth writes 211 if (!mEnableDepthWrite) 212 { 213 usedPass->setDepthWriteEnabled(false); 214 } 215 //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;} 216 217 218 //-- set actual pass here 219 Pass *result = SceneManager::setPass(usedPass); 220 221 222 // reset depth write 223 if (!mEnableDepthWrite) 224 { 225 usedPass->setDepthWriteEnabled(IsDepthWrite); 226 } 227 228 // reset illumination stage 229 mIlluminationStage = savedStage; 230 231 return result; 232 } 233 //----------------------------------------------------------------------- 234 void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam, bool onlyShadowCasters) 235 { 236 if (NORMAL_RENDER_HACK) 237 { 238 OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters); 239 return; 240 } 241 242 //-- show visible scene nodes and octree bounding boxes from last frame 243 if (mShowVisualization) 244 { 245 PrepareVisualization(cam); 246 } 247 else 248 { 249 // for hierarchical culling, we interleave identification 250 // and rendering of objects in _renderVisibibleObjects 251 252 // for the shadow pass we use only standard rendering 253 // because of low occlusion 254 if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 255 mIlluminationStage == IRS_RENDER_TO_TEXTURE) 256 { 257 OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters); 258 } 259 // only shadow casters will be rendered in shadow texture pass 260 if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters); 261 } 262 263 264 // -- delete lists stored for visualization 265 mVisible.clear(); 266 mBoxes.clear(); 267 } 268 //----------------------------------------------------------------------- 269 void OcclusionCullingSceneManager::_renderVisibleObjects() 270 { 271 if (NORMAL_RENDER_HACK) 272 { 273 OctreeSceneManager::_renderVisibleObjects(); 274 275 return; 276 } 277 278 InitDepthPass(); // create material for depth pass 279 InitItemBufferPass(); // create material for item buffer pass 280 281 // save ambient light to reset later 282 ColourValue savedAmbient = mAmbientLight; 283 284 //-- apply standard rendering for some modes (e.g., visualization, shadow pass) 285 286 if (mShowVisualization || 287 (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 288 mIlluminationStage == IRS_RENDER_TO_TEXTURE)) 289 { 290 IlluminationRenderStage savedStage = mIlluminationStage; 291 292 if (mShowVisualization) 293 { 294 // disable illumination stage to prevent rendering shadows 295 mIlluminationStage = IRS_NONE; 296 } 297 298 // standard rendering for shadow maps because of performance 299 TerrainSceneManager::_renderVisibleObjects(); 300 301 mIlluminationStage = savedStage; 302 } 303 else //-- the hierarchical culling algorithm 304 { 305 // this is also called in TerrainSceneManager: really 306 // nexessary? 307 mDestRenderSystem -> setLightingEnabled(false); 308 309 // don't render backgrounds for item buffer 310 if (mUseItemBuffer) 311 { 312 clearSpecialCaseRenderQueues(); 313 getRenderQueue()->clear(); 314 } 315 316 //-- hierarchical culling 317 // the objects of different layers (e.g., background, scene, 318 // overlay) must be identified and rendered one after another 319 320 //-- render all early skies 321 clearSpecialCaseRenderQueues(); 322 addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND); 323 addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY); 324 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE); 325 326 TerrainSceneManager::_renderVisibleObjects(); 327 328 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 329 // delete previously rendered content 330 _deleteRenderedQueueGroups(); 331 #endif 332 333 //-- prepare queue for visible objects (i.e., all but overlay and skies late) 334 clearSpecialCaseRenderQueues(); 335 addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE); 336 addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY); 337 338 // exclude this queues from hierarchical rendering 339 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 340 341 // set all necessary parameters for 342 // hierarchical visibility culling and rendering 343 InitVisibilityCulling(mCameraInProgress); 344 345 346 /** 347 * the hierarchical culling algorithm 348 * for depth pass: we just find objects and update depth buffer 349 * for "delayed" rendering: we render some passes afterwards 350 * e.g., transparents, because they need front-to-back sorting 351 **/ 352 353 mVisibilityManager->ApplyVisibilityCulling(); 354 355 // delete remaining renderables from queue: 356 // all which are not in mLeavePassesInQueue) 357 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 358 _deleteRenderedQueueGroups(mLeavePassesInQueue); 359 #endif 360 361 //-- reset parameters 362 mIsDepthPassPhase = false; 363 mIsItemBufferPhase = false; 364 mSkipTransparents = false; 365 mIsHierarchicalCulling = false; 366 367 mLeavePassesInQueue = 0; 368 369 #if 1 370 // add visible nodes found by the visibility culling algorithm 371 if (mUseDepthPass) 372 { 373 NodeList::const_iterator it, it_end = mVisible.end(); 374 375 //getRenderQueue()->clear(); 376 for (it = mVisible.begin(); it != it_end; ++ it) 377 { 378 (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false); 379 } 380 } 381 #endif 382 //-- now we can render all remaining queue objects 383 //-- used for depth pass, transparents, overlay 384 clearSpecialCaseRenderQueues(); 385 386 TerrainSceneManager::_renderVisibleObjects(); 387 } // hierarchical culling 388 389 // HACK: set the new render level index, important to avoid cracks 390 // in terrain caused by LOD 391 TerrainRenderable::NextRenderLevelIndex(); 392 393 // reset ambient light 394 setAmbientLight(savedAmbient); 395 396 getRenderQueue()->clear(); // finally clear render queue 397 if (0) OGRE_DELETE(mRenderQueue); // HACK: should rather only be cleared ... 398 399 if (0) WriteLog(); // write out stats 400 } 401 402 //----------------------------------------------------------------------- 403 void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam) 404 { 405 if (NORMAL_RENDER_HACK) 406 { 407 OctreeSceneManager::_updateSceneGraph(cam); 408 return; 409 } 410 411 mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface); 412 mHierarchyInterface->SetRenderSystem(mDestRenderSystem); 413 414 TerrainSceneManager::_updateSceneGraph(cam); 415 } 416 //----------------------------------------------------------------------- 417 bool OcclusionCullingSceneManager::setOption(const String & key, const void * val) 418 { 419 if (key == "UseDepthPass") 420 { 421 mUseDepthPass = (*static_cast<const bool *>(val)); 422 return true; 423 } 424 if (key == "PrepareVisualization") 425 { 426 mShowVisualization = (*static_cast<const bool *>(val)); 427 return true; 428 } 429 if (key == "RenderNodesForViz") 430 { 431 mRenderNodesForViz = (*static_cast<const bool *>(val)); 432 return true; 433 } 434 if (key == "RenderNodesContentForViz") 435 { 436 mRenderNodesContentForViz = (*static_cast<const bool *>(val)); 437 return true; 438 } 439 if (key == "SkyBoxEnabled") 440 { 441 mSkyBoxEnabled = (*static_cast<const bool *>(val)); 442 return true; 443 } 444 if (key == "SkyPlaneEnabled") 445 { 446 mSkyPlaneEnabled = (*static_cast<const bool *>(val)); 447 return true; 448 } 449 if (key == "SkyDomeEnabled") 450 { 451 mSkyDomeEnabled = (*static_cast<const bool *>(val)); 452 return true; 453 } 454 if (key == "VisualizeCulledNodes") 455 { 456 mVisualizeCulledNodes = (*static_cast<const bool *>(val)); 457 return true; 458 } 459 if (key == "DelayRenderTransparents") 460 { 461 mDelayRenderTransparents = (*static_cast<const bool *>(val)); 462 return true; 463 } 464 465 if (key == "DepthWrite") 466 { 467 mEnableDepthWrite = (*static_cast<const bool *>(val)); 468 return true; 469 } 470 if (key == "UseItemBuffer") 471 { 472 mUseItemBuffer = (*static_cast<const bool *>(val)); 473 return true; 474 } 475 if (key == "ExecuteVertexProgramForAllPasses") 476 { 477 mExecuteVertexProgramForAllPasses = (*static_cast<const bool *>(val)); 478 return true; 479 } 480 if (key == "RenderTransparentsForItemBuffer") 481 { 482 mRenderTransparentsForItemBuffer = (*static_cast<const bool *>(val)); 483 return true; 484 } 485 if (key == "NodeVizScale") 486 { 487 OctreeNode::setVizScale(*static_cast<const float *>(val)); 488 return true; 489 } 490 491 if (key == "UseArbQueries") 492 { 493 bool useArbQueries = (*static_cast<const bool *>(val)); 494 495 if (useArbQueries) 496 { 497 mHierarchyInterface->DeleteQueries(); 498 mDestRenderSystem->setConfigOption("ArbQueries", "Yes"); 499 } 500 else 501 { 502 mHierarchyInterface->DeleteQueries(); 503 mDestRenderSystem->setConfigOption("ArbQueries", "No"); 504 } 505 } 506 507 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 508 setOption(key, val) || TerrainSceneManager::setOption(key, val); 509 } 510 //----------------------------------------------------------------------- 511 bool OcclusionCullingSceneManager::getOption(const String & key, void *val) 512 { 513 if (key == "NumHierarchyNodes") 514 { 515 * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants; 516 return true; 517 } 518 519 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 520 getOption(key, val) && TerrainSceneManager::getOption(key, val); 521 } 522 //----------------------------------------------------------------------- 523 bool OcclusionCullingSceneManager::getOptionValues(const String & key, 524 StringVector &refValueList) 525 { 526 return TerrainSceneManager::getOptionValues( key, refValueList); 527 } 528 //----------------------------------------------------------------------- 529 bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys) 530 { 531 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 532 getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys); 533 } 534 //----------------------------------------------------------------------- 535 void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility:: 536 VisibilityManager *visManager) 537 { 538 mVisibilityManager = visManager; 539 } 540 //----------------------------------------------------------------------- 541 GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void ) 542 { 543 return mVisibilityManager; 544 } 545 //----------------------------------------------------------------------- 546 void OcclusionCullingSceneManager::WriteLog() 547 { 548 std::stringstream d; 549 550 d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", " 551 << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", " 552 << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", " 553 << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", " 554 << "Hierarchy nodes: " << mNumOctants << ", " 555 << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", " 556 << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", " 557 << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", " 558 << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", " 559 << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", " 560 << "Found objects: " << (int)mVisible.size() << "\n"; 561 562 LogManager::getSingleton().logMessage(d.str()); 563 } 564 //----------------------------------------------------------------------- 565 void OcclusionCullingSceneManager::renderObjects( 566 const RenderPriorityGroup::TransparentRenderablePassList& objs, 567 bool doLightIteration, const LightList* manualLightList) 568 { 569 // for correct rendering, transparents must be rendered after hierarchical culling 570 // => do nothing 571 if (NORMAL_RENDER_HACK || !mSkipTransparents) 572 { 573 OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList); 574 } 575 } 576 //----------------------------------------------------------------------- 577 bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass) 578 { 579 if (NORMAL_RENDER_HACK) 580 { 581 return SceneManager::validatePassForRendering(pass); 582 } 583 584 // skip all but first pass if we are doing the depth pass 585 if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0)) 586 { 587 return false; 588 } 589 // all but first pass 590 /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0)) 591 { 592 return false; 593 }*/ 594 595 return SceneManager::validatePassForRendering(pass); 596 } 597 //----------------------------------------------------------------------- 598 void OcclusionCullingSceneManager::renderQueueGroupObjects(RenderQueueGroup* pGroup) 599 { 600 if (NORMAL_RENDER_HACK || !mIsItemBufferPhase) 601 { 602 TerrainSceneManager::renderQueueGroupObjects(pGroup); 603 return; 604 } 605 606 //-- item buffer: render objects using false colors 607 608 // Iterate through priorities 609 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 610 611 while (groupIt.hasMoreElements()) 612 { 613 RenderItemBuffer(groupIt.getNext()); 614 } 615 } 616 //----------------------------------------------------------------------- 617 void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup) 618 { 619 // Do solids 620 RenderPriorityGroup::SolidRenderablePassMap solidObjs = pGroup->_getSolidPasses(); 621 622 // ----- SOLIDS LOOP ----- 623 RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend; 624 ipassend = solidObjs.end(); 625 626 for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass) 627 { 628 // Fast bypass if this group is now empty 629 if (ipass->second->empty()) 630 continue; 631 632 // Render only first pass of renderable as false color 633 if (ipass->first->getIndex() > 0) 634 continue; 635 636 RenderPriorityGroup::RenderableList* rendList = ipass->second; 637 638 RenderPriorityGroup::RenderableList::const_iterator irend, irendend; 639 irendend = rendList->end(); 640 641 for (irend = rendList->begin(); irend != irendend; ++irend) 642 { 643 if (0) 644 { 645 std::stringstream d; d << "itembuffer, pass name: " << 646 ipass->first->getParent()->getParent()->getName(); 647 648 LogManager::getSingleton().logMessage(d.str()); 649 } 650 651 RenderSingleObjectForItemBuffer(*irend, ipass->first); 652 } 653 } 654 655 //-- TRANSPARENT LOOP: must be handled differently from solids 656 657 // transparents are treated either as solids or completely discarded 658 if (mRenderTransparentsForItemBuffer) 659 { 660 RenderPriorityGroup::TransparentRenderablePassList transpObjs = 661 pGroup->_getTransparentPasses(); 662 RenderPriorityGroup::TransparentRenderablePassList::const_iterator 663 itrans, itransend; 664 665 itransend = transpObjs.end(); 666 for (itrans = transpObjs.begin(); itrans != itransend; ++itrans) 667 { 668 // like for solids, render only first pass 669 if (itrans->pass->getIndex() == 0) 670 { 671 RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass); 672 } 673 } 674 } 675 } 676 //----------------------------------------------------------------------- 677 void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass) 678 { 679 static LightList nullLightList; 680 681 int col[4]; 682 683 // -- create color code out of object id 684 col[0] = (rend->getId() >> 16) & 255; 685 col[1] = (rend->getId() >> 8) & 255; 686 col[2] = rend->getId() & 255; 687 // col[3] = 255; 688 689 //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]); 690 691 mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f, 692 col[1] / 255.0f, 693 col[2] / 255.0f, 1)); 694 695 // set vertex program of current pass 696 if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram()) 697 { 698 mItemBufferPass->setVertexProgram(pass->getVertexProgramName()); 699 700 if (mItemBufferPass->hasVertexProgram()) 701 { 702 const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram(); 703 // Load this program if not done already 704 if (!prg->isLoaded()) 705 prg->load(); 706 // Copy params 707 mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters()); 708 } 709 } 710 else if (mItemBufferPass->hasVertexProgram()) 711 { 712 mItemBufferPass->setVertexProgram(""); 713 } 714 715 Pass *usedPass = setPass(mItemBufferPass); 716 717 718 // Render a single object, this will set up auto params if required 719 renderSingleObject(rend, usedPass, false, &nullLightList); 720 } 721 //----------------------------------------------------------------------- 722 GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager() 723 { 724 return mVisibilityManager; 725 } 726 //----------------------------------------------------------------------- 727 void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam) 728 { 729 // reset culling manager stats 730 mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes); 731 732 // set depth pass flag before rendering 733 mIsDepthPassPhase = mUseDepthPass; 734 735 mIsHierarchicalCulling = true; // during hierarchical culling 736 737 // item buffer needs full ambient lighting to use item colors as unique id 738 if (mUseItemBuffer) 739 { 740 mIsItemBufferPhase = true; 741 setAmbientLight(ColourValue(1,1,1,1)); 742 } 743 744 745 // set passes which are stored in render queue 746 // for rendering AFTER hierarchical culling, i.e., passes which need 747 // a special rendering order 748 749 mLeavePassesInQueue = 0; 750 751 if (!mUseDepthPass && !mUseItemBuffer) 752 { 753 if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE) 754 { 755 // TODO: remove this pass because it should be processed during hierarchical culling 756 //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 757 758 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL; 759 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR; 760 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 761 762 // just render ambient stuff 763 mIlluminationStage = IRS_AMBIENT; 764 getRenderQueue()->setSplitPassesByLightingType(true); 765 } 766 767 if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE) 768 { 769 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 770 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 771 } 772 773 // transparents should be rendered after hierarchical culling to 774 // provide front-to-back ordering 775 if (mDelayRenderTransparents) 776 { 777 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 778 } 779 } 780 781 // skip rendering transparents during the hierarchical culling 782 // (because they will be rendered afterwards) 783 mSkipTransparents = 784 (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES)); 785 786 // -- initialise interface for rendering traversal of the hierarchy 787 mHierarchyInterface->SetHierarchyRoot(mOctree); 788 789 // possible two cameras (one for culling, one for rendering) 790 mHierarchyInterface->InitTraversal(mCameraInProgress, 791 mCullCamera ? getCamera("CullCamera") : NULL, 792 mLeavePassesInQueue); 793 794 } 795 //----------------------------------------------------------------------- 796 OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface() 797 { 798 return mHierarchyInterface; 799 } 800 //----------------------------------------------------------------------- 801 void OcclusionCullingSceneManager::endFrame() 802 { 803 TerrainRenderable::ResetRenderLevelIndex(); 804 } 805 //----------------------------------------------------------------------- 806 Entity* OcclusionCullingSceneManager::createEntity(const String& entityName, 807 const String& meshName) 808 { 809 Entity *ent = SceneManager::createEntity(entityName, meshName); 810 811 for (int i = 0; i < (int)ent->getNumSubEntities(); ++i) 812 { 813 ent->getSubEntity(i)->setId(mCurrentEntityId); 814 } 815 816 // increase counter of entity id values 817 ++ mCurrentEntityId; 818 819 return ent; 820 } 821 //----------------------------------------------------------------------- 822 void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup) 823 { 824 // only render solid passes during hierarchical culling 825 if (mIsHierarchicalCulling) 826 { 827 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 828 LightList lightList; 829 830 while (groupIt.hasMoreElements()) 831 { 832 RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 833 834 // Sort the queue first 835 pPriorityGrp->sort(mCameraInProgress); 836 837 // Clear light list 838 lightList.clear(); 839 840 // Render all the ambient passes first, no light iteration, no lights 841 mIlluminationStage = IRS_AMBIENT; 842 843 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), false, &lightList); 844 // Also render any objects which have receive shadows disabled 845 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPassesNoShadow(), true); 846 } 847 } 848 else 849 { 850 OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup); 851 } 852 } 853 //----------------------------------------------------------------------- 854 void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup) 855 { 856 if (mIsHierarchicalCulling) 857 { 858 // Iterate through priorities 859 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 860 861 while (groupIt.hasMoreElements()) 862 { 863 RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 864 865 // Sort the queue first 866 pPriorityGrp->sort(mCameraInProgress); 867 868 // Do (shadowable) solids 869 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), true); 870 } 871 } 872 else 873 { 874 SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup); 875 } 100 876 } 101 877 //------------------------------------------------------------------------- … … 123 899 124 900 setupTerrainMaterial(); 125 126 901 setupTerrainPages(); 127 128 } 129 130 //----------------------------------------------------------------------- 131 void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam) 132 { 133 // add player camera for visualization purpose 134 try 135 { 136 Camera *c; 137 if ((c = getCamera("PlayerCam")) != NULL) 138 { 139 getRenderQueue()->addRenderable(c); 140 } 141 } 142 catch (...) 143 { 144 // ignore 145 } 146 for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) 147 { 148 getRenderQueue()->addRenderable(*it); 149 } 150 if (mRenderNodesForViz || mRenderNodesContentForViz) 151 { 152 // HACK: change node material so it is better suited for visualization 153 MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial"); 154 nodeMat->setAmbient(1, 1, 0); 155 nodeMat->setLightingEnabled(true); 156 nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); 157 158 for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it) 159 { 160 if (mRenderNodesForViz) 161 { 162 // render the leaf nodes 163 if (((*it)->numAttachedObjects() > 0) && ((*it)->numChildren() == 0) && 164 (*it)->getAttachedObject(0)->getMovableType() == "Entity") 165 { 166 getRenderQueue()->addRenderable((*it)); 167 } 168 169 // addbounding boxes instead of node itself 170 //(*it)->_addBoundingBoxToQueue(getRenderQueue()); 171 } 172 if (mRenderNodesContentForViz) 173 { 174 (*it)->_addToRenderQueue(cam, getRenderQueue(), false); 175 } 176 } 177 } 178 } 179 //----------------------------------------------------------------------- 180 Pass *OcclusionCullingSceneManager::setPass(Pass* pass) 181 { 182 // TODO: setting vertex program is not efficient 183 //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass); 184 185 // set depth fill pass if we currently do not make an aabb occlusion query 186 Pass *usedPass = (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery() ? 187 mDepthPass : pass); 188 189 IlluminationRenderStage savedStage = mIlluminationStage; 190 191 // set illumination stage to NONE so no shadow material is used 192 // for depth pass or for occlusion query 193 if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery()) 194 { 195 mIlluminationStage = IRS_NONE; 196 } 197 198 // --- set vertex program of current pass in order to set correct depth 199 if (mExecuteVertexProgramForAllPasses && mIsDepthPassPhase && pass->hasVertexProgram()) 200 { 201 // add vertex program of current pass to depth pass 202 mDepthPass->setVertexProgram(pass->getVertexProgramName()); 203 204 if (mDepthPass->hasVertexProgram()) 205 { 206 const GpuProgramPtr& prg = mDepthPass->getVertexProgram(); 207 // Load this program if not done already 208 if (!prg->isLoaded()) 209 prg->load(); 210 // Copy params 211 mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters()); 212 } 213 } 214 else if (mDepthPass->hasVertexProgram()) 215 { 216 mDepthPass->setVertexProgram(""); 217 } 218 219 220 bool IsDepthWrite = usedPass->getDepthWriteEnabled(); 221 222 // global option which enables / disables depth writes 223 if (!mEnableDepthWrite) 224 { 225 usedPass->setDepthWriteEnabled(false); 226 } 227 //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;} 228 229 Pass *result = SceneManager::setPass(usedPass); 230 231 // reset depth write 232 if (!mEnableDepthWrite) 233 { 234 usedPass->setDepthWriteEnabled(IsDepthWrite); 235 } 236 237 // reset illumination stage 238 mIlluminationStage = savedStage; 239 240 return result; 241 } 242 //----------------------------------------------------------------------- 243 void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam, 244 bool onlyShadowCasters) 245 { 246 //-- show visible scene nodes and octree bounding boxes from last frame 247 if (mShowVisualization) 248 { 249 PrepareVisualization(cam); 250 } 251 else 252 { 253 // for hierarchical culling, we interleave identification 254 // and rendering of objects in _renderVisibibleObjects 255 256 // for the shadow pass we use only standard rendering 257 // because of low occlusion 258 if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 259 mIlluminationStage == IRS_RENDER_TO_TEXTURE) 260 { 261 TerrainSceneManager::_findVisibleObjects(cam, onlyShadowCasters); 262 } 263 // only shadow casters will be rendered in shadow texture pass 264 // mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters); 265 } 266 267 268 // -- delete lists stored for visualization 269 mVisible.clear(); 270 mBoxes.clear(); 271 } 272 //----------------------------------------------------------------------- 273 void OcclusionCullingSceneManager::_renderVisibleObjects() 274 { 275 276 InitDepthPass(); // create material for depth pass 277 InitItemBufferPass(); // create material for item buffer pass 278 279 // save ambient light to reset later 280 ColourValue savedAmbient = mAmbientLight; 281 282 //-- apply standard rendering for some modes (e.g., visualization, shadow pass) 283 284 if (mShowVisualization || 285 (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 286 mIlluminationStage == IRS_RENDER_TO_TEXTURE)) 287 { 288 IlluminationRenderStage savedStage = mIlluminationStage; 289 290 if (mShowVisualization) 291 // disable illumination stage to prevent rendering shadows 292 mIlluminationStage = IRS_NONE; 293 294 // standard rendering for shadow maps because of performance 295 TerrainSceneManager::_renderVisibleObjects(); 296 297 mIlluminationStage = savedStage; 298 } 299 else //-- the hierarchical culling algorithm 300 { 301 // don't render backgrounds for item buffer 302 if (mUseItemBuffer) 303 { 304 clearSpecialCaseRenderQueues(); 305 getRenderQueue()->clear(); 306 } 307 308 //-- hierarchical culling 309 // the objects of different layers (e.g., background, scene, 310 // overlay) must be identified and rendered one after another 311 312 //-- render all early skies 313 clearSpecialCaseRenderQueues(); 314 addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND); 315 addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY); 316 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE); 317 318 TerrainSceneManager::_renderVisibleObjects(); 319 320 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 321 // delete previously rendered content 322 _deleteRenderedQueueGroups(); 323 #endif 324 325 //-- prepare queue for visible objects (i.e., all but overlay and skies late) 326 clearSpecialCaseRenderQueues(); 327 addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE); 328 addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY); 329 330 // exclude this queues from hierarchical rendering 331 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 332 333 // set all necessary parameters for 334 // hierarchical visibility culling and rendering 335 InitVisibilityCulling(mCameraInProgress); 336 337 338 /** 339 * the hierarchical culling algorithm 340 * for depth pass: we just find objects and update depth buffer 341 * for "delayed" rendering: we render some passes afterwards 342 * e.g., transparents, because they need front-to-back sorting 343 **/ 344 345 mVisibilityManager->ApplyVisibilityCulling(); 346 347 // delete remaining renderables from queue (all not in mLeavePassesInQueue) 348 #ifdef GTP_VISIBILITY_MODIFIED_OGRE 349 _deleteRenderedQueueGroups(mLeavePassesInQueue); 350 #endif 351 352 //-- reset parameters 353 mIsDepthPassPhase = false; 354 mIsItemBufferPhase = false; 355 mSkipTransparents = false; 356 mLeavePassesInQueue = 0; 357 358 359 // add visible nodes found by the visibility culling algorithm 360 if (mUseDepthPass) 361 { 362 for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++ it) 363 { 364 (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false); 365 } 366 } 367 368 //-- now we can render all remaining queue objects 369 // used for depth pass, transparents, overlay 370 clearSpecialCaseRenderQueues(); 371 372 TerrainSceneManager::_renderVisibleObjects(); 373 } 374 375 // HACK: set the new render level index, important to avoid cracks 376 // in terrain caused by LOD 377 TerrainRenderable::NextRenderLevelIndex(); 378 379 // reset ambient light 380 setAmbientLight(savedAmbient); 381 382 getRenderQueue()->clear(); // finally clear render queue 383 OGRE_DELETE(mRenderQueue); // HACK: should be cleared before ... 384 WriteLog(); // write out stats 385 386 } 387 388 //----------------------------------------------------------------------- 389 void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam) 390 { 391 mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface); 392 mHierarchyInterface->SetRenderSystem(mDestRenderSystem); 393 394 TerrainSceneManager::_updateSceneGraph(cam); 395 } 396 //----------------------------------------------------------------------- 397 bool OcclusionCullingSceneManager::setOption(const String & key, const void * val) 398 { 399 if (key == "UseDepthPass") 400 { 401 mUseDepthPass = (*static_cast<const bool *>(val)); 402 return true; 403 } 404 if (key == "PrepareVisualization") 405 { 406 mShowVisualization = (*static_cast<const bool *>(val)); 407 return true; 408 } 409 if (key == "RenderNodesForViz") 410 { 411 mRenderNodesForViz = (*static_cast<const bool *>(val)); 412 return true; 413 } 414 if (key == "RenderNodesContentForViz") 415 { 416 mRenderNodesContentForViz = (*static_cast<const bool *>(val)); 417 return true; 418 } 419 if (key == "SkyBoxEnabled") 420 { 421 mSkyBoxEnabled = (*static_cast<const bool *>(val)); 422 return true; 423 } 424 if (key == "SkyPlaneEnabled") 425 { 426 mSkyPlaneEnabled = (*static_cast<const bool *>(val)); 427 return true; 428 } 429 if (key == "SkyDomeEnabled") 430 { 431 mSkyDomeEnabled = (*static_cast<const bool *>(val)); 432 return true; 433 } 434 if (key == "VisualizeCulledNodes") 435 { 436 mVisualizeCulledNodes = (*static_cast<const bool *>(val)); 437 return true; 438 } 439 if (key == "DelayRenderTransparents") 440 { 441 mDelayRenderTransparents = (*static_cast<const bool *>(val)); 442 return true; 443 } 444 445 if (key == "DepthWrite") 446 { 447 mEnableDepthWrite = (*static_cast<const bool *>(val)); 448 return true; 449 } 450 if (key == "UseItemBuffer") 451 { 452 mUseItemBuffer = (*static_cast<const bool *>(val)); 453 return true; 454 } 455 if (key == "ExecuteVertexProgramForAllPasses") 456 { 457 mExecuteVertexProgramForAllPasses = (*static_cast<const bool *>(val)); 458 return true; 459 } 460 if (key == "RenderTransparentsForItemBuffer") 461 { 462 mRenderTransparentsForItemBuffer = (*static_cast<const bool *>(val)); 463 return true; 464 } 465 if (key == "NodeVizScale") 466 { 467 OctreeNode::setVizScale(*static_cast<const float *>(val)); 468 return true; 469 } 470 471 if (key == "UseArbQueries") 472 { 473 bool useArbQueries = (*static_cast<const bool *>(val)); 474 475 if (useArbQueries) 476 { 477 mHierarchyInterface->DeleteQueries(); 478 mDestRenderSystem->setConfigOption("ArbQueries", "Yes"); 479 } 480 else 481 { 482 mHierarchyInterface->DeleteQueries(); 483 mDestRenderSystem->setConfigOption("ArbQueries", "No"); 484 } 485 } 486 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 487 setOption(key, val) || TerrainSceneManager::setOption(key, val); 488 } 489 //----------------------------------------------------------------------- 490 bool OcclusionCullingSceneManager::getOption(const String & key, void *val) 491 { 492 if (key == "NumHierarchyNodes") 493 { 494 * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants; 495 return true; 496 } 497 498 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 499 getOption(key, val) && TerrainSceneManager::getOption(key, val); 500 } 501 //----------------------------------------------------------------------- 502 bool OcclusionCullingSceneManager::getOptionValues(const String & key, 503 StringVector &refValueList) 504 { 505 return TerrainSceneManager::getOptionValues( key, refValueList); 506 } 507 //----------------------------------------------------------------------- 508 bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys) 509 { 510 return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 511 getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys); 512 } 513 //----------------------------------------------------------------------- 514 void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility:: 515 VisibilityManager *visManager) 516 { 517 mVisibilityManager = visManager; 518 } 519 //----------------------------------------------------------------------- 520 GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void ) 521 { 522 return mVisibilityManager; 523 } 524 //----------------------------------------------------------------------- 525 void OcclusionCullingSceneManager::WriteLog() 526 { 527 std::stringstream d; 528 529 d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", " 530 << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", " 531 << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", " 532 << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", " 533 << "Hierarchy nodes: " << mNumOctants << ", " 534 << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", " 535 << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", " 536 << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", " 537 << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", " 538 << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << "\n"; 539 540 LogManager::getSingleton().logMessage(d.str()); 541 } 542 //----------------------------------------------------------------------- 543 void OcclusionCullingSceneManager::renderObjects( 544 const RenderPriorityGroup::TransparentRenderablePassList& objs, 545 bool doLightIteration, const LightList* manualLightList) 546 { 547 // for correct rendering, transparents must be rendered after hierarchical culling 548 if (!mSkipTransparents) 549 { 550 OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList); 551 } 552 } 553 //----------------------------------------------------------------------- 554 bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass) 555 { 556 // skip all but first pass if we are doing the depth pass 557 if ((mIsDepthPassPhase || mIsItemBufferPhase) && pass->getIndex() > 0) 558 { 559 return false; 560 } 561 562 return SceneManager::validatePassForRendering(pass); 563 } 564 //----------------------------------------------------------------------- 565 void OcclusionCullingSceneManager::renderQueueGroupObjects(RenderQueueGroup* pGroup) 566 { 567 if (!mIsItemBufferPhase) 568 { 569 TerrainSceneManager::renderQueueGroupObjects(pGroup); 570 return; 571 } 572 573 //-- item buffer 574 575 // Iterate through priorities 576 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 577 578 while (groupIt.hasMoreElements()) 579 { 580 RenderItemBuffer(groupIt.getNext()); 581 } 582 } 583 //----------------------------------------------------------------------- 584 void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup) 585 { 586 // Do solids 587 RenderPriorityGroup::SolidRenderablePassMap solidObjs = pGroup->_getSolidPasses(); 588 589 // ----- SOLIDS LOOP ----- 590 RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend; 591 ipassend = solidObjs.end(); 592 593 for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass) 594 { 595 // Fast bypass if this group is now empty 596 if (ipass->second->empty()) 597 continue; 598 599 // Render only first pass 600 if (ipass->first->getIndex() > 0) 601 continue; 602 603 RenderPriorityGroup::RenderableList* rendList = ipass->second; 604 605 RenderPriorityGroup::RenderableList::const_iterator irend, irendend; 606 irendend = rendList->end(); 607 608 for (irend = rendList->begin(); irend != irendend; ++irend) 609 { 610 //std::stringstream d; d << "itembuffer, pass name: " << 611 // ipass->first->getParent()->getParent()->getName(); 612 // LogManager::getSingleton().logMessage(d.str()); 613 614 RenderSingleObjectForItemBuffer(*irend, ipass->first); 615 } 616 } 617 618 // -- TRANSPARENT LOOP: must be handled differently 619 620 // transparents are treated either as solids or completely discarded 621 if (mRenderTransparentsForItemBuffer) 622 { 623 RenderPriorityGroup::TransparentRenderablePassList transpObjs = 624 pGroup->_getTransparentPasses(); 625 RenderPriorityGroup::TransparentRenderablePassList::const_iterator 626 itrans, itransend; 627 628 itransend = transpObjs.end(); 629 for (itrans = transpObjs.begin(); itrans != itransend; ++itrans) 630 { 631 // like for solids, render only first pass 632 if (itrans->pass->getIndex() == 0) 633 { 634 RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass); 635 } 636 } 637 } 638 } 639 //----------------------------------------------------------------------- 640 void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass) 641 { 642 static LightList nullLightList; 643 644 int col[4]; 645 646 // -- create color code out of object id 647 col[0] = (rend->getId() >> 16) & 255; 648 col[1] = (rend->getId() >> 8) & 255; 649 col[2] = rend->getId() & 255; 650 // col[3] = 255; 651 652 //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]); 653 654 mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f, 655 col[1] / 255.0f, 656 col[2] / 255.0f, 1)); 657 658 // set vertex program of current pass 659 if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram()) 660 { 661 mItemBufferPass->setVertexProgram(pass->getVertexProgramName()); 662 663 if (mItemBufferPass->hasVertexProgram()) 664 { 665 const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram(); 666 // Load this program if not done already 667 if (!prg->isLoaded()) 668 prg->load(); 669 // Copy params 670 mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters()); 671 } 672 } 673 else if (mItemBufferPass->hasVertexProgram()) 674 { 675 mItemBufferPass->setVertexProgram(""); 676 } 677 678 Pass *usedPass = setPass(mItemBufferPass); 679 680 681 // Render a single object, this will set up auto params if required 682 renderSingleObject(rend, usedPass, false, &nullLightList); 683 } 684 //----------------------------------------------------------------------- 685 GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager() 686 { 687 return mVisibilityManager; 688 } 689 //----------------------------------------------------------------------- 690 void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam) 691 { 692 // reset culling manager stats 693 mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes); 694 695 // set depth pass flag before rendering 696 mIsDepthPassPhase = mUseDepthPass; 697 698 // item buffer needs full ambient lighting to use item colors as unique id 699 if (mUseItemBuffer) 700 { 701 mIsItemBufferPhase = true; 702 setAmbientLight(ColourValue(1,1,1,1)); 703 } 704 705 706 // set passes which are stored in render queue 707 // for rendering AFTER hierarchical culling, i.e., passes which need 708 // a special rendering order 709 mLeavePassesInQueue = 0; 710 711 // if we have the depth pass or use an item buffer, no passes are left in the queue 712 if (0 && !mUseDepthPass && !mUseItemBuffer) 713 { 714 if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE) 715 { 716 // TODO: remove this pass because it should be processed during hierarchical culling 717 //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 718 719 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL; 720 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR; 721 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 722 723 // just render ambient stuff 724 mIlluminationStage = IRS_AMBIENT; 725 } 726 727 if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE) 728 { 729 mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW; 730 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 731 } 732 733 // transparents should be rendered after hierarchical culling to 734 // provide front-to-back ordering 735 if (mDelayRenderTransparents) 736 { 737 mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES; 738 } 739 } 740 741 // skip rendering transparents in the hierarchical culling 742 // (because they will be rendered afterwards) 743 mSkipTransparents = mUseDepthPass || 744 (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES); 745 746 // -- initialise interface for rendering traversal of the hierarchy 747 mHierarchyInterface->SetHierarchyRoot(mOctree); 748 749 // possible two cameras (one for culling, one for rendering) 750 mHierarchyInterface->InitTraversal(mCameraInProgress, 751 mCullCamera ? getCamera("CullCamera") : NULL, 752 mLeavePassesInQueue); 753 754 } 755 //----------------------------------------------------------------------- 756 OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface() 757 { 758 return mHierarchyInterface; 759 } 760 //----------------------------------------------------------------------- 761 void OcclusionCullingSceneManager::endFrame() 762 { 763 TerrainRenderable::ResetRenderLevelIndex(); 764 } 765 //----------------------------------------------------------------------- 766 Entity* OcclusionCullingSceneManager::createEntity(const String& entityName, 767 const String& meshName) 768 { 769 Entity *ent = SceneManager::createEntity(entityName, meshName); 770 771 for (int i = 0; i < (int)ent->getNumSubEntities(); ++i) 772 { 773 ent->getSubEntity(i)->setId(mCurrentEntityId); 774 } 775 776 // increase counter of entity id values 777 ++ mCurrentEntityId; 778 779 return ent; 780 } 781 //----------------------------------------------------------------------- 782 void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup) 783 { 784 // only render solid passes during hierarchical culling 785 if (mIsHierarchicalCulling) 786 { 787 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 788 LightList lightList; 789 790 while (groupIt.hasMoreElements()) 791 { 792 RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 793 794 // Sort the queue first 795 pPriorityGrp->sort(mCameraInProgress); 796 797 // Clear light list 798 lightList.clear(); 799 800 // Render all the ambient passes first, no light iteration, no lights 801 mIlluminationStage = IRS_AMBIENT; 802 803 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), false, &lightList); 804 // Also render any objects which have receive shadows disabled 805 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPassesNoShadow(), true); 806 } 807 } 808 else 809 { 810 OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup); 811 } 812 } 813 //----------------------------------------------------------------------- 814 void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup) 815 { 816 if (mIsHierarchicalCulling) 817 { 818 // Iterate through priorities 819 RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); 820 821 while (groupIt.hasMoreElements()) 822 { 823 RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); 824 825 // Sort the queue first 826 pPriorityGrp->sort(mCameraInProgress); 827 828 // Do (shadowable) solids 829 OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), true); 830 } 831 } 832 else 833 { 834 SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup); 835 } 836 } 837 838 902 } 903 904 //------------------------------------------------------------------------- 839 905 MovableObject *OcclusionCullingSceneManager::FindCorrespondingObject(const AxisAlignedBox &box) 840 906 { … … 861 927 const AxisAlignedBox bbox = mo->getWorldBoundingBox(); 862 928 863 const float overlap = GtpVisibilityPreprocessor:: FactorOfOverlap(929 const float overlap = GtpVisibilityPreprocessor::RatioOfOverlap( 864 930 OgreTypeConverter::ConvertFromOgre(bbox), 865 931 OgreTypeConverter::ConvertFromOgre(box)); … … 869 935 bestFit = overlap; 870 936 bestFittingObj = mo; 871 937 872 938 // perfect fit => object found 873 939 if (overlap > (1.0 - GtpVisibilityPreprocessor::Limits::Small)) … … 886 952 // identify the corresponding Ogre meshes using the bounding boxes 887 953 IdentifyObjects(objects); 888 954 889 955 // load the view cells assigning the found objects to the pvss 890 956 mViewCellsManager->LoadViewCells(filename, &objects); … … 908 974 909 975 MovableObject *mo = FindCorrespondingObject(currentBox); 910 911 976 //objects.push_back(mi); 912 977 } -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOctreeHierarchyInterface.cpp
r827 r868 112 112 OctreeSceneManager *ocm = 113 113 //dynamic_cast<OctreeSceneManager *>(mSceneManager); 114 static_cast<OctreeSceneManager *>(mSceneManager);114 dynamic_cast<OctreeSceneManager *>(mSceneManager); 115 115 ocm->_renderOctant(mCamera, octant, mOnlyShadowCasters, mLeavePassesInQueue); 116 116 … … 144 144 { 145 145 mSavedNode = node; 146 // static_cast<Octree *>(node)->_getCullBounds(&mBox);146 //dynamic_cast<Octree *>(node)->_getCullBounds(&mBox); 147 147 mBox = static_cast<Octree *>(node)->_getWorldAABB(); 148 148 } … … 166 166 167 167 //dynamic_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box); 168 static_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box);168 dynamic_cast<OctreeSceneManager *>(mSceneManager)->getBoxes()->push_back(box); 169 169 } 170 170 //----------------------------------------------------------------------- -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreVisibilityOctreeSceneManager.cpp
r865 r868 9 9 #include <OgreEntity.h> 10 10 #include <OgreSubEntity.h> 11 #include <OgreIteratorWrappers.h> 12 #include "VspBspTree.h" 13 #include "Containers.h" 14 #include "ViewCellsManager.h" 11 15 #include <OgreConfigFile.h> 16 #include "OgreTypeConverter.h" 12 17 13 18 // normal terrain rendering … … 36 41 mRenderTransparentsForItemBuffer(true), 37 42 mExecuteVertexProgramForAllPasses(true), 38 mIsHierarchicalCulling(false) 43 mIsHierarchicalCulling(false), 44 mViewCellsLoaded(false) 39 45 { 40 46 mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem); … … 51 57 52 58 //loadVisibilityConfig("GtpVisibility.cfg"); 59 //LoadViewCells(""); 60 //mViewCellsLoaded = true; 53 61 } 54 62 //----------------------------------------------------------------------- … … 140 148 (*it)->getAttachedObject(0)->getMovableType() == "Entity") 141 149 { 142 getRenderQueue()->addRenderable((*it)); 150 getRenderQueue()->addRenderable((*it)); 151 std::stringstream d; 152 d << "here 223 " << (*it)->getAttachedObject(0)->getWorldBoundingBox(); 153 Ogre::LogManager::getSingleton().logMessage(d.str()); 143 154 } 144 155 … … 146 157 //(*it)->_addBoundingBoxToQueue(getRenderQueue()); 147 158 } 159 // add renderables itself 148 160 if (mRenderNodesContentForViz) 149 161 { … … 301 313 // this is also called in TerrainSceneManager: really 302 314 // nexessary? 303 mDestRenderSystem -> setLightingEnabled(false);315 //mDestRenderSystem -> setLightingEnabled(false); 304 316 305 317 // don't render backgrounds for item buffer … … 332 344 addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE); 333 345 addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY); 334 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); 335 346 336 347 // exclude this queues from hierarchical rendering 337 348 setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); … … 340 351 // hierarchical visibility culling and rendering 341 352 InitVisibilityCulling(mCameraInProgress); 353 342 354 343 355 /** … … 482 494 return true; 483 495 } 484 485 if (key == "UseArbQueries") 486 { 487 bool useArbQueries = (*static_cast<const bool *>(val)); 488 489 if (useArbQueries) 490 { 491 mHierarchyInterface->DeleteQueries(); 492 mDestRenderSystem->setConfigOption("ArbQueries", "Yes"); 493 } 494 else 495 { 496 mHierarchyInterface->DeleteQueries(); 497 mDestRenderSystem->setConfigOption("ArbQueries", "No"); 498 } 496 if (key == "LoadViewCells") 497 { 498 if (!mViewCellsLoaded) 499 { 500 LoadViewCells(""); 501 mViewCellsLoaded = true; 502 } 503 504 return true; 499 505 } 500 506 … … 563 569 if (NORMAL_RENDER_HACK || !mSkipTransparents) 564 570 { 565 SceneManager::renderObjects(objs, doLightIteration, manualLightList);571 OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList); 566 572 } 567 573 } … … 870 876 } 871 877 } 878 //----------------------------------------------------------------------- 879 MovableObject *VisibilityOctreeSceneManager::FindCorrespondingObject(const AxisAlignedBox &box) 880 { 881 list<SceneNode *> sceneNodeList; 882 883 findNodesIn(box, sceneNodeList, NULL); 884 std::stringstream d; 885 d << "\n*******************"; 886 Ogre::LogManager::getSingleton().logMessage(d.str()); 887 list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end(); 888 889 float overlap = GtpVisibilityPreprocessor::Limits::Small; 890 891 892 d << "here23 " << box; 893 Ogre::LogManager::getSingleton().logMessage(d.str()); 894 895 MovableObject *bestFittingObj = NULL; 896 float bestFit = overlap; 897 898 // perfect fit threshold 899 const float thresh = 1.0 - GtpVisibilityPreprocessor::Limits::Small; 900 901 902 // find the bbox which is closest to the current bbox 903 for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit) 904 { 905 SceneNode *sn = *sit; 906 SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator(); 907 908 while (oit.hasMoreElements()) 909 { 910 MovableObject *mo = oit.getNext(); 911 const AxisAlignedBox bbox = mo->getWorldBoundingBox(true); 912 913 overlap = RatioOfOverlap(OgreTypeConverter::ConvertFromOgre(box), 914 OgreTypeConverter::ConvertFromOgre(bbox)); 915 if (overlap > bestFit) 916 { 917 bestFit = overlap; 918 bestFittingObj = mo; 919 d << "new bestfit " << bestFit << endl;Ogre::LogManager::getSingleton().logMessage(d.str()); 920 // perfect fit => object found 921 if (overlap >= thresh) 922 { 923 std::stringstream d2; 924 925 d2 << "!!best fit " << bestFittingObj->getWorldBoundingBox(true); 926 Ogre::LogManager::getSingleton().logMessage(d2.str()); 927 return bestFittingObj; 928 } 929 } 930 } 931 } 932 933 std::stringstream d2; 934 if (bestFittingObj) 935 { 936 d2 << "best fit " << bestFittingObj->getWorldBoundingBox(true); 937 } 938 else 939 { 940 d2 << "warning, no best fitting objects"; 941 } 942 943 Ogre::LogManager::getSingleton().logMessage(d2.str()); 944 945 return bestFittingObj; 946 } 947 //----------------------------------------------------------------------- 948 void VisibilityOctreeSceneManager::LoadViewCells(string filename) 949 { 950 GtpVisibilityPreprocessor::ObjectContainer objects; 951 // identify the corresponding Ogre meshes using the bounding boxes 952 IdentifyObjects(objects); 953 954 // load the view cells assigning the found objects to the pvss 955 //mViewCellsManager->LoadViewCells(filename, &objects); 956 } 957 //----------------------------------------------------------------------- 958 void VisibilityOctreeSceneManager::IdentifyObjects(GtpVisibilityPreprocessor::ObjectContainer &objects) 959 { 960 const string bboxesFilename = "boxes.out"; 961 962 GtpVisibilityPreprocessor::IndexedBoundingBoxContainer iboxes; 963 mViewCellsManager->LoadBoundingBoxes(bboxesFilename, iboxes); 964 965 GtpVisibilityPreprocessor::IndexedBoundingBoxContainer:: 966 const_iterator iit, iit_end = iboxes.end(); 967 968 for (iit = iboxes.begin(); iit != iit_end; ++ iit) 969 { 970 const GtpVisibilityPreprocessor::AxisAlignedBox3 box = (*iit).second; 971 const AxisAlignedBox currentBox = OgreTypeConverter::ConvertToOgre(box); 972 973 MovableObject *mo = FindCorrespondingObject(currentBox); 974 975 //objects.push_back(mi); 976 } 977 } 978 872 979 //------------------------------------------------------------------------- 873 980 void VisibilityOctreeSceneManager::loadVisibilityConfig(const String& filename) -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreVisibilityTerrainSceneManager.cpp
r865 r868 380 380 381 381 OctreeSceneManager::_renderVisibleObjects(); 382 382 383 } // hierarchical culling 383 384 … … 874 875 } 875 876 877 //------------------------------------------------------------------------- 878 void VisibilityTerrainSceneManager::setWorldGeometry( const String& filename ) 879 { 880 // Clear out any existing world resources (if not default) 881 if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() != 882 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) 883 { 884 ResourceGroupManager::getSingleton().clearResourceGroup( 885 ResourceGroupManager::getSingleton().getWorldResourceGroupName()); 886 } 887 888 mTerrainPages.clear(); 889 // Load the configuration 890 loadConfig(filename); 891 892 // Resize the octree, allow for 1 page for now 893 float max_x = mOptions.scale.x * mOptions.pageSize; 894 float max_y = mOptions.scale.y; 895 float max_z = mOptions.scale.z * mOptions.pageSize; 896 897 //-- note: slows down view frustum culling! 898 #if 1 899 float maxAxis = std::max(max_x, max_y); 900 maxAxis = std::max(maxAxis, max_z); 901 resize( AxisAlignedBox( 0, 0, 0, maxAxis, maxAxis, maxAxis ) ); 902 #else 903 resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) ); 904 #endif 905 906 setupTerrainMaterial(); 907 setupTerrainPages(); 908 909 } 910 876 911 } // namespace Ogre
Note: See TracChangeset
for help on using the changeset viewer.