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).

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