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

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