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

Revision 1990, 38.3 KB checked in by mattausch, 17 years ago (diff)
  • 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#ifdef USE_CG
18
19#include <Cg/cg.h>
20#include <Cg/cgGL.h>
21
22#endif
23
24namespace GtpVisibilityPreprocessor {
25
26
27static bool arbQuerySupport = false;
28static bool nvQuerySupport = false;
29
30static GLuint frontDepthMap;
31static GLuint backDepthMap;
32
33const int depthMapSize = 512;
34
35static void InitExtensions()
36{
37        GLenum err = glewInit();
38
39        if (GLEW_OK != err)
40        {
41                // problem: glewInit failed, something is seriously wrong
42                cerr << "Error: " << glewGetErrorString(err) << endl;
43                exit(1);
44        }
45
46        if (GLEW_ARB_occlusion_query)
47                arbQuerySupport = true;
48       
49        if (GLEW_NV_occlusion_query)
50                nvQuerySupport = true;
51       
52
53        if  (!arbQuerySupport && !nvQuerySupport)
54        {
55                cout << "I require the GL_ARB_occlusion_query or the GL_NV_occlusion_query OpenGL extension to work.\n";
56                exit(1);
57        }
58}
59
60
61GlRenderer::GlRenderer(SceneGraph *sceneGraph,
62                                           ViewCellsManager *viewCellsManager,
63                                           KdTree *tree):
64  Renderer(sceneGraph, viewCellsManager),
65  mKdTree(tree)
66{
67  mSceneGraph->CollectObjects(&mObjects);
68
69  //  mViewCellsManager->GetViewPoint(mViewPoint);
70
71  viewCellsManager->GetViewPoint(mViewPoint);
72        //mSceneGraph->GetBox().Center();
73  mViewDirection = Vector3(0,0,1);
74
75  //  mViewPoint = Vector3(991.7, 187.8, -271);
76  //  mViewDirection = Vector3(0.9, 0, -0.4);
77
78  //  timerId = startTimer(10);
79  // debug coords for atlanta
80  //  mViewPoint = Vector3(3473, 6.778, -1699);
81  //  mViewDirection = Vector3(-0.2432, 0, 0.97);
82 
83  mFrame = 0;
84  mWireFrame = false;
85  Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace",
86                                                                                        mDetectEmptyViewSpace);
87  mSnapErrorFrames = true;
88  mSnapPrefix = "snap/";
89  mUseForcedColors = false;
90  mRenderBoxes = false;
91  //mUseGlLists = true;
92  mUseGlLists = false;
93
94  Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", mPvsStatFrames);
95  mPvsErrorBuffer.resize(mPvsStatFrames);
96  ClearErrorBuffer();
97 
98}
99
100GlRenderer::~GlRenderer()
101{
102  cerr<<"gl renderer destructor..\n";
103 
104  //CLEAR_CONTAINER(sQueries);
105  CLEAR_CONTAINER(mOcclusionQueries);
106
107  cerr<<"done."<<endl;
108}
109
110
111void
112GlRenderer::RenderTriangle(TriangleIntersectable *object)
113{
114  Triangle3 &t = object->GetItem();
115 
116  glBegin(GL_TRIANGLES);
117  glVertex3f(t.mVertices[0].x, t.mVertices[0].y, t.mVertices[0].z);
118  glVertex3f(t.mVertices[1].x, t.mVertices[1].y, t.mVertices[1].z);
119  glVertex3f(t.mVertices[2].x, t.mVertices[2].y, t.mVertices[2].z);
120  glEnd();
121}
122
123void
124GlRenderer::RenderIntersectable(Intersectable *object)
125{
126  if (object->Mailed())
127        return;
128  object->Mail();
129 
130  glPushAttrib(GL_CURRENT_BIT);
131  if (mUseFalseColors)
132        SetupFalseColor(object->mId);
133 
134  switch (object->Type()) {
135  case Intersectable::MESH_INSTANCE:
136        RenderMeshInstance((MeshInstance *)object);
137        break;
138  case Intersectable::VIEW_CELL:
139        RenderViewCell(dynamic_cast<ViewCell *>(object));
140        break;
141  case Intersectable::TRANSFORMED_MESH_INSTANCE:
142        RenderTransformedMeshInstance(dynamic_cast<TransformedMeshInstance *>(object));
143        break;
144  case Intersectable::TRIANGLE_INTERSECTABLE:
145        RenderTriangle(dynamic_cast<TriangleIntersectable *>(object));
146        break;
147  case Intersectable::BVH_INTERSECTABLE: {
148
149        BvhNode *node = dynamic_cast<BvhNode *>(object);
150       
151        if (mRenderBoxes)
152          RenderBox(node->GetBoundingBox());
153        else
154          RenderBvhNode(node);
155        break;
156  }
157  case Intersectable::KD_INTERSECTABLE: {
158        KdNode *node = (dynamic_cast<KdIntersectable *>(object))->GetItem();
159       
160        if (mRenderBoxes)
161          RenderBox(mKdTree->GetBox(node));
162        else
163          RenderKdNode(node);
164        break;
165  }
166       
167  default:
168        cerr<<"Rendering this object not yet implemented\n";
169        break;
170  }
171
172  glPopAttrib();
173}
174
175void
176GlRenderer::RenderRays(const VssRayContainer &rays)
177{
178  VssRayContainer::const_iterator it = rays.begin(), it_end = rays.end();
179
180  glBegin(GL_LINES);
181  for (; it != it_end; ++it) {
182        VssRay *ray = *it;
183        float importance = log10(1e3*ray->mWeightedPvsContribution)/3.0f;
184        //      cout<<"w="<<ray->mWeightedPvsContribution<<" r="<<ray->mWeightedPvsContribution;
185        glColor3f(importance, importance, importance);
186        glVertex3fv(&ray->mOrigin.x);
187        glVertex3fv(&ray->mTermination.x);
188  }
189  glEnd();
190}
191
192
193
194void
195GlRenderer::RenderViewCell(ViewCell *vc)
196{
197  if (vc->GetMesh()) {
198
199        if (!mUseFalseColors) {
200          if (vc->GetValid())
201                glColor3f(0,1,0);
202          else
203                glColor3f(0,0,1);
204        }
205       
206        RenderMesh(vc->GetMesh());
207  } else {
208        // render viewcells in the subtree
209        if (!vc->IsLeaf()) {
210          ViewCellInterior *vci = (ViewCellInterior *) vc;
211
212          ViewCellContainer::iterator it = vci->mChildren.begin();
213          for (; it != vci->mChildren.end(); ++it) {
214                RenderViewCell(*it);
215          }
216        } else {
217          //      cerr<<"Empty viewcell mesh\n";
218        }
219  }
220}
221
222
223void
224GlRenderer::RenderMeshInstance(MeshInstance *mi)
225{
226  RenderMesh(mi->GetMesh());
227}
228
229
230void
231GlRenderer::RenderTransformedMeshInstance(TransformedMeshInstance *mi)
232{
233        // apply world transform before rendering
234        Matrix4x4 m;
235        mi->GetWorldTransform(m);
236
237        glPushMatrix();
238/* cout << "\n";
239        for (int i = 0; i < 4; ++ i)
240                for (int j = 0; j < 4; ++ j)
241                        cout << m.x[i][j] << " "; cout << "\n"*/
242
243        glMultMatrixf((float *)m.x);
244
245        /*GLfloat dummy[16];
246        glGetFloatv(GL_MODELVIEW_MATRIX, dummy);
247        for (int i = 0; i < 16; ++ i)
248                cout << dummy[i] << " ";
249        cout << endl;*/
250        RenderMesh(mi->GetMesh());
251       
252        glPopMatrix();
253}
254
255
256void
257GlRenderer::SetupFalseColor(const unsigned int id)
258{
259        // swap bits of the color
260        glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
261}
262
263
264unsigned int GlRenderer::GetId(const unsigned char r,
265                                                           const unsigned char g,
266                                                           const unsigned char b) const
267{
268        return r + (g << 8) + (b << 16);
269}
270
271
272void
273GlRenderer::SetupMaterial(Material *m)
274{
275  if (m)
276        glColor3fv(&(m->mDiffuseColor.r));
277}
278
279
280void
281GlRenderer::RenderMesh(Mesh *mesh)
282{
283  int i = 0;
284
285  if (!mUseFalseColors && !mUseForcedColors)
286          SetupMaterial(mesh->mMaterial);
287 
288  for (i=0; i < mesh->mFaces.size(); i++) {
289        if (mWireFrame)
290          glBegin(GL_LINE_LOOP);
291        else
292          glBegin(GL_POLYGON);
293
294        Face *face = mesh->mFaces[i];
295        for (int j = 0; j < face->mVertexIndices.size(); j++) {
296          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
297        }
298        glEnd();
299  }
300}
301       
302void
303GlRenderer::InitGL()
304{
305  mSphere = (GLUquadric *)gluNewQuadric();
306 
307  glMatrixMode(GL_PROJECTION);
308  glLoadIdentity();
309 
310  glMatrixMode(GL_MODELVIEW);
311  glLoadIdentity();
312
313  glFrontFace(GL_CCW);
314  glCullFace(GL_BACK);
315  glEnable(GL_CULL_FACE);
316  glShadeModel(GL_FLAT);
317  glEnable(GL_DEPTH_TEST);
318  glEnable(GL_CULL_FACE);
319 
320  InitExtensions();
321 
322#if 0
323  GLfloat mat_ambient[]   = {  0.5, 0.5, 0.5, 1.0  };
324  /*  mat_specular and mat_shininess are NOT default values     */
325  GLfloat mat_diffuse[]   = {  1.0, 1.0, 1.0, 1.0  };
326  GLfloat mat_specular[]  = {  0.3, 0.3, 0.3, 1.0  };
327  GLfloat mat_shininess[] = {  1.0  };
328 
329  GLfloat light_ambient[]  = {  0.2, 0.2, 0.2, 1.0  };
330  GLfloat light_diffuse[]  = {  0.4, 0.4, 0.4, 1.0  };
331  GLfloat light_specular[] = {  0.3, 0.3, 0.3, 1.0  };
332 
333  GLfloat lmodel_ambient[] = {  0.3, 0.3, 0.3, 1.0  };
334 
335 
336  // default Material
337  glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
338  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
339  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
340  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
341
342  // a light
343  glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
344  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
345  glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
346 
347  glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
348  glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
349  glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
350 
351  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
352 
353  glEnable(GL_LIGHTING);
354  glEnable(GL_LIGHT0);
355  glEnable(GL_LIGHT1);
356 
357 
358  // set position of the light
359  GLfloat infinite_light[] = {  1.0, 0.8, 1.0, 0.0  };
360  glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
361 
362  // set position of the light2
363  GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
364  glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
365 
366  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
367  //   glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR);
368  glEnable(GL_COLOR_MATERIAL);
369 
370  glShadeModel( GL_FLAT );
371 
372  glDepthFunc( GL_LESS );
373  glEnable( GL_DEPTH_TEST );
374#endif
375
376  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
377
378  glEnable( GL_NORMALIZE );
379 
380  glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
381}
382
383
384void
385GlRenderer::SetupProjection(const int w, const int h, const float angle)
386{
387  glViewport(0, 0, w, h);
388  glMatrixMode(GL_PROJECTION);
389  glLoadIdentity();
390  gluPerspective(angle, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
391  glMatrixMode(GL_MODELVIEW);
392}
393
394
395
396void
397GlRenderer::SetupCamera()
398{
399  Vector3 target = mViewPoint + mViewDirection;
400
401  Vector3 up(0,1,0);
402 
403  if (abs(DotProd(mViewDirection, up)) > 0.99f)
404        up = Vector3(1, 0, 0);
405 
406  glLoadIdentity();
407  gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
408                        target.x, target.y, target.z,
409                        up.x, up.y, up.z);
410}
411
412void
413GlRenderer::_RenderScene()
414{
415  ObjectContainer::const_iterator oi = mObjects.begin();
416
417  for (; oi != mObjects.end(); oi++)
418        RenderIntersectable(*oi);
419}
420
421bool
422GlRenderer::RenderScene()
423{
424  Intersectable::NewMail();
425  static int glList = -1;
426  if (mUseGlLists) {
427        if (glList == -1) {
428          glList = glGenLists(1);
429          glNewList(glList, GL_COMPILE);
430          _RenderScene();
431          glEndList();
432        }
433       
434        glCallList(glList);
435  } else
436        _RenderScene();
437       
438 
439  return true;
440}
441
442
443void
444GlRendererBuffer::EvalQueryWithItemBuffer(
445                                                                                  //RenderCostSample &sample
446                                                                           )
447{
448        // read back the texture
449        glReadPixels(0, 0,
450                                GetWidth(), GetHeight(),
451                                GL_RGBA,
452                                GL_UNSIGNED_BYTE,
453                                mPixelBuffer);
454               
455                       
456        unsigned int *p = mPixelBuffer;
457                       
458        for (int y = 0; y < GetHeight(); y++)
459        {
460                for (int x = 0; x < GetWidth(); x++, p++)
461                {
462                        unsigned int id = (*p) & 0xFFFFFF;
463
464                        if (id != 0xFFFFFF)
465                                ++ mObjects[id]->mCounter;
466                }
467        }
468}
469
470
471
472/****************************************************************/
473/*               GlRendererBuffer implementation                */
474/****************************************************************/
475
476
477
478GlRendererBuffer::GlRendererBuffer(SceneGraph *sceneGraph,
479                                                                   ViewCellsManager *viewcells,
480                                                                   KdTree *tree):
481GlRenderer(sceneGraph, viewcells, tree) 
482{
483 
484  mPixelBuffer = NULL;
485 
486  // implement width and height in subclasses
487}
488
489
490void
491GlRendererBuffer::EvalQueryWithOcclusionQueries(
492                                                                           //RenderCostSample &sample
493                                                                           )
494{
495        glDepthFunc(GL_LEQUAL);
496               
497        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
498        glDepthMask(GL_FALSE);
499
500
501        // simulate detectemptyviewspace using backface culling
502        if (mDetectEmptyViewSpace)
503        {
504                glEnable(GL_CULL_FACE);
505                //cout << "culling" << endl;
506        }
507        else
508        {
509                //cout << "not culling" << endl;
510                glDisable(GL_CULL_FACE);
511        }
512
513       
514        //const int numQ = 1;
515        const int numQ = (int)mOcclusionQueries.size();
516       
517        //glFinish();
518#if 0
519        //-- now issue queries for all objects
520        for (int j = 0; j < (int)mObjects.size(); ++ j)
521        {
522                mOcclusionQueries[j]->BeginQuery();
523                RenderIntersectable(mObjects[j]);
524                mOcclusionQueries[j]->EndQuery();
525
526                unsigned int pixelCount;
527
528                pixelCount = mOcclusionQueries[j]->GetQueryResult();
529                mObjects[j]->mCounter += pixelCount;
530        }
531#else
532
533        int q = 0;
534
535        //-- now issue queries for all objects
536        for (int j = 0; j < (int)mObjects.size(); j += q)
537        {       
538                for (q = 0; ((j + q) < (int)mObjects.size()) && (q < numQ); ++ q)
539                {
540                        //glFinish();
541                        mOcclusionQueries[q]->BeginQuery();
542                       
543                        RenderIntersectable(mObjects[j + q]);
544               
545                        mOcclusionQueries[q]->EndQuery();
546                        //glFinish();
547                }
548                //cout << "q: " << q << endl;
549                // collect results of the queries
550                for (int t = 0; t < q; ++ t)
551                {
552                        unsigned int pixelCount;
553               
554                        //-- reenable other state
555#if 0
556                        bool available;
557
558                        do
559                        {
560                                available = mOcclusionQueries[t]->ResultAvailable();
561                               
562                                if (!available) cout << "W";
563                        }
564                        while (!available);
565#endif
566
567                        pixelCount = mOcclusionQueries[t]->GetQueryResult();
568
569                        //if (pixelCount > 0)
570                        //      cout <<"o="<<j+q<<" q="<<mOcclusionQueries[q]->GetQueryId()<<" pc="<<pixelCount<<" ";
571                        mObjects[j + t]->mCounter += pixelCount;
572                }
573
574                //j += q;
575        }
576#endif
577        //glFinish();
578        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
579        glDepthMask(GL_TRUE);
580       
581        glEnable(GL_CULL_FACE);
582}
583
584
585void
586GlRenderer::RandomViewPoint()
587{
588  // do not use this function since it could return different viewpoints for
589  // different executions of the algorithm
590
591  //  mViewCellsManager->GetViewPoint(mViewPoint);
592
593  while (1) {
594        Vector3 pVector = Vector3(halton.GetNumber(1),
595                                                          halton.GetNumber(2),
596                                                          halton.GetNumber(3));
597       
598        mViewPoint =  mViewCellsManager->GetViewSpaceBox().GetPoint(pVector);
599        ViewCell *v = mViewCellsManager->GetViewCell(mViewPoint);
600        if (v && v->GetValid())
601          break;
602        // generate a new vector
603        halton.GenerateNext();
604  }
605 
606  Vector3 dVector = Vector3(2*M_PI*halton.GetNumber(4),
607                                                        M_PI*halton.GetNumber(5),
608                                                        0.0f);
609 
610  mViewDirection = Normalize(Vector3(sin(dVector.x),
611                                                                         //                                                                      cos(dVector.y),
612                                                                         0.0f,
613                                                                         cos(dVector.x)));
614  halton.GenerateNext();
615}
616
617
618void
619GlRenderer::RenderBox(const AxisAlignedBox3 &box)
620{
621
622  glBegin(GL_LINE_LOOP);
623  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
624  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
625  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
626  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
627  glEnd();
628
629  glBegin(GL_LINE_LOOP);
630  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
631  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
632  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
633  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
634  glEnd();
635
636  glBegin(GL_LINE_LOOP);
637  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
638  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
639  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
640  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
641  glEnd();
642
643  glBegin(GL_LINE_LOOP);
644  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
645  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
646  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
647  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
648  glEnd();
649
650  glBegin(GL_LINE_LOOP);
651  glVertex3d(box.Min().x, box.Min().y, box.Min().z );
652  glVertex3d(box.Max().x, box.Min().y, box.Min().z );
653  glVertex3d(box.Max().x, box.Min().y, box.Max().z );
654  glVertex3d(box.Min().x, box.Min().y, box.Max().z );
655  glEnd();
656
657  glBegin(GL_LINE_LOOP);
658  glVertex3d(box.Min().x, box.Max().y, box.Min().z );
659  glVertex3d(box.Max().x, box.Max().y, box.Min().z );
660  glVertex3d(box.Max().x, box.Max().y, box.Max().z );
661  glVertex3d(box.Min().x, box.Max().y, box.Max().z );
662
663  glEnd();
664
665}
666
667void
668GlRenderer::RenderBvhNode(BvhNode *node)
669{
670  if (node->IsLeaf()) {
671        BvhLeaf *leaf = (BvhLeaf *) node;
672
673#if 0
674        if (leaf->mGlList == 0) {
675          leaf->mGlList = glGenLists(1);
676          if (leaf->mGlList != 0)
677                glNewList(leaf->mGlList, GL_COMPILE);
678         
679          for (int i=0; i < leaf->mObjects.size(); i++)
680                RenderIntersectable(leaf->mObjects[i]);
681         
682          if (leaf->mGlList != 0)
683                glEndList();
684        }
685       
686        if (leaf->mGlList != 0)
687          glCallList(leaf->mGlList);
688#else
689        for (int i=0; i < leaf->mObjects.size(); i++)
690          RenderIntersectable(leaf->mObjects[i]);
691#endif
692  } else {
693        BvhInterior *in = (BvhInterior *)node;
694        RenderBvhNode(in->GetBack());
695        RenderBvhNode(in->GetFront());
696  }
697
698  //cout << "leaf obj " << i << endl;
699
700}
701
702void
703GlRenderer::RenderKdNode(KdNode *node)
704{
705  if (node->IsLeaf()) {
706        KdLeaf *leaf = (KdLeaf *) node;
707        for (int i=0; i < leaf->mObjects.size(); i++) {
708          RenderIntersectable(leaf->mObjects[i]);
709        }
710  } else {
711        KdInterior *in = (KdInterior *)node;
712        RenderKdNode(in->mBack);
713        RenderKdNode(in->mFront);
714  }
715 
716}
717
718
719
720
721
722
723
724void
725GlRendererBuffer::EvalRenderCostSample(RenderCostSample &sample,
726                                                                           const bool useOcclusionQueries,
727                                                                           const int threshold
728                                                                           )
729{
730  // choose a random view point
731  mViewCellsManager->GetViewPoint(mViewPoint);
732  sample.mPosition = mViewPoint;
733  //cout << "viewpoint: " << mViewPoint << endl;
734 
735  // take a render cost sample by rendering a cube
736  Vector3 directions[6];
737 
738  directions[0] = Vector3(1,0,0);
739  directions[1] = Vector3(0,1,0);
740  directions[2] = Vector3(0,0,1);
741  directions[3] = Vector3(-1,0,0);
742  directions[4] = Vector3(0,-1,0);
743  directions[5] = Vector3(0,0,-1);
744 
745  sample.mVisibleObjects = 0;
746 
747  // reset object counters
748  ObjectContainer::const_iterator it, it_end = mObjects.end();
749 
750  for (it = mObjects.begin(); it != it_end; ++ it)
751        {
752          (*it)->mCounter = 0;
753        }
754
755  ++ mFrame;
756 
757  //glCullFace(GL_FRONT);
758  glCullFace(GL_BACK);
759  glDisable(GL_CULL_FACE);
760 
761 
762        // query all 6 directions for a full point sample
763  for (int i = 0; i < 6; ++ i)
764        {
765          mViewDirection = directions[i];
766          SetupCamera();
767         
768          glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
769          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
770          //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);    glDepthMask(GL_TRUE);
771          glDepthFunc(GL_LESS);
772         
773          mUseFalseColors = true;
774         
775          // the actual scene rendering fills the depth (for occlusion queries)
776          // and the frame buffer (for item buffer)
777          RenderScene();
778         
779         
780          if (0)
781                {
782                  char filename[256];
783                  sprintf(filename, "snap/frame-%04d-%d.png", mFrame, i);
784                  //              QImage im = toImage();
785                  //              im.save(filename, "PNG");
786                }
787         
788          // evaluate the sample
789          if (useOcclusionQueries)
790                {
791                  EvalQueryWithOcclusionQueries();
792                }
793          else
794                {
795                  EvalQueryWithItemBuffer();
796                }
797        } 
798 
799  // now evaluate the statistics over that sample
800  // currently only the number of visible objects is taken into account
801  sample.Reset();
802 
803  for (it = mObjects.begin(); it != it_end; ++ it)
804        {
805          Intersectable *obj = *it;
806          if (obj->mCounter >= threshold)
807                {
808                  ++ sample.mVisibleObjects;
809                  sample.mVisiblePixels += obj->mCounter;
810                }
811        }
812 
813  //cout << "RS=" << sample.mVisibleObjects << " ";
814}
815
816
817GlRendererBuffer::~GlRendererBuffer()
818{
819#if 0
820#ifdef USE_CG
821        if (sCgFragmentProgram)
822                cgDestroyProgram(sCgFragmentProgram);
823        if (sCgContext)
824                cgDestroyContext(sCgContext);
825#endif
826#endif
827}
828
829
830void
831GlRendererBuffer::SampleRenderCost(const int numSamples,
832                                                                   vector<RenderCostSample> &samples,
833                                                                   const bool useOcclusionQueries,
834                                                                   const int threshold
835                                                                   )
836{
837  MakeCurrent();
838
839  if (mPixelBuffer == NULL)
840          mPixelBuffer = new unsigned int[GetWidth()*GetHeight()];
841 
842  // using 90 degree projection to capture 360 view with 6 samples
843  SetupProjection(GetHeight(), GetHeight(), 90.0f);
844
845  //samples.resize(numSamples);
846  halton.Reset();
847 
848  // the number of queries queried in batch mode
849  const int numQ = 500;
850
851  //const int numQ = (int)mObjects.size();
852  if (useOcclusionQueries)
853  {
854          cout << "\ngenerating " << numQ << " queries ... ";
855          OcclusionQuery::GenQueries(mOcclusionQueries, numQ);
856          cout << "finished" << endl;
857  }
858
859  // sampling queries
860  for (int i = 0; i < numSamples; ++ i)
861  {
862          cout << ".";
863          EvalRenderCostSample(samples[i], useOcclusionQueries, threshold);
864  }
865
866  DoneCurrent();
867}
868 
869
870
871
872
873void
874GlRenderer::ClearErrorBuffer()
875{
876  for (int i=0; i < mPvsStatFrames; i++) {
877        mPvsErrorBuffer[i].mError = 1.0f;
878  }
879}
880
881
882void
883GlRendererBuffer::EvalPvsStat()
884{
885
886  MakeCurrent();
887
888  GlRenderer::EvalPvsStat();
889 
890  DoneCurrent();
891 
892  //  mRenderingFinished.wakeAll();
893}
894
895
896void GlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject,
897                                                                                           Beam &beam,
898                                                                                           const int desiredSamples,
899                                                                                           BeamSampleStatistics &stat)
900{
901        // TODO: should be moved out of here (not to be done every time)
902        // only back faces are interesting for the depth pass
903        glShadeModel(GL_FLAT);
904        glDisable(GL_LIGHTING);
905
906        // needed to kill the fragments for the front buffer
907        glEnable(GL_ALPHA_TEST);
908        glAlphaFunc(GL_GREATER, 0);
909
910        // assumes that the beam is constructed and contains kd-tree nodes
911        // and viewcells which it intersects
912 
913 
914        // Get the number of viewpoints to be sampled
915        // Now it is a sqrt but in general a wiser decision could be made.
916        // The less viewpoints the better for rendering performance, since less passes
917        // over the beam is needed.
918        // The viewpoints could actually be generated outside of the bounding box which
919        // would distribute the 'efective viewpoints' of the object surface and thus
920        // with a few viewpoints better sample the viewpoint space....
921
922        //TODO: comment in
923        //int viewPointSamples = sqrt((float)desiredSamples);
924        int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1);
925       
926        // the number of direction samples per pass is given by the number of viewpoints
927        int directionalSamples = desiredSamples / viewPointSamples;
928       
929        Debug << "directional samples: " << directionalSamples << endl;
930        for (int i = 0; i < viewPointSamples; ++ i)
931        {
932                Vector3 viewPoint = beam.mBox.GetRandomPoint();
933               
934                // perhaps the viewpoint should be shifted back a little bit so that it always lies
935                // inside the source object
936                // 'ideally' the viewpoints would be distributed on the soureObject surface, but this
937        // would require more complicated sampling (perhaps hierarchical rejection sampling of
938                // the object surface is an option here - only the mesh faces which are inside the box
939                // are considered as candidates)
940               
941                SampleViewpointContributions(sourceObject,
942                                                                         viewPoint,
943                                                                         beam,
944                                                                         directionalSamples,
945                                                                         stat);
946        }
947
948
949        // note:
950        // this routine would be called only if the number of desired samples is sufficiently
951        // large - for other rss tree cells the cpu based sampling is perhaps more efficient
952        // distributing the work between cpu and gpu would also allow us to place more sophisticated
953        // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
954        // in order that thios scheme is working well the gpu render buffer should run in a separate
955        // thread than the cpu sampler, which would not be such a big problem....
956
957        // disable alpha test again
958        glDisable(GL_ALPHA_TEST);
959}
960
961
962
963void GlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
964                                                                                                        const Vector3 viewPoint,
965                                                                                                        Beam &beam,
966                                                                                                        const int samples,
967                                                    BeamSampleStatistics &stat)
968{
969    // 1. setup the view port to match the desired samples
970        glViewport(0, 0, samples, samples);
971
972        // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
973        SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
974
975
976        // 3. reset z-buffer to 0 and render the source object for the beam
977        //    with glCullFace(Enabled) and glFrontFace(GL_CW)
978        //    save result to the front depth map
979        //    the front depth map holds ray origins
980
981
982        // front depth buffer must be initialised to 0
983        float clearDepth;
984       
985        glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
986        glClearDepth(0.0f);
987        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
988
989
990        // glFrontFace(GL_CCW);
991        glEnable(GL_CULL_FACE);
992        glCullFace(GL_FRONT);
993        glColorMask(0, 0, 0, 0);
994       
995
996        // stencil is increased where the source object is located
997        glEnable(GL_STENCIL_TEST);     
998        glStencilFunc(GL_ALWAYS, 0x1, 0x1);
999        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1000
1001
1002#if 0
1003        static int glSourceObjList = -1;         
1004        if (glSourceObjList != -1)
1005        {
1006                glSourceObjList = glGenLists(1);
1007                glNewList(glSourceObjList, GL_COMPILE);
1008
1009                RenderIntersectable(sourceObject);
1010       
1011                glEndList();
1012        }
1013        glCallList(glSourceObjList);
1014
1015#else
1016        RenderIntersectable(sourceObject);
1017
1018#endif 
1019
1020         // copy contents of the front depth buffer into depth texture
1021        glBindTexture(GL_TEXTURE_2D, frontDepthMap);   
1022        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
1023
1024        // reset clear function
1025        glClearDepth(clearDepth);
1026       
1027       
1028        // 4. set up the termination depth buffer (= standard depth buffer)
1029        //    only rays which have non-zero entry in the origin buffer are valid since
1030        //    they realy start on the object surface (this is tagged by setting a
1031        //    stencil buffer bit at step 3).
1032       
1033        glStencilFunc(GL_EQUAL, 0x1, 0x1);
1034        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1035
1036        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1037        glDepthMask(1);
1038
1039        glEnable(GL_DEPTH_TEST);
1040               
1041        glEnable(GL_CULL_FACE);
1042        glCullFace(GL_BACK);
1043
1044        // setup front depth buffer
1045        glEnable(GL_TEXTURE_2D);
1046       
1047#if 0
1048#ifdef USE_CG
1049        // bind pixel shader implementing the front depth buffer functionality
1050        cgGLBindProgram(sCgFragmentProgram);
1051        cgGLEnableProfile(sCgFragmentProfile);
1052#endif
1053#endif
1054        // 5. render all objects inside the beam
1055        //    we can use id based false color to read them back for gaining the pvs
1056
1057        glColorMask(1, 1, 1, 1);
1058
1059       
1060        // if objects not stored in beam => extract objects
1061        if (beam.mFlags & !Beam::STORE_OBJECTS)
1062        {
1063                vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
1064
1065                Intersectable::NewMail();
1066                for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
1067                {
1068                        mKdTree->CollectObjects(*it, beam.mObjects);
1069                }
1070        }
1071
1072
1073        //    (objects can be compiled to a gl list now so that subsequent rendering for
1074        //    this beam is fast - the same hold for step 3)
1075        //    Afterwards we have two depth buffers defining the ray origin and termination
1076       
1077
1078#if 0
1079        static int glObjList = -1;
1080        if (glObjList != -1)
1081        {
1082                glObjList = glGenLists(1);
1083                glNewList(glObjList, GL_COMPILE);
1084       
1085                ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
1086                for (it = beam.mObjects.begin(); it != it_end; ++ it)
1087                {
1088                        // render all objects except the source object
1089                        if (*it != sourceObject)
1090                                RenderIntersectable(*it);
1091                }
1092               
1093                glEndList();
1094        }
1095
1096        glCallList(glObjList);
1097#else
1098        ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
1099        for (it = beam.mObjects.begin(); it != it_end; ++ it)
1100        {       
1101                // render all objects except the source object
1102                if (*it != sourceObject)
1103                        RenderIntersectable(*it);
1104        }
1105#endif
1106       
1107        // 6. Use occlusion queries for all viewcell meshes associated with the beam ->
1108        //     a fragment passes if the corresponding stencil fragment is set and its depth is
1109        //     between origin and termination buffer
1110
1111        // create new queries if necessary
1112        OcclusionQuery::GenQueries(mOcclusionQueries, (int)beam.mViewCells.size());
1113
1114        // check whether any backfacing polygon would pass the depth test?
1115        // matt: should check both back /front facing because of dual depth buffer
1116        // and danger of cutting the near plane with front facing polys.
1117       
1118        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1119        glDepthMask(GL_FALSE);
1120        glDisable(GL_CULL_FACE);
1121
1122 
1123        ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
1124
1125        int queryIdx = 0;
1126
1127        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
1128        {
1129                mOcclusionQueries[queryIdx ++]->BeginQuery();
1130
1131                RenderIntersectable(*vit);
1132               
1133                mOcclusionQueries[queryIdx]->EndQuery();
1134
1135                ++ queryIdx;
1136        }
1137
1138        // at this point, if possible, go and do some other computation
1139
1140        // 7. The number of visible pixels is the number of sample rays which see the source
1141        //    object from the corresponding viewcell -> remember these values for later update
1142        //   of the viewcell pvs - or update immediately?
1143
1144        queryIdx = 0;
1145
1146        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
1147        {
1148                // fetch queries
1149                unsigned int pixelCount = mOcclusionQueries[queryIdx ++]->GetQueryResult();
1150
1151                if (pixelCount)
1152                        Debug << "view cell " << (*vit)->GetId() << " visible pixels: " << pixelCount << endl;
1153        }
1154       
1155
1156        // 8. Copmpute rendering statistics
1157        // In general it is not neccessary to remember to extract all the rays cast. I hope it
1158        // would be sufficient to gain only the intergral statistics about the new contributions
1159        // and so the rss tree would actually store no new rays (only the initial ones)
1160        // the subdivision of the tree would only be driven by the statistics (the glrender could
1161        // evaluate the contribution entropy for example)
1162        // However might be an option to extract/store only those the rays which made a contribution
1163        // (new viewcell has been discovered) or relative contribution greater than a threshold ...
1164
1165        ObjectContainer pvsObj;
1166        stat.pvsSize = ComputePvs(beam.mObjects, pvsObj);
1167       
1168        // to gain ray source and termination
1169        // copy contents of ray termination buffer into depth texture
1170        // and compare with ray source buffer
1171#if 0
1172        VssRayContainer rays;
1173
1174        glBindTexture(GL_TEXTURE_2D, backDepthMap);     
1175        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
1176
1177        ComputeRays(Intersectable *sourceObj, rays);
1178
1179#endif
1180
1181        ////////
1182        //-- cleanup
1183
1184        // reset gl state
1185        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1186        glDepthMask(GL_TRUE);
1187        glEnable(GL_CULL_FACE);
1188        glDisable(GL_STENCIL_TEST);
1189
1190#if 0
1191#ifdef USE_CG
1192        cgGLDisableProfile(sCgFragmentProfile);
1193#endif
1194#endif
1195
1196        glDisable(GL_TEXTURE_2D);
1197
1198        // remove objects from beam
1199        if (beam.mFlags & !Beam::STORE_OBJECTS)
1200                beam.mObjects.clear();
1201}
1202
1203
1204void GlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint,
1205                                                                                                   const Beam &beam,
1206                                                                                                   Intersectable *sourceObject)
1207{
1208        float left, right, bottom, top, znear, zfar;
1209
1210        beam.ComputePerspectiveFrustum(left, right, bottom, top, znear, zfar,
1211                                                                   mSceneGraph->GetBox());
1212
1213        //Debug << left << " " << right << " " << bottom << " " << top << " " << znear << " " << zfar << endl;
1214        glMatrixMode(GL_PROJECTION);
1215        glLoadIdentity();
1216        glFrustum(left, right, bottom, top, znear, zfar);
1217        //glFrustum(-1, 1, -1, 1, 1, 20000);
1218
1219    const Vector3 center = viewPoint + beam.GetMainDirection() * (zfar - znear) * 0.3f;
1220        const Vector3 up =
1221                Normalize(CrossProd(beam.mPlanes[0].mNormal, beam.mPlanes[4].mNormal));
1222
1223#ifdef GTP_DEBUG
1224        Debug << "view point: " << viewPoint << endl;
1225        Debug << "eye: " << center << endl;
1226        Debug << "up: " << up << endl;
1227#endif
1228
1229        glMatrixMode(GL_MODELVIEW);
1230        glLoadIdentity();
1231        gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,
1232                          center.x, center.y, center.z,                   
1233                          up.x, up.y, up.z);
1234}               
1235
1236 
1237void GlRendererBuffer::InitGL()
1238{
1239        MakeCurrent();
1240        GlRenderer::InitGL();
1241
1242        // initialise dual depth buffer textures
1243        glGenTextures(1, &frontDepthMap);
1244        glBindTexture(GL_TEXTURE_2D, frontDepthMap);
1245       
1246        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
1247                                 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
1248
1249        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1250        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1251        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1252        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1253
1254        glGenTextures(1, &backDepthMap);
1255        glBindTexture(GL_TEXTURE_2D, backDepthMap);
1256       
1257        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
1258                                 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
1259        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1260        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1261        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1262        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1263
1264#if 0
1265#ifdef USE_CG
1266
1267        // cg initialization
1268        cgSetErrorCallback(handleCgError);
1269        sCgContext = cgCreateContext();
1270       
1271        if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
1272                sCgFragmentProfile = CG_PROFILE_ARBFP1;
1273        else
1274        {
1275          // try FP30
1276          if (cgGLIsProfileSupported(CG_PROFILE_FP30))
1277            sCgFragmentProfile = CG_PROFILE_FP30;
1278          else
1279          {
1280                  Debug << "Neither arbfp1 or fp30 fragment profiles supported on this system" << endl;
1281                  exit(1);
1282          }
1283  }
1284
1285 sCgFragmentProgram = cgCreateProgramFromFile(sCgContext,
1286                                                                                           CG_SOURCE, "../src/dual_depth.cg",
1287                                                                                           sCgFragmentProfile,
1288                                                                                           NULL,
1289                                                                                           NULL);
1290
1291  if (!cgIsProgramCompiled(sCgFragmentProgram))
1292          cgCompileProgram(sCgFragmentProgram);
1293
1294  cgGLLoadProgram(sCgFragmentProgram);
1295  cgGLBindProgram(sCgFragmentProgram);
1296
1297  Debug << "---- PROGRAM BEGIN ----\n" <<
1298          cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n";
1299
1300#endif
1301
1302#endif
1303  DoneCurrent();
1304}
1305
1306
1307void GlRendererBuffer::ComputeRays(Intersectable *sourceObj, VssRayContainer &rays)
1308{
1309        for (int i = 0; i < depthMapSize * depthMapSize; ++ i)
1310        {
1311                //todo glGetTexImage()
1312        }
1313}
1314
1315
1316void
1317GlRenderer::EvalPvsStat()
1318{
1319
1320  mPvsStat.Reset();
1321  halton.Reset();
1322
1323
1324  SetupProjection(GetWidth(), GetHeight());
1325
1326  cout<<"mPvsStatFrames="<<mPvsStatFrames<<endl;
1327 
1328  for (int i=0; i < mPvsStatFrames; i++) {
1329        float err;
1330        // set frame id for saving the error buffer
1331        mFrame = i;
1332        RandomViewPoint();
1333
1334        // atlanta problematic frames: 325 525 691 1543
1335#if 0
1336        if (mFrame != 325 &&
1337                mFrame != 525 &&
1338                mFrame != 691 &&
1339                mFrame != 1543)
1340          mPvsErrorBuffer[i] = -1;
1341        else {
1342          Debug<<"frame ="<<mFrame<<" vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
1343        }
1344#endif
1345       
1346        if (mPvsErrorBuffer[i].mError > 0.0f) {
1347          int pvsSize;
1348
1349
1350          float error = GetPixelError(pvsSize);
1351          mPvsErrorBuffer[i].mError = error;
1352          mPvsErrorBuffer[i].mPvsSize = pvsSize;
1353
1354          //      emit UpdatePvsErrorItem(i,
1355          //                                                      mPvsErrorBuffer[i]);
1356
1357          cout<<"("<<i<<","<<mPvsErrorBuffer[i].mError<<")";
1358          //      swapBuffers();
1359        }
1360       
1361        err = mPvsErrorBuffer[i].mError;
1362       
1363        if (err >= 0.0f) {
1364          if (err > mPvsStat.maxError)
1365                mPvsStat.maxError = err;
1366          mPvsStat.sumError += err;
1367          mPvsStat.sumPvsSize += mPvsErrorBuffer[i].mPvsSize;
1368         
1369          if (err == 0.0f)
1370                mPvsStat.errorFreeFrames++;
1371          mPvsStat.frames++;
1372        }
1373  }
1374
1375  glFinish();
1376  cout<<endl<<flush;
1377
1378}
1379
1380
1381float
1382GlRenderer::GetPixelError(int &pvsSize)
1383{
1384  float pErrorPixels = -1.0f;
1385 
1386  glReadBuffer(GL_BACK);
1387 
1388  //  mUseFalseColors = true;
1389 
1390  mUseFalseColors = false;
1391  unsigned int pixelCount;
1392
1393  //static int query = -1;
1394  //if (query == -1)
1395  //      glGenOcclusionQueriesNV(1, (unsigned int *)&query);
1396
1397  OcclusionQuery query;
1398
1399  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
1400  if (viewcell == NULL)
1401        return 0.0f;
1402
1403  if (mDetectEmptyViewSpace) {
1404        // now check whether any backfacing polygon would pass the depth test
1405        SetupCamera();
1406        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1407        glEnable( GL_CULL_FACE );
1408        glCullFace(GL_BACK);
1409
1410        cout<<"RS ";
1411        RenderScene();
1412       
1413        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1414        glDepthMask(GL_FALSE);
1415        glDisable( GL_CULL_FACE );
1416
1417        query.BeginQuery();
1418       
1419        cout<<"RS ";
1420        RenderScene();
1421        cout<<"RS3 ";
1422       
1423        query.EndQuery();
1424       
1425        // at this point, if possible, go and do some other computation
1426        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1427        glDepthMask(GL_TRUE);
1428        glEnable( GL_CULL_FACE );
1429       
1430        // reenable other state
1431        pixelCount = query.GetQueryResult();
1432        cout<<"RS4 ";
1433       
1434        if (pixelCount > 0)
1435          return -1.0f; // backfacing polygon found -> not a valid viewspace sample
1436
1437  } else
1438        glDisable( GL_CULL_FACE );
1439       
1440
1441  //  ViewCell *viewcell = NULL;
1442 
1443  //  PrVs prvs;
1444 
1445  //  mViewCellsManager->SetMaxFilterSize(0);
1446  //  mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth());
1447  //  viewcell = prvs.mViewCell;
1448 
1449  ObjectPvs pvs;
1450  if (1) {
1451        pvs = viewcell->GetPvs();
1452  } else {
1453        mViewCellsManager->ApplyFilter2(viewcell,
1454                                                                        false,
1455                                                                        1.0f,
1456                                                                        pvs);
1457  }
1458 
1459  SetupCamera();
1460  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1461  glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
1462 
1463 
1464  //    // Render PVS
1465  ObjectPvsIterator it = pvs.GetIterator();
1466 
1467  pvsSize = pvs.GetSize();
1468  Intersectable::NewMail();
1469  for (; it.HasMoreEntries(); ) {
1470        ObjectPvsEntry entry = it.Next();
1471        Intersectable *object = entry.mObject;
1472        RenderIntersectable(object);
1473  }
1474 
1475  //    glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
1476  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1477 
1478  mUseFalseColors = true;
1479 
1480  query.BeginQuery();
1481 
1482  SetupCamera();
1483 
1484  RenderScene();
1485 
1486  query.EndQuery();
1487 
1488 
1489  // reenable other state
1490  pixelCount = query.GetQueryResult();
1491 
1492 
1493  pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight());
1494
1495#if 0 
1496  if (mSnapErrorFrames && pErrorPixels > 0.001f) {
1497       
1498        char filename[256];
1499        sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
1500        QImage im = toImage();
1501        string str = mSnapPrefix + filename;
1502        QString qstr(str.c_str());
1503       
1504        im.save(qstr, "PNG");
1505        if (1) { //0 && mFrame == 1543) {
1506          int x,y;
1507          int lastIndex = -1;
1508          for (y=0; y < im.height(); y++)
1509                for (x=0; x < im.width(); x++) {
1510                  QRgb p = im.pixel(x,y);
1511                  int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
1512                  if (qGreen(p) != 255 && index!=0) {
1513                        if (index != lastIndex) {
1514                          //                            Debug<<"ei="<<index<<" ";
1515                          lastIndex = index;
1516                        }
1517                  }
1518                }
1519        }
1520       
1521       
1522        mUseFalseColors = false;
1523        glPushAttrib(GL_CURRENT_BIT);
1524        glColor3f(0,1,0);
1525        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1526        SetupCamera();
1527        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1528       
1529        // Render PVS
1530        Intersectable::NewMail();
1531
1532        ObjectPvsIterator it = pvs.GetIterator();
1533        for (; it.HasMoreEntries(); ) {
1534          ObjectPvsEntry entry = it.Next();
1535          Intersectable *object = entry.mObject;
1536          RenderIntersectable(object);
1537        }
1538       
1539        im = toImage();
1540        sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
1541        str = mSnapPrefix + filename;
1542        qstr = str.c_str();
1543        im.save(qstr, "PNG");
1544        glPopAttrib();
1545  }
1546#endif
1547 
1548  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1549 
1550  return pErrorPixels;
1551}
1552
1553void
1554GlRenderer::RenderViewPoint()
1555{
1556  mWireFrame = true;
1557  glPushMatrix();
1558  glTranslatef(mViewPoint.x, mViewPoint.y, mViewPoint.z);
1559  glScalef(5.0f,5.0f,5.0f);
1560  glPushAttrib(GL_CURRENT_BIT);
1561  glColor3f(1.0f, 0.0f, 0.0f);
1562  gluSphere((::GLUquadric *)mSphere,
1563                        1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6);
1564  glPopAttrib();
1565  glPopMatrix();
1566  mWireFrame = false;
1567}
1568
1569
1570
1571
1572}
Note: See TracBrowser for help on using the repository browser.