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

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