source: GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlRenderer.cpp @ 2627

Revision 2627, 59.2 KB checked in by bittner, 16 years ago (diff)

commit before merge with vlastimil

Line 
1#include "glInterface.h"
2#include "QtGlRenderer.h"
3#include "Mesh.h"
4#include "OcclusionQuery.h"
5#include "ViewCellsManager.h"
6#include "SceneGraph.h"
7#include "Pvs.h"
8#include "Viewcell.h"
9#include "Beam.h"
10#include "KdTree.h"
11#include "Environment.h"
12#include "RssPreprocessor.h"
13#include "RssTree.h"
14#include "Trackball.h"
15#include "QtPreprocessorThread.h"
16#include "Material.h"
17#include "IntersectableWrapper.h"
18#include "LogWriter.h"
19
20
21#define USE_CG 1
22
23#define TEST_PVS_RENDERING 0
24
25#if USE_CG
26#include <Cg/cg.h>
27#include <Cg/cgGL.h>
28#endif
29
30#include <QVBoxLayout>
31
32namespace GtpVisibilityPreprocessor {
33
34
35 
36class ViewCellsManager;
37
38static CGcontext sCgContext = NULL;
39static CGprogram sCgFragmentProgram = NULL;
40static CGprofile sCgFragmentProfile;
41
42
43//static vector<OcclusionQuery *> sQueries;
44
45QtGlRendererWidget *rendererWidget = NULL;
46QtGlDebuggerWidget *debuggerWidget = NULL;
47
48const static int SAMPLES_INCR = 2000000;
49
50
51
52static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
53{
54        return obj1->mId < obj2->mId;
55}
56
57
58inline static bool nearerThan(ViewCell *vc1, ViewCell *vc2)
59{
60        return vc1->GetDistance() > vc2->GetDistance();
61}
62
63
64#if USE_CG
65static void handleCgError()
66{
67    Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl;
68    exit(1);
69}
70#endif
71
72void
73QtGlRendererBuffer::MakeCurrent()
74{
75  makeCurrent();
76}
77
78void
79QtGlRendererBuffer::DoneCurrent()
80{
81  doneCurrent();
82}
83 
84
85QtGlRendererBuffer::QtGlRendererBuffer(const int w,
86                                                                           const int h,
87                                                                           SceneGraph *sceneGraph,
88                                                                           ViewCellsManager *viewcells,
89                                                                           KdTree *tree):
90  QGLPixelBuffer(QSize(w, h)),
91  GlRendererBuffer(sceneGraph, viewcells, tree)
92{
93  mUseVbos = true;
94  MakeCurrent();
95  InitGL();
96  DoneCurrent();
97}
98
99void
100QtGlRendererBuffer::RenderPvs(const ObjectPvs &pvs)
101{
102#if TEST_PVS_RENDERING
103
104  // Render PVS
105  ObjectPvsIterator it = pvs.GetIterator();
106 
107  Intersectable::NewMail();
108  mCurrentFrame++;
109  while (it.HasMoreEntries())
110        {
111          RenderIntersectable(it.Next());
112        }
113
114#else
115 
116  PreparePvs(pvs);
117
118  int offset = (int)mObjects.size() * 3;
119  char *arrayPtr = mUseVbos ? NULL : (char *)mData;
120
121  glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
122  glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
123  glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
124 
125#endif
126}
127
128// reimplemented here so that we can snap the error windows
129float
130QtGlRendererBuffer::GetPixelError(int &pvsSize)
131{
132
133  MakeCurrent();
134
135  float pErrorPixels = -1.0f;
136
137
138        mUseFalseColors = false;
139        unsigned int pixelCount;
140
141
142        ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
143        if (viewcell == NULL)
144                return 0.0f;
145
146        ObjectPvs pvs;
147
148        bool evaluateFilter;
149        Environment::GetSingleton()->GetBoolValue("Preprocessor.evaluateFilter", evaluateFilter);
150
151        if (!evaluateFilter)
152                pvs = viewcell->GetPvs();
153        else
154          mViewCellsManager->ApplyFilter2(viewcell,
155                                                                          false,
156                                                                          mViewCellsManager->GetFilterWidth(),
157                                                                          pvs);
158
159        mUseForcedColors = true;
160
161        SetupCamera();
162        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
163        glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
164        glColor3f(0,1,0);
165
166
167        glStencilFunc(GL_EQUAL, 0x0, 0x1);
168        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
169
170
171        pvsSize = pvs.GetSize();
172        cout<<pvsSize<<endl;
173       
174        RenderPvs(pvs);
175       
176        //glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
177        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
178        glEnable(GL_STENCIL_TEST);
179        glColor3f(1,0,0);
180
181       
182        OcclusionQuery *query = mOcclusionQueries[0];
183
184        //      SetupCamera();
185
186        Intersectable::NewMail();
187
188        query->BeginQuery();
189
190        RenderScene();
191       
192        query->EndQuery();
193        glDisable(GL_STENCIL_TEST);
194
195        // reenable other state
196        //  int wait=0;
197        //  while (!query.ResultAvailable()) {
198        //      wait++;
199        //  }
200       
201
202        pixelCount = query->GetQueryResult();
203        //      cout<<"pc="<<pixelCount<<endl;
204       
205        pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight());
206
207
208        if (mSnapErrorFrames && (pErrorPixels >= 0.01f)) {
209          glReadBuffer(GL_BACK);
210          //glReadBuffer(GL_FRONT);
211         
212          char filename[256];
213          sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
214          QImage im = toImage();
215          string str = mSnapPrefix + filename;
216          QString qstr(str.c_str());
217         
218          im.save(qstr, "PNG");
219          if (0) { //0 && mFrame == 1543) {
220                int x,y;
221                int lastIndex = -1;
222                for (y=0; y < im.height(); y++)
223                  for (x=0; x < im.width(); x++) {
224                        QRgb p = im.pixel(x,y);
225                        int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
226                        if (qGreen(p) != 255 && index!=0) {
227                          if (index != lastIndex) {
228                                //                              Debug<<"ei="<<index<<" ";
229                                lastIndex = index;
230                          }
231                        }
232                  }
233          }
234         
235          mUseFalseColors = false;
236          glPushAttrib(GL_CURRENT_BIT);
237          glColor3f(0,1,0);
238          glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
239          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
240         
241          RenderPvs(pvs);
242
243          mUseForcedColors = false;
244          im = toImage();
245          sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
246          str = mSnapPrefix + filename;
247          qstr = str.c_str();
248          im.save(qstr, "PNG");
249          glPopAttrib();
250        }
251       
252        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
253
254        DoneCurrent();
255
256        return pErrorPixels;
257}
258
259int
260QtGlRendererBuffer::ComputePvs(ObjectContainer &objects,
261                                                           ObjectContainer &pvs) const
262{
263        int pvsSize = 0;
264        QImage image = toImage();
265        Intersectable::NewMail();
266
267        std::stable_sort(objects.begin(), objects.end(), ilt);
268
269        MeshInstance dummy(NULL);
270
271        Intersectable *obj = NULL;
272
273        for (int x = 0; x < image.width(); ++ x)
274        {
275                for (int y = 0; y < image.height(); ++ y)
276                {
277                        QRgb pix = image.pixel(x, y);
278                        const int id = GetId(qRed(pix), qGreen(pix), qBlue(pix));
279
280                        dummy.SetId(id);
281
282                        ObjectContainer::iterator oit =
283                                lower_bound(objects.begin(), objects.end(), &dummy, ilt);
284
285
286                        if (//(oit != oit.end()) &&
287                                ((*oit)->GetId() == id) &&
288                                !obj->Mailed())
289                        {
290                                obj = *oit;
291                                obj->Mail();
292                                ++ pvsSize;
293                                pvs.push_back(obj);
294                        }
295                }
296        }
297
298        return pvsSize;
299}
300
301
302void QtGlRendererWidget::InitGL()
303{
304        GlRenderer::InitGL();
305
306        GLfloat mat_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
307       
308        // mat_specular and mat_shininess are NOT default values
309        GLfloat mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
310        GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
311        GLfloat mat_shininess[] = {1.0f};
312
313        GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
314        GLfloat light_diffuse[] = {0.4f, 0.4f, 0.4f, 1.0f};
315        GLfloat light_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
316
317        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
318
319
320        // default Material
321        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
322        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
323        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
324        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
325
326        // a light
327        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
328        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
329        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
330
331        glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
332        glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
333        glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
334
335        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
336
337        glEnable(GL_LIGHTING);
338        glEnable(GL_LIGHT0);
339        glEnable(GL_LIGHT1);
340
341        // set position of the light
342        GLfloat infinite_light[] = {  1.0, 0.8, 1.0, 0.0  };
343        glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
344
345        // set position of the light2
346        GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
347        glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
348
349        glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
350        // glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR);
351        glEnable(GL_COLOR_MATERIAL);
352
353        glShadeModel(GL_FLAT);
354}
355
356
357void
358QtGlRendererWidget::SetupCameraProjection(const int w, const int h, const float angle)
359{
360        if (!mTopView) {
361                int ww = w;
362                int hh = h;
363                glViewport(0, 0, ww, hh);
364                glMatrixMode(GL_PROJECTION);
365                glLoadIdentity();
366                gluPerspective(angle, ww/(float)hh, 0.1, 2.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
367                glMatrixMode(GL_MODELVIEW);
368        } else {
369                int ww = w;
370                int hh = h;
371                glViewport(0, 0, ww, hh);
372                glMatrixMode(GL_PROJECTION);
373                glLoadIdentity();
374                gluPerspective(50.0, ww / (float)hh, 0.1, 20.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
375                glMatrixMode(GL_MODELVIEW);
376        }
377}
378
379
380bool QtGlRendererWidget::PvsChanged(ViewCell *viewCell) const
381{
382        if (viewCell != mPvsCache.mViewCell)
383                return true;
384
385        if (viewCell->GetPvs().GetSize() != mPvsCache.mUnfilteredPvsSize)
386                return true;
387
388        return false;
389}
390
391
392void QtGlRendererWidget::_RenderPvs()
393{
394
395#if TEST_PVS_RENDERING
396 
397  ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
398
399  int pvsSize = mPvsCache.mPvs.GetSize();
400
401  Intersectable::NewMail();
402  mCurrentFrame++;
403  while (it.HasMoreEntries())
404        {
405          RenderIntersectable(it.Next());
406        }
407
408 
409  return;
410#endif
411 
412  mUseFalseColors = false;
413
414        int offset = (int)mObjects.size() * 3;
415        char *arrayPtr = mUseVbos ? NULL : (char *)mData;
416
417        glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
418        glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
419        glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
420#if DYNAMIC_OBJECTS_HACK
421        // handle dynamic objects
422        DynamicObjectsContainer::const_iterator dit, dit_end = mDynamicObjects.end();
423
424
425        for (dit = mDynamicObjects.begin(); dit != dit_end; ++ dit)
426        {
427#if USE_TRANSFORMED_MESH_INSTANCE_HACK
428                //cerr << "here45\n****"<<endl;
429                RenderIntersectable(*dit);
430#else
431                _RenderDynamicObject(*dit);
432#endif
433        }
434#endif
435}
436
437
438void QtGlRendererWidget::PreparePvs()
439{
440        int indexBufferSize = 0;
441       
442        KdNode::NewMail();
443        //Intersectable::NewMail();
444
445        mPvsSize = mPvsCache.mPvs.GetSize();
446#if DYNAMIC_OBJECTS_HACK
447        mDynamicObjects.clear();
448#endif
449        ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
450
451        while (it.HasMoreEntries())
452        {
453                Intersectable *obj = it.Next();
454                switch (obj->Type())
455                {
456                case Intersectable::KD_INTERSECTABLE:
457                        {
458                                KdNode *node = static_cast<KdIntersectable *>(obj)->GetItem();
459                                _UpdatePvsIndices(node, indexBufferSize);
460                        }
461                        break;
462#if DYNAMIC_OBJECTS_HACK
463#if USE_TRANSFORMED_MESH_INSTANCE_HACK
464
465                case Intersectable::TRANSFORMED_MESH_INSTANCE:
466                        mDynamicObjects.push_back(static_cast<TransformedMeshInstance *>(obj));
467                        break;
468
469#else
470                case Intersectable::SCENEGRAPHLEAF_INTERSECTABLE:
471                        mDynamicObjects.push_back(static_cast<SceneGraphLeafIntersectable *>(obj)->GetItem());
472                        break;
473#endif
474#endif
475                default:
476                        cerr << "PreparePvs: type " << Intersectable::GetTypeName(obj) << " not handled yet" << endl;
477                }
478        }
479
480        mIndexBufferSize = indexBufferSize;
481}
482
483
484
485
486void QtGlRendererWidget::RenderPvs()
487{
488        if (mUseVbos)
489                glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId);
490
491        ++ mCurrentFrame;
492
493        EnableDrawArrays();
494
495        //Intersectable::NewMail();
496       
497        if (mDetectEmptyViewSpace)
498                glEnable(GL_CULL_FACE);
499        else
500                glDisable(GL_CULL_FACE);
501
502        ViewCell *viewcell = NULL;
503        viewcell = mViewCellsManager->GetViewCell(mViewPoint, true);
504
505        if (viewcell)
506        {
507                // copy the pvs so that it can be filtered ...
508                if (PvsChanged(viewcell))
509                {
510                        mPvsCache.Reset();
511                        mPvsCache.mViewCell = viewcell;
512                        mPvsCache.mUnfilteredPvsSize = viewcell->GetPvs().GetSize();
513
514                        if (mUseSpatialFilter)
515                        {
516                                //mMutex.lock();
517                                // mSpatialFilter size is in range 0.001 - 0.1
518                                mViewCellsManager->ApplyFilter2(viewcell,
519                                                                    mUseFilter,
520                                                                    100.0f * mSpatialFilterSize,
521                                                                    //pvs,
522                                                                                                mPvsCache.mPvs,         
523                                                                    &mPvsCache.filteredBoxes);
524                                //mPvsCache.mPvs = pvs;
525                                //mMutex.unlock();
526                                cout << "pvs size: " << mPvsCache.mPvs.GetSize() << endl;
527                        }
528                        else
529                        {
530                                mPvsCache.mPvs = viewcell->GetPvs();
531                        }
532
533                        /// update the indices for rendering
534                        PreparePvs();
535
536                        emit PvsUpdated();
537                }
538
539
540                // Render PVS
541                if (mUseSpatialFilter && mRenderBoxes)
542                {
543                        for (int i=0; i < mPvsCache.filteredBoxes.size(); ++ i)
544                        {
545                                RenderBox(mPvsCache.filteredBoxes[i]);
546                        }
547                }
548                else
549                {
550                        if (!mRenderVisibilityEstimates && !mUseRandomColorPerPvsObject)
551                                _RenderPvs();
552                        else
553                                _RenderColoredPvs();
554                }
555
556                if (mRenderFilter)
557                {
558                        mWireFrame = true;
559                        RenderIntersectable(viewcell);
560                       
561                        /*glPushMatrix();
562                        glTranslatef(mViewPoint.x, mViewPoint.y, mViewPoint.z);
563                        glScalef(5.0f,5.0f,5.0f);
564                        glPushAttrib(GL_CURRENT_BIT);
565                        glColor3f(1.0f, 0.0f, 0.0f);
566                        //        gluSphere((::GLUquadric *)mSphere,
567                        //                              1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6);
568                        glPopAttrib();
569                        glPopMatrix();
570                        */
571                        mWireFrame = false;
572                }
573        }
574        else
575        {
576                //ObjectContainer::const_iterator oi = mObjects.begin();
577                //for (; oi != mObjects.end(); oi++)
578                //      RenderIntersectable(*oi);
579                RenderScene();
580        }
581}
582
583float
584QtGlRendererWidget::RenderErrors()
585{
586        float pErrorPixels = -1.0f;
587
588        SetupCamera();
589        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
590
591        glPushAttrib(GL_ENABLE_BIT);
592
593        glStencilFunc(GL_EQUAL, 0x0, 0x1);
594        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
595
596        mUseForcedColors = true;
597
598        glColor3f(0.0f, 0.8f, 0.2f);
599
600        // Render PVS
601        RenderPvs();
602
603        glEnable(GL_STENCIL_TEST);
604
605        //mUseFalseColors = true;
606
607        glDisable(GL_LIGHTING);
608
609        OcclusionQuery *query = mOcclusionQueries[0];
610        query->BeginQuery();
611
612        SetupCamera();
613
614        glColor3f(1.0f, 0.0f, 0.0f);
615
616        RenderScene();
617
618        mUseForcedColors = false;
619
620        query->EndQuery();
621
622        glDisable(GL_STENCIL_TEST);
623        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
624
625        glPopAttrib();
626
627        // reenable other state
628        //  int wait=0;
629        //  while (!query.ResultAvailable()) {
630        //      wait++;
631        //  }
632
633        int pixelCount = query->GetQueryResult();
634        pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight());
635        if (0) cout<<"error pixels="<<pixelCount<<endl;
636
637        mRenderError = pErrorPixels;
638
639        return pErrorPixels;
640}
641
642
643void QtGlRendererWidget::timerEvent(QTimerEvent *event)
644{
645        //std::cout << "Timer ID:" << event->timerId();
646        update();
647}
648
649
650void QtGlRendererWidget::mousePressEvent(QMouseEvent *e)
651{
652        int x = e->pos().x();
653        int y = e->pos().y();
654
655        mousePoint.x = x;
656        mousePoint.y = y;
657
658}
659
660void
661QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e)
662{
663        float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
664        float TURN_SENSITIVITY = 0.1f;
665        float TILT_SENSITIVITY = 32.0 ;
666        float TURN_ANGLE= M_PI  /36.0 ;
667
668        int x = e->pos().x();
669        int y = e->pos().y();
670
671        int diffx = -(mousePoint.x - x);
672        int diffy = -(mousePoint.y - y);
673
674        const float t = 1.0f;
675
676        if (e->modifiers() & Qt::ControlModifier)
677        {
678                mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY / 2.0;
679                mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY / 2.0;
680        }
681#if DYNAMIC_OBJECTS_HACK
682        else if (e->modifiers() & Qt::AltModifier)
683        {
684                if (mCurrentDynamicObjectIdx >= 0)
685                {
686                        Matrix4x4 tm;
687
688                        switch (mTrafoType)
689                        {
690                        case 0:
691                                {
692                                        const Vector3 transl(diffx, 0, diffy);
693                                       
694                                        tm = TranslationMatrix(transl);
695                                }
696                                break;
697                        case 1:
698                                {
699                                        float scalef = 1.0f + 0.01f * (diffx + diffy);
700                                        if (scalef < 0.9) scalef = 0.9f;
701                                        else if (scalef > 1.1f) scalef = 1.1f;
702                                        tm = ScaleMatrix(scalef, scalef, scalef);
703                                }
704                                break;
705                        case 2:
706                                {
707                                        tm = RotationXMatrix(diffx) * RotationYMatrix(diffy);
708                                }
709                                break;
710                        default:
711                                cerr << "not implemented" << endl;
712                        }
713
714#if USE_TRANSFORMED_MESH_INSTANCE_HACK
715                        TransformedMeshInstance *tmi = mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
716                        tmi->ApplyWorldTransform(tm);
717#else
718                        SceneGraphLeaf *l = mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
719                        l->ApplyTransform(tm);
720#endif
721                        updateGL();
722                }
723        }
724#endif
725        else
726        {
727                mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
728                float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
729                float angle = atan2(mViewDirection.x, mViewDirection.z);
730                mViewDirection.x = sin(angle + adiff);
731                mViewDirection.z = cos(angle + adiff);
732        }
733
734        mousePoint.x = x;
735        mousePoint.y = y;
736
737        updateGL();
738}
739
740void
741QtGlRendererWidget::mouseReleaseEvent(QMouseEvent *)
742{
743}
744
745void
746QtGlRendererWidget::resizeGL(int w, int h)
747{
748        SetupCameraProjection(w, h);
749        updateGL();
750}
751
752void
753QtGlRendererWidget::paintGL()
754{
755        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
756
757        if (1)
758        {
759                SetupCameraProjection(width(), height());
760                SetupCamera();
761
762                if (mRenderErrors)
763                {
764                        RenderErrors();
765                }
766                else
767                {
768                        glColor3f(0.6f, 0.6f, 0.6f);
769                        RenderPvs();
770                }
771
772                if (1 && mShowRays)
773                {
774                        RenderRays(mViewCellsManager->mVizBuffer.GetRays(), mRayVisualizationMethod, mShowDistribution, 1);
775                }
776        }
777
778        RenderInfo();
779        mFrame ++;
780}
781
782
783void
784QtGlRendererWidget::SetupCamera()
785{
786        if (!mTopView)
787                GlRenderer::SetupCamera();
788        else
789        {
790                if (0)
791                {
792                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
793                        Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
794                                -1,
795                                mViewDirection.y);
796
797                        Vector3 target = mViewPoint + dist*mViewDirection;
798                        Vector3 up(0,1,0);
799
800                        glLoadIdentity();
801                        gluLookAt(pos.x, pos.y, pos.z,
802                                target.x, target.y, target.z,
803                                up.x, up.y, up.z);
804                }
805                else
806                {
807                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal()) * mTopDistance;
808                        Vector3 pos = mViewPoint  + dist * Vector3(0,   1, 0);
809
810                        Vector3 target = mViewPoint;
811                        Vector3 up(mViewDirection.x, 0, mViewDirection.z);
812
813                        glLoadIdentity();
814                        gluLookAt(pos.x, pos.y, pos.z,
815                                target.x, target.y, target.z,
816                                up.x, up.y, up.z);
817
818                }
819        }
820
821}
822
823
824void
825QtGlRendererWidget::keyPressEvent ( QKeyEvent * e )
826{
827        switch (e->key())
828        {
829case Qt::Key_E:
830        mRenderErrors = !mRenderErrors;
831        updateGL();
832        break;
833case Qt::Key_R:
834        mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject;;
835        updateGL();
836        break;
837case Qt::Key_T:
838        mTopView = !mTopView;
839        SetupCameraProjection(width(), height());
840        updateGL();
841        break;
842case Qt::Key_V:
843        mRenderViewCells = !mRenderViewCells;
844        updateGL();
845        break;
846case Qt::Key_P:
847        // set random viewpoint
848        mViewCellsManager->GetViewPoint(mViewPoint);
849        updateGL();
850        break;
851case Qt::Key_S: {
852        // set view poitn and direction
853        QString text;
854        bool ok;
855        text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z);
856        text = QInputDialog::getText(this,
857                "Enter a view point",
858                "",
859                QLineEdit::Normal,
860                text,
861                &ok);
862        if (!ok)
863                break;
864
865        if (sscanf(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) {
866                text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z);
867                text = QInputDialog::getText(this,
868                        "Enter a direction",
869                        "",
870                        QLineEdit::Normal,
871                        text,
872                        &ok);
873                if (!ok)
874                        break;
875                if (sscanf(text.toAscii(), "%f %f %f", &mViewDirection.x,
876                        &mViewDirection.y, &mViewDirection.z) == 3) {
877                                updateGL();
878                        }
879                        break;
880        }
881                                }
882default:
883        cerr << "unknown key" << endl;
884        e->ignore();
885        break;
886        }
887}
888
889
890
891QtGlRendererWidget::QtGlRendererWidget(
892                                                                           SceneGraph *sceneGraph,
893                                                                           ViewCellsManager *viewcells,
894                                                                           KdTree *tree,
895                                                                           QWidget * parent,
896                                                                           const QGLWidget * shareWidget,
897                                                                           Qt::WFlags f
898                                                                           )
899                                                                           :
900GlRendererWidget(sceneGraph, viewcells, tree), QGLWidget(parent, shareWidget, f)
901{
902        mPreprocessorThread = NULL;
903        mTopView = false;
904        mRenderViewCells = false;
905        mTopDistance = 1.0f;
906        mCutViewCells = false;
907        mCutScene = false;
908        mRenderErrors = false;
909        mRenderBoxes = false;
910        mRenderFilter = true;
911        mRenderVisibilityEstimates = false;
912
913        mUseRandomColorPerPvsObject = false;
914
915        mHideByCost = false;
916        mUseTransparency = false;
917
918        mTransferFunction = 1.0f;
919        mIndexBufferSize = 0;
920
921        //mCurrentFrame = 0;
922
923        const int delay = 250; // in milliseconds
924        timerId = startTimer(delay);
925
926        bool tmp;
927
928        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
929        mUseFilter = tmp;
930
931        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp );
932        mUseSpatialFilter = tmp;
933
934        //mLogWriter = new LogWriter("myfile.out");
935
936        mShowRenderCost = false;
937        mShowPvsSizes = false;
938        mShowComparison = false;
939        mShowPiercingRays = false;
940        mShowWeightedRays = false;
941        mUseStandardColors = false;
942        mShowWeightedCost = true;
943
944        mShowDistanceWeightedPvs = true;
945        mShowDistanceWeightedTriangles = false;
946        mShowWeightedTriangles = false;
947        mShowDistribution = 15;
948        mCurrentDynamicObjectIdx = -1;
949
950        mSpatialFilterSize = 0.01;
951        mPvsSize = 0;
952        mRayVisualizationMethod = 0;
953        mTrafoType = 0;
954
955        mRenderError = 0.0f;
956        mShowRays = false;
957
958        mControlWidget = new QtRendererControlWidget(NULL);
959
960        connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int)));
961        connect(mControlWidget, SIGNAL(SetTransferFunction(int)), this, SLOT(SetTransferFunction(int)));
962
963        connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs()));
964        connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility()));
965        connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation()));
966        connect(mControlWidget, SIGNAL(SetRandomViewPoint()), this,     SLOT(SetRandomViewPoint()));
967        connect(mControlWidget, SIGNAL(StoreStatistics(void)), this, SLOT(StoreStatistics(void)));
968        connect(mControlWidget, SIGNAL(LoadObject(void)), this, SLOT(LoadObject(void)));
969
970        connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int)));
971        connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int)));
972        connect(mControlWidget, SIGNAL(SetTransparency(int)), this, SLOT(SetTransparency(int)));
973
974        connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int)));
975        connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int)));
976        connect(mControlWidget, SIGNAL(SetHidingCost(int)), this, SLOT(SetHidingCost(int)));
977
978        connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool)));
979        connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool)));
980        connect(mControlWidget, SIGNAL(SetUseTransparency(bool)), this, SLOT(SetUseTransparency(bool)));
981        connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool)));
982        connect(mControlWidget, SIGNAL(SetShowComparison(bool)), this, SLOT(SetShowComparison(bool)));
983        connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool)));
984        connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool)));
985        connect(mControlWidget, SIGNAL(SetHideByCost(bool)), this, SLOT(SetHideByCost(bool)));
986        connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
987        connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
988        connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
989        connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
990        connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)), this, SLOT(SetRenderVisibilityEstimates(bool)));
991        connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
992        connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), this, SLOT(SetUseSpatialFilter(bool)));
993        connect(mControlWidget, SIGNAL(SetShowPiercingRays(bool)), this, SLOT(SetShowPiercingRays(bool)));
994        connect(mControlWidget, SIGNAL(SetShowWireFrame(bool)), this, SLOT(SetShowWireFrame(bool)));
995        connect(mControlWidget, SIGNAL(SetShowWeightedRays(bool)), this, SLOT(SetShowWeightedRays(bool)));
996        connect(mControlWidget, SIGNAL(SetShowWeightedCost(bool)), this, SLOT(SetShowWeightedCost(bool)));
997
998        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedTriangles(bool)), this, SLOT(SetShowDistanceWeightedTriangles(bool)));
999        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedPvs(bool)), this, SLOT(SetShowDistanceWeightedPvs(bool)));
1000        connect(mControlWidget, SIGNAL(SetShowWeightedTriangles(bool)), this, SLOT(SetShowWeightedTriangles(bool)));
1001
1002        connect(mControlWidget, SIGNAL(UseConstColorForRayViz(bool)), this, SLOT(UseConstColorForRayViz(bool)));
1003        connect(mControlWidget, SIGNAL(UseRayLengthForRayViz(bool)), this, SLOT(UseRayLengthForRayViz(bool)));
1004        connect(mControlWidget, SIGNAL(SetShowContribution(bool)), this, SLOT(SetShowContribution(bool)));
1005        connect(mControlWidget, SIGNAL(SetShowDistribution(bool)), this, SLOT(SetShowDistribution(bool)));
1006
1007        connect(mControlWidget, SIGNAL(SetShowDistribution1(bool)), this, SLOT(SetShowDistribution1(bool)));
1008        connect(mControlWidget, SIGNAL(SetShowDistribution2(bool)), this, SLOT(SetShowDistribution2(bool)));
1009        connect(mControlWidget, SIGNAL(SetShowDistribution3(bool)), this, SLOT(SetShowDistribution3(bool)));
1010        connect(mControlWidget, SIGNAL(SetShowDistribution4(bool)), this, SLOT(SetShowDistribution4(bool)));
1011
1012        connect(mControlWidget, SIGNAL(SetShowRays(bool)), this, SLOT(SetShowRays(bool)));
1013
1014        connect(mControlWidget, SIGNAL(SetTranslation(bool)), this, SLOT(SetTranslation(bool)));
1015        connect(mControlWidget, SIGNAL(SetRotation(bool)), this, SLOT(SetRotation(bool)));
1016        connect(mControlWidget, SIGNAL(SetScale(bool)), this, SLOT(SetScale(bool)));
1017       
1018        setWindowTitle("PVS Visualization");
1019
1020        // setting the main window size here
1021        //resize(800, 600);
1022        //resize(640, 480);
1023        //resize(512, 384);
1024        //resize(512, 320);
1025        resize(640, 400);
1026       
1027        mControlWidget->show();
1028}
1029
1030void
1031QtGlRendererWidget::UpdateAllPvs()
1032{
1033        // $$ does not work so far:(
1034        mViewCellsManager->UpdatePvsForEvaluation();
1035        //      mViewCellsManager->FinalizeViewCells(false);
1036}
1037
1038void
1039QtGlRendererWidget::ComputeVisibility()
1040{
1041        cerr<<"Compute Visibility called!\n"<<endl;
1042        if (!mPreprocessorThread->isRunning())
1043                mPreprocessorThread->RunThread();
1044}
1045
1046void
1047QtGlRendererWidget::StopComputation()
1048{
1049        cerr<<"stop computation called!\n"<<endl;
1050        mViewCellsManager->GetPreprocessor()->mStopComputation = true;
1051}
1052
1053void
1054QtGlRendererWidget::SetRandomViewPoint()
1055{
1056        cerr<<"setting random view point!\n"<<endl;
1057        mViewCellsManager->GetViewPoint(mViewPoint);
1058        updateGL();
1059}
1060
1061
1062void QtGlRendererWidget::StoreStatistics()
1063{
1064        cerr<<"storing statistics!\n"<<endl;
1065        const int currentSamples = mViewCellsManager->GetPreprocessor()->mCurrentSamples;
1066
1067        cout<<"**********************************************" << endl;
1068        cout << "reached " << currentSamples << " samples " << " => writing file" << endl;
1069               
1070        LogWriter writer;
1071        writer.SetFilename("compare.log");
1072        writer.Write(currentSamples, mViewCellsManager->GetViewCells());
1073        cout << "finished writing file" << endl;
1074        mCompareInfo.clear();
1075        updateGL();
1076}
1077
1078
1079void QtGlRendererWidget::LoadObject()
1080{
1081        string filename("../data/teapot.bn");
1082       
1083        cout << "Loading model << " << filename << endl;
1084
1085        ++ mCurrentDynamicObjectIdx;
1086
1087        if (mViewCellsManager->GetPreprocessor()->LoadDynamicGeometry(filename))
1088                cout << "Loading finished" << endl;
1089        else
1090                cerr << "Loading failed" << endl;
1091
1092    updateGL();
1093}
1094
1095void
1096QtGlRendererWidget::RenderRenderCost()
1097{
1098        static vector<float> costFunction;
1099        static float maxCost = -1;
1100        if (costFunction.size()==0) {
1101                ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree();
1102                if (tree) {
1103                        tree->GetCostFunction(costFunction);
1104                        maxCost = -1;
1105                        for (int i=0;  i < costFunction.size(); i++) {
1106                                //                cout<<i<<":"<<costFunction[i]<<" ";
1107                                // update cost function to an absolute value based on the total geometry count
1108                                costFunction[i] *= mSceneGraph->GetSize();
1109                                if (costFunction[i] > maxCost)
1110                                        maxCost = costFunction[i];
1111                        }
1112                }
1113        }
1114
1115
1116        int currentPos = (int)mViewCellsManager->GetViewCells().size();
1117        float currentCost= -1;
1118
1119        if (currentPos < costFunction.size())
1120                currentCost = costFunction[currentPos];
1121#if 1   
1122        cout<<"costFunction.size()="<<(int)costFunction.size()<<endl;
1123        cout<<"CP="<<currentPos<<endl;
1124        cout<<"MC="<<maxCost<<endl;
1125        cout<<"CC="<<currentCost<<endl;
1126#endif
1127        if (costFunction.size()) {
1128                float scaley = 1.0f/log10(maxCost);
1129                float scalex = 1.0f/(float)costFunction.size();
1130
1131                glDisable(GL_DEPTH_TEST);
1132                // init ortographic projection
1133                glMatrixMode(GL_PROJECTION);
1134
1135                glPushMatrix();
1136
1137                glLoadIdentity();
1138                gluOrtho2D(0, 1.0f, 0, 1.0f);
1139
1140                glTranslatef(0.1f, 0.1f, 0.0f);
1141                glScalef(0.8f, 0.8f, 1.0f);
1142                glMatrixMode(GL_MODELVIEW);
1143                glLoadIdentity();
1144
1145                glColor3f(1.0f,0,0);
1146                glBegin(GL_LINE_STRIP);
1147                //        glVertex3f(0,0,0);
1148
1149                for (int i=0;  i < costFunction.size(); i++) {
1150                        float x =  i*scalex;
1151                        float y = log10(costFunction[i])*scaley;
1152                        glVertex3f(x,y,0.0f);
1153                }
1154                glEnd();
1155
1156                glColor3f(1.0f,0,0);
1157                glBegin(GL_LINES);
1158                float x =  currentPos*scalex;
1159                glVertex3f(x,0.0,0.0f);
1160                glVertex3f(x,1.0f,0.0f);
1161                glEnd();
1162
1163                glColor3f(0.0f,0,0);
1164                // show a grid
1165                glBegin(GL_LINE_LOOP);
1166                glVertex3f(0,0,0.0f);
1167                glVertex3f(1,0,0.0f);
1168                glVertex3f(1,1,0.0f);
1169                glVertex3f(0,1,0.0f);
1170                glEnd();
1171
1172                glBegin(GL_LINES);
1173                for (int i=0;  i < costFunction.size(); i += 1000) {
1174                        float x =  i*scalex;
1175                        glVertex3f(x,0.0,0.0f);
1176                        glVertex3f(x,1.0f,0.0f);
1177                }
1178
1179                for (int i=0;  pow(10.0f, i) < maxCost; i+=1) {
1180                        float y = i*scaley;
1181                        //              QString s;
1182                        //              s.sprintf("%d", (int)pow(10,i));
1183                        //              renderText(width()/2+5, y*height(), s);
1184                        glVertex3f(0.0f, y, 0.0f);
1185                        glVertex3f(1.0f, y, 0.0f);
1186                }
1187
1188                glEnd();
1189
1190
1191                // restore the projection matrix
1192                glMatrixMode(GL_PROJECTION);
1193                glPopMatrix();
1194                glMatrixMode(GL_MODELVIEW);
1195                glEnable(GL_DEPTH_TEST);
1196
1197        }
1198
1199
1200
1201}
1202
1203void
1204QtGlRendererWidget::RenderInfo()
1205{
1206
1207        QString s;
1208
1209        int vc = 0;
1210        if (mViewCellsManager)
1211                vc = (int)mViewCellsManager->GetViewCells().size();
1212
1213        int filter = 0;
1214        if (mViewCellsManager)
1215                filter = mViewCellsManager->GetMaxFilterSize();
1216
1217        glColor3f(0.0f, 0.0f, 1.0f);
1218
1219#if REMOVE_TEMPORARY
1220        s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)",
1221                mFrame,
1222                mViewPoint.x,
1223                mViewPoint.y,
1224                mViewPoint.z,
1225                mViewDirection.x,
1226                mViewDirection.y,
1227                mViewDirection.z
1228                );
1229
1230        renderText(20, 20, s);
1231
1232        s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f %",
1233                vc,
1234                filter,
1235                mPvsSize,
1236                mRenderError*100.0f);
1237
1238        renderText(20, 40, s);
1239#endif
1240       
1241        QFont font40; font40.setPointSize(30);
1242        s.sprintf("PVS: %04d", mPvsSize);
1243        renderText(20, 40, s, font40);
1244}
1245
1246
1247void
1248QtGlRendererWidget::SetViewCellGranularity(int number)
1249{
1250        if (mViewCellsManager) {
1251                //      mViewCellsManager->SetMaxFilterSize(number);
1252
1253                // $$ tmp off
1254                mViewCellsManager->CollectViewCells(number);
1255
1256                // $$ does not work so far:(
1257                //      mViewCellsManager->UpdatePvsForEvaluation();
1258                //      mViewCellsManager->FinalizeViewCells(false);
1259        }
1260        updateGL();
1261}
1262
1263void
1264QtGlRendererWidget::SetVisibilityFilterSize(int number)
1265{
1266        if (mViewCellsManager)
1267                mViewCellsManager->SetMaxFilterSize(number);
1268        mPvsCache.Reset();
1269        updateGL();
1270}
1271
1272void
1273QtGlRendererWidget::SetSpatialFilterSize(int number)
1274{
1275        mSpatialFilterSize = 1e-3*number;
1276        mPvsCache.Reset();
1277        updateGL();
1278}
1279
1280void
1281QtGlRendererWidget::SetSceneCut(int number)
1282{
1283        // assume the cut plane can only be aligned with xz plane
1284        // shift it along y according to number, which is percentage of the bounding
1285        // box position
1286        if (mViewCellsManager)
1287        {
1288                const float f = number / 1000.0f;
1289                AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
1290                Vector3 p = (1.0f - f) * box.Min() + f * box.Max();
1291                mSceneCutPlane.mNormal = Vector3(0,-1,0);
1292                mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p);
1293
1294                updateGL();
1295        }
1296}
1297
1298void
1299QtGlRendererWidget::SetHidingCost(int number)
1300{
1301        mHidingCost = (float)number / 1000.0f;
1302}
1303
1304
1305void
1306QtGlRendererWidget::SetTopDistance(int number)
1307{
1308        mTopDistance = number / 1000.0f;
1309        updateGL();
1310}
1311
1312void QtGlRendererWidget::SetTransparency(int number)
1313{
1314        mTransparency = number / 1000.0f;
1315        updateGL();
1316}
1317
1318#if 0
1319float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1320{
1321        ObjectPvs basePvs;
1322       
1323        basePvs = vc->CopyPvs();
1324        ObjectPvsIterator pit = basePvs.GetIterator();
1325
1326        float renderCost = 0;
1327
1328        //cout << "cost vis: " << mShowDistanceWeightedPvs << " " << " " << mShowDistanceWeightedTriangles << " " << mShowWeightedTriangles << endl;
1329       
1330        // first mark all objects from this pvs
1331        while (pit.HasMoreEntries())   
1332        {
1333                KdIntersectable *kdObj = static_cast<KdIntersectable *>(pit.Next());
1334
1335                if (mShowDistanceWeightedPvs)
1336                {
1337                        const AxisAlignedBox3 box = kdObj->GetBox();
1338
1339                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1340                        renderCost += 1.0f / dist;
1341                }
1342                else if (mShowDistanceWeightedTriangles)
1343                {
1344                        const AxisAlignedBox3 box = kdObj->GetBox();
1345
1346                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1347                        renderCost += kdObj->ComputeNumTriangles() / dist;
1348                }
1349                else //if (mShowWeightedTriangles)
1350                {
1351                        renderCost += kdObj->ComputeNumTriangles();
1352                }
1353                //if (pit.Next()->Mail();
1354        }
1355
1356        return renderCost;
1357}
1358#else
1359
1360float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1361{
1362        float renderCost = 0;
1363
1364#ifndef USE_BIT_PVS
1365        if (mShowDistanceWeightedPvs)
1366        {
1367                return vc->GetPvs().mStats.mDistanceWeightedPvs;
1368        }
1369        else if (mShowDistanceWeightedTriangles)
1370        {
1371                return vc->GetPvs().mStats.mDistanceWeightedTriangles;
1372        }
1373        else //if (mShowWeightedTriangles)
1374        {
1375                return vc->GetPvs().mStats.mWeightedTriangles;
1376        }
1377#else
1378        return 0.0f;
1379#endif
1380}
1381#endif
1382
1383
1384
1385void QtGlRendererWidget::ComputeMaxValues(const ViewCellContainer &viewCells,
1386                                                                                  int &maxPvs,
1387                                                                                  int &maxPiercingRays,
1388                                                                                  float &maxRelativeRays,
1389                                                                                  float &maxRcCost)
1390{
1391        maxPvs = -1;
1392        maxPiercingRays = 1; // not zero for savety
1393        maxRelativeRays = Limits::Small; // not zero for savety
1394        maxRcCost = Limits::Small;
1395
1396        for (size_t i = 0; i < viewCells.size(); ++ i)
1397        {
1398                ViewCell *vc = viewCells[i];
1399
1400                if (mShowPvsSizes) // pvs size
1401                {
1402                        //const int p = vc->GetPvs().CountObjectsInPvs();
1403                        const int p = vc->GetPvs().GetSize();
1404                        if (p > maxPvs)
1405                                maxPvs = p;
1406                }
1407                else if (mShowPiercingRays) // relative number of rays
1408                {
1409                        const int piercingRays = vc->GetNumPiercingRays();
1410
1411                        if (piercingRays > maxPiercingRays)
1412                                maxPiercingRays = piercingRays;
1413                }
1414                else if (mShowWeightedRays)
1415                {
1416                        const int piercingRays = vc->GetNumPiercingRays();
1417
1418                        const float relativeArea =
1419                                vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1420
1421                        if ((float)piercingRays / relativeArea > maxRelativeRays)
1422                                maxRelativeRays = (float)piercingRays / relativeArea;
1423                }
1424                else if (mShowWeightedCost)
1425                {
1426                        const float rcCost = ComputeRenderCost(vc);
1427                        mViewCellsManager->UpdateScalarPvsCost(vc, rcCost);
1428
1429                        if (rcCost > maxRcCost)
1430                                maxRcCost = rcCost;
1431                }
1432        }
1433}
1434
1435
1436void QtGlRendererWidget::RenderViewCells()
1437{
1438        mUseFalseColors = true;
1439        //glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
1440
1441        glEnable(GL_CULL_FACE);
1442        glCullFace(GL_FRONT);
1443        //glDisable(GL_CULL_FACE);
1444
1445        if (mCutViewCells)
1446        {
1447                double eq[4];
1448                eq[0] = mSceneCutPlane.mNormal.x;
1449                eq[1] = mSceneCutPlane.mNormal.y;
1450                eq[2] = mSceneCutPlane.mNormal.z;
1451                eq[3] = mSceneCutPlane.mD;
1452
1453                glClipPlane(GL_CLIP_PLANE0, eq);
1454                glEnable(GL_CLIP_PLANE0);
1455        }
1456
1457        ViewCellContainer &viewcells = mViewCellsManager->GetViewCells();
1458       
1459        int maxPvs, maxPiercingRays;
1460        float maxRelativeRays, maxRcCost;
1461
1462        ComputeMaxValues(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1463        // matt: temp hack
1464        maxRcCost = 200.0f;
1465        //cout << "maxRcCost: " << maxRcCost << endl;
1466        int i;
1467
1468        // transparency
1469        if (!mUseTransparency)
1470        {
1471                glEnable(GL_DEPTH_TEST);
1472                glDisable(GL_BLEND);
1473        }
1474        else
1475        {
1476                glDisable(GL_DEPTH_TEST);
1477                glEnable(GL_BLEND);
1478
1479                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1480                //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1481
1482                for (i = 0; i < viewcells.size(); ++ i)
1483                {
1484                        ViewCell *vc = viewcells[i];
1485
1486                        const float dist = SqrDistance(mDummyViewPoint, vc->GetBox().Center());
1487                        vc->SetDistance(dist);
1488                }
1489
1490                sort(viewcells.begin(), viewcells.end(), nearerThan);
1491        }
1492
1493        //mWireFrame = true;
1494               
1495        // normal rendering
1496        //if (!mShowPvsSizes && !mShowPiercingRays && !mShowWeightedRays && !mShowWeightedCost && !mShowComparison)
1497        if (mUseStandardColors)
1498        {
1499                for (i = 0; i < viewcells.size(); ++ i)
1500                {
1501                        ViewCell *vc = viewcells[i];
1502                        RgbColor c;
1503
1504                        //if (!mShowPvsSizes && !mShowPiercingRays)
1505                        c = vc->GetColor();
1506                       
1507                        glColor3f(c.r, c.g, c.b);
1508
1509                        if (!mHideByCost || (mHidingCost < (vc->GetNumPiercingRays() / (float)maxPiercingRays)))
1510                        {
1511                RenderViewCell(vc);
1512                        }
1513                }
1514        }
1515        else // using specialised colors
1516        {
1517                if (!mShowComparison)
1518                        AssignImportanceByRelativeValue(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1519                else
1520                {
1521                        if (mCompareInfo.empty())
1522                        {
1523                                LogReader reader;
1524                                reader.SetFilename("compare.log");
1525                                int samples;
1526                                reader.Read(samples, mCompareInfo);
1527                        }
1528
1529                        AssignColorByComparison(viewcells, mCompareInfo);
1530                }
1531
1532                glEnable(GL_DEPTH_TEST);       
1533        }
1534       
1535        glEnable(GL_CULL_FACE);
1536        glDisable(GL_CULL_FACE);
1537
1538        glDisable(GL_CLIP_PLANE0);
1539
1540        mUseFalseColors = false;
1541        mWireFrame = false;
1542
1543        glPopAttrib();
1544}
1545
1546
1547void QtGlRendererWidget::AssignImportanceByRelativeValue(const ViewCellContainer &viewCells,
1548                                                                                                                 int &maxPvs,
1549                                                                                                                 int &maxPiercingRays,
1550                                                                                                                 float &maxRelativeRays,
1551                                                                                                                 float &maxRcCost)
1552{
1553        for (size_t i = 0; i < viewCells.size(); ++ i)
1554        {
1555                RgbColor c;
1556                ViewCell *vc = viewCells[i];
1557
1558                float importance;
1559
1560                if (mShowPiercingRays)
1561                {
1562                        importance = mTransferFunction *
1563                                ((float)vc->GetNumPiercingRays() / (float)maxPiercingRays);
1564                }
1565                else if (mShowWeightedRays) // relative number of rays
1566                {
1567                        float relativeArea = vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1568
1569                        if (relativeArea < Limits::Small)
1570                                relativeArea = Limits::Small;
1571
1572                        importance = mTransferFunction * ((float)vc->GetNumPiercingRays() / relativeArea) / maxRelativeRays;
1573                }
1574                else if (mShowPvsSizes) // pvs size
1575                {
1576                        importance = mTransferFunction *
1577                                ((float)vc->GetPvs().GetSize() / (float)maxPvs);
1578                } // weighted render cost
1579                else if (mShowWeightedCost)
1580                {
1581                        const float rcCost = mTransferFunction * ComputeRenderCost(vc);
1582                        importance = rcCost / maxRcCost;
1583                }
1584if (importance > 1.0f) importance = 1.0f;
1585                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1586                c = RainbowColorMapping(importance);
1587
1588                glColor4f(c.r, c.g, c.b, 1.0f - mTransparency);
1589
1590                if (!mHideByCost || (mHidingCost < importance))
1591                {
1592                        RenderViewCell(vc);
1593                }
1594        }
1595}
1596
1597
1598void QtGlRendererWidget::AssignColorByComparison(const ViewCellContainer &viewcells,
1599                                                                                                 //const ViewCellInfoContainer &infos1,
1600                                                                                                 const ViewCellInfoContainer &compareInfo)
1601{
1602        //cout << "comparing " << viewcells.size() << " view cells to " << compareInfo.size() << " values" << endl;
1603
1604        if (viewcells.size() > compareInfo.size())
1605        {
1606                cerr << "loaded size (" << (int)compareInfo.size() << ") does not fit to view cells size (" << (int)viewcells.size() << ")" << endl;
1607                return;
1608        }
1609
1610        //const float maxRatio = 1.0f;
1611        const float maxRatio = 2.0f;
1612        const float minRatio = 0.0f;
1613
1614        const float scale = 1.0f / (maxRatio - minRatio);
1615
1616        for (size_t i = 0; i < viewcells.size(); ++ i)
1617        {
1618                RgbColor c;
1619                ViewCell *vc = viewcells[i];
1620
1621                //ViewCellInfo vc1Info = infos1[i];
1622                ViewCellInfo vc2Info = compareInfo[i];
1623
1624                //const float vcRatio = vc->GetNumPiercingRays() / vc2Info.mPiercingRays + Limits::Small;
1625                float vcRatio = 1.0f;//maxRatio;
1626               
1627                if (vc2Info.mPvsSize > Limits::Small)
1628                        vcRatio = (float)vc->GetPvs().GetSize() / vc2Info.mPvsSize;
1629
1630                // truncate here
1631                if (vcRatio > maxRatio) vcRatio = 1.0f;
1632
1633                const float importance = (vcRatio - minRatio) * scale;
1634       
1635                if (0 && (i < 20))
1636                {
1637                        cout << "pvs1: " << vc->GetPvs().GetSize() << " pvs2: " << compareInfo[i].mPvsSize << " importance: " << importance << endl;
1638                }
1639
1640                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1641                c = RainbowColorMapping(importance);
1642
1643                glColor4f(c.r, c.g, c.b, 1.0f);
1644
1645                if (1)//!mHideByCost || (mHidingCost < importance))
1646                {
1647                        RenderViewCell(vc);
1648                }
1649        }
1650}
1651
1652
1653
1654/**********************************************************************/
1655/*              QtRendererControlWidget implementation                */
1656/**********************************************************************/
1657
1658
1659QGroupBox *QtRendererControlWidget::CreateVisualizationPanel(QWidget *parent)
1660{
1661        QRadioButton *rb1, *rb2, *rb3, *rb4, *rb5;
1662       
1663        rb1 = new QRadioButton("random colors", parent);
1664        rb1->setText("random");
1665        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWireFrame(bool)));
1666
1667        // Create a check box to be in the group box
1668        rb2 = new QRadioButton("piercing rays", parent);
1669        rb2->setText("piercing rays");
1670        //vl->addWidget(rb1);
1671        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowPiercingRays(bool)));
1672
1673        rb3 = new QRadioButton("pvs size", parent);
1674        rb3->setText("pvs size");
1675        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool)));
1676       
1677        rb4 = new QRadioButton("weighted rays", parent);
1678        rb4->setText("weighted rays");
1679        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedRays(bool)));
1680       
1681        rb5 = new QRadioButton("pvs cost", parent);
1682        rb5->setText("pvs cost");
1683        connect(rb5, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedCost(bool)));
1684
1685        QGroupBox *groupBox = new QGroupBox("PVS Visualization");
1686
1687        QVBoxLayout *vbox2 = new QVBoxLayout;
1688   
1689        vbox2->addWidget(rb1);
1690        vbox2->addWidget(rb2);
1691        vbox2->addWidget(rb3);
1692        vbox2->addWidget(rb4);
1693        vbox2->addWidget(rb5);
1694       
1695        rb5->setChecked(true);
1696
1697        vbox2->addStretch(1);
1698        groupBox->setLayout(vbox2);
1699
1700        return groupBox;
1701}
1702
1703
1704QGroupBox *QtRendererControlWidget::CreateTrafoPanel(QWidget *parent)
1705{
1706        QRadioButton *rb1, *rb2, *rb3;
1707       
1708        rb1 = new QRadioButton("translation", parent);
1709        rb1->setText("translation");
1710        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetTranslation(bool)));
1711
1712        // Create a check box to be in the group box
1713        rb2 = new QRadioButton("scale", parent);
1714        rb2->setText("scale");
1715        //vl->addWidget(rb1);
1716        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetScale(bool)));
1717
1718        rb3 = new QRadioButton("rotation", parent);
1719        rb3->setText("rotation");
1720        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetRotation(bool)));
1721   
1722        QVBoxLayout *vbox2 = new QVBoxLayout;
1723        QGroupBox *groupBox = new QGroupBox("Trafo types");
1724
1725        vbox2->addWidget(rb1);
1726        vbox2->addWidget(rb2);
1727        vbox2->addWidget(rb3);
1728       
1729        rb1->setChecked(true);
1730
1731        vbox2->addStretch(1);
1732        groupBox->setLayout(vbox2);
1733
1734        return groupBox;
1735}
1736
1737
1738
1739QGroupBox *QtRendererControlWidget::CreateRenderCostPanel(QWidget *parent)
1740{
1741        QRadioButton *rb1, *rb2, *rb3;
1742       
1743        // Create a check box to be in the group box
1744        rb1 = new QRadioButton("triangles", parent);
1745        rb1->setText("triangles");
1746        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedTriangles(bool)));
1747
1748        rb2 = new QRadioButton("distance weighted pvs", parent);
1749        rb2->setText("distance weighted");
1750        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedPvs(bool)));
1751
1752        rb3 = new QRadioButton("distance weighted triangles", parent);
1753        rb3->setText("distance weighted triangles");
1754        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedTriangles(bool)));
1755
1756        QGroupBox *groupBox = new QGroupBox("Render cost options");
1757        QVBoxLayout *vbox2 = new QVBoxLayout;
1758   
1759        vbox2->addWidget(rb1);
1760        vbox2->addWidget(rb2);
1761        vbox2->addWidget(rb3);
1762       
1763        rb1->setChecked(true);
1764
1765        vbox2->addStretch(1);
1766        groupBox->setLayout(vbox2);
1767
1768        return groupBox;
1769}
1770
1771
1772QGroupBox *QtRendererControlWidget::CreateRayVisualizationPanel(QWidget *parent)
1773{
1774        QRadioButton *rb1, *rb2, *rb3, *rb4;
1775       
1776        // Create a check box to be in the group box
1777        rb1 = new QRadioButton("const color", parent);
1778        rb1->setText("const color");
1779        //vl->addWidget(rb1);
1780        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(UseConstColorForRayViz(bool)));
1781
1782        rb2 = new QRadioButton("ray length", parent);
1783        rb2->setText("ray length");
1784        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(UseRayLengthForRayViz(bool)));
1785       
1786        rb3 = new QRadioButton("contribution", parent);
1787        rb3->setText("contribution");
1788        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowContribution(bool)));
1789       
1790        rb4 = new QRadioButton("distribution", parent);
1791        rb4->setText("distribution");
1792        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution(bool)));
1793
1794
1795        ///////////////////////////
1796
1797       
1798        QGroupBox *groupBox = new QGroupBox("Ray visualization");
1799        QVBoxLayout *vbox2 = new QVBoxLayout;
1800   
1801        vbox2->addWidget(rb1);
1802        vbox2->addWidget(rb2);
1803        vbox2->addWidget(rb3);
1804        vbox2->addWidget(rb4);
1805       
1806        rb1->setChecked(true);
1807
1808
1809        QCheckBox *cb = new QCheckBox("Distribution 1", parent);
1810        vbox2->addWidget(cb);
1811        cb->setChecked(true);
1812        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution1(bool)));
1813
1814        cb = new QCheckBox("Distribution 2", parent);
1815        vbox2->addWidget(cb);
1816        cb->setChecked(true);
1817        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution2(bool)));
1818
1819        cb = new QCheckBox("Distribution 3", parent);
1820        vbox2->addWidget(cb);
1821        cb->setChecked(true);
1822        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution3(bool)));
1823       
1824        cb = new QCheckBox("Distribution 4", parent);
1825        vbox2->addWidget(cb);
1826        cb->setChecked(true);
1827        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution4(bool)));
1828
1829
1830        vbox2->addStretch(1);
1831        groupBox->setLayout(vbox2);
1832
1833        return groupBox;
1834}
1835
1836
1837QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f):
1838QWidget(parent, f)
1839{
1840
1841        QVBoxLayout *vl = new QVBoxLayout;
1842        setLayout(vl);
1843       
1844        //QWidget *vbox;
1845
1846        //vbox = new QGroupBox("Render Controls", this);
1847        //layout()->addWidget(vbox);
1848        //vl = new QVBoxLayout;
1849        //vbox->setLayout(vl);
1850
1851        QLabel *label;
1852        QSlider *slider;
1853        QPushButton *button;
1854
1855#if REMOVE_TEMPORARY
1856
1857        label = new QLabel("Granularity");
1858        //vbox->layout()->addWidget(label);
1859        vl->addWidget(label);
1860
1861        slider = new QSlider(Qt::Horizontal, vbox);
1862        vl->addWidget(slider);
1863        slider->show();
1864        slider->setRange(1, 10000);
1865        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1866        slider->setValue(200);
1867
1868        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int)));
1869
1870        ///////////////////////////
1871
1872        label = new QLabel("Transfer function");
1873        vl->addWidget(label);
1874
1875        slider = new QSlider(Qt::Horizontal, vbox);
1876        vl->addWidget(slider);
1877        slider->show();
1878        slider->setRange(1, 10000);
1879        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1880        slider->setValue(100);
1881
1882
1883        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int)));
1884
1885        ////////////////////////////////////////7
1886
1887        button = new QPushButton("Update all PVSs", vbox);
1888        vl->addWidget(button);
1889        connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs()));
1890
1891        ////////////////////////////////////////77777
1892
1893        label = new QLabel("Filter size");
1894        vl->addWidget(label);
1895
1896        slider = new QSlider(Qt::Horizontal, vbox);
1897        vl->addWidget(slider);
1898        slider->show();
1899        slider->setRange(1, 100);
1900        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1901        slider->setValue(3);
1902
1903        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int)));
1904
1905#endif
1906
1907
1908       
1909        ///////////////////////////////////
1910
1911
1912        QWidget *hbox = new QWidget();//vbox);
1913        vl->addWidget(hbox);
1914        QHBoxLayout *hlayout = new QHBoxLayout;
1915        hbox->setLayout(hlayout);
1916
1917        QCheckBox *cb = new QCheckBox("Show viewcells", hbox);
1918        hlayout->addWidget(cb);
1919        cb->setChecked(false);
1920        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool)));
1921       
1922        cb = new QCheckBox("Render errors", hbox);
1923        hlayout->layout()->addWidget(cb);
1924        cb->setChecked(false);
1925        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
1926
1927#if REMOVE_TEMPORARY
1928        cb = new QCheckBox("Render cost curve", hbox);
1929        hlayout->addWidget(cb);
1930        cb->setChecked(false);
1931        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool)));
1932#endif
1933        cb = new QCheckBox("Show rays", hbox);
1934        hlayout->addWidget(cb);
1935        cb->setChecked(false);
1936        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool)));
1937#if REMOVE_TEMPORARY   
1938        cb = new QCheckBox("Show Comparison", hbox);
1939        hlayout->addWidget(cb);
1940        cb->setChecked(false);
1941        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowComparison(bool)));
1942#endif
1943
1944        //////////////////
1945
1946        QHBoxLayout *vh = new QHBoxLayout;
1947
1948        QGroupBox *myBox = new QGroupBox("Visualization");
1949
1950        myBox->setLayout(vh);
1951        vl->addWidget(myBox, 0, 0);
1952
1953        QGroupBox *groupBox = CreateVisualizationPanel(hbox);
1954        vh->addWidget(groupBox, 0, 0);
1955#if REMOVE_TEMPORARY
1956        QGroupBox *groupBox2 = CreateRenderCostPanel(hbox);
1957        vh->addWidget(groupBox2, 0, 0);
1958#endif
1959        QGroupBox *groupBox3 = CreateRayVisualizationPanel(hbox);
1960        vh->addWidget(groupBox3, 0, 0);
1961
1962        QGroupBox *groupBox4 = CreateTrafoPanel(hbox);
1963        vh->addWidget(groupBox4, 0, 0);
1964
1965        //////////////////////////////////
1966
1967
1968        /*cb = new QRadiobox("Top View", vbox);
1969        vl->addWidget(cb);
1970        cb->setChecked(false);
1971        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
1972*/
1973
1974        //vbox->resize(800,150);
1975        QWidget *vbox;
1976
1977        vbox = new QGroupBox("Rendering", this);
1978        layout()->addWidget(vbox);
1979
1980        vl = new QVBoxLayout;
1981        vbox->setLayout(vl);
1982
1983
1984
1985        cb = new QCheckBox("Cut view cells", vbox);
1986        vbox->layout()->addWidget(cb);
1987        cb->setChecked(false);
1988        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool)));
1989
1990
1991        slider = new QSlider(Qt::Horizontal, vbox);
1992        vbox->layout()->addWidget(slider);
1993        slider->show();
1994        slider->setRange(0, 1000);
1995        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1996        slider->setValue(1000);
1997
1998        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
1999
2000       
2001        cb = new QCheckBox("Hide view cells by render cost ", vbox);
2002        vbox->layout()->addWidget(cb);
2003        cb->setChecked(false);
2004        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetHideByCost(bool)));
2005
2006        ////////////////////////////
2007
2008        const int range = 1000;
2009
2010        label = new QLabel("Hide by cost");
2011        vbox->layout()->addWidget(label);
2012
2013        // the render cost visualization
2014        slider = new QSlider(Qt::Horizontal, vbox);
2015        vbox->layout()->addWidget(slider);
2016        slider->show();
2017        slider->setRange(0, range);
2018        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2019        slider->setValue(0);
2020        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetHidingCost(int)));
2021
2022        ///////////////////////////////////////////
2023
2024        cb = new QCheckBox("Top View", vbox);
2025        vbox->layout()->addWidget(cb);
2026        cb->setChecked(false);
2027        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
2028
2029
2030        label = new QLabel("Top distance");
2031        vbox->layout()->addWidget(label);
2032       
2033        slider = new QSlider(Qt::Horizontal, vbox);
2034        vbox->layout()->addWidget(slider);
2035        slider->show();
2036        slider->setRange(1, 1000);
2037        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2038        slider->setValue(500);
2039
2040        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int)));
2041       
2042
2043        ///////////////////////////////////////////
2044#if REMOVE_TEMPORARY
2045        cb = new QCheckBox("Transparency", vbox);
2046        vbox->layout()->addWidget(cb);
2047        cb->setChecked(false);
2048        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseTransparency(bool)));
2049
2050        label = new QLabel("Use transparency");
2051        vbox->layout()->addWidget(label);
2052
2053        // the render cost visualization
2054        slider = new QSlider(Qt::Horizontal, vbox);
2055        vbox->layout()->addWidget(slider);
2056        slider->show();
2057        slider->setRange(0, range);
2058        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2059        slider->setValue(0);
2060#endif
2061        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransparency(int)));
2062
2063        //////////////////////////////
2064
2065#if REMOVE_TEMPORARY
2066        cb = new QCheckBox("Cut scene", vbox);
2067        vbox->layout()->addWidget(cb);
2068        cb->setChecked(false);
2069        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool)));
2070
2071        cb = new QCheckBox("Render boxes", vbox);
2072        vbox->layout()->addWidget(cb);
2073        cb->setChecked(false);
2074        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
2075
2076        cb = new QCheckBox("Render visibility estimates", vbox);
2077        vbox->layout()->addWidget(cb);
2078        cb->setChecked(false);
2079        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
2080#endif
2081
2082        bool tmp;
2083#if REMOVE_TEMPORARY
2084
2085        cb = new QCheckBox("Use filter", vbox);
2086        vbox->layout()->addWidget(cb);
2087        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
2088        cb->setChecked(tmp);
2089        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
2090#endif
2091
2092        cb = new QCheckBox("Use spatial filter", vbox);
2093        vbox->layout()->addWidget(cb);
2094        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
2095                tmp );
2096        cb->setChecked(tmp);
2097        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
2098#if REMOVE_TEMPORARY
2099        cb = new QCheckBox("Render filter", vbox);
2100        vbox->layout()->addWidget(cb);
2101        cb->setChecked(true);
2102        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool)));
2103
2104
2105        /*vbox = new QGroupBox("PVS Errors", this);
2106        layout()->addWidget(vbox);
2107
2108        vl = new QVBoxLayout;
2109        vbox->setLayout(vl);
2110
2111        button = new QPushButton("Compute Visibility", vbox);
2112        vbox->layout()->addWidget(button);
2113        connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility()));
2114
2115        button = new QPushButton("Stop Computation", vbox);
2116        vbox->layout()->addWidget(button);
2117        connect(button, SIGNAL(clicked()), SLOT(StopComputation()));
2118
2119        button = new QPushButton("Set Random View Point", vbox);
2120        vbox->layout()->addWidget(button);
2121        connect(button, SIGNAL(clicked()), SLOT(SetRandomViewPoint()));*/
2122
2123        button = new QPushButton("Store statistics", vbox);
2124        vbox->layout()->addWidget(button);
2125        connect(button, SIGNAL(clicked()), SIGNAL(StoreStatistics()));
2126#endif
2127
2128#if DYNAMIC_OBJECTS_HACK
2129
2130        button = new QPushButton("Load object", vbox);
2131        vbox->layout()->addWidget(button);
2132        connect(button, SIGNAL(clicked()), SIGNAL(LoadObject()));
2133#endif
2134
2135        /*cb = new QCheckBox("Stats", vbox);
2136        vbox->layout()->addWidget(cb);
2137        cb->setChecked(false);
2138        connect(cb, SIGNAL(toggled(bool)), SIGNAL(StoreStatistics()));*/
2139
2140        if (0)
2141        {
2142                vbox = new QGroupBox("PVS Errors", this);
2143                layout()->addWidget(vbox);
2144
2145                vl = new QVBoxLayout;
2146                vbox->setLayout(vl);
2147
2148                mPvsErrorWidget = new QListWidget(vbox);
2149                vbox->layout()->addWidget(mPvsErrorWidget);
2150
2151                connect(mPvsErrorWidget,
2152                        SIGNAL(doubleClicked(const QModelIndex &)),
2153                        this,
2154                        SLOT(PvsErrorClicked(const QModelIndex &)));
2155
2156                button = new QPushButton("Next Error Frame", vbox);
2157                vbox->layout()->addWidget(button);
2158                connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void)));
2159        }
2160       
2161        //connect(button, SIGNAL(clicked(void)), SLOT(StoreStatistics(void)));
2162        //mHidingCost = 0.1f;
2163//////////////////////////////////////////
2164
2165        label = new QLabel("Spatial Filter size");
2166        vbox->layout()->addWidget(label);
2167
2168        slider = new QSlider(Qt::Horizontal, vbox);
2169        vbox->layout()->addWidget(slider);
2170        slider->show();
2171        slider->setRange(1, 100);
2172        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2173        slider->setValue(10);
2174
2175        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int)));
2176
2177
2178        setWindowTitle("Preprocessor Control Widget");
2179        adjustSize();
2180}
2181
2182
2183
2184
2185void
2186QtRendererControlWidget::FocusNextPvsErrorFrame(void)
2187{}
2188
2189void
2190QtRendererControlWidget::UpdatePvsErrorItem(int row,
2191                                                                                        GlRendererBuffer::PvsErrorEntry &pvsErrorEntry)
2192{
2193
2194        QListWidgetItem *i = mPvsErrorWidget->item(row);
2195        QString s;
2196        s.sprintf("%5.5f", pvsErrorEntry.mError);
2197        if (i) {
2198                i->setText(s);
2199        } else {
2200                new QListWidgetItem(s, mPvsErrorWidget);
2201        }
2202        mPvsErrorWidget->update();
2203}
2204
2205
2206
2207
2208/*********************************************************************/
2209/*                   QtGlDebuggerWidget implementation               */
2210/*********************************************************************/
2211
2212
2213QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent)
2214: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf)
2215{
2216        // create the pbuffer
2217        //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
2218        timerId = startTimer(20);
2219        setWindowTitle(("OpenGL pbuffers"));
2220}
2221
2222
2223QtGlDebuggerWidget::~QtGlDebuggerWidget()
2224{
2225        mRenderBuffer->releaseFromDynamicTexture();
2226        glDeleteTextures(1, &dynamicTexture);
2227
2228        DEL_PTR(mRenderBuffer);
2229}
2230
2231
2232void QtGlDebuggerWidget::initializeGL()
2233{
2234        glMatrixMode(GL_PROJECTION);
2235        glLoadIdentity();
2236
2237        glFrustum(-1, 1, -1, 1, 10, 100);
2238        glTranslatef(-0.5f, -0.5f, -0.5f);
2239        glTranslatef(0.0f, 0.0f, -15.0f);
2240        glMatrixMode(GL_MODELVIEW);
2241
2242        glEnable(GL_CULL_FACE);
2243        initCommon();
2244        initPbuffer();
2245
2246}
2247
2248
2249void QtGlDebuggerWidget::resizeGL(int w, int h)
2250{
2251        glViewport(0, 0, w, h);
2252}
2253
2254
2255void QtGlDebuggerWidget::paintGL()
2256{
2257        // draw a spinning cube into the pbuffer..
2258        mRenderBuffer->makeCurrent();
2259
2260        BeamSampleStatistics stats;
2261        mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats);
2262
2263        glFlush();
2264
2265        // rendering directly to a texture is not supported on X11, unfortunately
2266        mRenderBuffer->updateDynamicTexture(dynamicTexture);
2267
2268        // and use the pbuffer contents as a texture when rendering the
2269        // background and the bouncing cubes
2270        makeCurrent();
2271        glBindTexture(GL_TEXTURE_2D, dynamicTexture);
2272        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2273
2274        // draw the background
2275        glMatrixMode(GL_MODELVIEW);
2276        glPushMatrix();
2277        glLoadIdentity();
2278        glMatrixMode(GL_PROJECTION);
2279        glPushMatrix();
2280        glLoadIdentity();
2281
2282        glPopMatrix();
2283        glMatrixMode(GL_MODELVIEW);
2284        glPopMatrix();
2285}
2286
2287
2288void QtGlDebuggerWidget::initPbuffer()
2289{
2290        // set up the pbuffer context
2291        mRenderBuffer->makeCurrent();
2292        /*mRenderBuffer->InitGL();
2293
2294        glViewport(0, 0, mRenderBuffer->size().width(), mRenderBuffer->size().height());
2295        glMatrixMode(GL_PROJECTION);
2296        glLoadIdentity();
2297        glOrtho(-1, 1, -1, 1, -99, 99);
2298        glTranslatef(-0.5f, -0.5f, 0.0f);
2299        glMatrixMode(GL_MODELVIEW);
2300        glLoadIdentity();
2301
2302        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);*/
2303
2304        // generate a texture that has the same size/format as the pbuffer
2305        dynamicTexture = mRenderBuffer->generateDynamicTexture();
2306
2307        // bind the dynamic texture to the pbuffer - this is a no-op under X11
2308        mRenderBuffer->bindToDynamicTexture(dynamicTexture);
2309        makeCurrent();
2310}
2311
2312
2313void QtGlDebuggerWidget::initCommon()
2314{
2315        glEnable(GL_TEXTURE_2D);
2316        glEnable(GL_DEPTH_TEST);
2317
2318        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2319}
2320
2321
2322void QtGlRendererWidget::_RenderColoredPvs()
2323{
2324        // note: could be done more efficiently using color buffers
2325        mPvsSize = mPvsCache.mPvs.GetSize();
2326
2327        ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
2328
2329        PvsData pvsData;
2330
2331        while (it.HasMoreEntries())
2332        {
2333                Intersectable *object = it.Next(pvsData);
2334
2335                RgbColor color;
2336
2337                //float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
2338                // glColor3f(visibility, 0.0f, 0.0f);
2339                //cerr << "sumpdf: " << pvsData.mSumPdf << endl;
2340                if (mUseRandomColorPerPvsObject)
2341                {
2342                        KdIntersectable *kdint = static_cast<KdIntersectable *>(object);
2343
2344                        if (kdint->mGenericIdx == -1)
2345                        {
2346                                kdint->mGenericIdx = (int)mColors.size();
2347                                mColors.push_back(RandomColor());
2348                        }
2349                        color = mColors[kdint->mGenericIdx];
2350                }
2351                else
2352                {
2353                        color = RainbowColorMapping(mTransferFunction * log10(pvsData.mSumPdf + 1));
2354                }
2355
2356                glColor3f(color.r, color.g, color.b);
2357
2358                mUseForcedColors = true;
2359                RenderIntersectable(object);
2360                mUseForcedColors = false;
2361        }
2362}
2363
2364}
Note: See TracBrowser for help on using the repository browser.