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

Revision 1757, 54.0 KB checked in by bittner, 18 years ago (diff)

pvs updates

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