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

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