source: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp @ 2776

Revision 2776, 4.9 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "RenderTraverser.h"
2#include "glInterface.h"
3#include "Timers.h"
4#include "Camera.h"
5#include "SceneEntity.h"
6#include "RenderState.h"
7#include "Geometry.h"
8#include "Timer/PerfTimer.h"
9
10
11using namespace std;
12
13
14namespace CHCDemoEngine
15{
16
17       
18void TraversalStatistics::Reset()
19{
20        mNumTraversedNodes = 0;
21        mNumQueryCulledNodes = 0;
22        mNumFrustumCulledNodes = 0;
23       
24        mNumRenderedGeometry = 0;
25        mNumRenderedTriangles = 0;
26        mNumRenderedNodes = 0;
27
28        mNumPreviouslyVisibleNodeQueries = 0;
29        mNumIssuedQueries = 0;
30        mNumStateChanges = 0;
31
32        mRenderTime = 0;
33}
34
35
36
37/******************************************************/
38/*           RenderTraverser implementation           */
39/******************************************************/
40
41
42RenderTraverser::RenderTraverser(): 
43mVisibilityThreshold(0),
44mBvh(NULL),
45mUseOptimization(false),
46mFrameId(-1),
47mUseRenderQueue(false),
48mAssumedVisibleFrames(10),
49mMaxBatchSize(50)
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        PerfTimer timer;
131
132        timer.Start();
133
134        //InitTiming();
135        //long t1, t2;
136        //t1 = GetTime();
137
138        glEnableClientState(GL_VERTEX_ARRAY);
139        glEnableClientState(GL_NORMAL_ARRAY);
140
141        ++ mFrameId;
142
143        mBvh->InitFrame();
144
145        mStats.Reset();
146        mQueryHandler.ResetQueries();
147       
148        EnqueueNode(mBvh->GetRoot());
149
150
151        ///////////
152        //-- the actual rendering algorithm
153
154        Traverse();
155
156        mRenderState->Reset();
157
158        glDisableClientState(GL_VERTEX_ARRAY);
159        glDisableClientState(GL_NORMAL_ARRAY);
160
161        //t2 = GetTime();
162        //mStats.mRenderTime = TimeDiff(t1, t2);
163        mStats.mRenderTime = timer.Elapsedms();
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}
184
185
186void RenderTraverser::SetAssumedVisibleFrames(int assumedVisibleFrames)
187{
188        mAssumedVisibleFrames = assumedVisibleFrames;
189}
190
191
192void RenderTraverser::SetMaxBatchSize(int batchSize)
193{
194        mMaxBatchSize = batchSize;
195}
196
197
198void RenderTraverser::SetUseMultiQueries(bool useMultiQueries)
199{
200        mUseMultiQueries = useMultiQueries;
201        std::cout << "using multiqueries: " << mUseMultiQueries << std::endl;
202}
203
204
205
206OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node, bool wasVisible)
207{
208        OcclusionQuery *query = mQueryHandler.RequestQuery();
209        query->AddNode(node);
210
211        IssueOcclusionQuery(*query, wasVisible);
212
213        return query;
214}
215
216
217void RenderTraverser::IssueOcclusionQuery(const OcclusionQuery &query, bool wasVisible)
218{
219        ++ mStats.mNumIssuedQueries;
220
221        if (mUseRenderQueue && (mRenderState->GetMode() == RenderState::RENDER))
222        {
223                //cout << "render queue: " << mRenderQueue.GetSize() << endl;
224                mRenderQueue.Render();
225                mRenderQueue.Clear();
226        }
227
228        query.BeginQuery();
229
230        if (wasVisible)
231                ++ mStats.mNumPreviouslyVisibleNodeQueries;
232
233        // if this node is a previous visible leaf:
234        // leaves will be rendered anyway => we can also test with the real geometry
235        if (wasVisible && mUseOptimization)
236        {
237                for (size_t i = 0; i < query.GetSize(); ++ i)
238                        RenderNode(query.GetNodes()[i]);
239        }
240        else
241        {
242                // change to query mode and render box
243                if (mRenderState->SetState(RenderState::QUERY))
244                        ++ mStats.mNumStateChanges;
245
246                mBvh->RenderBoundingBoxes(query.GetNodes(), mRenderState);
247        }
248
249        query.EndQuery();
250}
251
252
253}
Note: See TracBrowser for help on using the repository browser.