Changeset 868 for GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE
- Timestamp:
- 05/01/06 00:08:09 (19 years ago)
- Location:
- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOcclusionCullingSceneManager.h
r863 r868 71 71 */ 72 72 bool validatePassForRendering(Pass* pass); 73 73 /** This function renders renderables using false color ids. 74 */ 74 75 void RenderItemBuffer(RenderPriorityGroup* pGroup); 76 /** Renders a single object using false color id. 77 */ 75 78 void RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass); 79 /** Overritten from scene manager to include the false color id rendering of the 80 scene objects. 81 */ 76 82 void renderQueueGroupObjects(RenderQueueGroup* pGroup); 77 83 … … 88 94 OctreeHierarchyInterface *GetHierarchyInterface(); 89 95 90 /** Inherited from scene manager. Neccesary to draw terrain properly.96 /** Override this because we must handle shadows differently. 91 97 */ 92 98 void endFrame(); … … 171 177 int mLeavePassesInQueue; 172 178 179 173 180 /// if transparent object are considered for item buffer visibility 174 181 bool mRenderTransparentsForItemBuffer; 175 182 /// Always execute the vertex program of a pass, e.g., for the depth pass or item buffer 176 183 bool mExecuteVertexProgramForAllPasses; 184 177 185 /// if hierarchical culling is currently in use 178 186 bool mIsHierarchicalCulling; -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreVisibilityOctreeSceneManager.h
r865 r868 11 11 #include "OgrePlatformQueryManager.h" 12 12 #include "VisibilityManager.h" 13 #include "ViewCellsManager.h" 14 15 //class GtpVisibilityPreprocessor::ViewCellsManager; 13 16 14 17 … … 98 101 void loadVisibilityConfig(const String& filename); 99 102 103 104 /** Loads view cells for this particular scene. 105 */ 106 void LoadViewCells(std::string filename); 107 100 108 protected: 101 109 … … 113 121 void InitVisibilityCulling(Camera *cam); 114 122 123 /** Finds object corresponding to this bounding box in the scene. 124 */ 125 MovableObject *FindCorrespondingObject(const AxisAlignedBox &box); 115 126 127 /** Identifies objects in the scene and gives them unique ids that 128 correspond to preprocessor ids. 129 */ 130 void IdentifyObjects(GtpVisibilityPreprocessor::ObjectContainer &objects); 116 131 117 132 /// the interface to the scene hierarchy. … … 163 178 bool mExecuteVertexProgramForAllPasses; 164 179 180 /// if hierarchical culling is currently in use 165 181 bool mIsHierarchicalCulling; 166 182 167 std::ofstream mDummyLog; 183 bool mViewCellsLoaded; 184 GtpVisibilityPreprocessor::ViewCellsManager *mViewCellsManager; 168 185 }; 169 186 -
GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreVisibilityTerrainSceneManager.h
r865 r868 102 102 void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup); 103 103 104 /** Override standard function so octree boxes are always of equal side length. 105 This has advantages for CHC, because terrain tiles are in different octree nodes 106 and can be culled. 107 */ 108 void setWorldGeometry(const String& filename); 109 104 110 protected: 105 111 -
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.