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

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