source: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp @ 1594

Revision 1594, 15.4 KB checked in by bittner, 18 years ago (diff)

support for kd tree based pvs

  • Property svn:executable set to *
Line 
1#include "Mesh.h"
2#include "glInterface.h"
3#include "OcclusionQuery.h"
4#include "GlRenderer.h"
5#include "ViewCellsManager.h"
6#include "SceneGraph.h"
7#include "Pvs.h"
8#include "Viewcell.h"
9#include "Beam.h"
10#include "KdTree.h"
11#include "Environment.h"
12#include "Triangle3.h"
13#include "IntersectableWrapper.h"
14#include "BvHierarchy.h"
15#include "KdTree.h"
16
17//#include <Cg/cg.h>
18//#include <Cg/cgGL.h>
19
20
21namespace GtpVisibilityPreprocessor {
22
23
24static bool arbQuerySupport = false;
25static bool nvQuerySupport = false;
26
27
28static void InitExtensions()
29{
30        GLenum err = glewInit();
31
32        if (GLEW_OK != err)
33        {
34                // problem: glewInit failed, something is seriously wrong
35                cerr << "Error: " << glewGetErrorString(err) << endl;
36                exit(1);
37        }
38
39        if (GLEW_ARB_occlusion_query)
40                arbQuerySupport = true;
41       
42        if (GLEW_NV_occlusion_query)
43                nvQuerySupport = true;
44       
45
46        if  (!arbQuerySupport && !nvQuerySupport)
47        {
48                cout << "I require the GL_ARB_occlusion_query or the GL_NV_occlusion_query OpenGL extension to work.\n";
49                exit(1);
50        }
51}
52
53
54GlRenderer::GlRenderer(SceneGraph *sceneGraph,
55                                           ViewCellsManager *viewCellsManager,
56                                           KdTree *tree):
57  Renderer(sceneGraph, viewCellsManager),
58  mKdTree(tree)
59{
60  mSceneGraph->CollectObjects(&mObjects);
61
62  //  mViewCellsManager->GetViewPoint(mViewPoint);
63
64  mViewPoint = mSceneGraph->GetBox().Center();
65  mViewDirection = Vector3(0,0,1);
66
67  //  mViewPoint = Vector3(991.7, 187.8, -271);
68  //  mViewDirection = Vector3(0.9, 0, -0.4);
69
70  //  timerId = startTimer(10);
71  // debug coords for atlanta
72  //  mViewPoint = Vector3(3473, 6.778, -1699);
73  //  mViewDirection = Vector3(-0.2432, 0, 0.97);
74 
75  mFrame = 0;
76  mWireFrame = false;
77  Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
78  mSnapErrorFrames = true;
79  mSnapPrefix = "snap/";
80  mUseForcedColors = false;
81  mRenderBoxes = false;
82  mUseGlLists = true;
83  //mUseGlLists = false;
84}
85
86GlRenderer::~GlRenderer()
87{
88  cerr<<"gl renderer destructor..\n";
89 
90  //CLEAR_CONTAINER(sQueries);
91  CLEAR_CONTAINER(mOcclusionQueries);
92
93  cerr<<"done."<<endl;
94}
95
96
97void
98GlRenderer::RenderTriangle(TriangleIntersectable *object)
99{
100  Triangle3 &t = object->GetItem();
101  glBegin(GL_TRIANGLES);
102  glVertex3f(t.mVertices[0].x, t.mVertices[0].y, t.mVertices[0].z);
103  glVertex3f(t.mVertices[1].x, t.mVertices[1].y, t.mVertices[1].z);
104  glVertex3f(t.mVertices[2].x, t.mVertices[2].y, t.mVertices[2].z);
105  glEnd();
106}
107
108void
109GlRenderer::RenderIntersectable(Intersectable *object)
110{
111  if (object->Mailed())
112        return;
113  object->Mail();
114 
115  glPushAttrib(GL_CURRENT_BIT);
116  if (mUseFalseColors)
117        SetupFalseColor(object->mId);
118 
119
120  switch (object->Type()) {
121  case Intersectable::MESH_INSTANCE:
122        RenderMeshInstance((MeshInstance *)object);
123        break;
124  case Intersectable::VIEW_CELL:
125        RenderViewCell(dynamic_cast<ViewCell *>(object));
126        break;
127  case Intersectable::TRANSFORMED_MESH_INSTANCE:
128        RenderTransformedMeshInstance(dynamic_cast<TransformedMeshInstance *>(object));
129        break;
130  case Intersectable::TRIANGLE_INTERSECTABLE:
131        RenderTriangle(dynamic_cast<TriangleIntersectable *>(object));
132        break;
133  case Intersectable::BVH_INTERSECTABLE: {
134
135       
136        BvhNode *node = (dynamic_cast<BvhIntersectable *>(object))->GetItem();
137
138        if (mRenderBoxes)
139          RenderBox(node->GetBoundingBox());
140        else
141          RenderBvhNode(node);
142        break;
143  }
144  case Intersectable::KD_INTERSECTABLE: {
145        KdNode *node = (dynamic_cast<KdIntersectable *>(object))->GetItem();
146
147        if (mRenderBoxes)
148          RenderBox(mKdTree->GetBox(node));
149        else
150          RenderKdNode(node);
151        break;
152  }
153       
154  default:
155        cerr<<"Rendering this object not yet implemented\n";
156        break;
157  }
158
159  glPopAttrib();
160}
161
162void
163GlRenderer::RenderRays(const VssRayContainer &rays)
164{
165  VssRayContainer::const_iterator it = rays.begin(), it_end = rays.end();
166
167  glBegin(GL_LINES);
168  for (; it != it_end; ++it) {
169        VssRay *ray = *it;
170        float importance = log10(1e3*ray->mWeightedPvsContribution)/3.0f;
171        //      cout<<"w="<<ray->mWeightedPvsContribution<<" r="<<ray->mWeightedPvsContribution;
172        glColor3f(importance, importance, importance);
173        glVertex3fv(&ray->mOrigin.x);
174        glVertex3fv(&ray->mTermination.x);
175  }
176  glEnd();
177}
178
179void
180GlRenderer::RenderViewCell(ViewCell *vc)
181{
182  if (vc->GetMesh()) {
183
184        if (!mUseFalseColors) {
185          if (vc->GetValid())
186                glColor3f(0,1,0);
187          else
188                glColor3f(0,0,1);
189        }
190       
191        RenderMesh(vc->GetMesh());
192  } else {
193        // render viewcells in the subtree
194        if (!vc->IsLeaf()) {
195          ViewCellInterior *vci = (ViewCellInterior *) vc;
196
197          ViewCellContainer::iterator it = vci->mChildren.begin();
198          for (; it != vci->mChildren.end(); ++it) {
199                RenderViewCell(*it);
200          }
201        } else {
202          //      cerr<<"Empty viewcell mesh\n";
203        }
204  }
205}
206
207
208void
209GlRenderer::RenderMeshInstance(MeshInstance *mi)
210{
211  RenderMesh(mi->GetMesh());
212}
213
214
215void
216GlRenderer::RenderTransformedMeshInstance(TransformedMeshInstance *mi)
217{
218        // apply world transform before rendering
219        Matrix4x4 m;
220        mi->GetWorldTransform(m);
221
222        glPushMatrix();
223/* cout << "\n";
224        for (int i = 0; i < 4; ++ i)
225                for (int j = 0; j < 4; ++ j)
226                        cout << m.x[i][j] << " "; cout << "\n"*/
227
228        glMultMatrixf((float *)m.x);
229
230        /*GLfloat dummy[16];
231        glGetFloatv(GL_MODELVIEW_MATRIX, dummy);
232        for (int i = 0; i < 16; ++ i)
233                cout << dummy[i] << " ";
234        cout << endl;*/
235        RenderMesh(mi->GetMesh());
236       
237        glPopMatrix();
238}
239
240
241void
242GlRenderer::SetupFalseColor(const int id)
243{
244  // swap bits of the color
245  glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
246}
247
248
249int GlRenderer::GetId(int r, int g, int b) const
250{
251        return r + (g << 8) + (b << 16);
252}
253
254void
255GlRenderer::SetupMaterial(Material *m)
256{
257  if (m)
258        glColor3fv(&(m->mDiffuseColor.r));
259}
260
261void
262GlRenderer::RenderMesh(Mesh *mesh)
263{
264  int i = 0;
265
266  if (!mUseFalseColors && !mUseForcedColors)
267        SetupMaterial(mesh->mMaterial);
268 
269  for (i=0; i < mesh->mFaces.size(); i++) {
270        if (mWireFrame)
271          glBegin(GL_LINE_LOOP);
272        else
273          glBegin(GL_POLYGON);
274
275        Face *face = mesh->mFaces[i];
276        for (int j = 0; j < face->mVertexIndices.size(); j++) {
277          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
278        }
279        glEnd();
280  }
281}
282       
283void
284GlRenderer::InitGL()
285{
286  glMatrixMode(GL_PROJECTION);
287  glLoadIdentity();
288 
289  glMatrixMode(GL_MODELVIEW);
290  glLoadIdentity();
291
292  glEnable(GL_CULL_FACE);
293  glShadeModel(GL_FLAT);
294  glEnable(GL_DEPTH_TEST);
295  glEnable(GL_CULL_FACE);
296 
297  InitExtensions();
298 
299#if 0
300  GLfloat mat_ambient[]   = {  0.5, 0.5, 0.5, 1.0  };
301  /*  mat_specular and mat_shininess are NOT default values     */
302  GLfloat mat_diffuse[]   = {  1.0, 1.0, 1.0, 1.0  };
303  GLfloat mat_specular[]  = {  0.3, 0.3, 0.3, 1.0  };
304  GLfloat mat_shininess[] = {  1.0  };
305 
306  GLfloat light_ambient[]  = {  0.2, 0.2, 0.2, 1.0  };
307  GLfloat light_diffuse[]  = {  0.4, 0.4, 0.4, 1.0  };
308  GLfloat light_specular[] = {  0.3, 0.3, 0.3, 1.0  };
309 
310  GLfloat lmodel_ambient[] = {  0.3, 0.3, 0.3, 1.0  };
311 
312 
313  // default Material
314  glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
315  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
316  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
317  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
318
319  // a light
320  glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
321  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
322  glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
323 
324  glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
325  glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
326  glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
327 
328  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
329 
330  glEnable(GL_LIGHTING);
331  glEnable(GL_LIGHT0);
332  glEnable(GL_LIGHT1);
333 
334 
335  // set position of the light
336  GLfloat infinite_light[] = {  1.0, 0.8, 1.0, 0.0  };
337  glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
338 
339  // set position of the light2
340  GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
341  glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
342 
343  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
344  //   glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR);
345  glEnable(GL_COLOR_MATERIAL);
346 
347  glShadeModel( GL_FLAT );
348 
349  glDepthFunc( GL_LESS );
350  glEnable( GL_DEPTH_TEST );
351#endif
352
353  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
354
355  glEnable( GL_NORMALIZE );
356 
357  glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
358}
359
360
361void
362GlRenderer::SetupProjection(const int w, const int h, const float angle)
363{
364  glViewport(0, 0, w, h);
365  glMatrixMode(GL_PROJECTION);
366  glLoadIdentity();
367  gluPerspective(angle, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
368  glMatrixMode(GL_MODELVIEW);
369}
370
371
372
373void
374GlRenderer::SetupCamera()
375{
376  Vector3 target = mViewPoint + mViewDirection;
377
378  Vector3 up(0,1,0);
379 
380  if (abs(DotProd(mViewDirection, up)) > 0.99f)
381        up = Vector3(1, 0, 0);
382 
383  glLoadIdentity();
384  gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
385                        target.x, target.y, target.z,
386                        up.x, up.y, up.z);
387}
388
389void
390GlRenderer::_RenderScene()
391{
392  ObjectContainer::const_iterator oi = mObjects.begin();
393
394  for (; oi != mObjects.end(); oi++)
395        RenderIntersectable(*oi);
396}
397
398bool
399GlRenderer::RenderScene()
400{
401  static int glList = -1;
402  if (mUseGlLists) {
403        if (glList == -1) {
404          glList = glGenLists(1);
405          glNewList(glList, GL_COMPILE);
406          _RenderScene();
407          glEndList();
408        }
409        glCallList(glList);
410  } else
411        _RenderScene();
412       
413 
414  return true;
415}
416
417
418void
419GlRendererBuffer::EvalQueryWithItemBuffer(
420                                                                                  //RenderCostSample &sample
421                                                                           )
422{
423        // read back the texture
424        glReadPixels(0, 0,
425                                GetWidth(), GetHeight(),
426                                GL_RGBA,
427                                GL_UNSIGNED_BYTE,
428                                mPixelBuffer);
429               
430                       
431        unsigned int *p = mPixelBuffer;
432                       
433        for (int y = 0; y < GetHeight(); y++)
434        {
435                for (int x = 0; x < GetWidth(); x++, p++)
436                {
437                        unsigned int id = (*p) & 0xFFFFFF;
438
439                        if (id != 0xFFFFFF)
440                                ++ mObjects[id]->mCounter;
441                }
442        }
443}
444
445
446
447/****************************************************************/
448/*               GlRendererBuffer implementation                */
449/****************************************************************/
450
451
452
453GlRendererBuffer::GlRendererBuffer(SceneGraph *sceneGraph,
454                                                                   ViewCellsManager *viewcells,
455                                                                   KdTree *tree):
456GlRenderer(sceneGraph, viewcells, tree) 
457{
458        mPixelBuffer = NULL;
459
460        // implement width and height in subclasses
461}
462
463
464void
465GlRendererBuffer::EvalQueryWithOcclusionQueries(
466                                                                           //RenderCostSample &sample
467                                                                           )
468{
469        glDepthFunc(GL_LEQUAL);
470               
471        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
472        glDepthMask(GL_FALSE);
473
474
475        // simulate detectemptyviewspace using backface culling
476        if (mDetectEmptyViewSpace)
477        {
478                glEnable(GL_CULL_FACE);
479                //cout << "culling" << endl;
480        }
481        else
482        {
483                //cout << "not culling" << endl;
484                glDisable(GL_CULL_FACE);
485        }
486
487       
488        //const int numQ = 1;
489        const int numQ = (int)mOcclusionQueries.size();
490       
491        //glFinish();
492#if 0
493        //-- now issue queries for all objects
494        for (int j = 0; j < (int)mObjects.size(); ++ j)
495        {
496                mOcclusionQueries[j]->BeginQuery();
497                RenderIntersectable(mObjects[j]);
498                mOcclusionQueries[j]->EndQuery();
499
500                unsigned int pixelCount;
501
502                pixelCount = mOcclusionQueries[j]->GetQueryResult();
503                mObjects[j]->mCounter += pixelCount;
504        }
505#else
506
507        int q = 0;
508
509        //-- now issue queries for all objects
510        for (int j = 0; j < (int)mObjects.size(); j += q)
511        {       
512                for (q = 0; ((j + q) < (int)mObjects.size()) && (q < numQ); ++ q)
513                {
514                        //glFinish();
515                        mOcclusionQueries[q]->BeginQuery();
516                       
517                        RenderIntersectable(mObjects[j + q]);
518               
519                        mOcclusionQueries[q]->EndQuery();
520                        //glFinish();
521                }
522                //cout << "q: " << q << endl;
523                // collect results of the queries
524                for (int t = 0; t < q; ++ t)
525                {
526                        unsigned int pixelCount;
527               
528                        //-- reenable other state
529#if 0
530                        bool available;
531
532                        do
533                        {
534                                available = mOcclusionQueries[t]->ResultAvailable();
535                               
536                                if (!available) cout << "W";
537                        }
538                        while (!available);
539#endif
540
541                        pixelCount = mOcclusionQueries[t]->GetQueryResult();
542
543                        //if (pixelCount > 0)
544                        //      cout <<"o="<<j+q<<" q="<<mOcclusionQueries[q]->GetQueryId()<<" pc="<<pixelCount<<" ";
545                        mObjects[j + t]->mCounter += pixelCount;
546                }
547
548                //j += q;
549        }
550#endif
551        //glFinish();
552        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
553        glDepthMask(GL_TRUE);
554       
555        glEnable(GL_CULL_FACE);
556}
557
558
559void
560GlRendererBuffer::RandomViewPoint()
561{
562  // do not use this function since it could return different viewpoints for
563  // different executions of the algorithm
564
565  //  mViewCellsManager->GetViewPoint(mViewPoint);
566
567  while (1) {
568        Vector3 pVector = Vector3(halton.GetNumber(1),
569                                                          halton.GetNumber(2),
570                                                          halton.GetNumber(3));
571       
572        mViewPoint =  mViewCellsManager->GetViewSpaceBox().GetPoint(pVector);
573        ViewCell *v = mViewCellsManager->GetViewCell(mViewPoint);
574        if (v && v->GetValid())
575          break;
576        // generate a new vector
577        halton.GenerateNext();
578  }
579 
580  Vector3 dVector = Vector3(2*M_PI*halton.GetNumber(4),
581                                                        M_PI*halton.GetNumber(5),
582                                                        0.0f);
583 
584  mViewDirection = Normalize(Vector3(sin(dVector.x),
585                                                                         //                                                                      cos(dVector.y),
586                                                                         0.0f,
587                                                                         cos(dVector.x)));
588  halton.GenerateNext();
589}
590
591
592void
593GlRenderer::RenderBox(const AxisAlignedBox3 &box)
594{
595
596  glBegin(GL_LINE_LOOP);
597  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
598  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
599  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
600  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
601  glEnd();
602
603  glBegin(GL_LINE_LOOP);
604  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
605  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
606  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
607  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
608  glEnd();
609
610  glBegin(GL_LINE_LOOP);
611  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
612  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
613  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
614  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
615  glEnd();
616
617  glBegin(GL_LINE_LOOP);
618  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
619  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
620  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
621  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
622  glEnd();
623
624  glBegin(GL_LINE_LOOP);
625  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
626  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
627  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
628  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
629  glEnd();
630
631  glBegin(GL_LINE_LOOP);
632  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
633  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
634  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
635  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
636
637  glEnd();
638
639}
640
641void
642GlRenderer::RenderBvhNode(BvhNode *node)
643{
644  if (node->IsLeaf()) {
645        BvhLeaf *leaf = (BvhLeaf *) node;
646        for (int i=0; i < leaf->mObjects.size(); i++)
647          RenderIntersectable(leaf->mObjects[i]);
648  } else {
649        BvhInterior *in = (BvhInterior *)node;
650        RenderBvhNode(in->GetBack());
651        RenderBvhNode(in->GetFront());
652  }
653
654  //cout << "leaf obj " << i << endl;
655
656}
657
658void
659GlRenderer::RenderKdNode(KdNode *node)
660{
661  if (node->IsLeaf()) {
662        KdLeaf *leaf = (KdLeaf *) node;
663        for (int i=0; i < leaf->mObjects.size(); i++) {
664          RenderIntersectable(leaf->mObjects[i]);
665        }
666  } else {
667        KdInterior *in = (KdInterior *)node;
668        RenderKdNode(in->mBack);
669        RenderKdNode(in->mFront);
670  }
671 
672}
673
674}
Note: See TracBrowser for help on using the repository browser.