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

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