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

Revision 3259, 6.6 KB checked in by mattausch, 16 years ago (diff)
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 "RenderQueue.h"
8#include "Timer/PerfTimer.h"
9
10
11using namespace std;
12
13
14namespace CHCDemoEngine
15{
16
17       
18void TraversalStatistics::Reset()
19{
20        mNumTraversedNodes = 0;
21        mNumQueryCulledNodes = 0;
22        mNumFrustumCulledNodes = 0;
23       
24        mNumRenderedGeometry = 0;
25        mNumRenderedTriangles = 0;
26        mNumRenderedNodes = 0;
27
28        mNumIssuedQueries = 0;
29        mNumStateChanges = 0;
30        mNumBatches = 0;
31
32        mWaitTime = 0;
33        mQueryTime = 0;
34        mRestTime = 0;
35}
36
37
38
39/******************************************************/
40/*           RenderTraverser implementation           */
41/******************************************************/
42
43
44RenderTraverser::RenderTraverser(): 
45mVisibilityThreshold(0),
46mBvh(NULL),
47mUseOptimization(false),
48mFrameId(-1),
49mUseRenderQueue(false),
50mAssumedVisibleFrames(10),
51mMaxBatchSize(50),
52mUseTightBounds(false),
53mShowBounds(false),
54mRenderQueue(NULL),
55mMaxVisibleDistance(.0f),
56mRenderDynamicObjects(true)
57{
58        mStats.Reset();
59}
60
61
62RenderTraverser::~RenderTraverser()
63{
64        mQueryHandler.DestroyQueries();
65}
66
67
68void RenderTraverser::EnqueueNode(BvhNode *node)
69{
70        mBvh->UpdateDistance(node);
71        mDistanceQueue.push(node);
72}
73
74
75void RenderTraverser::TraverseNode(BvhNode *node)
76{
77        ++ mStats.mNumTraversedNodes;
78
79        if (node->IsVirtualLeaf())
80        {
81                RenderNode(node);
82
83                if (mShowBounds)
84                        mBvh->RenderBoundsForViz(node, mRenderState, mUseTightBounds);
85        }
86        else
87        {
88                BvhInterior *interior = static_cast<BvhInterior *>(node);
89
90                EnqueueNode(interior->GetFront());
91                EnqueueNode(interior->GetBack());
92        }
93}
94
95
96void RenderTraverser::RenderNode(BvhNode *node)
97{
98        // test if node was already rendered in this frame
99        if (node->GetLastRenderedFrame() != mFrameId)
100        {
101                if (mRenderState->SetMode(RenderState::RENDER))
102                        ++ mStats.mNumStateChanges;
103               
104                node->SetLastRenderedFrame(mFrameId);
105
106                int geometrySize;
107                SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
108
109                mStats.mNumRenderedGeometry += geometrySize;
110                ++ mStats.mNumRenderedNodes;
111               
112                for (int i = 0; i < geometrySize; ++ i)
113                {
114                        SceneEntity *ent = entities[i];
115       
116                        if (!ent->IsVisible()) continue;
117
118                        mStats.mNumRenderedTriangles += ent->CountNumTriangles();
119
120                        if (mUseRenderQueue)
121                                mRenderQueue->Enqueue(ent);
122                        else
123                                ent->Render(mRenderState);
124
125                        // store the visible entities for rendering in the second pass
126                        if (mUseDepthPass) mVisibleObjects.push_back(ent);
127                }
128
129                // store the max distance in the scene for later use
130                float maxDist = mBvh->CalcMaxDistance(node);
131
132                if (maxDist > mMaxVisibleDistance)
133                        mMaxVisibleDistance = maxDist;
134        }
135}
136
137
138void RenderTraverser::SetHierarchy(Bvh *bvh)
139{
140        mBvh = bvh;
141}
142
143
144void RenderTraverser::SetRenderState(RenderState *state)
145{
146        mRenderState = state;
147}
148
149
150void RenderTraverser::RenderScene()
151{
152        mVisibleObjects.clear();
153        mMaxVisibleDistance = .0f;
154
155        ++ mFrameId;
156
157        mBvh->InitFrame(mCamera, mRenderState);
158
159        mStats.Reset();
160        mQueryHandler.ResetQueries();
161
162        // add root node to queue
163        if (mRenderDynamicObjects)
164                EnqueueNode(mBvh->GetRoot());
165        else
166                EnqueueNode(mBvh->GetStaticRoot());
167
168       
169
170        ///////////
171        //-- the actual rendering algorithm
172
173        Traverse();
174
175        // render the contents of the render queue
176        if (mUseRenderQueue) ApplyRenderQueue();
177       
178        // reset the render state
179        mRenderState->Reset();
180}
181
182
183void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
184{
185        mUseRenderQueue = useRenderQueue;
186        //std::cout << "using render queue: " << mUseRenderQueue << std::endl;
187}
188
189
190void RenderTraverser::SetUseDepthPass(bool b)
191{
192        mUseDepthPass = b;
193}
194
195
196void RenderTraverser::SetVisibilityThreshold(int threshold)
197{
198        mVisibilityThreshold = threshold;
199}
200
201
202void RenderTraverser::SetUseOptimization(bool useOptimization)
203{
204        mUseOptimization = useOptimization;
205        //cout << "using optimization: " << mUseOptimization << endl;
206}
207
208
209void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
210{
211        mAssumedVisibleFrames = assumedVisibleFrames;
212}
213
214
215void RenderTraverser::SetMaxBatchSize(int batchSize)
216{
217        mMaxBatchSize = batchSize;
218}
219
220
221void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
222{
223        mUseMultiQueries = useMultiQueries;
224        //cout << "using multiqueries: " << mUseMultiQueries << endl;
225}
226
227
228void RenderTraverser::SetShowBounds(bool showBounds)
229{
230        mShowBounds = showBounds;
231}
232
233
234void RenderTraverser::SetUseTightBounds(bool useTightBounds)
235{
236        mUseTightBounds = useTightBounds;
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
294bool RenderTraverser::IsNodeGeometryVisible(BvhNode *node, int maxSize)
295{
296        // no invisible objects
297        if (SceneEntity::GetCurrentVisibleId() == -1) return true;
298
299        int geometrySize;
300        SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
301
302        if ((maxSize != -1) && (geometrySize > maxSize)) return true;
303
304        for (int i = 0; i < geometrySize; ++ i)
305        {
306                if (entities[i]->IsVisible()) return true;
307        }
308       
309        return false;
310}
311
312
313void RenderTraverser::SetCamera(Camera *cam)
314{
315        mCamera = cam;
316}
317
318
319void RenderTraverser::SetRenderQueue(RenderQueue *rq)
320{
321        mRenderQueue = rq;
322}
323
324
325const TraversalStatistics &RenderTraverser::GetStats() const
326{
327        return mStats;
328}
329
330
331const SceneEntityContainer &RenderTraverser::GetVisibleObjects() const
332{
333        return mVisibleObjects;
334}
335
336
337float RenderTraverser::GetMaxVisibleDistance() const
338{
339        return mMaxVisibleDistance;
340}
341
342
343Camera *RenderTraverser::GetCamera() const
344{
345        return mCamera;
346}
347
348
349
350}
Note: See TracBrowser for help on using the repository browser.