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

Revision 2790, 5.2 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),
49mUseTightBounds(false), mShowBounds(false)
50{
51}
52
53
54RenderTraverser::~RenderTraverser()
55{
56        mQueryHandler.DestroyQueries();
57}
58
59
60void RenderTraverser::EnqueueNode(BvhNode *node)
61{
62        mBvh->CalcDistance(node);
63        mDistanceQueue.push(node);
64}
65
66
67void RenderTraverser::TraverseNode(BvhNode *node)
68{
69        ++ mStats.mNumTraversedNodes;
70
71        if (node->IsVirtualLeaf())
72        {
73                RenderNode(node);
74
75                if (mShowBounds)
76                        mBvh->RenderBoundsForViz(node, mUseTightBounds);               
77        }
78        else
79        {
80                // for non leafs this renders only the bounding volume (if the flag is set)
81                BvhInterior *interior = static_cast<BvhInterior *>(node);
82
83                EnqueueNode(interior->GetFront());
84                EnqueueNode(interior->GetBack());
85        }
86}
87
88
89void RenderTraverser::RenderNode(BvhNode *node)
90{
91        if (node->GetLastRenderedFrame() != mFrameId)
92        {
93                if (mRenderState->SetState(RenderState::RENDER))
94                        ++ mStats.mNumStateChanges;
95               
96                node->SetLastRenderedFrame(mFrameId);
97
98                int geometrySize;
99                SceneEntity **entities = mBvh->GetGeometry(node, geometrySize);
100
101                mStats.mNumRenderedGeometry += geometrySize;
102                ++ mStats.mNumRenderedNodes;
103               
104                for (int i = 0; i < geometrySize; ++ i)
105                {
106                        SceneEntity *ent = entities[i];
107                        mStats.mNumRenderedTriangles += ent->GetGeometry()->GetNumTriangles();
108
109                        if (mUseRenderQueue)
110                                mRenderQueue.Enqueue(ent);
111                        else
112                                ent->Render(mRenderState);
113                }               
114        }
115}
116
117
118void RenderTraverser::SetHierarchy(Bvh *bvh)
119{
120        mBvh = bvh;
121}
122
123
124void RenderTraverser::SetRenderState(RenderState *state)
125{
126        mRenderState = state;
127        mRenderQueue.SetRenderState(state);
128}
129
130
131void RenderTraverser::RenderScene()
132{
133        //glFinish();
134        PerfTimer timer;
135        timer.Start();
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        //glFinish();
161        mStats.mRenderTime = timer.Elapsedms();
162}
163
164
165void RenderTraverser::SetUseRenderQueue(bool useRenderQueue)
166{
167        mUseRenderQueue = useRenderQueue;
168        std::cout << "using render queue: " << mUseRenderQueue << std::endl;
169}
170
171
172void RenderTraverser::SetVisibilityThreshold(int threshold)
173{
174        mVisibilityThreshold = threshold;
175}
176
177
178void RenderTraverser::SetUseOptimization(bool useOptimization)
179{
180        mUseOptimization = useOptimization;
181}
182
183
184void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
185{
186        mAssumedVisibleFrames = assumedVisibleFrames;
187}
188
189
190void RenderTraverser::SetMaxBatchSize(int batchSize)
191{
192        mMaxBatchSize = batchSize;
193}
194
195
196void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
197{
198        mUseMultiQueries = useMultiQueries;
199        //cout << "using multiqueries: " << mUseMultiQueries << endl;
200}
201
202
203void RenderTraverser::SetShowBounds(bool showBounds)
204{
205        mShowBounds = showBounds;
206}
207
208
209void RenderTraverser::SetUseTightBounds(bool useTightBounds)
210{
211        mUseTightBounds = useTightBounds;
212        //cout << "using tight bounds: " << useTightBounds << endl;
213}
214
215
216OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node, bool wasVisible)
217{
218        OcclusionQuery *query = mQueryHandler.RequestQuery();
219        query->AddNode(node);
220
221        IssueOcclusionQuery(*query, wasVisible);
222
223        return query;
224}
225
226
227void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query, bool wasVisible)
228{
229        ++ mStats.mNumIssuedQueries;
230
231        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
232        {
233                //Debug << "render queue: " << mRenderQueue.GetSize() << endl;
234                mRenderQueue.Render();
235                mRenderQueue.Clear();
236        }
237
238        query.BeginQuery();
239
240        if (wasVisible)
241                ++ mStats.mNumPreviouslyVisibleNodeQueries;
242
243        // if this node is a previous visible leaf:
244        // leaves will be rendered anyway => we can also test with the real geometry
245        if (wasVisible && mUseOptimization)
246        {
247                for (size_t i = 0; i < query.GetSize(); ++ i)
248                        RenderNode(query.GetNodes()[i]);
249        }
250        else
251        {
252                // change to query mode and render box
253                if (mRenderState->SetState(RenderState::QUERY))
254                        ++ mStats.mNumStateChanges;
255
256                mBvh->RenderBounds(query.GetNodes(), mRenderState, mUseTightBounds);
257        }
258
259        query.EndQuery();
260}
261
262
263}
Note: See TracBrowser for help on using the repository browser.