source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp @ 3245

Revision 3245, 5.7 KB checked in by mattausch, 16 years ago (diff)

pvs seems to work now

Line 
1#include "RenderTraverser.h"
2#include "glInterface.h"
3#include "Camera.h"
4#include "SceneEntity.h"
5#include "RenderState.h"
6#include "Geometry.h"
7#include "Timer/PerfTimer.h"
8
9
10using namespace std;
11
12
13namespace CHCDemoEngine
14{
15
16       
17void TraversalStatistics::Reset()
18{
19        mNumTraversedNodes = 0;
20        mNumQueryCulledNodes = 0;
21        mNumFrustumCulledNodes = 0;
22       
23        mNumRenderedGeometry = 0;
24        mNumRenderedTriangles = 0;
25        mNumRenderedNodes = 0;
26
27        mNumIssuedQueries = 0;
28        mNumStateChanges = 0;
29        mNumBatches = 0;
30
31        mWaitTime = 0;
32        mQueryTime = 0;
33        mRestTime = 0;
34}
35
36
37
38/******************************************************/
39/*           RenderTraverser implementation           */
40/******************************************************/
41
42
43RenderTraverser::RenderTraverser(): 
44mVisibilityThreshold(0),
45mBvh(NULL),
46mUseOptimization(false),
47mFrameId(-1),
48mUseRenderQueue(false),
49mAssumedVisibleFrames(10),
50mMaxBatchSize(50),
51mUseTightBounds(false),
52mShowBounds(false),
53mRenderQueue(NULL),
54mMaxVisibleDistance(.0f),
55mRenderDynamicObjects(true)
56{
57        mStats.Reset();
58}
59
60
61RenderTraverser::~RenderTraverser()
62{
63        mQueryHandler.DestroyQueries();
64}
65
66
67void RenderTraverser::EnqueueNode(BvhNode *node)
68{
69        mBvh->UpdateDistance(node);
70        mDistanceQueue.push(node);
71}
72
73
74void RenderTraverser::TraverseNode(BvhNode *node)
75{
76        ++ mStats.mNumTraversedNodes;
77
78        if (node->IsVirtualLeaf())
79        {
80                RenderNode(node);
81
82                if (mShowBounds)
83                        mBvh->RenderBoundsForViz(node, mRenderState, mUseTightBounds);
84        }
85        else
86        {
87                BvhInterior *interior = static_cast<BvhInterior *>(node);
88
89                EnqueueNode(interior->GetFront());
90                EnqueueNode(interior->GetBack());
91        }
92}
93
94
95void RenderTraverser::RenderNode(BvhNode *node)
96{
97        // test if node was already rendered in this frame
98        if (node->GetLastRenderedFrame() != mFrameId)
99        {
100                if (mRenderState->SetMode(RenderState::RENDER))
101                        ++ mStats.mNumStateChanges;
102               
103                node->SetLastRenderedFrame(mFrameId);
104
105                int geometrySize;
106                SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
107
108                mStats.mNumRenderedGeometry += geometrySize;
109                ++ mStats.mNumRenderedNodes;
110               
111                for (int i = 0; i < geometrySize; ++ i)
112                {
113                        SceneEntity *ent = entities[i];
114       
115                        if (!ent->IsVisible()) continue;
116
117                        mStats.mNumRenderedTriangles += ent->CountNumTriangles();
118
119                        if (mUseRenderQueue)
120                                mRenderQueue->Enqueue(ent);
121                        else
122                                ent->Render(mRenderState);
123
124                        // store the visible entities for rendering in the second pass
125                        if (mUseDepthPass) mVisibleObjects.push_back(ent);
126                }
127
128                // store the max distance in the scene for later use
129                float maxDist = mBvh->CalcMaxDistance(node);
130
131                if (maxDist > mMaxVisibleDistance)
132                        mMaxVisibleDistance = maxDist;
133        }
134}
135
136
137void RenderTraverser::SetHierarchy(Bvh *bvh)
138{
139        mBvh = bvh;
140}
141
142
143void RenderTraverser::SetRenderState(RenderState *state)
144{
145        mRenderState = state;
146}
147
148
149void RenderTraverser::RenderScene()
150{
151        mVisibleObjects.clear();
152        mMaxVisibleDistance = .0f;
153
154        ++ mFrameId;
155
156        mBvh->InitFrame(mCamera, mRenderState);
157
158        mStats.Reset();
159        mQueryHandler.ResetQueries();
160
161        // add root node to queue
162        if (mRenderDynamicObjects)
163                EnqueueNode(mBvh->GetRoot());
164        else
165                EnqueueNode(mBvh->GetStaticRoot());
166
167       
168
169        ///////////
170        //-- the actual rendering algorithm
171
172        Traverse();
173
174        // render the contents of the render queue
175        if (mUseRenderQueue) ApplyRenderQueue();
176       
177        // reset the render state
178        mRenderState->Reset();
179}
180
181
182void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
183{
184        mUseRenderQueue = useRenderQueue;
185        //std::cout << "using render queue: " << mUseRenderQueue << std::endl;
186}
187
188
189void RenderTraverser::SetUseDepthPass(bool b)
190{
191        mUseDepthPass = b;
192}
193
194
195void RenderTraverser::SetVisibilityThreshold(int threshold)
196{
197        mVisibilityThreshold = threshold;
198}
199
200
201void RenderTraverser::SetUseOptimization(bool useOptimization)
202{
203        mUseOptimization = useOptimization;
204        //cout << "using optimization: " << mUseOptimization << endl;
205}
206
207
208void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
209{
210        mAssumedVisibleFrames = assumedVisibleFrames;
211}
212
213
214void RenderTraverser::SetMaxBatchSize(int batchSize)
215{
216        mMaxBatchSize = batchSize;
217}
218
219
220void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
221{
222        mUseMultiQueries = useMultiQueries;
223        //cout << "using multiqueries: " << mUseMultiQueries << endl;
224}
225
226
227void RenderTraverser::SetShowBounds(bool showBounds)
228{
229        mShowBounds = showBounds;
230}
231
232
233void RenderTraverser::SetUseTightBounds(bool useTightBounds)
234{
235        mUseTightBounds = useTightBounds;
236        //cout << "using tight bounds: " << useTightBounds << endl;
237}
238
239
240OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node)
241{
242        OcclusionQuery *query = mQueryHandler.RequestQuery();
243        query->AddNode(node);
244
245        IssueOcclusionQuery(*query);
246
247        return query;
248}
249
250
251void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query)
252{
253        ++ mStats.mNumIssuedQueries;
254
255        // render pending objects before changing to query mode
256        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
257        {
258                ApplyRenderQueue();
259        }
260
261        query.BeginQuery();
262
263        // change to query mode and render box
264        if (mRenderState->SetMode(RenderState::QUERY))
265        {
266                ++ mStats.mNumStateChanges;
267        }
268
269        mBvh->RenderBounds(query.GetNodes(), mRenderState, mUseTightBounds);
270       
271        query.EndQuery();
272}
273
274
275void RenderTraverser::ApplyRenderQueue()
276{
277        if (mRenderState->SetMode(RenderState::RENDER))
278                ++ mStats.mNumStateChanges;
279                 
280        if (mRenderQueue->GetSize() > 0)
281        {
282                ++ mStats.mNumBatches;
283                mRenderQueue->Apply();
284        }
285}
286
287
288void RenderTraverser::SetRenderDynamicObjects(bool dynamic)
289{
290        mRenderDynamicObjects = dynamic;
291}
292
293}
Note: See TracBrowser for help on using the repository browser.