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

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