source: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp @ 524

Revision 524, 18.7 KB checked in by mattausch, 18 years ago (diff)
  • Property svn:executable set to *
Line 
1#include "Mesh.h"
2#include "GlRenderer.h"
3#include "ViewCellsManager.h"
4#include "SceneGraph.h"
5#include "Pvs.h"
6#include "Viewcell.h"
7#include "Beam.h"
8
9#include <GL/glext.h>
10#include <Cg/cg.h>
11#include <Cg/cgGL.h>
12
13static CGcontext sCgContext = NULL;
14static CGprogram sCgFragmentProgram = NULL;
15
16static CGparameter sCgKdParam = NULL;
17static CGparameter sCgModelViewProjParam = NULL;
18
19
20static CGprofile sCgFragmentProfile = CG_PROFILE_FP30;
21
22GLuint depthMap;
23const int depthMapSize = 512;
24static vector<int> sQueries;
25
26GlRendererWidget *rendererWidget = NULL;
27
28
29#ifdef _WIN32
30PFNGLGENOCCLUSIONQUERIESNVPROC glGenOcclusionQueriesNV;
31PFNGLBEGINOCCLUSIONQUERYNVPROC glBeginOcclusionQueryNV;
32PFNGLENDOCCLUSIONQUERYNVPROC glEndOcclusionQueryNV;
33PFNGLGETOCCLUSIONQUERYUIVNVPROC glGetOcclusionQueryuivNV;
34#endif
35
36GlRenderer::GlRenderer(SceneGraph *sceneGraph,
37                                           ViewCellsManager *viewCellsManager):
38  Renderer(sceneGraph, viewCellsManager)
39{
40  mSceneGraph->CollectObjects(&mObjects);
41  mViewPoint = mSceneGraph->GetBox().Center();
42  mViewDirection = Vector3(0,0,1);
43  //  timerId = startTimer(10);
44  mFrame = 0;
45  mWireFrame = false;
46}
47
48GlRenderer::~GlRenderer()
49{
50}
51
52
53static void handleCgError()
54{
55    fprintf(stderr, "Cg error: %s\n", cgGetErrorString(cgGetError()));
56    exit(1);
57}
58
59void
60GlRenderer::RenderIntersectable(Intersectable *object)
61{
62
63  SetupFalseColor(object->mId);
64
65  switch (object->Type()) {
66  case Intersectable::MESH_INSTANCE:
67        RenderMeshInstance((MeshInstance *)object);
68        break;
69  default:
70        cerr<<"Rendering this object not yet implemented\n";
71        break;
72  }
73}
74
75
76void
77GlRenderer::RenderMeshInstance(MeshInstance *mi)
78{
79  RenderMesh(mi->GetMesh());
80}
81
82void
83GlRenderer::SetupFalseColor(const int id)
84{
85  // swap bits of the color
86 
87  glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
88}
89
90void
91GlRenderer::SetupMaterial(Material *m)
92{
93  if (m)
94        glColor3fv(&(m->mDiffuseColor.r));
95  else
96        glColor3f(1.0f, 1.0f, 1.0f);
97}
98
99void
100GlRenderer::RenderMesh(Mesh *mesh)
101{
102  int i = 0;
103
104  if (!mUseFalseColors)
105        SetupMaterial(mesh->mMaterial);
106 
107  for (i=0; i < mesh->mFaces.size(); i++) {
108        if (mWireFrame)
109          glBegin(GL_LINE_LOOP);
110        else
111          glBegin(GL_POLYGON);
112
113        Face *face = mesh->mFaces[i];
114        for (int j = 0; j < face->mVertexIndices.size(); j++) {
115          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
116        }
117        glEnd();
118  }
119}
120       
121void
122GlRenderer::InitGL()
123{
124  glMatrixMode(GL_PROJECTION);
125  glLoadIdentity();
126 
127  glMatrixMode(GL_MODELVIEW);
128  glLoadIdentity();
129
130  glEnable(GL_CULL_FACE);
131  glShadeModel(GL_FLAT);
132  glEnable(GL_DEPTH_TEST);
133  glEnable(GL_CULL_FACE);
134 
135  glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)
136        wglGetProcAddress("glGenOcclusionQueriesNV");
137  glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)
138        wglGetProcAddress("glBeginOcclusionQueryNV");
139  glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)
140        wglGetProcAddress("glEndOcclusionQueryNV");
141  glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)
142        wglGetProcAddress("glGetOcclusionQueryuivNV");
143
144  // initialise second depth buffer texture
145  glGenTextures(1, &depthMap);
146  glBindTexture(GL_TEXTURE_2D, depthMap);
147 
148  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
149                           depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
150  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
151  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
152  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
153  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
154
155  // cg initialization
156  cgSetErrorCallback(handleCgError);
157  sCgContext = cgCreateContext();
158
159  sCgFragmentProgram = cgCreateProgramFromFile(sCgContext,             
160                                                                                           CG_SOURCE, "../src/dual_depth.cg",
161                                                                                           sCgFragmentProfile,
162                                                                                           NULL,
163                                                                                           NULL);
164}
165
166
167
168void
169GlRenderer::SetupProjection(const int w, const int h)
170{
171  glViewport(0, 0, w, h);
172  glMatrixMode(GL_PROJECTION);
173  glLoadIdentity();
174  gluPerspective(70.0, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
175  glMatrixMode(GL_MODELVIEW);
176}
177
178void
179GlRenderer::SetupCamera()
180{
181  Vector3 target = mViewPoint + mViewDirection;
182  Vector3 up(0,1,0);
183 
184  glLoadIdentity();
185  gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
186                        target.x, target.y, target.z,
187                        up.x, up.y, up.z);
188}
189
190void
191GlRenderer::RandomViewPoint()
192{
193  Vector3 pVector = Vector3(halton.GetNumber(1),
194                                                        halton.GetNumber(2),
195                                                        halton.GetNumber(3));
196 
197  Vector3 dVector = Vector3(2*M_PI*halton.GetNumber(4),
198                                                        M_PI*halton.GetNumber(5),
199                                                        0.0f);
200 
201  mViewPoint = mSceneGraph->GetBox().GetPoint(pVector);
202 
203  mViewDirection = Normalize(Vector3(sin(dVector.x),
204                                                                         //                                                                      cos(dVector.y),
205                                                                         0.0f,
206                                                                         cos(dVector.x)));
207
208  halton.GenerateNext();
209}
210
211
212float
213GlRenderer::GetPixelError()
214{
215  float pErrorPixels = -1.0f;
216
217  glReadBuffer(GL_BACK);
218 
219  mUseFalseColors = true;
220
221  SetupCamera();
222  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
223  glEnable( GL_CULL_FACE );
224 
225  RenderScene();
226
227  // now check whether any backfacing polygon would pass the depth test
228  static int query = -1;
229  if (query == -1)
230        glGenOcclusionQueriesNV(1, (unsigned int *)&query);
231 
232  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
233  glDepthMask(GL_FALSE);
234  glDisable( GL_CULL_FACE );
235 
236  glBeginOcclusionQueryNV(query);
237 
238  RenderScene();
239 
240  glEndOcclusionQueryNV();
241
242  // at this point, if possible, go and do some other computation
243  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
244  glDepthMask(GL_TRUE);
245  glEnable( GL_CULL_FACE );
246 
247  unsigned int pixelCount;
248  // reenable other state
249  glGetOcclusionQueryuivNV(query,
250                                                   GL_PIXEL_COUNT_NV,
251                                                   &pixelCount);
252
253  if (pixelCount > 0)
254        return -1.0f; // backfacing polygon found -> not a valid viewspace sample
255
256  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
257 
258  if (viewcell) {
259        SetupCamera();
260        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
261
262        // Render PVS
263        std::map<Intersectable *,
264          PvsData<Intersectable *>,
265          LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin();
266       
267        for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
268          Intersectable *object = (*it).first;
269          RenderIntersectable(object);
270        }
271
272        glBeginOcclusionQueryNV(query);
273
274        SetupCamera();
275
276        RenderScene();
277       
278        glEndOcclusionQueryNV();
279       
280
281        unsigned int pixelCount;
282        // reenable other state
283        glGetOcclusionQueryuivNV(query,
284                                                         GL_PIXEL_COUNT_NV,
285                                                         &pixelCount);
286       
287        pErrorPixels = (100.f*pixelCount)/(GetWidth()*GetHeight());
288  }
289 
290  return pErrorPixels;
291}
292
293
294float
295GlRendererWidget::RenderErrors()
296{
297  float pErrorPixels = -1.0f;
298
299  glReadBuffer(GL_BACK);
300 
301  mUseFalseColors = true;
302
303  SetupCamera();
304  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
305  glEnable( GL_CULL_FACE );
306 
307  ObjectContainer::const_iterator oi = mObjects.begin();
308  for (; oi != mObjects.end(); oi++)
309        RenderIntersectable(*oi);
310
311  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
312 
313  QImage im1, im2;
314  QImage diff;
315 
316  if (viewcell) {
317        // read back the texture
318        im1 = grabFrameBuffer(true);
319       
320        SetupCamera();
321        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
322       
323        std::map<Intersectable *,
324          PvsData<Intersectable *>,
325          LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin();
326       
327        for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
328          Intersectable *object = (*it).first;
329          RenderIntersectable(object);
330        }
331
332        // read back the texture
333        im2 = grabFrameBuffer(true);
334       
335        diff = im1;
336        int x, y;
337        int errorPixels = 0;
338       
339        for (y = 0; y < im1.height(); y++)
340          for (x = 0; x < im1.width(); x++)
341                if (im1.pixel(x, y) == im2.pixel(x, y))
342                  diff.setPixel(x, y, qRgba(0,0,0,0));
343                else {
344                  diff.setPixel(x, y, qRgba(255,128,128,255));
345                  errorPixels++;
346                }
347        pErrorPixels = (100.f*errorPixels)/(im1.height()*im1.width());
348  }
349
350  // now render the pvs again
351  SetupCamera();
352  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
353  mUseFalseColors = false;
354       
355  oi = mObjects.begin();
356  for (; oi != mObjects.end(); oi++)
357        RenderIntersectable(*oi);
358
359  // now render im1
360  if (viewcell) {
361        if (mTopView) {
362          mWireFrame = true;
363          RenderMeshInstance(viewcell);
364          mWireFrame = false;
365        }
366       
367        // init ortographic projection
368        glMatrixMode(GL_PROJECTION);
369        glPushMatrix();
370       
371        glLoadIdentity();
372        gluOrtho2D(0, 1.0f, 0, 1.0f);
373       
374        glMatrixMode(GL_MODELVIEW);
375        glLoadIdentity();
376       
377        bindTexture(diff);
378       
379        glPushAttrib(GL_ENABLE_BIT);
380        glEnable( GL_ALPHA_TEST );
381        glDisable( GL_CULL_FACE );
382        glAlphaFunc( GL_GREATER, 0.5 );
383       
384        glEnable( GL_TEXTURE_2D );
385        glBegin(GL_QUADS);
386       
387        glTexCoord2f(0,0);
388        glVertex3f(0,0,0);
389       
390        glTexCoord2f(1,0);
391        glVertex3f( 1, 0, 0);
392       
393        glTexCoord2f(1,1);
394        glVertex3f( 1, 1, 0);
395       
396        glTexCoord2f(0,1);
397        glVertex3f(0, 1, 0);
398        glEnd();
399       
400        glPopAttrib();
401       
402        // restore the projection matrix
403        glMatrixMode(GL_PROJECTION);
404        glPopMatrix();
405        glMatrixMode(GL_MODELVIEW);
406  }
407
408  return pErrorPixels;
409}
410
411
412bool
413GlRenderer::RenderScene()
414{
415  static int glList = -1;
416  if (glList != -1) {
417        glCallList(glList);
418  } else {
419        glList = glGenLists(1);
420        glNewList(glList, GL_COMPILE_AND_EXECUTE);
421        ObjectContainer::const_iterator oi = mObjects.begin();
422        for (; oi != mObjects.end(); oi++)
423          RenderIntersectable(*oi);
424        glEndList();
425  }
426  return true;
427}
428
429
430void
431GlRendererBuffer::ClearErrorBuffer()
432{
433  for (int i=0; i < mPvsStatFrames; i++) {
434        mPvsErrorBuffer[i] = 1.0f;
435  }
436}
437
438
439void
440GlRendererBuffer::EvalPvsStat()
441{
442  mPvsStat.Reset();
443  halton.Reset();
444
445  makeCurrent();
446  SetupProjection(GetWidth(), GetHeight());
447 
448  for (int i=0; i < mPvsStatFrames; i++) {
449        float err;
450        RandomViewPoint();
451        if (mPvsErrorBuffer[i] > 0.0f) {
452          mPvsErrorBuffer[i] = GetPixelError();
453          cout<<"("<<i<<","<<mPvsErrorBuffer[i]<<")";
454          //      swapBuffers();
455        }
456       
457        err = mPvsErrorBuffer[i];
458       
459        if (err >= 0.0f) {
460          if (err > mPvsStat.maxError)
461                mPvsStat.maxError = err;
462          mPvsStat.sumError += err;
463          if (err == 0.0f)
464                mPvsStat.errorFreeFrames++;
465          mPvsStat.frames++;
466        }
467  }
468 
469  doneCurrent();
470
471  cout<<endl<<flush;
472  mRenderingFinished.wakeAll();
473}
474
475
476
477
478
479void
480GlRendererWidget::mousePressEvent(QMouseEvent *e)
481{
482  int x = e->pos().x();
483  int y = e->pos().y();
484
485  mousePoint.x = x;
486  mousePoint.y = y;
487 
488}
489
490void
491GlRendererWidget::mouseMoveEvent(QMouseEvent *e)
492{
493  float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
494  float TURN_SENSITIVITY=0.1f;
495  float TILT_SENSITIVITY=32.0 ;
496  float TURN_ANGLE= M_PI/36.0 ;
497
498  int x = e->pos().x();
499  int y = e->pos().y();
500 
501  if (e->modifiers() & Qt::ControlModifier) {
502        mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY/2.0;
503        mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY/2.0;
504  } else {
505        mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
506        float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
507        float angle = atan2(mViewDirection.x, mViewDirection.z);
508        mViewDirection.x = sin(angle+adiff);
509        mViewDirection.z = cos(angle+adiff);
510  }
511 
512  mousePoint.x = x;
513  mousePoint.y = y;
514 
515  updateGL();
516}
517
518void
519GlRendererWidget::mouseReleaseEvent(QMouseEvent *)
520{
521
522
523}
524
525void
526GlRendererWidget::resizeGL(int w, int h)
527{
528  SetupProjection(w, h);
529  updateGL();
530}
531
532void
533GlRendererWidget::paintGL()
534{
535  RenderErrors();
536  mFrame++;
537}
538
539
540void
541GlRendererWidget::SetupCamera()
542{
543  if (!mTopView)
544        GlRenderer::SetupCamera();
545  else {
546        float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
547        Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
548                                                                                        -1,
549                                                                                        mViewDirection.y);
550       
551        Vector3 target = mViewPoint + dist*mViewDirection;
552        Vector3 up(0,1,0);
553       
554        glLoadIdentity();
555        gluLookAt(pos.x, pos.y, pos.z,
556                          target.x, target.y, target.z,
557                          up.x, up.y, up.z);
558  }
559
560}
561
562void
563GlRendererWidget::keyPressEvent ( QKeyEvent * e )
564{
565  switch (e->key()) {
566  case Qt::Key_T:
567        mTopView = !mTopView;
568        updateGL();
569        break;
570  default:
571        e->ignore();
572        break;
573  }
574 
575}
576
577
578void GlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject,
579                                                                                           Beam &beam,
580                                                                                           const int desiredSamples,
581                                                                                           BeamSampleStatistics &stat)
582{
583        // TODO: should not be done every time here
584        // only back faces are interesting for the depth pass
585        glShadeModel(GL_FLAT);
586        glDisable(GL_LIGHTING);
587
588        // assumes that the beam is constructed and contains kd-tree nodes
589        // and viewcells which it intersects
590 
591 
592        // Get the number of viewpoints to be sampled
593        // Now it is a sqrt but in general a wiser decision could be made.
594        // The less viewpoints the better for rendering performance, since less passes
595        // over the beam is needed.
596        // The viewpoints could actually be generated outside of the bounding box which
597        // would distribute the 'efective viewpoints' of the object surface and thus
598        // with a few viewpoints better sample the vipoint space....
599 
600        int viewPointSamples = sqrt((float)desiredSamples);
601
602        // the number of direction samples per pass is given by the number of viewpoints
603        int directionalSamples = desiredSamples/viewPointSamples;
604       
605        for (int i = 0; i < viewPointSamples; ++ i)
606        {
607                Vector3 viewPoint = beam.mBox.GetRandomPoint();
608               
609                // perhaps the viewpoint should be shifted back a little bit so that it always lies
610                // inside the source object
611                // 'ideally' the viewpoints would be distributed on the soureObject surface, but this
612        // would require more complicated sampling (perhaps hierarchical rejection sampling of
613                // the object surface is an option here - only the mesh faces which are inside the box
614                // are considered as candidates)
615               
616                SampleViewpointContributions(sourceObject,
617                                                                         viewPoint,
618                                                                         beam,
619                                                                         directionalSamples,
620                                                                         stat);
621        }
622
623
624        // note:
625        // this routine would be called only if the number of desired samples is sufficiently
626        // large - for other rss tree cells the cpu based sampling is perhaps more efficient
627        // distributing the work between cpu and gpu would also allow us to place more sophisticated
628        // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
629        // in order that thios scheme is working well the gpu render buffer should run in a separate
630        // thread than the cpu sampler, which would not be such a big problem....
631}
632
633
634void GlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
635                                                                                                        const Vector3 viewPoint,
636                                                                                                        Beam &beam,
637                                                                                                        const int desiredSamples,
638                                                    BeamSampleStatistics &stat)
639{
640        // 1. setup the view port to match the desired samples
641        // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
642 
643        // 3. reset z-buffer to 0 and render the source object for the beam
644        //    with glCullFace(Enabled) and glFrontFace(GL_CW)
645        //    save result to depth map
646        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
647        glEnable(GL_CULL_FACE);
648        glEnable(GL_STENCIL_TEST);
649        glCullFace(GL_FRONT);
650        glColorMask(0, 0, 0, 0);
651       
652        // stencil is increased where the source object is located
653        glStencilFunc(GL_ALWAYS, 0x1, 0x1);
654        glStencilOp(GL_INCR, GL_INCR, GL_INCR);
655
656#if 0
657        static int glSourceObjList = -1;         
658        if (glSourceObjList != -1)
659        {
660                glSourceObjList = glGenLists(1);
661                glNewList(glSourceObjList, GL_COMPILE);
662
663                RenderIntersectable(sourceObject);
664       
665                glEndList();
666        }
667        glCallList(glSourceObjList);
668
669#else
670        RenderIntersectable(sourceObject);
671
672#endif 
673
674        // 4. set back to normal rendering and clear the ray termination depth buffer
675        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
676        glColorMask(1, 1, 1, 1);
677       
678        // 5. render all objects inside the beam using id based false color
679        //    (objects can be compiled to a gl list now so that subsequent rendering for
680        //     this beam is fast - the same hold for step 3)
681
682        // list of objects intersected by the frustum
683#if 0
684        static int glObjList = -1;
685        if (glObjList != -1)
686        {
687                glObjList = glGenLists(1);
688                glNewList(glObjList, GL_COMPILE);
689       
690                ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
691                for (it = beam.mObjects.begin(); it != it_end; ++ it)
692                        RenderIntersectable(*it);
693               
694                glEndList();
695        }
696        glCallList(glObjList);
697#else
698        ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
699                for (it = beam.mObjects.begin(); it != it_end; ++ it)
700                        RenderIntersectable(*it);
701#endif
702
703        // bind ray origin depth buffer
704        glBindTexture(GL_TEXTURE_2D, depthMap);
705    glEnable(GL_TEXTURE_2D);
706       
707
708        //Read the depth buffer into the shadow map texture
709        glBindTexture(GL_TEXTURE_2D, depthMap);
710        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
711
712       
713        // 6. Now we have a two depth buffers defining the ray origin and termination
714        //    only rays which have non-zero entry in the origin buffer are valid since
715        //    they realy start on the object surface (this can also be tagged by setting a
716        //    stencil buffer bit at step 3)
717        glStencilFunc(GL_EQUAL, 0x1, 0x1);
718
719        // compare with second depth buffer: done in pixel shader
720        cgGLBindProgram(sCgFragmentProgram);
721        cgGLEnableProfile(sCgFragmentProfile);
722
723        // 7. Use occlusion queries for all viewcell meshes associated with the beam ->
724        // a fragment passes if the corresponding stencil fragment is set and its depth is
725        // between origin and termination buffer
726
727        // create new queries if necessary
728        GenQueries((int)beam.mViewCells.size());
729
730        // now check whether any backfacing polygon would pass the depth test
731        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
732        glDepthMask(GL_FALSE);
733        glDisable(GL_CULL_FACE);
734 
735        ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
736
737        int queryIdx = 0;
738
739        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
740        {
741                glBeginOcclusionQueryNV(sQueries[queryIdx ++]);
742 
743                RenderIntersectable(*vit);
744 
745                glEndOcclusionQueryNV();
746        }
747
748        // at this point, if possible, go and do some other computation
749        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
750        glDepthMask(GL_TRUE);
751        glEnable(GL_CULL_FACE);
752
753        // 8. The number of visible pixels is the number of sample rays which see the source
754        //    object from the corresponding viewcell -> rember these values for later update
755        //   of the viewcell pvs - or update immediatelly?
756
757        //  In general it is not neccessary to rember to extract all the rays cast. I hope it
758        // would be sufficient to gain only the intergral statistics about the new contributions
759        // and so the rss tree would actually store no new rays (only the initial ones)
760        // the subdivision of the tree would only be driven by the statistics (the glrender could
761        // evaluate the contribution entropy for example)
762        // However might be an option to extract/store only those the rays which made a contribution
763        // (new viewcell has been discovered) or relative contribution greater than a threashold ...
764
765        cgGLDisableProfile(sCgFragmentProfile);
766        glDisable(GL_TEXTURE_2D);
767}
768
769
770void GlRendererBuffer::GenQueries(const int numQueries)
771{
772        if ((int)sQueries.size() < numQueries)
773        {
774                const int n = numQueries - (int)sQueries.size();
775                int *newQueries = new int[n];
776
777                glGenOcclusionQueriesNV(n, (unsigned int *)&newQueries);
778
779                for (int i = 0; i < n; ++ i)
780                {
781                        sQueries.push_back(newQueries[i]);
782                }
783
784                delete newQueries;
785        }
786}
Note: See TracBrowser for help on using the repository browser.