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

Revision 1694, 53.4 KB checked in by bittner, 18 years ago (diff)

obj exporter, vienna.obj + kdf added

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