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

Revision 2784, 4.9 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        mNumPreviouslyVisibleNodeQueries = 0;
28        mNumIssuedQueries = 0;
29        mNumStateChanges = 0;
30
31        mRenderTime = 0;
32}
33
34
35
36/******************************************************/
37/*           RenderTraverser implementation           */
38/******************************************************/
39
40
41RenderTraverser::RenderTraverser(): 
42mVisibilityThreshold(0),
43mBvh(NULL),
44mUseOptimization(false),
45mFrameId(-1),
46mUseRenderQueue(false),
47mAssumedVisibleFrames(10),
48mMaxBatchSize(50)
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        else
75        {
76                // for non leafs this renders only the bounding volume (if the flag is set)
77                BvhInterior *interior = static_cast<BvhInterior *>(node);
78
79                EnqueueNode(interior->GetFront());
80                EnqueueNode(interior->GetBack());
81        }
82}
83
84
85void RenderTraverser::RenderNode(BvhNode *node)
86{
87        if (node->GetLastRenderedFrame() != mFrameId)
88        {
89                if (mRenderState->SetState(RenderState::RENDER))
90                        ++ mStats.mNumStateChanges;
91               
92                node->SetLastRenderedFrame(mFrameId);
93
94                int geometrySize;
95                SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
96
97                mStats.mNumRenderedGeometry += geometrySize;
98                ++ mStats.mNumRenderedNodes;
99               
100                for (int i = 0; i < geometrySize; ++ i)
101                {
102                        SceneEntity *ent = entities[i];
103                        mStats.mNumRenderedTriangles += ent->GetGeometry()->GetNumTriangles();
104
105                        if (mUseRenderQueue)
106                                mRenderQueue.Enqueue(ent);
107                        else
108                                ent->Render(mRenderState);
109                }               
110        }
111}
112
113
114void RenderTraverser::SetHierarchy(Bvh *bvh)
115{
116        mBvh = bvh;
117}
118
119
120void RenderTraverser::SetRenderState(RenderState *state)
121{
122        mRenderState = state;
123        mRenderQueue.SetRenderState(state);
124}
125
126
127void RenderTraverser::RenderScene()
128{
129        PerfTimer timer;
130
131        timer.Start();
132
133        //InitTiming();
134        //long t1, t2;
135        //t1 = GetTime();
136
137        glEnableClientState(GL_VERTEX_ARRAY);
138        glEnableClientState(GL_NORMAL_ARRAY);
139
140        ++ mFrameId;
141
142        mBvh->InitFrame();
143
144        mStats.Reset();
145        mQueryHandler.ResetQueries();
146       
147        EnqueueNode(mBvh->GetRoot());
148
149
150        ///////////
151        //-- the actual rendering algorithm
152
153        Traverse();
154
155        mRenderState->Reset();
156
157        glDisableClientState(GL_VERTEX_ARRAY);
158        glDisableClientState(GL_NORMAL_ARRAY);
159
160        //t2 = GetTime();
161        //mStats.mRenderTime = TimeDiff(t1, t2);
162        mStats.mRenderTime = timer.Elapsedms();
163}
164
165
166void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
167{
168        mUseRenderQueue = useRenderQueue;
169        std::cout << "using render queue: " << mUseRenderQueue << std::endl;
170}
171
172
173void RenderTraverser::SetVisibilityThreshold(int threshold)
174{
175        mVisibilityThreshold = threshold;
176}
177
178
179void RenderTraverser::SetUseOptimization(bool useOptimization)
180{
181        mUseOptimization = useOptimization;
182}
183
184
185void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
186{
187        mAssumedVisibleFrames = assumedVisibleFrames;
188}
189
190
191void RenderTraverser::SetMaxBatchSize(int batchSize)
192{
193        mMaxBatchSize = batchSize;
194}
195
196
197void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
198{
199        mUseMultiQueries = useMultiQueries;
200        std::cout << "using multiqueries: " << mUseMultiQueries << std::endl;
201}
202
203
204
205OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node, bool wasVisible)
206{
207        OcclusionQuery *query = mQueryHandler.RequestQuery();
208        query->AddNode(node);
209
210        IssueOcclusionQuery(*query, wasVisible);
211
212        return query;
213}
214
215
216void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query, bool wasVisible)
217{
218        ++ mStats.mNumIssuedQueries;
219
220        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
221        {
222                //cout << "render queue: " << mRenderQueue.GetSize() << endl;
223                mRenderQueue.Render();
224                mRenderQueue.Clear();
225        }
226
227        query.BeginQuery();
228
229        if (wasVisible)
230                ++ mStats.mNumPreviouslyVisibleNodeQueries;
231
232        // if this node is a previous visible leaf:
233        // leaves will be rendered anyway => we can also test with the real geometry
234        if (wasVisible && mUseOptimization)
235        {
236                for (size_t i = 0; i < query.GetSize(); ++ i)
237                        RenderNode(query.GetNodes()[i]);
238        }
239        else
240        {
241                // change to query mode and render box
242                if (mRenderState->SetState(RenderState::QUERY))
243                        ++ mStats.mNumStateChanges;
244
245                mBvh->RenderBoundingBoxes(query.GetNodes(), mRenderState);
246        }
247
248        query.EndQuery();
249}
250
251
252}
Note: See TracBrowser for help on using the repository browser.