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

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