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

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