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

Revision 2705, 68.4 KB checked in by mattausch, 16 years ago (diff)

enabled view cell visualization

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