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

Revision 2763, 10.0 KB checked in by mattausch, 16 years ago (diff)
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
103void RenderTraverser::Switch2GLRenderState()
104{
105        // boolean used to avoid unnecessary state changes
106        if (mIsQueryMode)
107        {
108                // switch back to rendermode           
109                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
110                glDepthMask(GL_TRUE);
111                glEnable(GL_LIGHTING);
112                mIsQueryMode = false;
113        }
114}
115
116
117OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node, bool wasVisible)
118{
119        OcclusionQuery *query = mQueryHandler.RequestQuery();
120
121        query->BeginQuery();
122       
123        // if leaf and was visible => will be rendered anyway, thus we
124        // can also test with the real geometry
125        /*if(node->IsLeaf() && wasVisible && mUseOptimization)
126        {
127                mNumRenderedGeometry += node->Render();
128        }
129        else
130        {*/
131
132        // change state so the bounding box gets not actually rendered on the screen
133        //Switch2GLQueryState();
134        mBvh->RenderBoundingBox(node);
135        //Switch2GLRenderState();
136
137        query->EndQuery();
138
139        return query;
140}
141
142
143void RenderTraverser::Switch2GLQueryState()
144{       
145        // boolean used to avoid unnecessary state changes
146        if (!mIsQueryMode)
147        {
148                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
149                glDepthMask(GL_FALSE);
150                glDisable(GL_LIGHTING);
151                mIsQueryMode = true;
152        }
153}
154
155
156
157#if 0
158
159Bvh *RenderTraverser::GetHierarchy()
160{
161        return mBvh;
162}
163
164
165void RenderTraverser::RenderVisualization()
166{
167        mDistanceQueue.push(mHierarchyRoot);
168
169        while(! mDistanceQueue.empty())
170        {
171                HierarchyNode *node = mDistanceQueue.top();
172                mDistanceQueue.pop();
173
174                // identify previously visible nodes
175                bool wasVisible = node->Visible() && (node->LastVisited() == mFrameID - 1);
176
177                if(wasVisible)
178                        TraverseNode(node);
179                else
180                {
181                        // also render culled nodes
182                        glColor3f(1.0,0.0,0.0);
183                        node->RenderBoundingVolumeForVisualization();           
184                }
185        }
186}
187
188
189void RenderTraverser::PullUpVisibility(HierarchyNode *node)
190{
191        while(node && !node->Visible())
192        {
193                node->SetVisible(true);
194                node = node->GetParent();
195        }
196}
197
198bool RenderTraverser::ResultAvailable(HierarchyNode *node) const
199{
200        unsigned int result;
201        if (mUseArbQueries)
202        {
203                glGetQueryObjectuivARB(node->GetOcclusionQuery(),
204                                                           GL_QUERY_RESULT_AVAILABLE_ARB, &result);
205        }
206        else
207        {
208               
209                glGetOcclusionQueryuivNV(node->GetOcclusionQuery(),
210                                                                 GL_PIXEL_COUNT_AVAILABLE_NV, &result);
211
212        }
213       
214        return (result == GL_TRUE);
215}
216
217
218void RenderTraverser::Preprocess()
219{
220        if (!mOcclusionQueries)
221        {
222                mOcclusionQueries = new unsigned int[mHierarchyRoot->GetNumHierarchyNodes()];
223
224                // generate ids for occlusion test
225                if (mUseArbQueries)
226                {
227                        glGenQueriesARB(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
228                }
229                else
230                {
231                        glGenOcclusionQueriesNV(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
232                }
233        }
234
235        // view frustum planes for view frustum culling
236        calcViewFrustumPlanes(&mClipPlanes, mProjViewMatrix);
237        calcAABNPVertexIndices(mNPVertexIndices, mClipPlanes);
238
239        mCurrentQueryIdx = 0;
240
241        // reset statistics
242        mNumTraversedNodes = 0;
243        mNumQueryCulledNodes = 0;
244        mNumFrustumCulledNodes = 0;
245        mNumRenderedGeometry = 0;
246}
247
248
249void RenderTraverser::DelQueries()
250{
251        if (!mOcclusionQueries)
252                return;
253
254        // tell the driver that the occlusion queries won't be needed any more
255        if (mUseArbQueries)
256        {
257                glDeleteQueriesARB(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
258        }
259        else
260        {
261                glDeleteOcclusionQueriesNV(mHierarchyRoot->GetNumHierarchyNodes(), mOcclusionQueries);
262        }
263
264        delete [] mOcclusionQueries;
265
266        mOcclusionQueries = NULL;
267}
268
269
270void RenderTraverser::SetViewpoint(Vector3 const &viewpoint)
271{
272        copyVector3(mViewpoint, viewpoint);
273}
274       
275
276void RenderTraverser::SetProjViewMatrix(Matrix4x4 const &projViewMatrix)
277{
278        copyMatrix(mProjViewMatrix, projViewMatrix);
279}
280
281
282bool RenderTraverser::InsideViewFrustum(HierarchyNode *node, bool &intersects)
283{
284        Vector3x8 vertices;
285       
286        bool intersect = false;
287
288        calcAABoxPoints(vertices, node->GetBoundingVolume());
289
290        // simply test all 6 vertices
291        for (int i = 0; i < 6; i++)
292        {               
293                // test the n-vertex
294                // note: the calcAABNearestVertexId should be preprocessed
295                if(!pointBeforePlane(mClipPlanes.plane[i], vertices[mNPVertexIndices[i * 2]]))
296                {
297                        // outside
298                        return false;
299                }
300        }
301
302        // test if bounding box is intersected by nearplane (using the p-vertex)
303        intersects = (!pointBeforePlane(mClipPlanes.plane[5], vertices[mNPVertexIndices[11]]));
304
305        // -- get vector from viewpoint to center of bounding volume
306        Vector3 vec;
307        calcAABoxCenter(vec, node->GetBoundingVolume());
308        diffVector3(vec, vec, mViewpoint);
309
310        // compute distance from nearest point to viewpoint
311        diffVector3(vec, vertices[calcAABNearestVertexIdx(vec)], mViewpoint);
312        node->SetDistance(squaredLength(vec));
313       
314        return true;
315}
316
317
318void RenderTraverser::SetVisibilityThreshold(int threshold)
319{
320        mVisibilityThreshold = threshold;
321}
322
323void RenderTraverser::SetUseArbQueries(const bool useArbQueries)
324{
325        DelQueries();
326        mUseArbQueries = useArbQueries;
327}
328
329bool RenderTraverser::GetUseArbQueries() const
330{
331        return mUseArbQueries;
332}
333
334long RenderTraverser::GetRenderTime()
335{
336        return mRenderTime;
337}
338
339int RenderTraverser::GetNumTraversedNodes()
340{
341        return mNumTraversedNodes;
342}
343
344int RenderTraverser::GetNumQueryCulledNodes()
345{
346        return mNumQueryCulledNodes;
347}
348
349int RenderTraverser::GetNumFrustumCulledNodes()
350{
351        return mNumFrustumCulledNodes;
352}
353
354
355int RenderTraverser::GetNumRenderedGeometry()
356{
357        return mNumRenderedGeometry;
358}
359
360
361#endif
362
363
364void RenderTraverser::SetUseOptimization(bool useOptimization)
365{
366        mUseOptimization = useOptimization;
367        printf("using opt %d\n", mUseOptimization);
368}
369
370
371void RenderTraverser::RenderBox(const AxisAlignedBox3 &box)
372{
373        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
374        glDisable(GL_CULL_FACE);
375        glColor3f(1.0f, 0.0f, 0.0f);
376
377        glBegin(GL_QUADS);
378        glVertex3f(box.Min().x, box.Max().y, box.Min().z);
379        glVertex3f(box.Max().x, box.Max().y, box.Min().z);
380        glVertex3f(box.Max().x, box.Min().y, box.Min().z);
381        glVertex3f(box.Min().x, box.Min().y, box.Min().z);
382        glEnd();
383
384        glBegin(GL_QUADS);
385        glVertex3f(box.Min().x, box.Min().y, box.Max().z);
386        glVertex3f(box.Max().x, box.Min().y, box.Max().z);
387        glVertex3f(box.Max().x, box.Max().y, box.Max().z);
388        glVertex3f(box.Min().x, box.Max().y, box.Max().z);
389        glEnd();
390
391        glBegin(GL_QUADS);
392        glVertex3f(box.Max().x, box.Min().y, box.Min().z);
393        glVertex3f(box.Max().x, box.Min().y, box.Max().z);
394        glVertex3f(box.Max().x, box.Max().y, box.Max().z);
395        glVertex3f(box.Max().x, box.Max().y, box.Min().z);
396        glEnd();
397
398        glBegin(GL_QUADS);
399        glVertex3f(box.Min().x, box.Min().y, box.Min().z);
400        glVertex3f(box.Min().x, box.Min().y, box.Max().z);
401        glVertex3f(box.Min().x, box.Max().y, box.Max().z);
402        glVertex3f(box.Min().x, box.Max().y, box.Min().z);
403        glEnd();
404
405        glBegin(GL_QUADS);
406        glVertex3f(box.Min().x, box.Min().y, box.Min().z);
407        glVertex3f(box.Max().x, box.Min().y, box.Min().z);
408        glVertex3f(box.Max().x, box.Min().y, box.Max().z);
409        glVertex3f(box.Min().x, box.Min().y, box.Max().z);
410        glEnd();
411
412        glBegin(GL_QUADS);
413        glVertex3f(box.Min().x, box.Max().y, box.Min().z);
414        glVertex3f(box.Max().x, box.Max().y, box.Min().z);
415        glVertex3f(box.Max().x, box.Max().y, box.Max().z);
416        glVertex3f(box.Min().x, box.Max().y, box.Max().z);
417        glEnd();
418
419        glEnable(GL_CULL_FACE);
420
421        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
422}
423
424
425void RenderTraverser::RenderFrustum()
426{
427        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
428        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
429
430        glLineWidth(2);
431
432        glBegin(GL_LINE_LOOP);
433        glVertex3d(fbl.x, fbl.y, fbl.z);
434        glVertex3d(fbr.x, fbr.y, fbr.z);
435        glVertex3d(ftr.x, ftr.y, ftr.z);
436        glVertex3d(ftl.x, ftl.y, ftl.z);
437        glEnd();
438
439        glBegin(GL_LINE_LOOP);
440        glVertex3d(nbl.x, nbl.y, nbl.z);
441        glVertex3d(nbr.x, nbr.y, nbr.z);
442        glVertex3d(ntr.x, ntr.y, ntr.z);
443        glVertex3d(ntl.x, ntl.y, ntl.z);
444        glEnd();
445
446        glBegin(GL_LINE_LOOP);
447        glVertex3d(fbl.x, fbl.y, fbl.z);
448        glVertex3d(ftl.x, ftl.y, ftl.z);
449        glVertex3d(ntl.x, ntl.y, ntl.z);
450        glVertex3d(nbl.x, nbl.y, nbl.z);
451        glEnd();
452
453        glBegin(GL_LINE_LOOP);
454        glVertex3d(fbr.x, fbr.y, fbr.z);
455        glVertex3d(ftr.x, ftr.y, ftr.z);
456        glVertex3d(ntr.x, ntr.y, ntr.z);
457        glVertex3d(nbr.x, nbr.y, nbr.z);
458        glEnd();
459
460        glBegin(GL_LINE_LOOP);
461        glVertex3d(fbr.x, fbr.y, fbr.z);
462        glVertex3d(fbl.x, fbl.y, fbl.z);
463        glVertex3d(nbl.x, nbl.y, nbl.z);
464        glVertex3d(nbr.x, nbr.y, nbr.z);
465        glEnd();
466
467        glBegin(GL_LINE_LOOP);
468        glVertex3d(ftr.x, ftr.y, ftr.z);
469        glVertex3d(ftl.x, ftl.y, ftl.z);
470        glVertex3d(ntl.x, ntl.y, ntl.z);
471        glVertex3d(ntr.x, ntr.y, ntr.z);
472        glEnd();
473}
474
475
476}
Note: See TracBrowser for help on using the repository browser.