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

Revision 2825, 5.4 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 "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)
54{
55}
56
57
58RenderTraverser::~RenderTraverser()
59{
60        mQueryHandler.DestroyQueries();
61}
62
63
64void RenderTraverser::EnqueueNode(BvhNode *node)
65{
66        mBvh->CalcDistance(node);
67        mDistanceQueue.push(node);
68}
69
70
71void RenderTraverser::TraverseNode(BvhNode *node)
72{
73        ++ mStats.mNumTraversedNodes;
74
75        if (node->IsVirtualLeaf())
76        {
77                RenderNode(node);
78
79                if (mShowBounds)
80                        mBvh->RenderBoundsForViz(node, mRenderState, mUseTightBounds);         
81        }
82        else
83        {
84                // for non leafs this renders only the bounding volume (if the flag is set)
85                BvhInterior *interior = static_cast<BvhInterior *>(node);
86
87                EnqueueNode(interior->GetFront());
88                EnqueueNode(interior->GetBack());
89        }
90}
91
92
93void RenderTraverser::RenderNode(BvhNode *node)
94{
95        if (node->GetLastRenderedFrame() != mFrameId)
96        {
97                if (mRenderState->SetState(RenderState::RENDER))
98                        ++ mStats.mNumStateChanges;
99               
100                node->SetLastRenderedFrame(mFrameId);
101
102                int geometrySize;
103                SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
104
105                mStats.mNumRenderedGeometry += geometrySize;
106                ++ mStats.mNumRenderedNodes;
107               
108                for (int i = 0; i < geometrySize; ++ i)
109                {
110                        SceneEntity *ent = entities[i];
111                        mStats.mNumRenderedTriangles += ent->GetGeometry()->GetNumTriangles();
112
113                        if (mUseRenderQueue)
114                                mRenderQueue->Enqueue(ent);
115                        else
116                                ent->Render(mRenderState);
117
118                        // store the visible entities for rendering in the second pass
119                        if (mUseDepthPass)
120                                mVisibleObjects.push_back(ent);
121                }               
122        }
123}
124
125
126void RenderTraverser::SetHierarchy(Bvh *bvh)
127{
128        mBvh = bvh;
129}
130
131
132void RenderTraverser::SetRenderState(RenderState *state)
133{
134        mRenderState = state;
135}
136
137
138void RenderTraverser::RenderScene()
139{
140        mVisibleObjects.clear();
141
142        glEnableClientState(GL_VERTEX_ARRAY);
143       
144        if (!mUseDepthPass)
145                glEnableClientState(GL_NORMAL_ARRAY);
146
147        ++ mFrameId;
148
149        mBvh->InitFrame();
150
151        mStats.Reset();
152        mQueryHandler.ResetQueries();
153       
154        EnqueueNode(mBvh->GetRoot());
155
156
157        ///////////
158        //-- the actual rendering algorithm
159
160        Traverse();
161
162        // render the contents of the render queue
163        if (mUseRenderQueue) ApplyRenderQueue();
164       
165        // reset the render state
166        mRenderState->Reset();
167
168        glDisableClientState(GL_VERTEX_ARRAY);
169        glDisableClientState(GL_NORMAL_ARRAY);
170
171        //cout << "rq overhead: " << 1e3f * mRenderQueue->rTimer.TotalTime() << " ms" << endl;
172}
173
174
175void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
176{
177        mUseRenderQueue = useRenderQueue;
178        //std::cout << "using render queue: " << mUseRenderQueue << std::endl;
179}
180
181
182void RenderTraverser::SetUseDepthPass(bool b)
183{
184        mUseDepthPass = b;
185}
186
187
188void RenderTraverser::SetVisibilityThreshold(int threshold)
189{
190        mVisibilityThreshold = threshold;
191}
192
193
194void RenderTraverser::SetUseOptimization(bool useOptimization)
195{
196        mUseOptimization = useOptimization;
197        //cout << "using optimization: " << mUseOptimization << endl;
198}
199
200
201void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
202{
203        mAssumedVisibleFrames = assumedVisibleFrames;
204}
205
206
207void RenderTraverser::SetMaxBatchSize(int batchSize)
208{
209        mMaxBatchSize = batchSize;
210}
211
212
213void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
214{
215        mUseMultiQueries = useMultiQueries;
216        //cout << "using multiqueries: " << mUseMultiQueries << endl;
217}
218
219
220void RenderTraverser::SetShowBounds(bool showBounds)
221{
222        mShowBounds = showBounds;
223}
224
225
226void RenderTraverser::SetUseTightBounds(bool useTightBounds)
227{
228        mUseTightBounds = useTightBounds;
229        //cout << "using tight bounds: " << useTightBounds << endl;
230}
231
232
233OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node)
234{
235        OcclusionQuery *query = mQueryHandler.RequestQuery();
236        query->AddNode(node);
237
238        IssueOcclusionQuery(*query);
239
240        return query;
241}
242
243
244void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query)
245{
246        ++ mStats.mNumIssuedQueries;
247
248        // render pending objects before changing to query mode
249        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
250                ApplyRenderQueue();
251       
252
253        query.BeginQuery();
254
255        // change to query mode and render box
256        if (mRenderState->SetState(RenderState::QUERY))
257                ++ mStats.mNumStateChanges;
258
259        mBvh->RenderBounds(query.GetNodes(), mRenderState, mUseTightBounds);
260       
261        query.EndQuery();
262}
263
264
265void RenderTraverser::ApplyRenderQueue()
266{
267        if (mRenderState->SetState(RenderState::RENDER))
268                ++ mStats.mNumStateChanges;
269                 
270        if (mRenderQueue->GetSize() > 0)
271                ++ mStats.mNumBatches;
272
273        mRenderQueue->Apply();
274}
275
276
277}
Note: See TracBrowser for help on using the repository browser.