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

Revision 1743, 53.8 KB checked in by bittner, 18 years ago (diff)

merge with new pvs

  • Property svn:executable set to *
Line 
1#include "Mesh.h"
2#include "glInterface.h"
3#include "OcclusionQuery.h"
4#include "QtGlRenderer.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
17
18#include <Cg/cg.h>
19#include <Cg/cgGL.h>
20
21#include <QVBoxLayout>
22
23namespace GtpVisibilityPreprocessor {
24
25
26#define CAMERA_VIEW_WIDTH 0.5f
27 
28class ViewCellsManager;
29
30static CGcontext sCgContext = NULL;
31static CGprogram sCgFragmentProgram = NULL;
32static CGprofile sCgFragmentProfile;
33
34GLuint frontDepthMap;
35GLuint backDepthMap;
36
37const int depthMapSize = 512;
38
39//static vector<OcclusionQuery *> sQueries;
40
41QtGlRendererWidget *rendererWidget = NULL;
42QtGlDebuggerWidget *debuggerWidget = NULL;
43
44
45static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
46{
47        return obj1->mId < obj2->mId;
48}
49
50
51static void handleCgError()
52{
53    Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl;
54    exit(1);
55}
56
57void
58QtGlRendererBuffer::EvalRenderCostSample(RenderCostSample &sample,
59                                                                                 const bool useOcclusionQueries,
60                                                                                 const int threshold
61                                                                                 )
62{
63        // choose a random view point
64        mViewCellsManager->GetViewPoint(mViewPoint);
65        sample.mPosition = mViewPoint;
66        //cout << "viewpoint: " << mViewPoint << endl;
67
68        // take a render cost sample by rendering a cube
69        Vector3 directions[6];
70
71        directions[0] = Vector3(1,0,0);
72        directions[1] = Vector3(0,1,0);
73        directions[2] = Vector3(0,0,1);
74        directions[3] = Vector3(-1,0,0);
75        directions[4] = Vector3(0,-1,0);
76        directions[5] = Vector3(0,0,-1);
77
78        sample.mVisibleObjects = 0;
79
80        // reset object counters
81        ObjectContainer::const_iterator it, it_end = mObjects.end();
82
83        for (it = mObjects.begin(); it != it_end; ++ it)
84        {
85                (*it)->mCounter = 0;
86        }
87
88        ++ mFrame;
89
90        //glCullFace(GL_FRONT);
91        glCullFace(GL_BACK);
92        glDisable(GL_CULL_FACE);
93       
94
95        // query all 6 directions for a full point sample
96        for (int i = 0; i < 6; ++ i)
97        {
98                mViewDirection = directions[i];
99                SetupCamera();
100
101                glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
102                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103                //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);      glDepthMask(GL_TRUE);
104                glDepthFunc(GL_LESS);
105
106                mUseFalseColors = true;
107
108                // the actual scene rendering fills the depth (for occlusion queries)
109                // and the frame buffer (for item buffer)
110                RenderScene();
111
112
113                if (0)
114                {
115                        char filename[256];
116                        sprintf(filename, "snap/frame-%04d-%d.png", mFrame, i);
117                        QImage im = toImage();
118                        im.save(filename, "PNG");
119                }
120         
121                // evaluate the sample
122                if (useOcclusionQueries)
123                {
124                        EvalQueryWithOcclusionQueries();
125                }
126                else
127                {
128                        EvalQueryWithItemBuffer();
129                }
130        } 
131
132        // now evaluate the statistics over that sample
133        // currently only the number of visible objects is taken into account
134        sample.Reset();
135
136        for (it = mObjects.begin(); it != it_end; ++ it)
137        {
138                Intersectable *obj = *it;
139                if (obj->mCounter >= threshold)
140                {
141                        ++ sample.mVisibleObjects;
142                        sample.mVisiblePixels += obj->mCounter;
143                }
144        }
145
146        //cout << "RS=" << sample.mVisibleObjects << " ";
147}
148
149
150QtGlRendererBuffer::~QtGlRendererBuffer()
151{
152        if (sCgFragmentProgram)
153                cgDestroyProgram(sCgFragmentProgram);
154        if (sCgContext)
155                cgDestroyContext(sCgContext);
156}
157
158
159void
160QtGlRendererBuffer::SampleRenderCost(const int numSamples,
161                                                                         vector<RenderCostSample> &samples,
162                                                                         const bool useOcclusionQueries,
163                                                                         const int threshold
164                                                                         )
165{
166  makeCurrent();
167
168  if (mPixelBuffer == NULL)
169          mPixelBuffer = new unsigned int[GetWidth()*GetHeight()];
170 
171  // using 90 degree projection to capture 360 view with 6 samples
172  SetupProjection(GetHeight(), GetHeight(), 90.0f);
173
174  //samples.resize(numSamples);
175  halton.Reset();
176 
177  // the number of queries queried in batch mode
178  const int numQ = 500;
179
180  //const int numQ = (int)mObjects.size();
181  if (useOcclusionQueries)
182  {
183          cout << "\ngenerating " << numQ << " queries ... ";
184          OcclusionQuery::GenQueries(mOcclusionQueries, numQ);
185          cout << "finished" << endl;
186  }
187
188  // sampling queries
189  for (int i = 0; i < numSamples; ++ i)
190  {
191          cout << ".";
192          EvalRenderCostSample(samples[i], useOcclusionQueries, threshold);
193  }
194
195  doneCurrent();
196
197}
198 
199
200
201QtGlRendererBuffer::QtGlRendererBuffer(const int w,
202                                                                           const int h,
203                                                                           SceneGraph *sceneGraph,
204                                                                           ViewCellsManager *viewcells,
205                                                                           KdTree *tree):
206  QGLPixelBuffer(QSize(w, h)), GlRendererBuffer(sceneGraph, viewcells, tree) {
207 
208  Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", mPvsStatFrames);
209  mPvsErrorBuffer.resize(mPvsStatFrames);
210  ClearErrorBuffer();
211
212  mPixelBuffer = NULL;
213 
214  makeCurrent();
215  InitGL();
216  doneCurrent();
217 
218}
219
220float
221QtGlRendererBuffer::GetPixelError(int &pvsSize)
222{
223  float pErrorPixels = -1.0f;
224 
225  glReadBuffer(GL_BACK);
226 
227  //  mUseFalseColors = true;
228 
229  mUseFalseColors = false;
230  unsigned int pixelCount;
231
232  //static int query = -1;
233  //if (query == -1)
234//        glGenOcclusionQueriesNV(1, (unsigned int *)&query);
235
236  OcclusionQuery query;
237
238  if (mDetectEmptyViewSpace) {
239        // now check whether any backfacing polygon would pass the depth test
240        SetupCamera();
241        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
242        glEnable( GL_CULL_FACE );
243       
244        RenderScene();
245       
246        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
247        glDepthMask(GL_FALSE);
248        glDisable( GL_CULL_FACE );
249
250       
251        query.BeginQuery();
252       
253        RenderScene();
254       
255        query.EndQuery();
256       
257        // at this point, if possible, go and do some other computation
258        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
259        glDepthMask(GL_TRUE);
260        glEnable( GL_CULL_FACE );
261       
262        // reenable other state
263        pixelCount = query.GetQueryResult();
264       
265        if (pixelCount > 0)
266          return -1.0f; // backfacing polygon found -> not a valid viewspace sample
267  } else
268        glDisable( GL_CULL_FACE );
269       
270
271  ViewCell *viewcell = NULL;
272 
273  PrVs prvs;
274 
275  mViewCellsManager->SetMaxFilterSize(0);
276  mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth());
277  viewcell = prvs.mViewCell;
278 
279  //  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
280  pvsSize = 0;
281  if (viewcell) {
282        SetupCamera();
283        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
284
285        glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
286       
287        // Render PVS
288        ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
289
290        pvsSize = viewcell->GetPvs().GetSize();
291       
292        for (; it.HasMoreEntries(); ) {
293          ObjectPvsEntry entry = it.Next();
294          Intersectable *object = entry.mObject;
295          RenderIntersectable(object);
296        }
297
298        //      glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
299        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
300        mUseFalseColors = true;
301
302        query.BeginQuery();
303
304        SetupCamera();
305
306        RenderScene();
307       
308        query.EndQuery();
309       
310
311        unsigned int pixelCount;
312        // reenable other state
313        pixelCount = query.GetQueryResult();
314       
315       
316        pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight());
317        if (mSnapErrorFrames && pErrorPixels > 0.01) {
318         
319          char filename[256];
320          sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
321          QImage im = toImage();
322          string str = mSnapPrefix + filename;
323          QString qstr(str.c_str());
324
325          im.save(qstr, "PNG");
326          if (1) { //0 && mFrame == 1543) {
327                int x,y;
328                int lastIndex = -1;
329                for (y=0; y < im.height(); y++)
330                  for (x=0; x < im.width(); x++) {
331                        QRgb p = im.pixel(x,y);
332                        int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
333                        if (qGreen(p) != 255 && index!=0) {
334                          if (index != lastIndex) {
335                                //                              Debug<<"ei="<<index<<" ";
336                                lastIndex = index;
337                          }
338                        }
339                  }
340          }
341
342
343          mUseFalseColors = false;
344          glPushAttrib(GL_CURRENT_BIT);
345          glColor3f(0,1,0);
346          glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
347          SetupCamera();
348          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
349         
350          // Render PVS
351          ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
352          for (; it.HasMoreEntries(); ) {
353                ObjectPvsEntry entry = it.Next();
354                Intersectable *object = entry.mObject;
355                RenderIntersectable(object);
356          }
357
358          im = toImage();
359          sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
360          str = mSnapPrefix + filename;
361          qstr = str.c_str();
362          im.save(qstr, "PNG");
363          glPopAttrib();
364        }
365        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
366  }
367
368  if (viewcell && mViewCellsManager->GetMaxFilterSize() > 0)
369        mViewCellsManager->DeleteLocalMergeTree(viewcell);
370 
371  return pErrorPixels;
372}
373
374
375void
376QtGlRendererBuffer::ClearErrorBuffer()
377{
378  for (int i=0; i < mPvsStatFrames; i++) {
379        mPvsErrorBuffer[i].mError = 1.0f;
380  }
381}
382
383
384void
385QtGlRendererBuffer::EvalPvsStat()
386{
387  mPvsStat.Reset();
388  halton.Reset();
389
390  makeCurrent();
391
392  SetupProjection(GetWidth(), GetHeight());
393 
394  for (int i=0; i < mPvsStatFrames; i++) {
395        float err;
396        // set frame id for saving the error buffer
397        mFrame = i;
398        RandomViewPoint();
399
400        // atlanta problematic frames: 325 525 691 1543
401#if 0
402        if (mFrame != 325 &&
403                mFrame != 525 &&
404                mFrame != 691 &&
405                mFrame != 1543)
406          mPvsErrorBuffer[i] = -1;
407        else {
408          Debug<<"frame ="<<mFrame<<" vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
409        }
410#endif
411        if (mPvsErrorBuffer[i].mError > 0.0f) {
412          int pvsSize;
413
414
415          float error = GetPixelError(pvsSize);
416          mPvsErrorBuffer[i].mError = error;
417          mPvsErrorBuffer[i].mPvsSize = pvsSize;
418
419          emit UpdatePvsErrorItem(i,
420                                                          mPvsErrorBuffer[i]);
421         
422          cout<<"("<<i<<","<<mPvsErrorBuffer[i].mError<<")";
423          //      swapBuffers();
424        }
425       
426        err = mPvsErrorBuffer[i].mError;
427       
428        if (err >= 0.0f) {
429          if (err > mPvsStat.maxError)
430                mPvsStat.maxError = err;
431          mPvsStat.sumError += err;
432          mPvsStat.sumPvsSize += mPvsErrorBuffer[i].mPvsSize;
433         
434          if (err == 0.0f)
435                mPvsStat.errorFreeFrames++;
436          mPvsStat.frames++;
437        }
438  }
439
440  glFinish();
441  doneCurrent();
442
443  cout<<endl<<flush;
444  //  mRenderingFinished.wakeAll();
445}
446
447
448
449
450
451
452
453void QtGlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject,
454                                                                                           Beam &beam,
455                                                                                           const int desiredSamples,
456                                                                                           BeamSampleStatistics &stat)
457{
458        // TODO: should be moved out of here (not to be done every time)
459        // only back faces are interesting for the depth pass
460        glShadeModel(GL_FLAT);
461        glDisable(GL_LIGHTING);
462
463        // needed to kill the fragments for the front buffer
464        glEnable(GL_ALPHA_TEST);
465        glAlphaFunc(GL_GREATER, 0);
466
467        // assumes that the beam is constructed and contains kd-tree nodes
468        // and viewcells which it intersects
469 
470 
471        // Get the number of viewpoints to be sampled
472        // Now it is a sqrt but in general a wiser decision could be made.
473        // The less viewpoints the better for rendering performance, since less passes
474        // over the beam is needed.
475        // The viewpoints could actually be generated outside of the bounding box which
476        // would distribute the 'efective viewpoints' of the object surface and thus
477        // with a few viewpoints better sample the viewpoint space....
478
479        //TODO: comment in
480        //int viewPointSamples = sqrt((float)desiredSamples);
481        int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1);
482       
483        // the number of direction samples per pass is given by the number of viewpoints
484        int directionalSamples = desiredSamples / viewPointSamples;
485       
486        Debug << "directional samples: " << directionalSamples << endl;
487        for (int i = 0; i < viewPointSamples; ++ i)
488        {
489                Vector3 viewPoint = beam.mBox.GetRandomPoint();
490               
491                // perhaps the viewpoint should be shifted back a little bit so that it always lies
492                // inside the source object
493                // 'ideally' the viewpoints would be distributed on the soureObject surface, but this
494        // would require more complicated sampling (perhaps hierarchical rejection sampling of
495                // the object surface is an option here - only the mesh faces which are inside the box
496                // are considered as candidates)
497               
498                SampleViewpointContributions(sourceObject,
499                                                                         viewPoint,
500                                                                         beam,
501                                                                         directionalSamples,
502                                                                         stat);
503        }
504
505
506        // note:
507        // this routine would be called only if the number of desired samples is sufficiently
508        // large - for other rss tree cells the cpu based sampling is perhaps more efficient
509        // distributing the work between cpu and gpu would also allow us to place more sophisticated
510        // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
511        // in order that thios scheme is working well the gpu render buffer should run in a separate
512        // thread than the cpu sampler, which would not be such a big problem....
513
514        // disable alpha test again
515        glDisable(GL_ALPHA_TEST);
516}
517
518
519
520void QtGlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
521                                                                                                        const Vector3 viewPoint,
522                                                                                                        Beam &beam,
523                                                                                                        const int samples,
524                                                    BeamSampleStatistics &stat)
525{
526    // 1. setup the view port to match the desired samples
527        glViewport(0, 0, samples, samples);
528
529        // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
530        SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
531
532
533        // 3. reset z-buffer to 0 and render the source object for the beam
534        //    with glCullFace(Enabled) and glFrontFace(GL_CW)
535        //    save result to the front depth map
536        //    the front depth map holds ray origins
537
538
539        // front depth buffer must be initialised to 0
540        float clearDepth;
541       
542        glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
543        glClearDepth(0.0f);
544        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
545
546
547        //glFrontFace(GL_CW);
548        glEnable(GL_CULL_FACE);
549        glCullFace(GL_FRONT);
550        glColorMask(0, 0, 0, 0);
551       
552
553        // stencil is increased where the source object is located
554        glEnable(GL_STENCIL_TEST);     
555        glStencilFunc(GL_ALWAYS, 0x1, 0x1);
556        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
557
558
559#if 0
560        static int glSourceObjList = -1;         
561        if (glSourceObjList != -1)
562        {
563                glSourceObjList = glGenLists(1);
564                glNewList(glSourceObjList, GL_COMPILE);
565
566                RenderIntersectable(sourceObject);
567       
568                glEndList();
569        }
570        glCallList(glSourceObjList);
571
572#else
573        RenderIntersectable(sourceObject);
574
575#endif 
576
577         // copy contents of the front depth buffer into depth texture
578        glBindTexture(GL_TEXTURE_2D, frontDepthMap);   
579        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
580
581
582        // reset clear function
583        glClearDepth(clearDepth);
584
585       
586       
587        // 4. set up the termination depth buffer (= standard depth buffer)
588        //    only rays which have non-zero entry in the origin buffer are valid since
589        //    they realy start on the object surface (this is tagged by setting a
590        //    stencil buffer bit at step 3).
591       
592        glStencilFunc(GL_EQUAL, 0x1, 0x1);
593        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
594
595        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
596        glDepthMask(1);
597
598        glEnable(GL_DEPTH_TEST);
599               
600        glEnable(GL_CULL_FACE);
601        glCullFace(GL_BACK);
602
603        // setup front depth buffer
604        glEnable(GL_TEXTURE_2D);
605       
606        // bind pixel shader implementing the front depth buffer functionality
607        cgGLBindProgram(sCgFragmentProgram);
608        cgGLEnableProfile(sCgFragmentProfile);
609
610
611        // 5. render all objects inside the beam
612        //    we can use id based false color to read them back for gaining the pvs
613
614        glColorMask(1, 1, 1, 1);
615
616       
617        // if objects not stored in beam => extract objects
618        if (beam.mFlags & !Beam::STORE_OBJECTS)
619        {
620                vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
621
622                Intersectable::NewMail();
623                for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
624                {
625                        mKdTree->CollectObjects(*it, beam.mObjects);
626                }
627        }
628
629
630        //    (objects can be compiled to a gl list now so that subsequent rendering for
631        //    this beam is fast - the same hold for step 3)
632        //    Afterwards we have two depth buffers defining the ray origin and termination
633       
634
635#if 0
636        static int glObjList = -1;
637        if (glObjList != -1)
638        {
639                glObjList = glGenLists(1);
640                glNewList(glObjList, GL_COMPILE);
641       
642                ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
643                for (it = beam.mObjects.begin(); it != it_end; ++ it)
644                {
645                        // render all objects except the source object
646                        if (*it != sourceObject)
647                                RenderIntersectable(*it);
648                }
649               
650                glEndList();
651        }
652
653        glCallList(glObjList);
654#else
655        ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
656        for (it = beam.mObjects.begin(); it != it_end; ++ it)
657        {       
658                // render all objects except the source object
659                if (*it != sourceObject)
660                        RenderIntersectable(*it);
661        }
662#endif
663       
664   
665
666        // 6. Use occlusion queries for all viewcell meshes associated with the beam ->
667        //     a fragment passes if the corresponding stencil fragment is set and its depth is
668        //     between origin and termination buffer
669
670        // create new queries if necessary
671        OcclusionQuery::GenQueries(mOcclusionQueries, (int)beam.mViewCells.size());
672
673        // check whether any backfacing polygon would pass the depth test?
674        // matt: should check both back /front facing because of dual depth buffer
675        // and danger of cutting the near plane with front facing polys.
676       
677        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
678        glDepthMask(GL_FALSE);
679        glDisable(GL_CULL_FACE);
680
681 
682        ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
683
684        int queryIdx = 0;
685
686        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
687        {
688                mOcclusionQueries[queryIdx ++]->BeginQuery();
689
690                RenderIntersectable(*vit);
691               
692                mOcclusionQueries[queryIdx]->EndQuery();
693
694                ++ queryIdx;
695        }
696
697
698
699        // at this point, if possible, go and do some other computation
700
701
702       
703        // 7. The number of visible pixels is the number of sample rays which see the source
704        //    object from the corresponding viewcell -> remember these values for later update
705        //   of the viewcell pvs - or update immediately?
706
707        queryIdx = 0;
708
709        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
710        {
711                // fetch queries
712                unsigned int pixelCount = mOcclusionQueries[queryIdx ++]->GetQueryResult();
713
714                if (pixelCount)
715                        Debug << "view cell " << (*vit)->GetId() << " visible pixels: " << pixelCount << endl;
716        }
717       
718
719        // 8. Copmpute rendering statistics
720        // In general it is not neccessary to remember to extract all the rays cast. I hope it
721        // would be sufficient to gain only the intergral statistics about the new contributions
722        // and so the rss tree would actually store no new rays (only the initial ones)
723        // the subdivision of the tree would only be driven by the statistics (the glrender could
724        // evaluate the contribution entropy for example)
725        // However might be an option to extract/store only those the rays which made a contribution
726        // (new viewcell has been discovered) or relative contribution greater than a threshold ...
727
728        ObjectContainer pvsObj;
729        stat.pvsSize = ComputePvs(beam.mObjects, pvsObj);
730       
731        // to gain ray source and termination
732        // copy contents of ray termination buffer into depth texture
733        // and compare with ray source buffer
734#if 0
735        VssRayContainer rays;
736
737        glBindTexture(GL_TEXTURE_2D, backDepthMap);     
738        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
739
740        ComputeRays(Intersectable *sourceObj, rays);
741
742#endif
743
744
745
746        //-- cleanup
747
748
749        // reset gl state
750        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
751        glDepthMask(GL_TRUE);
752        glEnable(GL_CULL_FACE);
753        glDisable(GL_STENCIL_TEST);
754        cgGLDisableProfile(sCgFragmentProfile);
755        glDisable(GL_TEXTURE_2D);
756
757        // remove objects from beam
758        if (beam.mFlags & !Beam::STORE_OBJECTS)
759                beam.mObjects.clear();
760}
761
762
763void QtGlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint,
764                                                                                                   const Beam &beam,
765                                                                                                   Intersectable *sourceObject)
766{
767        float left, right, bottom, top, znear, zfar;
768
769        beam.ComputePerspectiveFrustum(left, right, bottom, top, znear, zfar,
770                                                                   mSceneGraph->GetBox());
771
772        //Debug << left << " " << right << " " << bottom << " " << top << " " << znear << " " << zfar << endl;
773        glMatrixMode(GL_PROJECTION);
774        glLoadIdentity();
775        glFrustum(left, right, bottom, top, znear, zfar);
776        //glFrustum(-1, 1, -1, 1, 1, 20000);
777
778    const Vector3 center = viewPoint + beam.GetMainDirection() * (zfar - znear) * 0.3f;
779        const Vector3 up =
780                Normalize(CrossProd(beam.mPlanes[0].mNormal, beam.mPlanes[4].mNormal));
781
782#ifdef GTP_DEBUG
783        Debug << "view point: " << viewPoint << endl;
784        Debug << "eye: " << center << endl;
785        Debug << "up: " << up << endl;
786#endif
787
788        glMatrixMode(GL_MODELVIEW);
789        glLoadIdentity();
790        gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z,
791                          center.x, center.y, center.z,                   
792                          up.x, up.y, up.z);
793}               
794
795 
796void QtGlRendererBuffer::InitGL()
797{
798 makeCurrent();
799 GlRenderer::InitGL();
800
801#if 1
802        // initialise dual depth buffer textures
803        glGenTextures(1, &frontDepthMap);
804        glBindTexture(GL_TEXTURE_2D, frontDepthMap);
805       
806        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
807                                 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
808
809        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
810        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
811        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
812        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
813
814        glGenTextures(1, &backDepthMap);
815        glBindTexture(GL_TEXTURE_2D, backDepthMap);
816       
817        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
818                depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
819        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
820        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
821        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
822        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
823
824        // cg initialization
825        cgSetErrorCallback(handleCgError);
826        sCgContext = cgCreateContext();
827       
828        if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
829                sCgFragmentProfile = CG_PROFILE_ARBFP1;
830        else
831        {
832          // try FP30
833          if (cgGLIsProfileSupported(CG_PROFILE_FP30))
834            sCgFragmentProfile = CG_PROFILE_FP30;
835          else
836          {
837                  Debug << "Neither arbfp1 or fp30 fragment profiles supported on this system" << endl;
838                  exit(1);
839          }
840  }
841
842
843 sCgFragmentProgram = cgCreateProgramFromFile(sCgContext,
844                                                                                           CG_SOURCE, "../src/dual_depth.cg",
845                                                                                           sCgFragmentProfile,
846                                                                                           NULL,
847                                                                                           NULL);
848
849  if (!cgIsProgramCompiled(sCgFragmentProgram))
850          cgCompileProgram(sCgFragmentProgram);
851
852  cgGLLoadProgram(sCgFragmentProgram);
853  cgGLBindProgram(sCgFragmentProgram);
854
855  Debug << "---- PROGRAM BEGIN ----\n" <<
856          cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n";
857
858#endif
859  doneCurrent();
860}
861
862
863void QtGlRendererBuffer::ComputeRays(Intersectable *sourceObj, VssRayContainer &rays)
864{
865        for (int i = 0; i < depthMapSize * depthMapSize; ++ i)
866        {
867                //todo glGetTexImage()
868        }
869}
870
871
872
873int QtGlRendererBuffer::ComputePvs(ObjectContainer &objects,
874                                                                   ObjectContainer &pvs) const
875{
876        int pvsSize = 0;
877        QImage image = toImage();
878        Intersectable::NewMail();
879
880        std::stable_sort(objects.begin(), objects.end(), ilt);
881
882        MeshInstance dummy(NULL);
883
884        Intersectable *obj = NULL;
885                       
886        for (int x = 0; x < image.width(); ++ x)
887        {
888                for (int y = 0; y < image.height(); ++ y)
889                {
890                        QRgb pix = image.pixel(x, y);
891                        const int id = GetId(qRed(pix), qGreen(pix), qBlue(pix));
892
893                        dummy.SetId(id);
894
895                        ObjectContainer::iterator oit =
896                                lower_bound(objects.begin(), objects.end(), &dummy, ilt);
897                       
898                       
899                        if (//(oit != oit.end()) &&
900                                ((*oit)->GetId() == id) &&
901                                !obj->Mailed())
902                        {
903                                obj = *oit;
904                                obj->Mail();
905                                ++ pvsSize;
906                                pvs.push_back(obj);
907                        }
908                }
909        }
910
911        return pvsSize;
912}
913
914
915
916void
917QtGlRendererWidget::SetupCameraProjection(const int w, const int h, const float angle)
918{
919  if (!mTopView) {
920        int ww = w*CAMERA_VIEW_WIDTH;
921        int hh = h;
922        glViewport(0, 0, ww, hh);
923        glMatrixMode(GL_PROJECTION);
924        glLoadIdentity();
925        gluPerspective(angle, ww/(float)hh, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
926        glMatrixMode(GL_MODELVIEW);
927  } else {
928        int ww = w*CAMERA_VIEW_WIDTH;
929        int hh = h;
930        glViewport(0, 0, ww, hh);
931        glMatrixMode(GL_PROJECTION);
932        glLoadIdentity();
933        gluPerspective(50.0, ww/(float)hh, 0.1, 20.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
934        glMatrixMode(GL_MODELVIEW);
935  }
936}
937
938void
939QtGlRendererWidget::SetupManipulatorProjection(const int w, const int h, const float angle)
940{
941  int ww = w*(1.0f - CAMERA_VIEW_WIDTH);
942  int hh = h;
943  glViewport(w - ww, 0, ww, hh);
944  glMatrixMode(GL_PROJECTION);
945  glLoadIdentity();
946  gluPerspective(angle, ww/(float)hh, 0.1f, 1000.0f);
947  glMatrixMode(GL_MODELVIEW);
948}
949
950
951void
952QtGlRendererWidget::RenderPvs()
953{
954 
955  Intersectable::NewMail();
956
957  ViewCell *viewcell = NULL;
958
959  PrVs prvs;
960 
961  if (1 || !mUseFilter) {
962        viewcell = mViewCellsManager->GetViewCell(mViewPoint, true);
963  } else {
964        //  mViewCellsManager->SetMaxFilterSize(1);
965        mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth());
966        viewcell = prvs.mViewCell;
967  }
968 
969  if (viewcell) {
970        // copy the pvs so that it can be filtered...
971       
972        ObjectPvs &pvs = mPvsCache.mPvs;
973       
974        if (mPvsCache.mViewCell != viewcell) {
975          mPvsCache.Reset();
976          mPvsCache.mViewCell = viewcell;
977         
978          if (mUseSpatialFilter) {
979                // 9.11. 2006 -> experiment with new spatial filter
980#if 0
981                mViewCellsManager->ApplySpatialFilter(mKdTree,
982                                                                                          mSpatialFilterSize*
983                                                                                          Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
984                                                                                          pvs);
985#else
986                // mSpatialFilter size is in range 0.001 - 0.1
987                mViewCellsManager->ApplyFilter2(viewcell,
988                                                                                mUseFilter,
989                                                                                100*mSpatialFilterSize,
990                                                                                pvs);
991#endif
992          } else
993                pvs = viewcell->GetPvs();
994        }
995
996        // Render PVS
997        ObjectPvsIterator it = pvs.GetIterator();
998       
999        mPvsSize = pvs.GetSize();
1000       
1001        for (; it.HasMoreEntries(); ) {
1002          ObjectPvsEntry entry = it.Next();
1003          Intersectable *object = entry.mObject;
1004         
1005          if (mRenderVisibilityEstimates) {
1006               
1007                float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
1008                glColor3f(visibility, 0.0f, 0.0f);
1009                mUseForcedColors = true;
1010                RenderIntersectable(object);
1011                mUseForcedColors = false;
1012          } else {
1013                mUseForcedColors = false;
1014                RenderIntersectable(object);
1015          }
1016        }
1017
1018        if (mRenderFilter) {
1019          mWireFrame = true;
1020          RenderIntersectable(viewcell);
1021          glPushMatrix();
1022          glTranslatef(mViewPoint.x, mViewPoint.y, mViewPoint.z);
1023          glScalef(5.0f,5.0f,5.0f);
1024          glPushAttrib(GL_CURRENT_BIT);
1025          glColor3f(1.0f, 0.0f, 0.0f);
1026          gluSphere((::GLUquadric *)mSphere,
1027                                1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6);
1028          glPopAttrib();
1029          glPopMatrix();
1030          mWireFrame = false;
1031        }
1032       
1033        if (0 && mUseFilter)
1034          mViewCellsManager->DeleteLocalMergeTree(viewcell);
1035
1036  } else {
1037        ObjectContainer::const_iterator oi = mObjects.begin();
1038        for (; oi != mObjects.end(); oi++)
1039          RenderIntersectable(*oi);
1040  }
1041}
1042
1043float
1044QtGlRendererWidget::RenderErrors()
1045{
1046  float pErrorPixels = -1.0f;
1047
1048  glReadBuffer(GL_BACK);
1049 
1050  mUseFalseColors = true;
1051
1052  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1053 
1054  double eq[4];
1055  eq[0] = mSceneCutPlane.mNormal.x;
1056  eq[1] = mSceneCutPlane.mNormal.y;
1057  eq[2] = mSceneCutPlane.mNormal.z;
1058  eq[3] = mSceneCutPlane.mD;
1059 
1060  if (mCutScene) {
1061        glClipPlane(GL_CLIP_PLANE0, eq);
1062    glEnable(GL_CLIP_PLANE0);
1063  }
1064 
1065  if (mDetectEmptyViewSpace)
1066        glEnable( GL_CULL_FACE );
1067  else
1068        glDisable( GL_CULL_FACE );
1069
1070  ObjectContainer::const_iterator oi = mObjects.begin();
1071  for (; oi != mObjects.end(); oi++)
1072        RenderIntersectable(*oi);
1073
1074  ViewCell *viewcell = NULL;
1075
1076  QImage im1, im2;
1077  QImage diff;
1078 
1079  if (viewcell) {
1080        // read back the texture
1081        im1 = grabFrameBuffer(true);
1082       
1083        RenderPvs();
1084
1085        // read back the texture
1086        im2 = grabFrameBuffer(true);
1087       
1088        diff = im1;
1089        int x, y;
1090        int errorPixels = 0;
1091       
1092        for (y = 0; y < im1.height(); y++)
1093          for (x = 0; x < im1.width(); x++)
1094                if (im1.pixel(x, y) == im2.pixel(x, y))
1095                  diff.setPixel(x, y, qRgba(0,0,0,0));
1096                else {
1097                  diff.setPixel(x, y, qRgba(255,128,128,255));
1098                  errorPixels++;
1099                }
1100        pErrorPixels = ((float)errorPixels)/(im1.height()*im1.width());
1101  }
1102
1103  // now render the pvs again
1104  SetupCamera();
1105  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1106  mUseFalseColors = false;
1107 
1108  oi = mObjects.begin();
1109  for (; oi != mObjects.end(); oi++)
1110        RenderIntersectable(*oi);
1111
1112  // now render im1
1113  if (viewcell) {
1114        if (0 && mTopView) {
1115          mWireFrame = true;
1116          RenderIntersectable(viewcell);
1117          mWireFrame = false;
1118        }
1119       
1120        // init ortographic projection
1121        glMatrixMode(GL_PROJECTION);
1122        glPushMatrix();
1123       
1124        glLoadIdentity();
1125        gluOrtho2D(0, 1.0f, 0, 1.0f);
1126       
1127        glMatrixMode(GL_MODELVIEW);
1128        glLoadIdentity();
1129       
1130        bindTexture(diff);
1131       
1132        glPushAttrib(GL_ENABLE_BIT);
1133        glEnable( GL_ALPHA_TEST );
1134        glDisable( GL_CULL_FACE );
1135        glAlphaFunc( GL_GREATER, 0.5 );
1136       
1137        glEnable( GL_TEXTURE_2D );
1138        glBegin(GL_QUADS);
1139       
1140        glTexCoord2f(0,0);
1141        glVertex3f(0,0,0);
1142       
1143        glTexCoord2f(1,0);
1144        glVertex3f( 1, 0, 0);
1145       
1146        glTexCoord2f(1,1);
1147        glVertex3f( 1, 1, 0);
1148       
1149        glTexCoord2f(0,1);
1150        glVertex3f(0, 1, 0);
1151        glEnd();
1152       
1153        glPopAttrib();
1154       
1155        // restore the projection matrix
1156        glMatrixMode(GL_PROJECTION);
1157        glPopMatrix();
1158        glMatrixMode(GL_MODELVIEW);
1159  }
1160
1161  glDisable(GL_CLIP_PLANE0);
1162 
1163  mRenderError = pErrorPixels;
1164  return pErrorPixels;
1165}
1166
1167
1168void
1169QtGlRendererWidget::mousePressEvent(QMouseEvent *e)
1170{
1171  int x = e->pos().x();
1172  int y = e->pos().y();
1173
1174  mousePoint.x = x;
1175  mousePoint.y = y;
1176 
1177}
1178
1179void
1180QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e)
1181{
1182  float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
1183  float TURN_SENSITIVITY=0.1f;
1184  float TILT_SENSITIVITY=32.0 ;
1185  float TURN_ANGLE= M_PI/36.0 ;
1186
1187  int x = e->pos().x();
1188  int y = e->pos().y();
1189
1190  int diffx = -(mousePoint.x - x);
1191  int diffy = -(mousePoint.y - y);
1192 
1193  if (x < width()*CAMERA_VIEW_WIDTH) {
1194        if (e->modifiers() & Qt::ControlModifier) {
1195          mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY/2.0;
1196          mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY/2.0;
1197        } else {
1198          mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
1199          float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
1200          float angle = atan2(mViewDirection.x, mViewDirection.z);
1201          mViewDirection.x = sin(angle+adiff);
1202          mViewDirection.z = cos(angle+adiff);
1203        }
1204  } else {
1205        float W = width()*(1.0f-CAMERA_VIEW_WIDTH);
1206        float H = height();
1207        int xx = x - width()*CAMERA_VIEW_WIDTH;
1208        int mxx = mousePoint.x - width()*CAMERA_VIEW_WIDTH;
1209    if (e->modifiers() & Qt::ControlModifier) {
1210          mManipulatorScale = mManipulatorScale * (1.0 + (((float) (-diffy)) / H));
1211        } else {
1212          float quat[4];
1213          trackball(quat,
1214                                (2.0 * mxx - W) / W,
1215                                (H - 2.0 * mousePoint.y) / H,
1216                                (2.0 * xx - W) / W,
1217                                (H - 2.0 * y) / H
1218                                );
1219          add_quats(quat, mManipulatorLastQuat, mManipulatorLastQuat);
1220        }
1221  }
1222 
1223  mousePoint.x = x;
1224  mousePoint.y = y;
1225 
1226  updateGL();
1227}
1228
1229void
1230QtGlRendererWidget::mouseReleaseEvent(QMouseEvent *)
1231{
1232
1233
1234}
1235
1236void
1237QtGlRendererWidget::resizeGL(int w, int h)
1238{
1239  SetupCameraProjection(w, h);
1240  updateGL();
1241}
1242
1243void
1244QtGlRendererWidget::paintGL()
1245{
1246  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1247
1248  if (1) {
1249        SetupCameraProjection(width(), height());
1250        SetupCamera();
1251       
1252        if (mRenderErrors) {
1253          RenderErrors();
1254        } else {
1255          RenderPvs();
1256        }
1257       
1258  }
1259
1260  mFrame++;
1261
1262  if (1) {
1263        // render into the right side of the window buffer
1264        SetupManipulatorProjection(width(), height());
1265        SetupManipulator();
1266       
1267       
1268        if (mRenderViewCells)
1269          RenderViewCells();
1270       
1271        RenderPvs();
1272       
1273        if (0) {
1274          mWireFrame = true;
1275          RenderScene();
1276          mWireFrame = false;
1277        }
1278       
1279        if (mShowRays) {
1280          RssPreprocessor *p = (RssPreprocessor *)mViewCellsManager->GetPreprocessor();
1281          if (p->mRssTree) {
1282                VssRayContainer rays;
1283                p->mRssTree->CollectRays(rays, 10000);
1284                RenderRays(rays);
1285          }
1286        }
1287
1288        if (mShowRenderCost)
1289          RenderRenderCost();
1290
1291        RenderInfo();
1292  }
1293  mFrame++;
1294 
1295}
1296
1297
1298void
1299QtGlRendererWidget::SetupCamera()
1300{
1301  if (!mTopView)
1302        GlRenderer::SetupCamera();
1303  else {
1304        if (0) {
1305          float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
1306          Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
1307                                                                                          -1,
1308                                                                                          mViewDirection.y);
1309         
1310          Vector3 target = mViewPoint + dist*mViewDirection;
1311          Vector3 up(0,1,0);
1312         
1313          glLoadIdentity();
1314          gluLookAt(pos.x, pos.y, pos.z,
1315                                target.x, target.y, target.z,
1316                                up.x, up.y, up.z);
1317        } else {
1318          float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*mTopDistance;
1319          Vector3 pos = mViewPoint  + dist*Vector3(0,
1320                                                                                           1,
1321                                                                                           0);
1322         
1323          Vector3 target = mViewPoint;
1324          Vector3 up(mViewDirection.x, 0, mViewDirection.z);
1325         
1326          glLoadIdentity();
1327          gluLookAt(pos.x, pos.y, pos.z,
1328                                target.x, target.y, target.z,
1329                                up.x, up.y, up.z);
1330         
1331        }
1332  }
1333
1334}
1335
1336void
1337QtGlRendererWidget::SetupManipulator()
1338{
1339  float m[4][4];
1340
1341  glLoadIdentity();
1342  gluLookAt(0.0, 0.0, 30.0,  /* eye is at (0,0,30) */
1343                        0.0, 0.0, 0.0,      /* center is at (0,0,0) */
1344                        0.0, 1.0, 0.);      /* up is in positive Y direction */
1345 
1346  build_rotmatrix(m, mManipulatorLastQuat);
1347  glMultMatrixf(&m[0][0]);
1348 
1349  float scale = mManipulatorScale*20.0f/Magnitude(mSceneGraph->GetBox().Diagonal());
1350  glScalef(scale, scale, scale);
1351 
1352  Vector3 t = -mSceneGraph->GetBox().Center();
1353  glTranslatef(t.x, t.y, t.z);
1354 
1355}
1356
1357void
1358QtGlRendererWidget::keyPressEvent ( QKeyEvent * e )
1359{
1360  switch (e->key()) {
1361  case Qt::Key_T:
1362        mTopView = !mTopView;
1363        SetupCameraProjection(width(), height());
1364        updateGL();
1365        break;
1366  case Qt::Key_V:
1367        mRenderViewCells = !mRenderViewCells;
1368        updateGL();
1369        break;
1370  case Qt::Key_P:
1371        // set random viewpoint
1372        mViewCellsManager->GetViewPoint(mViewPoint);
1373        updateGL();
1374        break;
1375
1376  default:
1377        e->ignore();
1378        break;
1379  }
1380}
1381
1382 
1383
1384QtGlRendererWidget::QtGlRendererWidget(
1385                                                                           SceneGraph *sceneGraph,
1386                                                                           ViewCellsManager *viewcells,
1387                                                                           KdTree *tree,
1388                                                                           QWidget * parent,
1389                                                                           const QGLWidget * shareWidget,
1390                                                                           Qt::WFlags f
1391                                                                           )
1392  :
1393  GlRendererWidget(sceneGraph, viewcells, tree), QGLWidget(parent, shareWidget, f)
1394{
1395  mPreprocessorThread = NULL;
1396  mTopView = false;
1397  mRenderViewCells = false;
1398  mTopDistance = 1.0f;
1399  mCutViewCells = false;
1400  mCutScene = false;
1401  mRenderErrors = false;
1402  mRenderBoxes = false;
1403  mRenderFilter = true;
1404  mRenderVisibilityEstimates = false;
1405  mTransferFunction = 0.2f;
1406  mManipulatorScale = 1.0f;
1407  trackball(mManipulatorLastQuat, 0.0f, 0.0f, 0.0f, 0.0f);
1408  bool tmp;
1409
1410  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
1411  mUseFilter = tmp;
1412 
1413  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
1414                                                        tmp );
1415  mUseSpatialFilter = tmp;
1416
1417  mShowRenderCost = false;
1418  mShowPvsSizes = false;
1419  mSpatialFilterSize = 0.01;
1420  mPvsSize = 0;
1421  mRenderError = 0.0f;
1422  mShowRays = false;
1423 
1424  mControlWidget = new QtRendererControlWidget(NULL);
1425 
1426  connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int)));
1427  connect(mControlWidget,
1428                  SIGNAL(SetTransferFunction(int)),
1429                  this,
1430                  SLOT(SetTransferFunction(int)));
1431  connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs()));
1432  connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility()));
1433  connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation()));
1434
1435  connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int)));
1436  connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int)));
1437
1438  connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int)));
1439  connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int)));
1440
1441  connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool)));
1442  connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool)));
1443  connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool)));
1444  connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool)));
1445  connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool)));
1446  connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
1447  connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
1448  connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
1449  connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
1450  connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)),
1451                  this, SLOT(SetRenderVisibilityEstimates(bool)));
1452  connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
1453  connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)),
1454                  this, SLOT(SetUseSpatialFilter(bool)));
1455
1456  connect(mControlWidget,
1457                  SIGNAL(SetShowRays(bool)),
1458                  this,
1459                  SLOT(SetShowRays(bool)));
1460
1461  resize(1000, 500);
1462  mControlWidget->show();
1463}
1464
1465void
1466QtGlRendererWidget::UpdateAllPvs()
1467{
1468  // $$ does not work so far:(
1469  mViewCellsManager->UpdatePvsForEvaluation();
1470  //    mViewCellsManager->FinalizeViewCells(false);
1471}
1472
1473void
1474QtGlRendererWidget::ComputeVisibility()
1475{
1476  cerr<<"Compute Visibility called!\n"<<endl;
1477  if (!mPreprocessorThread->isRunning())
1478        mPreprocessorThread->RunThread();
1479}
1480
1481void
1482QtGlRendererWidget::StopComputation()
1483{
1484  cerr<<"stop computation called!\n"<<endl;
1485  mViewCellsManager->GetPreprocessor()->mStopComputation = true;
1486}
1487
1488void
1489QtGlRendererWidget::RenderRenderCost()
1490{
1491        static vector<float> costFunction;
1492        static float maxCost = -1;
1493        if (costFunction.size()==0) {
1494          ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree();
1495          if (tree) {
1496                tree->GetCostFunction(costFunction);
1497                maxCost = -1;
1498                for (int i=0;  i < costFunction.size(); i++) {
1499                  //              cout<<i<<":"<<costFunction[i]<<" ";
1500                  // update cost function to an absolute value based on the total geometry count
1501                  costFunction[i]*=mSceneGraph->GetRoot()->mGeometry.size();
1502                  if (costFunction[i] > maxCost)
1503                        maxCost = costFunction[i];
1504                }
1505          }
1506        }
1507
1508       
1509        int currentPos = (int)mViewCellsManager->GetViewCells().size();
1510        float currentCost= -1;
1511
1512        if (currentPos < costFunction.size())
1513          currentCost = costFunction[currentPos];
1514#if 1   
1515        cout<<"costFunction.size()="<<costFunction.size()<<endl;
1516        cout<<"CP="<<currentPos<<endl;
1517        cout<<"MC="<<maxCost<<endl;
1518        cout<<"CC="<<currentCost<<endl;
1519#endif
1520        if (costFunction.size()) {
1521          float scaley = 1.0f/log10(maxCost);
1522          float scalex = 1.0f/(float)costFunction.size();
1523
1524          glDisable(GL_DEPTH_TEST);
1525          // init ortographic projection
1526          glMatrixMode(GL_PROJECTION);
1527         
1528          glPushMatrix();
1529         
1530          glLoadIdentity();
1531          gluOrtho2D(0, 1.0f, 0, 1.0f);
1532         
1533          glTranslatef(0.1f, 0.1f, 0.0f);
1534          glScalef(0.8f, 0.8f, 1.0f);
1535          glMatrixMode(GL_MODELVIEW);
1536          glLoadIdentity();
1537         
1538          glColor3f(1.0f,0,0);
1539          glBegin(GL_LINE_STRIP);
1540          //      glVertex3f(0,0,0);
1541         
1542          for (int i=0;  i < costFunction.size(); i++) {
1543                float x =  i*scalex;
1544                float y = log10(costFunction[i])*scaley;
1545                glVertex3f(x,y,0.0f);
1546          }
1547          glEnd();
1548         
1549          glColor3f(1.0f,0,0);
1550          glBegin(GL_LINES);
1551          float x =  currentPos*scalex;
1552          glVertex3f(x,0.0,0.0f);
1553          glVertex3f(x,1.0f,0.0f);
1554          glEnd();
1555         
1556          glColor3f(0.0f,0,0);
1557          // show a grid
1558          glBegin(GL_LINE_LOOP);
1559          glVertex3f(0,0,0.0f);
1560          glVertex3f(1,0,0.0f);
1561          glVertex3f(1,1,0.0f);
1562          glVertex3f(0,1,0.0f);
1563          glEnd();
1564
1565          glBegin(GL_LINES);
1566          for (int i=0;  i < costFunction.size(); i += 1000) {
1567                float x =  i*scalex;
1568                glVertex3f(x,0.0,0.0f);
1569                glVertex3f(x,1.0f,0.0f);
1570          }
1571
1572          for (int i=0;  pow(10, i) < maxCost; i+=1) {
1573                float y = i*scaley;
1574                //              QString s;
1575                //              s.sprintf("%d", (int)pow(10,i));
1576                //              renderText(width()/2+5, y*height(), s);
1577                glVertex3f(0.0f, y, 0.0f);
1578                glVertex3f(1.0f, y, 0.0f);
1579          }
1580
1581          glEnd();
1582
1583         
1584          // restore the projection matrix
1585          glMatrixMode(GL_PROJECTION);
1586          glPopMatrix();
1587          glMatrixMode(GL_MODELVIEW);
1588          glEnable(GL_DEPTH_TEST);
1589
1590        }
1591 
1592
1593
1594}
1595
1596void
1597QtGlRendererWidget::RenderInfo()
1598{
1599
1600  // $$JB temporal hack for two windows separation
1601  if (1) {
1602
1603        // model view
1604        glPushMatrix();
1605        glLoadIdentity();
1606       
1607        // init ortographic projection
1608        glMatrixMode(GL_PROJECTION);
1609        glPushMatrix();
1610       
1611        glLoadIdentity();
1612        gluOrtho2D(0, 1.0f, 0, 1.0f);
1613       
1614        float w = 0.01f;
1615        float h = 1.0f;
1616        float px = 0.0f;
1617        float py = 0.0f;
1618       
1619        glColor3f(0.8f, 0.8f, 0.8f);
1620        glBegin(GL_QUADS);
1621       
1622        glVertex3f(px+w, py, 0);
1623        glVertex3f(px+w, py+h + w, 0);
1624        glVertex3f(px, py+h, 0);
1625        glVertex3f(px, py, 0);
1626        glEnd();
1627       
1628        // projection
1629        glPopMatrix();
1630       
1631        glMatrixMode(GL_MODELVIEW);
1632        // model view
1633        glPopMatrix();
1634  }
1635
1636
1637  QString s;
1638  int vc = 0;
1639  if (mViewCellsManager)
1640        vc = mViewCellsManager->GetViewCells().size();
1641  int filter = 0;
1642  if (mViewCellsManager)
1643        filter = mViewCellsManager->GetMaxFilterSize();
1644
1645  glColor3f(1.0f,1.0f,1.0f);
1646
1647  s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)",
1648                        mFrame,
1649                        mViewPoint.x,
1650                        mViewPoint.y,
1651                        mViewPoint.z,
1652                        mViewDirection.x,
1653                        mViewDirection.y,
1654                        mViewDirection.z
1655                        );
1656
1657  renderText(20,20,s);
1658
1659  s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f\%",
1660                        vc,
1661                        filter,
1662                        mPvsSize,
1663                        mRenderError*100.0f);
1664
1665
1666  renderText(20,40,s);
1667
1668 
1669
1670 
1671}
1672
1673
1674void
1675QtGlRendererWidget::SetViewCellGranularity(int number)
1676{
1677  if (mViewCellsManager) {
1678        //      mViewCellsManager->SetMaxFilterSize(number);
1679    mViewCellsManager->CollectViewCells(number);
1680
1681        // $$ does not work so far:(
1682        //      mViewCellsManager->UpdatePvsForEvaluation();
1683        //      mViewCellsManager->FinalizeViewCells(false);
1684  }
1685  updateGL();
1686}
1687
1688void
1689QtGlRendererWidget::SetVisibilityFilterSize(int number)
1690{
1691  if (mViewCellsManager)
1692        mViewCellsManager->SetMaxFilterSize(number);
1693  updateGL();
1694}
1695
1696void
1697QtGlRendererWidget::SetSpatialFilterSize(int number)
1698{
1699  mSpatialFilterSize = 1e-3*number;
1700  updateGL();
1701}
1702
1703void
1704QtGlRendererWidget::SetSceneCut(int number)
1705{
1706  // assume the cut plane can only be aligned with xz plane
1707  // shift it along y according to number, which is percentage of the bounding
1708  // box position
1709  if (mViewCellsManager) {
1710        AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
1711        Vector3 p = box.Min() + (number/1000.0f)*box.Max();
1712        mSceneCutPlane.mNormal = Vector3(0,-1,0);
1713        mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p);
1714        updateGL();
1715  }
1716}
1717
1718void
1719QtGlRendererWidget::SetTopDistance(int number)
1720{
1721  mTopDistance = number/1000.0f;
1722  updateGL();
1723}
1724
1725void
1726QtGlRendererWidget::RenderViewCells()
1727{
1728  mUseFalseColors = true;
1729
1730  glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
1731 
1732  glEnable(GL_CULL_FACE);
1733  //glDisable(GL_CULL_FACE);
1734  glCullFace(GL_FRONT);
1735  double eq[4];
1736  eq[0] = mSceneCutPlane.mNormal.x;
1737  eq[1] = mSceneCutPlane.mNormal.y;
1738  eq[2] = mSceneCutPlane.mNormal.z;
1739  eq[3] = mSceneCutPlane.mD;
1740
1741  if (mCutViewCells) {
1742        glClipPlane(GL_CLIP_PLANE0, eq);
1743        glEnable(GL_CLIP_PLANE0);
1744  }
1745 
1746  int i;
1747  ViewCellContainer &viewcells = mViewCellsManager->GetViewCells();
1748  int maxPvs = -1;
1749  for (i=0; i < viewcells.size(); i++)
1750  {
1751        ViewCell *vc = viewcells[i];
1752
1753        //const int p = vc->GetPvs().CountObjectsInPvs();
1754        const int p = vc->GetPvs().GetSize();
1755        if (p > maxPvs)
1756          maxPvs = p;
1757  }
1758
1759
1760  for (i=0; i < viewcells.size(); i++) {
1761        ViewCell *vc = viewcells[i];
1762        //      Mesh *m = vc->GetMesh();
1763
1764
1765        RgbColor c;
1766
1767        if (!mShowPvsSizes) {
1768          mWireFrame = true;
1769          c = vc->GetColor();
1770        } else {
1771          //      const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().CountObjectsInPvs() / (float)maxPvs);
1772          const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().GetSize() / (float)maxPvs);
1773          c = RgbColor(importance, 1.0f - importance, 0.0f);
1774        }
1775        glColor3f(c.r, c.g, c.b);
1776       
1777        RenderViewCell(vc);
1778  }
1779
1780  mUseFalseColors = false;
1781  mWireFrame = false;
1782
1783  glPopAttrib();
1784 
1785}
1786
1787
1788
1789
1790
1791/***********************************************************************/
1792/*                     QtGlDebuggerWidget implementation                                   */
1793/***********************************************************************/
1794
1795
1796QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent)
1797      : QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf)
1798{
1799        // create the pbuffer
1800    //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
1801    timerId = startTimer(20);
1802    setWindowTitle(("OpenGL pbuffers"));
1803}
1804
1805
1806QtGlDebuggerWidget::~QtGlDebuggerWidget()
1807{
1808 mRenderBuffer->releaseFromDynamicTexture();
1809   glDeleteTextures(1, &dynamicTexture);
1810         
1811         DEL_PTR(mRenderBuffer);
1812}
1813
1814
1815
1816QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f):
1817  QWidget(parent, f)
1818{
1819
1820  QVBoxLayout *vl = new QVBoxLayout;
1821  setLayout(vl);
1822 
1823  QWidget *vbox = new QGroupBox("ViewCells", this);
1824  layout()->addWidget(vbox);
1825 
1826  vl = new QVBoxLayout;
1827  vbox->setLayout(vl);
1828
1829  QLabel *label = new QLabel("Granularity");
1830  vbox->layout()->addWidget(label);
1831 
1832  QSlider *slider = new QSlider(Qt::Horizontal, vbox);
1833  vl->addWidget(slider);
1834  slider->show();
1835  slider->setRange(1, 10000);
1836  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1837  slider->setValue(200);
1838
1839 
1840  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int)));
1841
1842  label = new QLabel("Transfer function");
1843  vbox->layout()->addWidget(label);
1844 
1845  slider = new QSlider(Qt::Horizontal, vbox);
1846  vl->addWidget(slider);
1847  slider->show();
1848  slider->setRange(1, 1000);
1849  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1850  slider->setValue(100);
1851
1852 
1853  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int)));
1854
1855  {
1856        QPushButton *button = new QPushButton("Update all PVSs", vbox);
1857        vbox->layout()->addWidget(button);
1858        connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs()));
1859  }
1860 
1861 
1862  label = new QLabel("Filter size");
1863  vbox->layout()->addWidget(label);
1864 
1865  slider = new QSlider(Qt::Horizontal, vbox);
1866  vbox->layout()->addWidget(slider);
1867  slider->show();
1868  slider->setRange(1, 100);
1869  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1870  slider->setValue(3);
1871 
1872  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int)));
1873
1874
1875  label = new QLabel("Spatial Filter size");
1876  vbox->layout()->addWidget(label);
1877 
1878  slider = new QSlider(Qt::Horizontal, vbox);
1879  vbox->layout()->addWidget(slider);
1880  slider->show();
1881  slider->setRange(1, 100);
1882  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1883  slider->setValue(10);
1884 
1885  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int)));
1886
1887
1888
1889  QWidget *hbox = new QWidget(vbox);
1890  vl->addWidget(hbox);
1891  QHBoxLayout *hlayout = new QHBoxLayout;
1892  hbox->setLayout(hlayout);
1893 
1894  QCheckBox *cb = new QCheckBox("Show viewcells", hbox);
1895  hlayout->addWidget(cb);
1896  cb->setChecked(false);
1897  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool)));
1898
1899  cb = new QCheckBox("Render cost curve", hbox);
1900  hlayout->addWidget(cb);
1901  cb->setChecked(false);
1902  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool)));
1903
1904  cb = new QCheckBox("Show render cost", hbox);
1905  hlayout->addWidget(cb);
1906  cb->setChecked(false);
1907  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool)));
1908
1909  cb = new QCheckBox("Show rays", hbox);
1910  hlayout->addWidget(cb);
1911  cb->setChecked(false);
1912  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool)));
1913
1914  vbox->resize(800,100);
1915
1916 
1917  vbox = new QGroupBox("Rendering", this);
1918  layout()->addWidget(vbox);
1919 
1920  vl = new QVBoxLayout;
1921  vbox->setLayout(vl);
1922
1923
1924
1925  cb = new QCheckBox("Cut view cells", vbox);
1926  vbox->layout()->addWidget(cb);
1927  cb->setChecked(false);
1928  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool)));
1929
1930
1931  slider = new QSlider(Qt::Horizontal, vbox);
1932  vbox->layout()->addWidget(slider);
1933  slider->show();
1934  slider->setRange(0, 1000);
1935  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1936  slider->setValue(1000);
1937
1938  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
1939
1940
1941  cb = new QCheckBox("Cut scene", vbox);
1942  vbox->layout()->addWidget(cb);
1943  cb->setChecked(false);
1944  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool)));
1945
1946  cb = new QCheckBox("Render boxes", vbox);
1947  vbox->layout()->addWidget(cb);
1948  cb->setChecked(false);
1949  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
1950
1951  cb = new QCheckBox("Render visibility estimates", vbox);
1952  vbox->layout()->addWidget(cb);
1953  cb->setChecked(false);
1954  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
1955
1956 
1957  cb = new QCheckBox("Render errors", vbox);
1958  vbox->layout()->addWidget(cb);
1959  cb->setChecked(false);
1960  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
1961
1962 
1963  bool tmp;
1964
1965  cb = new QCheckBox("Use filter", vbox);
1966  vbox->layout()->addWidget(cb);
1967  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
1968  cb->setChecked(tmp);
1969  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
1970
1971 
1972  cb = new QCheckBox("Use spatial filter", vbox);
1973  vbox->layout()->addWidget(cb);
1974  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
1975                                                                                        tmp );
1976  cb->setChecked(tmp);
1977  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
1978
1979  cb = new QCheckBox("Render filter", vbox);
1980  vbox->layout()->addWidget(cb);
1981  cb->setChecked(true);
1982  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool)));
1983
1984
1985
1986 
1987  slider = new QSlider(Qt::Horizontal, vbox);
1988  vbox->layout()->addWidget(slider);
1989  slider->show();
1990  slider->setRange(1, 1000);
1991  slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1992  slider->setValue(500);
1993 
1994  connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int)));
1995 
1996  cb = new QCheckBox("Top View", vbox);
1997  vbox->layout()->addWidget(cb);
1998  cb->setChecked(false);
1999  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
2000
2001
2002
2003  vbox = new QGroupBox("PVS Errors", this);
2004  layout()->addWidget(vbox);
2005 
2006  vl = new QVBoxLayout;
2007  vbox->setLayout(vl);
2008
2009  QPushButton *button = new QPushButton("Compute Visibility", vbox);
2010  vbox->layout()->addWidget(button);
2011  connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility()));
2012
2013  button = new QPushButton("Stop Computation", vbox);
2014  vbox->layout()->addWidget(button);
2015  connect(button, SIGNAL(clicked()), SLOT(StopComputation()));
2016
2017
2018  if (0) {
2019        vbox = new QGroupBox("PVS Errors", this);
2020        layout()->addWidget(vbox);
2021       
2022        vl = new QVBoxLayout;
2023        vbox->setLayout(vl);
2024       
2025        mPvsErrorWidget = new QListWidget(vbox);
2026        vbox->layout()->addWidget(mPvsErrorWidget);
2027       
2028        connect(mPvsErrorWidget,
2029                        SIGNAL(doubleClicked(const QModelIndex &)),
2030                        this,
2031                        SLOT(PvsErrorClicked(const QModelIndex &)));
2032       
2033        QPushButton *button = new QPushButton("Next Error Frame", vbox);
2034        vbox->layout()->addWidget(button);
2035        connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void)));
2036  }
2037 
2038  setWindowTitle("Preprocessor Control Widget");
2039  adjustSize();
2040}
2041
2042
2043
2044
2045void
2046QtRendererControlWidget::FocusNextPvsErrorFrame(void)
2047{
2048 
2049 
2050}
2051
2052void
2053QtRendererControlWidget::UpdatePvsErrorItem(int row,
2054                                                                                  GlRendererBuffer::PvsErrorEntry &pvsErrorEntry)
2055{
2056
2057  QListWidgetItem *i = mPvsErrorWidget->item(row);
2058  QString s;
2059  s.sprintf("%5.5f", pvsErrorEntry.mError);
2060  if (i) {
2061        i->setText(s);
2062  } else {
2063        new QListWidgetItem(s, mPvsErrorWidget);
2064  }
2065  mPvsErrorWidget->update();
2066}
2067
2068
2069void QtGlDebuggerWidget::initializeGL()
2070{
2071        glMatrixMode(GL_PROJECTION);
2072        glLoadIdentity();
2073
2074        glFrustum(-1, 1, -1, 1, 10, 100);
2075        glTranslatef(-0.5f, -0.5f, -0.5f);
2076        glTranslatef(0.0f, 0.0f, -15.0f);
2077        glMatrixMode(GL_MODELVIEW);
2078
2079        glEnable(GL_CULL_FACE);
2080        initCommon();
2081        initPbuffer();
2082
2083}
2084
2085
2086void QtGlDebuggerWidget::resizeGL(int w, int h)
2087{
2088        glViewport(0, 0, w, h);
2089}
2090
2091
2092void QtGlDebuggerWidget::paintGL()
2093{
2094        // draw a spinning cube into the pbuffer..
2095        mRenderBuffer->makeCurrent();
2096       
2097        BeamSampleStatistics stats;
2098        mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats);
2099
2100        glFlush();
2101
2102        // rendering directly to a texture is not supported on X11, unfortunately
2103    mRenderBuffer->updateDynamicTexture(dynamicTexture);
2104   
2105    // and use the pbuffer contents as a texture when rendering the
2106    // background and the bouncing cubes
2107    makeCurrent();
2108    glBindTexture(GL_TEXTURE_2D, dynamicTexture);
2109    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2110
2111    // draw the background
2112    glMatrixMode(GL_MODELVIEW);
2113    glPushMatrix();
2114    glLoadIdentity();
2115    glMatrixMode(GL_PROJECTION);
2116    glPushMatrix();
2117    glLoadIdentity();
2118
2119        glPopMatrix();
2120        glMatrixMode(GL_MODELVIEW);
2121        glPopMatrix();
2122}
2123
2124
2125void QtGlDebuggerWidget::initPbuffer()
2126{
2127        // set up the pbuffer context
2128    mRenderBuffer->makeCurrent();
2129        /*mRenderBuffer->InitGL();
2130
2131        glViewport(0, 0, mRenderBuffer->size().width(), mRenderBuffer->size().height());
2132        glMatrixMode(GL_PROJECTION);
2133        glLoadIdentity();
2134        glOrtho(-1, 1, -1, 1, -99, 99);
2135        glTranslatef(-0.5f, -0.5f, 0.0f);
2136        glMatrixMode(GL_MODELVIEW);
2137        glLoadIdentity();
2138
2139        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);*/
2140       
2141        // generate a texture that has the same size/format as the pbuffer
2142    dynamicTexture = mRenderBuffer->generateDynamicTexture();
2143
2144        // bind the dynamic texture to the pbuffer - this is a no-op under X11
2145        mRenderBuffer->bindToDynamicTexture(dynamicTexture);
2146        makeCurrent();
2147}
2148
2149void QtGlDebuggerWidget::initCommon()
2150{
2151        glEnable(GL_TEXTURE_2D);
2152        glEnable(GL_DEPTH_TEST);
2153
2154        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2155}
2156
2157
2158
2159}
Note: See TracBrowser for help on using the repository browser.