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

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