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

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