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

Revision 2702, 68.3 KB checked in by mattausch, 16 years ago (diff)

implemented dynamic object placement / removal

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(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(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                /*if (mCurrentDynamicObjectIdx >= 0) {
838                preprocessor->ScheduleUpdateDynamicObjects();
839                }*/
840        }
841}
842
843void
844QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e)
845{
846        if (mReplayMode)
847                return;
848
849        float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
850        float TURN_SENSITIVITY = 0.1f;
851        float TILT_SENSITIVITY = 32.0 ;
852        float TURN_ANGLE= M_PI / 36.0 ;
853
854        int x = e->pos().x();
855        int y = e->pos().y();
856
857        int diffx = -(mousePoint.x - x);
858        int diffy = -(mousePoint.y - y);
859
860        const float t = 1.0f;
861        if (e->modifiers() & Qt::ControlModifier)
862        {
863                mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY / 2.0;
864                mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY / 2.0;
865        }
866#if 0// DYNAMIC_OBJECTS_HACK
867        else if (e->modifiers() & Qt::AltModifier)
868        {
869                if (mCurrentDynamicObjectIdx >= 0)
870                {
871                        Matrix4x4 tm;
872
873                        switch (mTrafoType)
874                        {
875                        case 0:
876                                {
877                                  if (e->modifiers() & Qt::ShiftModifier) {
878                                        const Vector3 transl(0, diffy, 0);
879                                        tm = TranslationMatrix(transl);
880                                 
881                                  } else {
882                                        const Vector3 transl(diffx, 0, diffy);
883                                        tm = TranslationMatrix(transl);
884                                  }
885                                }
886                                break;
887                        case 1:
888                                {
889                                        float scalef = 1.0f + 0.01f * (diffx + diffy);
890                                        if (scalef < 0.9) scalef = 0.9f;
891                                        else if (scalef > 1.1f) scalef = 1.1f;
892                                        tm = ScaleMatrix(scalef, scalef, scalef);
893                                }
894                                break;
895                        case 2:
896                                {
897                                  //                                    tm = RotationXMatrix(diffx) * RotationYMatrix(diffy);
898                                  tm = RotationYMatrix(diffx);
899                                }
900                                break;
901                        default:
902                                cerr << "not implemented" << endl;
903                        }
904
905                        SceneGraphLeaf *l =
906                          mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
907                        l->ApplyTransform(tm);
908                       
909                        updateGL();
910                }
911        }
912#endif
913        else
914        {
915                mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
916                float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
917                float angle = atan2(mViewDirection.x, mViewDirection.z);
918                mViewDirection.x = sin(angle + adiff);
919                mViewDirection.z = cos(angle + adiff);
920        }
921
922        mousePoint.x = x;
923        mousePoint.y = y;
924
925        updateGL();
926}
927
928
929void
930QtGlRendererWidget::resizeGL(int w, int h)
931{
932        SetupCameraProjection(w, h);
933        updateGL();
934}
935
936
937void QtGlRendererWidget::paintGL()
938{
939        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
940
941        SetupCameraProjection(width(), height());
942        SetupCamera();
943
944        if (mRenderErrors)
945                RenderErrors();
946        else
947        {
948                glColor3f(0.6f, 0.6f, 0.6f);
949                VisualizePvs();
950        }
951
952        if (mShowRays)
953                RenderRays(mViewCellsManager->mVizBuffer.GetRays(), mRayVisualizationMethod, mShowDistribution, 1);
954       
955        RenderInfo();
956
957        ++ mFrame;
958        //      cout<<"vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
959}
960
961
962void
963QtGlRendererWidget::SetupCamera()
964{
965        if (!mTopView)
966                GlRenderer::SetupCamera();
967        else
968        {
969                if (0)
970                {
971                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
972                        Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
973                                -1,
974                                mViewDirection.y);
975
976                        Vector3 target = mViewPoint + dist*mViewDirection;
977                        Vector3 up(0,1,0);
978
979                        glLoadIdentity();
980                        gluLookAt(pos.x, pos.y, pos.z,
981                                target.x, target.y, target.z,
982                                up.x, up.y, up.z);
983                }
984                else
985                {
986                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal()) * mTopDistance;
987                        Vector3 pos = mViewPoint  + dist * Vector3(0,   1, 0);
988
989                        Vector3 target = mViewPoint;
990                        Vector3 up(mViewDirection.x, 0, mViewDirection.z);
991
992                        glLoadIdentity();
993                        gluLookAt(pos.x, pos.y, pos.z,
994                                target.x, target.y, target.z,
995                                up.x, up.y, up.z);
996
997                }
998        }
999
1000}
1001
1002
1003void
1004QtGlRendererWidget::keyPressEvent ( QKeyEvent * e )
1005{
1006        switch (e->key())
1007        {
1008case Qt::Key_E:
1009        mRenderErrors = !mRenderErrors;
1010        updateGL();
1011        break;
1012case Qt::Key_R:
1013        mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject;;
1014        updateGL();
1015        break;
1016case Qt::Key_T:
1017        mTopView = !mTopView;
1018        SetupCameraProjection(width(), height());
1019        updateGL();
1020        break;
1021case Qt::Key_V:
1022        mRenderViewCells = !mRenderViewCells;
1023        updateGL();
1024        break;
1025case Qt::Key_P:
1026        // set random viewpoint
1027        mViewCellsManager->GetViewPoint(mViewPoint);
1028        updateGL();
1029        break;
1030case Qt::Key_S: {
1031        // set view poitn and direction
1032        QString text;
1033        bool ok;
1034        text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z);
1035        text = QInputDialog::getText(this,
1036                "Enter a view point",
1037                "",
1038                QLineEdit::Normal,
1039                text,
1040                &ok);
1041        if (!ok)
1042                break;
1043
1044        if (sscanf(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) {
1045                text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z);
1046                text = QInputDialog::getText(this,
1047                        "Enter a direction",
1048                        "",
1049                        QLineEdit::Normal,
1050                        text,
1051                        &ok);
1052                if (!ok)
1053                        break;
1054                if (sscanf(text.toAscii(), "%f %f %f", &mViewDirection.x,
1055                        &mViewDirection.y, &mViewDirection.z) == 3) {
1056                                updateGL();
1057                        }
1058                        break;
1059        }
1060                                }
1061default:
1062        cerr << "unknown key" << endl;
1063        e->ignore();
1064        break;
1065        }
1066}
1067
1068
1069
1070QtGlRendererWidget::QtGlRendererWidget(
1071                                                                           SceneGraph *sceneGraph,
1072                                                                           ViewCellsManager *viewcells,
1073                                                                           KdTree *tree,
1074                                                                           QWidget * parent,
1075                                                                           const QGLWidget * shareWidget,
1076                                                                           Qt::WFlags f
1077                                                                           )
1078                                                                           :
1079GlRendererWidget(sceneGraph, viewcells, tree), QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget, f)
1080{
1081        mPreprocessorThread = NULL;
1082        mTopView = false;
1083        mRenderViewCells = false;
1084        mTopDistance = 1.0f;
1085        mCutViewCells = false;
1086        mCutScene = false;
1087        mRenderErrors = false;
1088        mRenderBoxes = false;
1089        mRenderFilter = true;
1090        mRenderVisibilityEstimates = false;
1091        //mRenderVisibilityEstimates = true;
1092
1093        mComputeGVS = false;
1094        mUseRandomColorPerPvsObject = false;
1095        //mUseRandomColorPerPvsObject = true;
1096
1097        mHideByCost = false;
1098        mUseTransparency = false;
1099
1100        mTransferFunction = 1.0f;
1101        mIndexBufferSize = 0;
1102
1103        const int delay = 250; // in milliseconds
1104        mUpdateTimerId = startTimer(delay);
1105        mReplayTimerId = startTimer(1); // use fastest replay rate
1106
1107        bool tmp;
1108
1109        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
1110        mUseFilter = tmp;
1111
1112        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp );
1113        mUseSpatialFilter = tmp;
1114
1115        //mLogWriter = new LogWriter("myfile.out");
1116
1117        mShowRenderCost = false;
1118        mShowPvsSizes = false;
1119        mShowComparison = false;
1120        mShowPiercingRays = false;
1121        mShowWeightedRays = false;
1122        mUseStandardColors = false;
1123        mShowWeightedCost = true;
1124
1125        mShowDistanceWeightedPvs = true;
1126        mShowDistanceWeightedTriangles = false;
1127        mShowWeightedTriangles = false;
1128        mShowDistribution = 15;
1129        mCurrentDynamicObjectIdx = -1;
1130
1131        mSpatialFilterSize = 0.01;
1132        mPvsSize = 0;
1133        mRayVisualizationMethod = 0;
1134        mTrafoType = 0;
1135
1136        mRenderError = 0.0f;
1137
1138        mShowRays = false;
1139        mReplayMode = false;
1140
1141        mPlacer = new ObjectPlacer();
1142
1143        //mPendingDynamicObject = NULL;
1144
1145        SetSceneCut(1000);
1146        mControlWidget = new QtRendererControlWidget(NULL);
1147
1148        connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int)));
1149        connect(mControlWidget, SIGNAL(SetTransferFunction(int)), this, SLOT(SetTransferFunction(int)));
1150
1151        connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs()));
1152        connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility()));
1153        connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation()));
1154        connect(mControlWidget, SIGNAL(SetRandomViewPoint()), this,     SLOT(SetRandomViewPoint()));
1155        connect(mControlWidget, SIGNAL(StoreStatistics(void)), this, SLOT(StoreStatistics(void)));
1156        connect(mControlWidget, SIGNAL(ComputeGVS(void)), this, SLOT(ComputeGVS(void)));
1157        connect(mControlWidget, SIGNAL(ReplayViewPoints(void)), this, SLOT(ReplayViewPoints(void)));
1158        connect(mControlWidget, SIGNAL(LoadObject(void)), this, SLOT(LoadObject(void)));
1159
1160        connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int)));
1161        connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int)));
1162        connect(mControlWidget, SIGNAL(SetTransparency(int)), this, SLOT(SetTransparency(int)));
1163
1164        connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int)));
1165        connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int)));
1166        connect(mControlWidget, SIGNAL(SetHidingCost(int)), this, SLOT(SetHidingCost(int)));
1167
1168        connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool)));
1169        connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool)));
1170        connect(mControlWidget, SIGNAL(SetUseTransparency(bool)), this, SLOT(SetUseTransparency(bool)));
1171        connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool)));
1172        connect(mControlWidget, SIGNAL(SetShowComparison(bool)), this, SLOT(SetShowComparison(bool)));
1173        connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool)));
1174        connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool)));
1175        connect(mControlWidget, SIGNAL(SetHideByCost(bool)), this, SLOT(SetHideByCost(bool)));
1176        connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
1177        connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
1178        connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
1179        connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
1180        connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)), this, SLOT(SetRenderVisibilityEstimates(bool)));
1181        connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
1182        connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), this, SLOT(SetUseSpatialFilter(bool)));
1183        connect(mControlWidget, SIGNAL(SetShowPiercingRays(bool)), this, SLOT(SetShowPiercingRays(bool)));
1184        connect(mControlWidget, SIGNAL(SetShowWireFrame(bool)), this, SLOT(SetShowWireFrame(bool)));
1185        connect(mControlWidget, SIGNAL(SetShowWeightedRays(bool)), this, SLOT(SetShowWeightedRays(bool)));
1186        connect(mControlWidget, SIGNAL(SetShowWeightedCost(bool)), this, SLOT(SetShowWeightedCost(bool)));
1187
1188        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedTriangles(bool)), this, SLOT(SetShowDistanceWeightedTriangles(bool)));
1189        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedPvs(bool)), this, SLOT(SetShowDistanceWeightedPvs(bool)));
1190        connect(mControlWidget, SIGNAL(SetShowWeightedTriangles(bool)), this, SLOT(SetShowWeightedTriangles(bool)));
1191
1192        connect(mControlWidget, SIGNAL(UseConstColorForRayViz(bool)), this, SLOT(UseConstColorForRayViz(bool)));
1193        connect(mControlWidget, SIGNAL(UseRayLengthForRayViz(bool)), this, SLOT(UseRayLengthForRayViz(bool)));
1194        connect(mControlWidget, SIGNAL(SetShowContribution(bool)), this, SLOT(SetShowContribution(bool)));
1195        connect(mControlWidget, SIGNAL(SetShowDistribution(bool)), this, SLOT(SetShowDistribution(bool)));
1196
1197        connect(mControlWidget, SIGNAL(SetShowDistribution1(bool)), this, SLOT(SetShowDistribution1(bool)));
1198        connect(mControlWidget, SIGNAL(SetShowDistribution2(bool)), this, SLOT(SetShowDistribution2(bool)));
1199        connect(mControlWidget, SIGNAL(SetShowDistribution3(bool)), this, SLOT(SetShowDistribution3(bool)));
1200        connect(mControlWidget, SIGNAL(SetShowDistribution4(bool)), this, SLOT(SetShowDistribution4(bool)));
1201
1202        connect(mControlWidget, SIGNAL(SetShowRays(bool)), this, SLOT(SetShowRays(bool)));
1203
1204        connect(mControlWidget, SIGNAL(SetTranslation(bool)), this, SLOT(SetTranslation(bool)));
1205        connect(mControlWidget, SIGNAL(SetRotation(bool)), this, SLOT(SetRotation(bool)));
1206        connect(mControlWidget, SIGNAL(SetScale(bool)), this, SLOT(SetScale(bool)));
1207
1208        connect(mControlWidget, SIGNAL(UpdateDynamicObjects()), this, SLOT(UpdateDynamicObjects()));
1209
1210        setWindowTitle("PVS Visualization");
1211
1212        // setting the main window size here
1213        resize(800, 600);
1214        //resize(640, 400);
1215       
1216        mControlWidget->show();
1217}
1218
1219void
1220QtGlRendererWidget::UpdateAllPvs()
1221{
1222        // $$ does not work so far:(
1223        mViewCellsManager->UpdatePvsForEvaluation();
1224        //      mViewCellsManager->FinalizeViewCells(false);
1225}
1226
1227void
1228QtGlRendererWidget::ComputeVisibility()
1229{
1230        cerr<<"Compute Visibility called!\n"<<endl;
1231        if (!mPreprocessorThread->isRunning())
1232                mPreprocessorThread->RunThread();
1233}
1234
1235void
1236QtGlRendererWidget::StopComputation()
1237{
1238        cerr<<"stop computation called!\n"<<endl;
1239        mViewCellsManager->GetPreprocessor()->mStopComputation = true;
1240}
1241
1242void
1243QtGlRendererWidget::SetRandomViewPoint()
1244{
1245        cerr<<"setting random view point!\n"<<endl;
1246        mViewCellsManager->GetViewPoint(mViewPoint);
1247        updateGL();
1248}
1249
1250
1251void QtGlRendererWidget::StoreStatistics()
1252{
1253        cerr<<"storing statistics!\n"<<endl;
1254        const int currentSamples = mViewCellsManager->GetPreprocessor()->mCurrentSamples;
1255
1256        cout<<"**********************************************" << endl;
1257        cout << "reached " << currentSamples << " samples " << " => writing file" << endl;
1258               
1259        LogWriter writer;
1260        writer.SetFilename("compare.log");
1261        writer.Write(currentSamples, mViewCellsManager->GetViewCells());
1262        cout << "finished writing file" << endl;
1263        mCompareInfo.clear();
1264        updateGL();
1265}
1266
1267
1268void QtGlRendererWidget::LoadObject()
1269{
1270        string filename("../data/teapot.bn");
1271        //string filename("../data/cube.obj");
1272       
1273        cout << "Loading model << " << filename << endl;
1274
1275        ++ mCurrentDynamicObjectIdx;
1276
1277        SceneGraphLeaf *leaf =
1278                mViewCellsManager->GetPreprocessor()->LoadDynamicGeometry(filename);
1279
1280        if (leaf)
1281        {
1282                mPlacer->AddObject(leaf);
1283                cout << "Loading finished" << endl;
1284        }
1285        else
1286                cerr << "Loading failed" << endl;
1287       
1288    updateGL();
1289}
1290
1291
1292QtGlRendererWidget::~QtGlRendererWidget()
1293{
1294        delete mPlacer;
1295}
1296
1297
1298void
1299QtGlRendererWidget::RenderRenderCost()
1300{
1301        static vector<float> costFunction;
1302        static float maxCost = -1;
1303        if (costFunction.size()==0) {
1304                ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree();
1305                if (tree) {
1306                        tree->GetCostFunction(costFunction);
1307                        maxCost = -1;
1308                        for (int i=0;  i < costFunction.size(); i++) {
1309                                //                cout<<i<<":"<<costFunction[i]<<" ";
1310                                // update cost function to an absolute value based on the total geometry count
1311                                costFunction[i] *= mSceneGraph->GetSize();
1312                                if (costFunction[i] > maxCost)
1313                                        maxCost = costFunction[i];
1314                        }
1315                }
1316        }
1317
1318
1319        int currentPos = (int)mViewCellsManager->GetViewCells().size();
1320        float currentCost= -1;
1321
1322        if (currentPos < costFunction.size())
1323                currentCost = costFunction[currentPos];
1324#if 1   
1325        cout<<"costFunction.size()="<<(int)costFunction.size()<<endl;
1326        cout<<"CP="<<currentPos<<endl;
1327        cout<<"MC="<<maxCost<<endl;
1328        cout<<"CC="<<currentCost<<endl;
1329#endif
1330        if (costFunction.size()) {
1331                float scaley = 1.0f/log10(maxCost);
1332                float scalex = 1.0f/(float)costFunction.size();
1333
1334                glDisable(GL_DEPTH_TEST);
1335                // init ortographic projection
1336                glMatrixMode(GL_PROJECTION);
1337
1338                glPushMatrix();
1339
1340                glLoadIdentity();
1341                gluOrtho2D(0, 1.0f, 0, 1.0f);
1342
1343                glTranslatef(0.1f, 0.1f, 0.0f);
1344                glScalef(0.8f, 0.8f, 1.0f);
1345                glMatrixMode(GL_MODELVIEW);
1346                glLoadIdentity();
1347
1348                glColor3f(1.0f,0,0);
1349                glBegin(GL_LINE_STRIP);
1350                //        glVertex3f(0,0,0);
1351
1352                for (int i=0;  i < costFunction.size(); i++) {
1353                        float x =  i*scalex;
1354                        float y = log10(costFunction[i])*scaley;
1355                        glVertex3f(x,y,0.0f);
1356                }
1357                glEnd();
1358
1359                glColor3f(1.0f,0,0);
1360                glBegin(GL_LINES);
1361                float x =  currentPos*scalex;
1362                glVertex3f(x,0.0,0.0f);
1363                glVertex3f(x,1.0f,0.0f);
1364                glEnd();
1365
1366                glColor3f(0.0f,0,0);
1367                // show a grid
1368                glBegin(GL_LINE_LOOP);
1369                glVertex3f(0,0,0.0f);
1370                glVertex3f(1,0,0.0f);
1371                glVertex3f(1,1,0.0f);
1372                glVertex3f(0,1,0.0f);
1373                glEnd();
1374
1375                glBegin(GL_LINES);
1376                for (int i=0;  i < costFunction.size(); i += 1000) {
1377                        float x =  i*scalex;
1378                        glVertex3f(x,0.0,0.0f);
1379                        glVertex3f(x,1.0f,0.0f);
1380                }
1381
1382                for (int i=0;  pow(10.0f, i) < maxCost; i+=1) {
1383                        float y = i*scaley;
1384                        //              QString s;
1385                        //              s.sprintf("%d", (int)pow(10,i));
1386                        //              renderText(width()/2+5, y*height(), s);
1387                        glVertex3f(0.0f, y, 0.0f);
1388                        glVertex3f(1.0f, y, 0.0f);
1389                }
1390
1391                glEnd();
1392
1393
1394                // restore the projection matrix
1395                glMatrixMode(GL_PROJECTION);
1396                glPopMatrix();
1397                glMatrixMode(GL_MODELVIEW);
1398                glEnable(GL_DEPTH_TEST);
1399
1400        }
1401
1402
1403
1404}
1405
1406void
1407QtGlRendererWidget::RenderInfo()
1408{
1409
1410        QString s;
1411
1412        int vc = 0;
1413        if (mViewCellsManager)
1414                vc = (int)mViewCellsManager->GetViewCells().size();
1415
1416        int filter = 0;
1417        if (mViewCellsManager)
1418                filter = mViewCellsManager->GetMaxFilterSize();
1419
1420        glColor3f(0.0f, 0.0f, 1.0f);
1421
1422#if REMOVE_TEMPORARY
1423        s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)",
1424                mFrame,
1425                mViewPoint.x,
1426                mViewPoint.y,
1427                mViewPoint.z,
1428                mViewDirection.x,
1429                mViewDirection.y,
1430                mViewDirection.z
1431                );
1432
1433        renderText(20, 20, s);
1434
1435        s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f %",
1436                vc,
1437                filter,
1438                mPvsSize,
1439                mRenderError*100.0f);
1440
1441        renderText(20, 40, s);
1442#endif
1443
1444        QFont font40; font40.setPointSize(30);
1445        //s.sprintf("PVS: %04d", mPvsSize);
1446        //renderText(20, 40, s, font40);
1447       
1448        //s.sprintf("RAW TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats);
1449        //renderText(290, 40, s, font40);
1450        //s.sprintf("PVS TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats2);
1451        //renderText(290, 70, s, font40);
1452
1453        s.sprintf("PVS TRI: %07d", (int)mCurrentPvsCost);
1454        renderText(290, 70, s, font40);
1455        //renderText(290, 70, s, font40);
1456
1457}
1458
1459
1460void
1461QtGlRendererWidget::SetViewCellGranularity(int number)
1462{
1463        if (mViewCellsManager)
1464        {
1465                //      mViewCellsManager->SetMaxFilterSize(number);
1466
1467                // $$ tmp off
1468                mViewCellsManager->CollectViewCells(number);
1469
1470                // $$ does not work so far:(
1471                //      mViewCellsManager->UpdatePvsForEvaluation();
1472                //      mViewCellsManager->FinalizeViewCells(false);
1473        }
1474        updateGL();
1475}
1476
1477void
1478QtGlRendererWidget::SetVisibilityFilterSize(int number)
1479{
1480        if (mViewCellsManager)
1481                mViewCellsManager->SetMaxFilterSize(number);
1482
1483        mPvsCache.Reset();
1484        updateGL();
1485}
1486
1487void
1488QtGlRendererWidget::SetSpatialFilterSize(int number)
1489{
1490        mSpatialFilterSize = 1e-3*number;
1491        mPvsCache.Reset();
1492        updateGL();
1493}
1494
1495void
1496QtGlRendererWidget::SetSceneCut(int number)
1497{
1498        // assume the cut plane can only be aligned with xz plane
1499        // shift it along y according to number, which is percentage of the bounding
1500        // box position
1501        if (mViewCellsManager)
1502        {
1503                const float f = number / 1000.0f;
1504                AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
1505                Vector3 p = (1.0f - f) * box.Min() + f * box.Max();
1506                mSceneCutPlane.mNormal = Vector3(0, -1, 0);
1507                mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p);
1508
1509                updateGL();
1510        }
1511}
1512
1513void
1514QtGlRendererWidget::SetHidingCost(int number)
1515{
1516        mHidingCost = (float)number / 1000.0f;
1517}
1518
1519
1520void
1521QtGlRendererWidget::SetTopDistance(int number)
1522{
1523        mTopDistance = number / 1000.0f;
1524        updateGL();
1525}
1526
1527void QtGlRendererWidget::SetTransparency(int number)
1528{
1529        mTransparency = number / 1000.0f;
1530        updateGL();
1531}
1532
1533#if 0
1534float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1535{
1536        ObjectPvs basePvs;
1537       
1538        basePvs = vc->CopyPvs();
1539        ObjectPvsIterator pit = basePvs.GetIterator();
1540
1541        float renderCost = 0;
1542
1543        //cout << "cost vis: " << mShowDistanceWeightedPvs << " " << " " << mShowDistanceWeightedTriangles << " " << mShowWeightedTriangles << endl;
1544       
1545        // first mark all objects from this pvs
1546        while (pit.HasMoreEntries())   
1547        {
1548                KdIntersectable *kdObj = static_cast<KdIntersectable *>(pit.Next());
1549
1550                if (mShowDistanceWeightedPvs)
1551                {
1552                        const AxisAlignedBox3 box = kdObj->GetBox();
1553
1554                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1555                        renderCost += 1.0f / dist;
1556                }
1557                else if (mShowDistanceWeightedTriangles)
1558                {
1559                        const AxisAlignedBox3 box = kdObj->GetBox();
1560
1561                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1562                        renderCost += kdObj->ComputeNumTriangles() / dist;
1563                }
1564                else //if (mShowWeightedTriangles)
1565                {
1566                        renderCost += kdObj->ComputeNumTriangles();
1567                }
1568                //if (pit.Next()->Mail();
1569        }
1570
1571        return renderCost;
1572}
1573#else
1574
1575float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1576{
1577        float renderCost = 0;
1578
1579#ifdef USE_VERBOSE_PVS
1580        if (mShowDistanceWeightedPvs)
1581        {
1582                return vc->GetPvs().mStats.mDistanceWeightedPvs;
1583        }
1584        else if (mShowDistanceWeightedTriangles)
1585        {
1586                return vc->GetPvs().mStats.mDistanceWeightedTriangles;
1587        }
1588        else //if (mShowWeightedTriangles)
1589        {
1590                return vc->GetPvs().mStats.mWeightedTriangles;
1591        }
1592#else
1593        return 0.0f;
1594#endif
1595}
1596#endif
1597
1598
1599
1600void QtGlRendererWidget::ComputeMaxValues(const ViewCellContainer &viewCells,
1601                                                                                  int &maxPvs,
1602                                                                                  int &maxPiercingRays,
1603                                                                                  float &maxRelativeRays,
1604                                                                                  float &maxRcCost)
1605{
1606        maxPvs = -1;
1607        maxPiercingRays = 1; // not zero for savety
1608        maxRelativeRays = Limits::Small; // not zero for savety
1609        maxRcCost = Limits::Small;
1610
1611        for (size_t i = 0; i < viewCells.size(); ++ i)
1612        {
1613                ViewCell *vc = viewCells[i];
1614
1615                if (mShowPvsSizes) // pvs size
1616                {
1617                        //const int p = vc->GetPvs().CountObjectsInPvs();
1618                        const int p = vc->GetPvs().GetSize();
1619                        if (p > maxPvs)
1620                                maxPvs = p;
1621                }
1622                else if (mShowPiercingRays) // relative number of rays
1623                {
1624                        const int piercingRays = vc->GetNumPiercingRays();
1625
1626                        if (piercingRays > maxPiercingRays)
1627                                maxPiercingRays = piercingRays;
1628                }
1629                else if (mShowWeightedRays)
1630                {
1631                        const int piercingRays = vc->GetNumPiercingRays();
1632
1633                        const float relativeArea =
1634                                vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1635
1636                        if ((float)piercingRays / relativeArea > maxRelativeRays)
1637                                maxRelativeRays = (float)piercingRays / relativeArea;
1638                }
1639                else if (mShowWeightedCost)
1640                {
1641                        const float rcCost = ComputeRenderCost(vc);
1642                        mViewCellsManager->UpdateScalarPvsCost(vc, rcCost);
1643
1644                        if (rcCost > maxRcCost)
1645                                maxRcCost = rcCost;
1646                }
1647        }
1648}
1649
1650
1651void QtGlRendererWidget::RenderViewCells()
1652{
1653        mUseFalseColors = true;
1654        //glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
1655
1656        glEnable(GL_CULL_FACE);
1657        glCullFace(GL_FRONT);
1658        //glDisable(GL_CULL_FACE);
1659
1660        if (mCutViewCells)
1661        {
1662                double eq[4];
1663                eq[0] = mSceneCutPlane.mNormal.x;
1664                eq[1] = mSceneCutPlane.mNormal.y;
1665                eq[2] = mSceneCutPlane.mNormal.z;
1666                eq[3] = mSceneCutPlane.mD;
1667
1668                glClipPlane(GL_CLIP_PLANE0, eq);
1669                glEnable(GL_CLIP_PLANE0);
1670        }
1671
1672        ViewCellContainer &viewcells = mViewCellsManager->GetViewCells();
1673       
1674        int maxPvs, maxPiercingRays;
1675        float maxRelativeRays, maxRcCost;
1676
1677        ComputeMaxValues(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1678       
1679        // matt: temp hack
1680        //maxRcCost = 5000.0f;
1681        //cout << "maxRcCost: " << maxRcCost << endl;
1682
1683        int i;
1684
1685        // transparency
1686        if (!mUseTransparency)
1687        {
1688                glEnable(GL_DEPTH_TEST);
1689                glDisable(GL_BLEND);
1690        }
1691        else
1692        {
1693                glDisable(GL_DEPTH_TEST);
1694                glEnable(GL_BLEND);
1695
1696                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1697                //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1698
1699                for (i = 0; i < viewcells.size(); ++ i)
1700                {
1701                        ViewCell *vc = viewcells[i];
1702
1703                        const float dist = SqrDistance(mDummyViewPoint, vc->GetBox().Center());
1704                        vc->SetDistance(dist);
1705                }
1706
1707                sort(viewcells.begin(), viewcells.end(), nearerThan);
1708        }
1709
1710        //mWireFrame = true;
1711               
1712        // normal rendering
1713        //if (!mShowPvsSizes && !mShowPiercingRays && !mShowWeightedRays && !mShowWeightedCost && !mShowComparison)
1714        if (mUseStandardColors)
1715        {
1716                for (i = 0; i < viewcells.size(); ++ i)
1717                {
1718                        ViewCell *vc = viewcells[i];
1719                        RgbColor c;
1720
1721                        //if (!mShowPvsSizes && !mShowPiercingRays)
1722                        c = vc->GetColor();
1723                       
1724                        glColor3f(c.r, c.g, c.b);
1725
1726                        if (!mHideByCost || (mHidingCost < (vc->GetNumPiercingRays() / (float)maxPiercingRays)))
1727                        {
1728                RenderViewCell(vc);
1729                        }
1730                }
1731        }
1732        else // using specialised colors
1733        {
1734                if (!mShowComparison)
1735                        AssignImportanceByRelativeValue(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1736                else
1737                {
1738                        if (mCompareInfo.empty())
1739                        {
1740                                LogReader reader;
1741                                reader.SetFilename("compare.log");
1742                                int samples;
1743                                reader.Read(samples, mCompareInfo);
1744                        }
1745
1746                        AssignColorByComparison(viewcells, mCompareInfo);
1747                }
1748
1749                glEnable(GL_DEPTH_TEST);       
1750        }
1751       
1752        glEnable(GL_CULL_FACE);
1753        glDisable(GL_CULL_FACE);
1754
1755        glDisable(GL_CLIP_PLANE0);
1756
1757        mUseFalseColors = false;
1758        mWireFrame = false;
1759
1760        glPopAttrib();
1761}
1762
1763
1764void QtGlRendererWidget::AssignImportanceByRelativeValue(const ViewCellContainer &viewCells,
1765                                                                                                                 int &maxPvs,
1766                                                                                                                 int &maxPiercingRays,
1767                                                                                                                 float &maxRelativeRays,
1768                                                                                                                 float &maxRcCost)
1769{
1770        for (size_t i = 0; i < viewCells.size(); ++ i)
1771        {
1772                RgbColor c;
1773                ViewCell *vc = viewCells[i];
1774
1775                float importance;
1776
1777                if (mShowPiercingRays)
1778                {
1779                        importance = mTransferFunction *
1780                                ((float)vc->GetNumPiercingRays() / (float)maxPiercingRays);
1781                }
1782                else if (mShowWeightedRays) // relative number of rays
1783                {
1784                        float relativeArea = vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1785
1786                        if (relativeArea < Limits::Small)
1787                                relativeArea = Limits::Small;
1788
1789                        importance = mTransferFunction * ((float)vc->GetNumPiercingRays() / relativeArea) / maxRelativeRays;
1790                }
1791                else if (mShowPvsSizes) // pvs size
1792                {
1793                        importance = mTransferFunction *
1794                                ((float)vc->GetPvs().GetSize() / (float)maxPvs);
1795                } // weighted render cost
1796                else if (mShowWeightedCost)
1797                {
1798                        const float rcCost = mTransferFunction * ComputeRenderCost(vc);
1799                        importance = rcCost / maxRcCost;
1800                }
1801if (importance > 1.0f) importance = 1.0f;
1802                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1803                c = RainbowColorMapping(importance);
1804
1805                glColor4f(c.r, c.g, c.b, 1.0f - mTransparency);
1806
1807                if (!mHideByCost || (mHidingCost < importance))
1808                {
1809                        RenderViewCell(vc);
1810                }
1811        }
1812}
1813
1814
1815void QtGlRendererWidget::AssignColorByComparison(const ViewCellContainer &viewcells,
1816                                                                                                 //const ViewCellInfoContainer &infos1,
1817                                                                                                 const ViewCellInfoContainer &compareInfo)
1818{
1819        if (viewcells.size() > compareInfo.size())
1820        {
1821                cerr << "loaded size (" << (int)compareInfo.size()
1822                         << ") does not fit to view cells size (" << (int)viewcells.size() << ")" << endl;
1823                return;
1824        }
1825
1826        //const float maxRatio = 1.0f;
1827        const float maxRatio = 2.0f;
1828        const float minRatio = 0.0f;
1829
1830        const float scale = 1.0f / (maxRatio - minRatio);
1831
1832        for (size_t i = 0; i < viewcells.size(); ++ i)
1833        {
1834                RgbColor c;
1835                ViewCell *vc = viewcells[i];
1836
1837                //ViewCellInfo vc1Info = infos1[i];
1838                ViewCellInfo vc2Info = compareInfo[i];
1839
1840                //const float vcRatio = vc->GetNumPiercingRays() / vc2Info.mPiercingRays + Limits::Small;
1841                float vcRatio = 1.0f;//maxRatio;
1842               
1843                if (vc2Info.mPvsSize > Limits::Small)
1844                        vcRatio = (float)vc->GetPvs().GetSize() / vc2Info.mPvsSize;
1845
1846                // truncate here
1847                if (vcRatio > maxRatio) vcRatio = 1.0f;
1848
1849                const float importance = (vcRatio - minRatio) * scale;
1850       
1851                if (0 && (i < 20))
1852                {
1853                        cout << "pvs1: " << vc->GetPvs().GetSize() << " pvs2: " << compareInfo[i].mPvsSize << " importance: " << importance << endl;
1854                }
1855
1856                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1857                c = RainbowColorMapping(importance);
1858
1859                glColor4f(c.r, c.g, c.b, 1.0f);
1860
1861                if (1)//!mHideByCost || (mHidingCost < importance))
1862                {
1863                        RenderViewCell(vc);
1864                }
1865        }
1866}
1867
1868
1869
1870/**********************************************************************/
1871/*              QtRendererControlWidget implementation                */
1872/**********************************************************************/
1873
1874
1875QGroupBox *QtRendererControlWidget::CreateVisualizationPanel(QWidget *parent)
1876{
1877        QRadioButton *rb1, *rb2, *rb3, *rb4, *rb5;
1878       
1879        rb1 = new QRadioButton("random colors", parent);
1880        rb1->setText("random");
1881        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWireFrame(bool)));
1882
1883        // Create a check box to be in the group box
1884        rb2 = new QRadioButton("piercing rays", parent);
1885        rb2->setText("piercing rays");
1886        //vl->addWidget(rb1);
1887        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowPiercingRays(bool)));
1888
1889        rb3 = new QRadioButton("pvs size", parent);
1890        rb3->setText("pvs size");
1891        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool)));
1892       
1893        rb4 = new QRadioButton("weighted rays", parent);
1894        rb4->setText("weighted rays");
1895        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedRays(bool)));
1896       
1897        rb5 = new QRadioButton("pvs cost", parent);
1898        rb5->setText("pvs cost");
1899        connect(rb5, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedCost(bool)));
1900
1901        QGroupBox *groupBox = new QGroupBox("PVS Visualization");
1902
1903        QVBoxLayout *vbox2 = new QVBoxLayout;
1904   
1905        vbox2->addWidget(rb1);
1906        vbox2->addWidget(rb2);
1907        vbox2->addWidget(rb3);
1908        vbox2->addWidget(rb4);
1909        vbox2->addWidget(rb5);
1910       
1911        rb5->setChecked(true);
1912
1913        vbox2->addStretch(1);
1914        groupBox->setLayout(vbox2);
1915
1916        return groupBox;
1917}
1918
1919
1920QGroupBox *QtRendererControlWidget::CreateTrafoPanel(QWidget *parent)
1921{
1922        QRadioButton *rb1, *rb2, *rb3;
1923       
1924        rb1 = new QRadioButton("translation", parent);
1925        rb1->setText("translation");
1926        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetTranslation(bool)));
1927
1928        // Create a check box to be in the group box
1929        rb2 = new QRadioButton("scale", parent);
1930        rb2->setText("scale");
1931        //vl->addWidget(rb1);
1932        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetScale(bool)));
1933
1934        rb3 = new QRadioButton("rotation", parent);
1935        rb3->setText("rotation");
1936        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetRotation(bool)));
1937   
1938        QVBoxLayout *vbox2 = new QVBoxLayout;
1939        QGroupBox *groupBox = new QGroupBox("Trafo types");
1940
1941        vbox2->addWidget(rb1);
1942        vbox2->addWidget(rb2);
1943        vbox2->addWidget(rb3);
1944       
1945        rb1->setChecked(true);
1946
1947        vbox2->addStretch(1);
1948
1949
1950        QPushButton *button = new QPushButton("Update", groupBox);
1951        vbox2->addWidget(button);
1952        connect(button, SIGNAL(clicked()), SIGNAL(UpdateDynamicObjects()));
1953       
1954       
1955        groupBox->setLayout(vbox2);
1956       
1957        return groupBox;
1958}
1959
1960
1961QGroupBox *QtRendererControlWidget::CreateRenderCostPanel(QWidget *parent)
1962{
1963        QRadioButton *rb1, *rb2, *rb3;
1964       
1965        // Create a check box to be in the group box
1966        rb1 = new QRadioButton("triangles", parent);
1967        rb1->setText("triangles");
1968        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedTriangles(bool)));
1969
1970        rb2 = new QRadioButton("distance weighted pvs", parent);
1971        rb2->setText("distance weighted");
1972        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedPvs(bool)));
1973
1974        rb3 = new QRadioButton("distance weighted triangles", parent);
1975        rb3->setText("distance weighted triangles");
1976        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedTriangles(bool)));
1977
1978        QGroupBox *groupBox = new QGroupBox("Render cost options");
1979        QVBoxLayout *vbox2 = new QVBoxLayout;
1980   
1981        vbox2->addWidget(rb1);
1982        vbox2->addWidget(rb2);
1983        vbox2->addWidget(rb3);
1984       
1985        rb1->setChecked(true);
1986
1987        vbox2->addStretch(1);
1988        groupBox->setLayout(vbox2);
1989
1990        return groupBox;
1991}
1992
1993
1994QGroupBox *QtRendererControlWidget::CreateRayVisualizationPanel(QWidget *parent)
1995{
1996        QRadioButton *rb1, *rb2, *rb3, *rb4;
1997       
1998        // Create a check box to be in the group box
1999        rb1 = new QRadioButton("const color", parent);
2000        rb1->setText("const color");
2001        //vl->addWidget(rb1);
2002        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(UseConstColorForRayViz(bool)));
2003
2004        rb2 = new QRadioButton("ray length", parent);
2005        rb2->setText("ray length");
2006        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(UseRayLengthForRayViz(bool)));
2007       
2008        rb3 = new QRadioButton("contribution", parent);
2009        rb3->setText("contribution");
2010        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowContribution(bool)));
2011       
2012        rb4 = new QRadioButton("distribution", parent);
2013        rb4->setText("distribution");
2014        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution(bool)));
2015
2016
2017        ///////////////////////////
2018
2019       
2020        QGroupBox *groupBox = new QGroupBox("Ray visualization");
2021        QVBoxLayout *vbox2 = new QVBoxLayout;
2022   
2023        vbox2->addWidget(rb1);
2024        vbox2->addWidget(rb2);
2025        vbox2->addWidget(rb3);
2026        vbox2->addWidget(rb4);
2027       
2028        rb1->setChecked(true);
2029
2030
2031        QCheckBox *cb = new QCheckBox("Distribution 1", parent);
2032        vbox2->addWidget(cb);
2033        cb->setChecked(true);
2034        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution1(bool)));
2035
2036        cb = new QCheckBox("Distribution 2", parent);
2037        vbox2->addWidget(cb);
2038        cb->setChecked(true);
2039        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution2(bool)));
2040
2041        cb = new QCheckBox("Distribution 3", parent);
2042        vbox2->addWidget(cb);
2043        cb->setChecked(true);
2044        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution3(bool)));
2045       
2046        cb = new QCheckBox("Distribution 4", parent);
2047        vbox2->addWidget(cb);
2048        cb->setChecked(true);
2049        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution4(bool)));
2050
2051
2052        vbox2->addStretch(1);
2053        groupBox->setLayout(vbox2);
2054
2055        return groupBox;
2056}
2057
2058
2059QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f):
2060QWidget(parent, f)
2061{
2062
2063        QVBoxLayout *vl = new QVBoxLayout;
2064        setLayout(vl);
2065       
2066        //QWidget *vbox;
2067
2068        //vbox = new QGroupBox("Render Controls", this);
2069        //layout()->addWidget(vbox);
2070        //vl = new QVBoxLayout;
2071        //vbox->setLayout(vl);
2072
2073        QLabel *label;
2074        QSlider *slider;
2075        QPushButton *button;
2076
2077#if 0//REMOVE_TEMPORARY
2078
2079        label = new QLabel("Granularity");
2080        //vbox->layout()->addWidget(label);
2081        vl->addWidget(label);
2082
2083        slider = new QSlider(Qt::Horizontal);
2084        vl->addWidget(slider);
2085        slider->show();
2086        slider->setRange(1, 10000);
2087        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2088        slider->setValue(200);
2089
2090        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int)));
2091
2092        ///////////////////////////
2093
2094        label = new QLabel("Transfer function");
2095        vl->addWidget(label);
2096
2097        slider = new QSlider(Qt::Horizontal);
2098        vl->addWidget(slider);
2099        slider->show();
2100        slider->setRange(1, 10000);
2101        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2102        slider->setValue(100);
2103
2104
2105        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int)));
2106
2107        ////////////////////////////////////////7
2108
2109        button = new QPushButton("Update all PVSs");
2110        vl->addWidget(button);
2111        connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs()));
2112
2113        ////////////////////////////////////////77777
2114
2115        label = new QLabel("Filter size");
2116        vl->addWidget(label);
2117
2118        slider = new QSlider(Qt::Horizontal);
2119        vl->addWidget(slider);
2120        slider->show();
2121        slider->setRange(1, 100);
2122        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2123        slider->setValue(3);
2124
2125        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int)));
2126
2127#endif
2128
2129
2130       
2131        ///////////////////////////////////
2132
2133
2134        QWidget *hbox = new QWidget();
2135        vl->addWidget(hbox);
2136        QHBoxLayout *hlayout = new QHBoxLayout;
2137        hbox->setLayout(hlayout);
2138
2139        QCheckBox *cb = new QCheckBox("Show viewcells", hbox);
2140        hlayout->addWidget(cb);
2141        cb->setChecked(false);
2142        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool)));
2143       
2144        cb = new QCheckBox("Render errors", hbox);
2145        hlayout->layout()->addWidget(cb);
2146        cb->setChecked(false);
2147        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
2148
2149#if REMOVE_TEMPORARY
2150        cb = new QCheckBox("Render cost curve", hbox);
2151        hlayout->addWidget(cb);
2152        cb->setChecked(false);
2153        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool)));
2154#endif
2155        cb = new QCheckBox("Show rays", hbox);
2156        hlayout->addWidget(cb);
2157        cb->setChecked(false);
2158        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool)));
2159#if REMOVE_TEMPORARY   
2160        cb = new QCheckBox("Show Comparison", hbox);
2161        hlayout->addWidget(cb);
2162        cb->setChecked(false);
2163        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowComparison(bool)));
2164#endif
2165
2166        //////////////////
2167
2168        QHBoxLayout *vh = new QHBoxLayout;
2169
2170        QGroupBox *myBox = new QGroupBox("Visualization");
2171
2172        myBox->setLayout(vh);
2173        vl->addWidget(myBox, 0, 0);
2174
2175        QGroupBox *groupBox = CreateVisualizationPanel(hbox);
2176        vh->addWidget(groupBox, 0, 0);
2177
2178#if REMOVE_TEMPORARY
2179        QGroupBox *groupBox2 = CreateRenderCostPanel(hbox);
2180        vh->addWidget(groupBox2, 0, 0);
2181       
2182        QGroupBox *groupBox3 = CreateRayVisualizationPanel(hbox);
2183        vh->addWidget(groupBox3, 0, 0);
2184
2185        QGroupBox *groupBox4 = CreateTrafoPanel(hbox);
2186        vh->addWidget(groupBox4, 0, 0);
2187#endif
2188
2189        //////////////////////////////////
2190
2191        bool tmp = false;
2192        const int range = 1000;
2193
2194        //vbox->resize(800,150);
2195        QWidget *vbox;
2196
2197        vbox = new QGroupBox("Rendering", this);
2198        layout()->addWidget(vbox);
2199
2200        vl = new QVBoxLayout;
2201        vbox->setLayout(vl);
2202
2203
2204        cb = new QCheckBox("Cut view cells", vbox);
2205        vbox->layout()->addWidget(cb);
2206        cb->setChecked(false);
2207        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool)));
2208
2209
2210        slider = new QSlider(Qt::Horizontal, vbox);
2211        vbox->layout()->addWidget(slider);
2212        slider->show();
2213        slider->setRange(0, 1000);
2214        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2215        slider->setValue(1000);
2216
2217        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
2218
2219
2220        cb = new QCheckBox("Use spatial filter", vbox);
2221        vbox->layout()->addWidget(cb);
2222        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp);
2223        cb->setChecked(tmp);
2224        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
2225
2226
2227        label = new QLabel("Spatial Filter size");
2228        vbox->layout()->addWidget(label);
2229       
2230        slider = new QSlider(Qt::Horizontal, vbox);
2231        vbox->layout()->addWidget(slider);
2232        slider->show();
2233        slider->setRange(1, 100);
2234        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2235        slider->setValue(10);
2236
2237        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int)));
2238
2239        ////////////////////////////
2240
2241       
2242        cb = new QCheckBox("Hide view cells by render cost ", vbox);
2243        vbox->layout()->addWidget(cb);
2244        cb->setChecked(false);
2245        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetHideByCost(bool)));
2246
2247        label = new QLabel("Hide by cost");
2248        vbox->layout()->addWidget(label);
2249
2250        // the render cost visualization
2251        slider = new QSlider(Qt::Horizontal, vbox);
2252        vbox->layout()->addWidget(slider);
2253        slider->show();
2254        slider->setRange(0, range);
2255        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2256        slider->setValue(0);
2257        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetHidingCost(int)));
2258
2259        ///////////////////////////////////////////
2260
2261        cb = new QCheckBox("Top View", vbox);
2262        vbox->layout()->addWidget(cb);
2263        cb->setChecked(false);
2264        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
2265
2266
2267        label = new QLabel("Top distance");
2268        vbox->layout()->addWidget(label);
2269       
2270        slider = new QSlider(Qt::Horizontal, vbox);
2271        vbox->layout()->addWidget(slider);
2272        slider->show();
2273        slider->setRange(1, 1000);
2274        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2275        slider->setValue(500);
2276
2277        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int)));
2278       
2279
2280        ///////////////////////////////////////////
2281#if REMOVE_TEMPORARY
2282        cb = new QCheckBox("Transparency", vbox);
2283        vbox->layout()->addWidget(cb);
2284        cb->setChecked(false);
2285        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseTransparency(bool)));
2286
2287        label = new QLabel("Use transparency");
2288        vbox->layout()->addWidget(label);
2289
2290        // the render cost visualization
2291        slider = new QSlider(Qt::Horizontal, vbox);
2292        vbox->layout()->addWidget(slider);
2293        slider->show();
2294        slider->setRange(0, range);
2295        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2296        slider->setValue(0);
2297        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransparency(int)));
2298#endif
2299       
2300
2301        //////////////////////////////
2302
2303#if REMOVE_TEMPORARY
2304
2305        cb = new QCheckBox("Cut scene", vbox);
2306        vbox->layout()->addWidget(cb);
2307        cb->setChecked(false);
2308        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool)));
2309
2310        cb = new QCheckBox("Render boxes", vbox);
2311        vbox->layout()->addWidget(cb);
2312        cb->setChecked(false);
2313        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
2314
2315        cb = new QCheckBox("Render visibility estimates", vbox);
2316        vbox->layout()->addWidget(cb);
2317        cb->setChecked(false);
2318        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
2319#endif
2320
2321#if REMOVE_TEMPORARY
2322
2323        cb = new QCheckBox("Use filter", vbox);
2324        vbox->layout()->addWidget(cb);
2325        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp);
2326        cb->setChecked(tmp);
2327        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
2328#endif
2329
2330
2331       
2332
2333#if REMOVE_TEMPORARY
2334       
2335        cb = new QCheckBox("Render filter", vbox);
2336        vbox->layout()->addWidget(cb);
2337        cb->setChecked(true);
2338        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool)));
2339
2340        /*vbox = new QGroupBox("PVS Errors", this);
2341        layout()->addWidget(vbox);
2342
2343        vl = new QVBoxLayout;
2344        vbox->setLayout(vl);
2345
2346        button = new QPushButton("Compute Visibility", vbox);
2347        vbox->layout()->addWidget(button);
2348        connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility()));
2349
2350        button = new QPushButton("Stop Computation", vbox);
2351        vbox->layout()->addWidget(button);
2352        connect(button, SIGNAL(clicked()), SLOT(StopComputation()));
2353
2354        button = new QPushButton("Set Random View Point", vbox);
2355        vbox->layout()->addWidget(button);
2356        connect(button, SIGNAL(clicked()), SLOT(SetRandomViewPoint()));*/
2357
2358        button = new QPushButton("Store statistics", vbox);
2359        vbox->layout()->addWidget(button);
2360        connect(button, SIGNAL(clicked()), SIGNAL(StoreStatistics()));
2361
2362#endif
2363
2364#if 0
2365       
2366        button = new QPushButton("Compute GVS", vbox);
2367        vbox->layout()->addWidget(button);
2368        connect(button, SIGNAL(clicked()), SIGNAL(ComputeGVS()));
2369#endif
2370
2371#if 1   
2372        button = new QPushButton("Replay view points", vbox);
2373        vbox->layout()->addWidget(button);
2374        connect(button, SIGNAL(clicked()), SIGNAL(ReplayViewPoints()));
2375
2376#endif
2377
2378        button = new QPushButton("Load object", vbox);
2379        vbox->layout()->addWidget(button);
2380        connect(button, SIGNAL(clicked()), SIGNAL(LoadObject()));
2381
2382        /*cb = new QCheckBox("Stats", vbox);
2383        vbox->layout()->addWidget(cb);
2384        cb->setChecked(false);
2385        connect(cb, SIGNAL(toggled(bool)), SIGNAL(StoreStatistics()));*/
2386
2387        if (0)
2388        {
2389                vbox = new QGroupBox("PVS Errors", this);
2390                layout()->addWidget(vbox);
2391
2392                vl = new QVBoxLayout;
2393                vbox->setLayout(vl);
2394
2395                mPvsErrorWidget = new QListWidget(vbox);
2396                vbox->layout()->addWidget(mPvsErrorWidget);
2397
2398                connect(mPvsErrorWidget,
2399                        SIGNAL(doubleClicked(const QModelIndex &)),
2400                        this,
2401                        SLOT(PvsErrorClicked(const QModelIndex &)));
2402
2403                button = new QPushButton("Next Error Frame", vbox);
2404                vbox->layout()->addWidget(button);
2405                connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void)));
2406        }
2407       
2408        //connect(button, SIGNAL(clicked(void)), SLOT(StoreStatistics(void)));
2409       
2410        //////////////////////////////////////////
2411
2412
2413        setWindowTitle("Preprocessor Control Widget");
2414        adjustSize();
2415}
2416
2417
2418
2419
2420void
2421QtRendererControlWidget::FocusNextPvsErrorFrame(void)
2422{}
2423
2424void
2425QtRendererControlWidget::UpdatePvsErrorItem(int row,
2426                                                                                        GlRendererBuffer::PvsErrorEntry &pvsErrorEntry)
2427{
2428
2429        QListWidgetItem *i = mPvsErrorWidget->item(row);
2430        QString s;
2431        s.sprintf("%5.5f", pvsErrorEntry.mError);
2432        if (i) {
2433                i->setText(s);
2434        } else {
2435                new QListWidgetItem(s, mPvsErrorWidget);
2436        }
2437        mPvsErrorWidget->update();
2438}
2439
2440
2441
2442
2443/*********************************************************************/
2444/*                   QtGlDebuggerWidget implementation               */
2445/*********************************************************************/
2446
2447
2448QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent)
2449: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf)
2450{
2451        // create the pbuffer
2452        //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
2453        //mUpdateTimerId = startTimer(20);
2454        setWindowTitle(("OpenGL pbuffers"));
2455}
2456
2457
2458QtGlDebuggerWidget::~QtGlDebuggerWidget()
2459{
2460        mRenderBuffer->releaseFromDynamicTexture();
2461        glDeleteTextures(1, &dynamicTexture);
2462
2463        DEL_PTR(mRenderBuffer);
2464}
2465
2466
2467void QtGlDebuggerWidget::initializeGL()
2468{
2469        glMatrixMode(GL_PROJECTION);
2470        glLoadIdentity();
2471
2472        glFrustum(-1, 1, -1, 1, 10, 100);
2473        glTranslatef(-0.5f, -0.5f, -0.5f);
2474        glTranslatef(0.0f, 0.0f, -15.0f);
2475        glMatrixMode(GL_MODELVIEW);
2476
2477        glEnable(GL_CULL_FACE);
2478        initCommon();
2479        initPbuffer();
2480
2481}
2482
2483
2484void QtGlDebuggerWidget::resizeGL(int w, int h)
2485{
2486        glViewport(0, 0, w, h);
2487}
2488
2489
2490void QtGlDebuggerWidget::paintGL()
2491{
2492        // draw a spinning cube into the pbuffer..
2493        mRenderBuffer->makeCurrent();
2494
2495        BeamSampleStatistics stats;
2496        mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats);
2497
2498        glFlush();
2499
2500        // rendering directly to a texture is not supported on X11, unfortunately
2501        mRenderBuffer->updateDynamicTexture(dynamicTexture);
2502
2503        // and use the pbuffer contents as a texture when rendering the
2504        // background and the bouncing cubes
2505        makeCurrent();
2506        glBindTexture(GL_TEXTURE_2D, dynamicTexture);
2507        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2508
2509        // draw the background
2510        glMatrixMode(GL_MODELVIEW);
2511        glPushMatrix();
2512        glLoadIdentity();
2513        glMatrixMode(GL_PROJECTION);
2514        glPushMatrix();
2515        glLoadIdentity();
2516
2517        glPopMatrix();
2518        glMatrixMode(GL_MODELVIEW);
2519        glPopMatrix();
2520}
2521
2522
2523void QtGlDebuggerWidget::initPbuffer()
2524{
2525        // set up the pbuffer context
2526        mRenderBuffer->makeCurrent();
2527       
2528        // generate a texture that has the same size/format as the pbuffer
2529        dynamicTexture = mRenderBuffer->generateDynamicTexture();
2530
2531        // bind the dynamic texture to the pbuffer - this is a no-op under X11
2532        mRenderBuffer->bindToDynamicTexture(dynamicTexture);
2533        //makeCurrent();
2534}
2535
2536
2537void QtGlDebuggerWidget::initCommon()
2538{
2539        glEnable(GL_TEXTURE_2D);
2540        glEnable(GL_DEPTH_TEST);
2541
2542        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2543}
2544
2545
2546void QtGlRendererWidget::_RenderColoredPvs()
2547{
2548        // note: could be done more efficiently using color buffers
2549        mPvsSize = mPvsCache.mPvs.GetSize();
2550
2551        ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
2552
2553        PvsData pvsData;
2554
2555        while (it.HasMoreEntries())
2556        {
2557                Intersectable *obj = it.Next(pvsData);
2558
2559                RgbColor color;
2560
2561                //cerr << "sumpdf: " << pvsData.mSumPdf << endl;
2562                if (mUseRandomColorPerPvsObject)
2563                {
2564                        KdIntersectable *kdint = static_cast<KdIntersectable *>(obj);
2565
2566                        if (kdint->mGenericIdx == -1)
2567                        {
2568                                kdint->mGenericIdx = (int)mColors.size();
2569                                mColors.push_back(RandomColor(0, 1));
2570                        }
2571                        color = mColors[kdint->mGenericIdx];
2572                }
2573                else
2574                {
2575                        color = RainbowColorMapping(mTransferFunction * log10(pvsData.mSumPdf + 1));
2576                }
2577
2578                glColor3f(color.r, color.g, color.b);
2579
2580                mUseForcedColors = true;
2581                RenderIntersectable(obj);
2582                mUseForcedColors = false;
2583        }
2584}
2585
2586
2587void QtGlRendererWidget::UpdateDynamicObjects()
2588{
2589        preprocessor->ScheduleUpdateDynamicObjects(); 
2590}
2591
2592
2593void QtGlRendererWidget::ReplayViewPoints()
2594{
2595        ViewCellPointsList *vcPoints = mViewCellsManager->GetViewCellPointsList();
2596
2597        ViewCellPointsList::const_iterator vit, vit_end = vcPoints->end();
2598
2599        sViewPointsList.clear();
2600
2601        for (vit = vcPoints->begin(); vit != vit_end; ++ vit)
2602        {
2603                ViewCellPoints *vp = *vit;
2604
2605                SimpleRayContainer::const_iterator rit, rit_end = vp->second.end();
2606       
2607                for (rit = vp->second.begin(); rit != rit_end; ++ rit)
2608                {
2609                        sViewPointsList.push_back(*rit);
2610                }
2611        }
2612
2613        if (!sViewPointsList.empty())
2614        {
2615                cout << "replaying " << (int)sViewPointsList.size() << " view points " << endl;
2616
2617                mReplayMode = true;
2618                sViewPointsListIt = sViewPointsList.begin();
2619        }
2620}
2621
2622
2623
2624Vector3 QtGlRendererWidget::Unproject(int x, int y)
2625{
2626        // swap y coordinate
2627        y = GetHeight() - y;
2628
2629        // HACK: should come from camera!
2630        double projection[16];
2631        glGetDoublev(GL_PROJECTION_MATRIX, projection);
2632        double modelview[16];
2633        glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
2634
2635        const int viewport[4] = {0,0, GetWidth(), GetHeight()};
2636
2637        RenderScene();
2638
2639        float z;
2640        glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
2641       
2642        GLdouble rx, ry, rz;
2643        gluUnProject(x, y, z, modelview, projection, viewport, &rx, &ry, &rz);
2644
2645        return Vector3(rx, ry, rz);
2646}
2647
2648
2649int QtGlRendererWidget::FindDynamicObject(float x, float y)
2650{
2651        makeCurrent();
2652        // we need to lock the rendering context
2653        //glw.lockGLContext();
2654       
2655        // this is the same as in every OpenGL picking example
2656        const int maxSize = 512;
2657       
2658        // see below for an explanation on the buffer content
2659        GLuint buffer[maxSize];
2660        glSelectBuffer(maxSize, buffer);
2661       
2662        // enter select mode
2663        glRenderMode(GL_SELECT);
2664        glInitNames();
2665        glPushName(0);
2666       
2667        glMatrixMode(GL_PROJECTION);
2668        glPushMatrix();
2669        glLoadIdentity();
2670
2671        glViewport(0, 0, width(), height());
2672
2673        GLint viewport[4];
2674        glGetIntegerv(GL_VIEWPORT, viewport);
2675
2676        const float w = 1.0f;
2677
2678        //gluPickMatrix(x, y, 1000.0, 1000.0, viewport);
2679        gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), w, w, viewport);
2680
2681        GLfloat aspect = (GLfloat) width() / height();
2682        gluPerspective(70.0f, aspect, 0.1f, 2.0f * Magnitude(mSceneGraph->GetBox().Diagonal()));
2683       
2684        glMatrixMode(GL_MODELVIEW);
2685        glPushMatrix();
2686        glLoadIdentity();
2687        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2688       
2689       
2690        SetupCamera();
2691
2692        for (size_t i = 0; i < GetPreprocessor()->mDynamicObjects.size(); ++ i)
2693        {
2694                glLoadName(i);
2695                _RenderDynamicObject(GetPreprocessor()->mDynamicObjects[i]);
2696        }
2697
2698        glFlush();
2699        glPopMatrix();
2700
2701        glMatrixMode(GL_PROJECTION);
2702        glPopMatrix();
2703
2704        //updateGL();
2705
2706        int hits;
2707        // finally release the rendering context again
2708        if ((hits = glRenderMode(GL_RENDER)) < 0)
2709        {
2710                cout << "no object picked" << endl;
2711                //glw.unlockGLContext();
2712                return -1;
2713        }
2714
2715
2716        //processHits(hits, buffer);
2717
2718       
2719        //glw.unlockGLContext();
2720       
2721        // Each hit takes 4 items in the buffer.
2722        // The first item is the number of names on the name stack when the hit occured.
2723        // The second item is the minimum z value of all the verticies that intersected
2724        // the viewing area at the time of the hit. The third item is the maximum z value
2725        // of all the vertices that intersected the viewing area at the time of the hit
2726        // and the last item is the content of the name stack at the time of the hit
2727        // (name of the object). We are only interested in the object name
2728        // (number of the surface).
2729        // return the name of the clicked surface
2730        return buffer[3];
2731}
2732
2733
2734}
Note: See TracBrowser for help on using the repository browser.