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

Revision 2761, 7.8 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "RenderTraverser.h"
2#include "glInterface.h"
3#include "Timers.h"
4
5
6namespace CHCDemo
7{
8
9RenderTraverser::RenderTraverser():
10mFrameID(1),
11mVisibilityThreshold(0),
12mBvh(NULL),
13mIsQueryMode(false),
14mUseOptimization(true),
15mCurrentQueryIdx(0)
16{
17}
18
19
20RenderTraverser::~RenderTraverser()
21{
22        //DelQueries();
23}
24
25
26/*void RenderTraverser::Render(int mode)
27{
28        mDistanceQueue.push(mHierarchyRoot);
29
30        long startTime = getTime();
31
32        Preprocess();
33
34        switch(mode)
35        {
36                case RENDER_CULL_FRUSTUM:
37                        RenderCullFrustum();
38            break;
39                case RENDER_STOP_AND_WAIT:
40                        RenderStopAndWait();
41                        break;
42                case RENDER_COHERENT:
43                        RenderCoherentWithQueue();
44                        break;
45                default:
46                        RenderCullFrustum();
47                        break;
48        }
49
50        mFrameID ++;
51       
52
53        long endTime = getTime();
54        mRenderTime = endTime - startTime;
55
56        finishTiming();
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        if (node->IsVirtualLeaf()||node->IsLeaf())
69        {
70                //mNumRenderedGeometry +=
71                mBvh->Render(node, mRenderState);
72        }
73        else
74        {
75                // for non leafs this renders only the bounding volume (if the flag is set)
76                //node->Render();
77                BvhInterior *interior = static_cast<BvhInterior *>(node);
78
79                EnqueueNode(interior->GetFront());
80                EnqueueNode(interior->GetBack());
81        }
82}
83
84
85void RenderTraverser::SetHierarchy(Bvh *bvh)
86{
87        mBvh = bvh;
88        //DelQueries();
89}
90
91
92void RenderTraverser::SetRenderState(RenderState *state)
93{
94        mRenderState = state;
95        //DelQueries();
96}
97
98
99#if 0
100
101Bvh *RenderTraverser::GetHierarchy()
102{
103        return mBvh;
104}
105
106
107void RenderTraverser::RenderVisualization()
108{
109        mDistanceQueue.push(mHierarchyRoot);
110
111        while(! mDistanceQueue.empty())
112        {
113                HierarchyNode *node = mDistanceQueue.top();
114                mDistanceQueue.pop();
115
116                // identify previously visible nodes
117                bool wasVisible = node->Visible() && (node->LastVisited() == mFrameID - 1);
118
119                if(wasVisible)
120                        TraverseNode(node);
121                else
122                {
123                        // also render culled nodes
124                        glColor3f(1.0,0.0,0.0);
125                        node->RenderBoundingVolumeForVisualization();           
126                }
127        }
128}
129
130
131void RenderTraverser::PullUpVisibility(HierarchyNode *node)
132{
133        while(node && !node->Visible())
134        {
135                node->SetVisible(true);
136                node = node->GetParent();
137        }
138}
139
140bool RenderTraverser::ResultAvailable(HierarchyNode *node) const
141{
142        unsigned int result;
143        if (mUseArbQueries)
144        {
145                glGetQueryObjectuivARB(node->GetOcclusionQuery(),
146                                                           GL_QUERY_RESULT_AVAILABLE_ARB, &result);
147        }
148        else
149        {
150               
151                glGetOcclusionQueryuivNV(node->GetOcclusionQuery(),
152                                                                 GL_PIXEL_COUNT_AVAILABLE_NV, &result);
153
154        }
155       
156        return (result == GL_TRUE);
157}
158
159
160unsigned int RenderTraverser::GetOcclusionQueryResult(HierarchyNode *node) const
161{
162        unsigned int result;
163
164        if (mUseArbQueries)
165        {
166                glGetQueryObjectuivARB(node->GetOcclusionQuery(), GL_QUERY_RESULT_ARB, &result);
167        }
168        else
169        {
170                glGetOcclusionQueryuivNV(node->GetOcclusionQuery(), GL_PIXEL_COUNT_NV, &result);
171        }
172
173        return result;
174}
175
176
177void RenderTraverser::Switch2GLQueryState()
178{       
179        // boolean used to avoid unnecessary state changes
180        if(!mIsQueryMode)
181        {
182                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
183                glDepthMask(GL_FALSE);
184                glDisable(GL_LIGHTING);
185                mIsQueryMode = true;
186        }
187}
188
189
190void RenderTraverser::Switch2GLRenderState()
191{
192        // boolean used to avoid unnecessary state changes
193        if(mIsQueryMode)
194        {
195                // switch back to rendermode           
196                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
197                glDepthMask(GL_TRUE);
198                glEnable(GL_LIGHTING);
199                mIsQueryMode = false;
200        }
201}
202
203void RenderTraverser::IssueOcclusionQuery(HierarchyNode *node, const bool wasVisible)
204{
205        // get next available test id
206        unsigned int occlusionQuery = mOcclusionQueries[mCurrentQueryIdx ++];
207       
208        node->SetOcclusionQuery(occlusionQuery);
209
210        // do the actual occlusion query for this node
211        if (mUseArbQueries)
212        {
213                glBeginQueryARB(GL_SAMPLES_PASSED_ARB, occlusionQuery);
214        }
215        else
216        {
217                glBeginOcclusionQueryNV(occlusionQuery);
218        }
219       
220        // if leaf and was visible => will be rendered anyway, thus we
221        // can also test with the real geometry
222        if(node->IsLeaf() && wasVisible && mUseOptimization)
223        {
224                mNumRenderedGeometry += node->Render();
225        }
226        else
227        {
228                // change state so the bounding box gets not actually rendered on the screen
229                Switch2GLQueryState();
230                node->RenderBoundingVolume();
231                Switch2GLRenderState();
232        }
233
234        if (mUseArbQueries)
235        {
236                glEndQueryARB(GL_SAMPLES_PASSED_ARB);
237        }
238        else
239        {
240                glEndOcclusionQueryNV();
241        }
242}
243
244void RenderTraverser::Preprocess()
245{
246        if (!mOcclusionQueries)
247        {
248                mOcclusionQueries = new unsigned int[mHierarchyRoot->GetNumHierarchyNodes()];
249
250                // generate ids for occlusion test
251                if (mUseArbQueries)
252                {
253                        glGenQueriesARB(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
254                }
255                else
256                {
257                        glGenOcclusionQueriesNV(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
258                }
259        }
260
261        // view frustum planes for view frustum culling
262        calcViewFrustumPlanes(&mClipPlanes, mProjViewMatrix);
263        calcAABNPVertexIndices(mNPVertexIndices, mClipPlanes);
264
265        mCurrentQueryIdx = 0;
266
267        // reset statistics
268        mNumTraversedNodes = 0;
269        mNumQueryCulledNodes = 0;
270        mNumFrustumCulledNodes = 0;
271        mNumRenderedGeometry = 0;
272}
273
274
275void RenderTraverser::DelQueries()
276{
277        if (!mOcclusionQueries)
278                return;
279
280        // tell the driver that the occlusion queries won't be needed any more
281        if (mUseArbQueries)
282        {
283                glDeleteQueriesARB(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
284        }
285        else
286        {
287                glDeleteOcclusionQueriesNV(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
288        }
289
290        delete [] mOcclusionQueries;
291
292        mOcclusionQueries = NULL;
293}
294
295
296void RenderTraverser::SetViewpoint(Vector3 const &viewpoint)
297{
298        copyVector3(mViewpoint, viewpoint);
299}
300       
301
302void RenderTraverser::SetProjViewMatrix(Matrix4x4 const &projViewMatrix)
303{
304        copyMatrix(mProjViewMatrix, projViewMatrix);
305}
306
307
308bool RenderTraverser::InsideViewFrustum(HierarchyNode *node, bool &intersects)
309{
310        Vector3x8 vertices;
311       
312        bool intersect = false;
313
314        calcAABoxPoints(vertices, node->GetBoundingVolume());
315
316        // simply test all 6 vertices
317        for (int i = 0; i < 6; i++)
318        {               
319                // test the n-vertex
320                // note: the calcAABNearestVertexId should be preprocessed
321                if(!pointBeforePlane(mClipPlanes.plane[i], vertices[mNPVertexIndices[i * 2]]))
322                {
323                        // outside
324                        return false;
325                }
326        }
327
328        // test if bounding box is intersected by nearplane (using the p-vertex)
329        intersects = (!pointBeforePlane(mClipPlanes.plane[5], vertices[mNPVertexIndices[11]]));
330
331        // -- get vector from viewpoint to center of bounding volume
332        Vector3 vec;
333        calcAABoxCenter(vec, node->GetBoundingVolume());
334        diffVector3(vec, vec, mViewpoint);
335
336        // compute distance from nearest point to viewpoint
337        diffVector3(vec, vertices[calcAABNearestVertexIdx(vec)], mViewpoint);
338        node->SetDistance(squaredLength(vec));
339       
340        return true;
341}
342
343
344void RenderTraverser::SetVisibilityThreshold(int threshold)
345{
346        mVisibilityThreshold = threshold;
347}
348
349void RenderTraverser::SetUseArbQueries(const bool useArbQueries)
350{
351        DelQueries();
352        mUseArbQueries = useArbQueries;
353}
354
355bool RenderTraverser::GetUseArbQueries() const
356{
357        return mUseArbQueries;
358}
359
360long RenderTraverser::GetRenderTime()
361{
362        return mRenderTime;
363}
364
365int RenderTraverser::GetNumTraversedNodes()
366{
367        return mNumTraversedNodes;
368}
369
370int RenderTraverser::GetNumQueryCulledNodes()
371{
372        return mNumQueryCulledNodes;
373}
374
375int RenderTraverser::GetNumFrustumCulledNodes()
376{
377        return mNumFrustumCulledNodes;
378}
379
380
381int RenderTraverser::GetNumRenderedGeometry()
382{
383        return mNumRenderedGeometry;
384}
385
386
387#endif
388
389
390void RenderTraverser::SetUseOptimization(bool useOptimization)
391{
392        mUseOptimization = useOptimization;
393        printf("using opt %d\n", mUseOptimization);
394}
395
396}
Note: See TracBrowser for help on using the repository browser.