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

Revision 2762, 10.7 KB checked in by mattausch, 16 years ago (diff)

debug version

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