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

Revision 3074, 5.4 KB checked in by mattausch, 16 years ago (diff)

included vbo support for dynamic objects

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