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

Revision 2588, 41.4 KB checked in by bittner, 16 years ago (diff)

sceneBox bugfix

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