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

Revision 2725, 71.6 KB checked in by mattausch, 16 years ago (diff)

siggraph asia submission

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