source: GTP/trunk/Lib/Vis/Preprocessing/src/CHCRenderer.cpp @ 2613

Revision 2613, 40.5 KB checked in by bittner, 17 years ago (diff)

evaluation of pvs error still does not work

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