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

Revision 1758, 15.4 KB checked in by mattausch, 18 years ago (diff)

bvhnode is now derived from Intersectable

  • 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          BvhNode *node = dynamic_cast<BvhNode *>(object);
136
137        if (mRenderBoxes)
138          RenderBox(node->GetBoundingBox());
139        else
140          RenderBvhNode(node);
141        break;
142  }
143  case Intersectable::KD_INTERSECTABLE: {
144        KdNode *node = (dynamic_cast<KdIntersectable *>(object))->GetItem();
145
146        if (mRenderBoxes)
147          RenderBox(mKdTree->GetBox(node));
148        else
149          RenderKdNode(node);
150        break;
151  }
152       
153  default:
154        cerr<<"Rendering this object not yet implemented\n";
155        break;
156  }
157
158  glPopAttrib();
159}
160
161void
162GlRenderer::RenderRays(const VssRayContainer &rays)
163{
164  VssRayContainer::const_iterator it = rays.begin(), it_end = rays.end();
165
166  glBegin(GL_LINES);
167  for (; it != it_end; ++it) {
168        VssRay *ray = *it;
169        float importance = log10(1e3*ray->mWeightedPvsContribution)/3.0f;
170        //      cout<<"w="<<ray->mWeightedPvsContribution<<" r="<<ray->mWeightedPvsContribution;
171        glColor3f(importance, importance, importance);
172        glVertex3fv(&ray->mOrigin.x);
173        glVertex3fv(&ray->mTermination.x);
174  }
175  glEnd();
176}
177
178
179
180void
181GlRenderer::RenderViewCell(ViewCell *vc)
182{
183  if (vc->GetMesh()) {
184
185        if (!mUseFalseColors) {
186          if (vc->GetValid())
187                glColor3f(0,1,0);
188          else
189                glColor3f(0,0,1);
190        }
191       
192        RenderMesh(vc->GetMesh());
193  } else {
194        // render viewcells in the subtree
195        if (!vc->IsLeaf()) {
196          ViewCellInterior *vci = (ViewCellInterior *) vc;
197
198          ViewCellContainer::iterator it = vci->mChildren.begin();
199          for (; it != vci->mChildren.end(); ++it) {
200                RenderViewCell(*it);
201          }
202        } else {
203          //      cerr<<"Empty viewcell mesh\n";
204        }
205  }
206}
207
208
209void
210GlRenderer::RenderMeshInstance(MeshInstance *mi)
211{
212  RenderMesh(mi->GetMesh());
213}
214
215
216void
217GlRenderer::RenderTransformedMeshInstance(TransformedMeshInstance *mi)
218{
219        // apply world transform before rendering
220        Matrix4x4 m;
221        mi->GetWorldTransform(m);
222
223        glPushMatrix();
224/* cout << "\n";
225        for (int i = 0; i < 4; ++ i)
226                for (int j = 0; j < 4; ++ j)
227                        cout << m.x[i][j] << " "; cout << "\n"*/
228
229        glMultMatrixf((float *)m.x);
230
231        /*GLfloat dummy[16];
232        glGetFloatv(GL_MODELVIEW_MATRIX, dummy);
233        for (int i = 0; i < 16; ++ i)
234                cout << dummy[i] << " ";
235        cout << endl;*/
236        RenderMesh(mi->GetMesh());
237       
238        glPopMatrix();
239}
240
241
242void
243GlRenderer::SetupFalseColor(const int id)
244{
245  // swap bits of the color
246  glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
247}
248
249
250int GlRenderer::GetId(int r, int g, int b) const
251{
252        return r + (g << 8) + (b << 16);
253}
254
255void
256GlRenderer::SetupMaterial(Material *m)
257{
258  if (m)
259        glColor3fv(&(m->mDiffuseColor.r));
260}
261
262void
263GlRenderer::RenderMesh(Mesh *mesh)
264{
265  int i = 0;
266
267  if (!mUseFalseColors && !mUseForcedColors)
268        SetupMaterial(mesh->mMaterial);
269 
270  for (i=0; i < mesh->mFaces.size(); i++) {
271        if (mWireFrame)
272          glBegin(GL_LINE_LOOP);
273        else
274          glBegin(GL_POLYGON);
275
276        Face *face = mesh->mFaces[i];
277        for (int j = 0; j < face->mVertexIndices.size(); j++) {
278          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
279        }
280        glEnd();
281  }
282}
283       
284void
285GlRenderer::InitGL()
286{
287  mSphere = (GLUquadric *)gluNewQuadric();
288 
289  glMatrixMode(GL_PROJECTION);
290  glLoadIdentity();
291 
292  glMatrixMode(GL_MODELVIEW);
293  glLoadIdentity();
294
295  glEnable(GL_CULL_FACE);
296  glShadeModel(GL_FLAT);
297  glEnable(GL_DEPTH_TEST);
298  glEnable(GL_CULL_FACE);
299 
300  InitExtensions();
301 
302#if 0
303  GLfloat mat_ambient[]   = {  0.5, 0.5, 0.5, 1.0  };
304  /*  mat_specular and mat_shininess are NOT default values     */
305  GLfloat mat_diffuse[]   = {  1.0, 1.0, 1.0, 1.0  };
306  GLfloat mat_specular[]  = {  0.3, 0.3, 0.3, 1.0  };
307  GLfloat mat_shininess[] = {  1.0  };
308 
309  GLfloat light_ambient[]  = {  0.2, 0.2, 0.2, 1.0  };
310  GLfloat light_diffuse[]  = {  0.4, 0.4, 0.4, 1.0  };
311  GLfloat light_specular[] = {  0.3, 0.3, 0.3, 1.0  };
312 
313  GLfloat lmodel_ambient[] = {  0.3, 0.3, 0.3, 1.0  };
314 
315 
316  // default Material
317  glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
318  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
319  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
320  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
321
322  // a light
323  glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
324  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
325  glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
326 
327  glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
328  glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
329  glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
330 
331  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
332 
333  glEnable(GL_LIGHTING);
334  glEnable(GL_LIGHT0);
335  glEnable(GL_LIGHT1);
336 
337 
338  // set position of the light
339  GLfloat infinite_light[] = {  1.0, 0.8, 1.0, 0.0  };
340  glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
341 
342  // set position of the light2
343  GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
344  glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
345 
346  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
347  //   glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR);
348  glEnable(GL_COLOR_MATERIAL);
349 
350  glShadeModel( GL_FLAT );
351 
352  glDepthFunc( GL_LESS );
353  glEnable( GL_DEPTH_TEST );
354#endif
355
356  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
357
358  glEnable( GL_NORMALIZE );
359 
360  glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
361}
362
363
364void
365GlRenderer::SetupProjection(const int w, const int h, const float angle)
366{
367  glViewport(0, 0, w, h);
368  glMatrixMode(GL_PROJECTION);
369  glLoadIdentity();
370  gluPerspective(angle, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
371  glMatrixMode(GL_MODELVIEW);
372}
373
374
375
376void
377GlRenderer::SetupCamera()
378{
379  Vector3 target = mViewPoint + mViewDirection;
380
381  Vector3 up(0,1,0);
382 
383  if (abs(DotProd(mViewDirection, up)) > 0.99f)
384        up = Vector3(1, 0, 0);
385 
386  glLoadIdentity();
387  gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
388                        target.x, target.y, target.z,
389                        up.x, up.y, up.z);
390}
391
392void
393GlRenderer::_RenderScene()
394{
395  ObjectContainer::const_iterator oi = mObjects.begin();
396
397  for (; oi != mObjects.end(); oi++)
398        RenderIntersectable(*oi);
399}
400
401bool
402GlRenderer::RenderScene()
403{
404  static int glList = -1;
405  if (mUseGlLists) {
406        if (glList == -1) {
407          glList = glGenLists(1);
408          glNewList(glList, GL_COMPILE);
409          _RenderScene();
410          glEndList();
411        }
412        glCallList(glList);
413  } else
414        _RenderScene();
415       
416 
417  return true;
418}
419
420
421void
422GlRendererBuffer::EvalQueryWithItemBuffer(
423                                                                                  //RenderCostSample &sample
424                                                                           )
425{
426        // read back the texture
427        glReadPixels(0, 0,
428                                GetWidth(), GetHeight(),
429                                GL_RGBA,
430                                GL_UNSIGNED_BYTE,
431                                mPixelBuffer);
432               
433                       
434        unsigned int *p = mPixelBuffer;
435                       
436        for (int y = 0; y < GetHeight(); y++)
437        {
438                for (int x = 0; x < GetWidth(); x++, p++)
439                {
440                        unsigned int id = (*p) & 0xFFFFFF;
441
442                        if (id != 0xFFFFFF)
443                                ++ mObjects[id]->mCounter;
444                }
445        }
446}
447
448
449
450/****************************************************************/
451/*               GlRendererBuffer implementation                */
452/****************************************************************/
453
454
455
456GlRendererBuffer::GlRendererBuffer(SceneGraph *sceneGraph,
457                                                                   ViewCellsManager *viewcells,
458                                                                   KdTree *tree):
459GlRenderer(sceneGraph, viewcells, tree) 
460{
461        mPixelBuffer = NULL;
462
463        // implement width and height in subclasses
464}
465
466
467void
468GlRendererBuffer::EvalQueryWithOcclusionQueries(
469                                                                           //RenderCostSample &sample
470                                                                           )
471{
472        glDepthFunc(GL_LEQUAL);
473               
474        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
475        glDepthMask(GL_FALSE);
476
477
478        // simulate detectemptyviewspace using backface culling
479        if (mDetectEmptyViewSpace)
480        {
481                glEnable(GL_CULL_FACE);
482                //cout << "culling" << endl;
483        }
484        else
485        {
486                //cout << "not culling" << endl;
487                glDisable(GL_CULL_FACE);
488        }
489
490       
491        //const int numQ = 1;
492        const int numQ = (int)mOcclusionQueries.size();
493       
494        //glFinish();
495#if 0
496        //-- now issue queries for all objects
497        for (int j = 0; j < (int)mObjects.size(); ++ j)
498        {
499                mOcclusionQueries[j]->BeginQuery();
500                RenderIntersectable(mObjects[j]);
501                mOcclusionQueries[j]->EndQuery();
502
503                unsigned int pixelCount;
504
505                pixelCount = mOcclusionQueries[j]->GetQueryResult();
506                mObjects[j]->mCounter += pixelCount;
507        }
508#else
509
510        int q = 0;
511
512        //-- now issue queries for all objects
513        for (int j = 0; j < (int)mObjects.size(); j += q)
514        {       
515                for (q = 0; ((j + q) < (int)mObjects.size()) && (q < numQ); ++ q)
516                {
517                        //glFinish();
518                        mOcclusionQueries[q]->BeginQuery();
519                       
520                        RenderIntersectable(mObjects[j + q]);
521               
522                        mOcclusionQueries[q]->EndQuery();
523                        //glFinish();
524                }
525                //cout << "q: " << q << endl;
526                // collect results of the queries
527                for (int t = 0; t < q; ++ t)
528                {
529                        unsigned int pixelCount;
530               
531                        //-- reenable other state
532#if 0
533                        bool available;
534
535                        do
536                        {
537                                available = mOcclusionQueries[t]->ResultAvailable();
538                               
539                                if (!available) cout << "W";
540                        }
541                        while (!available);
542#endif
543
544                        pixelCount = mOcclusionQueries[t]->GetQueryResult();
545
546                        //if (pixelCount > 0)
547                        //      cout <<"o="<<j+q<<" q="<<mOcclusionQueries[q]->GetQueryId()<<" pc="<<pixelCount<<" ";
548                        mObjects[j + t]->mCounter += pixelCount;
549                }
550
551                //j += q;
552        }
553#endif
554        //glFinish();
555        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
556        glDepthMask(GL_TRUE);
557       
558        glEnable(GL_CULL_FACE);
559}
560
561
562void
563GlRendererBuffer::RandomViewPoint()
564{
565  // do not use this function since it could return different viewpoints for
566  // different executions of the algorithm
567
568  //  mViewCellsManager->GetViewPoint(mViewPoint);
569
570  while (1) {
571        Vector3 pVector = Vector3(halton.GetNumber(1),
572                                                          halton.GetNumber(2),
573                                                          halton.GetNumber(3));
574       
575        mViewPoint =  mViewCellsManager->GetViewSpaceBox().GetPoint(pVector);
576        ViewCell *v = mViewCellsManager->GetViewCell(mViewPoint);
577        if (v && v->GetValid())
578          break;
579        // generate a new vector
580        halton.GenerateNext();
581  }
582 
583  Vector3 dVector = Vector3(2*M_PI*halton.GetNumber(4),
584                                                        M_PI*halton.GetNumber(5),
585                                                        0.0f);
586 
587  mViewDirection = Normalize(Vector3(sin(dVector.x),
588                                                                         //                                                                      cos(dVector.y),
589                                                                         0.0f,
590                                                                         cos(dVector.x)));
591  halton.GenerateNext();
592}
593
594
595void
596GlRenderer::RenderBox(const AxisAlignedBox3 &box)
597{
598
599  glBegin(GL_LINE_LOOP);
600  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
601  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
602  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
603  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
604  glEnd();
605
606  glBegin(GL_LINE_LOOP);
607  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
608  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
609  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
610  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
611  glEnd();
612
613  glBegin(GL_LINE_LOOP);
614  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
615  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
616  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
617  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
618  glEnd();
619
620  glBegin(GL_LINE_LOOP);
621  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
622  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
623  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
624  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
625  glEnd();
626
627  glBegin(GL_LINE_LOOP);
628  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
629  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
630  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
631  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
632  glEnd();
633
634  glBegin(GL_LINE_LOOP);
635  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
636  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
637  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
638  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
639
640  glEnd();
641
642}
643
644void
645GlRenderer::RenderBvhNode(BvhNode *node)
646{
647  if (node->IsLeaf()) {
648        BvhLeaf *leaf = (BvhLeaf *) node;
649        for (int i=0; i < leaf->mObjects.size(); i++)
650          RenderIntersectable(leaf->mObjects[i]);
651  } else {
652        BvhInterior *in = (BvhInterior *)node;
653        RenderBvhNode(in->GetBack());
654        RenderBvhNode(in->GetFront());
655  }
656
657  //cout << "leaf obj " << i << endl;
658
659}
660
661void
662GlRenderer::RenderKdNode(KdNode *node)
663{
664  if (node->IsLeaf()) {
665        KdLeaf *leaf = (KdLeaf *) node;
666        for (int i=0; i < leaf->mObjects.size(); i++) {
667          RenderIntersectable(leaf->mObjects[i]);
668        }
669  } else {
670        KdInterior *in = (KdInterior *)node;
671        RenderKdNode(in->mBack);
672        RenderKdNode(in->mFront);
673  }
674 
675}
676
677}
Note: See TracBrowser for help on using the repository browser.