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

Revision 3258, 6.6 KB checked in by mattausch, 15 years ago (diff)

worked on new method

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        //cout << "using tight bounds: " << useTightBounds << endl;
238}
239
240
241OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node)
242{
243        OcclusionQuery *query = mQueryHandler.RequestQuery();
244        query->AddNode(node);
245
246        IssueOcclusionQuery(*query);
247
248        return query;
249}
250
251
252void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query)
253{
254        ++ mStats.mNumIssuedQueries;
255
256        // render pending objects before changing to query mode
257        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
258        {
259                ApplyRenderQueue();
260        }
261
262        query.BeginQuery();
263
264        // change to query mode and render box
265        if (mRenderState->SetMode(RenderState::QUERY))
266        {
267                ++ mStats.mNumStateChanges;
268        }
269
270        mBvh->RenderBounds(query.GetNodes(), mRenderState, mUseTightBounds);
271       
272        query.EndQuery();
273}
274
275
276void RenderTraverser::ApplyRenderQueue()
277{
278        if (mRenderState->SetMode(RenderState::RENDER))
279                ++ mStats.mNumStateChanges;
280                 
281        if (mRenderQueue->GetSize() > 0)
282        {
283                ++ mStats.mNumBatches;
284                mRenderQueue->Apply();
285        }
286}
287
288
289void RenderTraverser::SetRenderDynamicObjects(bool dynamic)
290{
291        mRenderDynamicObjects = dynamic;
292}
293
294
295bool RenderTraverser::IsNodeGeometryVisible(BvhNode *node, int maxSize)
296{
297        // no invisible objects
298        if (SceneEntity::GetGlobalVisibleId() == -1) return true;
299
300        int geometrySize;
301        SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
302
303        if ((maxSize != -1) && (geometrySize > maxSize)) return true;
304
305        for (int i = 0; i < geometrySize; ++ i)
306        {
307                if (entities[i]->IsVisible()) return true;
308        }
309       
310        return false;
311}
312
313
314void RenderTraverser::SetCamera(Camera *cam)
315{
316        mCamera = cam;
317}
318
319
320void RenderTraverser::SetRenderQueue(RenderQueue *rq)
321{
322        mRenderQueue = rq;
323}
324
325
326const TraversalStatistics &RenderTraverser::GetStats() const
327{
328        return mStats;
329}
330
331
332const SceneEntityContainer &RenderTraverser::GetVisibleObjects() const
333{
334        return mVisibleObjects;
335}
336
337
338float RenderTraverser::GetMaxVisibleDistance() const
339{
340        return mMaxVisibleDistance;
341}
342
343
344Camera *RenderTraverser::GetCamera() const
345{
346        return mCamera;
347}
348
349
350
351}
Note: See TracBrowser for help on using the repository browser.