Ignore:
Timestamp:
05/01/06 00:08:09 (18 years ago)
Author:
mattausch
Message:

fitting objects to bb, debug

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp

    r865 r868  
    1515#include "ViewCellsManager.h" 
    1616 
     17 
     18// normal terrain rendering 
     19const static NORMAL_RENDER_HACK = false; 
     20 
    1721namespace Ogre { 
    1822 
     
    2024OcclusionCullingSceneManager::OcclusionCullingSceneManager( 
    2125                                                        GtpVisibility::VisibilityManager *visManager):  
     26TerrainSceneManager(), 
    2227mVisibilityManager(visManager),  
    2328mShowVisualization(false), 
     
    3035mIsDepthPassPhase(false), 
    3136mUseItemBuffer(false), 
    32 //mUseItemBuffer(true), 
    3337mIsItemBufferPhase(false), 
    3438mCurrentEntityId(1), 
     
    4145        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem); 
    4246         
    43 #if 0 
     47        if (0) 
     48        { 
    4449        mDisplayNodes = true; 
    4550        mShowBoundingBoxes = true; 
    4651        mShowBoxes = true; 
    47 #endif 
     52        } 
     53 
    4854        // TODO: set maxdepth to reasonable value 
    4955        mMaxDepth = 50; 
     
    98104        } 
    99105        //mItemBufferPass->setAmbient(1, 1, 0); 
     106} 
     107//----------------------------------------------------------------------- 
     108void 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//----------------------------------------------------------------------- 
     159Pass *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//----------------------------------------------------------------------- 
     234void 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//----------------------------------------------------------------------- 
     269void 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//----------------------------------------------------------------------- 
     403void 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//----------------------------------------------------------------------- 
     417bool 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//----------------------------------------------------------------------- 
     511bool 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//----------------------------------------------------------------------- 
     523bool OcclusionCullingSceneManager::getOptionValues(const String & key,  
     524                                                                                                        StringVector &refValueList) 
     525{ 
     526        return TerrainSceneManager::getOptionValues( key, refValueList); 
     527} 
     528//----------------------------------------------------------------------- 
     529bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys) 
     530{ 
     531        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface). 
     532                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys); 
     533} 
     534//----------------------------------------------------------------------- 
     535void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility:: 
     536                                                                                                                 VisibilityManager *visManager) 
     537{ 
     538        mVisibilityManager = visManager; 
     539} 
     540//----------------------------------------------------------------------- 
     541GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void ) 
     542{ 
     543        return mVisibilityManager; 
     544} 
     545//----------------------------------------------------------------------- 
     546void 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//----------------------------------------------------------------------- 
     565void 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//----------------------------------------------------------------------- 
     577bool 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//----------------------------------------------------------------------- 
     598void 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//----------------------------------------------------------------------- 
     617void 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//----------------------------------------------------------------------- 
     677void 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//----------------------------------------------------------------------- 
     722GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager() 
     723{ 
     724        return mVisibilityManager; 
     725} 
     726//----------------------------------------------------------------------- 
     727void 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//----------------------------------------------------------------------- 
     796OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface() 
     797{ 
     798        return mHierarchyInterface; 
     799} 
     800//----------------------------------------------------------------------- 
     801void OcclusionCullingSceneManager::endFrame() 
     802{ 
     803        TerrainRenderable::ResetRenderLevelIndex(); 
     804} 
     805//----------------------------------------------------------------------- 
     806Entity* 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//----------------------------------------------------------------------- 
     822void 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//----------------------------------------------------------------------- 
     854void 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   } 
    100876} 
    101877//------------------------------------------------------------------------- 
     
    123899     
    124900    setupTerrainMaterial(); 
    125  
    126901    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//------------------------------------------------------------------------- 
    839905MovableObject *OcclusionCullingSceneManager::FindCorrespondingObject(const AxisAlignedBox &box) 
    840906{ 
     
    861927                         const AxisAlignedBox bbox = mo->getWorldBoundingBox(); 
    862928                          
    863                          const float overlap = GtpVisibilityPreprocessor::FactorOfOverlap( 
     929                         const float overlap = GtpVisibilityPreprocessor::RatioOfOverlap( 
    864930                                 OgreTypeConverter::ConvertFromOgre(bbox),  
    865931                                 OgreTypeConverter::ConvertFromOgre(box)); 
     
    869935                                 bestFit = overlap; 
    870936                                 bestFittingObj = mo; 
    871  
     937                                         
    872938                                 // perfect fit => object found 
    873939                                 if (overlap > (1.0 - GtpVisibilityPreprocessor::Limits::Small)) 
     
    886952        // identify the corresponding Ogre meshes using the bounding boxes 
    887953        IdentifyObjects(objects); 
    888  
     954         
    889955        // load the view cells assigning the found objects to the pvss 
    890956        mViewCellsManager->LoadViewCells(filename, &objects); 
     
    908974                   
    909975                  MovableObject *mo = FindCorrespondingObject(currentBox); 
    910  
    911976                  //objects.push_back(mi); 
    912977        } 
Note: See TracChangeset for help on using the changeset viewer.