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

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