source: trunk/VUT/GtpVisibility/src/CoherentHierarchicalCullingManager.cpp @ 343

Revision 343, 4.8 KB checked in by mattausch, 19 years ago (diff)

added switch between NV and ARB queries in the render system and in the demos.
Fixed render queue bug: when clearing queue, we traversed through all priority groups
to clear the passmaps. This became very slow because had to traverse many elements (over 1000
for city demo). Now all we destroy the priority groups for each rendering (per hierarchy node).

RevLine 
[59]1#include "CoherentHierarchicalCullingManager.h"
[147]2#include <OgreLogManager.h>
[59]3
4namespace GtpVisibility {
5
6//-----------------------------------------------------------------------
[155]7CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager()
[142]8{
[155]9        SetAssumedVisibility(0);
10        // initialise random generator in case we use assumed visibility
[142]11        srand(time(NULL));
12}
13//-----------------------------------------------------------------------
[155]14CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(const unsigned int
[295]15                                                                                                                                           assumedVisibility)
[155]16{
17        SetAssumedVisibility(assumedVisibility);
18        // initialise random generator in case we use assumed visibility
19        srand(time(NULL));
20}
21//-----------------------------------------------------------------------
[59]22void CoherentHierarchicalCullingManager::RenderScene()
23{
[85]24        QueryQueue queryQueue;
[86]25        unsigned int visiblePixels = 0;
26        bool isAvailable = false;
[259]27        //Ogre::LogManager::getSingleton().logMessage("Coherent Hierarchical Culling");
[175]28
[59]29        //-- PART 1: process finished occlusion queries
30        while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
31        {
32                while (!queryQueue.empty() &&
[86]33                           queryQueue.front().second->GetQueryResult(visiblePixels,
34                                                                        mHierarchyInterface->GetQueue()->empty()))
[59]35                {
[94]36                HierarchyNode *node = queryQueue.front().first;
[115]37                       
[59]38                        queryQueue.pop();
39
[96]40                        if (visiblePixels > mVisibilityThreshold)
[59]41                        {
42                                mHierarchyInterface->PullUpVisibility(node);
[158]43                                mHierarchyInterface->TraverseNode(node);
[59]44                        }
45                        else
[142]46                        {       
[155]47                                ++ mNumQueryCulledNodes;
[112]48                               
49                                if(mVisualizeCulledNodes)
50                                {
51                                        mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
52                                }
[59]53                        }
[85]54                }
[87]55               
[59]56                //-- PART 2: hierarchical traversal
57                if (!mHierarchyInterface->GetQueue()->empty())
58                {
59                        HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
60                        mHierarchyInterface->GetQueue()->pop();
61                               
62                        bool intersects = false;
63
[74]64                        if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
[130]65                        {
[147]66                                ++ mNumFrustumCulledNodes;
[112]67                               
[147]68                                if (mVisualizeCulledNodes)
[112]69                                {
[113]70                                        mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
[112]71                                }
[59]72                        }
[155]73                        // -- if node intersects near plane, skip query because wrong results possible
74                        else if (intersects)
75                        {
76                                SkipQuery(node);
77                        }
[74]78                        else
[59]79                        {
[148]80                                // identify previously visible nodes
81                                bool wasVisible = mHierarchyInterface->IsNodeVisible(node) &&
82                                        (mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
[155]83                                       
84                                // if we assume node to be visible in this frame => skip query
[343]85                                // TODO: check this (not the expected speed up)
[187]86                                if (wasVisible && (mAssumedVisibility > 0) &&  DecideVisible(node) && mHierarchyInterface->HasGeometry(node))
[74]87                                {
[155]88                                        SkipQuery(node);
[59]89
[74]90                                        continue;
91                                }
[59]92
[148]93                // identify nodes that we cannot skip queries for
[87]94                                // geometry not only in leaves => test for renderable geometry
[148]95                                bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
[147]96                                                               
97                                // reset node's visibility classification
[148]98                                mHierarchyInterface->SetNodeVisible(node, false);
[59]99
[74]100                                // update node's visited flag
101                                mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
[59]102                       
[87]103                                // skip testing previously visible nodes without geometry
104                                if (issueQuery)
[74]105                                {
[147]106                                        ++ mNumQueriesIssued;
[142]107                                       
[87]108                                        queryQueue.push(QueryPair(node, mHierarchyInterface->
[175]109                                                IssueNodeOcclusionQuery(node, wasVisible)));
[74]110                                }
[147]111                               
[74]112                                // always traverse a node if it was visible
113                                if (wasVisible)
114                                {
[158]115                                        mHierarchyInterface->TraverseNode(node);
[74]116                                }
[59]117                        }
118                }
119        }
120}
[142]121//-----------------------------------------------------------------------
[146]122void CoherentHierarchicalCullingManager::SetAssumedVisibility(unsigned int assumedVisibility)
[142]123{
124        mAssumedVisibility = assumedVisibility;
[146]125       
126        mThreshold = 0;
127
[147]128        if (mAssumedVisibility > 0)
[146]129        {
[147]130                mThreshold =  RAND_MAX - RAND_MAX / mAssumedVisibility;
[146]131        }
[147]132        //std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
[142]133}
134//-----------------------------------------------------------------------
[147]135bool CoherentHierarchicalCullingManager::DecideVisible(HierarchyNode *node) const
[142]136{
[155]137        /*bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
[147]138        Ogre::LogManager::getSingleton().logMessage(d.str()); return result;*/
139       
[146]140        return rand() < mThreshold;
[142]141}
[155]142//-----------------------------------------------------------------------
143void CoherentHierarchicalCullingManager::SkipQuery(HierarchyNode *node)
144{
145        // -- set node to be visible in this frame, then traverse it
146        mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
147
148        mHierarchyInterface->PullUpVisibility(node);                   
[158]149        mHierarchyInterface->TraverseNode(node);
[155]150}
151
[59]152} // namespace GtpVisibility
Note: See TracBrowser for help on using the repository browser.