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

Revision 2848, 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               
112                        mStats.mNumRenderedTriangles += ent->CountNumTriangles();
113
114                        if (mUseRenderQueue)
115                                mRenderQueue->Enqueue(ent);
116                        else
117                                ent->Render(mRenderState);
118
119                        // store the visible entities for rendering in the second pass
120                        if (mUseDepthPass)
121                                mVisibleObjects.push_back(ent);
122                }               
123        }
124}
125
126
127void RenderTraverser::SetHierarchy(Bvh *bvh)
128{
129        mBvh = bvh;
130}
131
132
133void RenderTraverser::SetRenderState(RenderState *state)
134{
135        mRenderState = state;
136}
137
138
139void RenderTraverser::RenderScene()
140{
141        mVisibleObjects.clear();
142
143        glEnableClientState(GL_VERTEX_ARRAY);
144       
145        if (!mUseDepthPass)
146                glEnableClientState(GL_NORMAL_ARRAY);
147
148        ++ mFrameId;
149
150        mBvh->InitFrame();
151
152        mStats.Reset();
153        mQueryHandler.ResetQueries();
154       
155        EnqueueNode(mBvh->GetRoot());
156
157
158        ///////////
159        //-- the actual rendering algorithm
160
161        Traverse();
162
163        // render the contents of the render queue
164        if (mUseRenderQueue) ApplyRenderQueue();
165       
166        // reset the render state
167        mRenderState->Reset();
168
169        glDisableClientState(GL_VERTEX_ARRAY);
170        glDisableClientState(GL_NORMAL_ARRAY);
171
172        //cout << "rq overhead: " << 1e3f * mRenderQueue->rTimer.TotalTime() << " ms" << endl;
173}
174
175
176void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
177{
178        mUseRenderQueue = useRenderQueue;
179        //std::cout << "using render queue: " << mUseRenderQueue << std::endl;
180}
181
182
183void RenderTraverser::SetUseDepthPass(bool b)
184{
185        mUseDepthPass = b;
186}
187
188
189void RenderTraverser::SetVisibilityThreshold(int threshold)
190{
191        mVisibilityThreshold = threshold;
192}
193
194
195void RenderTraverser::SetUseOptimization(bool useOptimization)
196{
197        mUseOptimization = useOptimization;
198        //cout << "using optimization: " << mUseOptimization << endl;
199}
200
201
202void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
203{
204        mAssumedVisibleFrames = assumedVisibleFrames;
205}
206
207
208void RenderTraverser::SetMaxBatchSize(int batchSize)
209{
210        mMaxBatchSize = batchSize;
211}
212
213
214void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
215{
216        mUseMultiQueries = useMultiQueries;
217        //cout << "using multiqueries: " << mUseMultiQueries << endl;
218}
219
220
221void RenderTraverser::SetShowBounds(bool showBounds)
222{
223        mShowBounds = showBounds;
224}
225
226
227void RenderTraverser::SetUseTightBounds(bool useTightBounds)
228{
229        mUseTightBounds = useTightBounds;
230        //cout << "using tight bounds: " << useTightBounds << endl;
231}
232
233
234OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node)
235{
236        OcclusionQuery *query = mQueryHandler.RequestQuery();
237        query->AddNode(node);
238
239        IssueOcclusionQuery(*query);
240
241        return query;
242}
243
244
245void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query)
246{
247        ++ mStats.mNumIssuedQueries;
248
249        // render pending objects before changing to query mode
250        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
251                ApplyRenderQueue();
252       
253
254        query.BeginQuery();
255
256        // change to query mode and render box
257        if (mRenderState->SetState(RenderState::QUERY))
258                ++ mStats.mNumStateChanges;
259
260        mBvh->RenderBounds(query.GetNodes(), mRenderState, mUseTightBounds);
261       
262        query.EndQuery();
263}
264
265
266void RenderTraverser::ApplyRenderQueue()
267{
268        if (mRenderState->SetState(RenderState::RENDER))
269                ++ mStats.mNumStateChanges;
270                 
271        if (mRenderQueue->GetSize() > 0)
272        {
273                ++ mStats.mNumBatches;
274                mRenderQueue->Apply();
275        }
276}
277
278
279}
Note: See TracBrowser for help on using the repository browser.