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

Revision 2695, 66.4 KB checked in by mattausch, 16 years ago (diff)

debug version: problematic view points for vienna detected

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