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

Revision 1935, 37.7 KB checked in by mattausch, 18 years ago (diff)

started depth peeling

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