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

Revision 527, 19.5 KB checked in by mattausch, 19 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;
15static CGprofile sCgFragmentProfile;// = CG_PROFILE_FP30;
16
17//static CGparameter sCgKdParam = NULL;
18//static CGparameter sCgModelViewProjParam = NULL;
19
20GLuint depthMap;
21const int depthMapSize = 512;
22static vector<int> sQueries;
23
24GlRendererWidget *rendererWidget = NULL;
25
26
27#ifdef _WIN32
28PFNGLGENOCCLUSIONQUERIESNVPROC glGenOcclusionQueriesNV;
29PFNGLBEGINOCCLUSIONQUERYNVPROC glBeginOcclusionQueryNV;
30PFNGLENDOCCLUSIONQUERYNVPROC glEndOcclusionQueryNV;
31PFNGLGETOCCLUSIONQUERYUIVNVPROC glGetOcclusionQueryuivNV;
32#endif
33
34GlRenderer::GlRenderer(SceneGraph *sceneGraph,
35                                           ViewCellsManager *viewCellsManager):
36  Renderer(sceneGraph, viewCellsManager)
37{
38  mSceneGraph->CollectObjects(&mObjects);
39  mViewPoint = mSceneGraph->GetBox().Center();
40  mViewDirection = Vector3(0,0,1);
41  //  timerId = startTimer(10);
42  mFrame = 0;
43  mWireFrame = false;
44}
45
46GlRenderer::~GlRenderer()
47{
48}
49
50
51static void handleCgError()
52{
53    Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl;
54    exit(1);
55}
56
57void
58GlRenderer::RenderIntersectable(Intersectable *object)
59{
60
61  SetupFalseColor(object->mId);
62
63  switch (object->Type()) {
64  case Intersectable::MESH_INSTANCE:
65        RenderMeshInstance((MeshInstance *)object);
66        break;
67  default:
68        cerr<<"Rendering this object not yet implemented\n";
69        break;
70  }
71}
72
73
74void
75GlRenderer::RenderMeshInstance(MeshInstance *mi)
76{
77  RenderMesh(mi->GetMesh());
78}
79
80void
81GlRenderer::SetupFalseColor(const int id)
82{
83  // swap bits of the color
84 
85  glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
86}
87
88void
89GlRenderer::SetupMaterial(Material *m)
90{
91  if (m)
92        glColor3fv(&(m->mDiffuseColor.r));
93  else
94        glColor3f(1.0f, 1.0f, 1.0f);
95}
96
97void
98GlRenderer::RenderMesh(Mesh *mesh)
99{
100  int i = 0;
101
102  if (!mUseFalseColors)
103        SetupMaterial(mesh->mMaterial);
104 
105  for (i=0; i < mesh->mFaces.size(); i++) {
106        if (mWireFrame)
107          glBegin(GL_LINE_LOOP);
108        else
109          glBegin(GL_POLYGON);
110
111        Face *face = mesh->mFaces[i];
112        for (int j = 0; j < face->mVertexIndices.size(); j++) {
113          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
114        }
115        glEnd();
116  }
117}
118       
119void
120GlRenderer::InitGL()
121{
122  glMatrixMode(GL_PROJECTION);
123  glLoadIdentity();
124 
125  glMatrixMode(GL_MODELVIEW);
126  glLoadIdentity();
127
128  glEnable(GL_CULL_FACE);
129  glShadeModel(GL_FLAT);
130  glEnable(GL_DEPTH_TEST);
131  glEnable(GL_CULL_FACE);
132 
133  glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)
134        wglGetProcAddress("glGenOcclusionQueriesNV");
135  glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)
136        wglGetProcAddress("glBeginOcclusionQueryNV");
137  glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)
138        wglGetProcAddress("glEndOcclusionQueryNV");
139  glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)
140        wglGetProcAddress("glGetOcclusionQueryuivNV");
141
142  // initialise second depth buffer texture
143  glGenTextures(1, &depthMap);
144  glBindTexture(GL_TEXTURE_2D, depthMap);
145 
146  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize,
147                           depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
148  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
149  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
150  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
151  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
152
153  // cg initialization
154  cgSetErrorCallback(handleCgError);
155  sCgContext = cgCreateContext();
156
157  sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
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        // needed to kill fragments
588        glEnable(GL_ALPHA_TEST);
589        glAlphaFunc(GL_GREATER, 0);
590
591        // assumes that the beam is constructed and contains kd-tree nodes
592        // and viewcells which it intersects
593 
594 
595        // Get the number of viewpoints to be sampled
596        // Now it is a sqrt but in general a wiser decision could be made.
597        // The less viewpoints the better for rendering performance, since less passes
598        // over the beam is needed.
599        // The viewpoints could actually be generated outside of the bounding box which
600        // would distribute the 'efective viewpoints' of the object surface and thus
601        // with a few viewpoints better sample the vipoint space....
602 
603        int viewPointSamples = sqrt((float)desiredSamples);
604
605        // the number of direction samples per pass is given by the number of viewpoints
606        int directionalSamples = desiredSamples/viewPointSamples;
607       
608        for (int i = 0; i < viewPointSamples; ++ i)
609        {
610                Vector3 viewPoint = beam.mBox.GetRandomPoint();
611               
612                // perhaps the viewpoint should be shifted back a little bit so that it always lies
613                // inside the source object
614                // 'ideally' the viewpoints would be distributed on the soureObject surface, but this
615        // would require more complicated sampling (perhaps hierarchical rejection sampling of
616                // the object surface is an option here - only the mesh faces which are inside the box
617                // are considered as candidates)
618               
619                SampleViewpointContributions(sourceObject,
620                                                                         viewPoint,
621                                                                         beam,
622                                                                         directionalSamples,
623                                                                         stat);
624        }
625
626
627        // note:
628        // this routine would be called only if the number of desired samples is sufficiently
629        // large - for other rss tree cells the cpu based sampling is perhaps more efficient
630        // distributing the work between cpu and gpu would also allow us to place more sophisticated
631        // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
632        // in order that thios scheme is working well the gpu render buffer should run in a separate
633        // thread than the cpu sampler, which would not be such a big problem....
634}
635
636
637void GlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
638                                                                                                        const Vector3 viewPoint,
639                                                                                                        Beam &beam,
640                                                                                                        const int desiredSamples,
641                                                    BeamSampleStatistics &stat)
642{
643        // 1. setup the view port to match the desired samples
644        glViewport(0, 0, desiredSamples, desiredSamples);
645
646        // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
647        SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
648       
649        // 3. reset z-buffer to 0 and render the source object for the beam
650        //    with glCullFace(Enabled) and glFrontFace(GL_CW)
651        //    save result to depth map
652        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
653        glEnable(GL_CULL_FACE);
654        glEnable(GL_STENCIL_TEST);
655        glCullFace(GL_FRONT);
656        glColorMask(0, 0, 0, 0);
657       
658        // stencil is increased where the source object is located
659        glStencilFunc(GL_ALWAYS, 0x1, 0x1);
660        glStencilOp(GL_INCR, GL_INCR, GL_INCR);
661
662#if 0
663        static int glSourceObjList = -1;         
664        if (glSourceObjList != -1)
665        {
666                glSourceObjList = glGenLists(1);
667                glNewList(glSourceObjList, GL_COMPILE);
668
669                RenderIntersectable(sourceObject);
670       
671                glEndList();
672        }
673        glCallList(glSourceObjList);
674
675#else
676        RenderIntersectable(sourceObject);
677
678#endif 
679
680        // 4. set back to normal rendering and clear the ray termination depth buffer
681        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
682        glColorMask(1, 1, 1, 1);
683       
684        // 5. render all objects inside the beam using id based false color
685        //    (objects can be compiled to a gl list now so that subsequent rendering for
686        //     this beam is fast - the same hold for step 3)
687
688        // list of objects intersected by the frustum
689#if 0
690        static int glObjList = -1;
691        if (glObjList != -1)
692        {
693                glObjList = glGenLists(1);
694                glNewList(glObjList, GL_COMPILE);
695       
696                ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
697                for (it = beam.mObjects.begin(); it != it_end; ++ it)
698                        RenderIntersectable(*it);
699               
700                glEndList();
701        }
702        glCallList(glObjList);
703#else
704        ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
705                for (it = beam.mObjects.begin(); it != it_end; ++ it)
706                        RenderIntersectable(*it);
707#endif
708
709        // bind ray origin depth buffer
710        glBindTexture(GL_TEXTURE_2D, depthMap);
711    glEnable(GL_TEXTURE_2D);
712       
713
714        //Read the depth buffer into the shadow map texture
715        glBindTexture(GL_TEXTURE_2D, depthMap);
716        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
717
718       
719        // 6. Now we have a two depth buffers defining the ray origin and termination
720        //    only rays which have non-zero entry in the origin buffer are valid since
721        //    they realy start on the object surface (this can also be tagged by setting a
722        //    stencil buffer bit at step 3)
723        glStencilFunc(GL_EQUAL, 0x1, 0x1);
724
725        // compare with second depth buffer: done in pixel shader
726        cgGLBindProgram(sCgFragmentProgram);
727        cgGLEnableProfile(sCgFragmentProfile);
728
729        // 7. Use occlusion queries for all viewcell meshes associated with the beam ->
730        // a fragment passes if the corresponding stencil fragment is set and its depth is
731        // between origin and termination buffer
732
733        // create new queries if necessary
734        GenQueries((int)beam.mViewCells.size());
735
736        // now check whether any backfacing polygon would pass the depth test
737        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
738        glDepthMask(GL_FALSE);
739        glDisable(GL_CULL_FACE);
740 
741        ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
742
743        int queryIdx = 0;
744
745        for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
746        {
747                glBeginOcclusionQueryNV(sQueries[queryIdx ++]);
748
749                RenderIntersectable(*vit);
750               
751                glEndOcclusionQueryNV();
752        }
753
754        // at this point, if possible, go and do some other computation
755        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
756        glDepthMask(GL_TRUE);
757        glEnable(GL_CULL_FACE);
758
759        // 8. The number of visible pixels is the number of sample rays which see the source
760        //    object from the corresponding viewcell -> rember these values for later update
761        //   of the viewcell pvs - or update immediatelly?
762
763        //  In general it is not neccessary to rember to extract all the rays cast. I hope it
764        // would be sufficient to gain only the intergral statistics about the new contributions
765        // and so the rss tree would actually store no new rays (only the initial ones)
766        // the subdivision of the tree would only be driven by the statistics (the glrender could
767        // evaluate the contribution entropy for example)
768        // However might be an option to extract/store only those the rays which made a contribution
769        // (new viewcell has been discovered) or relative contribution greater than a threashold ...
770
771        cgGLDisableProfile(sCgFragmentProfile);
772        glDisable(GL_TEXTURE_2D);
773}
774
775
776void GlRendererBuffer::GenQueries(const int numQueries)
777{
778        if ((int)sQueries.size() < numQueries)
779        {
780                const int n = numQueries - (int)sQueries.size();
781                int *newQueries = new int[n];
782
783                glGenOcclusionQueriesNV(n, (unsigned int *)&newQueries);
784
785                for (int i = 0; i < n; ++ i)
786                {
787                        sQueries.push_back(newQueries[i]);
788                }
789
790                delete newQueries;
791        }
792}
793
794void GlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint,
795                                                                                                 const Beam &beam,
796                                                                                                 Intersectable *sourceObject)
797{
798        float left, right, bottom, top, znear, zfar;
799
800        beam.ComputeFrustum(left, right, bottom, top, znear, zfar,
801                                                mSceneGraph->GetBox());
802
803        glFrustum(left, right, bottom, top, znear, zfar);
804
805    const Vector3 eye = viewPoint + beam.GetMainDirection();
806        const Vector3 up;//AbitraryNormal(eye);
807
808        gluLookAt(eye.x, eye.y, eye.z,
809                          viewPoint.x, viewPoint.y, viewPoint.z,
810                          up.x, up.y, up.z);
811}                         
Note: See TracBrowser for help on using the repository browser.